From 2849c9af80043819f447b9686f1302c0a1e0fe28 Mon Sep 17 00:00:00 2001 From: Jakob Anderson Date: Fri, 2 Jun 2017 22:50:12 -0600 Subject: [PATCH 1/8] working import of external problem content --- gulpfile.js | 2 +- package-lock.json | 7014 ++++++++++++++++++++++ package.json | 7 +- public/dist/css/style.css | 2 +- public/dist/js/bundle.min.js | 9382 ++++++++++++++++++++++++++++++ public/dist/js/bundle.min.js.map | 6 +- public/service-worker.js | 4 + public/service-worker.js.map | 6 +- shrinkwrap.yaml | 4148 +++++++++++++ src/js/index.js | 31 +- src/service-worker.js | 4 + 11 files changed, 20599 insertions(+), 7 deletions(-) create mode 100644 package-lock.json create mode 100644 shrinkwrap.yaml diff --git a/gulpfile.js b/gulpfile.js index e6bcaf9..0a3bb92 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -71,7 +71,7 @@ function compile(watch) { .pipe(sourcemaps.init({ loadMaps: true })) - .pipe(uglify(uglifyConf)) + // .pipe(uglify()) .pipe(sourcemaps.write('./')) .pipe(gulp.dest('./public/dist/js')); } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..98c3996 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,7014 @@ +{ + "name": "javascript-practice", + "version": "1.0.0", + "lockfileVersion": 1, + "dependencies": { + "@ava/babel-preset-stage-4": { + "version": "https://registry.npmjs.org/@ava/babel-preset-stage-4/-/babel-preset-stage-4-1.0.0.tgz", + "integrity": "sha1-phO14VL1KTBUIlRrBy1H+s+yYpE=", + "dev": true + }, + "@ava/babel-preset-transform-test-files": { + "version": "https://registry.npmjs.org/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-2.0.1.tgz", + "integrity": "sha1-11IyzG1x3Jx+rkt2qQBP2BUB0ME=", + "dev": true + }, + "@ava/pretty-format": { + "version": "https://registry.npmjs.org/@ava/pretty-format/-/pretty-format-1.1.0.tgz", + "integrity": "sha1-0KV9Jeua6rlkO90aAwZCuRwSPig=", + "dev": true + }, + "@gulp-sourcemaps/identity-map": { + "version": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.1.tgz", + "integrity": "sha1-z6I7xYQPkQTOMqZedNt+epdLvuE=", + "dev": true, + "dependencies": { + "acorn": { + "version": "https://registry.npmjs.org/acorn/-/acorn-5.0.3.tgz", + "integrity": "sha1-xGDfCEkUY/AozLguqzcwvwEIez0=", + "dev": true + }, + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + }, + "through2": { + "version": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "@gulp-sourcemaps/map-sources": { + "version": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", + "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + }, + "through2": { + "version": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "abbrev": { + "version": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", + "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=", + "dev": true + }, + "acorn": { + "version": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz", + "integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ=" + }, + "acorn-jsx": { + "version": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "dependencies": { + "acorn": { + "version": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "dependencies": { + "co": { + "version": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "json-stable-stringify": { + "version": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true + } + } + }, + "ajv-keywords": { + "version": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "align-text": { + "version": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true + }, + "alphanum-sort": { + "version": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "amdefine": { + "version": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "ansi-align": { + "version": "https://registry.npmjs.org/ansi-align/-/ansi-align-1.1.0.tgz", + "integrity": "sha1-LwwWWIKXOa3V67FeawxuNCPwFro=", + "dev": true + }, + "ansi-escapes": { + "version": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, + "ansi-regex": { + "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz", + "integrity": "sha1-o+Uvo5FoyCX/V7AkgSbOWo/5VQc=", + "dev": true + }, + "app-root-path": { + "version": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.0.1.tgz", + "integrity": "sha1-zWLc+OT9WkF+/GZNLlsQZTxlG0Y=", + "dev": true + }, + "aproba": { + "version": "https://registry.npmjs.org/aproba/-/aproba-1.1.1.tgz", + "integrity": "sha1-ldNgDwdxCqDpKYxyatXs8urLq6s=", + "dev": true + }, + "archy": { + "version": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "are-we-there-yet": { + "version": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + } + } + }, + "argparse": { + "version": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true + }, + "arr-diff": { + "version": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true + }, + "arr-exclude": { + "version": "https://registry.npmjs.org/arr-exclude/-/arr-exclude-1.0.0.tgz", + "integrity": "sha1-38fC5VKicHI8zaBM8xKMjL/lxjE=", + "dev": true + }, + "arr-flatten": { + "version": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.3.tgz", + "integrity": "sha1-onTthawIhJtr14R8RYB0XcUa37E=", + "dev": true + }, + "array-differ": { + "version": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "dev": true + }, + "array-filter": { + "version": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", + "dev": true + }, + "array-find-index": { + "version": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-map": { + "version": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", + "dev": true + }, + "array-reduce": { + "version": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", + "dev": true + }, + "array-union": { + "version": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true + }, + "array-uniq": { + "version": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "arrify": { + "version": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true + }, + "asn1.js": { + "version": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz", + "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=", + "dev": true + }, + "assert": { + "version": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true + }, + "assert-plus": { + "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true + }, + "assertion-error": { + "version": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", + "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=" + }, + "ast-types": { + "version": "https://registry.npmjs.org/ast-types/-/ast-types-0.8.15.tgz", + "integrity": "sha1-ju8IJ/BN/w7IhXupJavj/qYZTlI=" + }, + "astw": { + "version": "https://registry.npmjs.org/astw/-/astw-2.2.0.tgz", + "integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=", + "dev": true, + "dependencies": { + "acorn": { + "version": "https://registry.npmjs.org/acorn/-/acorn-4.0.11.tgz", + "integrity": "sha1-7c2jvZN+dVZBDULtWGD2c5nHlMA=", + "dev": true + } + } + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "async-each": { + "version": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "async-foreach": { + "version": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "dev": true + }, + "asynckit": { + "version": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz", + "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=", + "dev": true + }, + "auto-bind": { + "version": "https://registry.npmjs.org/auto-bind/-/auto-bind-1.1.0.tgz", + "integrity": "sha1-k7hk3H7gGjJigXddXHXKCnUeWWE=", + "dev": true + }, + "autoprefixer": { + "version": "6.7.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", + "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", + "dev": true + }, + "ava": { + "version": "0.18.2", + "resolved": "https://registry.npmjs.org/ava/-/ava-0.18.2.tgz", + "integrity": "sha1-eSU9FjYHcDSieAu1W1w+bD1/MS8=", + "dev": true, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + } + } + }, + "ava-init": { + "version": "https://registry.npmjs.org/ava-init/-/ava-init-0.2.0.tgz", + "integrity": "sha1-kwTItMNX1m49/a4fv/R7EZnVxV0=", + "dev": true + }, + "aws-sign2": { + "version": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true + }, + "aws4": { + "version": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "dev": true + }, + "babel-code-frame": { + "version": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", + "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", + "dev": true + }, + "babel-core": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.24.1.tgz", + "integrity": "sha1-jEKFZNzh4fQfszfsNPTDsCK1rYM=", + "dependencies": { + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" + } + } + }, + "babel-generator": { + "version": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.24.1.tgz", + "integrity": "sha1-5xX0hsWN7SVknYiJRNUqoHxdlJc=", + "dev": true, + "dependencies": { + "jsesc": { + "version": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + }, + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true + } + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true + }, + "babel-helper-call-delegate": { + "version": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true + }, + "babel-helper-define-map": { + "version": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz", + "integrity": "sha1-epdH8ljYlH0y1RX2qhx70CIEoIA=", + "dev": true + }, + "babel-helper-explode-assignable-expression": { + "version": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true + }, + "babel-helper-function-name": { + "version": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true + }, + "babel-helper-get-function-arity": { + "version": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true + }, + "babel-helper-hoist-variables": { + "version": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true + }, + "babel-helper-optimise-call-expression": { + "version": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true + }, + "babel-helper-regex": { + "version": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz", + "integrity": "sha1-024i+rEAjXnYhkjjIRaGgShFbOg=", + "dev": true + }, + "babel-helper-remap-async-to-generator": { + "version": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true + }, + "babel-helper-replace-supers": { + "version": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true + }, + "babel-helpers": { + "version": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true + }, + "babel-messages": { + "version": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true + }, + "babel-plugin-ava-throws-helper": { + "version": "https://registry.npmjs.org/babel-plugin-ava-throws-helper/-/babel-plugin-ava-throws-helper-1.0.0.tgz", + "integrity": "sha1-j+bnnS/RmDi1w2Sfic+wP9Vj4kE=", + "dev": true + }, + "babel-plugin-check-es2015-constants": { + "version": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true + }, + "babel-plugin-espower": { + "version": "https://registry.npmjs.org/babel-plugin-espower/-/babel-plugin-espower-2.3.2.tgz", + "integrity": "sha1-VRa4/NsmyfDh2BYHSfbkxl5xJx4=", + "dev": true + }, + "babel-plugin-syntax-async-functions": { + "version": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "babel-plugin-transform-async-to-generator": { + "version": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz", + "integrity": "sha1-dsKV3DpHQbFmWt/TFnIV3P8ypXY=", + "dev": true + }, + "babel-plugin-transform-es2015-classes": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true + }, + "babel-plugin-transform-es2015-for-of": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true + }, + "babel-plugin-transform-es2015-function-name": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true + }, + "babel-plugin-transform-es2015-literals": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz", + "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", + "dev": true + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true + }, + "babel-plugin-transform-es2015-object-super": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true + }, + "babel-plugin-transform-es2015-parameters": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true + }, + "babel-plugin-transform-es2015-spread": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true + }, + "babel-plugin-transform-regenerator": { + "version": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz", + "integrity": "sha1-uNowWtQ8PJm0hI5P5AN7dw0jxBg=", + "dev": true + }, + "babel-plugin-transform-strict-mode": { + "version": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true + }, + "babel-preset-es2015": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", + "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", + "dev": true + }, + "babel-preset-es2016": { + "version": "https://registry.npmjs.org/babel-preset-es2016/-/babel-preset-es2016-6.24.1.tgz", + "integrity": "sha1-+QC/k+LrwNJ235uKtZck6/2Vn4s=", + "dev": true + }, + "babel-preset-es2017": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-es2017/-/babel-preset-es2017-6.24.1.tgz", + "integrity": "sha1-WXvq37n38gi8/YoS6bKym4svFNE=", + "dev": true + }, + "babel-preset-latest": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-latest/-/babel-preset-latest-6.24.1.tgz", + "integrity": "sha1-Z33gaRVKdIXC0lxXfAL2JLhbheg=", + "dev": true + }, + "babel-register": { + "version": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.1.tgz", + "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", + "dev": true + }, + "babel-runtime": { + "version": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", + "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", + "dev": true + }, + "babel-template": { + "version": "https://registry.npmjs.org/babel-template/-/babel-template-6.24.1.tgz", + "integrity": "sha1-BK5RTx+Ts6JTfyoPYKWkX7gwgzM=", + "dev": true + }, + "babel-traverse": { + "version": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.24.1.tgz", + "integrity": "sha1-qzZnP9NW+aCUhlnnszjV/q2zFpU=", + "dev": true + }, + "babel-types": { + "version": "https://registry.npmjs.org/babel-types/-/babel-types-6.24.1.tgz", + "integrity": "sha1-oTaHncFbNga9oNkMH8dDBML/CXU=", + "dev": true + }, + "babelify": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", + "dev": true + }, + "babylon": { + "version": "https://registry.npmjs.org/babylon/-/babylon-6.17.0.tgz", + "integrity": "sha1-N9qUiHhIi5xOPEA4iT+jMUs/yTI=", + "dev": true + }, + "balanced-match": { + "version": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "base62": { + "version": "https://registry.npmjs.org/base62/-/base62-0.1.1.tgz", + "integrity": "sha1-e0F0wvlESXU7EcJlHAg9qEGnsIQ=" + }, + "base64-js": { + "version": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.0.tgz", + "integrity": "sha1-o5mS1yNYSBGYK+XikLtqU9hnAPE=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "dev": true, + "optional": true + }, + "beeper": { + "version": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "dev": true + }, + "binary-extensions": { + "version": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.8.0.tgz", + "integrity": "sha1-SOyNFt9Dd+rl+liEaCSAr02Vx3Q=", + "dev": true + }, + "block-stream": { + "version": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true + }, + "bluebird": { + "version": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "dev": true + }, + "bn.js": { + "version": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "body-parser": { + "version": "https://registry.npmjs.org/body-parser/-/body-parser-1.14.2.tgz", + "integrity": "sha1-EBXLH+LEQ4WCWVgdtTMy+NDPUPk=", + "dev": true, + "dependencies": { + "debug": { + "version": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true + }, + "ms": { + "version": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + }, + "qs": { + "version": "https://registry.npmjs.org/qs/-/qs-5.2.0.tgz", + "integrity": "sha1-qfMRQq9GjLcrJbMBNrokVoNJFr4=", + "dev": true + } + } + }, + "boom": { + "version": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true + }, + "boxen": { + "version": "https://registry.npmjs.org/boxen/-/boxen-0.6.0.tgz", + "integrity": "sha1-g2TUJIrDT/DvGy8r9JpsYM4NgbY=", + "dev": true + }, + "brace-expansion": { + "version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", + "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", + "dev": true + }, + "braces": { + "version": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true + }, + "brorand": { + "version": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.2.tgz", + "integrity": "sha1-+GzWzvT1MAyOY+B6TVEvZfv/RTE=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + }, + "through2": { + "version": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "browser-resolve": { + "version": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", + "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", + "dev": true, + "dependencies": { + "resolve": { + "version": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browserify": { + "version": "14.4.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-14.4.0.tgz", + "integrity": "sha1-CJo0Y69Y0OSNjNQHCz90ZU1avKk=", + "dev": true, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.10.tgz", + "integrity": "sha512-HQEnnoV404e0EtwB9yNiuk2tJ+egeVC8Y9QBAxzDg8DBJt4BzRp+yQuIb/t3FIWkSTmIi+sgx7yVv/ZM0GNoqw==", + "dev": true + }, + "string_decoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", + "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "browserify-aes": { + "version": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.6.tgz", + "integrity": "sha1-Xncl297x/Vkw1OurSFZ85FHEigo=", + "dev": true + }, + "browserify-cache-api": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/browserify-cache-api/-/browserify-cache-api-3.0.1.tgz", + "integrity": "sha1-liR+hT8Gj9bg1FzHPwuyzZd47wI=", + "dev": true, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.10.tgz", + "integrity": "sha512-HQEnnoV404e0EtwB9yNiuk2tJ+egeVC8Y9QBAxzDg8DBJt4BzRp+yQuIb/t3FIWkSTmIi+sgx7yVv/ZM0GNoqw==", + "dev": true + }, + "string_decoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", + "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "browserify-cipher": { + "version": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", + "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "dev": true + }, + "browserify-des": { + "version": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", + "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "dev": true + }, + "browserify-incremental": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/browserify-incremental/-/browserify-incremental-3.1.1.tgz", + "integrity": "sha1-BxPLdYckemMqnwjPG9FpuHi2Koo=", + "dev": true, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "jsonparse": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-0.0.5.tgz", + "integrity": "sha1-MwVCrT8KZUZlt3jz6y2an6UHrGQ=", + "dev": true + }, + "JSONStream": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-0.10.0.tgz", + "integrity": "sha1-dDSdDYlSK3HzDwoD/5vSDKbxKsA=", + "dev": true + }, + "readable-stream": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.10.tgz", + "integrity": "sha512-HQEnnoV404e0EtwB9yNiuk2tJ+egeVC8Y9QBAxzDg8DBJt4BzRp+yQuIb/t3FIWkSTmIi+sgx7yVv/ZM0GNoqw==", + "dev": true + }, + "string_decoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", + "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "browserify-rsa": { + "version": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true + }, + "browserify-sign": { + "version": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true + }, + "browserify-zlib": { + "version": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "dev": true + }, + "browserslist": { + "version": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", + "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true + }, + "buf-compare": { + "version": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz", + "integrity": "sha1-/vKNqLgROgoNtEMLC2Rntpcws0o=", + "dev": true + }, + "buffer": { + "version": "https://registry.npmjs.org/buffer/-/buffer-5.0.6.tgz", + "integrity": "sha1-LqZp9+7Atu2gWwj4tf9mGyhXNYg=", + "dev": true + }, + "buffer-shims": { + "version": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "dev": true + }, + "buffer-xor": { + "version": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz", + "integrity": "sha1-/TVGSkA/b5EXwt42Cez/nK4ABYg=", + "dev": true + }, + "cached-path-relative": { + "version": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", + "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=", + "dev": true + }, + "caching-transform": { + "version": "https://registry.npmjs.org/caching-transform/-/caching-transform-1.0.1.tgz", + "integrity": "sha1-bb2y8g+Nj7znnz6U6dF0Lc31wKE=", + "dev": true, + "dependencies": { + "md5-hex": { + "version": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", + "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", + "dev": true + } + } + }, + "call-matcher": { + "version": "https://registry.npmjs.org/call-matcher/-/call-matcher-1.0.1.tgz", + "integrity": "sha1-UTTQd5hPcSpU2tPL9i3ijc5BbKg=", + "dev": true + }, + "call-signature": { + "version": "https://registry.npmjs.org/call-signature/-/call-signature-0.0.2.tgz", + "integrity": "sha1-qEq8glpV70yysCi9dOIFpluaSZY=", + "dev": true + }, + "caller-path": { + "version": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true + }, + "callsites": { + "version": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "camelcase": { + "version": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true + }, + "caniuse-api": { + "version": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", + "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=", + "dev": true, + "dependencies": { + "lodash.memoize": { + "version": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + } + } + }, + "caniuse-db": { + "version": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000665.tgz", + "integrity": "sha1-6E9Cd5NfKV9Ub4UzywtBCoQVuXI=", + "dev": true + }, + "capture-stack-trace": { + "version": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", + "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=", + "dev": true + }, + "caseless": { + "version": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "center-align": { + "version": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true + }, + "chai": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", + "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=" + }, + "chalk": { + "version": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "supports-color": { + "version": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "chokidar": { + "version": "https://registry.npmjs.org/chokidar/-/chokidar-1.6.1.tgz", + "integrity": "sha1-L0RHq16W5Q+z14n9kNTHLg5McMI=", + "dev": true + }, + "ci-info": { + "version": "https://registry.npmjs.org/ci-info/-/ci-info-1.0.0.tgz", + "integrity": "sha1-3FKF8rTiUYIWg2gcOBwziPRuxTQ=", + "dev": true + }, + "cipher-base": { + "version": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.3.tgz", + "integrity": "sha1-7qvxlEGc6QDaMBjCB9IS8qbfCgc=", + "dev": true + }, + "circular-json": { + "version": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.1.tgz", + "integrity": "sha1-vos2rvzN6LPKeqLWr8B6NyQsDS0=", + "dev": true + }, + "clap": { + "version": "https://registry.npmjs.org/clap/-/clap-1.1.3.tgz", + "integrity": "sha1-s7026T3Uy/s5WjwmiWNSRFJlwFs=", + "dev": true + }, + "clean-stack": { + "version": "https://registry.npmjs.org/clean-stack/-/clean-stack-1.1.1.tgz", + "integrity": "sha1-obNxESLfFi33x8ubPARw8oy1its=", + "dev": true + }, + "clean-yaml-object": { + "version": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", + "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", + "dev": true + }, + "cli-boxes": { + "version": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "dev": true + }, + "cli-cursor": { + "version": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true + }, + "cli-spinners": { + "version": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.0.0.tgz", + "integrity": "sha1-75h+09SDkaw9q5GAtAanQhgNbmo=", + "dev": true + }, + "cli-truncate": { + "version": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "dev": true + }, + "cli-width": { + "version": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", + "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=", + "dev": true + }, + "cliui": { + "version": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true + }, + "clone": { + "version": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", + "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", + "dev": true + }, + "clone-stats": { + "version": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + }, + "co-with-promise": { + "version": "https://registry.npmjs.org/co-with-promise/-/co-with-promise-4.6.0.tgz", + "integrity": "sha1-QT59tvWJOmC5Qs9JLEvsk9tBWrc=", + "dev": true, + "dependencies": { + "pinkie": { + "version": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz", + "integrity": "sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q=", + "dev": true + }, + "pinkie-promise": { + "version": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz", + "integrity": "sha1-0dpn9UglY7t89X8oauKCLs+/NnA=", + "dev": true + } + } + }, + "coa": { + "version": "https://registry.npmjs.org/coa/-/coa-1.0.1.tgz", + "integrity": "sha1-f5WTRs/IcZ4/cjPNaFKFSnxn2KM=", + "dev": true + }, + "code-excerpt": { + "version": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-2.1.0.tgz", + "integrity": "sha1-XcwIHoj0p+O1VOnjXX7yMtR/gUc=", + "dev": true + }, + "code-point-at": { + "version": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color": { + "version": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", + "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", + "dev": true + }, + "color-convert": { + "version": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", + "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", + "dev": true + }, + "color-name": { + "version": "https://registry.npmjs.org/color-name/-/color-name-1.1.2.tgz", + "integrity": "sha1-XIq3K2S9IhXWF66VWeuxSEdc+Y0=", + "dev": true + }, + "color-string": { + "version": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz", + "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=", + "dev": true + }, + "colormin": { + "version": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", + "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=", + "dev": true + }, + "colors": { + "version": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "combine-source-map": { + "version": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", + "integrity": "sha1-CHAxKFazB6h8xKxIbzqaYq7MwJ4=", + "dev": true, + "dependencies": { + "convert-source-map": { + "version": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true + } + } + }, + "combined-stream": { + "version": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "dev": true + }, + "commander": { + "version": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true + }, + "common-path-prefix": { + "version": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-1.0.0.tgz", + "integrity": "sha1-zVL28HEuC6q5fW+XModPIvR3UsA=", + "dev": true + }, + "commondir": { + "version": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", + "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true + } + } + }, + "configstore": { + "version": "https://registry.npmjs.org/configstore/-/configstore-2.1.0.tgz", + "integrity": "sha1-c3o6cDbpiGECqmCZ5HuzOrGroaE=", + "dev": true, + "dependencies": { + "dot-prop": { + "version": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", + "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", + "dev": true + } + } + }, + "console-browserify": { + "version": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true + }, + "console-control-strings": { + "version": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "constants-browserify": { + "version": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "contains-path": { + "version": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "content-type": { + "version": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", + "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=", + "dev": true + }, + "convert-source-map": { + "version": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", + "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", + "dev": true + }, + "convert-to-spaces": { + "version": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz", + "integrity": "sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU=", + "dev": true + }, + "core-assert": { + "version": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz", + "integrity": "sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8=", + "dev": true + }, + "core-js": { + "version": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", + "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=", + "dev": true + }, + "core-util-is": { + "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cosmiconfig": { + "version": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.1.3.tgz", + "integrity": "sha1-lSdx6w3dwcs/ovb75RpSLpOz7go=", + "dev": true, + "dependencies": { + "minimist": { + "version": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "create-ecdh": { + "version": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", + "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "dev": true + }, + "create-error-class": { + "version": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true + }, + "create-hash": { + "version": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.2.tgz", + "integrity": "sha1-USEAYte7dHn2xlu0GpIgix1hq60=", + "dev": true + }, + "create-hmac": { + "version": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.4.tgz", + "integrity": "sha1-0/tLolPriz9W456i+8uK90e9MXA=", + "dev": true + }, + "cross-spawn": { + "version": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "dev": true + }, + "cross-spawn-async": { + "version": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz", + "integrity": "sha1-hF/wwINKPe2dFg2sptOQkGuyiMw=", + "dev": true + }, + "cryptiles": { + "version": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true + }, + "crypto-browserify": { + "version": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.0.tgz", + "integrity": "sha1-NlKgkGq5sqfgw85mpAjpV6JIVSI=", + "dev": true + }, + "crypto-random-string": { + "version": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, + "css": { + "version": "https://registry.npmjs.org/css/-/css-2.2.1.tgz", + "integrity": "sha1-c6TIHehdtmTU7mdPfUcIXjstVdw=", + "dev": true, + "dependencies": { + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "dev": true + } + } + }, + "css-color-names": { + "version": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + }, + "cssnano": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", + "dev": true + }, + "csso": { + "version": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", + "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", + "dev": true, + "dependencies": { + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true + } + } + }, + "currently-unhandled": { + "version": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true + }, + "d": { + "version": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true + }, + "dashdash": { + "version": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": { + "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "date-fns": { + "version": "https://registry.npmjs.org/date-fns/-/date-fns-1.28.4.tgz", + "integrity": "sha1-eTiuw0ujH8i9E00jRLwuC7/ZUWU=", + "dev": true + }, + "date-now": { + "version": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "date-time": { + "version": "https://registry.npmjs.org/date-time/-/date-time-0.1.1.tgz", + "integrity": "sha1-7S9tk9l5DOL9ZtW1/z7dW7y/Owc=", + "dev": true + }, + "dateformat": { + "version": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", + "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=", + "dev": true + }, + "debug": { + "version": "https://registry.npmjs.org/debug/-/debug-2.6.6.tgz", + "integrity": "sha1-qfpvvpykPPHnn3O3XAGJy7fW21o=", + "dev": true + }, + "debug-fabulous": { + "version": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.1.0.tgz", + "integrity": "sha1-rQ6gel1RkyT7VYQqjzTuWcf4/2w=", + "dev": true, + "dependencies": { + "object-assign": { + "version": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", + "dev": true + } + } + }, + "decamelize": { + "version": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-assign": { + "version": "https://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz", + "integrity": "sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s=", + "dev": true + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dependencies": { + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=" + } + } + }, + "deep-equal": { + "version": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "deep-extend": { + "version": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.1.tgz", + "integrity": "sha1-7+QRPQgIX05vlod1mBD4B0aeIlM=", + "dev": true + }, + "deep-is": { + "version": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "deep-strict-equal": { + "version": "https://registry.npmjs.org/deep-strict-equal/-/deep-strict-equal-0.2.0.tgz", + "integrity": "sha1-SgeBR6irV/ag1PVUckPNIvROtOQ=", + "dev": true + }, + "defaults": { + "version": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true + }, + "defined": { + "version": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "del": { + "version": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "dependencies": { + "globby": { + "version": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true + } + } + }, + "delayed-stream": { + "version": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "delegates": { + "version": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "depd": { + "version": "https://registry.npmjs.org/depd/-/depd-1.1.0.tgz", + "integrity": "sha1-4b2Cxqq2ztlluXuIsX7T5SjKGMM=", + "dev": true + }, + "deprecated": { + "version": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", + "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=", + "dev": true + }, + "deps-sort": { + "version": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + }, + "through2": { + "version": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "des.js": { + "version": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true + }, + "detect-file": { + "version": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", + "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", + "dev": true + }, + "detect-indent": { + "version": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true + }, + "detect-newline": { + "version": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "dev": true + }, + "detective": { + "version": "https://registry.npmjs.org/detective/-/detective-4.5.0.tgz", + "integrity": "sha1-blqMaybmx6JUsca210kNmOyR7dE=", + "dev": true, + "dependencies": { + "acorn": { + "version": "https://registry.npmjs.org/acorn/-/acorn-4.0.11.tgz", + "integrity": "sha1-7c2jvZN+dVZBDULtWGD2c5nHlMA=", + "dev": true + } + } + }, + "diff": { + "version": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "dev": true + }, + "diffie-hellman": { + "version": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", + "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "dev": true + }, + "doctrine": { + "version": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", + "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "domain-browser": { + "version": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", + "dev": true + }, + "dot-prop": { + "version": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.1.1.tgz", + "integrity": "sha1-qEk/C3te7sglJbXHWH+n3nyoWcE=", + "dev": true + }, + "duplexer": { + "version": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "duplexer2": { + "version": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + } + } + }, + "duplexer3": { + "version": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ecc-jsbn": { + "version": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "dev": true, + "optional": true + }, + "ee-first": { + "version": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "electron-to-chromium": { + "version": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.9.tgz", + "integrity": "sha1-2xy6KiauvMovf1uLA0VURoYJFX0=", + "dev": true + }, + "elegant-spinner": { + "version": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "dev": true + }, + "elliptic": { + "version": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "dev": true + }, + "empower-core": { + "version": "https://registry.npmjs.org/empower-core/-/empower-core-0.6.1.tgz", + "integrity": "sha1-bBh/UC/O91VNV5MzlqrGVUg3crE=", + "dev": true + }, + "end-of-stream": { + "version": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", + "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", + "dev": true, + "dependencies": { + "once": { + "version": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "dev": true + } + } + }, + "enhance-visitors": { + "version": "https://registry.npmjs.org/enhance-visitors/-/enhance-visitors-1.0.0.tgz", + "integrity": "sha1-qpRdBdpGVnKh69OP7i7T2oUY6Vo=", + "dev": true + }, + "equal-length": { + "version": "https://registry.npmjs.org/equal-length/-/equal-length-1.0.1.tgz", + "integrity": "sha1-IcoRLUirJLTh5//A5TOdMf38J0w=", + "dev": true + }, + "error-ex": { + "version": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true + }, + "es3ify": { + "version": "https://registry.npmjs.org/es3ify/-/es3ify-0.1.4.tgz", + "integrity": "sha1-rZ+l3xrjTz8x4SEbWBiy1RB439E=", + "dependencies": { + "esprima-fb": { + "version": "3001.1.0-dev-harmony-fb", + "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-3001.0001.0000-dev-harmony-fb.tgz", + "integrity": "sha1-t303q8046gt3Qmu4vCkizmtCZBE=" + } + } + }, + "es5-ext": { + "version": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.15.tgz", + "integrity": "sha1-wzClk0we4hKEp8CBqG5f2TfJHqY=", + "dev": true + }, + "es6-iterator": { + "version": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", + "dev": true + }, + "es6-map": { + "version": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true + }, + "es6-set": { + "version": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true + }, + "es6-symbol": { + "version": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true + }, + "es6-weak-map": { + "version": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true + }, + "escape-string-regexp": { + "version": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true + } + } + }, + "escope": { + "version": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true + }, + "eslint": { + "version": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "dev": true, + "dependencies": { + "json-stable-stringify": { + "version": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true + }, + "user-home": { + "version": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true + } + } + }, + "eslint-config-xo": { + "version": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.18.1.tgz", + "integrity": "sha1-87yHOzOyyCUT2IHqyy7jQoQHrTM=", + "dev": true + }, + "eslint-formatter-pretty": { + "version": "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-1.1.0.tgz", + "integrity": "sha1-q00G2gL+2ME66fDcVApDPvftb14=", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": { + "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", + "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=", + "dev": true + } + } + }, + "eslint-import-resolver-node": { + "version": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz", + "integrity": "sha1-Wt2BBujJKNssuiMrzZ76hG49oWw=", + "dev": true + }, + "eslint-module-utils": { + "version": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.0.0.tgz", + "integrity": "sha1-pvjCHZATWHWc3DXbrBmCrh7li84=", + "dev": true, + "dependencies": { + "debug": { + "version": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true + }, + "ms": { + "version": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true + } + } + }, + "eslint-plugin-ava": { + "version": "https://registry.npmjs.org/eslint-plugin-ava/-/eslint-plugin-ava-4.2.0.tgz", + "integrity": "sha1-EuRmRlnB+ueJX6PzRsMTzriQfHc=", + "dev": true + }, + "eslint-plugin-import": { + "version": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz", + "integrity": "sha1-crowb60wXWfEgWNIpGmaQimsi04=", + "dev": true, + "dependencies": { + "doctrine": { + "version": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true + }, + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "eslint-plugin-no-use-extend-native": { + "version": "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.3.12.tgz", + "integrity": "sha1-OtmgDC3yO11/f2vpFVCYWkq3Aeo=", + "dev": true + }, + "eslint-plugin-promise": { + "version": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz", + "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=", + "dev": true + }, + "eslint-plugin-unicorn": { + "version": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-2.1.1.tgz", + "integrity": "sha1-PpKUNmeZtxXham34kVlJW2iTDLM=", + "dev": true + }, + "esmangle-evaluator": { + "version": "https://registry.npmjs.org/esmangle-evaluator/-/esmangle-evaluator-1.0.1.tgz", + "integrity": "sha1-Yg2GbvSGGzMR91dm1SqFcrs8YzY=" + }, + "espower-location-detector": { + "version": "https://registry.npmjs.org/espower-location-detector/-/espower-location-detector-1.0.0.tgz", + "integrity": "sha1-oXt+zFnTDheeK+9z+0E3cEyzMbU=", + "dev": true, + "dependencies": { + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true + } + } + }, + "espree": { + "version": "https://registry.npmjs.org/espree/-/espree-3.4.3.tgz", + "integrity": "sha1-KRC1zNSc6JPC//+qtP2LOjG4I3Q=", + "dev": true, + "dependencies": { + "acorn": { + "version": "https://registry.npmjs.org/acorn/-/acorn-5.0.3.tgz", + "integrity": "sha1-xGDfCEkUY/AozLguqzcwvwEIez0=", + "dev": true + } + } + }, + "esprima-fb": { + "version": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-3001.0001.0000-dev-harmony-fb.tgz", + "integrity": "sha1-t303q8046gt3Qmu4vCkizmtCZBE=" + }, + "espurify": { + "version": "https://registry.npmjs.org/espurify/-/espurify-1.7.0.tgz", + "integrity": "sha1-HFz2y8zDLm9jk4C9T5kfq5up0iY=", + "dev": true + }, + "esquery": { + "version": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true + }, + "esrecurse": { + "version": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.1.0.tgz", + "integrity": "sha1-RxO2U2rffyrE8yfVWed1a/9kgiA=", + "dev": true, + "dependencies": { + "estraverse": { + "version": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.1.tgz", + "integrity": "sha1-9srKcokzqFDvkGYdDheYK6RxEaI=", + "dev": true + } + } + }, + "estraverse": { + "version": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "event-emitter": { + "version": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true + }, + "event-stream": { + "version": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "dev": true + }, + "events": { + "version": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "evp_bytestokey": { + "version": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz", + "integrity": "sha1-SXtmrZ/vZc18CKYYCCS6FHa2blM=", + "dev": true + }, + "execa": { + "version": "https://registry.npmjs.org/execa/-/execa-0.5.1.tgz", + "integrity": "sha1-3j+4XLjW6RyFvLzrFkWBeFy1ezY=", + "dev": true + }, + "exit-hook": { + "version": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "expand-brackets": { + "version": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true + }, + "expand-range": { + "version": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true + }, + "expand-tilde": { + "version": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", + "dev": true + }, + "extend": { + "version": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "extglob": { + "version": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true + }, + "extsprintf": { + "version": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", + "dev": true + }, + "falafel": { + "version": "https://registry.npmjs.org/falafel/-/falafel-1.2.0.tgz", + "integrity": "sha1-wY0k71CRF0pJfzGM0ksCaiXN2rQ=" + }, + "fancy-log": { + "version": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", + "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "dev": true + }, + "fast-levenshtein": { + "version": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "faye-websocket": { + "version": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.7.3.tgz", + "integrity": "sha1-zEB0x/Sk39A69U3WXDVLE1EyzhE=", + "dev": true + }, + "figures": { + "version": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true + }, + "file-entry-cache": { + "version": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true + }, + "filename-regex": { + "version": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true + }, + "filled-array": { + "version": "https://registry.npmjs.org/filled-array/-/filled-array-1.1.0.tgz", + "integrity": "sha1-w8T2xmO5I0WamqKZEtLQMfFQf4Q=", + "dev": true + }, + "find-cache-dir": { + "version": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", + "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", + "dev": true + }, + "find-index": { + "version": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", + "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", + "dev": true + }, + "find-parent-dir": { + "version": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", + "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=", + "dev": true + }, + "find-up": { + "version": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true + }, + "findup-sync": { + "version": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz", + "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=", + "dev": true + }, + "fined": { + "version": "https://registry.npmjs.org/fined/-/fined-1.0.2.tgz", + "integrity": "sha1-WyhCS3YNdZiWC374SA3/itNmDpc=", + "dev": true + }, + "first-chunk-stream": { + "version": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=", + "dev": true + }, + "flagged-respawn": { + "version": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", + "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=", + "dev": true + }, + "flat-cache": { + "version": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", + "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", + "dev": true + }, + "flatten": { + "version": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", + "dev": true + }, + "fn-name": { + "version": "https://registry.npmjs.org/fn-name/-/fn-name-2.0.1.tgz", + "integrity": "sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc=", + "dev": true + }, + "for-in": { + "version": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true + }, + "foreach": { + "version": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "forever-agent": { + "version": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dev": true + }, + "from": { + "version": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "dev": true + }, + "fs-exists-sync": { + "version": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", + "dev": true + }, + "fs.realpath": { + "version": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.1.tgz", + "integrity": "sha1-8Z/Sj0Pur3YWgOUZogPE0LPTGv8=", + "dev": true, + "optional": true, + "dependencies": { + "abbrev": { + "version": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", + "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=", + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "optional": true + }, + "aproba": { + "version": "https://registry.npmjs.org/aproba/-/aproba-1.1.1.tgz", + "integrity": "sha1-ldNgDwdxCqDpKYxyatXs8urLq6s=", + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz", + "integrity": "sha1-gORw6VoIR5T+GJkmLFZnxuiN4bM=", + "dev": true, + "optional": true + }, + "asn1": { + "version": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true, + "optional": true + }, + "assert-plus": { + "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "dev": true, + "optional": true + }, + "asynckit": { + "version": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "dev": true, + "optional": true + }, + "aws4": { + "version": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "dev": true, + "optional": true + }, + "balanced-match": { + "version": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "dev": true, + "optional": true + }, + "block-stream": { + "version": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true + }, + "boom": { + "version": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "dev": true + }, + "brace-expansion": { + "version": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", + "integrity": "sha1-cZfX6qm4fmSDkOph/GbIRCdCDfk=", + "dev": true + }, + "buffer-shims": { + "version": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "dev": true + }, + "caseless": { + "version": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", + "dev": true, + "optional": true + }, + "chalk": { + "version": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "combined-stream": { + "version": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "dev": true + }, + "commander": { + "version": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "optional": true + }, + "concat-map": { + "version": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "console-control-strings": { + "version": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "core-util-is": { + "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cryptiles": { + "version": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dev": true, + "optional": true + }, + "dashdash": { + "version": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "optional": true, + "dependencies": { + "assert-plus": { + "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "optional": true + } + } + }, + "debug": { + "version": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "dev": true, + "optional": true + }, + "deep-extend": { + "version": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.1.tgz", + "integrity": "sha1-7+QRPQgIX05vlod1mBD4B0aeIlM=", + "dev": true, + "optional": true + }, + "delayed-stream": { + "version": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "delegates": { + "version": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "dev": true, + "optional": true + }, + "escape-string-regexp": { + "version": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "optional": true + }, + "extend": { + "version": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", + "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ=", + "dev": true, + "optional": true + }, + "extsprintf": { + "version": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", + "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", + "dev": true + }, + "forever-agent": { + "version": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "optional": true + }, + "form-data": { + "version": "https://registry.npmjs.org/form-data/-/form-data-2.1.2.tgz", + "integrity": "sha1-icNTQAi5fq2ky7FX1Y9vXfAl6uQ=", + "dev": true, + "optional": true + }, + "fs.realpath": { + "version": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fstream": { + "version": "https://registry.npmjs.org/fstream/-/fstream-1.0.10.tgz", + "integrity": "sha1-YE6Kkv4m/9n2+uMDmdSYThqyKCI=", + "dev": true + }, + "fstream-ignore": { + "version": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", + "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", + "dev": true, + "optional": true + }, + "gauge": { + "version": "https://registry.npmjs.org/gauge/-/gauge-2.7.3.tgz", + "integrity": "sha1-HCOFX5YvF7OtPQ3HRD8wRULt/gk=", + "dev": true, + "optional": true + }, + "generate-function": { + "version": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true, + "optional": true + }, + "generate-object-property": { + "version": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "optional": true + }, + "getpass": { + "version": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz", + "integrity": "sha1-KD/9n8ElaECHUxHBtg6MQBhxEOY=", + "dev": true, + "optional": true, + "dependencies": { + "assert-plus": { + "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "optional": true + } + } + }, + "glob": { + "version": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "dev": true + }, + "graceful-fs": { + "version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "graceful-readlink": { + "version": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true, + "optional": true + }, + "har-validator": { + "version": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "dev": true, + "optional": true + }, + "has-ansi": { + "version": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "optional": true + }, + "has-unicode": { + "version": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true, + "optional": true + }, + "hawk": { + "version": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true, + "optional": true + }, + "hoek": { + "version": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "http-signature": { + "version": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true, + "optional": true + }, + "inflight": { + "version": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true + }, + "inherits": { + "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true + }, + "is-my-json-valid": { + "version": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz", + "integrity": "sha1-k27do8o8IR/ZjzstPgjaQ/eykVs=", + "dev": true, + "optional": true + }, + "is-property": { + "version": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true, + "optional": true + }, + "is-typedarray": { + "version": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true, + "optional": true + }, + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isstream": { + "version": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true, + "optional": true + }, + "jodid25519": { + "version": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", + "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=", + "dev": true, + "optional": true + }, + "jsbn": { + "version": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "json-schema": { + "version": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true, + "optional": true + }, + "json-stringify-safe": { + "version": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true, + "optional": true + }, + "jsonpointer": { + "version": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true, + "optional": true + }, + "jsprim": { + "version": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz", + "integrity": "sha1-KnJW9wQSop7jZwqspiWZTE3P8lI=", + "dev": true, + "optional": true + }, + "mime-db": { + "version": "https://registry.npmjs.org/mime-db/-/mime-db-1.26.0.tgz", + "integrity": "sha1-6v/NDk/Gk1z4E02iRuLmw1MFrf8=", + "dev": true + }, + "mime-types": { + "version": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.14.tgz", + "integrity": "sha1-9+99l1g/yvO30oK2+LVnnaselO4=", + "dev": true + }, + "minimatch": { + "version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "dev": true + }, + "minimist": { + "version": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true + }, + "ms": { + "version": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", + "dev": true, + "optional": true + }, + "node-pre-gyp": { + "version": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.33.tgz", + "integrity": "sha1-ZArFUZj2qSWXLgwWxKwmoDTV7Mk=", + "dev": true, + "optional": true + }, + "nopt": { + "version": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "optional": true + }, + "npmlog": { + "version": "https://registry.npmjs.org/npmlog/-/npmlog-4.0.2.tgz", + "integrity": "sha1-0DlQ4OeM4VJ7om0qdZLpNIrD518=", + "dev": true, + "optional": true + }, + "number-is-nan": { + "version": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true, + "optional": true + }, + "object-assign": { + "version": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "optional": true + }, + "once": { + "version": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true + }, + "path-is-absolute": { + "version": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "pinkie": { + "version": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true, + "optional": true + }, + "pinkie-promise": { + "version": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "punycode": { + "version": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true, + "optional": true + }, + "qs": { + "version": "https://registry.npmjs.org/qs/-/qs-6.3.1.tgz", + "integrity": "sha1-kYwLO802Z5dyuvE1say0wWUe150=", + "dev": true, + "optional": true + }, + "rc": { + "version": "https://registry.npmjs.org/rc/-/rc-1.1.7.tgz", + "integrity": "sha1-xepWS7B6/5/TpbMukGwdOmWUD+o=", + "dev": true, + "optional": true, + "dependencies": { + "minimist": { + "version": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.2.tgz", + "integrity": "sha1-qeb+w8fdqF+LsbO6cChgRVb8gl4=", + "dev": true, + "optional": true + }, + "request": { + "version": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", + "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", + "dev": true, + "optional": true + }, + "rimraf": { + "version": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", + "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", + "dev": true + }, + "semver": { + "version": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true, + "optional": true + }, + "sntp": { + "version": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true, + "optional": true + }, + "sshpk": { + "version": "https://registry.npmjs.org/sshpk/-/sshpk-1.10.2.tgz", + "integrity": "sha1-1agEziJpVRVjjnmNviMnPeBwpfo=", + "dev": true, + "optional": true, + "dependencies": { + "assert-plus": { + "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "optional": true + } + } + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "string-width": { + "version": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true + }, + "stringstream": { + "version": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "dev": true, + "optional": true + }, + "strip-ansi": { + "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true + }, + "strip-json-comments": { + "version": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "optional": true + }, + "supports-color": { + "version": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "optional": true + }, + "tar": { + "version": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "dev": true + }, + "tar-pack": { + "version": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.3.0.tgz", + "integrity": "sha1-MJMYFkGPVa/E0hd1r91nIM7kXa4=", + "dev": true, + "optional": true, + "dependencies": { + "once": { + "version": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "dev": true, + "optional": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", + "dev": true, + "optional": true + } + } + }, + "tough-cookie": { + "version": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", + "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "dev": true, + "optional": true + }, + "tunnel-agent": { + "version": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", + "dev": true, + "optional": true + }, + "tweetnacl": { + "version": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + }, + "uid-number": { + "version": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", + "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=", + "dev": true, + "optional": true + }, + "util-deprecate": { + "version": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", + "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=", + "dev": true, + "optional": true + }, + "verror": { + "version": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", + "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", + "dev": true, + "optional": true + }, + "wide-align": { + "version": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.0.tgz", + "integrity": "sha1-QO3egCpx/qHwcNo+YtzaLnrdlq0=", + "dev": true, + "optional": true + }, + "wrappy": { + "version": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true, + "optional": true + } + } + }, + "fstream": { + "version": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "dev": true + }, + "function-bind": { + "version": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", + "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=", + "dev": true + }, + "gauge": { + "version": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true + }, + "gaze": { + "version": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", + "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", + "dev": true + }, + "generate-function": { + "version": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true + }, + "get-caller-file": { + "version": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "get-port": { + "version": "https://registry.npmjs.org/get-port/-/get-port-2.1.0.tgz", + "integrity": "sha1-h4P53OvR7qSVozThpqJR54iHqxo=", + "dev": true + }, + "get-set-props": { + "version": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz", + "integrity": "sha1-mYR1wXhEVobQsyJG2l3428++jqM=", + "dev": true + }, + "get-stdin": { + "version": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "get-stream": { + "version": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", + "dev": true + }, + "getpass": { + "version": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": { + "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "glob": { + "version": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "dev": true + }, + "glob-base": { + "version": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true + }, + "glob-parent": { + "version": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true + }, + "glob-stream": { + "version": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", + "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", + "dev": true, + "dependencies": { + "glob": { + "version": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", + "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", + "dev": true + }, + "minimatch": { + "version": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "dev": true + } + } + }, + "glob-watcher": { + "version": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", + "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", + "dev": true + }, + "glob2base": { + "version": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", + "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", + "dev": true + }, + "global-modules": { + "version": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", + "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", + "dev": true + }, + "global-prefix": { + "version": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", + "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", + "dev": true + }, + "globals": { + "version": "https://registry.npmjs.org/globals/-/globals-9.17.0.tgz", + "integrity": "sha1-DAymltm5u2lNLlRwvTd3fKrVAoY=", + "dev": true + }, + "globby": { + "version": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true + }, + "globule": { + "version": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", + "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", + "dev": true, + "dependencies": { + "glob": { + "version": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", + "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", + "dev": true + }, + "graceful-fs": { + "version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", + "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", + "dev": true + }, + "inherits": { + "version": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", + "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", + "dev": true + }, + "lodash": { + "version": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", + "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", + "dev": true + }, + "lru-cache": { + "version": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", + "dev": true + }, + "minimatch": { + "version": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", + "dev": true + } + } + }, + "glogg": { + "version": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", + "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "dev": true + }, + "got": { + "version": "https://registry.npmjs.org/got/-/got-5.7.1.tgz", + "integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + } + } + }, + "graceful-fs": { + "version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "graceful-readlink": { + "version": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, + "gulp": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", + "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", + "dev": true, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", + "dev": true + } + } + }, + "gulp-bro": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/gulp-bro/-/gulp-bro-1.0.2.tgz", + "integrity": "sha1-5W4GDzuf3hgJkCunsnkd8NnEK3A=", + "dev": true, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.10.tgz", + "integrity": "sha512-HQEnnoV404e0EtwB9yNiuk2tJ+egeVC8Y9QBAxzDg8DBJt4BzRp+yQuIb/t3FIWkSTmIi+sgx7yVv/ZM0GNoqw==", + "dev": true + }, + "string_decoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", + "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "gulp-livereload": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/gulp-livereload/-/gulp-livereload-3.8.1.tgz", + "integrity": "sha1-APdEstdJ0+njdGWJyKRKysd5tQ8=", + "dev": true, + "dependencies": { + "ansi-regex": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", + "dev": true + }, + "ansi-styles": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", + "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", + "dev": true + }, + "chalk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", + "dev": true + }, + "has-ansi": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", + "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", + "dev": true + }, + "strip-ansi": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", + "dev": true + }, + "supports-color": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", + "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", + "dev": true + } + } + }, + "gulp-postcss": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/gulp-postcss/-/gulp-postcss-6.4.0.tgz", + "integrity": "sha1-eKMuPIeqbNzsWuHJBeGW1HjoxdU=", + "dev": true + }, + "gulp-sass": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-3.1.0.tgz", + "integrity": "sha1-U9xLaKH13f5EJKtMJHZVJpqLdLc=", + "dev": true, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.10.tgz", + "integrity": "sha512-HQEnnoV404e0EtwB9yNiuk2tJ+egeVC8Y9QBAxzDg8DBJt4BzRp+yQuIb/t3FIWkSTmIi+sgx7yVv/ZM0GNoqw==", + "dev": true + }, + "string_decoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", + "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "gulp-sourcemaps": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.0.tgz", + "integrity": "sha1-fMzomaijv8oVk6M0jQ+/Qd0/UeU=", + "dev": true, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.10.tgz", + "integrity": "sha512-HQEnnoV404e0EtwB9yNiuk2tJ+egeVC8Y9QBAxzDg8DBJt4BzRp+yQuIb/t3FIWkSTmIi+sgx7yVv/ZM0GNoqw==", + "dev": true + }, + "string_decoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", + "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true + } + } + }, + "gulp-svgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/gulp-svgo/-/gulp-svgo-1.0.3.tgz", + "integrity": "sha1-9q0hnygc3JrD4ObBc9XHe7qM1pI=", + "dev": true, + "dependencies": { + "csso": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-2.0.0.tgz", + "integrity": "sha1-F4tDpEYhIhwndWCG9THgL0KQDug=", + "dev": true + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "js-yaml": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz", + "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=", + "dev": true + }, + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true + }, + "svgo": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.6.6.tgz", + "integrity": "sha1-s0CIkDbyD5tEdUMHfQ9Vc+0ETAg=", + "dev": true + } + } + }, + "gulp-uglify": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-2.1.2.tgz", + "integrity": "sha1-bbhbHQ7mPRgFhZK2WGSdZcLsRUE=", + "dev": true, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.10.tgz", + "integrity": "sha512-HQEnnoV404e0EtwB9yNiuk2tJ+egeVC8Y9QBAxzDg8DBJt4BzRp+yQuIb/t3FIWkSTmIi+sgx7yVv/ZM0GNoqw==", + "dev": true + }, + "string_decoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", + "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "dev": true, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "dev": true + }, + "readable-stream": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.10.tgz", + "integrity": "sha512-HQEnnoV404e0EtwB9yNiuk2tJ+egeVC8Y9QBAxzDg8DBJt4BzRp+yQuIb/t3FIWkSTmIi+sgx7yVv/ZM0GNoqw==", + "dev": true + }, + "string_decoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", + "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "gulplog": { + "version": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true + }, + "har-schema": { + "version": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", + "dev": true + }, + "har-validator": { + "version": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "dev": true + }, + "has": { + "version": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "dev": true + }, + "has-ansi": { + "version": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true + }, + "has-color": { + "version": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", + "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", + "dev": true + }, + "has-flag": { + "version": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "has-gulplog": { + "version": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true + }, + "has-unicode": { + "version": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "has-yarn": { + "version": "https://registry.npmjs.org/has-yarn/-/has-yarn-1.0.0.tgz", + "integrity": "sha1-ieJdtgS3Jcj1l2//Ct3JIbgopac=", + "dev": true + }, + "hash.js": { + "version": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz", + "integrity": "sha1-EzL/ABVsCg/92CNgE9B7d6BFFXM=", + "dev": true + }, + "hawk": { + "version": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dev": true + }, + "hmac-drbg": { + "version": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true + }, + "hoek": { + "version": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "dev": true + }, + "home-or-tmp": { + "version": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true + }, + "homedir-polyfill": { + "version": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", + "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "dev": true + }, + "hosted-git-info": { + "version": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.4.2.tgz", + "integrity": "sha1-AHa59GonBQbduq6lZJaJdGBhKmc=", + "dev": true + }, + "html-comment-regex": { + "version": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", + "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=", + "dev": true + }, + "htmlescape": { + "version": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "dev": true + }, + "http-errors": { + "version": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", + "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", + "dev": true + }, + "http-signature": { + "version": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "dev": true + }, + "https-browserify": { + "version": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "husky": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/husky/-/husky-0.13.4.tgz", + "integrity": "sha1-SHhcUCjeNFKlHEjBLE+UshJKFAc=", + "dev": true, + "dependencies": { + "normalize-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", + "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", + "dev": true + } + } + }, + "iconv-lite": { + "version": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=", + "dev": true + }, + "ieee754": { + "version": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "dev": true + }, + "ignore": { + "version": "https://registry.npmjs.org/ignore/-/ignore-3.3.0.tgz", + "integrity": "sha1-OBLSLL6RJfLCtJFXVaG4q9dFoAE=", + "dev": true + }, + "ignore-by-default": { + "version": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "immediate": { + "version": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" + }, + "imurmurhash": { + "version": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "in-publish": { + "version": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", + "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=", + "dev": true + }, + "indent-string": { + "version": "https://registry.npmjs.org/indent-string/-/indent-string-3.1.0.tgz", + "integrity": "sha1-CP9DNGAziDmbMp5rlTjcejz13n0=", + "dev": true + }, + "indexes-of": { + "version": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "indexof": { + "version": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true + }, + "inherits": { + "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", + "dev": true + }, + "inline-process-browser": { + "version": "https://registry.npmjs.org/inline-process-browser/-/inline-process-browser-1.0.0.tgz", + "integrity": "sha1-RqYbFT3TybFiSxoAYm7bT39BTyI=" + }, + "inline-source-map": { + "version": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "dependencies": { + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true + } + } + }, + "inquirer": { + "version": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "dependencies": { + "cli-cursor": { + "version": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true + }, + "figures": { + "version": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true + }, + "onetime": { + "version": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "restore-cursor": { + "version": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true + } + } + }, + "insert-module-globals": { + "version": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.1.tgz", + "integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + }, + "through2": { + "version": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "interpret": { + "version": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", + "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", + "dev": true + }, + "invariant": { + "version": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "dev": true + }, + "invert-kv": { + "version": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "irregular-plurals": { + "version": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.2.0.tgz", + "integrity": "sha1-OPKZg0uowAwwvpxVThNyaXUv86w=", + "dev": true + }, + "is-absolute": { + "version": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", + "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", + "dev": true + }, + "is-absolute-url": { + "version": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true + }, + "is-arrayish": { + "version": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true + }, + "is-buffer": { + "version": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "dev": true + }, + "is-builtin-module": { + "version": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true + }, + "is-ci": { + "version": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "dev": true + }, + "is-directory": { + "version": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-dotfile": { + "version": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.2.tgz", + "integrity": "sha1-LBMjg/ORmfjtwmjKAbmwB9IFzE0=", + "dev": true + }, + "is-equal-shallow": { + "version": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true + }, + "is-error": { + "version": "https://registry.npmjs.org/is-error/-/is-error-2.2.1.tgz", + "integrity": "sha1-aEqW2EB2V3yY9M20DG0mpRI78Zw=", + "dev": true + }, + "is-extendable": { + "version": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true + }, + "is-generator-fn": { + "version": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz", + "integrity": "sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=", + "dev": true + }, + "is-get-set-prop": { + "version": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz", + "integrity": "sha1-JzGHfk14pqae3M5rudaLB3nnYxI=", + "dev": true + }, + "is-glob": { + "version": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true + }, + "is-js-type": { + "version": "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz", + "integrity": "sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI=", + "dev": true + }, + "is-my-json-valid": { + "version": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", + "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", + "dev": true + }, + "is-npm": { + "version": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, + "is-number": { + "version": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true + }, + "is-obj": { + "version": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-obj-prop": { + "version": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz", + "integrity": "sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4=", + "dev": true + }, + "is-observable": { + "version": "https://registry.npmjs.org/is-observable/-/is-observable-0.2.0.tgz", + "integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=", + "dev": true + }, + "is-path-cwd": { + "version": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true + }, + "is-path-inside": { + "version": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "dev": true + }, + "is-plain-obj": { + "version": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-posix-bracket": { + "version": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-promise": { + "version": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-property": { + "version": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-proto-prop": { + "version": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-1.0.0.tgz", + "integrity": "sha1-s5UflcCJkk+11PzaZUKrPoPisiA=", + "dev": true + }, + "is-redirect": { + "version": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true + }, + "is-relative": { + "version": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", + "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", + "dev": true + }, + "is-resolvable": { + "version": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", + "dev": true + }, + "is-retry-allowed": { + "version": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "dev": true + }, + "is-stream": { + "version": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-svg": { + "version": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", + "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", + "dev": true + }, + "is-typedarray": { + "version": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unc-path": { + "version": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", + "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", + "dev": true + }, + "is-url": { + "version": "https://registry.npmjs.org/is-url/-/is-url-1.2.2.tgz", + "integrity": "sha1-SYkFpZO/R8wtnn9zg3K792lsfyY=", + "dev": true + }, + "is-utf8": { + "version": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "dev": true + }, + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isexe": { + "version": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "isstream": { + "version": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "jest-diff": { + "version": "https://registry.npmjs.org/jest-diff/-/jest-diff-18.1.0.tgz", + "integrity": "sha1-T/eedN2YjBORlbNl3GXYf2BvSAM=", + "dev": true + }, + "jest-file-exists": { + "version": "https://registry.npmjs.org/jest-file-exists/-/jest-file-exists-17.0.0.tgz", + "integrity": "sha1-f2Prc6HEOhP0Yb4mF2i0WvLN0Wk=", + "dev": true + }, + "jest-matcher-utils": { + "version": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-18.1.0.tgz", + "integrity": "sha1-GsRlGVXuKmDO8ef8yYzf13PA+TI=", + "dev": true + }, + "jest-mock": { + "version": "https://registry.npmjs.org/jest-mock/-/jest-mock-18.0.0.tgz", + "integrity": "sha1-XCSIRuoz+lWLUm9TEqtKZ2XkibM=", + "dev": true + }, + "jest-snapshot": { + "version": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-18.1.0.tgz", + "integrity": "sha1-VbltLuY5ybznb4fyo/1Atxx6WRY=", + "dev": true + }, + "jest-util": { + "version": "https://registry.npmjs.org/jest-util/-/jest-util-18.1.0.tgz", + "integrity": "sha1-OpnDIRSrF/hL4JQ4JScAbm1L/Go=", + "dev": true + }, + "jodid25519": { + "version": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", + "integrity": "sha1-BtSRIlUJNBlHfUJWM2BuDpB4KWc=", + "dev": true, + "optional": true + }, + "js-base64": { + "version": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz", + "integrity": "sha1-8OgK4DmkvWVLXygfyT8EqRSn/M4=", + "dev": true + }, + "js-tokens": { + "version": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz", + "integrity": "sha1-COnxMkhKLEWjCQfp3E1VZ7fxFNc=", + "dev": true + }, + "js-types": { + "version": "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz", + "integrity": "sha1-0kLmSU7Vcq08koCfyL7X92h8vwM=", + "dev": true + }, + "js-yaml": { + "version": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", + "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", + "dev": true, + "dependencies": { + "esprima": { + "version": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + } + } + }, + "jsbn": { + "version": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "jsesc": { + "version": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + }, + "json-schema": { + "version": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-stable-stringify": { + "version": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "dev": true + }, + "json-stringify-safe": { + "version": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "jsonify": { + "version": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonparse": { + "version": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.0.tgz", + "integrity": "sha1-hfwkWx2SWazGlBlguQWt9k594Og=", + "dev": true + }, + "jsonpointer": { + "version": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "JSONStream": { + "version": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz", + "integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=", + "dev": true + }, + "jsprim": { + "version": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", + "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", + "dev": true, + "dependencies": { + "assert-plus": { + "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "jstransform": { + "version": "https://registry.npmjs.org/jstransform/-/jstransform-3.0.0.tgz", + "integrity": "sha1-olkats7o2XvzvoMNv6IxO4fNZAs=" + }, + "kind-of": { + "version": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.0.tgz", + "integrity": "sha1-tYq+TVwEStM3JqjBUltIz4kb/wc=", + "dev": true + }, + "labeled-stream-splicer": { + "version": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz", + "integrity": "sha1-pS4dE4AkwAuGscDJH2d5GLiuClk=", + "dev": true + }, + "last-line-stream": { + "version": "https://registry.npmjs.org/last-line-stream/-/last-line-stream-1.0.0.tgz", + "integrity": "sha1-0bZNafhv8kry0EiDos7uFFIKVgA=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + }, + "through2": { + "version": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "latest-version": { + "version": "https://registry.npmjs.org/latest-version/-/latest-version-2.0.0.tgz", + "integrity": "sha1-VvjWE5YghHuAF/jx9NeOIRMkFos=", + "dev": true + }, + "lazy-cache": { + "version": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + }, + "lazy-req": { + "version": "https://registry.npmjs.org/lazy-req/-/lazy-req-1.1.0.tgz", + "integrity": "sha1-va6+rTD42CQDnODOFJ1Nqge6H6w=", + "dev": true + }, + "lcid": { + "version": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true + }, + "levn": { + "version": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true + }, + "lexical-scope": { + "version": "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz", + "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", + "dev": true + }, + "lie": { + "version": "https://registry.npmjs.org/lie/-/lie-3.0.2.tgz", + "integrity": "sha1-/9oh17uibzd8rYZdNkmy/Izjn+o=" + }, + "liftoff": { + "version": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz", + "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=", + "dev": true + }, + "lint-staged": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-3.6.0.tgz", + "integrity": "sha1-zajwvvFueSjMFLc1GGrhLNZiWZw=", + "dev": true, + "dependencies": { + "cosmiconfig": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-1.1.0.tgz", + "integrity": "sha1-DeoPmATv37kp+7GxiOJVU+oFPTc=", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true + }, + "execa": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.6.3.tgz", + "integrity": "sha1-V7aaWU8IF1nGnlNw8NF7nLEWWP4=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "listr": { + "version": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz", + "integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=", + "dev": true, + "dependencies": { + "figures": { + "version": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true + }, + "indent-string": { + "version": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true + } + } + }, + "listr-silent-renderer": { + "version": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", + "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", + "dev": true + }, + "listr-update-renderer": { + "version": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz", + "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=", + "dev": true, + "dependencies": { + "figures": { + "version": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true + } + } + }, + "listr-verbose-renderer": { + "version": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.4.0.tgz", + "integrity": "sha1-RNwBuww0oDxXIVTU0Izemx3FYg8=", + "dev": true, + "dependencies": { + "cli-cursor": { + "version": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true + }, + "figures": { + "version": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true + }, + "onetime": { + "version": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "restore-cursor": { + "version": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true + } + } + }, + "livereload-js": { + "version": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.2.2.tgz", + "integrity": "sha1-bIclfmSKtHW8JOoldFftzB+NC8I=", + "dev": true + }, + "load-json-file": { + "version": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true + }, + "localforage": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.5.0.tgz", + "integrity": "sha1-a5lOGbVmEfqF3zmS3zl6xKtm6BU=" + }, + "locate-path": { + "version": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true + }, + "lodash": { + "version": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "lodash._baseassign": { + "version": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "dev": true + }, + "lodash._basecopy": { + "version": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basetostring": { + "version": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", + "dev": true + }, + "lodash._basevalues": { + "version": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", + "dev": true + }, + "lodash._bindcallback": { + "version": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", + "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=", + "dev": true + }, + "lodash._createassigner": { + "version": "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz", + "integrity": "sha1-g4pbri/aymOsIt7o4Z+k5taXCxE=", + "dev": true + }, + "lodash._getnative": { + "version": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash._reescape": { + "version": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", + "dev": true + }, + "lodash._reevaluate": { + "version": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash._root": { + "version": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", + "dev": true + }, + "lodash.assign": { + "version": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz", + "integrity": "sha1-POnwI0tLIiPilrj6CsH+6OvKZPo=", + "dev": true + }, + "lodash.assignwith": { + "version": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", + "integrity": "sha1-EnqX8CrcQXUalU0ksN4X4QDgOOs=", + "dev": true + }, + "lodash.camelcase": { + "version": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, + "lodash.chunk": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", + "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=", + "dev": true + }, + "lodash.clonedeep": { + "version": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.cond": { + "version": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", + "dev": true + }, + "lodash.debounce": { + "version": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "lodash.difference": { + "version": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "dev": true + }, + "lodash.escape": { + "version": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "dev": true + }, + "lodash.flatten": { + "version": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "lodash.isarguments": { + "version": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.isempty": { + "version": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=", + "dev": true + }, + "lodash.isequal": { + "version": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true + }, + "lodash.isplainobject": { + "version": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "lodash.isstring": { + "version": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", + "dev": true + }, + "lodash.kebabcase": { + "version": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", + "dev": true + }, + "lodash.keys": { + "version": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true + }, + "lodash.mapvalues": { + "version": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", + "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", + "dev": true + }, + "lodash.memoize": { + "version": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "lodash.mergewith": { + "version": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz", + "integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=", + "dev": true + }, + "lodash.pick": { + "version": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", + "dev": true + }, + "lodash.restparam": { + "version": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", + "dev": true + }, + "lodash.snakecase": { + "version": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=", + "dev": true + }, + "lodash.template": { + "version": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "dev": true + }, + "lodash.templatesettings": { + "version": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "dev": true + }, + "lodash.uniq": { + "version": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "lodash.upperfirst": { + "version": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=", + "dev": true + }, + "log-symbols": { + "version": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true + }, + "log-update": { + "version": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz", + "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=", + "dev": true, + "dependencies": { + "cli-cursor": { + "version": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true + }, + "onetime": { + "version": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "restore-cursor": { + "version": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true + } + } + }, + "longest": { + "version": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loose-envify": { + "version": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "dev": true + }, + "loud-rejection": { + "version": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true + }, + "lowercase-keys": { + "version": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", + "dev": true + }, + "lru-cache": { + "version": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", + "dev": true + }, + "macaddress": { + "version": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz", + "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=", + "dev": true + }, + "make-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz", + "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=", + "dev": true + }, + "make-error": { + "version": "https://registry.npmjs.org/make-error/-/make-error-1.2.3.tgz", + "integrity": "sha1-bEQC33MuCXesb691SlB0s9Kx0Z0=", + "dev": true + }, + "make-error-cause": { + "version": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz", + "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=", + "dev": true + }, + "map-cache": { + "version": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "map-stream": { + "version": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", + "dev": true + }, + "matcher": { + "version": "https://registry.npmjs.org/matcher/-/matcher-0.1.2.tgz", + "integrity": "sha1-7yDL3mTCTFDMYa9bg+4LG4/wAQE=", + "dev": true + }, + "math-expression-evaluator": { + "version": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", + "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=", + "dev": true + }, + "max-timeout": { + "version": "https://registry.npmjs.org/max-timeout/-/max-timeout-1.0.0.tgz", + "integrity": "sha1-to9povmeC0dv1Msj4gWcp1BxXh8=", + "dev": true + }, + "md5-hex": { + "version": "https://registry.npmjs.org/md5-hex/-/md5-hex-2.0.0.tgz", + "integrity": "sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM=", + "dev": true + }, + "md5-o-matic": { + "version": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz", + "integrity": "sha1-givM1l4RfFFPqxdrJZRdVBAKA8M=", + "dev": true + }, + "media-typer": { + "version": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "meow": { + "version": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "dependencies": { + "find-up": { + "version": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true + }, + "load-json-file": { + "version": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true + }, + "minimist": { + "version": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "path-exists": { + "version": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true + }, + "path-type": { + "version": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true + }, + "read-pkg": { + "version": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true + }, + "read-pkg-up": { + "version": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true + }, + "strip-bom": { + "version": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true + } + } + }, + "micromatch": { + "version": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true + }, + "miller-rabin": { + "version": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.0.tgz", + "integrity": "sha1-SmL7HUKTPAVYOYL0xxb2+55sbT0=", + "dev": true + }, + "mime-db": { + "version": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz", + "integrity": "sha1-gg9XIpa70g7CXtVeW13oaeVDbrE=", + "dev": true + }, + "mime-types": { + "version": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz", + "integrity": "sha1-pOv1BkCUVpI3uM9wBGd20J/JKu0=", + "dev": true + }, + "mimic-fn": { + "version": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "mini-lr": { + "version": "https://registry.npmjs.org/mini-lr/-/mini-lr-0.1.9.tgz", + "integrity": "sha1-AhmdJzR5U9H9HW297UJh8Yey0PY=", + "dev": true + }, + "minimalistic-assert": { + "version": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", + "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "dev": true + }, + "minimist": { + "version": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true + }, + "module-deps": { + "version": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz", + "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + }, + "through2": { + "version": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "ms": { + "version": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz", + "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=", + "dev": true + }, + "multimatch": { + "version": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "dev": true + }, + "multipipe": { + "version": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dev": true, + "dependencies": { + "duplexer2": { + "version": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true + } + } + }, + "mute-stream": { + "version": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + }, + "nan": { + "version": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", + "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=", + "dev": true + }, + "natives": { + "version": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz", + "integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=", + "dev": true + }, + "natural-compare": { + "version": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node-gyp": { + "version": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.1.tgz", + "integrity": "sha1-GVYQZ/8YVGSt7UeCEmgfR/1XjLw=", + "dev": true + }, + "node-sass": { + "version": "https://registry.npmjs.org/node-sass/-/node-sass-4.5.2.tgz", + "integrity": "sha1-QBL6K9EpsdY2URfojZ2gUA2Z2mQ=", + "dev": true, + "dependencies": { + "cross-spawn": { + "version": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "dev": true + }, + "gaze": { + "version": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz", + "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=", + "dev": true + }, + "globule": { + "version": "https://registry.npmjs.org/globule/-/globule-1.1.0.tgz", + "integrity": "sha1-xJNS5NwYPYWJPuglOF65lLtt9F8=", + "dev": true + }, + "lodash": { + "version": "https://registry.npmjs.org/lodash/-/lodash-4.16.6.tgz", + "integrity": "sha1-0iyaxmAojzhD4Wun0rXQbMon13c=", + "dev": true + }, + "lodash.assign": { + "version": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "dev": true + } + } + }, + "node-status-codes": { + "version": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", + "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=", + "dev": true + }, + "nopt": { + "version": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true + }, + "normalize-package-data": { + "version": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.8.tgz", + "integrity": "sha1-2Bntoqne29H/pWPqQHHZNngilbs=", + "dev": true + }, + "normalize-path": { + "version": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true + }, + "normalize-range": { + "version": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "normalize-url": { + "version": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true + }, + "npm-path": { + "version": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.3.tgz", + "integrity": "sha1-Fc/04ciaONp39W9gVbJPl137K74=", + "dev": true + }, + "npm-run-path": { + "version": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true + }, + "npm-which": { + "version": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz", + "integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=", + "dev": true + }, + "npmlog": { + "version": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.0.tgz", + "integrity": "sha1-3Fm+6F9k8A7UJO+yrweD3yXRwLU=", + "dev": true + }, + "num2fraction": { + "version": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "number-is-nan": { + "version": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true + }, + "obj-props": { + "version": "https://registry.npmjs.org/obj-props/-/obj-props-1.1.0.tgz", + "integrity": "sha1-YmMT+qRCvv1KROmgLDy2vek3tRE=", + "dev": true + }, + "object-assign": { + "version": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-keys": { + "version": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=" + }, + "object.omit": { + "version": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true + }, + "observable-to-promise": { + "version": "https://registry.npmjs.org/observable-to-promise/-/observable-to-promise-0.4.0.tgz", + "integrity": "sha1-KK/nFkUwjy1B1x9HrT/s4aN35Ss=", + "dev": true + }, + "on-finished": { + "version": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true + }, + "once": { + "version": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true + }, + "onetime": { + "version": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true + }, + "option-chain": { + "version": "https://registry.npmjs.org/option-chain/-/option-chain-0.1.1.tgz", + "integrity": "sha1-6bgR4AbxwPVIAvKClb/Ilw+Nz70=", + "dev": true + }, + "optionator": { + "version": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "dependencies": { + "wordwrap": { + "version": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, + "ora": { + "version": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz", + "integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=", + "dev": true, + "dependencies": { + "cli-cursor": { + "version": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true + }, + "cli-spinners": { + "version": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz", + "integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=", + "dev": true + }, + "onetime": { + "version": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "restore-cursor": { + "version": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true + } + } + }, + "orchestrator": { + "version": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", + "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", + "dev": true + }, + "ordered-read-streams": { + "version": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", + "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=", + "dev": true + }, + "os-browserify": { + "version": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.1.2.tgz", + "integrity": "sha1-ScoCk+CxlZCl9d4Qx/JlphfY/lQ=", + "dev": true + }, + "os-homedir": { + "version": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true + }, + "os-tmpdir": { + "version": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", + "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", + "dev": true + }, + "outpipe": { + "version": "https://registry.npmjs.org/outpipe/-/outpipe-1.1.1.tgz", + "integrity": "sha1-UM+GFjZeh+Ax4ppeyTOaPaRyX6I=", + "dev": true + }, + "p-finally": { + "version": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", + "dev": true + }, + "p-locate": { + "version": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true + }, + "p-map": { + "version": "https://registry.npmjs.org/p-map/-/p-map-1.1.1.tgz", + "integrity": "sha1-BfXkrpegaDcbwqXMhr+9vBnErno=", + "dev": true + }, + "package-hash": { + "version": "https://registry.npmjs.org/package-hash/-/package-hash-1.2.0.tgz", + "integrity": "sha1-AD5WzVe3NqbtYRTMK4FUJnJ3DkQ=", + "dev": true, + "dependencies": { + "md5-hex": { + "version": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", + "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", + "dev": true + } + } + }, + "package-json": { + "version": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz", + "integrity": "sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs=", + "dev": true + }, + "pako": { + "version": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + }, + "parents": { + "version": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true + }, + "parse-asn1": { + "version": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", + "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "dev": true + }, + "parse-filepath": { + "version": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz", + "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", + "dev": true + }, + "parse-glob": { + "version": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true + }, + "parse-json": { + "version": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true + }, + "parse-ms": { + "version": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz", + "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=", + "dev": true + }, + "parse-passwd": { + "version": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parseurl": { + "version": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", + "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=", + "dev": true + }, + "path-browserify": { + "version": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "path-exists": { + "version": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-platform": { + "version": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "path-root": { + "version": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true + }, + "path-root-regex": { + "version": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, + "path-type": { + "version": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true + }, + "pause-stream": { + "version": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "dev": true + }, + "pbkdf2": { + "version": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.9.tgz", + "integrity": "sha1-8sSyWmAAWLPDdzwIbDfbvuH/5pM=", + "dev": true + }, + "performance-now": { + "version": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", + "dev": true + }, + "pify": { + "version": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true + }, + "pjs-problems": { + "version": "git+https://github.com/practicejavascript/pjs-problems.git#0823cc1cffb999352e3f0caed295df8633f13916" + }, + "pkg-conf": { + "version": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.0.0.tgz", + "integrity": "sha1-BxyHZQQDvM+5xif1h1G/5HwGcnk=", + "dev": true + }, + "pkg-dir": { + "version": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, + "dependencies": { + "find-up": { + "version": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true + }, + "path-exists": { + "version": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true + } + } + }, + "pkg-up": { + "version": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", + "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", + "dev": true, + "dependencies": { + "find-up": { + "version": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true + }, + "path-exists": { + "version": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true + } + } + }, + "plur": { + "version": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", + "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", + "dev": true + }, + "pluralize": { + "version": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "postcss": { + "version": "https://registry.npmjs.org/postcss/-/postcss-5.2.17.tgz", + "integrity": "sha1-z09Ze4ZNZcikkrLqvp1wbIecOIs=", + "dev": true, + "dependencies": { + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true + } + } + }, + "postcss-calc": { + "version": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", + "dev": true + }, + "postcss-colormin": { + "version": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", + "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", + "dev": true + }, + "postcss-convert-values": { + "version": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", + "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", + "dev": true + }, + "postcss-discard-comments": { + "version": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", + "dev": true + }, + "postcss-discard-duplicates": { + "version": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", + "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", + "dev": true + }, + "postcss-discard-empty": { + "version": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", + "dev": true + }, + "postcss-discard-overridden": { + "version": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", + "dev": true + }, + "postcss-discard-unused": { + "version": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", + "dev": true + }, + "postcss-filter-plugins": { + "version": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz", + "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=", + "dev": true + }, + "postcss-load-config": { + "version": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz", + "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=", + "dev": true + }, + "postcss-load-options": { + "version": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz", + "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=", + "dev": true + }, + "postcss-load-plugins": { + "version": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz", + "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=", + "dev": true + }, + "postcss-merge-idents": { + "version": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", + "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", + "dev": true + }, + "postcss-merge-longhand": { + "version": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", + "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", + "dev": true + }, + "postcss-merge-rules": { + "version": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", + "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=", + "dev": true + }, + "postcss-message-helpers": { + "version": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", + "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=", + "dev": true + }, + "postcss-minify-font-values": { + "version": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", + "dev": true + }, + "postcss-minify-gradients": { + "version": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", + "dev": true + }, + "postcss-minify-params": { + "version": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", + "dev": true + }, + "postcss-minify-selectors": { + "version": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", + "dev": true + }, + "postcss-normalize-charset": { + "version": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", + "dev": true + }, + "postcss-normalize-url": { + "version": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", + "dev": true + }, + "postcss-ordered-values": { + "version": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", + "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", + "dev": true + }, + "postcss-reduce-idents": { + "version": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", + "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", + "dev": true + }, + "postcss-reduce-initial": { + "version": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", + "dev": true + }, + "postcss-reduce-transforms": { + "version": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", + "dev": true + }, + "postcss-selector-parser": { + "version": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "dev": true + }, + "postcss-svgo": { + "version": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", + "dev": true + }, + "postcss-unique-selectors": { + "version": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", + "dev": true + }, + "postcss-value-parser": { + "version": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", + "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=", + "dev": true + }, + "postcss-zindex": { + "version": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", + "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", + "dev": true + }, + "prelude-ls": { + "version": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prepend-http": { + "version": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "preserve": { + "version": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "pretty-format": { + "version": "https://registry.npmjs.org/pretty-format/-/pretty-format-18.1.0.tgz", + "integrity": "sha1-+2Wob3p/kZSWPu6RhlwbzxA54oQ=", + "dev": true + }, + "pretty-hrtime": { + "version": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "dev": true + }, + "pretty-ms": { + "version": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", + "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=", + "dev": true, + "dependencies": { + "plur": { + "version": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", + "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=", + "dev": true + } + } + }, + "private": { + "version": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", + "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=" + }, + "process": { + "version": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "progress": { + "version": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "proto-props": { + "version": "https://registry.npmjs.org/proto-props/-/proto-props-0.2.1.tgz", + "integrity": "sha1-XgHcJnWg3pq/p255nfozTW9IP0s=", + "dev": true + }, + "pseudomap": { + "version": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "public-encrypt": { + "version": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", + "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "dev": true + }, + "punycode": { + "version": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "q": { + "version": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", + "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=", + "dev": true + }, + "qs": { + "version": "https://registry.npmjs.org/qs/-/qs-2.2.5.tgz", + "integrity": "sha1-EIirr53MCuWuRbcJ5sa1iIsjkjw=", + "dev": true + }, + "query-string": { + "version": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true + }, + "querystring": { + "version": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randomatic": { + "version": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.6.tgz", + "integrity": "sha1-EQ3Kv/OX6dz/fAeJzMCkmt8exbs=", + "dev": true + }, + "randombytes": { + "version": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.3.tgz", + "integrity": "sha1-Z0yZdgkBw8QRJ3GjHlIdw0nMCew=", + "dev": true + }, + "raw-body": { + "version": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz", + "integrity": "sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q=", + "dev": true, + "dependencies": { + "bytes": { + "version": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", + "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=", + "dev": true + } + } + }, + "rc": { + "version": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", + "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", + "dev": true, + "dependencies": { + "minimist": { + "version": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "read-all-stream": { + "version": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", + "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + } + } + }, + "read-only-stream": { + "version": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + } + } + }, + "read-pkg": { + "version": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true + }, + "read-pkg-up": { + "version": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=" + }, + "readdirp": { + "version": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + } + } + }, + "readline2": { + "version": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true + }, + "recast": { + "version": "https://registry.npmjs.org/recast/-/recast-0.10.43.tgz", + "integrity": "sha1-uV1Q9tYHYaX2JS4V2AZ4FoSRzn8=", + "dependencies": { + "esprima-fb": { + "version": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz", + "integrity": "sha1-Q761fsJujPI3092LM+QlM1d/Jlk=" + }, + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=" + } + } + }, + "rechoir": { + "version": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true + }, + "redent": { + "version": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "dependencies": { + "indent-string": { + "version": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true + } + } + }, + "reduce-css-calc": { + "version": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", + "dev": true + }, + "reduce-function-call": { + "version": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", + "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", + "dev": true + }, + "regenerate": { + "version": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz", + "integrity": "sha1-0ZQcZ7rUN+G+dkM63Vs4X5WxkmA=", + "dev": true + }, + "regenerator-runtime": { + "version": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "dev": true + }, + "regenerator-transform": { + "version": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.9.11.tgz", + "integrity": "sha1-On0GdSDLe3F2dp61/4aGkb7+EoM=", + "dev": true + }, + "regex-cache": { + "version": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", + "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", + "dev": true + }, + "regexpu-core": { + "version": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true + }, + "registry-auth-token": { + "version": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz", + "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=", + "dev": true + }, + "registry-url": { + "version": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true + }, + "regjsgen": { + "version": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true + }, + "remove-trailing-separator": { + "version": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz", + "integrity": "sha1-YV67lq9VlVLUv0BXyENtSGq2PMQ=", + "dev": true + }, + "repeat-element": { + "version": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true + }, + "replace-ext": { + "version": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "req-all": { + "version": "https://registry.npmjs.org/req-all/-/req-all-1.0.0.tgz", + "integrity": "sha1-0ShWlFHDQLQyQJxlbPFmJgzSYo0=", + "dev": true + }, + "request": { + "version": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "dev": true, + "dependencies": { + "qs": { + "version": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "dev": true + }, + "tunnel-agent": { + "version": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true + }, + "uuid": { + "version": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", + "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=", + "dev": true + } + } + }, + "require-directory": { + "version": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", + "dev": true + }, + "require-main-filename": { + "version": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "require-precompiled": { + "version": "https://registry.npmjs.org/require-precompiled/-/require-precompiled-0.1.0.tgz", + "integrity": "sha1-WhtS63Dr7UPrmC6XTIWrWVceVvo=", + "dev": true + }, + "require-uncached": { + "version": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "dependencies": { + "resolve-from": { + "version": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + } + } + }, + "resolve": { + "version": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz", + "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=", + "dev": true + }, + "resolve-cwd": { + "version": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-1.0.0.tgz", + "integrity": "sha1-Tq7qQe0EDRcCRX32SkKysH0kb58=", + "dev": true + }, + "resolve-dir": { + "version": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", + "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", + "dev": true + }, + "resolve-from": { + "version": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", + "dev": true + }, + "resolve-url": { + "version": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "restore-cursor": { + "version": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true + }, + "right-align": { + "version": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true + }, + "rimraf": { + "version": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "dev": true + }, + "ripemd160": { + "version": "https://registry.npmjs.org/ripemd160/-/ripemd160-1.0.1.tgz", + "integrity": "sha1-k6S71JQrxXS2mo+lfHHeEOzKfW4=", + "dev": true + }, + "rollup": { + "version": "0.41.6", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.41.6.tgz", + "integrity": "sha1-4NBUl4d6OYwQTYFtJzOnGKepTio=", + "dev": true + }, + "rollup-stream": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/rollup-stream/-/rollup-stream-1.19.0.tgz", + "integrity": "sha1-ircNOXDY7IUp8cHXpojY1l+QWZo=", + "dev": true + }, + "run-async": { + "version": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true + }, + "rx-lite": { + "version": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "rxjs": { + "version": "https://registry.npmjs.org/rxjs/-/rxjs-5.3.1.tgz", + "integrity": "sha1-nsyeciJH5PRJDTCoeFd6N0D9DLc=", + "dev": true, + "dependencies": { + "symbol-observable": { + "version": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz", + "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=", + "dev": true + } + } + }, + "safe-buffer": { + "version": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", + "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=", + "dev": true + }, + "sass-graph": { + "version": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.2.tgz", + "integrity": "sha1-9NbJW1RuoqCdFBdtD8GgfuK0g1Q=", + "dev": true, + "dependencies": { + "camelcase": { + "version": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "cliui": { + "version": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true + }, + "find-up": { + "version": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true + }, + "load-json-file": { + "version": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true + }, + "path-exists": { + "version": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true + }, + "path-type": { + "version": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true + }, + "read-pkg": { + "version": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true + }, + "read-pkg-up": { + "version": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true + }, + "strip-bom": { + "version": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true + }, + "yargs": { + "version": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", + "dev": true + } + } + }, + "sax": { + "version": "https://registry.npmjs.org/sax/-/sax-1.2.2.tgz", + "integrity": "sha1-/YYxojvHgmvvXYcb24c3jJVkeCg=", + "dev": true + }, + "scss-tokenizer": { + "version": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.1.tgz", + "integrity": "sha1-B8DMV3u3q00I/ZABha2/S8hEFB0=", + "dev": true, + "dependencies": { + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true + } + } + }, + "semver": { + "version": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + }, + "semver-diff": { + "version": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true + }, + "sequencify": { + "version": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", + "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=", + "dev": true + }, + "set-blocking": { + "version": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-immediate-shim": { + "version": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "sha.js": { + "version": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz", + "integrity": "sha1-NwaMLEdra69ALRSknGf1l5IfY08=", + "dev": true + }, + "shasum": { + "version": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true + }, + "shebang-command": { + "version": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true + }, + "shebang-regex": { + "version": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shell-quote": { + "version": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "dev": true + }, + "shelljs": { + "version": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.7.tgz", + "integrity": "sha1-svXHfvlxSPS09uImguELuoZnz/E=", + "dev": true + }, + "sigmund": { + "version": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "signal-exit": { + "version": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "slice-ansi": { + "version": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "slide": { + "version": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", + "dev": true + }, + "sntp": { + "version": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dev": true + }, + "sort-keys": { + "version": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true + }, + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.1.31.tgz", + "integrity": "sha1-n3BNDWnZ4TioG63267T94z0VHGE=" + }, + "source-map-resolve": { + "version": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz", + "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=", + "dev": true + }, + "source-map-support": { + "version": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz", + "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", + "dev": true, + "dependencies": { + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true + } + } + }, + "source-map-url": { + "version": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz", + "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=", + "dev": true + }, + "sparkles": { + "version": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true + }, + "spdx-correct": { + "version": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true + }, + "spdx-expression-parse": { + "version": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "split": { + "version": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "dev": true + }, + "sprintf-js": { + "version": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.0.tgz", + "integrity": "sha1-/yo+T9BEl1Vf7Zezmg/YL6+zozw=", + "dev": true, + "dependencies": { + "assert-plus": { + "version": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "stack-utils": { + "version": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=", + "dev": true + }, + "staged-git-files": { + "version": "https://registry.npmjs.org/staged-git-files/-/staged-git-files-0.0.4.tgz", + "integrity": "sha1-15fhtVHKemOd7AI33G60u5vhfTU=", + "dev": true + }, + "static-eval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-1.1.1.tgz", + "integrity": "sha1-yoEwIQNUzxPZpyK8fpI3eEV7sZI=", + "dev": true + }, + "statuses": { + "version": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + }, + "stdout-stream": { + "version": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz", + "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + } + } + }, + "stream-browserify": { + "version": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + } + } + }, + "stream-combiner": { + "version": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "dev": true + }, + "stream-combiner2": { + "version": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + } + } + }, + "stream-consume": { + "version": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", + "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=", + "dev": true + }, + "stream-http": { + "version": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.0.tgz", + "integrity": "sha1-zsH047SUvEqBtFGAiXD4sgtO1fY=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + } + } + }, + "stream-splicer": { + "version": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "dependencies": { + "isarray": { + "version": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", + "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", + "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "dev": true + } + } + }, + "stream-to-observable": { + "version": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz", + "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=", + "dev": true + }, + "strict-uri-encode": { + "version": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + }, + "string_decoder": { + "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "string-width": { + "version": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true + }, + "stringstream": { + "version": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "dev": true + }, + "strip-ansi": { + "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true + }, + "strip-bom": { + "version": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-bom-buf": { + "version": "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz", + "integrity": "sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI=", + "dev": true + }, + "strip-bom-string": { + "version": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", + "dev": true + }, + "strip-eof": { + "version": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true + }, + "strip-json-comments": { + "version": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "subarg": { + "version": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", + "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", + "dev": true, + "dependencies": { + "minimist": { + "version": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "supports-color": { + "version": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true + }, + "svgo": { + "version": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", + "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", + "dev": true + }, + "symbol-observable": { + "version": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz", + "integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=", + "dev": true + }, + "syntax-error": { + "version": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.3.0.tgz", + "integrity": "sha1-HtkmbE1AvnXcVb+bsct3Biu5bKE=", + "dev": true, + "dependencies": { + "acorn": { + "version": "https://registry.npmjs.org/acorn/-/acorn-4.0.11.tgz", + "integrity": "sha1-7c2jvZN+dVZBDULtWGD2c5nHlMA=", + "dev": true + } + } + }, + "table": { + "version": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": { + "version": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", + "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=", + "dev": true + } + } + }, + "tar": { + "version": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "dev": true + }, + "term-size": { + "version": "https://registry.npmjs.org/term-size/-/term-size-0.1.1.tgz", + "integrity": "sha1-hzYLljlsq1dgljcUzaDQy+7K2co=", + "dev": true, + "dependencies": { + "execa": { + "version": "https://registry.npmjs.org/execa/-/execa-0.4.0.tgz", + "integrity": "sha1-TrZGejaglfq7KXD/nV4/t7zm68M=", + "dev": true + }, + "npm-run-path": { + "version": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz", + "integrity": "sha1-9cMr9ZX+ga6Sfa7FLoL4sACsPI8=", + "dev": true + }, + "path-key": { + "version": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz", + "integrity": "sha1-XVPVeAGWRsDWiADbThRua9wqx68=", + "dev": true + } + } + }, + "text-table": { + "version": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "the-argv": { + "version": "https://registry.npmjs.org/the-argv/-/the-argv-1.0.0.tgz", + "integrity": "sha1-AIRwUAVzDdhNt1UlPJMa45jblSI=", + "dev": true + }, + "through": { + "version": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "through2": { + "version": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=" + }, + "tildify": { + "version": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", + "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "dev": true + }, + "time-require": { + "version": "https://registry.npmjs.org/time-require/-/time-require-0.1.2.tgz", + "integrity": "sha1-+eEss3D8JgXhFARYK6VO9corLZg=", + "dev": true, + "dependencies": { + "ansi-styles": { + "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", + "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", + "dev": true + }, + "chalk": { + "version": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", + "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "dev": true + }, + "parse-ms": { + "version": "https://registry.npmjs.org/parse-ms/-/parse-ms-0.1.2.tgz", + "integrity": "sha1-3T+iXtbC78e93hKtm0bBY6opIk4=", + "dev": true + }, + "pretty-ms": { + "version": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-0.2.2.tgz", + "integrity": "sha1-2oeaaC/zOjcBEEbxPWJ/Z8c7hPY=", + "dev": true + }, + "strip-ansi": { + "version": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", + "dev": true + } + } + }, + "time-stamp": { + "version": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.0.1.tgz", + "integrity": "sha1-n0vSNVnJNllm8zAtu6KwfGuZsVE=", + "dev": true + }, + "timed-out": { + "version": "https://registry.npmjs.org/timed-out/-/timed-out-3.1.3.tgz", + "integrity": "sha1-lYYL/MXHbCd/j4Mm/Q9bLiDrohc=", + "dev": true + }, + "timers-browserify": { + "version": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true + }, + "to-arraybuffer": { + "version": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "tough-cookie": { + "version": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", + "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "dev": true + }, + "trim-newlines": { + "version": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "trim-right": { + "version": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "tryit": { + "version": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", + "dev": true + }, + "tty-browserify": { + "version": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "tweetnacl": { + "version": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "optional": true + }, + "type-check": { + "version": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true + }, + "type-detect": { + "version": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", + "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=" + }, + "type-is": { + "version": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", + "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", + "dev": true + }, + "typedarray": { + "version": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uglify-js": { + "version": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.22.tgz", + "integrity": "sha1-1Uk0d4qNoUkD+imjJvskwKtRoaA=", + "dev": true, + "dependencies": { + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true + } + } + }, + "uglify-save-license": { + "version": "https://registry.npmjs.org/uglify-save-license/-/uglify-save-license-0.4.1.tgz", + "integrity": "sha1-lXJsF8xv0XHDYX479NjYKqjEzOE=", + "dev": true + }, + "uglify-to-browserify": { + "version": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "uglifyify": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/uglifyify/-/uglifyify-3.0.4.tgz", + "integrity": "sha1-SH4IClp3mIgOaOkN75sGaB+xO9I=", + "dev": true, + "dependencies": { + "convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "extend": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extend/-/extend-1.3.0.tgz", + "integrity": "sha1-0VFvsP9WJNLr+RI+odrFoZlABPg=", + "dev": true + } + } + }, + "uid2": { + "version": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", + "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=", + "dev": true + }, + "umd": { + "version": "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz", + "integrity": "sha1-iuVW4RAR9jwllnCKiDclnwGz1g4=", + "dev": true + }, + "unc-path-regex": { + "version": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "uniq": { + "version": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "uniqid": { + "version": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz", + "integrity": "sha1-iSIN32t1GuUrX3JISGNShZa7hME=", + "dev": true + }, + "uniqs": { + "version": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, + "unique-stream": { + "version": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", + "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", + "dev": true + }, + "unique-string": { + "version": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true + }, + "unique-temp-dir": { + "version": "https://registry.npmjs.org/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz", + "integrity": "sha1-bc6VsmgcoAPuv7MEpBX5y6vMU4U=", + "dev": true + }, + "unpipe": { + "version": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unreachable-branch-transform": { + "version": "https://registry.npmjs.org/unreachable-branch-transform/-/unreachable-branch-transform-0.3.0.tgz", + "integrity": "sha1-2ZzExudG0mSSiEW2EdtUsPNHTKo=" + }, + "unzip-response": { + "version": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", + "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=", + "dev": true + }, + "update-notifier": { + "version": "https://registry.npmjs.org/update-notifier/-/update-notifier-1.0.3.tgz", + "integrity": "sha1-j5LFFUgr1oMbfJMBPnD4dVLHz1o=", + "dev": true + }, + "urix": { + "version": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "dependencies": { + "punycode": { + "version": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-parse-lax": { + "version": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true + }, + "user-home": { + "version": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", + "dev": true + }, + "util": { + "version": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "dependencies": { + "inherits": { + "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", + "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", + "dev": true + }, + "v8flags": { + "version": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", + "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "dev": true + }, + "validate-npm-package-license": { + "version": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true + }, + "vendors": { + "version": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz", + "integrity": "sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=", + "dev": true + }, + "verror": { + "version": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", + "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", + "dev": true + }, + "vinyl": { + "version": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "dev": true + }, + "vinyl-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vinyl-buffer/-/vinyl-buffer-1.0.0.tgz", + "integrity": "sha1-ygZ+oIQx1QdyKx3lCD9gJhbrwjQ=", + "dev": true, + "dependencies": { + "bl": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", + "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=", + "dev": true + } + } + }, + "vinyl-fs": { + "version": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", + "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", + "dev": true, + "dependencies": { + "clone": { + "version": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", + "dev": true + }, + "graceful-fs": { + "version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", + "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", + "dev": true + }, + "strip-bom": { + "version": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", + "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", + "dev": true + }, + "vinyl": { + "version": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "dev": true + } + } + }, + "vinyl-source-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-source-stream/-/vinyl-source-stream-1.1.0.tgz", + "integrity": "sha1-RMvlEIIFJ53rDFZTwJSiiHk4sas=", + "dev": true, + "dependencies": { + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", + "dev": true + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "dev": true + } + } + }, + "vinyl-sourcemaps-apply": { + "version": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", + "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", + "dev": true, + "dependencies": { + "source-map": { + "version": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", + "dev": true + } + } + }, + "vm-browserify": { + "version": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true + }, + "watchify": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/watchify/-/watchify-3.9.0.tgz", + "integrity": "sha1-8HX9LoqGrN6Eztum5cKgvt1SPZ4=", + "dev": true, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.10.tgz", + "integrity": "sha512-HQEnnoV404e0EtwB9yNiuk2tJ+egeVC8Y9QBAxzDg8DBJt4BzRp+yQuIb/t3FIWkSTmIi+sgx7yVv/ZM0GNoqw==", + "dev": true + }, + "string_decoder": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", + "integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true + } + } + }, + "websocket-driver": { + "version": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", + "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", + "dev": true + }, + "websocket-extensions": { + "version": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.1.tgz", + "integrity": "sha1-domUmcGEtu91Q3fC27DNbLVdKec=", + "dev": true + }, + "whet.extend": { + "version": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", + "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=", + "dev": true + }, + "which": { + "version": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true + }, + "which-module": { + "version": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "wide-align": { + "version": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.0.tgz", + "integrity": "sha1-QO3egCpx/qHwcNo+YtzaLnrdlq0=", + "dev": true + }, + "widest-line": { + "version": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz", + "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=", + "dev": true + }, + "window-size": { + "version": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true + }, + "wordwrap": { + "version": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, + "wrap-ansi": { + "version": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true + }, + "wrappy": { + "version": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true + }, + "write-file-atomic": { + "version": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", + "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", + "dev": true + }, + "write-json-file": { + "version": "https://registry.npmjs.org/write-json-file/-/write-json-file-2.0.0.tgz", + "integrity": "sha1-Dq7Jgfz5KI28KAbL0m4Gq5vcpO0=", + "dev": true + }, + "write-pkg": { + "version": "https://registry.npmjs.org/write-pkg/-/write-pkg-2.1.0.tgz", + "integrity": "sha1-NTqkTDnEjCFED1wIzmq9RhQcnAg=", + "dev": true + }, + "xdg-basedir": { + "version": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", + "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=", + "dev": true + }, + "xo": { + "version": "0.18.2", + "resolved": "https://registry.npmjs.org/xo/-/xo-0.18.2.tgz", + "integrity": "sha1-kqQusCpPsUnf6lUYAhkU9arIT/A=", + "dev": true, + "dependencies": { + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dev": true + }, + "boxen": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.1.0.tgz", + "integrity": "sha1-sbad1SIwXoB6md7ud329blFnsQI=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "configstore": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.0.tgz", + "integrity": "sha1-Rd+QcHPibfoc9LLVL1tgVF6qEdE=", + "dev": true + }, + "get-stdin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", + "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true + }, + "lazy-req": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lazy-req/-/lazy-req-2.0.0.tgz", + "integrity": "sha1-yUUKNj7N2i5vDHATKtTzf48G8rQ=", + "dev": true + }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true + }, + "string-width": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", + "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=", + "dev": true + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "dev": true + }, + "update-notifier": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.1.0.tgz", + "integrity": "sha1-7AweU1NrdmR6JLd8uDlm2TFRI9k=", + "dev": true + }, + "write-file-atomic": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.1.0.tgz", + "integrity": "sha512-0TZ20a+xcIl4u0+Mj5xDH2yOWdmQiXlKf9Hm+TgDXjTMsEYb+gDrmb8e8UNAzMCitX8NBqG4Z/FUQIyzv/R1JQ==", + "dev": true + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + } + } + }, + "xo-init": { + "version": "https://registry.npmjs.org/xo-init/-/xo-init-0.5.0.tgz", + "integrity": "sha1-jijex5Z2zF4EL95f2PcQ4mRrDjY=", + "dev": true, + "dependencies": { + "minimist": { + "version": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "xtend": { + "version": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "y18n": { + "version": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "dependencies": { + "camelcase": { + "version": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + } + } + }, + "yargs-parser": { + "version": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", + "dev": true, + "dependencies": { + "camelcase": { + "version": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + } + } + } + } +} diff --git a/package.json b/package.json index ab58642..345896b 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,8 @@ "license": "MIT", "dependencies": { "chai": "^3.5.0", - "localforage": "^1.5.0" + "localforage": "^1.5.0", + "pjs-problems": "git+https://github.com/practicejavascript/pjs-problems.git" }, "devDependencies": { "autoprefixer": "^6.7.7", @@ -53,7 +54,10 @@ "babel-preset-latest": "^6.24.1", "babelify": "^7.3.0", "browserify": "^14.3.0", + "chai": "^3.5.0", "cssnano": "^3.10.0", + "dedent": "^0.7.0", + "gulp-bro": "^1.0.2", "gulp-htmlmin": "^3.0.0", "gulp-image": "^2.8.0", "gulp-livereload": "^3.8.1", @@ -66,6 +70,7 @@ "gulp": "^3.9.1", "husky": "^0.13.3", "lint-staged": "^3.4.0", + "localforage": "^1.5.0", "rollup-stream": "^1.19.0", "sw-precache": "^5.1.1", "uglifyify": "^3.0.4", diff --git a/public/dist/css/style.css b/public/dist/css/style.css index 1db0a90..1fa747c 100644 --- a/public/dist/css/style.css +++ b/public/dist/css/style.css @@ -1 +1 @@ -html{background-color:#0c141f;min-height:100%}body{margin:0}body,input,select,textarea{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,Arial,sans-serif;font-size:16pt;box-sizing:border-box;color:#e6ffff;-webkit-font-smoothing:antialiased}a{color:#6fc3df}.monospace{font-family:Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.hidden,.hide-until-load{visibility:hidden}.visually-hidden{position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);padding:0!important;border:0!important;height:1px!important;width:1px!important;overflow:hidden}body{opacity:1;transition:opacity .2s ease-in-out}.container{display:block}.site-heading{padding:.5em;text-align:center;margin:0;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.site-heading,.site-heading span{display:-webkit-box;display:-ms-flexbox;display:flex}.site-heading span{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-shadow:0 0 10px #fff,0 0 40px #6fc3df}.site-heading h1{font-size:200%;margin:.3em 0 .5em .5em;letter-spacing:0;font-weight:200}.site-heading img.logo{display:none}.controls{cursor:pointer;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-pack:distribute;justify-content:space-around;font-size:60%;text-transform:uppercase}.controls img{padding:1em;border-radius:1em;background-color:transparent;height:30px}.controls>div>.active,.controls>div>:active{background-color:#6fc3df;transition:color .1s ease-in-out}.problem-group{display:block;margin:.7em 0;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.problem{display:block;margin:1em}.code-and-tests{vertical-align:top;display:block}.code{font-size:80%;color:#f8f8f2;color:#fff;overflow-x:auto;padding:.5em;background:#23241f;background:#1a1a1a;border-radius:3px;padding:.25em .65em}.code,.test-area{display:inline-block;width:100%}.test-area{vertical-align:top}.test-suite{font-size:60%}.test{display:block;margin:.7em 0}.test-state{display:inline-block;transition:all .2s ease-in-out}.test-state.pass{color:#6fc3df}.test-state.fail{color:#df740c}.test-name{display:inline-block}.test-total{background-color:gray;color:#fff;text-align:center;padding:.5em;transition:all .2s ease-in-out}.test-total.working{background:url(/dist/img/reload.svg)}.test-total.pass{background-color:#6fc3df}.test-total.fail{background-color:#df740c}.console{font-size:70%;margin:.5em 0;vertical-align:top}.console>h4{text-align:center}.ads-bottom{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin:5em 0 1em}footer{margin:0 auto;text-align:center;left:0;bottom:0;height:70px;width:100%;font-size:60%}footer>div{margin:.4em auto}@media (min-width:760px){.container{width:92%;margin:0 auto;display:-webkit-box;display:-ms-flexbox;display:flex}.left-spacer{-webkit-box-flex:0.5;-ms-flex:0.5;flex:0.5}main{-webkit-box-flex:30;-ms-flex:30;flex:30}.site-heading .container{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.site-heading>.container>h1{font-size:200%}.site-heading img.logo{height:60px;display:-webkit-box;display:-ms-flexbox;display:flex}.problem-name{display:block}.problem-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.problem{display:block;margin-right:.6em}.code-and-tests{display:-webkit-box;display:-ms-flexbox;display:flex}.test-area{width:30%}.code-and-eval-console{width:70%}} \ No newline at end of file +html{background-color:#0c141f;min-height:100%}body{margin:0}body,input,select,textarea{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,Arial,sans-serif;font-size:16pt;box-sizing:border-box;color:#e6ffff;-webkit-font-smoothing:antialiased}a{color:#6fc3df}.monospace{font-family:Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.hidden,.hide-until-load{visibility:hidden}.visually-hidden{position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);padding:0!important;border:0!important;height:1px!important;width:1px!important;overflow:hidden}body{opacity:1;transition:opacity .2s ease-in-out}.container{display:block}.site-heading{padding:.5em;text-align:center;margin:0;display:flex;flex-direction:column}.site-heading span{display:flex;align-items:center;justify-content:center;text-shadow:0 0 10px #fff,0 0 40px #6fc3df}.site-heading h1{font-size:200%;margin:.3em 0 .5em .5em;letter-spacing:0;font-weight:200}.site-heading img.logo{display:none}.controls{cursor:pointer;display:flex;justify-content:space-around;font-size:60%;text-transform:uppercase}.controls img{padding:1em;border-radius:1em;background-color:transparent;height:30px}.controls>div>.active,.controls>div>:active{background-color:#6fc3df;transition:color .1s ease-in-out}.problem-group{display:block;margin:.7em 0;align-items:center}.problem{display:block;margin:1em}.code-and-tests{vertical-align:top;display:block}.code{font-size:80%;color:#f8f8f2;color:#fff;overflow-x:auto;padding:.5em;background:#23241f;background:#1a1a1a;border-radius:3px;padding:.25em .65em}.code,.test-area{display:inline-block;width:100%}.test-area{vertical-align:top}.test-suite{font-size:60%}.test{display:block;margin:.7em 0}.test-state{display:inline-block;transition:all .2s ease-in-out}.test-state.pass{color:#6fc3df}.test-state.fail{color:#df740c}.test-name{display:inline-block}.test-total{background-color:gray;color:#fff;text-align:center;padding:.5em;transition:all .2s ease-in-out}.test-total.working{background:url(/dist/img/reload.svg)}.test-total.pass{background-color:#6fc3df}.test-total.fail{background-color:#df740c}.console{font-size:70%;margin:.5em 0;vertical-align:top}.console>h4{text-align:center}.ads-bottom{display:flex;flex-direction:row;align-items:center;justify-content:center;margin:5em 0 1em}footer{margin:0 auto;text-align:center;left:0;bottom:0;height:70px;width:100%;font-size:60%}footer>div{margin:.4em auto}@media (min-width:760px){.container{width:92%;margin:0 auto;display:flex}.left-spacer{flex:0.5}main{flex:30}.site-heading .container{justify-content:space-between;flex-direction:row;align-items:center}.site-heading>.container>h1{font-size:200%}.site-heading img.logo{height:60px;display:flex}.problem-name{display:block}.problem-group{display:flex;justify-content:space-between}.problem{display:block;margin-right:.6em}.code-and-tests{display:flex}.test-area{width:30%}.code-and-eval-console{width:70%}} \ No newline at end of file diff --git a/public/dist/js/bundle.min.js b/public/dist/js/bundle.min.js index 81816b3..8c88a93 100644 --- a/public/dist/js/bundle.min.js +++ b/public/dist/js/bundle.min.js @@ -1,4 +1,9386 @@ +<<<<<<< HEAD !function e(t,n,r){function o(a,s){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var f=n[a]={exports:{}};t[a][0].call(f.exports,function(e){var n=t[a][1][e];return o(n||e)},f,f.exports,e,t,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;ae,"expected #{this} to have a length above #{exp} but got #{act}","expected #{this} to not have a length above #{exp}",e,r)}else this.assert(n>e,"expected #{this} to be above "+e,"expected #{this} to be at most "+e)}function c(e,t){t&&P(this,"message",t);var n=P(this,"object");if(P(this,"doLength")){new N(n,t).to.have.property("length");var r=n.length;this.assert(r>=e,"expected #{this} to have a length at least #{exp} but got #{act}","expected #{this} to have a length below #{exp}",e,r)}else this.assert(n>=e,"expected #{this} to be at least "+e,"expected #{this} to be below "+e)}function f(e,t){t&&P(this,"message",t);var n=P(this,"object");if(P(this,"doLength")){new N(n,t).to.have.property("length");var r=n.length;this.assert(r1)throw new Error(i);break;case"object":if(arguments.length>1)throw new Error(i);e=Object.keys(e);break;default:e=Array.prototype.slice.call(arguments)}if(!e.length)throw new Error("keys required");var a=Object.keys(r),s=e,u=e.length,c=P(this,"any"),f=P(this,"all");if(c||f||(f=!0),c){o=s.filter(function(e){return~a.indexOf(e)}).length>0}if(f&&(o=e.every(function(e){return~a.indexOf(e)}),P(this,"negate")||P(this,"contains")||(o=o&&e.length==a.length)),u>1){e=e.map(function(e){return t.inspect(e)});var l=e.pop();f&&(n=e.join(", ")+", and "+l),c&&(n=e.join(", ")+", or "+l)}else n=t.inspect(e[0]);n=(u>1?"keys ":"key ")+n,n=(P(this,"contains")?"contain ":"have ")+n,this.assert(o,"expected #{this} to "+n,"expected #{this} to not "+n,s.slice(0).sort(),a.sort(),!0)}function m(e,n,r){r&&P(this,"message",r);var o=P(this,"object");new N(o,r).is.a("function");var i=!1,a=null,s=null,u=null;0===arguments.length?(n=null,e=null):e&&(e instanceof RegExp||"string"==typeof e)?(n=e,e=null):e&&e instanceof Error?(a=e,e=null,n=null):"function"==typeof e?(!(s=e.prototype.name)||"Error"===s&&e!==Error)&&(s=e.name||(new e).name):e=null;try{o()}catch(r){if(a)return this.assert(r===a,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp}",a instanceof Error?a.toString():a,r instanceof Error?r.toString():r),P(this,"object",r),this;if(e&&(this.assert(r instanceof e,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp} but #{act} was thrown",s,r instanceof Error?r.toString():r),!n))return P(this,"object",r),this;var c="error"===t.type(r)&&"message"in r?r.message:""+r;if(null!=c&&n&&n instanceof RegExp)return this.assert(n.exec(c),"expected #{this} to throw error matching #{exp} but got #{act}","expected #{this} to throw error not matching #{exp}",n,c),P(this,"object",r),this;if(null!=c&&n&&"string"==typeof n)return this.assert(~c.indexOf(n),"expected #{this} to throw error including #{exp} but got #{act}","expected #{this} to throw error not including #{act}",n,c),P(this,"object",r),this;i=!0,u=r}var f="",l=null!==s?s:a?"#{exp}":"an error";i&&(f=" but #{act} was thrown"),this.assert(!0===i,"expected #{this} to throw "+l+f,"expected #{this} to not throw "+l+f,a instanceof Error?a.toString():a,u instanceof Error?u.toString():u),P(this,"object",u)}function w(e,n){n&&P(this,"message",n);var r=P(this,"object"),o=P(this,"itself"),i="function"!==t.type(r)||o?r[e]:r.prototype[e];this.assert("function"==typeof i,"expected #{this} to respond to "+t.inspect(e),"expected #{this} to not respond to "+t.inspect(e))}function x(e,n){n&&P(this,"message",n);var r=P(this,"object"),o=e(r);this.assert(o,"expected #{this} to satisfy "+t.objDisplay(e),"expected #{this} to not satisfy"+t.objDisplay(e),!this.negate,o)}function E(e,n,r){r&&P(this,"message",r);var o=P(this,"object");if(new N(o,r).is.a("number"),"number"!==t.type(e)||"number"!==t.type(n))throw new Error("the arguments to closeTo or approximately must be numbers");this.assert(Math.abs(o-e)<=n,"expected #{this} to be close to "+e+" +/- "+n,"expected #{this} not to be close to "+e+" +/- "+n)}function j(e,t,n){return e.every(function(e){return n?t.some(function(t){return n(e,t)}):-1!==t.indexOf(e)})}function O(e,t){t&&P(this,"message",t);var n=P(this,"object");new N(e).to.be.an("array"),this.assert(e.indexOf(n)>-1,"expected #{this} to be one of #{exp}","expected #{this} to not be one of #{exp}",e,n)}function S(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(o!==e[t],"expected ."+t+" to change","expected ."+t+" to not change")}function A(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(e[t]-o>0,"expected ."+t+" to increase","expected ."+t+" to not increase")}function _(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(e[t]-o<0,"expected ."+t+" to decrease","expected ."+t+" to not decrease")}var N=e.Assertion,P=(Object.prototype.toString,t.flag);["to","be","been","is","and","has","have","with","that","which","at","of","same"].forEach(function(e){N.addProperty(e,function(){return this})}),N.addProperty("not",function(){P(this,"negate",!0)}),N.addProperty("deep",function(){P(this,"deep",!0)}),N.addProperty("any",function(){P(this,"any",!0),P(this,"all",!1)}),N.addProperty("all",function(){P(this,"all",!0),P(this,"any",!1)}),N.addChainableMethod("an",n),N.addChainableMethod("a",n),N.addChainableMethod("include",o,r),N.addChainableMethod("contain",o,r),N.addChainableMethod("contains",o,r),N.addChainableMethod("includes",o,r),N.addProperty("ok",function(){this.assert(P(this,"object"),"expected #{this} to be truthy","expected #{this} to be falsy")}),N.addProperty("true",function(){this.assert(!0===P(this,"object"),"expected #{this} to be true","expected #{this} to be false",!this.negate)}),N.addProperty("false",function(){this.assert(!1===P(this,"object"),"expected #{this} to be false","expected #{this} to be true",!!this.negate)}),N.addProperty("null",function(){this.assert(null===P(this,"object"),"expected #{this} to be null","expected #{this} not to be null")}),N.addProperty("undefined",function(){this.assert(void 0===P(this,"object"),"expected #{this} to be undefined","expected #{this} not to be undefined")}),N.addProperty("NaN",function(){this.assert(isNaN(P(this,"object")),"expected #{this} to be NaN","expected #{this} not to be NaN")}),N.addProperty("exist",function(){this.assert(null!=P(this,"object"),"expected #{this} to exist","expected #{this} to not exist")}),N.addProperty("empty",function(){var e=P(this,"object"),t=e;Array.isArray(e)||"string"==typeof object?t=e.length:"object"==typeof e&&(t=Object.keys(e).length),this.assert(!t,"expected #{this} to be empty","expected #{this} not to be empty")}),N.addProperty("arguments",i),N.addProperty("Arguments",i),N.addMethod("equal",a),N.addMethod("equals",a),N.addMethod("eq",a),N.addMethod("eql",s),N.addMethod("eqls",s),N.addMethod("above",u),N.addMethod("gt",u),N.addMethod("greaterThan",u),N.addMethod("least",c),N.addMethod("gte",c),N.addMethod("below",f),N.addMethod("lt",f),N.addMethod("lessThan",f),N.addMethod("most",l),N.addMethod("lte",l),N.addMethod("within",function(e,t,n){n&&P(this,"message",n);var r=P(this,"object"),o=e+".."+t;if(P(this,"doLength")){new N(r,n).to.have.property("length");var i=r.length;this.assert(i>=e&&i<=t,"expected #{this} to have a length within "+o,"expected #{this} to not have a length within "+o)}else this.assert(r>=e&&r<=t,"expected #{this} to be within "+o,"expected #{this} to not be within "+o)}),N.addMethod("instanceof",d),N.addMethod("instanceOf",d),N.addMethod("property",function(e,n,r){r&&P(this,"message",r);var o=!!P(this,"deep"),i=o?"deep property ":"property ",a=P(this,"negate"),s=P(this,"object"),u=o?t.getPathInfo(e,s):null,c=o?u.exists:t.hasProperty(e,s),f=o?u.value:s[e];if(a&&arguments.length>1){if(void 0===f)throw r=null!=r?r+": ":"",new Error(r+t.inspect(s)+" has no "+i+t.inspect(e))}else this.assert(c,"expected #{this} to have a "+i+t.inspect(e),"expected #{this} to not have "+i+t.inspect(e));arguments.length>1&&this.assert(n===f,"expected #{this} to have a "+i+t.inspect(e)+" of #{exp}, but got #{act}","expected #{this} to not have a "+i+t.inspect(e)+" of #{act}",n,f),P(this,"object",f)}),N.addMethod("ownProperty",h),N.addMethod("haveOwnProperty",h),N.addMethod("ownPropertyDescriptor",p),N.addMethod("haveOwnPropertyDescriptor",p),N.addChainableMethod("length",b,v),N.addMethod("lengthOf",b),N.addMethod("match",y),N.addMethod("matches",y),N.addMethod("string",function(e,n){n&&P(this,"message",n);var r=P(this,"object");new N(r,n).is.a("string"),this.assert(~r.indexOf(e),"expected #{this} to contain "+t.inspect(e),"expected #{this} to not contain "+t.inspect(e))}),N.addMethod("keys",g),N.addMethod("key",g),N.addMethod("throw",m),N.addMethod("throws",m),N.addMethod("Throw",m),N.addMethod("respondTo",w),N.addMethod("respondsTo",w),N.addProperty("itself",function(){P(this,"itself",!0)}),N.addMethod("satisfy",x),N.addMethod("satisfies",x),N.addMethod("closeTo",E),N.addMethod("approximately",E),N.addMethod("members",function(e,n){n&&P(this,"message",n);var r=P(this,"object");new N(r).to.be.an("array"),new N(e).to.be.an("array");var o=P(this,"deep")?t.eql:void 0;if(P(this,"contains"))return this.assert(j(e,r,o),"expected #{this} to be a superset of #{act}","expected #{this} to not be a superset of #{act}",r,e);this.assert(j(r,e,o)&&j(e,r,o),"expected #{this} to have the same members as #{act}","expected #{this} to not have the same members as #{act}",r,e)}),N.addMethod("oneOf",O),N.addChainableMethod("change",S),N.addChainableMethod("changes",S),N.addChainableMethod("increase",A),N.addChainableMethod("increases",A),N.addChainableMethod("decrease",_),N.addChainableMethod("decreases",_),N.addProperty("extensible",function(){var e,t=P(this,"object");try{e=Object.isExtensible(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!1}this.assert(e,"expected #{this} to be extensible","expected #{this} to not be extensible")}),N.addProperty("sealed",function(){var e,t=P(this,"object");try{e=Object.isSealed(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!0}this.assert(e,"expected #{this} to be sealed","expected #{this} to not be sealed")}),N.addProperty("frozen",function(){var e,t=P(this,"object");try{e=Object.isFrozen(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!0}this.assert(e,"expected #{this} to be frozen","expected #{this} to not be frozen")})}},{}],7:[function(e,t,n){t.exports=function(e,t){var n=e.Assertion,r=t.flag,o=e.assert=function(t,r){new n(null,null,e.assert).assert(t,r,"[ negation message unavailable ]")};o.fail=function(t,n,r,i){throw r=r||"assert.fail()",new e.AssertionError(r,{actual:t,expected:n,operator:i},o.fail)},o.isOk=function(e,t){new n(e,t).is.ok},o.isNotOk=function(e,t){new n(e,t).is.not.ok},o.equal=function(e,t,i){var a=new n(e,i,o.equal);a.assert(t==r(a,"object"),"expected #{this} to equal #{exp}","expected #{this} to not equal #{act}",t,e)},o.notEqual=function(e,t,i){var a=new n(e,i,o.notEqual);a.assert(t!=r(a,"object"),"expected #{this} to not equal #{exp}","expected #{this} to equal #{act}",t,e)},o.strictEqual=function(e,t,r){new n(e,r).to.equal(t)},o.notStrictEqual=function(e,t,r){new n(e,r).to.not.equal(t)},o.deepEqual=function(e,t,r){new n(e,r).to.eql(t)},o.notDeepEqual=function(e,t,r){new n(e,r).to.not.eql(t)},o.isAbove=function(e,t,r){new n(e,r).to.be.above(t)},o.isAtLeast=function(e,t,r){new n(e,r).to.be.least(t)},o.isBelow=function(e,t,r){new n(e,r).to.be.below(t)},o.isAtMost=function(e,t,r){new n(e,r).to.be.most(t)},o.isTrue=function(e,t){new n(e,t).is.true},o.isNotTrue=function(e,t){new n(e,t).to.not.equal(!0)},o.isFalse=function(e,t){new n(e,t).is.false},o.isNotFalse=function(e,t){new n(e,t).to.not.equal(!1)},o.isNull=function(e,t){new n(e,t).to.equal(null)},o.isNotNull=function(e,t){new n(e,t).to.not.equal(null)},o.isNaN=function(e,t){new n(e,t).to.be.NaN},o.isNotNaN=function(e,t){new n(e,t).not.to.be.NaN},o.isUndefined=function(e,t){new n(e,t).to.equal(void 0)},o.isDefined=function(e,t){new n(e,t).to.not.equal(void 0)},o.isFunction=function(e,t){new n(e,t).to.be.a("function")},o.isNotFunction=function(e,t){new n(e,t).to.not.be.a("function")},o.isObject=function(e,t){new n(e,t).to.be.a("object")},o.isNotObject=function(e,t){new n(e,t).to.not.be.a("object")},o.isArray=function(e,t){new n(e,t).to.be.an("array")},o.isNotArray=function(e,t){new n(e,t).to.not.be.an("array")},o.isString=function(e,t){new n(e,t).to.be.a("string")},o.isNotString=function(e,t){new n(e,t).to.not.be.a("string")},o.isNumber=function(e,t){new n(e,t).to.be.a("number")},o.isNotNumber=function(e,t){new n(e,t).to.not.be.a("number")},o.isBoolean=function(e,t){new n(e,t).to.be.a("boolean")},o.isNotBoolean=function(e,t){new n(e,t).to.not.be.a("boolean")},o.typeOf=function(e,t,r){new n(e,r).to.be.a(t)},o.notTypeOf=function(e,t,r){new n(e,r).to.not.be.a(t)},o.instanceOf=function(e,t,r){new n(e,r).to.be.instanceOf(t)},o.notInstanceOf=function(e,t,r){new n(e,r).to.not.be.instanceOf(t)},o.include=function(e,t,r){new n(e,r,o.include).include(t)},o.notInclude=function(e,t,r){new n(e,r,o.notInclude).not.include(t)},o.match=function(e,t,r){new n(e,r).to.match(t)},o.notMatch=function(e,t,r){new n(e,r).to.not.match(t)},o.property=function(e,t,r){new n(e,r).to.have.property(t)},o.notProperty=function(e,t,r){new n(e,r).to.not.have.property(t)},o.deepProperty=function(e,t,r){new n(e,r).to.have.deep.property(t)},o.notDeepProperty=function(e,t,r){new n(e,r).to.not.have.deep.property(t)},o.propertyVal=function(e,t,r,o){new n(e,o).to.have.property(t,r)},o.propertyNotVal=function(e,t,r,o){new n(e,o).to.not.have.property(t,r)},o.deepPropertyVal=function(e,t,r,o){new n(e,o).to.have.deep.property(t,r)},o.deepPropertyNotVal=function(e,t,r,o){new n(e,o).to.not.have.deep.property(t,r)},o.lengthOf=function(e,t,r){new n(e,r).to.have.length(t)},o.throws=function(e,t,o,i){("string"==typeof t||t instanceof RegExp)&&(o=t,t=null);var a=new n(e,i).to.throw(t,o);return r(a,"object")},o.doesNotThrow=function(e,t,r){"string"==typeof t&&(r=t,t=null),new n(e,r).to.not.Throw(t)},o.operator=function(e,o,i,a){var s;switch(o){case"==":s=e==i;break;case"===":s=e===i;break;case">":s=e>i;break;case">=":s=e>=i;break;case"<":s=e1&&n===t.length-1?"or ":"")+r+" "+e}).join(", ");if(!t.some(function(t){return i(e)===t}))throw new r("object tested must be "+n+", but "+i(e)+" given")}},{"./flag":14,"assertion-error":1,"type-detect":36}],14:[function(e,t,n){t.exports=function(e,t,n){var r=e.__flags||(e.__flags=Object.create(null));if(3!==arguments.length)return r[t];r[t]=n}},{}],15:[function(e,t,n){t.exports=function(e,t){return t.length>4?t[4]:e._obj}},{}],16:[function(e,t,n){t.exports=function(e){var t=[];for(var n in e)t.push(n);return t}},{}],17:[function(e,t,n){var r=e("./flag"),o=e("./getActual"),i=(e("./inspect"),e("./objDisplay"));t.exports=function(e,t){var n=r(e,"negate"),a=r(e,"object"),s=t[3],u=o(e,t),c=n?t[2]:t[1],f=r(e,"message");return"function"==typeof c&&(c=c()),c=c||"",c=c.replace(/#\{this\}/g,function(){return i(a)}).replace(/#\{act\}/g,function(){return i(u)}).replace(/#\{exp\}/g,function(){return i(s)}),f?f+": "+c:c}},{"./flag":14,"./getActual":15,"./inspect":24,"./objDisplay":25}],18:[function(e,t,n){t.exports=function(e){if(e.name)return e.name;var t=/^\s?function ([^(]*)\(/.exec(e);return t&&t[1]?t[1]:""}},{}],19:[function(e,t,n){function r(e){return e.replace(/([^\\])\[/g,"$1.[").match(/(\\\.|[^.]+?)+/g).map(function(e){var t=/^\[(\d+)\]$/,n=t.exec(e);return n?{i:parseFloat(n[1])}:{p:e.replace(/\\([.\[\]])/g,"$1")}})}function o(e,t,n){var r,o=t;n=void 0===n?e.length:n;for(var i=0,a=n;i1?o(n,t,n.length-1):t,name:a.p||a.i,value:o(n,t)};return s.exists=i(s.name,s.parent),s}},{"./hasProperty":22}],20:[function(e,t,n){var r=e("./getPathInfo");t.exports=function(e,t){return r(e,t).value}},{"./getPathInfo":19}],21:[function(e,t,n){t.exports=function(e){function t(e){-1===n.indexOf(e)&&n.push(e)}for(var n=Object.getOwnPropertyNames(e),r=Object.getPrototypeOf(e);null!==r;)Object.getOwnPropertyNames(r).forEach(t),r=Object.getPrototypeOf(r);return n}},{}],22:[function(e,t,n){var r=e("type-detect"),o={number:Number,string:String};t.exports=function(e,t){var n=r(t);return"null"!==n&&"undefined"!==n&&(o[n]&&"object"!=typeof t&&(t=new o[n](t)),e in t)}},{"type-detect":36}],23:[function(e,t,n){var n=t.exports={};n.test=e("./test"),n.type=e("type-detect"),n.expectTypes=e("./expectTypes"),n.getMessage=e("./getMessage"),n.getActual=e("./getActual"),n.inspect=e("./inspect"),n.objDisplay=e("./objDisplay"),n.flag=e("./flag"),n.transferFlags=e("./transferFlags"),n.eql=e("deep-eql"),n.getPathValue=e("./getPathValue"),n.getPathInfo=e("./getPathInfo"),n.hasProperty=e("./hasProperty"),n.getName=e("./getName"),n.addProperty=e("./addProperty"),n.addMethod=e("./addMethod"),n.overwriteProperty=e("./overwriteProperty"),n.overwriteMethod=e("./overwriteMethod"),n.addChainableMethod=e("./addChainableMethod"),n.overwriteChainableMethod=e("./overwriteChainableMethod")},{"./addChainableMethod":10,"./addMethod":11,"./addProperty":12,"./expectTypes":13,"./flag":14,"./getActual":15,"./getMessage":17,"./getName":18,"./getPathInfo":19,"./getPathValue":20,"./hasProperty":22,"./inspect":24,"./objDisplay":25,"./overwriteChainableMethod":26,"./overwriteMethod":27,"./overwriteProperty":28,"./test":29,"./transferFlags":30,"deep-eql":31,"type-detect":36}],24:[function(e,t,n){function r(e,t,n,r){return o({showHidden:t,seen:[],stylize:function(e){return e}},e,void 0===n?2:n)}function o(e,t,r){if(t&&"function"==typeof t.inspect&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var p=t.inspect(r);return"string"!=typeof p&&(p=o(e,p,r)),p}var m=i(e,t);if(m)return m;if(g(t)){if("outerHTML"in t)return t.outerHTML;try{if(document.xmlVersion){return(new XMLSerializer).serializeToString(t)}var w=document.createElementNS("http://www.w3.org/1999/xhtml","_");return w.appendChild(t.cloneNode(!1)),html=w.innerHTML.replace("><",">"+t.innerHTML+"<"),w.innerHTML="",html}catch(e){}}var x=y(t),E=e.showHidden?b(t):x;if(0===E.length||h(t)&&(1===E.length&&"stack"===E[0]||2===E.length&&"description"===E[0]&&"stack"===E[1])){if("function"==typeof t){var j=v(t),O=j?": "+j:"";return e.stylize("[Function"+O+"]","special")}if(l(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(d(t))return e.stylize(Date.prototype.toUTCString.call(t),"date");if(h(t))return a(t)}var S="",A=!1,_=["{","}"];if(f(t)&&(A=!0,_=["[","]"]),"function"==typeof t){var j=v(t),O=j?": "+j:"";S=" [Function"+O+"]"}if(l(t)&&(S=" "+RegExp.prototype.toString.call(t)),d(t)&&(S=" "+Date.prototype.toUTCString.call(t)),h(t))return a(t);if(0===E.length&&(!A||0==t.length))return _[0]+S+_[1];if(r<0)return l(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var N;return N=A?s(e,t,r,x,E):E.map(function(n){return u(e,t,r,x,n,A)}),e.seen.pop(),c(N,S,_)}function i(e,t){switch(typeof t){case"undefined":return e.stylize("undefined","undefined");case"string":var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string");case"number":return 0===t&&1/t==-1/0?e.stylize("-0","number"):e.stylize(""+t,"number");case"boolean":return e.stylize(""+t,"boolean")}if(null===t)return e.stylize("null","null")}function a(e){return"["+Error.prototype.toString.call(e)+"]"}function s(e,t,n,r,o){for(var i=[],a=0,s=t.length;a-1&&(u=a?u.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+u.split("\n").map(function(e){return" "+e}).join("\n"))):u=e.stylize("[Circular]","special")),void 0===s){if(a&&i.match(/^\d+$/))return u;s=JSON.stringify(""+i),s.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(s=s.substr(1,s.length-2),s=e.stylize(s,"name")):(s=s.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),s=e.stylize(s,"string"))}return s+": "+u}function c(e,t,n){var r=0;return e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.length+1},0)>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function f(e){return Array.isArray(e)||"object"==typeof e&&"[object Array]"===p(e)}function l(e){return"object"==typeof e&&"[object RegExp]"===p(e)}function d(e){return"object"==typeof e&&"[object Date]"===p(e)}function h(e){return"object"==typeof e&&"[object Error]"===p(e)}function p(e){return Object.prototype.toString.call(e)}var v=e("./getName"),b=e("./getProperties"),y=e("./getEnumerableProperties");t.exports=r;var g=function(e){return"object"==typeof HTMLElement?e instanceof HTMLElement:e&&"object"==typeof e&&1===e.nodeType&&"string"==typeof e.nodeName}},{"./getEnumerableProperties":16,"./getName":18,"./getProperties":21}],25:[function(e,t,n){var r=e("./inspect"),o=e("../config");t.exports=function(e){var t=r(e),n=Object.prototype.toString.call(e);if(o.truncateThreshold&&t.length>=o.truncateThreshold){if("[object Function]"===n)return e.name&&""!==e.name?"[Function: "+e.name+"]":"[Function]";if("[object Array]"===n)return"[ Array("+e.length+") ]";if("[object Object]"===n){var i=Object.keys(e);return"{ Object ("+(i.length>2?i.splice(0,2).join(", ")+", ...":i.join(", "))+") }"}return t}return t}},{"../config":5,"./inspect":24}],26:[function(e,t,n){t.exports=function(e,t,n,r){var o=e.__methods[t],i=o.chainingBehavior;o.chainingBehavior=function(){var e=r(i).call(this);return void 0===e?this:e};var a=o.method;o.method=function(){var e=n(a).apply(this,arguments);return void 0===e?this:e}}},{}],27:[function(e,t,n){t.exports=function(e,t,n){var r=e[t],o=function(){return this};r&&"function"==typeof r&&(o=r),e[t]=function(){var e=n(o).apply(this,arguments);return void 0===e?this:e}}},{}],28:[function(e,t,n){t.exports=function(e,t,n){var r=Object.getOwnPropertyDescriptor(e,t),o=function(){};r&&"function"==typeof r.get&&(o=r.get),Object.defineProperty(e,t,{get:function(){var e=n(o).call(this);return void 0===e?this:e},configurable:!0})}},{}],29:[function(e,t,n){var r=e("./flag");t.exports=function(e,t){var n=r(e,"negate"),o=t[0];return n?!o:o}},{"./flag":14}],30:[function(e,t,n){t.exports=function(e,t,n){var r=e.__flags||(e.__flags=Object.create(null));t.__flags||(t.__flags=Object.create(null)),n=3!==arguments.length||n;for(var o in r)(n||"object"!==o&&"ssfi"!==o&&"message"!=o)&&(t.__flags[o]=r[o])}},{}],31:[function(e,t,n){t.exports=e("./lib/eql")},{"./lib/eql":32}],32:[function(e,t,n){function r(e,t,n){return!!o(e,t)||("date"===v(e)?a(e,t):"regexp"===v(e)?s(e,t):p.isBuffer(e)?l(e,t):"arguments"===v(e)?u(e,t,n):!!i(e,t)&&("object"!==v(e)&&"object"!==v(t)&&"array"!==v(e)&&"array"!==v(t)?o(e,t):h(e,t,n)))}function o(e,t){return e===t?0!==e||1/e==1/t:e!==e&&t!==t}function i(e,t){return v(e)===v(t)}function a(e,t){return"date"===v(t)&&o(e.getTime(),t.getTime())}function s(e,t){return"regexp"===v(t)&&o(e.toString(),t.toString())}function u(e,t,n){return"arguments"===v(t)&&(e=[].slice.call(e),t=[].slice.call(t),r(e,t,n))}function c(e){var t=[];for(var n in e)t.push(n);return t}function f(e,t){if(e.length!==t.length)return!1;for(var n=0,r=!0;n=0;o--)if(s=i[o],!r(e[s],t[s],n))return!1;return!0}var p,v=e("type-detect");try{p=e("buffer").Buffer}catch(e){p={},p.isBuffer=function(){return!1}}t.exports=r},{buffer:void 0,"type-detect":33}],33:[function(e,t,n){t.exports=e("./lib/type")},{"./lib/type":34}],34:[function(e,t,n){function r(e){var t=Object.prototype.toString.call(e);return i[t]?i[t]:null===e?"null":void 0===e?"undefined":e===Object(e)?"object":typeof e}function o(){this.tests={}}var n=t.exports=r,i={"[object Array]":"array","[object RegExp]":"regexp","[object Function]":"function","[object Arguments]":"arguments","[object Date]":"date"};n.Library=o,o.prototype.of=r,o.prototype.define=function(e,t){return 1===arguments.length?this.tests[e]:(this.tests[e]=t,this)},o.prototype.test=function(e,t){if(t===r(e))return!0;var n=this.tests[t];if(n&&"regexp"===r(n))return n.test(e);if(n&&"function"===r(n))return n(e);throw new ReferenceError('Type test "'+t+'" not defined or invalid.')}},{}],35:[function(e,t,n){(function(r){!function(e){if("object"==typeof n&&void 0!==t)t.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var o;o="undefined"!=typeof window?window:void 0!==r?r:"undefined"!=typeof self?self:this,o.localforage=e()}}(function(){return function t(n,r,o){function i(s,u){if(!r[s]){if(!n[s]){var c="function"==typeof e&&e;if(!u&&c)return c(s,!0);if(a)return a(s,!0);var f=new Error("Cannot find module '"+s+"'");throw f.code="MODULE_NOT_FOUND",f}var l=r[s]={exports:{}};n[s][0].call(l.exports,function(e){var t=n[s][1][e];return i(t||e)},l,l.exports,t,n,r,o)}return r[s].exports}for(var a="function"==typeof e&&e,s=0;s=43)}}).catch(function(){return!1})}function c(e){return"boolean"==typeof re?ie.resolve(re):u(e).then(function(e){return re=e})}function f(e){var t=oe[e.name],n={};n.promise=new ie(function(e){n.resolve=e}),t.deferredOperations.push(n),t.dbReady?t.dbReady=t.dbReady.then(function(){return n.promise}):t.dbReady=n.promise}function l(e){var t=oe[e.name],n=t.deferredOperations.pop();n&&n.resolve()}function d(e,t){return new ie(function(n,r){if(e.db){if(!t)return n(e.db);f(e),e.db.close()}var o=[e.name];t&&o.push(e.version);var i=ne.open.apply(ne,o);t&&(i.onupgradeneeded=function(t){var n=i.result;try{n.createObjectStore(e.storeName),t.oldVersion<=1&&n.createObjectStore(ae)}catch(n){if("ConstraintError"!==n.name)throw n;console.warn('The database "'+e.name+'" has been upgraded from version '+t.oldVersion+" to version "+t.newVersion+', but the storage "'+e.storeName+'" already exists.')}}),i.onerror=function(e){e.preventDefault(),r(i.error)},i.onsuccess=function(){n(i.result),l(e)}})}function h(e){return d(e,!1)}function p(e){return d(e,!0)}function v(e,t){if(!e.db)return!0;var n=!e.db.objectStoreNames.contains(e.storeName),r=e.versione.db.version;if(r&&(e.version!==t&&console.warn('The database "'+e.name+"\" can't be downgraded from version "+e.db.version+" to version "+e.version+"."),e.version=e.db.version),o||n){if(n){var i=e.db.version+1;i>e.version&&(e.version=i)}return!0}return!1}function b(e){return new ie(function(t,n){var r=new FileReader;r.onerror=n,r.onloadend=function(n){var r=btoa(n.target.result||"");t({__local_forage_encoded_blob:!0,data:r,type:e.type})},r.readAsBinaryString(e)})}function y(e){return o([s(atob(e.data))],{type:e.type})}function g(e){return e&&e.__local_forage_encoded_blob}function m(e){var t=this,n=t._initReady().then(function(){var e=oe[t._dbInfo.name];if(e&&e.dbReady)return e.dbReady});return a(n,e,e),n}function w(e){function t(){return ie.resolve()}var n=this,r={db:null};if(e)for(var o in e)r[o]=e[o];oe||(oe={});var i=oe[r.name];i||(i={forages:[],db:null,dbReady:null,deferredOperations:[]},oe[r.name]=i),i.forages.push(n),n._initReady||(n._initReady=n.ready,n.ready=m);for(var a=[],s=0;s>4,f[u++]=(15&r)<<4|o>>2,f[u++]=(3&o)<<6|63&i;return c}function M(e){var t,n=new Uint8Array(e),r="";for(t=0;t>2],r+=ce[(3&n[t])<<4|n[t+1]>>4],r+=ce[(15&n[t+1])<<2|n[t+2]>>6],r+=ce[63&n[t+2]];return n.length%3==2?r=r.substring(0,r.length-1)+"=":n.length%3==1&&(r=r.substring(0,r.length-2)+"=="),r}function I(e,t){var n="";if(e&&(n=Ae.call(e)),e&&("[object ArrayBuffer]"===n||e.buffer&&"[object ArrayBuffer]"===Ae.call(e.buffer))){var r,o=de;e instanceof ArrayBuffer?(r=e,o+=pe):(r=e.buffer,"[object Int8Array]"===n?o+=be:"[object Uint8Array]"===n?o+=ye:"[object Uint8ClampedArray]"===n?o+=ge:"[object Int16Array]"===n?o+=me:"[object Uint16Array]"===n?o+=xe:"[object Int32Array]"===n?o+=we:"[object Uint32Array]"===n?o+=Ee:"[object Float32Array]"===n?o+=je:"[object Float64Array]"===n?o+=Oe:t(new Error("Failed to get type for BinaryArray"))),t(o+M(r))}else if("[object Blob]"===n){var i=new FileReader;i.onload=function(){var n=fe+e.type+"~"+M(this.result);t(de+ve+n)},i.readAsArrayBuffer(e)}else try{t(JSON.stringify(e))}catch(n){console.error("Couldn't convert value into a JSON string: ",e),t(null,n)}}function k(e){if(e.substring(0,he)!==de)return JSON.parse(e);var t,n=e.substring(Se),r=e.substring(he,Se);if(r===ve&&le.test(n)){var i=n.match(le);t=i[1],n=n.substring(i[0].length)}var a=P(n);switch(r){case pe:return a;case ve:return o([a],{type:t});case be:return new Int8Array(a);case ye:return new Uint8Array(a);case ge:return new Uint8ClampedArray(a);case me:return new Int16Array(a);case xe:return new Uint16Array(a);case we:return new Int32Array(a);case Ee:return new Uint32Array(a);case je:return new Float32Array(a);case Oe:return new Float64Array(a);default:throw new Error("Unkown type: "+r)}}function T(e){var t=this,n={db:null};if(e)for(var r in e)n[r]="string"!=typeof e[r]?e[r].toString():e[r];var o=new ie(function(e,r){try{n.db=openDatabase(n.name,String(n.version),n.description,n.size)}catch(e){return r(e)}n.db.transaction(function(o){o.executeSql("CREATE TABLE IF NOT EXISTS "+n.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){t._dbInfo=n,e()},function(e,t){r(t)})})});return n.serializer=_e,o}function C(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT * FROM "+o.storeName+" WHERE key = ? LIMIT 1",[e],function(e,n){var r=n.rows.length?n.rows.item(0).value:null;r&&(r=o.serializer.deserialize(r)),t(r)},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function R(e,t){var n=this,r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT * FROM "+o.storeName,[],function(n,r){for(var i=r.rows,a=i.length,s=0;s0)return void i(q.apply(o,[e,s,n,r-1]));a(t)}})})}).catch(a)});return i(a,n),a}function L(e,t,n){return q.apply(this,[e,t,n,1])}function D(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("DELETE FROM "+o.storeName+" WHERE key = ?",[e],function(){t()},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function B(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("DELETE FROM "+r.storeName,[],function(){e()},function(e,t){n(t)})})}).catch(n)});return i(n,e),n}function F(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("SELECT COUNT(key) as c FROM "+r.storeName,[],function(t,n){var r=n.rows.item(0).c;e(r)},function(e,t){n(t)})})}).catch(n)});return i(n,e),n}function z(e,t){var n=this,r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT key FROM "+o.storeName+" WHERE id = ? LIMIT 1",[e+1],function(e,n){var r=n.rows.length?n.rows.item(0).key:null;t(r)},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function U(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("SELECT key FROM "+r.storeName,[],function(t,n){for(var r=[],o=0;o=0;n--){var r=localStorage.key(n);0===r.indexOf(e)&&localStorage.removeItem(r)}});return i(n,e),n}function J(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=n.ready().then(function(){var t=n._dbInfo,r=localStorage.getItem(t.keyPrefix+e);return r&&(r=t.serializer.deserialize(r)),r});return i(r,t),r}function G(e,t){var n=this,r=n.ready().then(function(){for(var t=n._dbInfo,r=t.keyPrefix,o=r.length,i=localStorage.length,a=1,s=0;s=e.length-1||t<0?0:t+1}function getCurrentProblem(e){return e[config.currentIndex]}function previousProblem(){console.log("previousProblem!"),previousProblemButtonEl.classList.add("active"),config.currentIndex=config.shuffle?getRandomIndex(problems):getPreviousIndex(problems),updateLocalstore(config).then(function(){window.location.reload()})}function nextProblem(){console.log("nextProblem!"), nextProblemButtonEl.classList.add("active"),config.currentIndex=config.shuffle?getRandomIndex(problems):getNextIndex(problems),updateLocalstore(config).then(function(){window.location.reload()})}function toggleShuffle(){console.log("toggle shuffle!"),config.shuffle=!config.shuffle,shuffleProblemsButtonEl.classList.toggle("active"),previousProblemButtonEl.parentNode.classList.toggle("hidden"),updateLocalstore(config)}function loadProblem(e){currentProblem=e,problemEl.innerText=e.prompt,e.given&&(codeEl.value=e.given),testSuite(null,!0)}function updateTests(e,t){!0===t&&buildTests(currentProblem.tests),updateTestStatus(e)}function buildTests(e){if(e){var t=e.map(function(e){return'
\n
[✘]
\n
'+e.name+"
\n
"}).join("");testSuiteEl.innerHTML=t}}function updateTestStatus(e){if(!e)throw new Error("No testStatuses provided.");var t=!0;e.forEach(function(e){!0!==e&&(t=!1)}),[].slice.call(testSuiteEl.querySelectorAll(".test-state")).forEach(function(t,n){!0===e[n]?(t.innerHTML="[✓]",t.classList.remove("fail"),t.classList.add("pass")):(t.innerHTML="[✘]",t.classList.remove("pass"),t.classList.add("fail"))}),!0===t?(testTotalEl.innerText="PASS",testTotalEl.classList.remove("fail"),testTotalEl.classList.add("pass")):(testTotalEl.innerText="FAIL",testTotalEl.classList.remove("pass"),testTotalEl.classList.add("fail"))}function printAssertError(e){var t="";null!==e&&(t='\n
\n Expected: '+JSON.stringify(e.expected)+"\n Actual: "+JSON.stringify(e.actual)+"\n
"),assertConsoleEl.innerHTML=t}function printEvalOutput(e,t){var n="";e&&void 0!==e.message?n='\n
\n Syntax Error: '+JSON.stringify(e.message)+"\n
":t&&(n='\n
\n Output: '+JSON.stringify(t)+"\n
"),evalConsoleEl.innerHTML=n}function testSuite(e){testTotalEl.classList.toggle("working");var t=getOutput(codeEl.value),n=runTests(t);testTotalEl.classList.toggle("working"),updateTests(n,e)}function getOutput(code){var evald=!1;try{evald=eval("(function(){"+code+"})()"),printEvalOutput(null,evald)}catch(e){printEvalOutput(e)}return evald}function runTests(e){return currentProblem.tests.map(function(t){var n=!1;try{e&&(n=t.test(e)),printAssertError(null)}catch(e){printAssertError(e)}return n})}function loadApp(e){function t(t){!1===e.shuffle&&13===t.keyCode&&t.shiftKey&&(t.metaKey||t.ctrlKey)?previousProblem():13!==t.keyCode||t.shiftKey||!t.metaKey&&!t.ctrlKey||nextProblem()}console.log("loading app!"),!0===e.shuffle&&(shuffleProblemsButtonEl.classList.add("active"),previousProblemButtonEl.parentNode.classList.add("hidden"));var n=debounce(function(e){-1===ignoreKeyCodes.indexOf(e.keyCode)&&testSuite()},200);codeEl.addEventListener("keydown",n),document.addEventListener("keydown",t),shuffleProblemsButtonEl.addEventListener("click",toggleShuffle),previousProblemButtonEl.addEventListener("click",previousProblem),nextProblemButtonEl.addEventListener("click",nextProblem),loadProblem(getCurrentProblem(problems)),testSuite(!0)}var localforage=require("localforage"),problems=require("../problems/arrays.js"),currentProblem=void 0,ignoreKeyCodes=[9,37,39,38,40],config={shuffle:!0,timer:!1,currentIndex:0};localforage.getItem("js_practice_config").then(function(e){e&&(config=e),loadApp(config)}).catch(function(e){console.log("localforage err:",e),loadApp(config)});var problemEl=document.getElementById("problem"),codeEl=document.getElementById("code"),testSuiteEl=document.getElementById("test-suite"),testTotalEl=document.getElementById("test-total"),evalConsoleEl=document.getElementById("eval-output"),assertConsoleEl=document.getElementById("assert-output"),shuffleProblemsButtonEl=document.getElementById("shuffle-problems"),previousProblemButtonEl=document.getElementById("prev-problem"),nextProblemButtonEl=document.getElementById("next-problem")}(document,window)},{"../problems/arrays.js":39,localforage:35}],39:[function(e,t,n){"use strict";var r=e("chai").assert;t.exports=[{name:"Create Array",time:10,prompt:"Create and return an array that contains 'apple' and 'banana'",given:"const fruits = [];\rreturn fruits;",answer:"const fruits = ['apple', 'banana'];\n return fruits;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["apple","banana"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 2 items",test:function(e){return void 0===r.lengthOf(e,2)}}]},{name:"Access Array by index (first)",time:10,prompt:"Return the first value of the Array",given:"const fruits = ['apple', 'banana'];\r",answer:"const fruits = ['apple', 'banana'];\n return fruits[0];",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,"apple")}},{name:"Returns a String",test:function(e){return void 0===r.isString(e)}}]},{name:"Access Array by index (last)",time:10,prompt:"Return the last value of the Array",given:"const fruits = ['apple', 'banana', 'orange'];\r",answer:"const fruits = ['apple', 'banana', 'orange'];\n return fruits[fruits.length - 1];",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,"orange")}},{name:"Returns a String",test:function(e){return void 0===r.isString(e)}}]},{name:"Access Array by index (second)",time:10,prompt:"Return the second value of the Array",given:"const fruits = ['apple', 'banana'];\r",answer:"const fruits = ['apple', 'banana'];\n return fruits[1];",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,"banana")}},{name:"Returns a String",test:function(e){return void 0===r.isString(e)}}]},{name:"Array.forEach()",time:20,prompt:"Loop over the array, add an 'x' to the end of each name, push each fruit into a new array, then return the new array.",given:"const fruits = ['apple', 'banana'];\r",answer:"const fruits = ['apple', 'banana'];\n const newFruits = [];\n fruits.forEach(function(item) {\n newFruits.push(item+'x');\n });\n return newFruits;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["applex","bananax"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 2 items",test:function(e){return void 0===r.lengthOf(e,2)}}]},{name:"Array.push()",time:10,prompt:"Add 'orange' to the end of the 'fruits' array and return 'fruits'.",given:"const fruits = ['apple', 'banana'];\r",answer:"const fruits = ['apple', 'banana'];\n fruits.push('orange');\n return fruits;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["apple","banana","orange"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 3 items",test:function(e){return void 0===r.lengthOf(e,3)}}]},{name:"Array.pop()",time:10,prompt:"Remove 'orange' from the end of the 'fruits' array and return 'fruits'.",given:"const fruits = ['apple', 'banana', 'orange'];\r",answer:"const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["apple","banana"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 2 items",test:function(e){return void 0===r.lengthOf(e,2)}}]},{name:"Array.shift()",time:10,prompt:"Remove 'apple' from the front of the 'fruits' array and return 'fruits'.",given:"const fruits = ['apple', 'banana', 'orange'];\r",answer:"const fruits = ['apple', 'banana', 'orange'];\n fruits.shift();\n return fruits;",tests:[{name:"Output must be correct",test:function(e){return void 0===r.deepEqual(e,["banana","orange"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 2 items",test:function(e){return void 0===r.lengthOf(e,2)}}]},{name:"Array.unshift()",time:10,prompt:"Add 'strawberry' to the front of the 'fruits' array and return 'fruits'.",given:"const fruits = ['apple', 'banana', 'orange'];\r",answer:"const fruits = ['apple', 'banana', 'orange'];\n fruits.unshift('strawberry');\n return fruits;",tests:[{name:"Output must be correct",test:function(e){return void 0===r.deepEqual(e,["strawberry","apple","banana","orange"])}},{name:"Must return an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 4 items",test:function(e){return void 0===r.lengthOf(e,4)}}]},{name:"Array.indexOf()",time:10,prompt:"Return the index of 'banana' in the Array.",given:"const fruits = ['strawberry', 'banana', 'mango'];\r",answer:"const fruits = ['strawberry', 'banana', 'mango'];\n const ind = fruits.indexOf('banana');\n return ind;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,1)}},{name:"Returns a Number",test:function(e){return void 0===r.isNumber(e)}}]},{name:"Array.concat()",time:10,prompt:"Merge the two arrays using Array's 'concat()' method. Return the resulting array.",given:"const fruits = ['strawberry', 'banana'];\rconst otherFruits = ['pear','peach'];\r",answer:"const fruits = ['strawberry', 'banana'];\n const otherFruits = ['pear','peach'];\n const allTheFruits = fruits.concat(otherFruits);\n return allTheFruits;\r",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["strawberry","banana","pear","peach"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 4 items",test:function(e){return void 0===r.lengthOf(e,4)}}]},{name:"Array.join()",time:10,prompt:"Mix the two flavors with a '-' using Array's 'join' method. Return the resulting hybrid flavor.",given:"const fruits = ['strawberry', 'banana'];\r",answer:"const fruits = ['strawberry', 'banana'];\n const hybrid = fruits.join('-');\n return hybrid;\r",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,"strawberry-banana")}},{name:"Returns a String",test:function(e){return void 0===r.isString(e)}}]},{name:"Array.slice()",time:20,prompt:"Return just the citrus fruits from the 'fruits' array using 'Array.slice()'",given:"const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\r",answer:"const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const citrus = fruits.slice(1, 3);\n return citrus;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["orange","lemon"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 2 items",test:function(e){return void 0===r.lengthOf(e,2)}}]},{name:"Array.reverse()",time:10,prompt:"Reverse the order of the 'fruit' array using 'Array.reverse()'",given:"const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\r",answer:"const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const stiurf = fruits.reverse();\n return stiurf;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["banana","lemon","orange","strawberry"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 4 items",test:function(e){return void 0===r.lengthOf(e,4)}},{name:"First item is 'banana'",test:function(e){return void 0===r.deepEqual(e[0],"banana")}}]},{name:"Array.sort()",time:10,prompt:"Sort the order of the 'fruit' array using 'Array.sort()'",given:"const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\r",answer:"const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const orderlyFruit = fruits.sort();\n return orderlyFruit;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["banana","lemon","orange","strawberry"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 4 items",test:function(e){return void 0===r.lengthOf(e,4)}},{name:"First item is 'banana'",test:function(e){return void 0===r.deepEqual(e[0],"banana")}}]},{name:"Array.lastIndexOf()",time:10,prompt:"Return the index of the last 'peach' instance in the 'fruit' array using 'Array.lastIndexOf()'",given:"const fruits = ['peach', 'orange', 'lemon', 'peach'];\r",answer:"const fruits = ['peach', 'orange', 'lemon', 'peach'];\n const wheresTheLastPeach = fruits.lastIndexOf('peach');\n return wheresTheLastPeach;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,3)}},{name:"Returns a Number",test:function(e){return void 0===r.isNumber(e)}}]},{name:"Array.filter()",time:10,prompt:"Return an array of the numbers greater than 5 in 'numbers' using 'Array.filter()'",given:"const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\r",answer:"const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\n const overFive = numbers.filter(num => num > 5);\n return overFive;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,[8,13,21])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 3 items",test:function(e){return void 0===r.lengthOf(e,3)}},{name:"First item is 8",test:function(e){return void 0===r.deepEqual(e[0],8)}}]},{name:"Array.map()",time:10,prompt:"Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'",given:"const numbers = [25, 121, 169];\r",answer:"const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,[5,11,13])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 3 items",test:function(e){return void 0===r.lengthOf(e,3)}},{name:"First item is 5",test:function(e){return void 0===r.deepEqual(e[0],5)}},{name:"Last item is 13",test:function(e){return void 0===r.deepEqual(e[e.length-1],13)}}]},{name:"Array.every()",time:10,prompt:"Return object that returns whether each array contains all even numbers using Array.every().",given:"\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 5, 6, 8];\nfunction isEven(element) {\n\n}\nreturn {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n};",answer:"\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 5, 6, 8];\nfunction isEven(element) {\n return element % 2 === 0\n}\nreturn {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n};",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,{evenNumbers:!0,someOddNumbers:!1})}},{name:"Returns an Object",test:function(e){return void 0===r.isObject(e)}},{name:"Object has 2 items",test:function(e){return void 0===r.lengthOf(Object.keys(e),2)}},{name:"First value is true",test:function(e){return void 0===r.isTrue(e.evenNumbers)}},{name:"Second value is false",test:function(e){return void 0===r.isFalse(e.someOddNumbers)}}]},{name:"Array.some()",time:10,prompt:"Return object that returns whether each array contains some odd numbers using Array.some().",given:"\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 4, 7, 8];\nfunction isOdd(element) {\n\n}\nreturn {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n};",answer:"\nconst evenNumbers = [1, 3, 5, 7];\nconst someOddNumbers = [1, 3, 6, 7];\nfunction isOdd(element) {\n return element % 2 !== 0;\n}\nreturn {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n};",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,{evenNumbers:!1,someOddNumbers:!0})}},{name:"Returns an Object",test:function(e){return void 0===r.isObject(e)}},{name:"Object has 2 items",test:function(e){return void 0===r.lengthOf(Object.keys(e),2)}},{name:"First value is false",test:function(e){return void 0===r.isFalse(e.evenNumbers)}},{name:"Second value is true",test:function(e){return void 0===r.isTrue(e.someOddNumbers)}}]}]},{chai:2}]},{},[38]); +======= +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o num > 5); + return overFive;`, + tests: [ + { + name: 'Correct output', + test: `assert.deepEqual(output, [8, 13, 21]) === undefined;` + }, + { + name: 'Returns an Array', + test: `assert.isArray(output) === undefined;` + }, + { + name: 'Array has 3 items', + test: `assert.lengthOf(output, 3) === undefined;` + }, + { + name: `First item is 8`, + test: `assert.deepEqual(output[0], 8) === undefined;` + } + ] + }, + { + name: 'Array.map()', + time: 10, + prompt: `Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`, + given: `const numbers = [25, 121, 169];\r`, + answer: `const numbers = [25, 121, 169]; + const roots = numbers.map(num => Math.sqrt(num)); + return roots;`, + tests: [ + { + name: 'Correct output', + test: `assert.deepEqual(output, [5, 11, 13]) === undefined;` + }, + { + name: 'Returns an Array', + test: `assert.isArray(output) === undefined;` + }, + { + name: 'Array has 3 items', + test: `assert.lengthOf(output, 3) === undefined;` + }, + { + name: `First item is 5`, + test: `assert.deepEqual(output[0], 5) === undefined;` + }, + { + name: `Last item is 13`, + test: `assert.deepEqual(output[output.length - 1], 13) === undefined;` + } + ] + }, + { + name: 'Array.every()', + time: 10, + prompt: `Return object that returns whether each array contains all even numbers using Array.every().`, + given: `const evenNumbers = [2, 4, 6, 8]; + const someOddNumbers = [2, 5, 6, 8]; + function isEven(element) { + + } + return { + evenNumbers: evenNumbers., + someOddNumbers: someOddNumbers. + };`, + answer: `const evenNumbers = [2, 4, 6, 8]; + const someOddNumbers = [2, 5, 6, 8]; + function isEven(element) { + return element % 2 === 0 + } + return { + evenNumbers: evenNumbers.every(isEven), + someOddNumbers: someOddNumbers.every(isEven) + };`, + tests: [ + { + name: 'Correct output', + test: `assert.deepEqual(output, { + evenNumbers: true, + someOddNumbers: false + }) === undefined;` + }, + { + name: 'Returns an Object', + test: `assert.isObject(output) === undefined;` + }, + { + name: 'Object has 2 items', + test: `assert.lengthOf(Object.keys(output), 2) === undefined;` + }, + { + name: `First value is true`, + test: `assert.isTrue(output.evenNumbers) === undefined;` + }, + { + name: `Second value is false`, + test: `assert.isFalse(output.someOddNumbers) === undefined;` + } + ] + }, + { + name: 'Array.some()', + time: 10, + prompt: `Return 'Object' that returns whether each array contains some odd numbers using 'Array.some()'.`, + given: `const evenNumbers = [2, 4, 6, 8]; + const someOddNumbers = [2, 4, 7, 8]; + function isOdd(element) { + + } + return { + evenNumbers: evenNumbers., + someOddNumbers: someOddNumbers. + };`, + answer: `const evenNumbers = [1, 3, 5, 7]; + const someOddNumbers = [1, 3, 6, 7]; + function isOdd(element) { + return element % 2 !== 0; + } + return { + evenNumbers: evenNumbers.some(isOdd), + someOddNumbers: someOddNumbers.some(isOdd) + };`, + tests: [ + { + name: 'Correct output', + test: `assert.deepEqual(output, { + evenNumbers: false, + someOddNumbers: true + }) === undefined;` + }, + { + name: 'Returns an Object', + test: `assert.isObject(output) === undefined;` + }, + { + name: 'Object has 2 items', + test: `assert.lengthOf(Object.keys(output), 2) === undefined;` + }, + { + name: `First value is false`, + test: `assert.isFalse(output.evenNumbers) === undefined;` + }, + { + name: `Second value is true`, + test: `assert.isTrue(output.someOddNumbers) === undefined;` + } + ] + } + // Next problems to create: + // forEach? fix one above that tried, but can't verify forEach was used + // some + // reduce + // reduceRight + // Array.from and other ways to turn array-like into array +]; + +},{}],3:[function(require,module,exports){ +module.exports = [ + { + name: 'Create Array', + time: 10, + prompt: 'Create and return an array that contains \'apple\' and \'banana\'', + given: `const fruits = [];\rreturn fruits;`, + answer: `const fruits = ['apple', 'banana']; + return fruits;`, + tests: [ + { + name: 'Correct output', + test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;` + }, + { + name: 'Returns an Array', + test: `assert.isArray(output) === undefined;` + }, + { + name: 'Array has 2 items', + test: `assert.lengthOf(output, 2) === undefined;` + } + ] + }, + { + name: 'Array.pop()', + time: 10, + prompt: `Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`, + given: `const fruits = ['apple', 'banana', 'orange'];\r`, + answer: `const fruits = ['apple', 'banana', 'orange']; + fruits.pop(); + return fruits;`, + tests: [ + { + name: 'Correct output', + test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;` + }, + { + name: 'Returns an Array', + test: `assert.isArray(output) === undefined;` + }, + { + name: 'Array has 2 items', + test: `assert.lengthOf(output, 2) === undefined;` + } + ] + }, +] + +},{}],4:[function(require,module,exports){ +/*! + * assertion-error + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ + +/*! + * Return a function that will copy properties from + * one object to another excluding any originally + * listed. Returned function will create a new `{}`. + * + * @param {String} excluded properties ... + * @return {Function} + */ + +function exclude () { + var excludes = [].slice.call(arguments); + + function excludeProps (res, obj) { + Object.keys(obj).forEach(function (key) { + if (!~excludes.indexOf(key)) res[key] = obj[key]; + }); + } + + return function extendExclude () { + var args = [].slice.call(arguments) + , i = 0 + , res = {}; + + for (; i < args.length; i++) { + excludeProps(res, args[i]); + } + + return res; + }; +}; + +/*! + * Primary Exports + */ + +module.exports = AssertionError; + +/** + * ### AssertionError + * + * An extension of the JavaScript `Error` constructor for + * assertion and validation scenarios. + * + * @param {String} message + * @param {Object} properties to include (optional) + * @param {callee} start stack function (optional) + */ + +function AssertionError (message, _props, ssf) { + var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON') + , props = extend(_props || {}); + + // default values + this.message = message || 'Unspecified AssertionError'; + this.showDiff = false; + + // copy from properties + for (var key in props) { + this[key] = props[key]; + } + + // capture stack trace + ssf = ssf || arguments.callee; + if (ssf && Error.captureStackTrace) { + Error.captureStackTrace(this, ssf); + } else { + try { + throw new Error(); + } catch(e) { + this.stack = e.stack; + } + } +} + +/*! + * Inherit from Error.prototype + */ + +AssertionError.prototype = Object.create(Error.prototype); + +/*! + * Statically set name + */ + +AssertionError.prototype.name = 'AssertionError'; + +/*! + * Ensure correct constructor + */ + +AssertionError.prototype.constructor = AssertionError; + +/** + * Allow errors to be converted to JSON for static transfer. + * + * @param {Boolean} include stack (default: `true`) + * @return {Object} object that can be `JSON.stringify` + */ + +AssertionError.prototype.toJSON = function (stack) { + var extend = exclude('constructor', 'toJSON', 'stack') + , props = extend({ name: this.name }, this); + + // include stack if exists and not turned off + if (false !== stack && this.stack) { + props.stack = this.stack; + } + + return props; +}; + +},{}],5:[function(require,module,exports){ +module.exports = require('./lib/chai'); + +},{"./lib/chai":6}],6:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +var used = [] + , exports = module.exports = {}; + +/*! + * Chai version + */ + +exports.version = '3.5.0'; + +/*! + * Assertion Error + */ + +exports.AssertionError = require('assertion-error'); + +/*! + * Utils for plugins (not exported) + */ + +var util = require('./chai/utils'); + +/** + * # .use(function) + * + * Provides a way to extend the internals of Chai + * + * @param {Function} + * @returns {this} for chaining + * @api public + */ + +exports.use = function (fn) { + if (!~used.indexOf(fn)) { + fn(this, util); + used.push(fn); + } + + return this; +}; + +/*! + * Utility Functions + */ + +exports.util = util; + +/*! + * Configuration + */ + +var config = require('./chai/config'); +exports.config = config; + +/*! + * Primary `Assertion` prototype + */ + +var assertion = require('./chai/assertion'); +exports.use(assertion); + +/*! + * Core Assertions + */ + +var core = require('./chai/core/assertions'); +exports.use(core); + +/*! + * Expect interface + */ + +var expect = require('./chai/interface/expect'); +exports.use(expect); + +/*! + * Should interface + */ + +var should = require('./chai/interface/should'); +exports.use(should); + +/*! + * Assert interface + */ + +var assert = require('./chai/interface/assert'); +exports.use(assert); + +},{"./chai/assertion":7,"./chai/config":8,"./chai/core/assertions":9,"./chai/interface/assert":10,"./chai/interface/expect":11,"./chai/interface/should":12,"./chai/utils":26,"assertion-error":4}],7:[function(require,module,exports){ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +var config = require('./config'); + +module.exports = function (_chai, util) { + /*! + * Module dependencies. + */ + + var AssertionError = _chai.AssertionError + , flag = util.flag; + + /*! + * Module export. + */ + + _chai.Assertion = Assertion; + + /*! + * Assertion Constructor + * + * Creates object for chaining. + * + * @api private + */ + + function Assertion (obj, msg, stack) { + flag(this, 'ssfi', stack || arguments.callee); + flag(this, 'object', obj); + flag(this, 'message', msg); + } + + Object.defineProperty(Assertion, 'includeStack', { + get: function() { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + return config.includeStack; + }, + set: function(value) { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + config.includeStack = value; + } + }); + + Object.defineProperty(Assertion, 'showDiff', { + get: function() { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + return config.showDiff; + }, + set: function(value) { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + config.showDiff = value; + } + }); + + Assertion.addProperty = function (name, fn) { + util.addProperty(this.prototype, name, fn); + }; + + Assertion.addMethod = function (name, fn) { + util.addMethod(this.prototype, name, fn); + }; + + Assertion.addChainableMethod = function (name, fn, chainingBehavior) { + util.addChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + Assertion.overwriteProperty = function (name, fn) { + util.overwriteProperty(this.prototype, name, fn); + }; + + Assertion.overwriteMethod = function (name, fn) { + util.overwriteMethod(this.prototype, name, fn); + }; + + Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) { + util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + /** + * ### .assert(expression, message, negateMessage, expected, actual, showDiff) + * + * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. + * + * @name assert + * @param {Philosophical} expression to be tested + * @param {String|Function} message or function that returns message to display if expression fails + * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails + * @param {Mixed} expected value (remember to check for negation) + * @param {Mixed} actual (optional) will default to `this.obj` + * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails + * @api private + */ + + Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) { + var ok = util.test(this, arguments); + if (true !== showDiff) showDiff = false; + if (true !== config.showDiff) showDiff = false; + + if (!ok) { + var msg = util.getMessage(this, arguments) + , actual = util.getActual(this, arguments); + throw new AssertionError(msg, { + actual: actual + , expected: expected + , showDiff: showDiff + }, (config.includeStack) ? this.assert : flag(this, 'ssfi')); + } + }; + + /*! + * ### ._obj + * + * Quick reference to stored `actual` value for plugin developers. + * + * @api private + */ + + Object.defineProperty(Assertion.prototype, '_obj', + { get: function () { + return flag(this, 'object'); + } + , set: function (val) { + flag(this, 'object', val); + } + }); +}; + +},{"./config":8}],8:[function(require,module,exports){ +module.exports = { + + /** + * ### config.includeStack + * + * User configurable property, influences whether stack trace + * is included in Assertion error message. Default of false + * suppresses stack trace in the error message. + * + * chai.config.includeStack = true; // enable stack on error + * + * @param {Boolean} + * @api public + */ + + includeStack: false, + + /** + * ### config.showDiff + * + * User configurable property, influences whether or not + * the `showDiff` flag should be included in the thrown + * AssertionErrors. `false` will always be `false`; `true` + * will be true when the assertion has requested a diff + * be shown. + * + * @param {Boolean} + * @api public + */ + + showDiff: true, + + /** + * ### config.truncateThreshold + * + * User configurable property, sets length threshold for actual and + * expected values in assertion errors. If this threshold is exceeded, for + * example for large data structures, the value is replaced with something + * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. + * + * Set it to zero if you want to disable truncating altogether. + * + * This is especially userful when doing assertions on arrays: having this + * set to a reasonable large value makes the failure messages readily + * inspectable. + * + * chai.config.truncateThreshold = 0; // disable truncating + * + * @param {Number} + * @api public + */ + + truncateThreshold: 40 + +}; + +},{}],9:[function(require,module,exports){ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, _) { + var Assertion = chai.Assertion + , toString = Object.prototype.toString + , flag = _.flag; + + /** + * ### Language Chains + * + * The following are provided as chainable getters to + * improve the readability of your assertions. They + * do not provide testing capabilities unless they + * have been overwritten by a plugin. + * + * **Chains** + * + * - to + * - be + * - been + * - is + * - that + * - which + * - and + * - has + * - have + * - with + * - at + * - of + * - same + * + * @name language chains + * @namespace BDD + * @api public + */ + + [ 'to', 'be', 'been' + , 'is', 'and', 'has', 'have' + , 'with', 'that', 'which', 'at' + , 'of', 'same' ].forEach(function (chain) { + Assertion.addProperty(chain, function () { + return this; + }); + }); + + /** + * ### .not + * + * Negates any of assertions following in the chain. + * + * expect(foo).to.not.equal('bar'); + * expect(goodFn).to.not.throw(Error); + * expect({ foo: 'baz' }).to.have.property('foo') + * .and.not.equal('bar'); + * + * @name not + * @namespace BDD + * @api public + */ + + Assertion.addProperty('not', function () { + flag(this, 'negate', true); + }); + + /** + * ### .deep + * + * Sets the `deep` flag, later used by the `equal` and + * `property` assertions. + * + * expect(foo).to.deep.equal({ bar: 'baz' }); + * expect({ foo: { bar: { baz: 'quux' } } }) + * .to.have.deep.property('foo.bar.baz', 'quux'); + * + * `.deep.property` special characters can be escaped + * by adding two slashes before the `.` or `[]`. + * + * var deepCss = { '.link': { '[target]': 42 }}; + * expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42); + * + * @name deep + * @namespace BDD + * @api public + */ + + Assertion.addProperty('deep', function () { + flag(this, 'deep', true); + }); + + /** + * ### .any + * + * Sets the `any` flag, (opposite of the `all` flag) + * later used in the `keys` assertion. + * + * expect(foo).to.have.any.keys('bar', 'baz'); + * + * @name any + * @namespace BDD + * @api public + */ + + Assertion.addProperty('any', function () { + flag(this, 'any', true); + flag(this, 'all', false) + }); + + + /** + * ### .all + * + * Sets the `all` flag (opposite of the `any` flag) + * later used by the `keys` assertion. + * + * expect(foo).to.have.all.keys('bar', 'baz'); + * + * @name all + * @namespace BDD + * @api public + */ + + Assertion.addProperty('all', function () { + flag(this, 'all', true); + flag(this, 'any', false); + }); + + /** + * ### .a(type) + * + * The `a` and `an` assertions are aliases that can be + * used either as language chains or to assert a value's + * type. + * + * // typeof + * expect('test').to.be.a('string'); + * expect({ foo: 'bar' }).to.be.an('object'); + * expect(null).to.be.a('null'); + * expect(undefined).to.be.an('undefined'); + * expect(new Error).to.be.an('error'); + * expect(new Promise).to.be.a('promise'); + * expect(new Float32Array()).to.be.a('float32array'); + * expect(Symbol()).to.be.a('symbol'); + * + * // es6 overrides + * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo'); + * + * // language chain + * expect(foo).to.be.an.instanceof(Foo); + * + * @name a + * @alias an + * @param {String} type + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function an (type, msg) { + if (msg) flag(this, 'message', msg); + type = type.toLowerCase(); + var obj = flag(this, 'object') + , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a '; + + this.assert( + type === _.type(obj) + , 'expected #{this} to be ' + article + type + , 'expected #{this} not to be ' + article + type + ); + } + + Assertion.addChainableMethod('an', an); + Assertion.addChainableMethod('a', an); + + /** + * ### .include(value) + * + * The `include` and `contain` assertions can be used as either property + * based language chains or as methods to assert the inclusion of an object + * in an array or a substring in a string. When used as language chains, + * they toggle the `contains` flag for the `keys` assertion. + * + * expect([1,2,3]).to.include(2); + * expect('foobar').to.contain('foo'); + * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo'); + * + * @name include + * @alias contain + * @alias includes + * @alias contains + * @param {Object|String|Number} obj + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function includeChainingBehavior () { + flag(this, 'contains', true); + } + + function include (val, msg) { + _.expectTypes(this, ['array', 'object', 'string']); + + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var expected = false; + + if (_.type(obj) === 'array' && _.type(val) === 'object') { + for (var i in obj) { + if (_.eql(obj[i], val)) { + expected = true; + break; + } + } + } else if (_.type(val) === 'object') { + if (!flag(this, 'negate')) { + for (var k in val) new Assertion(obj).property(k, val[k]); + return; + } + var subset = {}; + for (var k in val) subset[k] = obj[k]; + expected = _.eql(subset, val); + } else { + expected = (obj != undefined) && ~obj.indexOf(val); + } + this.assert( + expected + , 'expected #{this} to include ' + _.inspect(val) + , 'expected #{this} to not include ' + _.inspect(val)); + } + + Assertion.addChainableMethod('include', include, includeChainingBehavior); + Assertion.addChainableMethod('contain', include, includeChainingBehavior); + Assertion.addChainableMethod('contains', include, includeChainingBehavior); + Assertion.addChainableMethod('includes', include, includeChainingBehavior); + + /** + * ### .ok + * + * Asserts that the target is truthy. + * + * expect('everything').to.be.ok; + * expect(1).to.be.ok; + * expect(false).to.not.be.ok; + * expect(undefined).to.not.be.ok; + * expect(null).to.not.be.ok; + * + * @name ok + * @namespace BDD + * @api public + */ + + Assertion.addProperty('ok', function () { + this.assert( + flag(this, 'object') + , 'expected #{this} to be truthy' + , 'expected #{this} to be falsy'); + }); + + /** + * ### .true + * + * Asserts that the target is `true`. + * + * expect(true).to.be.true; + * expect(1).to.not.be.true; + * + * @name true + * @namespace BDD + * @api public + */ + + Assertion.addProperty('true', function () { + this.assert( + true === flag(this, 'object') + , 'expected #{this} to be true' + , 'expected #{this} to be false' + , this.negate ? false : true + ); + }); + + /** + * ### .false + * + * Asserts that the target is `false`. + * + * expect(false).to.be.false; + * expect(0).to.not.be.false; + * + * @name false + * @namespace BDD + * @api public + */ + + Assertion.addProperty('false', function () { + this.assert( + false === flag(this, 'object') + , 'expected #{this} to be false' + , 'expected #{this} to be true' + , this.negate ? true : false + ); + }); + + /** + * ### .null + * + * Asserts that the target is `null`. + * + * expect(null).to.be.null; + * expect(undefined).to.not.be.null; + * + * @name null + * @namespace BDD + * @api public + */ + + Assertion.addProperty('null', function () { + this.assert( + null === flag(this, 'object') + , 'expected #{this} to be null' + , 'expected #{this} not to be null' + ); + }); + + /** + * ### .undefined + * + * Asserts that the target is `undefined`. + * + * expect(undefined).to.be.undefined; + * expect(null).to.not.be.undefined; + * + * @name undefined + * @namespace BDD + * @api public + */ + + Assertion.addProperty('undefined', function () { + this.assert( + undefined === flag(this, 'object') + , 'expected #{this} to be undefined' + , 'expected #{this} not to be undefined' + ); + }); + + /** + * ### .NaN + * Asserts that the target is `NaN`. + * + * expect('foo').to.be.NaN; + * expect(4).not.to.be.NaN; + * + * @name NaN + * @namespace BDD + * @api public + */ + + Assertion.addProperty('NaN', function () { + this.assert( + isNaN(flag(this, 'object')) + , 'expected #{this} to be NaN' + , 'expected #{this} not to be NaN' + ); + }); + + /** + * ### .exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi' + * , bar = null + * , baz; + * + * expect(foo).to.exist; + * expect(bar).to.not.exist; + * expect(baz).to.not.exist; + * + * @name exist + * @namespace BDD + * @api public + */ + + Assertion.addProperty('exist', function () { + this.assert( + null != flag(this, 'object') + , 'expected #{this} to exist' + , 'expected #{this} to not exist' + ); + }); + + + /** + * ### .empty + * + * Asserts that the target's length is `0`. For arrays and strings, it checks + * the `length` property. For objects, it gets the count of + * enumerable keys. + * + * expect([]).to.be.empty; + * expect('').to.be.empty; + * expect({}).to.be.empty; + * + * @name empty + * @namespace BDD + * @api public + */ + + Assertion.addProperty('empty', function () { + var obj = flag(this, 'object') + , expected = obj; + + if (Array.isArray(obj) || 'string' === typeof object) { + expected = obj.length; + } else if (typeof obj === 'object') { + expected = Object.keys(obj).length; + } + + this.assert( + !expected + , 'expected #{this} to be empty' + , 'expected #{this} not to be empty' + ); + }); + + /** + * ### .arguments + * + * Asserts that the target is an arguments object. + * + * function test () { + * expect(arguments).to.be.arguments; + * } + * + * @name arguments + * @alias Arguments + * @namespace BDD + * @api public + */ + + function checkArguments () { + var obj = flag(this, 'object') + , type = Object.prototype.toString.call(obj); + this.assert( + '[object Arguments]' === type + , 'expected #{this} to be arguments but got ' + type + , 'expected #{this} to not be arguments' + ); + } + + Assertion.addProperty('arguments', checkArguments); + Assertion.addProperty('Arguments', checkArguments); + + /** + * ### .equal(value) + * + * Asserts that the target is strictly equal (`===`) to `value`. + * Alternately, if the `deep` flag is set, asserts that + * the target is deeply equal to `value`. + * + * expect('hello').to.equal('hello'); + * expect(42).to.equal(42); + * expect(1).to.not.equal(true); + * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' }); + * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' }); + * + * @name equal + * @alias equals + * @alias eq + * @alias deep.equal + * @param {Mixed} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertEqual (val, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'deep')) { + return this.eql(val); + } else { + this.assert( + val === obj + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{exp}' + , val + , this._obj + , true + ); + } + } + + Assertion.addMethod('equal', assertEqual); + Assertion.addMethod('equals', assertEqual); + Assertion.addMethod('eq', assertEqual); + + /** + * ### .eql(value) + * + * Asserts that the target is deeply equal to `value`. + * + * expect({ foo: 'bar' }).to.eql({ foo: 'bar' }); + * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]); + * + * @name eql + * @alias eqls + * @param {Mixed} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertEql(obj, msg) { + if (msg) flag(this, 'message', msg); + this.assert( + _.eql(obj, flag(this, 'object')) + , 'expected #{this} to deeply equal #{exp}' + , 'expected #{this} to not deeply equal #{exp}' + , obj + , this._obj + , true + ); + } + + Assertion.addMethod('eql', assertEql); + Assertion.addMethod('eqls', assertEql); + + /** + * ### .above(value) + * + * Asserts that the target is greater than `value`. + * + * expect(10).to.be.above(5); + * + * Can also be used in conjunction with `length` to + * assert a minimum length. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.above(2); + * expect([ 1, 2, 3 ]).to.have.length.above(2); + * + * @name above + * @alias gt + * @alias greaterThan + * @param {Number} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertAbove (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len > n + , 'expected #{this} to have a length above #{exp} but got #{act}' + , 'expected #{this} to not have a length above #{exp}' + , n + , len + ); + } else { + this.assert( + obj > n + , 'expected #{this} to be above ' + n + , 'expected #{this} to be at most ' + n + ); + } + } + + Assertion.addMethod('above', assertAbove); + Assertion.addMethod('gt', assertAbove); + Assertion.addMethod('greaterThan', assertAbove); + + /** + * ### .least(value) + * + * Asserts that the target is greater than or equal to `value`. + * + * expect(10).to.be.at.least(10); + * + * Can also be used in conjunction with `length` to + * assert a minimum length. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.of.at.least(2); + * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3); + * + * @name least + * @alias gte + * @param {Number} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertLeast (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len >= n + , 'expected #{this} to have a length at least #{exp} but got #{act}' + , 'expected #{this} to have a length below #{exp}' + , n + , len + ); + } else { + this.assert( + obj >= n + , 'expected #{this} to be at least ' + n + , 'expected #{this} to be below ' + n + ); + } + } + + Assertion.addMethod('least', assertLeast); + Assertion.addMethod('gte', assertLeast); + + /** + * ### .below(value) + * + * Asserts that the target is less than `value`. + * + * expect(5).to.be.below(10); + * + * Can also be used in conjunction with `length` to + * assert a maximum length. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.below(4); + * expect([ 1, 2, 3 ]).to.have.length.below(4); + * + * @name below + * @alias lt + * @alias lessThan + * @param {Number} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertBelow (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len < n + , 'expected #{this} to have a length below #{exp} but got #{act}' + , 'expected #{this} to not have a length below #{exp}' + , n + , len + ); + } else { + this.assert( + obj < n + , 'expected #{this} to be below ' + n + , 'expected #{this} to be at least ' + n + ); + } + } + + Assertion.addMethod('below', assertBelow); + Assertion.addMethod('lt', assertBelow); + Assertion.addMethod('lessThan', assertBelow); + + /** + * ### .most(value) + * + * Asserts that the target is less than or equal to `value`. + * + * expect(5).to.be.at.most(5); + * + * Can also be used in conjunction with `length` to + * assert a maximum length. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.of.at.most(4); + * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3); + * + * @name most + * @alias lte + * @param {Number} value + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertMost (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len <= n + , 'expected #{this} to have a length at most #{exp} but got #{act}' + , 'expected #{this} to have a length above #{exp}' + , n + , len + ); + } else { + this.assert( + obj <= n + , 'expected #{this} to be at most ' + n + , 'expected #{this} to be above ' + n + ); + } + } + + Assertion.addMethod('most', assertMost); + Assertion.addMethod('lte', assertMost); + + /** + * ### .within(start, finish) + * + * Asserts that the target is within a range. + * + * expect(7).to.be.within(5,10); + * + * Can also be used in conjunction with `length` to + * assert a length range. The benefit being a + * more informative error message than if the length + * was supplied directly. + * + * expect('foo').to.have.length.within(2,4); + * expect([ 1, 2, 3 ]).to.have.length.within(2,4); + * + * @name within + * @param {Number} start lowerbound inclusive + * @param {Number} finish upperbound inclusive + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('within', function (start, finish, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , range = start + '..' + finish; + if (flag(this, 'doLength')) { + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + this.assert( + len >= start && len <= finish + , 'expected #{this} to have a length within ' + range + , 'expected #{this} to not have a length within ' + range + ); + } else { + this.assert( + obj >= start && obj <= finish + , 'expected #{this} to be within ' + range + , 'expected #{this} to not be within ' + range + ); + } + }); + + /** + * ### .instanceof(constructor) + * + * Asserts that the target is an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , Chai = new Tea('chai'); + * + * expect(Chai).to.be.an.instanceof(Tea); + * expect([ 1, 2, 3 ]).to.be.instanceof(Array); + * + * @name instanceof + * @param {Constructor} constructor + * @param {String} message _optional_ + * @alias instanceOf + * @namespace BDD + * @api public + */ + + function assertInstanceOf (constructor, msg) { + if (msg) flag(this, 'message', msg); + var name = _.getName(constructor); + this.assert( + flag(this, 'object') instanceof constructor + , 'expected #{this} to be an instance of ' + name + , 'expected #{this} to not be an instance of ' + name + ); + }; + + Assertion.addMethod('instanceof', assertInstanceOf); + Assertion.addMethod('instanceOf', assertInstanceOf); + + /** + * ### .property(name, [value]) + * + * Asserts that the target has a property `name`, optionally asserting that + * the value of that property is strictly equal to `value`. + * If the `deep` flag is set, you can use dot- and bracket-notation for deep + * references into objects and arrays. + * + * // simple referencing + * var obj = { foo: 'bar' }; + * expect(obj).to.have.property('foo'); + * expect(obj).to.have.property('foo', 'bar'); + * + * // deep referencing + * var deepObj = { + * green: { tea: 'matcha' } + * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ] + * }; + * + * expect(deepObj).to.have.deep.property('green.tea', 'matcha'); + * expect(deepObj).to.have.deep.property('teas[1]', 'matcha'); + * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha'); + * + * You can also use an array as the starting point of a `deep.property` + * assertion, or traverse nested arrays. + * + * var arr = [ + * [ 'chai', 'matcha', 'konacha' ] + * , [ { tea: 'chai' } + * , { tea: 'matcha' } + * , { tea: 'konacha' } ] + * ]; + * + * expect(arr).to.have.deep.property('[0][1]', 'matcha'); + * expect(arr).to.have.deep.property('[1][2].tea', 'konacha'); + * + * Furthermore, `property` changes the subject of the assertion + * to be the value of that property from the original object. This + * permits for further chainable assertions on that property. + * + * expect(obj).to.have.property('foo') + * .that.is.a('string'); + * expect(deepObj).to.have.property('green') + * .that.is.an('object') + * .that.deep.equals({ tea: 'matcha' }); + * expect(deepObj).to.have.property('teas') + * .that.is.an('array') + * .with.deep.property('[2]') + * .that.deep.equals({ tea: 'konacha' }); + * + * Note that dots and bracket in `name` must be backslash-escaped when + * the `deep` flag is set, while they must NOT be escaped when the `deep` + * flag is not set. + * + * // simple referencing + * var css = { '.link[target]': 42 }; + * expect(css).to.have.property('.link[target]', 42); + * + * // deep referencing + * var deepCss = { '.link': { '[target]': 42 }}; + * expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42); + * + * @name property + * @alias deep.property + * @param {String} name + * @param {Mixed} value (optional) + * @param {String} message _optional_ + * @returns value of property for chaining + * @namespace BDD + * @api public + */ + + Assertion.addMethod('property', function (name, val, msg) { + if (msg) flag(this, 'message', msg); + + var isDeep = !!flag(this, 'deep') + , descriptor = isDeep ? 'deep property ' : 'property ' + , negate = flag(this, 'negate') + , obj = flag(this, 'object') + , pathInfo = isDeep ? _.getPathInfo(name, obj) : null + , hasProperty = isDeep + ? pathInfo.exists + : _.hasProperty(name, obj) + , value = isDeep + ? pathInfo.value + : obj[name]; + + if (negate && arguments.length > 1) { + if (undefined === value) { + msg = (msg != null) ? msg + ': ' : ''; + throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name)); + } + } else { + this.assert( + hasProperty + , 'expected #{this} to have a ' + descriptor + _.inspect(name) + , 'expected #{this} to not have ' + descriptor + _.inspect(name)); + } + + if (arguments.length > 1) { + this.assert( + val === value + , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}' + , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}' + , val + , value + ); + } + + flag(this, 'object', value); + }); + + + /** + * ### .ownProperty(name) + * + * Asserts that the target has an own property `name`. + * + * expect('test').to.have.ownProperty('length'); + * + * @name ownProperty + * @alias haveOwnProperty + * @param {String} name + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertOwnProperty (name, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + this.assert( + obj.hasOwnProperty(name) + , 'expected #{this} to have own property ' + _.inspect(name) + , 'expected #{this} to not have own property ' + _.inspect(name) + ); + } + + Assertion.addMethod('ownProperty', assertOwnProperty); + Assertion.addMethod('haveOwnProperty', assertOwnProperty); + + /** + * ### .ownPropertyDescriptor(name[, descriptor[, message]]) + * + * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`. + * + * expect('test').to.have.ownPropertyDescriptor('length'); + * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 }); + * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 }); + * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false); + * expect('test').ownPropertyDescriptor('length').to.have.keys('value'); + * + * @name ownPropertyDescriptor + * @alias haveOwnPropertyDescriptor + * @param {String} name + * @param {Object} descriptor _optional_ + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertOwnPropertyDescriptor (name, descriptor, msg) { + if (typeof descriptor === 'string') { + msg = descriptor; + descriptor = null; + } + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); + if (actualDescriptor && descriptor) { + this.assert( + _.eql(descriptor, actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor) + , descriptor + , actualDescriptor + , true + ); + } else { + this.assert( + actualDescriptor + , 'expected #{this} to have an own property descriptor for ' + _.inspect(name) + , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name) + ); + } + flag(this, 'object', actualDescriptor); + } + + Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor); + Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor); + + /** + * ### .length + * + * Sets the `doLength` flag later used as a chain precursor to a value + * comparison for the `length` property. + * + * expect('foo').to.have.length.above(2); + * expect([ 1, 2, 3 ]).to.have.length.above(2); + * expect('foo').to.have.length.below(4); + * expect([ 1, 2, 3 ]).to.have.length.below(4); + * expect('foo').to.have.length.within(2,4); + * expect([ 1, 2, 3 ]).to.have.length.within(2,4); + * + * *Deprecation notice:* Using `length` as an assertion will be deprecated + * in version 2.4.0 and removed in 3.0.0. Code using the old style of + * asserting for `length` property value using `length(value)` should be + * switched to use `lengthOf(value)` instead. + * + * @name length + * @namespace BDD + * @api public + */ + + /** + * ### .lengthOf(value[, message]) + * + * Asserts that the target's `length` property has + * the expected value. + * + * expect([ 1, 2, 3]).to.have.lengthOf(3); + * expect('foobar').to.have.lengthOf(6); + * + * @name lengthOf + * @param {Number} length + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertLengthChain () { + flag(this, 'doLength', true); + } + + function assertLength (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + new Assertion(obj, msg).to.have.property('length'); + var len = obj.length; + + this.assert( + len == n + , 'expected #{this} to have a length of #{exp} but got #{act}' + , 'expected #{this} to not have a length of #{act}' + , n + , len + ); + } + + Assertion.addChainableMethod('length', assertLength, assertLengthChain); + Assertion.addMethod('lengthOf', assertLength); + + /** + * ### .match(regexp) + * + * Asserts that the target matches a regular expression. + * + * expect('foobar').to.match(/^foo/); + * + * @name match + * @alias matches + * @param {RegExp} RegularExpression + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + function assertMatch(re, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + this.assert( + re.exec(obj) + , 'expected #{this} to match ' + re + , 'expected #{this} not to match ' + re + ); + } + + Assertion.addMethod('match', assertMatch); + Assertion.addMethod('matches', assertMatch); + + /** + * ### .string(string) + * + * Asserts that the string target contains another string. + * + * expect('foobar').to.have.string('bar'); + * + * @name string + * @param {String} string + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('string', function (str, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + new Assertion(obj, msg).is.a('string'); + + this.assert( + ~obj.indexOf(str) + , 'expected #{this} to contain ' + _.inspect(str) + , 'expected #{this} to not contain ' + _.inspect(str) + ); + }); + + + /** + * ### .keys(key1, [key2], [...]) + * + * Asserts that the target contains any or all of the passed-in keys. + * Use in combination with `any`, `all`, `contains`, or `have` will affect + * what will pass. + * + * When used in conjunction with `any`, at least one key that is passed + * in must exist in the target object. This is regardless whether or not + * the `have` or `contain` qualifiers are used. Note, either `any` or `all` + * should be used in the assertion. If neither are used, the assertion is + * defaulted to `all`. + * + * When both `all` and `contain` are used, the target object must have at + * least all of the passed-in keys but may have more keys not listed. + * + * When both `all` and `have` are used, the target object must both contain + * all of the passed-in keys AND the number of keys in the target object must + * match the number of keys passed in (in other words, a target object must + * have all and only all of the passed-in keys). + * + * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz'); + * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo'); + * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz'); + * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']); + * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6}); + * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']); + * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7}); + * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']); + * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6}); + * + * + * @name keys + * @alias key + * @param {...String|Array|Object} keys + * @namespace BDD + * @api public + */ + + function assertKeys (keys) { + var obj = flag(this, 'object') + , str + , ok = true + , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments'; + + switch (_.type(keys)) { + case "array": + if (arguments.length > 1) throw (new Error(mixedArgsMsg)); + break; + case "object": + if (arguments.length > 1) throw (new Error(mixedArgsMsg)); + keys = Object.keys(keys); + break; + default: + keys = Array.prototype.slice.call(arguments); + } + + if (!keys.length) throw new Error('keys required'); + + var actual = Object.keys(obj) + , expected = keys + , len = keys.length + , any = flag(this, 'any') + , all = flag(this, 'all'); + + if (!any && !all) { + all = true; + } + + // Has any + if (any) { + var intersection = expected.filter(function(key) { + return ~actual.indexOf(key); + }); + ok = intersection.length > 0; + } + + // Has all + if (all) { + ok = keys.every(function(key){ + return ~actual.indexOf(key); + }); + if (!flag(this, 'negate') && !flag(this, 'contains')) { + ok = ok && keys.length == actual.length; + } + } + + // Key string + if (len > 1) { + keys = keys.map(function(key){ + return _.inspect(key); + }); + var last = keys.pop(); + if (all) { + str = keys.join(', ') + ', and ' + last; + } + if (any) { + str = keys.join(', ') + ', or ' + last; + } + } else { + str = _.inspect(keys[0]); + } + + // Form + str = (len > 1 ? 'keys ' : 'key ') + str; + + // Have / include + str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; + + // Assertion + this.assert( + ok + , 'expected #{this} to ' + str + , 'expected #{this} to not ' + str + , expected.slice(0).sort() + , actual.sort() + , true + ); + } + + Assertion.addMethod('keys', assertKeys); + Assertion.addMethod('key', assertKeys); + + /** + * ### .throw(constructor) + * + * Asserts that the function target will throw a specific error, or specific type of error + * (as determined using `instanceof`), optionally with a RegExp or string inclusion test + * for the error's message. + * + * var err = new ReferenceError('This is a bad function.'); + * var fn = function () { throw err; } + * expect(fn).to.throw(ReferenceError); + * expect(fn).to.throw(Error); + * expect(fn).to.throw(/bad function/); + * expect(fn).to.not.throw('good function'); + * expect(fn).to.throw(ReferenceError, /bad function/); + * expect(fn).to.throw(err); + * + * Please note that when a throw expectation is negated, it will check each + * parameter independently, starting with error constructor type. The appropriate way + * to check for the existence of a type of error but for a message that does not match + * is to use `and`. + * + * expect(fn).to.throw(ReferenceError) + * .and.not.throw(/good function/); + * + * @name throw + * @alias throws + * @alias Throw + * @param {ErrorConstructor} constructor + * @param {String|RegExp} expected error message + * @param {String} message _optional_ + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @returns error for chaining (null if no error) + * @namespace BDD + * @api public + */ + + function assertThrows (constructor, errMsg, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + new Assertion(obj, msg).is.a('function'); + + var thrown = false + , desiredError = null + , name = null + , thrownError = null; + + if (arguments.length === 0) { + errMsg = null; + constructor = null; + } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) { + errMsg = constructor; + constructor = null; + } else if (constructor && constructor instanceof Error) { + desiredError = constructor; + constructor = null; + errMsg = null; + } else if (typeof constructor === 'function') { + name = constructor.prototype.name; + if (!name || (name === 'Error' && constructor !== Error)) { + name = constructor.name || (new constructor()).name; + } + } else { + constructor = null; + } + + try { + obj(); + } catch (err) { + // first, check desired error + if (desiredError) { + this.assert( + err === desiredError + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + , (desiredError instanceof Error ? desiredError.toString() : desiredError) + , (err instanceof Error ? err.toString() : err) + ); + + flag(this, 'object', err); + return this; + } + + // next, check constructor + if (constructor) { + this.assert( + err instanceof constructor + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp} but #{act} was thrown' + , name + , (err instanceof Error ? err.toString() : err) + ); + + if (!errMsg) { + flag(this, 'object', err); + return this; + } + } + + // next, check message + var message = 'error' === _.type(err) && "message" in err + ? err.message + : '' + err; + + if ((message != null) && errMsg && errMsg instanceof RegExp) { + this.assert( + errMsg.exec(message) + , 'expected #{this} to throw error matching #{exp} but got #{act}' + , 'expected #{this} to throw error not matching #{exp}' + , errMsg + , message + ); + + flag(this, 'object', err); + return this; + } else if ((message != null) && errMsg && 'string' === typeof errMsg) { + this.assert( + ~message.indexOf(errMsg) + , 'expected #{this} to throw error including #{exp} but got #{act}' + , 'expected #{this} to throw error not including #{act}' + , errMsg + , message + ); + + flag(this, 'object', err); + return this; + } else { + thrown = true; + thrownError = err; + } + } + + var actuallyGot = '' + , expectedThrown = name !== null + ? name + : desiredError + ? '#{exp}' //_.inspect(desiredError) + : 'an error'; + + if (thrown) { + actuallyGot = ' but #{act} was thrown' + } + + this.assert( + thrown === true + , 'expected #{this} to throw ' + expectedThrown + actuallyGot + , 'expected #{this} to not throw ' + expectedThrown + actuallyGot + , (desiredError instanceof Error ? desiredError.toString() : desiredError) + , (thrownError instanceof Error ? thrownError.toString() : thrownError) + ); + + flag(this, 'object', thrownError); + }; + + Assertion.addMethod('throw', assertThrows); + Assertion.addMethod('throws', assertThrows); + Assertion.addMethod('Throw', assertThrows); + + /** + * ### .respondTo(method) + * + * Asserts that the object or class target will respond to a method. + * + * Klass.prototype.bar = function(){}; + * expect(Klass).to.respondTo('bar'); + * expect(obj).to.respondTo('bar'); + * + * To check if a constructor will respond to a static function, + * set the `itself` flag. + * + * Klass.baz = function(){}; + * expect(Klass).itself.to.respondTo('baz'); + * + * @name respondTo + * @alias respondsTo + * @param {String} method + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function respondTo (method, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , itself = flag(this, 'itself') + , context = ('function' === _.type(obj) && !itself) + ? obj.prototype[method] + : obj[method]; + + this.assert( + 'function' === typeof context + , 'expected #{this} to respond to ' + _.inspect(method) + , 'expected #{this} to not respond to ' + _.inspect(method) + ); + } + + Assertion.addMethod('respondTo', respondTo); + Assertion.addMethod('respondsTo', respondTo); + + /** + * ### .itself + * + * Sets the `itself` flag, later used by the `respondTo` assertion. + * + * function Foo() {} + * Foo.bar = function() {} + * Foo.prototype.baz = function() {} + * + * expect(Foo).itself.to.respondTo('bar'); + * expect(Foo).itself.not.to.respondTo('baz'); + * + * @name itself + * @namespace BDD + * @api public + */ + + Assertion.addProperty('itself', function () { + flag(this, 'itself', true); + }); + + /** + * ### .satisfy(method) + * + * Asserts that the target passes a given truth test. + * + * expect(1).to.satisfy(function(num) { return num > 0; }); + * + * @name satisfy + * @alias satisfies + * @param {Function} matcher + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function satisfy (matcher, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var result = matcher(obj); + this.assert( + result + , 'expected #{this} to satisfy ' + _.objDisplay(matcher) + , 'expected #{this} to not satisfy' + _.objDisplay(matcher) + , this.negate ? false : true + , result + ); + } + + Assertion.addMethod('satisfy', satisfy); + Assertion.addMethod('satisfies', satisfy); + + /** + * ### .closeTo(expected, delta) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * expect(1.5).to.be.closeTo(1, 0.5); + * + * @name closeTo + * @alias approximately + * @param {Number} expected + * @param {Number} delta + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function closeTo(expected, delta, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + + new Assertion(obj, msg).is.a('number'); + if (_.type(expected) !== 'number' || _.type(delta) !== 'number') { + throw new Error('the arguments to closeTo or approximately must be numbers'); + } + + this.assert( + Math.abs(obj - expected) <= delta + , 'expected #{this} to be close to ' + expected + ' +/- ' + delta + , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta + ); + } + + Assertion.addMethod('closeTo', closeTo); + Assertion.addMethod('approximately', closeTo); + + function isSubsetOf(subset, superset, cmp) { + return subset.every(function(elem) { + if (!cmp) return superset.indexOf(elem) !== -1; + + return superset.some(function(elem2) { + return cmp(elem, elem2); + }); + }) + } + + /** + * ### .members(set) + * + * Asserts that the target is a superset of `set`, + * or that the target and `set` have the same strictly-equal (===) members. + * Alternately, if the `deep` flag is set, set members are compared for deep + * equality. + * + * expect([1, 2, 3]).to.include.members([3, 2]); + * expect([1, 2, 3]).to.not.include.members([3, 2, 8]); + * + * expect([4, 2]).to.have.members([2, 4]); + * expect([5, 2]).to.not.have.members([5, 2, 1]); + * + * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]); + * + * @name members + * @param {Array} set + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('members', function (subset, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + + new Assertion(obj).to.be.an('array'); + new Assertion(subset).to.be.an('array'); + + var cmp = flag(this, 'deep') ? _.eql : undefined; + + if (flag(this, 'contains')) { + return this.assert( + isSubsetOf(subset, obj, cmp) + , 'expected #{this} to be a superset of #{act}' + , 'expected #{this} to not be a superset of #{act}' + , obj + , subset + ); + } + + this.assert( + isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp) + , 'expected #{this} to have the same members as #{act}' + , 'expected #{this} to not have the same members as #{act}' + , obj + , subset + ); + }); + + /** + * ### .oneOf(list) + * + * Assert that a value appears somewhere in the top level of array `list`. + * + * expect('a').to.be.oneOf(['a', 'b', 'c']); + * expect(9).to.not.be.oneOf(['z']); + * expect([3]).to.not.be.oneOf([1, 2, [3]]); + * + * var three = [3]; + * // for object-types, contents are not compared + * expect(three).to.not.be.oneOf([1, 2, [3]]); + * // comparing references works + * expect(three).to.be.oneOf([1, 2, three]); + * + * @name oneOf + * @param {Array<*>} list + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function oneOf (list, msg) { + if (msg) flag(this, 'message', msg); + var expected = flag(this, 'object'); + new Assertion(list).to.be.an('array'); + + this.assert( + list.indexOf(expected) > -1 + , 'expected #{this} to be one of #{exp}' + , 'expected #{this} to not be one of #{exp}' + , list + , expected + ); + } + + Assertion.addMethod('oneOf', oneOf); + + + /** + * ### .change(function) + * + * Asserts that a function changes an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 3 }; + * var noChangeFn = function() { return 'foo' + 'bar'; } + * expect(fn).to.change(obj, 'val'); + * expect(noChangeFn).to.not.change(obj, 'val') + * + * @name change + * @alias changes + * @alias Change + * @param {String} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertChanges (object, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object'); + new Assertion(object, msg).to.have.property(prop); + new Assertion(fn).is.a('function'); + + var initial = object[prop]; + fn(); + + this.assert( + initial !== object[prop] + , 'expected .' + prop + ' to change' + , 'expected .' + prop + ' to not change' + ); + } + + Assertion.addChainableMethod('change', assertChanges); + Assertion.addChainableMethod('changes', assertChanges); + + /** + * ### .increase(function) + * + * Asserts that a function increases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * expect(fn).to.increase(obj, 'val'); + * + * @name increase + * @alias increases + * @alias Increase + * @param {String} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertIncreases (object, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object'); + new Assertion(object, msg).to.have.property(prop); + new Assertion(fn).is.a('function'); + + var initial = object[prop]; + fn(); + + this.assert( + object[prop] - initial > 0 + , 'expected .' + prop + ' to increase' + , 'expected .' + prop + ' to not increase' + ); + } + + Assertion.addChainableMethod('increase', assertIncreases); + Assertion.addChainableMethod('increases', assertIncreases); + + /** + * ### .decrease(function) + * + * Asserts that a function decreases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * expect(fn).to.decrease(obj, 'val'); + * + * @name decrease + * @alias decreases + * @alias Decrease + * @param {String} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace BDD + * @api public + */ + + function assertDecreases (object, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object'); + new Assertion(object, msg).to.have.property(prop); + new Assertion(fn).is.a('function'); + + var initial = object[prop]; + fn(); + + this.assert( + object[prop] - initial < 0 + , 'expected .' + prop + ' to decrease' + , 'expected .' + prop + ' to not decrease' + ); + } + + Assertion.addChainableMethod('decrease', assertDecreases); + Assertion.addChainableMethod('decreases', assertDecreases); + + /** + * ### .extensible + * + * Asserts that the target is extensible (can have new properties added to + * it). + * + * var nonExtensibleObject = Object.preventExtensions({}); + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * expect({}).to.be.extensible; + * expect(nonExtensibleObject).to.not.be.extensible; + * expect(sealedObject).to.not.be.extensible; + * expect(frozenObject).to.not.be.extensible; + * + * @name extensible + * @namespace BDD + * @api public + */ + + Assertion.addProperty('extensible', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible + // The following provides ES6 behavior when a TypeError is thrown under ES5. + + var isExtensible; + + try { + isExtensible = Object.isExtensible(obj); + } catch (err) { + if (err instanceof TypeError) isExtensible = false; + else throw err; + } + + this.assert( + isExtensible + , 'expected #{this} to be extensible' + , 'expected #{this} to not be extensible' + ); + }); + + /** + * ### .sealed + * + * Asserts that the target is sealed (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * expect(sealedObject).to.be.sealed; + * expect(frozenObject).to.be.sealed; + * expect({}).to.not.be.sealed; + * + * @name sealed + * @namespace BDD + * @api public + */ + + Assertion.addProperty('sealed', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed + // The following provides ES6 behavior when a TypeError is thrown under ES5. + + var isSealed; + + try { + isSealed = Object.isSealed(obj); + } catch (err) { + if (err instanceof TypeError) isSealed = true; + else throw err; + } + + this.assert( + isSealed + , 'expected #{this} to be sealed' + , 'expected #{this} to not be sealed' + ); + }); + + /** + * ### .frozen + * + * Asserts that the target is frozen (cannot have new properties added to it + * and its existing properties cannot be modified). + * + * var frozenObject = Object.freeze({}); + * + * expect(frozenObject).to.be.frozen; + * expect({}).to.not.be.frozen; + * + * @name frozen + * @namespace BDD + * @api public + */ + + Assertion.addProperty('frozen', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen + // The following provides ES6 behavior when a TypeError is thrown under ES5. + + var isFrozen; + + try { + isFrozen = Object.isFrozen(obj); + } catch (err) { + if (err instanceof TypeError) isFrozen = true; + else throw err; + } + + this.assert( + isFrozen + , 'expected #{this} to be frozen' + , 'expected #{this} to not be frozen' + ); + }); +}; + +},{}],10:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + + +module.exports = function (chai, util) { + + /*! + * Chai dependencies. + */ + + var Assertion = chai.Assertion + , flag = util.flag; + + /*! + * Module export. + */ + + /** + * ### assert(expression, message) + * + * Write your own test expressions. + * + * assert('foo' !== 'bar', 'foo is not bar'); + * assert(Array.isArray([]), 'empty arrays are arrays'); + * + * @param {Mixed} expression to test for truthiness + * @param {String} message to display on error + * @name assert + * @namespace Assert + * @api public + */ + + var assert = chai.assert = function (express, errmsg) { + var test = new Assertion(null, null, chai.assert); + test.assert( + express + , errmsg + , '[ negation message unavailable ]' + ); + }; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. Node.js `assert` module-compatible. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace Assert + * @api public + */ + + assert.fail = function (actual, expected, message, operator) { + message = message || 'assert.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, assert.fail); + }; + + /** + * ### .isOk(object, [message]) + * + * Asserts that `object` is truthy. + * + * assert.isOk('everything', 'everything is ok'); + * assert.isOk(false, 'this will fail'); + * + * @name isOk + * @alias ok + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isOk = function (val, msg) { + new Assertion(val, msg).is.ok; + }; + + /** + * ### .isNotOk(object, [message]) + * + * Asserts that `object` is falsy. + * + * assert.isNotOk('everything', 'this will fail'); + * assert.isNotOk(false, 'this will pass'); + * + * @name isNotOk + * @alias notOk + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotOk = function (val, msg) { + new Assertion(val, msg).is.not.ok; + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * assert.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.equal = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.equal); + + test.assert( + exp == flag(test, 'object') + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{act}' + , exp + , act + ); + }; + + /** + * ### .notEqual(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * assert.notEqual(3, 4, 'these numbers are not equal'); + * + * @name notEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notEqual = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.notEqual); + + test.assert( + exp != flag(test, 'object') + , 'expected #{this} to not equal #{exp}' + , 'expected #{this} to equal #{act}' + , exp + , act + ); + }; + + /** + * ### .strictEqual(actual, expected, [message]) + * + * Asserts strict equality (`===`) of `actual` and `expected`. + * + * assert.strictEqual(true, true, 'these booleans are strictly equal'); + * + * @name strictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.strictEqual = function (act, exp, msg) { + new Assertion(act, msg).to.equal(exp); + }; + + /** + * ### .notStrictEqual(actual, expected, [message]) + * + * Asserts strict inequality (`!==`) of `actual` and `expected`. + * + * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); + * + * @name notStrictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notStrictEqual = function (act, exp, msg) { + new Assertion(act, msg).to.not.equal(exp); + }; + + /** + * ### .deepEqual(actual, expected, [message]) + * + * Asserts that `actual` is deeply equal to `expected`. + * + * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); + * + * @name deepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepEqual = function (act, exp, msg) { + new Assertion(act, msg).to.eql(exp); + }; + + /** + * ### .notDeepEqual(actual, expected, [message]) + * + * Assert that `actual` is not deeply equal to `expected`. + * + * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); + * + * @name notDeepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepEqual = function (act, exp, msg) { + new Assertion(act, msg).to.not.eql(exp); + }; + + /** + * ### .isAbove(valueToCheck, valueToBeAbove, [message]) + * + * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove` + * + * assert.isAbove(5, 2, '5 is strictly greater than 2'); + * + * @name isAbove + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAbove + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAbove = function (val, abv, msg) { + new Assertion(val, msg).to.be.above(abv); + }; + + /** + * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message]) + * + * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast` + * + * assert.isAtLeast(5, 2, '5 is greater or equal to 2'); + * assert.isAtLeast(3, 3, '3 is greater or equal to 3'); + * + * @name isAtLeast + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtLeast + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtLeast = function (val, atlst, msg) { + new Assertion(val, msg).to.be.least(atlst); + }; + + /** + * ### .isBelow(valueToCheck, valueToBeBelow, [message]) + * + * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow` + * + * assert.isBelow(3, 6, '3 is strictly less than 6'); + * + * @name isBelow + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeBelow + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBelow = function (val, blw, msg) { + new Assertion(val, msg).to.be.below(blw); + }; + + /** + * ### .isAtMost(valueToCheck, valueToBeAtMost, [message]) + * + * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost` + * + * assert.isAtMost(3, 6, '3 is less than or equal to 6'); + * assert.isAtMost(4, 4, '4 is less than or equal to 4'); + * + * @name isAtMost + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtMost + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtMost = function (val, atmst, msg) { + new Assertion(val, msg).to.be.most(atmst); + }; + + /** + * ### .isTrue(value, [message]) + * + * Asserts that `value` is true. + * + * var teaServed = true; + * assert.isTrue(teaServed, 'the tea has been served'); + * + * @name isTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isTrue = function (val, msg) { + new Assertion(val, msg).is['true']; + }; + + /** + * ### .isNotTrue(value, [message]) + * + * Asserts that `value` is not true. + * + * var tea = 'tasty chai'; + * assert.isNotTrue(tea, 'great, time for tea!'); + * + * @name isNotTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotTrue = function (val, msg) { + new Assertion(val, msg).to.not.equal(true); + }; + + /** + * ### .isFalse(value, [message]) + * + * Asserts that `value` is false. + * + * var teaServed = false; + * assert.isFalse(teaServed, 'no tea yet? hmm...'); + * + * @name isFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFalse = function (val, msg) { + new Assertion(val, msg).is['false']; + }; + + /** + * ### .isNotFalse(value, [message]) + * + * Asserts that `value` is not false. + * + * var tea = 'tasty chai'; + * assert.isNotFalse(tea, 'great, time for tea!'); + * + * @name isNotFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFalse = function (val, msg) { + new Assertion(val, msg).to.not.equal(false); + }; + + /** + * ### .isNull(value, [message]) + * + * Asserts that `value` is null. + * + * assert.isNull(err, 'there was no error'); + * + * @name isNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNull = function (val, msg) { + new Assertion(val, msg).to.equal(null); + }; + + /** + * ### .isNotNull(value, [message]) + * + * Asserts that `value` is not null. + * + * var tea = 'tasty chai'; + * assert.isNotNull(tea, 'great, time for tea!'); + * + * @name isNotNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNull = function (val, msg) { + new Assertion(val, msg).to.not.equal(null); + }; + + /** + * ### .isNaN + * Asserts that value is NaN + * + * assert.isNaN('foo', 'foo is NaN'); + * + * @name isNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNaN = function (val, msg) { + new Assertion(val, msg).to.be.NaN; + }; + + /** + * ### .isNotNaN + * Asserts that value is not NaN + * + * assert.isNotNaN(4, '4 is not NaN'); + * + * @name isNotNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + assert.isNotNaN = function (val, msg) { + new Assertion(val, msg).not.to.be.NaN; + }; + + /** + * ### .isUndefined(value, [message]) + * + * Asserts that `value` is `undefined`. + * + * var tea; + * assert.isUndefined(tea, 'no tea defined'); + * + * @name isUndefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isUndefined = function (val, msg) { + new Assertion(val, msg).to.equal(undefined); + }; + + /** + * ### .isDefined(value, [message]) + * + * Asserts that `value` is not `undefined`. + * + * var tea = 'cup of chai'; + * assert.isDefined(tea, 'tea has been defined'); + * + * @name isDefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isDefined = function (val, msg) { + new Assertion(val, msg).to.not.equal(undefined); + }; + + /** + * ### .isFunction(value, [message]) + * + * Asserts that `value` is a function. + * + * function serveTea() { return 'cup of tea'; }; + * assert.isFunction(serveTea, 'great, we can have tea now'); + * + * @name isFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFunction = function (val, msg) { + new Assertion(val, msg).to.be.a('function'); + }; + + /** + * ### .isNotFunction(value, [message]) + * + * Asserts that `value` is _not_ a function. + * + * var serveTea = [ 'heat', 'pour', 'sip' ]; + * assert.isNotFunction(serveTea, 'great, we have listed the steps'); + * + * @name isNotFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFunction = function (val, msg) { + new Assertion(val, msg).to.not.be.a('function'); + }; + + /** + * ### .isObject(value, [message]) + * + * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`). + * _The assertion does not match subclassed objects._ + * + * var selection = { name: 'Chai', serve: 'with spices' }; + * assert.isObject(selection, 'tea selection is an object'); + * + * @name isObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isObject = function (val, msg) { + new Assertion(val, msg).to.be.a('object'); + }; + + /** + * ### .isNotObject(value, [message]) + * + * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`). + * + * var selection = 'chai' + * assert.isNotObject(selection, 'tea selection is not an object'); + * assert.isNotObject(null, 'null is not an object'); + * + * @name isNotObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotObject = function (val, msg) { + new Assertion(val, msg).to.not.be.a('object'); + }; + + /** + * ### .isArray(value, [message]) + * + * Asserts that `value` is an array. + * + * var menu = [ 'green', 'chai', 'oolong' ]; + * assert.isArray(menu, 'what kind of tea do we want?'); + * + * @name isArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isArray = function (val, msg) { + new Assertion(val, msg).to.be.an('array'); + }; + + /** + * ### .isNotArray(value, [message]) + * + * Asserts that `value` is _not_ an array. + * + * var menu = 'green|chai|oolong'; + * assert.isNotArray(menu, 'what kind of tea do we want?'); + * + * @name isNotArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotArray = function (val, msg) { + new Assertion(val, msg).to.not.be.an('array'); + }; + + /** + * ### .isString(value, [message]) + * + * Asserts that `value` is a string. + * + * var teaOrder = 'chai'; + * assert.isString(teaOrder, 'order placed'); + * + * @name isString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isString = function (val, msg) { + new Assertion(val, msg).to.be.a('string'); + }; + + /** + * ### .isNotString(value, [message]) + * + * Asserts that `value` is _not_ a string. + * + * var teaOrder = 4; + * assert.isNotString(teaOrder, 'order placed'); + * + * @name isNotString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotString = function (val, msg) { + new Assertion(val, msg).to.not.be.a('string'); + }; + + /** + * ### .isNumber(value, [message]) + * + * Asserts that `value` is a number. + * + * var cups = 2; + * assert.isNumber(cups, 'how many cups'); + * + * @name isNumber + * @param {Number} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNumber = function (val, msg) { + new Assertion(val, msg).to.be.a('number'); + }; + + /** + * ### .isNotNumber(value, [message]) + * + * Asserts that `value` is _not_ a number. + * + * var cups = '2 cups please'; + * assert.isNotNumber(cups, 'how many cups'); + * + * @name isNotNumber + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNumber = function (val, msg) { + new Assertion(val, msg).to.not.be.a('number'); + }; + + /** + * ### .isBoolean(value, [message]) + * + * Asserts that `value` is a boolean. + * + * var teaReady = true + * , teaServed = false; + * + * assert.isBoolean(teaReady, 'is the tea ready'); + * assert.isBoolean(teaServed, 'has tea been served'); + * + * @name isBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBoolean = function (val, msg) { + new Assertion(val, msg).to.be.a('boolean'); + }; + + /** + * ### .isNotBoolean(value, [message]) + * + * Asserts that `value` is _not_ a boolean. + * + * var teaReady = 'yep' + * , teaServed = 'nope'; + * + * assert.isNotBoolean(teaReady, 'is the tea ready'); + * assert.isNotBoolean(teaServed, 'has tea been served'); + * + * @name isNotBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotBoolean = function (val, msg) { + new Assertion(val, msg).to.not.be.a('boolean'); + }; + + /** + * ### .typeOf(value, name, [message]) + * + * Asserts that `value`'s type is `name`, as determined by + * `Object.prototype.toString`. + * + * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); + * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); + * assert.typeOf('tea', 'string', 'we have a string'); + * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); + * assert.typeOf(null, 'null', 'we have a null'); + * assert.typeOf(undefined, 'undefined', 'we have an undefined'); + * + * @name typeOf + * @param {Mixed} value + * @param {String} name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.typeOf = function (val, type, msg) { + new Assertion(val, msg).to.be.a(type); + }; + + /** + * ### .notTypeOf(value, name, [message]) + * + * Asserts that `value`'s type is _not_ `name`, as determined by + * `Object.prototype.toString`. + * + * assert.notTypeOf('tea', 'number', 'strings are not numbers'); + * + * @name notTypeOf + * @param {Mixed} value + * @param {String} typeof name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notTypeOf = function (val, type, msg) { + new Assertion(val, msg).to.not.be.a(type); + }; + + /** + * ### .instanceOf(object, constructor, [message]) + * + * Asserts that `value` is an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new Tea('chai'); + * + * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); + * + * @name instanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.instanceOf = function (val, type, msg) { + new Assertion(val, msg).to.be.instanceOf(type); + }; + + /** + * ### .notInstanceOf(object, constructor, [message]) + * + * Asserts `value` is not an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new String('chai'); + * + * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); + * + * @name notInstanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInstanceOf = function (val, type, msg) { + new Assertion(val, msg).to.not.be.instanceOf(type); + }; + + /** + * ### .include(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Works + * for strings and arrays. + * + * assert.include('foobar', 'bar', 'foobar contains string "bar"'); + * assert.include([ 1, 2, 3 ], 3, 'array contains value'); + * + * @name include + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.include = function (exp, inc, msg) { + new Assertion(exp, msg, assert.include).include(inc); + }; + + /** + * ### .notInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Works + * for strings and arrays. + * + * assert.notInclude('foobar', 'baz', 'string not include substring'); + * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value'); + * + * @name notInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notInclude).not.include(inc); + }; + + /** + * ### .match(value, regexp, [message]) + * + * Asserts that `value` matches the regular expression `regexp`. + * + * assert.match('foobar', /^foo/, 'regexp matches'); + * + * @name match + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.match = function (exp, re, msg) { + new Assertion(exp, msg).to.match(re); + }; + + /** + * ### .notMatch(value, regexp, [message]) + * + * Asserts that `value` does not match the regular expression `regexp`. + * + * assert.notMatch('foobar', /^foo/, 'regexp does not match'); + * + * @name notMatch + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notMatch = function (exp, re, msg) { + new Assertion(exp, msg).to.not.match(re); + }; + + /** + * ### .property(object, property, [message]) + * + * Asserts that `object` has a property named by `property`. + * + * assert.property({ tea: { green: 'matcha' }}, 'tea'); + * + * @name property + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.property = function (obj, prop, msg) { + new Assertion(obj, msg).to.have.property(prop); + }; + + /** + * ### .notProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a property named by `property`. + * + * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); + * + * @name notProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notProperty = function (obj, prop, msg) { + new Assertion(obj, msg).to.not.have.property(prop); + }; + + /** + * ### .deepProperty(object, property, [message]) + * + * Asserts that `object` has a property named by `property`, which can be a + * string using dot- and bracket-notation for deep reference. + * + * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green'); + * + * @name deepProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepProperty = function (obj, prop, msg) { + new Assertion(obj, msg).to.have.deep.property(prop); + }; + + /** + * ### .notDeepProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a property named by `property`, which + * can be a string using dot- and bracket-notation for deep reference. + * + * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); + * + * @name notDeepProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepProperty = function (obj, prop, msg) { + new Assertion(obj, msg).to.not.have.deep.property(prop); + }; + + /** + * ### .propertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with value given + * by `value`. + * + * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); + * + * @name propertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.propertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg).to.have.property(prop, val); + }; + + /** + * ### .propertyNotVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property`, but with a value + * different from that given by `value`. + * + * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad'); + * + * @name propertyNotVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.propertyNotVal = function (obj, prop, val, msg) { + new Assertion(obj, msg).to.not.have.property(prop, val); + }; + + /** + * ### .deepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with value given + * by `value`. `property` can use dot- and bracket-notation for deep + * reference. + * + * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha'); + * + * @name deepPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg).to.have.deep.property(prop, val); + }; + + /** + * ### .deepPropertyNotVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property`, but with a value + * different from that given by `value`. `property` can use dot- and + * bracket-notation for deep reference. + * + * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha'); + * + * @name deepPropertyNotVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepPropertyNotVal = function (obj, prop, val, msg) { + new Assertion(obj, msg).to.not.have.deep.property(prop, val); + }; + + /** + * ### .lengthOf(object, length, [message]) + * + * Asserts that `object` has a `length` property with the expected value. + * + * assert.lengthOf([1,2,3], 3, 'array has length of 3'); + * assert.lengthOf('foobar', 6, 'string has length of 6'); + * + * @name lengthOf + * @param {Mixed} object + * @param {Number} length + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.lengthOf = function (exp, len, msg) { + new Assertion(exp, msg).to.have.length(len); + }; + + /** + * ### .throws(function, [constructor/string/regexp], [string/regexp], [message]) + * + * Asserts that `function` will throw an error that is an instance of + * `constructor`, or alternately that it will throw an error with message + * matching `regexp`. + * + * assert.throws(fn, 'function throws a reference error'); + * assert.throws(fn, /function throws a reference error/); + * assert.throws(fn, ReferenceError); + * assert.throws(fn, ReferenceError, 'function throws a reference error'); + * assert.throws(fn, ReferenceError, /function throws a reference error/); + * + * @name throws + * @alias throw + * @alias Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.throws = function (fn, errt, errs, msg) { + if ('string' === typeof errt || errt instanceof RegExp) { + errs = errt; + errt = null; + } + + var assertErr = new Assertion(fn, msg).to.throw(errt, errs); + return flag(assertErr, 'object'); + }; + + /** + * ### .doesNotThrow(function, [constructor/regexp], [message]) + * + * Asserts that `function` will _not_ throw an error that is an instance of + * `constructor`, or alternately that it will not throw an error with message + * matching `regexp`. + * + * assert.doesNotThrow(fn, Error, 'function does not throw'); + * + * @name doesNotThrow + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.doesNotThrow = function (fn, type, msg) { + if ('string' === typeof type) { + msg = type; + type = null; + } + + new Assertion(fn, msg).to.not.Throw(type); + }; + + /** + * ### .operator(val1, operator, val2, [message]) + * + * Compares two values using `operator`. + * + * assert.operator(1, '<', 2, 'everything is ok'); + * assert.operator(1, '>', 2, 'this will fail'); + * + * @name operator + * @param {Mixed} val1 + * @param {String} operator + * @param {Mixed} val2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.operator = function (val, operator, val2, msg) { + var ok; + switch(operator) { + case '==': + ok = val == val2; + break; + case '===': + ok = val === val2; + break; + case '>': + ok = val > val2; + break; + case '>=': + ok = val >= val2; + break; + case '<': + ok = val < val2; + break; + case '<=': + ok = val <= val2; + break; + case '!=': + ok = val != val2; + break; + case '!==': + ok = val !== val2; + break; + default: + throw new Error('Invalid operator "' + operator + '"'); + } + var test = new Assertion(ok, msg); + test.assert( + true === flag(test, 'object') + , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2) + , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) ); + }; + + /** + * ### .closeTo(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.closeTo(1.5, 1, 0.5, 'numbers are close'); + * + * @name closeTo + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.closeTo = function (act, exp, delta, msg) { + new Assertion(act, msg).to.be.closeTo(exp, delta); + }; + + /** + * ### .approximately(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.approximately(1.5, 1, 0.5, 'numbers are close'); + * + * @name approximately + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.approximately = function (act, exp, delta, msg) { + new Assertion(act, msg).to.be.approximately(exp, delta); + }; + + /** + * ### .sameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members. + * Order is not taken into account. + * + * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); + * + * @name sameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameMembers = function (set1, set2, msg) { + new Assertion(set1, msg).to.have.same.members(set2); + } + + /** + * ### .sameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members - using a deep equality checking. + * Order is not taken into account. + * + * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members'); + * + * @name sameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameDeepMembers = function (set1, set2, msg) { + new Assertion(set1, msg).to.have.same.deep.members(set2); + } + + /** + * ### .includeMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset`. + * Order is not taken into account. + * + * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members'); + * + * @name includeMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeMembers = function (superset, subset, msg) { + new Assertion(superset, msg).to.include.members(subset); + } + + /** + * ### .includeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` - using deep equality checking. + * Order is not taken into account. + * Duplicates are ignored. + * + * assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members'); + * + * @name includeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeDeepMembers = function (superset, subset, msg) { + new Assertion(superset, msg).to.include.deep.members(subset); + } + + /** + * ### .oneOf(inList, list, [message]) + * + * Asserts that non-object, non-array value `inList` appears in the flat array `list`. + * + * assert.oneOf(1, [ 2, 1 ], 'Not found in list'); + * + * @name oneOf + * @param {*} inList + * @param {Array<*>} list + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.oneOf = function (inList, list, msg) { + new Assertion(inList, msg).to.be.oneOf(list); + } + + /** + * ### .changes(function, object, property) + * + * Asserts that a function changes the value of a property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 22 }; + * assert.changes(fn, obj, 'val'); + * + * @name changes + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changes = function (fn, obj, prop) { + new Assertion(fn).to.change(obj, prop); + } + + /** + * ### .doesNotChange(function, object, property) + * + * Asserts that a function does not changes the value of a property + * + * var obj = { val: 10 }; + * var fn = function() { console.log('foo'); }; + * assert.doesNotChange(fn, obj, 'val'); + * + * @name doesNotChange + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotChange = function (fn, obj, prop) { + new Assertion(fn).to.not.change(obj, prop); + } + + /** + * ### .increases(function, object, property) + * + * Asserts that a function increases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 13 }; + * assert.increases(fn, obj, 'val'); + * + * @name increases + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increases = function (fn, obj, prop) { + new Assertion(fn).to.increase(obj, prop); + } + + /** + * ### .doesNotIncrease(function, object, property) + * + * Asserts that a function does not increase object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 8 }; + * assert.doesNotIncrease(fn, obj, 'val'); + * + * @name doesNotIncrease + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotIncrease = function (fn, obj, prop) { + new Assertion(fn).to.not.increase(obj, prop); + } + + /** + * ### .decreases(function, object, property) + * + * Asserts that a function decreases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreases(fn, obj, 'val'); + * + * @name decreases + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreases = function (fn, obj, prop) { + new Assertion(fn).to.decrease(obj, prop); + } + + /** + * ### .doesNotDecrease(function, object, property) + * + * Asserts that a function does not decreases an object property + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.doesNotDecrease(fn, obj, 'val'); + * + * @name doesNotDecrease + * @param {Function} modifier function + * @param {Object} object + * @param {String} property name + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotDecrease = function (fn, obj, prop) { + new Assertion(fn).to.not.decrease(obj, prop); + } + + /*! + * ### .ifError(object) + * + * Asserts if value is not a false value, and throws if it is a true value. + * This is added to allow for chai to be a drop-in replacement for Node's + * assert class. + * + * var err = new Error('I am a custom error'); + * assert.ifError(err); // Rethrows err! + * + * @name ifError + * @param {Object} object + * @namespace Assert + * @api public + */ + + assert.ifError = function (val) { + if (val) { + throw(val); + } + }; + + /** + * ### .isExtensible(object) + * + * Asserts that `object` is extensible (can have new properties added to it). + * + * assert.isExtensible({}); + * + * @name isExtensible + * @alias extensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isExtensible = function (obj, msg) { + new Assertion(obj, msg).to.be.extensible; + }; + + /** + * ### .isNotExtensible(object) + * + * Asserts that `object` is _not_ extensible. + * + * var nonExtensibleObject = Object.preventExtensions({}); + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freese({}); + * + * assert.isNotExtensible(nonExtensibleObject); + * assert.isNotExtensible(sealedObject); + * assert.isNotExtensible(frozenObject); + * + * @name isNotExtensible + * @alias notExtensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotExtensible = function (obj, msg) { + new Assertion(obj, msg).to.not.be.extensible; + }; + + /** + * ### .isSealed(object) + * + * Asserts that `object` is sealed (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.seal({}); + * + * assert.isSealed(sealedObject); + * assert.isSealed(frozenObject); + * + * @name isSealed + * @alias sealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isSealed = function (obj, msg) { + new Assertion(obj, msg).to.be.sealed; + }; + + /** + * ### .isNotSealed(object) + * + * Asserts that `object` is _not_ sealed. + * + * assert.isNotSealed({}); + * + * @name isNotSealed + * @alias notSealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotSealed = function (obj, msg) { + new Assertion(obj, msg).to.not.be.sealed; + }; + + /** + * ### .isFrozen(object) + * + * Asserts that `object` is frozen (cannot have new properties added to it + * and its existing properties cannot be modified). + * + * var frozenObject = Object.freeze({}); + * assert.frozen(frozenObject); + * + * @name isFrozen + * @alias frozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isFrozen = function (obj, msg) { + new Assertion(obj, msg).to.be.frozen; + }; + + /** + * ### .isNotFrozen(object) + * + * Asserts that `object` is _not_ frozen. + * + * assert.isNotFrozen({}); + * + * @name isNotFrozen + * @alias notFrozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotFrozen = function (obj, msg) { + new Assertion(obj, msg).to.not.be.frozen; + }; + + /*! + * Aliases. + */ + + (function alias(name, as){ + assert[as] = assert[name]; + return alias; + }) + ('isOk', 'ok') + ('isNotOk', 'notOk') + ('throws', 'throw') + ('throws', 'Throw') + ('isExtensible', 'extensible') + ('isNotExtensible', 'notExtensible') + ('isSealed', 'sealed') + ('isNotSealed', 'notSealed') + ('isFrozen', 'frozen') + ('isNotFrozen', 'notFrozen'); +}; + +},{}],11:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + chai.expect = function (val, message) { + return new chai.Assertion(val, message); + }; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace Expect + * @api public + */ + + chai.expect.fail = function (actual, expected, message, operator) { + message = message || 'expect.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, chai.expect.fail); + }; +}; + +},{}],12:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + var Assertion = chai.Assertion; + + function loadShould () { + // explicitly define this method as function as to have it's name to include as `ssfi` + function shouldGetter() { + if (this instanceof String || this instanceof Number || this instanceof Boolean ) { + return new Assertion(this.valueOf(), null, shouldGetter); + } + return new Assertion(this, null, shouldGetter); + } + function shouldSetter(value) { + // See https://github.com/chaijs/chai/issues/86: this makes + // `whatever.should = someValue` actually set `someValue`, which is + // especially useful for `global.should = require('chai').should()`. + // + // Note that we have to use [[DefineProperty]] instead of [[Put]] + // since otherwise we would trigger this very setter! + Object.defineProperty(this, 'should', { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } + // modify Object.prototype to have `should` + Object.defineProperty(Object.prototype, 'should', { + set: shouldSetter + , get: shouldGetter + , configurable: true + }); + + var should = {}; + + /** + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace Should + * @api public + */ + + should.fail = function (actual, expected, message, operator) { + message = message || 'should.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, should.fail); + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * should.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.equal(val2); + }; + + /** + * ### .throw(function, [constructor/string/regexp], [string/regexp], [message]) + * + * Asserts that `function` will throw an error that is an instance of + * `constructor`, or alternately that it will throw an error with message + * matching `regexp`. + * + * should.throw(fn, 'function throws a reference error'); + * should.throw(fn, /function throws a reference error/); + * should.throw(fn, ReferenceError); + * should.throw(fn, ReferenceError, 'function throws a reference error'); + * should.throw(fn, ReferenceError, /function throws a reference error/); + * + * @name throw + * @alias Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.Throw(errt, errs); + }; + + /** + * ### .exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * + * should.exist(foo, 'foo exists'); + * + * @name exist + * @namespace Should + * @api public + */ + + should.exist = function (val, msg) { + new Assertion(val, msg).to.exist; + } + + // negation + should.not = {} + + /** + * ### .not.equal(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * should.not.equal(3, 4, 'these numbers are not equal'); + * + * @name not.equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.not.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.not.equal(val2); + }; + + /** + * ### .throw(function, [constructor/regexp], [message]) + * + * Asserts that `function` will _not_ throw an error that is an instance of + * `constructor`, or alternately that it will not throw an error with message + * matching `regexp`. + * + * should.not.throw(fn, Error, 'function does not throw'); + * + * @name not.throw + * @alias not.Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.not.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.not.Throw(errt, errs); + }; + + /** + * ### .not.exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var bar = null; + * + * should.not.exist(bar, 'bar does not exist'); + * + * @name not.exist + * @namespace Should + * @api public + */ + + should.not.exist = function (val, msg) { + new Assertion(val, msg).to.not.exist; + } + + should['throw'] = should['Throw']; + should.not['throw'] = should.not['Throw']; + + return should; + }; + + chai.should = loadShould; + chai.Should = loadShould; +}; + +},{}],13:[function(require,module,exports){ +/*! + * Chai - addChainingMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var transferFlags = require('./transferFlags'); +var flag = require('./flag'); +var config = require('../config'); + +/*! + * Module variables + */ + +// Check whether `__proto__` is supported +var hasProtoSupport = '__proto__' in Object; + +// Without `__proto__` support, this module will need to add properties to a function. +// However, some Function.prototype methods cannot be overwritten, +// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69). +var excludeNames = /^(?:length|name|arguments|caller)$/; + +// Cache `Function` properties +var call = Function.prototype.call, + apply = Function.prototype.apply; + +/** + * ### addChainableMethod (ctx, name, method, chainingBehavior) + * + * Adds a method to an object, such that the method can also be chained. + * + * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior); + * + * The result can then be used as both a method assertion, executing both `method` and + * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`. + * + * expect(fooStr).to.be.foo('bar'); + * expect(fooStr).to.be.foo.equal('foo'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for `name`, when called + * @param {Function} chainingBehavior function to be called every time the property is accessed + * @namespace Utils + * @name addChainableMethod + * @api public + */ + +module.exports = function (ctx, name, method, chainingBehavior) { + if (typeof chainingBehavior !== 'function') { + chainingBehavior = function () { }; + } + + var chainableBehavior = { + method: method + , chainingBehavior: chainingBehavior + }; + + // save the methods so we can overwrite them later, if we need to. + if (!ctx.__methods) { + ctx.__methods = {}; + } + ctx.__methods[name] = chainableBehavior; + + Object.defineProperty(ctx, name, + { get: function () { + chainableBehavior.chainingBehavior.call(this); + + var assert = function assert() { + var old_ssfi = flag(this, 'ssfi'); + if (old_ssfi && config.includeStack === false) + flag(this, 'ssfi', assert); + var result = chainableBehavior.method.apply(this, arguments); + return result === undefined ? this : result; + }; + + // Use `__proto__` if available + if (hasProtoSupport) { + // Inherit all properties from the object by replacing the `Function` prototype + var prototype = assert.__proto__ = Object.create(this); + // Restore the `call` and `apply` methods from `Function` + prototype.call = call; + prototype.apply = apply; + } + // Otherwise, redefine all properties (slow!) + else { + var asserterNames = Object.getOwnPropertyNames(ctx); + asserterNames.forEach(function (asserterName) { + if (!excludeNames.test(asserterName)) { + var pd = Object.getOwnPropertyDescriptor(ctx, asserterName); + Object.defineProperty(assert, asserterName, pd); + } + }); + } + + transferFlags(this, assert); + return assert; + } + , configurable: true + }); +}; + +},{"../config":8,"./flag":17,"./transferFlags":33}],14:[function(require,module,exports){ +/*! + * Chai - addMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var config = require('../config'); + +/** + * ### .addMethod (ctx, name, method) + * + * Adds a method to the prototype of an object. + * + * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(fooStr).to.be.foo('bar'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for name + * @namespace Utils + * @name addMethod + * @api public + */ +var flag = require('./flag'); + +module.exports = function (ctx, name, method) { + ctx[name] = function () { + var old_ssfi = flag(this, 'ssfi'); + if (old_ssfi && config.includeStack === false) + flag(this, 'ssfi', ctx[name]); + var result = method.apply(this, arguments); + return result === undefined ? this : result; + }; +}; + +},{"../config":8,"./flag":17}],15:[function(require,module,exports){ +/*! + * Chai - addProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var config = require('../config'); +var flag = require('./flag'); + +/** + * ### addProperty (ctx, name, getter) + * + * Adds a property to the prototype of an object. + * + * utils.addProperty(chai.Assertion.prototype, 'foo', function () { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.instanceof(Foo); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.foo; + * + * @param {Object} ctx object to which the property is added + * @param {String} name of property to add + * @param {Function} getter function to be used for name + * @namespace Utils + * @name addProperty + * @api public + */ + +module.exports = function (ctx, name, getter) { + Object.defineProperty(ctx, name, + { get: function addProperty() { + var old_ssfi = flag(this, 'ssfi'); + if (old_ssfi && config.includeStack === false) + flag(this, 'ssfi', addProperty); + + var result = getter.call(this); + return result === undefined ? this : result; + } + , configurable: true + }); +}; + +},{"../config":8,"./flag":17}],16:[function(require,module,exports){ +/*! + * Chai - expectTypes utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### expectTypes(obj, types) + * + * Ensures that the object being tested against is of a valid type. + * + * utils.expectTypes(this, ['array', 'object', 'string']); + * + * @param {Mixed} obj constructed Assertion + * @param {Array} type A list of allowed types for this assertion + * @namespace Utils + * @name expectTypes + * @api public + */ + +var AssertionError = require('assertion-error'); +var flag = require('./flag'); +var type = require('type-detect'); + +module.exports = function (obj, types) { + var obj = flag(obj, 'object'); + types = types.map(function (t) { return t.toLowerCase(); }); + types.sort(); + + // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum' + var str = types.map(function (t, index) { + var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a'; + var or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; + return or + art + ' ' + t; + }).join(', '); + + if (!types.some(function (expected) { return type(obj) === expected; })) { + throw new AssertionError( + 'object tested must be ' + str + ', but ' + type(obj) + ' given' + ); + } +}; + +},{"./flag":17,"assertion-error":4,"type-detect":40}],17:[function(require,module,exports){ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### flag(object, key, [value]) + * + * Get or set a flag value on an object. If a + * value is provided it will be set, else it will + * return the currently set value or `undefined` if + * the value is not set. + * + * utils.flag(this, 'foo', 'bar'); // setter + * utils.flag(this, 'foo'); // getter, returns `bar` + * + * @param {Object} object constructed Assertion + * @param {String} key + * @param {Mixed} value (optional) + * @namespace Utils + * @name flag + * @api private + */ + +module.exports = function (obj, key, value) { + var flags = obj.__flags || (obj.__flags = Object.create(null)); + if (arguments.length === 3) { + flags[key] = value; + } else { + return flags[key]; + } +}; + +},{}],18:[function(require,module,exports){ +/*! + * Chai - getActual utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * # getActual(object, [actual]) + * + * Returns the `actual` value for an Assertion + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getActual + */ + +module.exports = function (obj, args) { + return args.length > 4 ? args[4] : obj._obj; +}; + +},{}],19:[function(require,module,exports){ +/*! + * Chai - getEnumerableProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getEnumerableProperties(object) + * + * This allows the retrieval of enumerable property names of an object, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getEnumerableProperties + * @api public + */ + +module.exports = function getEnumerableProperties(object) { + var result = []; + for (var name in object) { + result.push(name); + } + return result; +}; + +},{}],20:[function(require,module,exports){ +/*! + * Chai - message composition utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var flag = require('./flag') + , getActual = require('./getActual') + , inspect = require('./inspect') + , objDisplay = require('./objDisplay'); + +/** + * ### .getMessage(object, message, negateMessage) + * + * Construct the error message based on flags + * and template tags. Template tags will return + * a stringified inspection of the object referenced. + * + * Message template tags: + * - `#{this}` current asserted object + * - `#{act}` actual value + * - `#{exp}` expected value + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getMessage + * @api public + */ + +module.exports = function (obj, args) { + var negate = flag(obj, 'negate') + , val = flag(obj, 'object') + , expected = args[3] + , actual = getActual(obj, args) + , msg = negate ? args[2] : args[1] + , flagMsg = flag(obj, 'message'); + + if(typeof msg === "function") msg = msg(); + msg = msg || ''; + msg = msg + .replace(/#\{this\}/g, function () { return objDisplay(val); }) + .replace(/#\{act\}/g, function () { return objDisplay(actual); }) + .replace(/#\{exp\}/g, function () { return objDisplay(expected); }); + + return flagMsg ? flagMsg + ': ' + msg : msg; +}; + +},{"./flag":17,"./getActual":18,"./inspect":27,"./objDisplay":28}],21:[function(require,module,exports){ +/*! + * Chai - getName utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * # getName(func) + * + * Gets the name of a function, in a cross-browser way. + * + * @param {Function} a function (usually a constructor) + * @namespace Utils + * @name getName + */ + +module.exports = function (func) { + if (func.name) return func.name; + + var match = /^\s?function ([^(]*)\(/.exec(func); + return match && match[1] ? match[1] : ""; +}; + +},{}],22:[function(require,module,exports){ +/*! + * Chai - getPathInfo utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var hasProperty = require('./hasProperty'); + +/** + * ### .getPathInfo(path, object) + * + * This allows the retrieval of property info in an + * object given a string path. + * + * The path info consists of an object with the + * following properties: + * + * * parent - The parent object of the property referenced by `path` + * * name - The name of the final property, a number if it was an array indexer + * * value - The value of the property, if it exists, otherwise `undefined` + * * exists - Whether the property exists or not + * + * @param {String} path + * @param {Object} object + * @returns {Object} info + * @namespace Utils + * @name getPathInfo + * @api public + */ + +module.exports = function getPathInfo(path, obj) { + var parsed = parsePath(path), + last = parsed[parsed.length - 1]; + + var info = { + parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj, + name: last.p || last.i, + value: _getPathValue(parsed, obj) + }; + info.exists = hasProperty(info.name, info.parent); + + return info; +}; + + +/*! + * ## parsePath(path) + * + * Helper function used to parse string object + * paths. Use in conjunction with `_getPathValue`. + * + * var parsed = parsePath('myobject.property.subprop'); + * + * ### Paths: + * + * * Can be as near infinitely deep and nested + * * Arrays are also valid using the formal `myobject.document[3].property`. + * * Literal dots and brackets (not delimiter) must be backslash-escaped. + * + * @param {String} path + * @returns {Object} parsed + * @api private + */ + +function parsePath (path) { + var str = path.replace(/([^\\])\[/g, '$1.[') + , parts = str.match(/(\\\.|[^.]+?)+/g); + return parts.map(function (value) { + var re = /^\[(\d+)\]$/ + , mArr = re.exec(value); + if (mArr) return { i: parseFloat(mArr[1]) }; + else return { p: value.replace(/\\([.\[\]])/g, '$1') }; + }); +} + + +/*! + * ## _getPathValue(parsed, obj) + * + * Helper companion function for `.parsePath` that returns + * the value located at the parsed address. + * + * var value = getPathValue(parsed, obj); + * + * @param {Object} parsed definition from `parsePath`. + * @param {Object} object to search against + * @param {Number} object to search against + * @returns {Object|Undefined} value + * @api private + */ + +function _getPathValue (parsed, obj, index) { + var tmp = obj + , res; + + index = (index === undefined ? parsed.length : index); + + for (var i = 0, l = index; i < l; i++) { + var part = parsed[i]; + if (tmp) { + if ('undefined' !== typeof part.p) + tmp = tmp[part.p]; + else if ('undefined' !== typeof part.i) + tmp = tmp[part.i]; + if (i == (l - 1)) res = tmp; + } else { + res = undefined; + } + } + return res; +} + +},{"./hasProperty":25}],23:[function(require,module,exports){ +/*! + * Chai - getPathValue utility + * Copyright(c) 2012-2014 Jake Luer + * @see https://github.com/logicalparadox/filtr + * MIT Licensed + */ + +var getPathInfo = require('./getPathInfo'); + +/** + * ### .getPathValue(path, object) + * + * This allows the retrieval of values in an + * object given a string path. + * + * var obj = { + * prop1: { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * , prop2: { + * arr: [ { nested: 'Universe' } ] + * , str: 'Hello again!' + * } + * } + * + * The following would be the results. + * + * getPathValue('prop1.str', obj); // Hello + * getPathValue('prop1.att[2]', obj); // b + * getPathValue('prop2.arr[0].nested', obj); // Universe + * + * @param {String} path + * @param {Object} object + * @returns {Object} value or `undefined` + * @namespace Utils + * @name getPathValue + * @api public + */ +module.exports = function(path, obj) { + var info = getPathInfo(path, obj); + return info.value; +}; + +},{"./getPathInfo":22}],24:[function(require,module,exports){ +/*! + * Chai - getProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getProperties(object) + * + * This allows the retrieval of property names of an object, enumerable or not, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getProperties + * @api public + */ + +module.exports = function getProperties(object) { + var result = Object.getOwnPropertyNames(object); + + function addProperty(property) { + if (result.indexOf(property) === -1) { + result.push(property); + } + } + + var proto = Object.getPrototypeOf(object); + while (proto !== null) { + Object.getOwnPropertyNames(proto).forEach(addProperty); + proto = Object.getPrototypeOf(proto); + } + + return result; +}; + +},{}],25:[function(require,module,exports){ +/*! + * Chai - hasProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var type = require('type-detect'); + +/** + * ### .hasProperty(object, name) + * + * This allows checking whether an object has + * named property or numeric array index. + * + * Basically does the same thing as the `in` + * operator but works properly with natives + * and null/undefined values. + * + * var obj = { + * arr: ['a', 'b', 'c'] + * , str: 'Hello' + * } + * + * The following would be the results. + * + * hasProperty('str', obj); // true + * hasProperty('constructor', obj); // true + * hasProperty('bar', obj); // false + * + * hasProperty('length', obj.str); // true + * hasProperty(1, obj.str); // true + * hasProperty(5, obj.str); // false + * + * hasProperty('length', obj.arr); // true + * hasProperty(2, obj.arr); // true + * hasProperty(3, obj.arr); // false + * + * @param {Objuect} object + * @param {String|Number} name + * @returns {Boolean} whether it exists + * @namespace Utils + * @name getPathInfo + * @api public + */ + +var literals = { + 'number': Number + , 'string': String +}; + +module.exports = function hasProperty(name, obj) { + var ot = type(obj); + + // Bad Object, obviously no props at all + if(ot === 'null' || ot === 'undefined') + return false; + + // The `in` operator does not work with certain literals + // box these before the check + if(literals[ot] && typeof obj !== 'object') + obj = new literals[ot](obj); + + return name in obj; +}; + +},{"type-detect":40}],26:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011 Jake Luer + * MIT Licensed + */ + +/*! + * Main exports + */ + +var exports = module.exports = {}; + +/*! + * test utility + */ + +exports.test = require('./test'); + +/*! + * type utility + */ + +exports.type = require('type-detect'); + +/*! + * expectTypes utility + */ +exports.expectTypes = require('./expectTypes'); + +/*! + * message utility + */ + +exports.getMessage = require('./getMessage'); + +/*! + * actual utility + */ + +exports.getActual = require('./getActual'); + +/*! + * Inspect util + */ + +exports.inspect = require('./inspect'); + +/*! + * Object Display util + */ + +exports.objDisplay = require('./objDisplay'); + +/*! + * Flag utility + */ + +exports.flag = require('./flag'); + +/*! + * Flag transferring utility + */ + +exports.transferFlags = require('./transferFlags'); + +/*! + * Deep equal utility + */ + +exports.eql = require('deep-eql'); + +/*! + * Deep path value + */ + +exports.getPathValue = require('./getPathValue'); + +/*! + * Deep path info + */ + +exports.getPathInfo = require('./getPathInfo'); + +/*! + * Check if a property exists + */ + +exports.hasProperty = require('./hasProperty'); + +/*! + * Function name + */ + +exports.getName = require('./getName'); + +/*! + * add Property + */ + +exports.addProperty = require('./addProperty'); + +/*! + * add Method + */ + +exports.addMethod = require('./addMethod'); + +/*! + * overwrite Property + */ + +exports.overwriteProperty = require('./overwriteProperty'); + +/*! + * overwrite Method + */ + +exports.overwriteMethod = require('./overwriteMethod'); + +/*! + * Add a chainable method + */ + +exports.addChainableMethod = require('./addChainableMethod'); + +/*! + * Overwrite chainable method + */ + +exports.overwriteChainableMethod = require('./overwriteChainableMethod'); + +},{"./addChainableMethod":13,"./addMethod":14,"./addProperty":15,"./expectTypes":16,"./flag":17,"./getActual":18,"./getMessage":20,"./getName":21,"./getPathInfo":22,"./getPathValue":23,"./hasProperty":25,"./inspect":27,"./objDisplay":28,"./overwriteChainableMethod":29,"./overwriteMethod":30,"./overwriteProperty":31,"./test":32,"./transferFlags":33,"deep-eql":35,"type-detect":40}],27:[function(require,module,exports){ +// This is (almost) directly from Node.js utils +// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js + +var getName = require('./getName'); +var getProperties = require('./getProperties'); +var getEnumerableProperties = require('./getEnumerableProperties'); + +module.exports = inspect; + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Boolean} showHidden Flag that shows hidden (not enumerable) + * properties of objects. + * @param {Number} depth Depth in which to descend in object. Default is 2. + * @param {Boolean} colors Flag to turn on ANSI escape codes to color the + * output. Default is false (no coloring). + * @namespace Utils + * @name inspect + */ +function inspect(obj, showHidden, depth, colors) { + var ctx = { + showHidden: showHidden, + seen: [], + stylize: function (str) { return str; } + }; + return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth)); +} + +// Returns true if object is a DOM element. +var isDOMElement = function (object) { + if (typeof HTMLElement === 'object') { + return object instanceof HTMLElement; + } else { + return object && + typeof object === 'object' && + object.nodeType === 1 && + typeof object.nodeName === 'string'; + } +}; + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (value && typeof value.inspect === 'function' && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes); + if (typeof ret !== 'string') { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // If this is a DOM element, try to get the outer HTML. + if (isDOMElement(value)) { + if ('outerHTML' in value) { + return value.outerHTML; + // This value does not have an outerHTML attribute, + // it could still be an XML element + } else { + // Attempt to serialize it + try { + if (document.xmlVersion) { + var xmlSerializer = new XMLSerializer(); + return xmlSerializer.serializeToString(value); + } else { + // Firefox 11- do not support outerHTML + // It does, however, support innerHTML + // Use the following to render the element + var ns = "http://www.w3.org/1999/xhtml"; + var container = document.createElementNS(ns, '_'); + + container.appendChild(value.cloneNode(false)); + html = container.innerHTML + .replace('><', '>' + value.innerHTML + '<'); + container.innerHTML = ''; + return html; + } + } catch (err) { + // This could be a non-native DOM implementation, + // continue with the normal flow: + // printing the element as if it is an object. + } + } + } + + // Look up the keys of the object. + var visibleKeys = getEnumerableProperties(value); + var keys = ctx.showHidden ? getProperties(value) : visibleKeys; + + // Some type of object without properties can be shortcutted. + // In IE, errors have a single `stack` property, or if they are vanilla `Error`, + // a `stack` plus `description` property; ignore those for consistency. + if (keys.length === 0 || (isError(value) && ( + (keys.length === 1 && keys[0] === 'stack') || + (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack') + ))) { + if (typeof value === 'function') { + var name = getName(value); + var nameSuffix = name ? ': ' + name : ''; + return ctx.stylize('[Function' + nameSuffix + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toUTCString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (typeof value === 'function') { + var name = getName(value); + var nameSuffix = name ? ': ' + name : ''; + base = ' [Function' + nameSuffix + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + return formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + switch (typeof value) { + case 'undefined': + return ctx.stylize('undefined', 'undefined'); + + case 'string': + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + + case 'number': + if (value === 0 && (1/value) === -Infinity) { + return ctx.stylize('-0', 'number'); + } + return ctx.stylize('' + value, 'number'); + + case 'boolean': + return ctx.stylize('' + value, 'boolean'); + } + // For some reason typeof null is "object", so special case here. + if (value === null) { + return ctx.stylize('null', 'null'); + } +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (Object.prototype.hasOwnProperty.call(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str; + if (value.__lookupGetter__) { + if (value.__lookupGetter__(key)) { + if (value.__lookupSetter__(key)) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (value.__lookupSetter__(key)) { + str = ctx.stylize('[Setter]', 'special'); + } + } + } + if (visibleKeys.indexOf(key) < 0) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(value[key]) < 0) { + if (recurseTimes === null) { + str = formatValue(ctx, value[key], null); + } else { + str = formatValue(ctx, value[key], recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (typeof name === 'undefined') { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + +function isArray(ar) { + return Array.isArray(ar) || + (typeof ar === 'object' && objectToString(ar) === '[object Array]'); +} + +function isRegExp(re) { + return typeof re === 'object' && objectToString(re) === '[object RegExp]'; +} + +function isDate(d) { + return typeof d === 'object' && objectToString(d) === '[object Date]'; +} + +function isError(e) { + return typeof e === 'object' && objectToString(e) === '[object Error]'; +} + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + +},{"./getEnumerableProperties":19,"./getName":21,"./getProperties":24}],28:[function(require,module,exports){ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var inspect = require('./inspect'); +var config = require('../config'); + +/** + * ### .objDisplay (object) + * + * Determines if an object or an array matches + * criteria to be inspected in-line for error + * messages or should be truncated. + * + * @param {Mixed} javascript object to inspect + * @name objDisplay + * @namespace Utils + * @api public + */ + +module.exports = function (obj) { + var str = inspect(obj) + , type = Object.prototype.toString.call(obj); + + if (config.truncateThreshold && str.length >= config.truncateThreshold) { + if (type === '[object Function]') { + return !obj.name || obj.name === '' + ? '[Function]' + : '[Function: ' + obj.name + ']'; + } else if (type === '[object Array]') { + return '[ Array(' + obj.length + ') ]'; + } else if (type === '[object Object]') { + var keys = Object.keys(obj) + , kstr = keys.length > 2 + ? keys.splice(0, 2).join(', ') + ', ...' + : keys.join(', '); + return '{ Object (' + kstr + ') }'; + } else { + return str; + } + } else { + return str; + } +}; + +},{"../config":8,"./inspect":27}],29:[function(require,module,exports){ +/*! + * Chai - overwriteChainableMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### overwriteChainableMethod (ctx, name, method, chainingBehavior) + * + * Overwites an already existing chainable method + * and provides access to the previous function or + * property. Must return functions to be used for + * name. + * + * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length', + * function (_super) { + * } + * , function (_super) { + * } + * ); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteChainableMethod('foo', fn, fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.have.length(3); + * expect(myFoo).to.have.length.above(3); + * + * @param {Object} ctx object whose method / property is to be overwritten + * @param {String} name of method / property to overwrite + * @param {Function} method function that returns a function to be used for name + * @param {Function} chainingBehavior function that returns a function to be used for property + * @namespace Utils + * @name overwriteChainableMethod + * @api public + */ + +module.exports = function (ctx, name, method, chainingBehavior) { + var chainableBehavior = ctx.__methods[name]; + + var _chainingBehavior = chainableBehavior.chainingBehavior; + chainableBehavior.chainingBehavior = function () { + var result = chainingBehavior(_chainingBehavior).call(this); + return result === undefined ? this : result; + }; + + var _method = chainableBehavior.method; + chainableBehavior.method = function () { + var result = method(_method).apply(this, arguments); + return result === undefined ? this : result; + }; +}; + +},{}],30:[function(require,module,exports){ +/*! + * Chai - overwriteMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### overwriteMethod (ctx, name, fn) + * + * Overwites an already existing method and provides + * access to previous function. Must return function + * to be used for name. + * + * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) { + * return function (str) { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.value).to.equal(str); + * } else { + * _super.apply(this, arguments); + * } + * } + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.equal('bar'); + * + * @param {Object} ctx object whose method is to be overwritten + * @param {String} name of method to overwrite + * @param {Function} method function that returns a function to be used for name + * @namespace Utils + * @name overwriteMethod + * @api public + */ + +module.exports = function (ctx, name, method) { + var _method = ctx[name] + , _super = function () { return this; }; + + if (_method && 'function' === typeof _method) + _super = _method; + + ctx[name] = function () { + var result = method(_super).apply(this, arguments); + return result === undefined ? this : result; + } +}; + +},{}],31:[function(require,module,exports){ +/*! + * Chai - overwriteProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### overwriteProperty (ctx, name, fn) + * + * Overwites an already existing property getter and provides + * access to previous value. Must return function to use as getter. + * + * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) { + * return function () { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.name).to.equal('bar'); + * } else { + * _super.call(this); + * } + * } + * }); + * + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.ok; + * + * @param {Object} ctx object whose property is to be overwritten + * @param {String} name of property to overwrite + * @param {Function} getter function that returns a getter function to be used for name + * @namespace Utils + * @name overwriteProperty + * @api public + */ + +module.exports = function (ctx, name, getter) { + var _get = Object.getOwnPropertyDescriptor(ctx, name) + , _super = function () {}; + + if (_get && 'function' === typeof _get.get) + _super = _get.get + + Object.defineProperty(ctx, name, + { get: function () { + var result = getter(_super).call(this); + return result === undefined ? this : result; + } + , configurable: true + }); +}; + +},{}],32:[function(require,module,exports){ +/*! + * Chai - test utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var flag = require('./flag'); + +/** + * # test(object, expression) + * + * Test and object for expression. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name test + */ + +module.exports = function (obj, args) { + var negate = flag(obj, 'negate') + , expr = args[0]; + return negate ? !expr : expr; +}; + +},{"./flag":17}],33:[function(require,module,exports){ +/*! + * Chai - transferFlags utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### transferFlags(assertion, object, includeAll = true) + * + * Transfer all the flags for `assertion` to `object`. If + * `includeAll` is set to `false`, then the base Chai + * assertion flags (namely `object`, `ssfi`, and `message`) + * will not be transferred. + * + * + * var newAssertion = new Assertion(); + * utils.transferFlags(assertion, newAssertion); + * + * var anotherAsseriton = new Assertion(myObj); + * utils.transferFlags(assertion, anotherAssertion, false); + * + * @param {Assertion} assertion the assertion to transfer the flags from + * @param {Object} object the object to transfer the flags to; usually a new assertion + * @param {Boolean} includeAll + * @namespace Utils + * @name transferFlags + * @api private + */ + +module.exports = function (assertion, object, includeAll) { + var flags = assertion.__flags || (assertion.__flags = Object.create(null)); + + if (!object.__flags) { + object.__flags = Object.create(null); + } + + includeAll = arguments.length === 3 ? includeAll : true; + + for (var flag in flags) { + if (includeAll || + (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) { + object.__flags[flag] = flags[flag]; + } + } +}; + +},{}],34:[function(require,module,exports){ +"use strict"; + +function dedent(strings) { + + var raw = void 0; + if (typeof strings === "string") { + // dedent can be used as a plain function + raw = [strings]; + } else { + raw = strings.raw; + } + + // first, perform interpolation + var result = ""; + for (var i = 0; i < raw.length; i++) { + result += raw[i]. + // join lines when there is a suppressed newline + replace(/\\\n[ \t]*/g, ""). + + // handle escaped backticks + replace(/\\`/g, "`"); + + if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) { + result += arguments.length <= i + 1 ? undefined : arguments[i + 1]; + } + } + + // now strip indentation + var lines = result.split("\n"); + var mindent = null; + lines.forEach(function (l) { + var m = l.match(/^(\s+)\S+/); + if (m) { + var indent = m[1].length; + if (!mindent) { + // this is the first indented line + mindent = indent; + } else { + mindent = Math.min(mindent, indent); + } + } + }); + + if (mindent !== null) { + result = lines.map(function (l) { + return l[0] === " " ? l.slice(mindent) : l; + }).join("\n"); + } + + // dedent eats leading and trailing whitespace too + result = result.trim(); + + // handle escaped newlines at the end to ensure they don't get stripped too + return result.replace(/\\n/g, "\n"); +} + +if (typeof module !== "undefined") { + module.exports = dedent; +} + +},{}],35:[function(require,module,exports){ +module.exports = require('./lib/eql'); + +},{"./lib/eql":36}],36:[function(require,module,exports){ +/*! + * deep-eql + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var type = require('type-detect'); + +/*! + * Buffer.isBuffer browser shim + */ + +var Buffer; +try { Buffer = require('buffer').Buffer; } +catch(ex) { + Buffer = {}; + Buffer.isBuffer = function() { return false; } +} + +/*! + * Primary Export + */ + +module.exports = deepEqual; + +/** + * Assert super-strict (egal) equality between + * two objects of any type. + * + * @param {Mixed} a + * @param {Mixed} b + * @param {Array} memoised (optional) + * @return {Boolean} equal match + */ + +function deepEqual(a, b, m) { + if (sameValue(a, b)) { + return true; + } else if ('date' === type(a)) { + return dateEqual(a, b); + } else if ('regexp' === type(a)) { + return regexpEqual(a, b); + } else if (Buffer.isBuffer(a)) { + return bufferEqual(a, b); + } else if ('arguments' === type(a)) { + return argumentsEqual(a, b, m); + } else if (!typeEqual(a, b)) { + return false; + } else if (('object' !== type(a) && 'object' !== type(b)) + && ('array' !== type(a) && 'array' !== type(b))) { + return sameValue(a, b); + } else { + return objectEqual(a, b, m); + } +} + +/*! + * Strict (egal) equality test. Ensures that NaN always + * equals NaN and `-0` does not equal `+0`. + * + * @param {Mixed} a + * @param {Mixed} b + * @return {Boolean} equal match + */ + +function sameValue(a, b) { + if (a === b) return a !== 0 || 1 / a === 1 / b; + return a !== a && b !== b; +} + +/*! + * Compare the types of two given objects and + * return if they are equal. Note that an Array + * has a type of `array` (not `object`) and arguments + * have a type of `arguments` (not `array`/`object`). + * + * @param {Mixed} a + * @param {Mixed} b + * @return {Boolean} result + */ + +function typeEqual(a, b) { + return type(a) === type(b); +} + +/*! + * Compare two Date objects by asserting that + * the time values are equal using `saveValue`. + * + * @param {Date} a + * @param {Date} b + * @return {Boolean} result + */ + +function dateEqual(a, b) { + if ('date' !== type(b)) return false; + return sameValue(a.getTime(), b.getTime()); +} + +/*! + * Compare two regular expressions by converting them + * to string and checking for `sameValue`. + * + * @param {RegExp} a + * @param {RegExp} b + * @return {Boolean} result + */ + +function regexpEqual(a, b) { + if ('regexp' !== type(b)) return false; + return sameValue(a.toString(), b.toString()); +} + +/*! + * Assert deep equality of two `arguments` objects. + * Unfortunately, these must be sliced to arrays + * prior to test to ensure no bad behavior. + * + * @param {Arguments} a + * @param {Arguments} b + * @param {Array} memoize (optional) + * @return {Boolean} result + */ + +function argumentsEqual(a, b, m) { + if ('arguments' !== type(b)) return false; + a = [].slice.call(a); + b = [].slice.call(b); + return deepEqual(a, b, m); +} + +/*! + * Get enumerable properties of a given object. + * + * @param {Object} a + * @return {Array} property names + */ + +function enumerable(a) { + var res = []; + for (var key in a) res.push(key); + return res; +} + +/*! + * Simple equality for flat iterable objects + * such as Arrays or Node.js buffers. + * + * @param {Iterable} a + * @param {Iterable} b + * @return {Boolean} result + */ + +function iterableEqual(a, b) { + if (a.length !== b.length) return false; + + var i = 0; + var match = true; + + for (; i < a.length; i++) { + if (a[i] !== b[i]) { + match = false; + break; + } + } + + return match; +} + +/*! + * Extension to `iterableEqual` specifically + * for Node.js Buffers. + * + * @param {Buffer} a + * @param {Mixed} b + * @return {Boolean} result + */ + +function bufferEqual(a, b) { + if (!Buffer.isBuffer(b)) return false; + return iterableEqual(a, b); +} + +/*! + * Block for `objectEqual` ensuring non-existing + * values don't get in. + * + * @param {Mixed} object + * @return {Boolean} result + */ + +function isValue(a) { + return a !== null && a !== undefined; +} + +/*! + * Recursively check the equality of two objects. + * Once basic sameness has been established it will + * defer to `deepEqual` for each enumerable key + * in the object. + * + * @param {Mixed} a + * @param {Mixed} b + * @return {Boolean} result + */ + +function objectEqual(a, b, m) { + if (!isValue(a) || !isValue(b)) { + return false; + } + + if (a.prototype !== b.prototype) { + return false; + } + + var i; + if (m) { + for (i = 0; i < m.length; i++) { + if ((m[i][0] === a && m[i][1] === b) + || (m[i][0] === b && m[i][1] === a)) { + return true; + } + } + } else { + m = []; + } + + try { + var ka = enumerable(a); + var kb = enumerable(b); + } catch (ex) { + return false; + } + + ka.sort(); + kb.sort(); + + if (!iterableEqual(ka, kb)) { + return false; + } + + m.push([ a, b ]); + + var key; + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!deepEqual(a[key], b[key], m)) { + return false; + } + } + + return true; +} + +},{"buffer":undefined,"type-detect":38}],37:[function(require,module,exports){ +(function (global){ +/*! + localForage -- Offline Storage, Improved + Version 1.5.0 + https://localforage.github.io/localForage + (c) 2013-2017 Mozilla, Apache License 2.0 +*/ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.localforage = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw (f.code="MODULE_NOT_FOUND", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o element; its readystatechange event will be fired asynchronously once it is inserted + // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called. + var scriptEl = global.document.createElement('script'); + scriptEl.onreadystatechange = function () { + nextTick(); + + scriptEl.onreadystatechange = null; + scriptEl.parentNode.removeChild(scriptEl); + scriptEl = null; + }; + global.document.documentElement.appendChild(scriptEl); + }; + } else { + scheduleDrain = function () { + setTimeout(nextTick, 0); + }; + } +} + +var draining; +var queue = []; +//named nextTick for less confusing stack traces +function nextTick() { + draining = true; + var i, oldQueue; + var len = queue.length; + while (len) { + oldQueue = queue; + queue = []; + i = -1; + while (++i < len) { + oldQueue[i](); + } + len = queue.length; + } + draining = false; +} + +module.exports = immediate; +function immediate(task) { + if (queue.push(task) === 1 && !draining) { + scheduleDrain(); + } +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],2:[function(_dereq_,module,exports){ +'use strict'; +var immediate = _dereq_(1); + +/* istanbul ignore next */ +function INTERNAL() {} + +var handlers = {}; + +var REJECTED = ['REJECTED']; +var FULFILLED = ['FULFILLED']; +var PENDING = ['PENDING']; + +module.exports = exports = Promise; + +function Promise(resolver) { + if (typeof resolver !== 'function') { + throw new TypeError('resolver must be a function'); + } + this.state = PENDING; + this.queue = []; + this.outcome = void 0; + if (resolver !== INTERNAL) { + safelyResolveThenable(this, resolver); + } +} + +Promise.prototype["catch"] = function (onRejected) { + return this.then(null, onRejected); +}; +Promise.prototype.then = function (onFulfilled, onRejected) { + if (typeof onFulfilled !== 'function' && this.state === FULFILLED || + typeof onRejected !== 'function' && this.state === REJECTED) { + return this; + } + var promise = new this.constructor(INTERNAL); + if (this.state !== PENDING) { + var resolver = this.state === FULFILLED ? onFulfilled : onRejected; + unwrap(promise, resolver, this.outcome); + } else { + this.queue.push(new QueueItem(promise, onFulfilled, onRejected)); + } + + return promise; +}; +function QueueItem(promise, onFulfilled, onRejected) { + this.promise = promise; + if (typeof onFulfilled === 'function') { + this.onFulfilled = onFulfilled; + this.callFulfilled = this.otherCallFulfilled; + } + if (typeof onRejected === 'function') { + this.onRejected = onRejected; + this.callRejected = this.otherCallRejected; + } +} +QueueItem.prototype.callFulfilled = function (value) { + handlers.resolve(this.promise, value); +}; +QueueItem.prototype.otherCallFulfilled = function (value) { + unwrap(this.promise, this.onFulfilled, value); +}; +QueueItem.prototype.callRejected = function (value) { + handlers.reject(this.promise, value); +}; +QueueItem.prototype.otherCallRejected = function (value) { + unwrap(this.promise, this.onRejected, value); +}; + +function unwrap(promise, func, value) { + immediate(function () { + var returnValue; + try { + returnValue = func(value); + } catch (e) { + return handlers.reject(promise, e); + } + if (returnValue === promise) { + handlers.reject(promise, new TypeError('Cannot resolve promise with itself')); + } else { + handlers.resolve(promise, returnValue); + } + }); +} + +handlers.resolve = function (self, value) { + var result = tryCatch(getThen, value); + if (result.status === 'error') { + return handlers.reject(self, result.value); + } + var thenable = result.value; + + if (thenable) { + safelyResolveThenable(self, thenable); + } else { + self.state = FULFILLED; + self.outcome = value; + var i = -1; + var len = self.queue.length; + while (++i < len) { + self.queue[i].callFulfilled(value); + } + } + return self; +}; +handlers.reject = function (self, error) { + self.state = REJECTED; + self.outcome = error; + var i = -1; + var len = self.queue.length; + while (++i < len) { + self.queue[i].callRejected(error); + } + return self; +}; + +function getThen(obj) { + // Make sure we only access the accessor once as required by the spec + var then = obj && obj.then; + if (obj && typeof obj === 'object' && typeof then === 'function') { + return function appyThen() { + then.apply(obj, arguments); + }; + } +} + +function safelyResolveThenable(self, thenable) { + // Either fulfill, reject or reject with error + var called = false; + function onError(value) { + if (called) { + return; + } + called = true; + handlers.reject(self, value); + } + + function onSuccess(value) { + if (called) { + return; + } + called = true; + handlers.resolve(self, value); + } + + function tryToUnwrap() { + thenable(onSuccess, onError); + } + + var result = tryCatch(tryToUnwrap); + if (result.status === 'error') { + onError(result.value); + } +} + +function tryCatch(func, value) { + var out = {}; + try { + out.value = func(value); + out.status = 'success'; + } catch (e) { + out.status = 'error'; + out.value = e; + } + return out; +} + +exports.resolve = resolve; +function resolve(value) { + if (value instanceof this) { + return value; + } + return handlers.resolve(new this(INTERNAL), value); +} + +exports.reject = reject; +function reject(reason) { + var promise = new this(INTERNAL); + return handlers.reject(promise, reason); +} + +exports.all = all; +function all(iterable) { + var self = this; + if (Object.prototype.toString.call(iterable) !== '[object Array]') { + return this.reject(new TypeError('must be an array')); + } + + var len = iterable.length; + var called = false; + if (!len) { + return this.resolve([]); + } + + var values = new Array(len); + var resolved = 0; + var i = -1; + var promise = new this(INTERNAL); + + while (++i < len) { + allResolver(iterable[i], i); + } + return promise; + function allResolver(value, i) { + self.resolve(value).then(resolveFromAll, function (error) { + if (!called) { + called = true; + handlers.reject(promise, error); + } + }); + function resolveFromAll(outValue) { + values[i] = outValue; + if (++resolved === len && !called) { + called = true; + handlers.resolve(promise, values); + } + } + } +} + +exports.race = race; +function race(iterable) { + var self = this; + if (Object.prototype.toString.call(iterable) !== '[object Array]') { + return this.reject(new TypeError('must be an array')); + } + + var len = iterable.length; + var called = false; + if (!len) { + return this.resolve([]); + } + + var i = -1; + var promise = new this(INTERNAL); + + while (++i < len) { + resolver(iterable[i]); + } + return promise; + function resolver(value) { + self.resolve(value).then(function (response) { + if (!called) { + called = true; + handlers.resolve(promise, response); + } + }, function (error) { + if (!called) { + called = true; + handlers.reject(promise, error); + } + }); + } +} + +},{"1":1}],3:[function(_dereq_,module,exports){ +(function (global){ +'use strict'; +if (typeof global.Promise !== 'function') { + global.Promise = _dereq_(2); +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"2":2}],4:[function(_dereq_,module,exports){ +'use strict'; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function getIDB() { + /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */ + try { + if (typeof indexedDB !== 'undefined') { + return indexedDB; + } + if (typeof webkitIndexedDB !== 'undefined') { + return webkitIndexedDB; + } + if (typeof mozIndexedDB !== 'undefined') { + return mozIndexedDB; + } + if (typeof OIndexedDB !== 'undefined') { + return OIndexedDB; + } + if (typeof msIndexedDB !== 'undefined') { + return msIndexedDB; + } + } catch (e) {} +} + +var idb = getIDB(); + +function isIndexedDBValid() { + try { + // Initialize IndexedDB; fall back to vendor-prefixed versions + // if needed. + if (!idb) { + return false; + } + // We mimic PouchDB here; + // + // We test for openDatabase because IE Mobile identifies itself + // as Safari. Oh the lulz... + var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform); + + var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1; + + // Safari <10.1 does not meet our requirements for IDB support (#5572) + // since Safari 10.1 shipped with fetch, we can use that to detect it + return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' && + // some outdated implementations of IDB that appear on Samsung + // and HTC Android devices <4.4 are missing IDBKeyRange + typeof IDBKeyRange !== 'undefined'; + } catch (e) { + return false; + } +} + +function isWebSQLValid() { + return typeof openDatabase === 'function'; +} + +function isLocalStorageValid() { + try { + return typeof localStorage !== 'undefined' && 'setItem' in localStorage && localStorage.setItem; + } catch (e) { + return false; + } +} + +// Abstracts constructing a Blob object, so it also works in older +// browsers that don't support the native Blob constructor. (i.e. +// old QtWebKit versions, at least). +// Abstracts constructing a Blob object, so it also works in older +// browsers that don't support the native Blob constructor. (i.e. +// old QtWebKit versions, at least). +function createBlob(parts, properties) { + /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */ + parts = parts || []; + properties = properties || {}; + try { + return new Blob(parts, properties); + } catch (e) { + if (e.name !== 'TypeError') { + throw e; + } + var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder; + var builder = new Builder(); + for (var i = 0; i < parts.length; i += 1) { + builder.append(parts[i]); + } + return builder.getBlob(properties.type); + } +} + +// This is CommonJS because lie is an external dependency, so Rollup +// can just ignore it. +if (typeof Promise === 'undefined') { + // In the "nopromises" build this will just throw if you don't have + // a global promise object, but it would throw anyway later. + _dereq_(3); +} +var Promise$1 = Promise; + +function executeCallback(promise, callback) { + if (callback) { + promise.then(function (result) { + callback(null, result); + }, function (error) { + callback(error); + }); + } +} + +function executeTwoCallbacks(promise, callback, errorCallback) { + if (typeof callback === 'function') { + promise.then(callback); + } + + if (typeof errorCallback === 'function') { + promise["catch"](errorCallback); + } +} + +// Some code originally from async_storage.js in +// [Gaia](https://github.com/mozilla-b2g/gaia). + +var DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support'; +var supportsBlobs; +var dbContexts; +var toString = Object.prototype.toString; + +// Transform a binary string to an array buffer, because otherwise +// weird stuff happens when you try to work with the binary string directly. +// It is known. +// From http://stackoverflow.com/questions/14967647/ (continues on next line) +// encode-decode-image-with-base64-breaks-image (2013-04-21) +function _binStringToArrayBuffer(bin) { + var length = bin.length; + var buf = new ArrayBuffer(length); + var arr = new Uint8Array(buf); + for (var i = 0; i < length; i++) { + arr[i] = bin.charCodeAt(i); + } + return buf; +} + +// +// Blobs are not supported in all versions of IndexedDB, notably +// Chrome <37 and Android <5. In those versions, storing a blob will throw. +// +// Various other blob bugs exist in Chrome v37-42 (inclusive). +// Detecting them is expensive and confusing to users, and Chrome 37-42 +// is at very low usage worldwide, so we do a hacky userAgent check instead. +// +// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120 +// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916 +// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836 +// +// Code borrowed from PouchDB. See: +// https://github.com/pouchdb/pouchdb/blob/master/packages/node_modules/pouchdb-adapter-idb/src/blobSupport.js +// +function _checkBlobSupportWithoutCaching(idb) { + return new Promise$1(function (resolve) { + var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, 'readwrite'); + var blob = createBlob(['']); + txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key'); + + txn.onabort = function (e) { + // If the transaction aborts now its due to not being able to + // write to the database, likely due to the disk being full + e.preventDefault(); + e.stopPropagation(); + resolve(false); + }; + + txn.oncomplete = function () { + var matchedChrome = navigator.userAgent.match(/Chrome\/(\d+)/); + var matchedEdge = navigator.userAgent.match(/Edge\//); + // MS Edge pretends to be Chrome 42: + // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx + resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43); + }; + })["catch"](function () { + return false; // error, so assume unsupported + }); +} + +function _checkBlobSupport(idb) { + if (typeof supportsBlobs === 'boolean') { + return Promise$1.resolve(supportsBlobs); + } + return _checkBlobSupportWithoutCaching(idb).then(function (value) { + supportsBlobs = value; + return supportsBlobs; + }); +} + +function _deferReadiness(dbInfo) { + var dbContext = dbContexts[dbInfo.name]; + + // Create a deferred object representing the current database operation. + var deferredOperation = {}; + + deferredOperation.promise = new Promise$1(function (resolve) { + deferredOperation.resolve = resolve; + }); + + // Enqueue the deferred operation. + dbContext.deferredOperations.push(deferredOperation); + + // Chain its promise to the database readiness. + if (!dbContext.dbReady) { + dbContext.dbReady = deferredOperation.promise; + } else { + dbContext.dbReady = dbContext.dbReady.then(function () { + return deferredOperation.promise; + }); + } +} + +function _advanceReadiness(dbInfo) { + var dbContext = dbContexts[dbInfo.name]; + + // Dequeue a deferred operation. + var deferredOperation = dbContext.deferredOperations.pop(); + + // Resolve its promise (which is part of the database readiness + // chain of promises). + if (deferredOperation) { + deferredOperation.resolve(); + } +} + +function _getConnection(dbInfo, upgradeNeeded) { + return new Promise$1(function (resolve, reject) { + + if (dbInfo.db) { + if (upgradeNeeded) { + _deferReadiness(dbInfo); + dbInfo.db.close(); + } else { + return resolve(dbInfo.db); + } + } + + var dbArgs = [dbInfo.name]; + + if (upgradeNeeded) { + dbArgs.push(dbInfo.version); + } + + var openreq = idb.open.apply(idb, dbArgs); + + if (upgradeNeeded) { + openreq.onupgradeneeded = function (e) { + var db = openreq.result; + try { + db.createObjectStore(dbInfo.storeName); + if (e.oldVersion <= 1) { + // Added when support for blob shims was added + db.createObjectStore(DETECT_BLOB_SUPPORT_STORE); + } + } catch (ex) { + if (ex.name === 'ConstraintError') { + console.warn('The database "' + dbInfo.name + '"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage "' + dbInfo.storeName + '" already exists.'); + } else { + throw ex; + } + } + }; + } + + openreq.onerror = function (e) { + e.preventDefault(); + reject(openreq.error); + }; + + openreq.onsuccess = function () { + resolve(openreq.result); + _advanceReadiness(dbInfo); + }; + }); +} + +function _getOriginalConnection(dbInfo) { + return _getConnection(dbInfo, false); +} + +function _getUpgradedConnection(dbInfo) { + return _getConnection(dbInfo, true); +} + +function _isUpgradeNeeded(dbInfo, defaultVersion) { + if (!dbInfo.db) { + return true; + } + + var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName); + var isDowngrade = dbInfo.version < dbInfo.db.version; + var isUpgrade = dbInfo.version > dbInfo.db.version; + + if (isDowngrade) { + // If the version is not the default one + // then warn for impossible downgrade. + if (dbInfo.version !== defaultVersion) { + console.warn('The database "' + dbInfo.name + '"' + ' can\'t be downgraded from version ' + dbInfo.db.version + ' to version ' + dbInfo.version + '.'); + } + // Align the versions to prevent errors. + dbInfo.version = dbInfo.db.version; + } + + if (isUpgrade || isNewStore) { + // If the store is new then increment the version (if needed). + // This will trigger an "upgradeneeded" event which is required + // for creating a store. + if (isNewStore) { + var incVersion = dbInfo.db.version + 1; + if (incVersion > dbInfo.version) { + dbInfo.version = incVersion; + } + } + + return true; + } + + return false; +} + +// encode a blob for indexeddb engines that don't support blobs +function _encodeBlob(blob) { + return new Promise$1(function (resolve, reject) { + var reader = new FileReader(); + reader.onerror = reject; + reader.onloadend = function (e) { + var base64 = btoa(e.target.result || ''); + resolve({ + __local_forage_encoded_blob: true, + data: base64, + type: blob.type + }); + }; + reader.readAsBinaryString(blob); + }); +} + +// decode an encoded blob +function _decodeBlob(encodedBlob) { + var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data)); + return createBlob([arrayBuff], { type: encodedBlob.type }); +} + +// is this one of our fancy encoded blobs? +function _isEncodedBlob(value) { + return value && value.__local_forage_encoded_blob; +} + +// Specialize the default `ready()` function by making it dependent +// on the current database operations. Thus, the driver will be actually +// ready when it's been initialized (default) *and* there are no pending +// operations on the database (initiated by some other instances). +function _fullyReady(callback) { + var self = this; + + var promise = self._initReady().then(function () { + var dbContext = dbContexts[self._dbInfo.name]; + + if (dbContext && dbContext.dbReady) { + return dbContext.dbReady; + } + }); + + executeTwoCallbacks(promise, callback, callback); + return promise; +} + +// Open the IndexedDB database (automatically creates one if one didn't +// previously exist), using any options set in the config. +function _initStorage(options) { + var self = this; + var dbInfo = { + db: null + }; + + if (options) { + for (var i in options) { + dbInfo[i] = options[i]; + } + } + + // Initialize a singleton container for all running localForages. + if (!dbContexts) { + dbContexts = {}; + } + + // Get the current context of the database; + var dbContext = dbContexts[dbInfo.name]; + + // ...or create a new context. + if (!dbContext) { + dbContext = { + // Running localForages sharing a database. + forages: [], + // Shared database. + db: null, + // Database readiness (promise). + dbReady: null, + // Deferred operations on the database. + deferredOperations: [] + }; + // Register the new context in the global container. + dbContexts[dbInfo.name] = dbContext; + } + + // Register itself as a running localForage in the current context. + dbContext.forages.push(self); + + // Replace the default `ready()` function with the specialized one. + if (!self._initReady) { + self._initReady = self.ready; + self.ready = _fullyReady; + } + + // Create an array of initialization states of the related localForages. + var initPromises = []; + + function ignoreErrors() { + // Don't handle errors here, + // just makes sure related localForages aren't pending. + return Promise$1.resolve(); + } + + for (var j = 0; j < dbContext.forages.length; j++) { + var forage = dbContext.forages[j]; + if (forage !== self) { + // Don't wait for itself... + initPromises.push(forage._initReady()["catch"](ignoreErrors)); + } + } + + // Take a snapshot of the related localForages. + var forages = dbContext.forages.slice(0); + + // Initialize the connection process only when + // all the related localForages aren't pending. + return Promise$1.all(initPromises).then(function () { + dbInfo.db = dbContext.db; + // Get the connection or open a new one without upgrade. + return _getOriginalConnection(dbInfo); + }).then(function (db) { + dbInfo.db = db; + if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) { + // Reopen the database for upgrading. + return _getUpgradedConnection(dbInfo); + } + return db; + }).then(function (db) { + dbInfo.db = dbContext.db = db; + self._dbInfo = dbInfo; + // Share the final connection amongst related localForages. + for (var k = 0; k < forages.length; k++) { + var forage = forages[k]; + if (forage !== self) { + // Self is already up-to-date. + forage._dbInfo.db = dbInfo.db; + forage._dbInfo.version = dbInfo.version; + } + } + }); +} + +function getItem(key, callback) { + var self = this; + + // Cast the key to a string, as that's all we can set as a key. + if (typeof key !== 'string') { + console.warn(key + ' used as a key, but it is not a string.'); + key = String(key); + } + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName); + var req = store.get(key); + + req.onsuccess = function () { + var value = req.result; + if (value === undefined) { + value = null; + } + if (_isEncodedBlob(value)) { + value = _decodeBlob(value); + } + resolve(value); + }; + + req.onerror = function () { + reject(req.error); + }; + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +// Iterate over all items stored in database. +function iterate(iterator, callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName); + + var req = store.openCursor(); + var iterationNumber = 1; + + req.onsuccess = function () { + var cursor = req.result; + + if (cursor) { + var value = cursor.value; + if (_isEncodedBlob(value)) { + value = _decodeBlob(value); + } + var result = iterator(value, cursor.key, iterationNumber++); + + if (result !== void 0) { + resolve(result); + } else { + cursor["continue"](); + } + } else { + resolve(); + } + }; + + req.onerror = function () { + reject(req.error); + }; + })["catch"](reject); + }); + + executeCallback(promise, callback); + + return promise; +} + +function setItem(key, value, callback) { + var self = this; + + // Cast the key to a string, as that's all we can set as a key. + if (typeof key !== 'string') { + console.warn(key + ' used as a key, but it is not a string.'); + key = String(key); + } + + var promise = new Promise$1(function (resolve, reject) { + var dbInfo; + self.ready().then(function () { + dbInfo = self._dbInfo; + if (toString.call(value) === '[object Blob]') { + return _checkBlobSupport(dbInfo.db).then(function (blobSupport) { + if (blobSupport) { + return value; + } + return _encodeBlob(value); + }); + } + return value; + }).then(function (value) { + var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite'); + var store = transaction.objectStore(dbInfo.storeName); + var req = store.put(value, key); + + // The reason we don't _save_ null is because IE 10 does + // not support saving the `null` type in IndexedDB. How + // ironic, given the bug below! + // See: https://github.com/mozilla/localForage/issues/161 + if (value === null) { + value = undefined; + } + + transaction.oncomplete = function () { + // Cast to undefined so the value passed to + // callback/promise is the same as what one would get out + // of `getItem()` later. This leads to some weirdness + // (setItem('foo', undefined) will return `null`), but + // it's not my fault localStorage is our baseline and that + // it's weird. + if (value === undefined) { + value = null; + } + + resolve(value); + }; + transaction.onabort = transaction.onerror = function () { + var err = req.error ? req.error : req.transaction.error; + reject(err); + }; + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function removeItem(key, callback) { + var self = this; + + // Cast the key to a string, as that's all we can set as a key. + if (typeof key !== 'string') { + console.warn(key + ' used as a key, but it is not a string.'); + key = String(key); + } + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite'); + var store = transaction.objectStore(dbInfo.storeName); + + // We use a Grunt task to make this safe for IE and some + // versions of Android (including those used by Cordova). + // Normally IE won't like `.delete()` and will insist on + // using `['delete']()`, but we have a build step that + // fixes this for us now. + var req = store["delete"](key); + transaction.oncomplete = function () { + resolve(); + }; + + transaction.onerror = function () { + reject(req.error); + }; + + // The request will be also be aborted if we've exceeded our storage + // space. + transaction.onabort = function () { + var err = req.error ? req.error : req.transaction.error; + reject(err); + }; + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function clear(callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite'); + var store = transaction.objectStore(dbInfo.storeName); + var req = store.clear(); + + transaction.oncomplete = function () { + resolve(); + }; + + transaction.onabort = transaction.onerror = function () { + var err = req.error ? req.error : req.transaction.error; + reject(err); + }; + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function length(callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName); + var req = store.count(); + + req.onsuccess = function () { + resolve(req.result); + }; + + req.onerror = function () { + reject(req.error); + }; + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function key(n, callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + if (n < 0) { + resolve(null); + + return; + } + + self.ready().then(function () { + var dbInfo = self._dbInfo; + var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName); + + var advanced = false; + var req = store.openCursor(); + req.onsuccess = function () { + var cursor = req.result; + if (!cursor) { + // this means there weren't enough keys + resolve(null); + + return; + } + + if (n === 0) { + // We have the first key, return it if that's what they + // wanted. + resolve(cursor.key); + } else { + if (!advanced) { + // Otherwise, ask the cursor to skip ahead n + // records. + advanced = true; + cursor.advance(n); + } else { + // When we get here, we've got the nth key. + resolve(cursor.key); + } + } + }; + + req.onerror = function () { + reject(req.error); + }; + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function keys(callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName); + + var req = store.openCursor(); + var keys = []; + + req.onsuccess = function () { + var cursor = req.result; + + if (!cursor) { + resolve(keys); + return; + } + + keys.push(cursor.key); + cursor["continue"](); + }; + + req.onerror = function () { + reject(req.error); + }; + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +var asyncStorage = { + _driver: 'asyncStorage', + _initStorage: _initStorage, + iterate: iterate, + getItem: getItem, + setItem: setItem, + removeItem: removeItem, + clear: clear, + length: length, + key: key, + keys: keys +}; + +// Sadly, the best way to save binary data in WebSQL/localStorage is serializing +// it to Base64, so this is how we store it to prevent very strange errors with less +// verbose ways of binary <-> string data storage. +var BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +var BLOB_TYPE_PREFIX = '~~local_forage_type~'; +var BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/; + +var SERIALIZED_MARKER = '__lfsc__:'; +var SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length; + +// OMG the serializations! +var TYPE_ARRAYBUFFER = 'arbf'; +var TYPE_BLOB = 'blob'; +var TYPE_INT8ARRAY = 'si08'; +var TYPE_UINT8ARRAY = 'ui08'; +var TYPE_UINT8CLAMPEDARRAY = 'uic8'; +var TYPE_INT16ARRAY = 'si16'; +var TYPE_INT32ARRAY = 'si32'; +var TYPE_UINT16ARRAY = 'ur16'; +var TYPE_UINT32ARRAY = 'ui32'; +var TYPE_FLOAT32ARRAY = 'fl32'; +var TYPE_FLOAT64ARRAY = 'fl64'; +var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length; + +var toString$1 = Object.prototype.toString; + +function stringToBuffer(serializedString) { + // Fill the string into a ArrayBuffer. + var bufferLength = serializedString.length * 0.75; + var len = serializedString.length; + var i; + var p = 0; + var encoded1, encoded2, encoded3, encoded4; + + if (serializedString[serializedString.length - 1] === '=') { + bufferLength--; + if (serializedString[serializedString.length - 2] === '=') { + bufferLength--; + } + } + + var buffer = new ArrayBuffer(bufferLength); + var bytes = new Uint8Array(buffer); + + for (i = 0; i < len; i += 4) { + encoded1 = BASE_CHARS.indexOf(serializedString[i]); + encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]); + encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]); + encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]); + + /*jslint bitwise: true */ + bytes[p++] = encoded1 << 2 | encoded2 >> 4; + bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2; + bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63; + } + return buffer; +} + +// Converts a buffer to a string to store, serialized, in the backend +// storage library. +function bufferToString(buffer) { + // base64-arraybuffer + var bytes = new Uint8Array(buffer); + var base64String = ''; + var i; + + for (i = 0; i < bytes.length; i += 3) { + /*jslint bitwise: true */ + base64String += BASE_CHARS[bytes[i] >> 2]; + base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4]; + base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6]; + base64String += BASE_CHARS[bytes[i + 2] & 63]; + } + + if (bytes.length % 3 === 2) { + base64String = base64String.substring(0, base64String.length - 1) + '='; + } else if (bytes.length % 3 === 1) { + base64String = base64String.substring(0, base64String.length - 2) + '=='; + } + + return base64String; +} + +// Serialize a value, afterwards executing a callback (which usually +// instructs the `setItem()` callback/promise to be executed). This is how +// we store binary data with localStorage. +function serialize(value, callback) { + var valueType = ''; + if (value) { + valueType = toString$1.call(value); + } + + // Cannot use `value instanceof ArrayBuffer` or such here, as these + // checks fail when running the tests using casper.js... + // + // TODO: See why those tests fail and use a better solution. + if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) { + // Convert binary arrays to a string and prefix the string with + // a special marker. + var buffer; + var marker = SERIALIZED_MARKER; + + if (value instanceof ArrayBuffer) { + buffer = value; + marker += TYPE_ARRAYBUFFER; + } else { + buffer = value.buffer; + + if (valueType === '[object Int8Array]') { + marker += TYPE_INT8ARRAY; + } else if (valueType === '[object Uint8Array]') { + marker += TYPE_UINT8ARRAY; + } else if (valueType === '[object Uint8ClampedArray]') { + marker += TYPE_UINT8CLAMPEDARRAY; + } else if (valueType === '[object Int16Array]') { + marker += TYPE_INT16ARRAY; + } else if (valueType === '[object Uint16Array]') { + marker += TYPE_UINT16ARRAY; + } else if (valueType === '[object Int32Array]') { + marker += TYPE_INT32ARRAY; + } else if (valueType === '[object Uint32Array]') { + marker += TYPE_UINT32ARRAY; + } else if (valueType === '[object Float32Array]') { + marker += TYPE_FLOAT32ARRAY; + } else if (valueType === '[object Float64Array]') { + marker += TYPE_FLOAT64ARRAY; + } else { + callback(new Error('Failed to get type for BinaryArray')); + } + } + + callback(marker + bufferToString(buffer)); + } else if (valueType === '[object Blob]') { + // Conver the blob to a binaryArray and then to a string. + var fileReader = new FileReader(); + + fileReader.onload = function () { + // Backwards-compatible prefix for the blob type. + var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result); + + callback(SERIALIZED_MARKER + TYPE_BLOB + str); + }; + + fileReader.readAsArrayBuffer(value); + } else { + try { + callback(JSON.stringify(value)); + } catch (e) { + console.error("Couldn't convert value into a JSON string: ", value); + + callback(null, e); + } + } +} + +// Deserialize data we've inserted into a value column/field. We place +// special markers into our strings to mark them as encoded; this isn't +// as nice as a meta field, but it's the only sane thing we can do whilst +// keeping localStorage support intact. +// +// Oftentimes this will just deserialize JSON content, but if we have a +// special marker (SERIALIZED_MARKER, defined above), we will extract +// some kind of arraybuffer/binary data/typed array out of the string. +function deserialize(value) { + // If we haven't marked this string as being specially serialized (i.e. + // something other than serialized JSON), we can just return it and be + // done with it. + if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) { + return JSON.parse(value); + } + + // The following code deals with deserializing some kind of Blob or + // TypedArray. First we separate out the type of data we're dealing + // with from the data itself. + var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH); + var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH); + + var blobType; + // Backwards-compatible blob type serialization strategy. + // DBs created with older versions of localForage will simply not have the blob type. + if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) { + var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX); + blobType = matcher[1]; + serializedString = serializedString.substring(matcher[0].length); + } + var buffer = stringToBuffer(serializedString); + + // Return the right type based on the code/type set during + // serialization. + switch (type) { + case TYPE_ARRAYBUFFER: + return buffer; + case TYPE_BLOB: + return createBlob([buffer], { type: blobType }); + case TYPE_INT8ARRAY: + return new Int8Array(buffer); + case TYPE_UINT8ARRAY: + return new Uint8Array(buffer); + case TYPE_UINT8CLAMPEDARRAY: + return new Uint8ClampedArray(buffer); + case TYPE_INT16ARRAY: + return new Int16Array(buffer); + case TYPE_UINT16ARRAY: + return new Uint16Array(buffer); + case TYPE_INT32ARRAY: + return new Int32Array(buffer); + case TYPE_UINT32ARRAY: + return new Uint32Array(buffer); + case TYPE_FLOAT32ARRAY: + return new Float32Array(buffer); + case TYPE_FLOAT64ARRAY: + return new Float64Array(buffer); + default: + throw new Error('Unkown type: ' + type); + } +} + +var localforageSerializer = { + serialize: serialize, + deserialize: deserialize, + stringToBuffer: stringToBuffer, + bufferToString: bufferToString +}; + +/* + * Includes code from: + * + * base64-arraybuffer + * https://github.com/niklasvh/base64-arraybuffer + * + * Copyright (c) 2012 Niklas von Hertzen + * Licensed under the MIT license. + */ +// Open the WebSQL database (automatically creates one if one didn't +// previously exist), using any options set in the config. +function _initStorage$1(options) { + var self = this; + var dbInfo = { + db: null + }; + + if (options) { + for (var i in options) { + dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i]; + } + } + + var dbInfoPromise = new Promise$1(function (resolve, reject) { + // Open the database; the openDatabase API will automatically + // create it for us if it doesn't exist. + try { + dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size); + } catch (e) { + return reject(e); + } + + // Create our key/value table if it doesn't exist. + dbInfo.db.transaction(function (t) { + t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' (id INTEGER PRIMARY KEY, key unique, value)', [], function () { + self._dbInfo = dbInfo; + resolve(); + }, function (t, error) { + reject(error); + }); + }); + }); + + dbInfo.serializer = localforageSerializer; + return dbInfoPromise; +} + +function getItem$1(key, callback) { + var self = this; + + // Cast the key to a string, as that's all we can set as a key. + if (typeof key !== 'string') { + console.warn(key + ' used as a key, but it is not a string.'); + key = String(key); + } + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + dbInfo.db.transaction(function (t) { + t.executeSql('SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) { + var result = results.rows.length ? results.rows.item(0).value : null; + + // Check to see if this is serialized content we need to + // unpack. + if (result) { + result = dbInfo.serializer.deserialize(result); + } + + resolve(result); + }, function (t, error) { + + reject(error); + }); + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function iterate$1(iterator, callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + + dbInfo.db.transaction(function (t) { + t.executeSql('SELECT * FROM ' + dbInfo.storeName, [], function (t, results) { + var rows = results.rows; + var length = rows.length; + + for (var i = 0; i < length; i++) { + var item = rows.item(i); + var result = item.value; + + // Check to see if this is serialized content + // we need to unpack. + if (result) { + result = dbInfo.serializer.deserialize(result); + } + + result = iterator(result, item.key, i + 1); + + // void(0) prevents problems with redefinition + // of `undefined`. + if (result !== void 0) { + resolve(result); + return; + } + } + + resolve(); + }, function (t, error) { + reject(error); + }); + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function _setItem(key, value, callback, retriesLeft) { + var self = this; + + // Cast the key to a string, as that's all we can set as a key. + if (typeof key !== 'string') { + console.warn(key + ' used as a key, but it is not a string.'); + key = String(key); + } + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + // The localStorage API doesn't return undefined values in an + // "expected" way, so undefined is always cast to null in all + // drivers. See: https://github.com/mozilla/localForage/pull/42 + if (value === undefined) { + value = null; + } + + // Save the original value to pass to the callback. + var originalValue = value; + + var dbInfo = self._dbInfo; + dbInfo.serializer.serialize(value, function (value, error) { + if (error) { + reject(error); + } else { + dbInfo.db.transaction(function (t) { + t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + ' (key, value) VALUES (?, ?)', [key, value], function () { + resolve(originalValue); + }, function (t, error) { + reject(error); + }); + }, function (sqlError) { + // The transaction failed; check + // to see if it's a quota error. + if (sqlError.code === sqlError.QUOTA_ERR) { + // We reject the callback outright for now, but + // it's worth trying to re-run the transaction. + // Even if the user accepts the prompt to use + // more storage on Safari, this error will + // be called. + // + // Try to re-run the transaction. + if (retriesLeft > 0) { + resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1])); + return; + } + reject(sqlError); + } + }); + } + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function setItem$1(key, value, callback) { + return _setItem.apply(this, [key, value, callback, 1]); +} + +function removeItem$1(key, callback) { + var self = this; + + // Cast the key to a string, as that's all we can set as a key. + if (typeof key !== 'string') { + console.warn(key + ' used as a key, but it is not a string.'); + key = String(key); + } + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + dbInfo.db.transaction(function (t) { + t.executeSql('DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () { + resolve(); + }, function (t, error) { + + reject(error); + }); + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +// Deletes every item in the table. +// TODO: Find out if this resets the AUTO_INCREMENT number. +function clear$1(callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + dbInfo.db.transaction(function (t) { + t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function () { + resolve(); + }, function (t, error) { + reject(error); + }); + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +// Does a simple `COUNT(key)` to get the number of items stored in +// localForage. +function length$1(callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + dbInfo.db.transaction(function (t) { + // Ahhh, SQL makes this one soooooo easy. + t.executeSql('SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) { + var result = results.rows.item(0).c; + + resolve(result); + }, function (t, error) { + + reject(error); + }); + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +// Return the key located at key index X; essentially gets the key from a +// `WHERE id = ?`. This is the most efficient way I can think to implement +// this rarely-used (in my experience) part of the API, but it can seem +// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so +// the ID of each key will change every time it's updated. Perhaps a stored +// procedure for the `setItem()` SQL would solve this problem? +// TODO: Don't change ID on `setItem()`. +function key$1(n, callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + dbInfo.db.transaction(function (t) { + t.executeSql('SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) { + var result = results.rows.length ? results.rows.item(0).key : null; + resolve(result); + }, function (t, error) { + reject(error); + }); + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +function keys$1(callback) { + var self = this; + + var promise = new Promise$1(function (resolve, reject) { + self.ready().then(function () { + var dbInfo = self._dbInfo; + dbInfo.db.transaction(function (t) { + t.executeSql('SELECT key FROM ' + dbInfo.storeName, [], function (t, results) { + var keys = []; + + for (var i = 0; i < results.rows.length; i++) { + keys.push(results.rows.item(i).key); + } + + resolve(keys); + }, function (t, error) { + + reject(error); + }); + }); + })["catch"](reject); + }); + + executeCallback(promise, callback); + return promise; +} + +var webSQLStorage = { + _driver: 'webSQLStorage', + _initStorage: _initStorage$1, + iterate: iterate$1, + getItem: getItem$1, + setItem: setItem$1, + removeItem: removeItem$1, + clear: clear$1, + length: length$1, + key: key$1, + keys: keys$1 +}; + +// Config the localStorage backend, using options set in the config. +function _initStorage$2(options) { + var self = this; + var dbInfo = {}; + if (options) { + for (var i in options) { + dbInfo[i] = options[i]; + } + } + + dbInfo.keyPrefix = dbInfo.name + '/'; + + if (dbInfo.storeName !== self._defaultConfig.storeName) { + dbInfo.keyPrefix += dbInfo.storeName + '/'; + } + + self._dbInfo = dbInfo; + dbInfo.serializer = localforageSerializer; + + return Promise$1.resolve(); +} + +// Remove all keys from the datastore, effectively destroying all data in +// the app's key/value store! +function clear$2(callback) { + var self = this; + var promise = self.ready().then(function () { + var keyPrefix = self._dbInfo.keyPrefix; + + for (var i = localStorage.length - 1; i >= 0; i--) { + var key = localStorage.key(i); + + if (key.indexOf(keyPrefix) === 0) { + localStorage.removeItem(key); + } + } + }); + + executeCallback(promise, callback); + return promise; +} + +// Retrieve an item from the store. Unlike the original async_storage +// library in Gaia, we don't modify return values at all. If a key's value +// is `undefined`, we pass that value to the callback function. +function getItem$2(key, callback) { + var self = this; + + // Cast the key to a string, as that's all we can set as a key. + if (typeof key !== 'string') { + console.warn(key + ' used as a key, but it is not a string.'); + key = String(key); + } + + var promise = self.ready().then(function () { + var dbInfo = self._dbInfo; + var result = localStorage.getItem(dbInfo.keyPrefix + key); + + // If a result was found, parse it from the serialized + // string into a JS object. If result isn't truthy, the key + // is likely undefined and we'll pass it straight to the + // callback. + if (result) { + result = dbInfo.serializer.deserialize(result); + } + + return result; + }); + + executeCallback(promise, callback); + return promise; +} + +// Iterate over all items in the store. +function iterate$2(iterator, callback) { + var self = this; + + var promise = self.ready().then(function () { + var dbInfo = self._dbInfo; + var keyPrefix = dbInfo.keyPrefix; + var keyPrefixLength = keyPrefix.length; + var length = localStorage.length; + + // We use a dedicated iterator instead of the `i` variable below + // so other keys we fetch in localStorage aren't counted in + // the `iterationNumber` argument passed to the `iterate()` + // callback. + // + // See: github.com/mozilla/localForage/pull/435#discussion_r38061530 + var iterationNumber = 1; + + for (var i = 0; i < length; i++) { + var key = localStorage.key(i); + if (key.indexOf(keyPrefix) !== 0) { + continue; + } + var value = localStorage.getItem(key); + + // If a result was found, parse it from the serialized + // string into a JS object. If result isn't truthy, the + // key is likely undefined and we'll pass it straight + // to the iterator. + if (value) { + value = dbInfo.serializer.deserialize(value); + } + + value = iterator(value, key.substring(keyPrefixLength), iterationNumber++); + + if (value !== void 0) { + return value; + } + } + }); + + executeCallback(promise, callback); + return promise; +} + +// Same as localStorage's key() method, except takes a callback. +function key$2(n, callback) { + var self = this; + var promise = self.ready().then(function () { + var dbInfo = self._dbInfo; + var result; + try { + result = localStorage.key(n); + } catch (error) { + result = null; + } + + // Remove the prefix from the key, if a key is found. + if (result) { + result = result.substring(dbInfo.keyPrefix.length); + } + + return result; + }); + + executeCallback(promise, callback); + return promise; +} + +function keys$2(callback) { + var self = this; + var promise = self.ready().then(function () { + var dbInfo = self._dbInfo; + var length = localStorage.length; + var keys = []; + + for (var i = 0; i < length; i++) { + if (localStorage.key(i).indexOf(dbInfo.keyPrefix) === 0) { + keys.push(localStorage.key(i).substring(dbInfo.keyPrefix.length)); + } + } + + return keys; + }); + + executeCallback(promise, callback); + return promise; +} + +// Supply the number of keys in the datastore to the callback function. +function length$2(callback) { + var self = this; + var promise = self.keys().then(function (keys) { + return keys.length; + }); + + executeCallback(promise, callback); + return promise; +} + +// Remove an item from the store, nice and simple. +function removeItem$2(key, callback) { + var self = this; + + // Cast the key to a string, as that's all we can set as a key. + if (typeof key !== 'string') { + console.warn(key + ' used as a key, but it is not a string.'); + key = String(key); + } + + var promise = self.ready().then(function () { + var dbInfo = self._dbInfo; + localStorage.removeItem(dbInfo.keyPrefix + key); + }); + + executeCallback(promise, callback); + return promise; +} + +// Set a key's value and run an optional callback once the value is set. +// Unlike Gaia's implementation, the callback function is passed the value, +// in case you want to operate on that value only after you're sure it +// saved, or something like that. +function setItem$2(key, value, callback) { + var self = this; + + // Cast the key to a string, as that's all we can set as a key. + if (typeof key !== 'string') { + console.warn(key + ' used as a key, but it is not a string.'); + key = String(key); + } + + var promise = self.ready().then(function () { + // Convert undefined values to null. + // https://github.com/mozilla/localForage/pull/42 + if (value === undefined) { + value = null; + } + + // Save the original value to pass to the callback. + var originalValue = value; + + return new Promise$1(function (resolve, reject) { + var dbInfo = self._dbInfo; + dbInfo.serializer.serialize(value, function (value, error) { + if (error) { + reject(error); + } else { + try { + localStorage.setItem(dbInfo.keyPrefix + key, value); + resolve(originalValue); + } catch (e) { + // localStorage capacity exceeded. + // TODO: Make this a specific error/event. + if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') { + reject(e); + } + reject(e); + } + } + }); + }); + }); + + executeCallback(promise, callback); + return promise; +} + +var localStorageWrapper = { + _driver: 'localStorageWrapper', + _initStorage: _initStorage$2, + // Default API, from Gaia/localStorage. + iterate: iterate$2, + getItem: getItem$2, + setItem: setItem$2, + removeItem: removeItem$2, + clear: clear$2, + length: length$2, + key: key$2, + keys: keys$2 +}; + +// Custom drivers are stored here when `defineDriver()` is called. +// They are shared across all instances of localForage. +var CustomDrivers = {}; + +var DriverType = { + INDEXEDDB: 'asyncStorage', + LOCALSTORAGE: 'localStorageWrapper', + WEBSQL: 'webSQLStorage' +}; + +var DefaultDriverOrder = [DriverType.INDEXEDDB, DriverType.WEBSQL, DriverType.LOCALSTORAGE]; + +var LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem']; + +var DefaultConfig = { + description: '', + driver: DefaultDriverOrder.slice(), + name: 'localforage', + // Default DB size is _JUST UNDER_ 5MB, as it's the highest size + // we can use without a prompt. + size: 4980736, + storeName: 'keyvaluepairs', + version: 1.0 +}; + +var driverSupport = {}; +// Check to see if IndexedDB is available and if it is the latest +// implementation; it's our preferred backend library. We use "_spec_test" +// as the name of the database because it's not the one we'll operate on, +// but it's useful to make sure its using the right spec. +// See: https://github.com/mozilla/localForage/issues/128 +driverSupport[DriverType.INDEXEDDB] = isIndexedDBValid(); + +driverSupport[DriverType.WEBSQL] = isWebSQLValid(); + +driverSupport[DriverType.LOCALSTORAGE] = isLocalStorageValid(); + +var isArray = Array.isArray || function (arg) { + return Object.prototype.toString.call(arg) === '[object Array]'; +}; + +function callWhenReady(localForageInstance, libraryMethod) { + localForageInstance[libraryMethod] = function () { + var _args = arguments; + return localForageInstance.ready().then(function () { + return localForageInstance[libraryMethod].apply(localForageInstance, _args); + }); + }; +} + +function extend() { + for (var i = 1; i < arguments.length; i++) { + var arg = arguments[i]; + + if (arg) { + for (var key in arg) { + if (arg.hasOwnProperty(key)) { + if (isArray(arg[key])) { + arguments[0][key] = arg[key].slice(); + } else { + arguments[0][key] = arg[key]; + } + } + } + } + } + + return arguments[0]; +} + +function isLibraryDriver(driverName) { + for (var driver in DriverType) { + if (DriverType.hasOwnProperty(driver) && DriverType[driver] === driverName) { + return true; + } + } + + return false; +} + +var LocalForage = function () { + function LocalForage(options) { + _classCallCheck(this, LocalForage); + + this.INDEXEDDB = DriverType.INDEXEDDB; + this.LOCALSTORAGE = DriverType.LOCALSTORAGE; + this.WEBSQL = DriverType.WEBSQL; + + this._defaultConfig = extend({}, DefaultConfig); + this._config = extend({}, this._defaultConfig, options); + this._driverSet = null; + this._initDriver = null; + this._ready = false; + this._dbInfo = null; + + this._wrapLibraryMethodsWithReady(); + this.setDriver(this._config.driver)["catch"](function () {}); + } + + // Set any config values for localForage; can be called anytime before + // the first API call (e.g. `getItem`, `setItem`). + // We loop through options so we don't overwrite existing config + // values. + + + LocalForage.prototype.config = function config(options) { + // If the options argument is an object, we use it to set values. + // Otherwise, we return either a specified config value or all + // config values. + if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') { + // If localforage is ready and fully initialized, we can't set + // any new configuration values. Instead, we return an error. + if (this._ready) { + return new Error("Can't call config() after localforage " + 'has been used.'); + } + + for (var i in options) { + if (i === 'storeName') { + options[i] = options[i].replace(/\W/g, '_'); + } + + if (i === 'version' && typeof options[i] !== 'number') { + return new Error('Database version must be a number.'); + } + + this._config[i] = options[i]; + } + + // after all config options are set and + // the driver option is used, try setting it + if ('driver' in options && options.driver) { + return this.setDriver(this._config.driver); + } + + return true; + } else if (typeof options === 'string') { + return this._config[options]; + } else { + return this._config; + } + }; + + // Used to define a custom driver, shared across all instances of + // localForage. + + + LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) { + var promise = new Promise$1(function (resolve, reject) { + try { + var driverName = driverObject._driver; + var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver'); + var namingError = new Error('Custom driver name already in use: ' + driverObject._driver); + + // A driver name should be defined and not overlap with the + // library-defined, default drivers. + if (!driverObject._driver) { + reject(complianceError); + return; + } + if (isLibraryDriver(driverObject._driver)) { + reject(namingError); + return; + } + + var customDriverMethods = LibraryMethods.concat('_initStorage'); + for (var i = 0; i < customDriverMethods.length; i++) { + var customDriverMethod = customDriverMethods[i]; + if (!customDriverMethod || !driverObject[customDriverMethod] || typeof driverObject[customDriverMethod] !== 'function') { + reject(complianceError); + return; + } + } + + var supportPromise = Promise$1.resolve(true); + if ('_support' in driverObject) { + if (driverObject._support && typeof driverObject._support === 'function') { + supportPromise = driverObject._support(); + } else { + supportPromise = Promise$1.resolve(!!driverObject._support); + } + } + + supportPromise.then(function (supportResult) { + driverSupport[driverName] = supportResult; + CustomDrivers[driverName] = driverObject; + resolve(); + }, reject); + } catch (e) { + reject(e); + } + }); + + executeTwoCallbacks(promise, callback, errorCallback); + return promise; + }; + + LocalForage.prototype.driver = function driver() { + return this._driver || null; + }; + + LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) { + var self = this; + var getDriverPromise = Promise$1.resolve().then(function () { + if (isLibraryDriver(driverName)) { + switch (driverName) { + case self.INDEXEDDB: + return asyncStorage; + case self.LOCALSTORAGE: + return localStorageWrapper; + case self.WEBSQL: + return webSQLStorage; + } + } else if (CustomDrivers[driverName]) { + return CustomDrivers[driverName]; + } else { + throw new Error('Driver not found.'); + } + }); + executeTwoCallbacks(getDriverPromise, callback, errorCallback); + return getDriverPromise; + }; + + LocalForage.prototype.getSerializer = function getSerializer(callback) { + var serializerPromise = Promise$1.resolve(localforageSerializer); + executeTwoCallbacks(serializerPromise, callback); + return serializerPromise; + }; + + LocalForage.prototype.ready = function ready(callback) { + var self = this; + + var promise = self._driverSet.then(function () { + if (self._ready === null) { + self._ready = self._initDriver(); + } + + return self._ready; + }); + + executeTwoCallbacks(promise, callback, callback); + return promise; + }; + + LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) { + var self = this; + + if (!isArray(drivers)) { + drivers = [drivers]; + } + + var supportedDrivers = this._getSupportedDrivers(drivers); + + function setDriverToConfig() { + self._config.driver = self.driver(); + } + + function extendSelfWithDriver(driver) { + self._extend(driver); + setDriverToConfig(); + + self._ready = self._initStorage(self._config); + return self._ready; + } + + function initDriver(supportedDrivers) { + return function () { + var currentDriverIndex = 0; + + function driverPromiseLoop() { + while (currentDriverIndex < supportedDrivers.length) { + var driverName = supportedDrivers[currentDriverIndex]; + currentDriverIndex++; + + self._dbInfo = null; + self._ready = null; + + return self.getDriver(driverName).then(extendSelfWithDriver)["catch"](driverPromiseLoop); + } + + setDriverToConfig(); + var error = new Error('No available storage method found.'); + self._driverSet = Promise$1.reject(error); + return self._driverSet; + } + + return driverPromiseLoop(); + }; + } + + // There might be a driver initialization in progress + // so wait for it to finish in order to avoid a possible + // race condition to set _dbInfo + var oldDriverSetDone = this._driverSet !== null ? this._driverSet["catch"](function () { + return Promise$1.resolve(); + }) : Promise$1.resolve(); + + this._driverSet = oldDriverSetDone.then(function () { + var driverName = supportedDrivers[0]; + self._dbInfo = null; + self._ready = null; + + return self.getDriver(driverName).then(function (driver) { + self._driver = driver._driver; + setDriverToConfig(); + self._wrapLibraryMethodsWithReady(); + self._initDriver = initDriver(supportedDrivers); + }); + })["catch"](function () { + setDriverToConfig(); + var error = new Error('No available storage method found.'); + self._driverSet = Promise$1.reject(error); + return self._driverSet; + }); + + executeTwoCallbacks(this._driverSet, callback, errorCallback); + return this._driverSet; + }; + + LocalForage.prototype.supports = function supports(driverName) { + return !!driverSupport[driverName]; + }; + + LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) { + extend(this, libraryMethodsAndProperties); + }; + + LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) { + var supportedDrivers = []; + for (var i = 0, len = drivers.length; i < len; i++) { + var driverName = drivers[i]; + if (this.supports(driverName)) { + supportedDrivers.push(driverName); + } + } + return supportedDrivers; + }; + + LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() { + // Add a stub for each driver API method that delays the call to the + // corresponding driver method until localForage is ready. These stubs + // will be replaced by the driver methods as soon as the driver is + // loaded, so there is no performance impact. + for (var i = 0; i < LibraryMethods.length; i++) { + callWhenReady(this, LibraryMethods[i]); + } + }; + + LocalForage.prototype.createInstance = function createInstance(options) { + return new LocalForage(options); + }; + + return LocalForage; +}(); + +// The actual localForage object that we expose as a module or via a +// global. It's extended by pulling in one of our other libraries. + + +var localforage_js = new LocalForage(); + +module.exports = localforage_js; + +},{"3":3}]},{},[4])(4) +}); +}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],38:[function(require,module,exports){ +module.exports = require('./lib/type'); + +},{"./lib/type":39}],39:[function(require,module,exports){ +/*! + * type-detect + * Copyright(c) 2013 jake luer + * MIT Licensed + */ + +/*! + * Primary Exports + */ + +var exports = module.exports = getType; + +/*! + * Detectable javascript natives + */ + +var natives = { + '[object Array]': 'array' + , '[object RegExp]': 'regexp' + , '[object Function]': 'function' + , '[object Arguments]': 'arguments' + , '[object Date]': 'date' +}; + +/** + * ### typeOf (obj) + * + * Use several different techniques to determine + * the type of object being tested. + * + * + * @param {Mixed} object + * @return {String} object type + * @api public + */ + +function getType (obj) { + var str = Object.prototype.toString.call(obj); + if (natives[str]) return natives[str]; + if (obj === null) return 'null'; + if (obj === undefined) return 'undefined'; + if (obj === Object(obj)) return 'object'; + return typeof obj; +} + +exports.Library = Library; + +/** + * ### Library + * + * Create a repository for custom type detection. + * + * ```js + * var lib = new type.Library; + * ``` + * + */ + +function Library () { + this.tests = {}; +} + +/** + * #### .of (obj) + * + * Expose replacement `typeof` detection to the library. + * + * ```js + * if ('string' === lib.of('hello world')) { + * // ... + * } + * ``` + * + * @param {Mixed} object to test + * @return {String} type + */ + +Library.prototype.of = getType; + +/** + * #### .define (type, test) + * + * Add a test to for the `.test()` assertion. + * + * Can be defined as a regular expression: + * + * ```js + * lib.define('int', /^[0-9]+$/); + * ``` + * + * ... or as a function: + * + * ```js + * lib.define('bln', function (obj) { + * if ('boolean' === lib.of(obj)) return true; + * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ]; + * if ('string' === lib.of(obj)) obj = obj.toLowerCase(); + * return !! ~blns.indexOf(obj); + * }); + * ``` + * + * @param {String} type + * @param {RegExp|Function} test + * @api public + */ + +Library.prototype.define = function (type, test) { + if (arguments.length === 1) return this.tests[type]; + this.tests[type] = test; + return this; +}; + +/** + * #### .test (obj, test) + * + * Assert that an object is of type. Will first + * check natives, and if that does not pass it will + * use the user defined custom tests. + * + * ```js + * assert(lib.test('1', 'int')); + * assert(lib.test('yes', 'bln')); + * ``` + * + * @param {Mixed} object + * @param {String} type + * @return {Boolean} result + * @api public + */ + +Library.prototype.test = function (obj, type) { + if (type === getType(obj)) return true; + var test = this.tests[type]; + + if (test && 'regexp' === getType(test)) { + return test.test(obj); + } else if (test && 'function' === getType(test)) { + return test(obj); + } else { + throw new ReferenceError('Type test "' + type + '" not defined or invalid.'); + } +}; + +},{}],40:[function(require,module,exports){ +arguments[4][38][0].apply(exports,arguments) +},{"./lib/type":41,"dup":38}],41:[function(require,module,exports){ +/*! + * type-detect + * Copyright(c) 2013 jake luer + * MIT Licensed + */ + +/*! + * Primary Exports + */ + +var exports = module.exports = getType; + +/** + * ### typeOf (obj) + * + * Use several different techniques to determine + * the type of object being tested. + * + * + * @param {Mixed} object + * @return {String} object type + * @api public + */ +var objectTypeRegexp = /^\[object (.*)\]$/; + +function getType(obj) { + var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase(); + // Let "new String('')" return 'object' + if (typeof Promise === 'function' && obj instanceof Promise) return 'promise'; + // PhantomJS has type "DOMWindow" for null + if (obj === null) return 'null'; + // PhantomJS has type "DOMWindow" for undefined + if (obj === undefined) return 'undefined'; + return type; +} + +exports.Library = Library; + +/** + * ### Library + * + * Create a repository for custom type detection. + * + * ```js + * var lib = new type.Library; + * ``` + * + */ + +function Library() { + if (!(this instanceof Library)) return new Library(); + this.tests = {}; +} + +/** + * #### .of (obj) + * + * Expose replacement `typeof` detection to the library. + * + * ```js + * if ('string' === lib.of('hello world')) { + * // ... + * } + * ``` + * + * @param {Mixed} object to test + * @return {String} type + */ + +Library.prototype.of = getType; + +/** + * #### .define (type, test) + * + * Add a test to for the `.test()` assertion. + * + * Can be defined as a regular expression: + * + * ```js + * lib.define('int', /^[0-9]+$/); + * ``` + * + * ... or as a function: + * + * ```js + * lib.define('bln', function (obj) { + * if ('boolean' === lib.of(obj)) return true; + * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ]; + * if ('string' === lib.of(obj)) obj = obj.toLowerCase(); + * return !! ~blns.indexOf(obj); + * }); + * ``` + * + * @param {String} type + * @param {RegExp|Function} test + * @api public + */ + +Library.prototype.define = function(type, test) { + if (arguments.length === 1) return this.tests[type]; + this.tests[type] = test; + return this; +}; + +/** + * #### .test (obj, test) + * + * Assert that an object is of type. Will first + * check natives, and if that does not pass it will + * use the user defined custom tests. + * + * ```js + * assert(lib.test('1', 'int')); + * assert(lib.test('yes', 'bln')); + * ``` + * + * @param {Mixed} object + * @param {String} type + * @return {Boolean} result + * @api public + */ + +Library.prototype.test = function(obj, type) { + if (type === getType(obj)) return true; + var test = this.tests[type]; + + if (test && 'regexp' === getType(test)) { + return test.test(obj); + } else if (test && 'function' === getType(test)) { + return test(obj); + } else { + throw new ReferenceError('Type test "' + type + '" not defined or invalid.'); + } +}; + +},{}],42:[function(require,module,exports){ +'use strict'; + +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +(function (document, window) { + // DEPENDENCIES + // ============================================================ + + var localforage = require('localforage'); + var probs = require('pjs-problems'); + var dedent = require('dedent'); + var assert = require('chai').assert; + + // PROBLEM TEMPLATE NICE-IFICATION + // ============================================================ + + function dedentStrings(problems) { + return problems.map(function (prob) { + prob.given = dedent(prob.given); + prob.answer = dedent(prob.answer); + return prob; + }); + } + + // PROBLEMS + // ============================================================ + + var problems = []; + Object.keys(probs).forEach(function (subject) { + var _problems; + + (_problems = problems).push.apply(_problems, _toConsumableArray(probs[subject])); + }); + problems = dedentStrings(problems); + console.log('problems:', problems); + + // CONFIG + // ============================================================ + + // Hoist current problem + var currentProblem = void 0; + // Keys to ignore while user is navigating around the textarea but not changing any code + var ignoreKeyCodes = [9, // Tab + 37, // Left arrow + 39, // Right arrow + 38, // Up arrow + 40 // Down arrow + ]; + + var config = { + shuffle: true, + timer: false, + currentIndex: 0 + }; + + // Pull config from localforage + localforage.getItem('js_practice_config').then(function (val) { + console.log('localforage val:', val); + if (val) { + config = val; + } + loadApp(config); + }).catch(function (err) { + console.log('localforage err:', err); + loadApp(config); + }); + + function updateLocalstore(config) { + return localforage.setItem('js_practice_config', config).then(function (val) { + console.log('Settings updated:', val); + }).catch(function (err) { + console.log('Settings update error:', err); + }); + } + + // UI + // ============================================================ + + // elements + var problemEl = document.getElementById('problem'); + var codeEl = document.getElementById('code'); + var testSuiteEl = document.getElementById('test-suite'); + var testTotalEl = document.getElementById('test-total'); + var evalConsoleEl = document.getElementById('eval-output'); + var assertConsoleEl = document.getElementById('assert-output'); + var shuffleProblemsButtonEl = document.getElementById('shuffle-problems'); + var previousProblemButtonEl = document.getElementById('prev-problem'); + var nextProblemButtonEl = document.getElementById('next-problem'); + + // Get indexes + function getRandomIndex(problemsArr) { + var ind = Math.floor(Math.random() * problemsArr.length); + config.currentIndex = ind; + updateLocalstore(config); + return ind; + } + + function getPreviousIndex(problemsArr) { + var probInd = void 0; + var currentIndex = config.currentIndex; + // If at beginning, go to end + if (currentIndex === 0) { + probInd = problemsArr.length - 1; + } else { + probInd = currentIndex - 1; + } + return probInd; + } + + function getNextIndex(problemsArr) { + var probInd = void 0; + var currentIndex = config.currentIndex; + // If at end or invalid, restart series + if (currentIndex >= problemsArr.length - 1 || currentIndex < 0) { + probInd = 0; + } else { + probInd = currentIndex + 1; + } + return probInd; + } + + // Get problems + function getCurrentProblem(problemsArr) { + return problemsArr[config.currentIndex]; + } + + function previousProblem() { + console.log('previousProblem!'); + config.currentIndex = config.shuffle ? getRandomIndex(problems) : getPreviousIndex(problems); + updateLocalstore(config).then(function () { + window.location.reload(); + }); + } + + function nextProblem() { + console.log('nextProblem!'); + config.currentIndex = config.shuffle ? getRandomIndex(problems) : getNextIndex(problems); + updateLocalstore(config).then(function () { + window.location.reload(); + }); + } + + function toggleShuffle() { + console.log('toggle shuffle!'); + config.shuffle = !config.shuffle; // Flip it + shuffleProblemsButtonEl.classList.toggle('active'); + updateLocalstore(config); + } + + function loadProblem(problemObj) { + currentProblem = problemObj; + // Prob question + problemEl.innerText = problemObj.prompt; + // Prob given code + if (problemObj.given) { + codeEl.value = problemObj.given; + } + // Seed the tests, pass (init = true) as second param + testSuite(null, true); + } + + function updateTests(testStatus, init) { + if (init === true) { + buildTests(currentProblem.tests); + } + updateTestStatus(testStatus); + } + + function buildTests(tests) { + if (tests) { + var testsDom = tests.map(function (test) { + return '
\n
[✘]
\n
' + test.name + '
\n
'; + }).join(''); + testSuiteEl.innerHTML = testsDom; + } + } + + function updateTestStatus(testStatuses) { + if (!testStatuses) { + throw new Error('No testStatuses provided.'); + } + // Find out if all tests have passed or not + var allPassed = true; + testStatuses.forEach(function (testPassed) { + if (testPassed !== true) { + allPassed = false; + } + }); + var testEls = Array.from(testSuiteEl.querySelectorAll('.test-state')); + testEls.forEach(function (testStatusEl, iter) { + if (testStatuses[iter] === true) { + testStatusEl.innerHTML = '[✓]'; + testStatusEl.classList.remove('fail'); + testStatusEl.classList.add('pass'); + } else { + testStatusEl.innerHTML = '[✘]'; + testStatusEl.classList.remove('pass'); + testStatusEl.classList.add('fail'); + } + }); + + if (allPassed === true) { + testTotalEl.innerText = 'PASS'; + testTotalEl.classList.remove('fail'); + testTotalEl.classList.add('pass'); + } else { + testTotalEl.innerText = 'FAIL'; + testTotalEl.classList.remove('pass'); + testTotalEl.classList.add('fail'); + } + } + + function printAssertError(errObj) { + // Make element string + var inner = ''; + if (errObj !== null) { + inner = '\n
\n Expected: ' + JSON.stringify(errObj.expected) + '\n Actual: ' + JSON.stringify(errObj.actual) + '\n
'; + } + + // Prepend element + assertConsoleEl.innerHTML = inner; + } + + function printEvalOutput(errObj, output) { + // Make element string + var inner = ''; + if (errObj && errObj.message !== undefined) { + inner = '\n
\n Syntax Error: ' + JSON.stringify(errObj.message) + '\n
'; + } else if (output) { + inner = '\n
\n Output: ' + JSON.stringify(output) + '\n
'; + } + // Prepend element + evalConsoleEl.innerHTML = inner; + } + + // VERIFICATION LOGIC + // ============================================================ + + function testSuite(init) { + // Run stuff + var output = getOutput(codeEl.value); + // Run tests on code, return object/array of test results + var tested = runTests(output); + // Update UI with results + updateTests(tested, init); + } + + function getOutput(code) { + var evald = false; + try { + evald = eval('(function(){' + code + '})()'); // eslint-disable-line no-eval + printEvalOutput(null, evald); // Print current output + } catch (err) { + printEvalOutput(err); + } + return evald; + } + + function runTests(output) { + var tested = false; + tested = currentProblem.tests.map(function (test) { + var testOutcome = false; + try { + if (output) { + // const testEval = eval(test.test); + + testOutcome = eval(test.test); + console.log('testOutcome:', testOutcome); + } + printAssertError(null); + } catch (err) { + printAssertError(err); + } + return testOutcome; + }); + return tested; + } + + // Wrapped to prevent race with local config retrieval + function loadApp(config) { + console.log('loading app!'); + + // Show current toggle state + if (config.shuffle === true) { + shuffleProblemsButtonEl.classList.add('active'); + } + + // Bind it up + codeEl.addEventListener('keyup', function (e) { + // If not arrow keys or other non-character keys + if (ignoreKeyCodes.indexOf(e.keyCode) === -1) { + // Run test suite + testSuite(); + } + }); + shuffleProblemsButtonEl.addEventListener('click', toggleShuffle); + previousProblemButtonEl.addEventListener('click', previousProblem); + nextProblemButtonEl.addEventListener('click', nextProblem); + + // Start it up! + // Load current problem + var currProb = getCurrentProblem(problems); + loadProblem(currProb); + // Initalized test suite with starting failures + testSuite(true); + } +})(document, window); + +},{"chai":5,"dedent":34,"localforage":37,"pjs-problems":1}]},{},[42]) + +>>>>>>> working import of external problem content //# sourceMappingURL=bundle.min.js.map diff --git a/public/dist/js/bundle.min.js.map b/public/dist/js/bundle.min.js.map index a3a5a8b..05d2de1 100644 --- a/public/dist/js/bundle.min.js.map +++ b/public/dist/js/bundle.min.js.map @@ -1 +1,5 @@ -{"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/assertion-error/index.js","node_modules/chai/index.js","node_modules/chai/lib/chai.js","node_modules/chai/lib/chai/assertion.js","node_modules/chai/lib/chai/config.js","node_modules/chai/lib/chai/core/assertions.js","node_modules/chai/lib/chai/interface/assert.js","node_modules/chai/lib/chai/interface/expect.js","node_modules/chai/lib/chai/interface/should.js","node_modules/chai/lib/chai/utils/addChainableMethod.js","node_modules/chai/lib/chai/utils/addMethod.js","node_modules/chai/lib/chai/utils/addProperty.js","node_modules/chai/lib/chai/utils/expectTypes.js","node_modules/chai/lib/chai/utils/flag.js","node_modules/chai/lib/chai/utils/getActual.js","node_modules/chai/lib/chai/utils/getEnumerableProperties.js","node_modules/chai/lib/chai/utils/getMessage.js","node_modules/chai/lib/chai/utils/getName.js","node_modules/chai/lib/chai/utils/getPathInfo.js","node_modules/chai/lib/chai/utils/getPathValue.js","node_modules/chai/lib/chai/utils/getProperties.js","node_modules/chai/lib/chai/utils/hasProperty.js","node_modules/chai/lib/chai/utils/index.js","node_modules/chai/lib/chai/utils/inspect.js","node_modules/chai/lib/chai/utils/objDisplay.js","node_modules/chai/lib/chai/utils/overwriteChainableMethod.js","node_modules/chai/lib/chai/utils/overwriteMethod.js","node_modules/chai/lib/chai/utils/overwriteProperty.js","node_modules/chai/lib/chai/utils/test.js","node_modules/chai/lib/chai/utils/transferFlags.js","node_modules/deep-eql/index.js","node_modules/deep-eql/lib/eql.js","node_modules/deep-eql/node_modules/type-detect/index.js","node_modules/deep-eql/node_modules/type-detect/lib/type.js","node_modules/localforage/dist/localforage.js","node_modules/type-detect/lib/type.js","src/js/index.js","src/problems/arrays.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length","1","module","exclude","excludeProps","res","obj","Object","keys","forEach","key","excludes","indexOf","slice","arguments","args","AssertionError","message","_props","ssf","extend","props","this","showDiff","callee","captureStackTrace","stack","prototype","create","name","constructor","toJSON","used","version","util","use","fn","push","config","assertion","core","expect","should","assert","_chai","Assertion","msg","flag","defineProperty","get","console","warn","includeStack","set","value","addProperty","addMethod","addChainableMethod","chainingBehavior","overwriteProperty","overwriteMethod","overwriteChainableMethod","expr","negateMsg","expected","_actual","ok","test","getMessage","actual","getActual","val","truncateThreshold","chai","_","an","type","toLowerCase","article","charAt","includeChainingBehavior","include","expectTypes","eql","k","property","subset","undefined","inspect","checkArguments","toString","assertEqual","_obj","assertEql","assertAbove","to","have","len","assertLeast","assertBelow","assertMost","assertInstanceOf","getName","assertOwnProperty","hasOwnProperty","assertOwnPropertyDescriptor","descriptor","actualDescriptor","getOwnPropertyDescriptor","assertLengthChain","assertLength","assertMatch","re","exec","assertKeys","str","mixedArgsMsg","Array","any","all","filter","every","map","last","pop","join","sort","assertThrows","errMsg","is","thrown","desiredError","thrownError","RegExp","err","actuallyGot","expectedThrown","respondTo","method","itself","context","satisfy","matcher","result","objDisplay","negate","closeTo","delta","Math","abs","isSubsetOf","superset","cmp","elem","some","elem2","oneOf","list","be","assertChanges","object","prop","initial","assertIncreases","assertDecreases","chain","isNaN","isArray","start","finish","range","isDeep","pathInfo","getPathInfo","hasProperty","exists","isExtensible","TypeError","isSealed","isFrozen","express","errmsg","fail","operator","isOk","isNotOk","not","equal","act","exp","notEqual","strictEqual","notStrictEqual","deepEqual","notDeepEqual","isAbove","abv","above","isAtLeast","atlst","least","isBelow","blw","below","isAtMost","atmst","most","isTrue","isNotTrue","isFalse","isNotFalse","isNull","isNotNull","NaN","isNotNaN","isUndefined","isDefined","isFunction","isNotFunction","isObject","isNotObject","isNotArray","isString","isNotString","isNumber","isNotNumber","isBoolean","isNotBoolean","typeOf","notTypeOf","instanceOf","notInstanceOf","inc","notInclude","match","notMatch","notProperty","deepProperty","deep","notDeepProperty","propertyVal","propertyNotVal","deepPropertyVal","deepPropertyNotVal","lengthOf","throws","errt","errs","assertErr","throw","doesNotThrow","Throw","val2","approximately","sameMembers","set1","set2","same","members","sameDeepMembers","includeMembers","includeDeepMembers","inList","changes","change","doesNotChange","increases","increase","doesNotIncrease","decreases","decrease","doesNotDecrease","ifError","extensible","isNotExtensible","sealed","isNotSealed","frozen","isNotFrozen","alias","as","loadShould","shouldGetter","String","Number","Boolean","valueOf","shouldSetter","enumerable","configurable","writable","val1","exist","Should","transferFlags","hasProtoSupport","excludeNames","Function","apply","ctx","chainableBehavior","__methods","__proto__","getOwnPropertyNames","asserterName","pd","getter","types","index","art","flags","__flags","flagMsg","replace","func","parsePath","path","mArr","parseFloat","p","_getPathValue","parsed","tmp","part","info","parent","proto","getPrototypeOf","literals","number","string","ot","getPathValue","showHidden","depth","colors","formatValue","seen","stylize","recurseTimes","ret","primitive","formatPrimitive","isDOMElement","outerHTML","document","xmlVersion","XMLSerializer","serializeToString","container","createElementNS","appendChild","cloneNode","html","innerHTML","visibleKeys","getEnumerableProperties","getProperties","isError","nameSuffix","isRegExp","isDate","Date","toUTCString","formatError","base","array","braces","output","formatArray","formatProperty","reduceToSingleString","simple","JSON","stringify","Infinity","__lookupGetter__","__lookupSetter__","split","line","substr","numLinesEst","reduce","prev","cur","ar","objectToString","d","HTMLElement","nodeType","nodeName","splice","_chainingBehavior","_method","_super","_get","includeAll","b","m","sameValue","dateEqual","regexpEqual","Buffer","isBuffer","bufferEqual","argumentsEqual","typeEqual","objectEqual","getTime","iterableEqual","isValue","ka","kb","ex","getType","natives","Library","tests","[object Array]","[object RegExp]","[object Function]","[object Arguments]","[object Date]","of","define","ReferenceError","amd","g","window","global","self","localforage","_dereq_","nextTick","draining","oldQueue","queue","immediate","task","scheduleDrain","Mutation","MutationObserver","WebKitMutationObserver","called","observer","element","createTextNode","observe","characterData","data","setImmediate","MessageChannel","createElement","scriptEl","onreadystatechange","parentNode","removeChild","documentElement","setTimeout","channel","port1","onmessage","port2","postMessage","2","INTERNAL","Promise","resolver","state","PENDING","outcome","safelyResolveThenable","QueueItem","promise","onFulfilled","onRejected","callFulfilled","otherCallFulfilled","callRejected","otherCallRejected","unwrap","returnValue","handlers","reject","resolve","getThen","then","thenable","onError","onSuccess","tryToUnwrap","tryCatch","status","out","reason","iterable","values","resolved","resolveFromAll","outValue","error","race","response","REJECTED","FULFILLED","3","4","_classCallCheck","instance","Constructor","createBlob","parts","properties","Blob","Builder","BlobBuilder","MSBlobBuilder","MozBlobBuilder","WebKitBlobBuilder","builder","append","getBlob","executeCallback","callback","executeTwoCallbacks","errorCallback","_binStringToArrayBuffer","bin","buf","ArrayBuffer","arr","Uint8Array","charCodeAt","_checkBlobSupportWithoutCaching","idb","Promise$1","txn","transaction","DETECT_BLOB_SUPPORT_STORE","blob","objectStore","put","onabort","preventDefault","stopPropagation","oncomplete","matchedChrome","navigator","userAgent","matchedEdge","parseInt","_checkBlobSupport","supportsBlobs","_deferReadiness","dbInfo","dbContext","dbContexts","deferredOperation","deferredOperations","dbReady","_advanceReadiness","_getConnection","upgradeNeeded","db","close","dbArgs","openreq","open","onupgradeneeded","createObjectStore","storeName","oldVersion","newVersion","onerror","onsuccess","_getOriginalConnection","_getUpgradedConnection","_isUpgradeNeeded","defaultVersion","isNewStore","objectStoreNames","contains","isDowngrade","isUpgrade","incVersion","_encodeBlob","reader","FileReader","onloadend","base64","btoa","target","__local_forage_encoded_blob","readAsBinaryString","_decodeBlob","encodedBlob","atob","_isEncodedBlob","_fullyReady","_initReady","_dbInfo","_initStorage","options","ignoreErrors","forages","ready","initPromises","j","forage","_defaultConfig","getItem","store","req","iterate","iterator","openCursor","iterationNumber","cursor","setItem","blobSupport","removeItem","clear","count","advanced","advance","stringToBuffer","serializedString","encoded1","encoded2","encoded3","encoded4","bufferLength","buffer","bytes","BASE_CHARS","bufferToString","base64String","substring","serialize","valueType","toString$1","marker","SERIALIZED_MARKER","TYPE_ARRAYBUFFER","TYPE_INT8ARRAY","TYPE_UINT8ARRAY","TYPE_UINT8CLAMPEDARRAY","TYPE_INT16ARRAY","TYPE_UINT16ARRAY","TYPE_INT32ARRAY","TYPE_UINT32ARRAY","TYPE_FLOAT32ARRAY","TYPE_FLOAT64ARRAY","fileReader","onload","BLOB_TYPE_PREFIX","TYPE_BLOB","readAsArrayBuffer","deserialize","SERIALIZED_MARKER_LENGTH","parse","blobType","TYPE_SERIALIZED_MARKER_LENGTH","BLOB_TYPE_PREFIX_REGEX","Int8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","_initStorage$1","dbInfoPromise","openDatabase","description","size","executeSql","serializer","localforageSerializer","getItem$1","results","rows","item","iterate$1","_setItem","retriesLeft","originalValue","sqlError","QUOTA_ERR","setItem$1","removeItem$1","clear$1","length$1","c","key$1","keys$1","_initStorage$2","keyPrefix","clear$2","localStorage","getItem$2","iterate$2","keyPrefixLength","key$2","keys$2","length$2","removeItem$2","setItem$2","callWhenReady","localForageInstance","libraryMethod","_args","arg","isLibraryDriver","driverName","driver","DriverType","_typeof","Symbol","indexedDB","webkitIndexedDB","mozIndexedDB","OIndexedDB","msIndexedDB","asyncStorage","_driver","webSQLStorage","localStorageWrapper","CustomDrivers","INDEXEDDB","LOCALSTORAGE","WEBSQL","DefaultDriverOrder","LibraryMethods","DefaultConfig","driverSupport","isSafari","platform","hasFetch","fetch","IDBKeyRange","LocalForage","_config","_driverSet","_initDriver","_ready","_wrapLibraryMethodsWithReady","setDriver","defineDriver","driverObject","complianceError","namingError","customDriverMethods","concat","customDriverMethod","supportPromise","_support","supportResult","getDriver","getDriverPromise","getSerializer","serializerPromise","drivers","setDriverToConfig","extendSelfWithDriver","_extend","initDriver","supportedDrivers","driverPromiseLoop","currentDriverIndex","_getSupportedDrivers","oldDriverSetDone","supports","libraryMethodsAndProperties","createInstance","localforage_js","objectTypeRegexp","updateLocalstore","catch","log","debounce","wait","timeout","later","callNow","clearTimeout","getRandomIndex","problemsArr","ind","floor","random","currentIndex","getPreviousIndex","getNextIndex","getCurrentProblem","previousProblem","previousProblemButtonEl","classList","add","shuffle","problems","location","reload","nextProblem","nextProblemButtonEl","toggleShuffle","shuffleProblemsButtonEl","toggle","loadProblem","problemObj","currentProblem","problemEl","innerText","prompt","given","codeEl","testSuite","updateTests","testStatus","init","buildTests","updateTestStatus","testsDom","testSuiteEl","testStatuses","allPassed","testPassed","querySelectorAll","testStatusEl","iter","remove","testTotalEl","printAssertError","errObj","inner","assertConsoleEl","printEvalOutput","evalConsoleEl","getOutput","tested","runTests","evald","eval","testOutcome","loadApp","problemNav","keyCode","shiftKey","metaKey","ctrlKey","debouncedInputValidation","ignoreKeyCodes","addEventListener","timer","getElementById","time","answer","evenNumbers","someOddNumbers"],"mappings":"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","file":"bundle.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o\n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n var excludes = [].slice.call(arguments);\n\n function excludeProps (res, obj) {\n Object.keys(obj).forEach(function (key) {\n if (!~excludes.indexOf(key)) res[key] = obj[key];\n });\n }\n\n return function extendExclude () {\n var args = [].slice.call(arguments)\n , i = 0\n , res = {};\n\n for (; i < args.length; i++) {\n excludeProps(res, args[i]);\n }\n\n return res;\n };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n , props = extend(_props || {});\n\n // default values\n this.message = message || 'Unspecified AssertionError';\n this.showDiff = false;\n\n // copy from properties\n for (var key in props) {\n this[key] = props[key];\n }\n\n // capture stack trace\n ssf = ssf || arguments.callee;\n if (ssf && Error.captureStackTrace) {\n Error.captureStackTrace(this, ssf);\n } else {\n try {\n throw new Error();\n } catch(e) {\n this.stack = e.stack;\n }\n }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n var extend = exclude('constructor', 'toJSON', 'stack')\n , props = extend({ name: this.name }, this);\n\n // include stack if exists and not turned off\n if (false !== stack && this.stack) {\n props.stack = this.stack;\n }\n\n return props;\n};\n","module.exports = require('./lib/chai');\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar used = []\n , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n if (!~used.indexOf(fn)) {\n fn(this, util);\n used.push(fn);\n }\n\n return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n /*!\n * Module dependencies.\n */\n\n var AssertionError = _chai.AssertionError\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n _chai.Assertion = Assertion;\n\n /*!\n * Assertion Constructor\n *\n * Creates object for chaining.\n *\n * @api private\n */\n\n function Assertion (obj, msg, stack) {\n flag(this, 'ssfi', stack || arguments.callee);\n flag(this, 'object', obj);\n flag(this, 'message', msg);\n }\n\n Object.defineProperty(Assertion, 'includeStack', {\n get: function() {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n return config.includeStack;\n },\n set: function(value) {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n config.includeStack = value;\n }\n });\n\n Object.defineProperty(Assertion, 'showDiff', {\n get: function() {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n return config.showDiff;\n },\n set: function(value) {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n config.showDiff = value;\n }\n });\n\n Assertion.addProperty = function (name, fn) {\n util.addProperty(this.prototype, name, fn);\n };\n\n Assertion.addMethod = function (name, fn) {\n util.addMethod(this.prototype, name, fn);\n };\n\n Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n Assertion.overwriteProperty = function (name, fn) {\n util.overwriteProperty(this.prototype, name, fn);\n };\n\n Assertion.overwriteMethod = function (name, fn) {\n util.overwriteMethod(this.prototype, name, fn);\n };\n\n Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n /**\n * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n *\n * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n *\n * @name assert\n * @param {Philosophical} expression to be tested\n * @param {String|Function} message or function that returns message to display if expression fails\n * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n * @param {Mixed} expected value (remember to check for negation)\n * @param {Mixed} actual (optional) will default to `this.obj`\n * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n * @api private\n */\n\n Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n var ok = util.test(this, arguments);\n if (true !== showDiff) showDiff = false;\n if (true !== config.showDiff) showDiff = false;\n\n if (!ok) {\n var msg = util.getMessage(this, arguments)\n , actual = util.getActual(this, arguments);\n throw new AssertionError(msg, {\n actual: actual\n , expected: expected\n , showDiff: showDiff\n }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n }\n };\n\n /*!\n * ### ._obj\n *\n * Quick reference to stored `actual` value for plugin developers.\n *\n * @api private\n */\n\n Object.defineProperty(Assertion.prototype, '_obj',\n { get: function () {\n return flag(this, 'object');\n }\n , set: function (val) {\n flag(this, 'object', val);\n }\n });\n};\n","module.exports = {\n\n /**\n * ### config.includeStack\n *\n * User configurable property, influences whether stack trace\n * is included in Assertion error message. Default of false\n * suppresses stack trace in the error message.\n *\n * chai.config.includeStack = true; // enable stack on error\n *\n * @param {Boolean}\n * @api public\n */\n\n includeStack: false,\n\n /**\n * ### config.showDiff\n *\n * User configurable property, influences whether or not\n * the `showDiff` flag should be included in the thrown\n * AssertionErrors. `false` will always be `false`; `true`\n * will be true when the assertion has requested a diff\n * be shown.\n *\n * @param {Boolean}\n * @api public\n */\n\n showDiff: true,\n\n /**\n * ### config.truncateThreshold\n *\n * User configurable property, sets length threshold for actual and\n * expected values in assertion errors. If this threshold is exceeded, for\n * example for large data structures, the value is replaced with something\n * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n *\n * Set it to zero if you want to disable truncating altogether.\n *\n * This is especially userful when doing assertions on arrays: having this\n * set to a reasonable large value makes the failure messages readily\n * inspectable.\n *\n * chai.config.truncateThreshold = 0; // disable truncating\n *\n * @param {Number}\n * @api public\n */\n\n truncateThreshold: 40\n\n};\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n var Assertion = chai.Assertion\n , toString = Object.prototype.toString\n , flag = _.flag;\n\n /**\n * ### Language Chains\n *\n * The following are provided as chainable getters to\n * improve the readability of your assertions. They\n * do not provide testing capabilities unless they\n * have been overwritten by a plugin.\n *\n * **Chains**\n *\n * - to\n * - be\n * - been\n * - is\n * - that\n * - which\n * - and\n * - has\n * - have\n * - with\n * - at\n * - of\n * - same\n *\n * @name language chains\n * @namespace BDD\n * @api public\n */\n\n [ 'to', 'be', 'been'\n , 'is', 'and', 'has', 'have'\n , 'with', 'that', 'which', 'at'\n , 'of', 'same' ].forEach(function (chain) {\n Assertion.addProperty(chain, function () {\n return this;\n });\n });\n\n /**\n * ### .not\n *\n * Negates any of assertions following in the chain.\n *\n * expect(foo).to.not.equal('bar');\n * expect(goodFn).to.not.throw(Error);\n * expect({ foo: 'baz' }).to.have.property('foo')\n * .and.not.equal('bar');\n *\n * @name not\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('not', function () {\n flag(this, 'negate', true);\n });\n\n /**\n * ### .deep\n *\n * Sets the `deep` flag, later used by the `equal` and\n * `property` assertions.\n *\n * expect(foo).to.deep.equal({ bar: 'baz' });\n * expect({ foo: { bar: { baz: 'quux' } } })\n * .to.have.deep.property('foo.bar.baz', 'quux');\n *\n * `.deep.property` special characters can be escaped\n * by adding two slashes before the `.` or `[]`.\n *\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name deep\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('deep', function () {\n flag(this, 'deep', true);\n });\n\n /**\n * ### .any\n *\n * Sets the `any` flag, (opposite of the `all` flag)\n * later used in the `keys` assertion.\n *\n * expect(foo).to.have.any.keys('bar', 'baz');\n *\n * @name any\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('any', function () {\n flag(this, 'any', true);\n flag(this, 'all', false)\n });\n\n\n /**\n * ### .all\n *\n * Sets the `all` flag (opposite of the `any` flag)\n * later used by the `keys` assertion.\n *\n * expect(foo).to.have.all.keys('bar', 'baz');\n *\n * @name all\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('all', function () {\n flag(this, 'all', true);\n flag(this, 'any', false);\n });\n\n /**\n * ### .a(type)\n *\n * The `a` and `an` assertions are aliases that can be\n * used either as language chains or to assert a value's\n * type.\n *\n * // typeof\n * expect('test').to.be.a('string');\n * expect({ foo: 'bar' }).to.be.an('object');\n * expect(null).to.be.a('null');\n * expect(undefined).to.be.an('undefined');\n * expect(new Error).to.be.an('error');\n * expect(new Promise).to.be.a('promise');\n * expect(new Float32Array()).to.be.a('float32array');\n * expect(Symbol()).to.be.a('symbol');\n *\n * // es6 overrides\n * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n *\n * // language chain\n * expect(foo).to.be.an.instanceof(Foo);\n *\n * @name a\n * @alias an\n * @param {String} type\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function an (type, msg) {\n if (msg) flag(this, 'message', msg);\n type = type.toLowerCase();\n var obj = flag(this, 'object')\n , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n this.assert(\n type === _.type(obj)\n , 'expected #{this} to be ' + article + type\n , 'expected #{this} not to be ' + article + type\n );\n }\n\n Assertion.addChainableMethod('an', an);\n Assertion.addChainableMethod('a', an);\n\n /**\n * ### .include(value)\n *\n * The `include` and `contain` assertions can be used as either property\n * based language chains or as methods to assert the inclusion of an object\n * in an array or a substring in a string. When used as language chains,\n * they toggle the `contains` flag for the `keys` assertion.\n *\n * expect([1,2,3]).to.include(2);\n * expect('foobar').to.contain('foo');\n * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n *\n * @name include\n * @alias contain\n * @alias includes\n * @alias contains\n * @param {Object|String|Number} obj\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function includeChainingBehavior () {\n flag(this, 'contains', true);\n }\n\n function include (val, msg) {\n _.expectTypes(this, ['array', 'object', 'string']);\n\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var expected = false;\n\n if (_.type(obj) === 'array' && _.type(val) === 'object') {\n for (var i in obj) {\n if (_.eql(obj[i], val)) {\n expected = true;\n break;\n }\n }\n } else if (_.type(val) === 'object') {\n if (!flag(this, 'negate')) {\n for (var k in val) new Assertion(obj).property(k, val[k]);\n return;\n }\n var subset = {};\n for (var k in val) subset[k] = obj[k];\n expected = _.eql(subset, val);\n } else {\n expected = (obj != undefined) && ~obj.indexOf(val);\n }\n this.assert(\n expected\n , 'expected #{this} to include ' + _.inspect(val)\n , 'expected #{this} to not include ' + _.inspect(val));\n }\n\n Assertion.addChainableMethod('include', include, includeChainingBehavior);\n Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n /**\n * ### .ok\n *\n * Asserts that the target is truthy.\n *\n * expect('everything').to.be.ok;\n * expect(1).to.be.ok;\n * expect(false).to.not.be.ok;\n * expect(undefined).to.not.be.ok;\n * expect(null).to.not.be.ok;\n *\n * @name ok\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('ok', function () {\n this.assert(\n flag(this, 'object')\n , 'expected #{this} to be truthy'\n , 'expected #{this} to be falsy');\n });\n\n /**\n * ### .true\n *\n * Asserts that the target is `true`.\n *\n * expect(true).to.be.true;\n * expect(1).to.not.be.true;\n *\n * @name true\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('true', function () {\n this.assert(\n true === flag(this, 'object')\n , 'expected #{this} to be true'\n , 'expected #{this} to be false'\n , this.negate ? false : true\n );\n });\n\n /**\n * ### .false\n *\n * Asserts that the target is `false`.\n *\n * expect(false).to.be.false;\n * expect(0).to.not.be.false;\n *\n * @name false\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('false', function () {\n this.assert(\n false === flag(this, 'object')\n , 'expected #{this} to be false'\n , 'expected #{this} to be true'\n , this.negate ? true : false\n );\n });\n\n /**\n * ### .null\n *\n * Asserts that the target is `null`.\n *\n * expect(null).to.be.null;\n * expect(undefined).to.not.be.null;\n *\n * @name null\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('null', function () {\n this.assert(\n null === flag(this, 'object')\n , 'expected #{this} to be null'\n , 'expected #{this} not to be null'\n );\n });\n\n /**\n * ### .undefined\n *\n * Asserts that the target is `undefined`.\n *\n * expect(undefined).to.be.undefined;\n * expect(null).to.not.be.undefined;\n *\n * @name undefined\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('undefined', function () {\n this.assert(\n undefined === flag(this, 'object')\n , 'expected #{this} to be undefined'\n , 'expected #{this} not to be undefined'\n );\n });\n\n /**\n * ### .NaN\n * Asserts that the target is `NaN`.\n *\n * expect('foo').to.be.NaN;\n * expect(4).not.to.be.NaN;\n *\n * @name NaN\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('NaN', function () {\n this.assert(\n isNaN(flag(this, 'object'))\n , 'expected #{this} to be NaN'\n , 'expected #{this} not to be NaN'\n );\n });\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi'\n * , bar = null\n * , baz;\n *\n * expect(foo).to.exist;\n * expect(bar).to.not.exist;\n * expect(baz).to.not.exist;\n *\n * @name exist\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('exist', function () {\n this.assert(\n null != flag(this, 'object')\n , 'expected #{this} to exist'\n , 'expected #{this} to not exist'\n );\n });\n\n\n /**\n * ### .empty\n *\n * Asserts that the target's length is `0`. For arrays and strings, it checks\n * the `length` property. For objects, it gets the count of\n * enumerable keys.\n *\n * expect([]).to.be.empty;\n * expect('').to.be.empty;\n * expect({}).to.be.empty;\n *\n * @name empty\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('empty', function () {\n var obj = flag(this, 'object')\n , expected = obj;\n\n if (Array.isArray(obj) || 'string' === typeof object) {\n expected = obj.length;\n } else if (typeof obj === 'object') {\n expected = Object.keys(obj).length;\n }\n\n this.assert(\n !expected\n , 'expected #{this} to be empty'\n , 'expected #{this} not to be empty'\n );\n });\n\n /**\n * ### .arguments\n *\n * Asserts that the target is an arguments object.\n *\n * function test () {\n * expect(arguments).to.be.arguments;\n * }\n *\n * @name arguments\n * @alias Arguments\n * @namespace BDD\n * @api public\n */\n\n function checkArguments () {\n var obj = flag(this, 'object')\n , type = Object.prototype.toString.call(obj);\n this.assert(\n '[object Arguments]' === type\n , 'expected #{this} to be arguments but got ' + type\n , 'expected #{this} to not be arguments'\n );\n }\n\n Assertion.addProperty('arguments', checkArguments);\n Assertion.addProperty('Arguments', checkArguments);\n\n /**\n * ### .equal(value)\n *\n * Asserts that the target is strictly equal (`===`) to `value`.\n * Alternately, if the `deep` flag is set, asserts that\n * the target is deeply equal to `value`.\n *\n * expect('hello').to.equal('hello');\n * expect(42).to.equal(42);\n * expect(1).to.not.equal(true);\n * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n *\n * @name equal\n * @alias equals\n * @alias eq\n * @alias deep.equal\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEqual (val, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'deep')) {\n return this.eql(val);\n } else {\n this.assert(\n val === obj\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{exp}'\n , val\n , this._obj\n , true\n );\n }\n }\n\n Assertion.addMethod('equal', assertEqual);\n Assertion.addMethod('equals', assertEqual);\n Assertion.addMethod('eq', assertEqual);\n\n /**\n * ### .eql(value)\n *\n * Asserts that the target is deeply equal to `value`.\n *\n * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n *\n * @name eql\n * @alias eqls\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEql(obj, msg) {\n if (msg) flag(this, 'message', msg);\n this.assert(\n _.eql(obj, flag(this, 'object'))\n , 'expected #{this} to deeply equal #{exp}'\n , 'expected #{this} to not deeply equal #{exp}'\n , obj\n , this._obj\n , true\n );\n }\n\n Assertion.addMethod('eql', assertEql);\n Assertion.addMethod('eqls', assertEql);\n\n /**\n * ### .above(value)\n *\n * Asserts that the target is greater than `value`.\n *\n * expect(10).to.be.above(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n *\n * @name above\n * @alias gt\n * @alias greaterThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertAbove (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len > n\n , 'expected #{this} to have a length above #{exp} but got #{act}'\n , 'expected #{this} to not have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj > n\n , 'expected #{this} to be above ' + n\n , 'expected #{this} to be at most ' + n\n );\n }\n }\n\n Assertion.addMethod('above', assertAbove);\n Assertion.addMethod('gt', assertAbove);\n Assertion.addMethod('greaterThan', assertAbove);\n\n /**\n * ### .least(value)\n *\n * Asserts that the target is greater than or equal to `value`.\n *\n * expect(10).to.be.at.least(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.least(2);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n *\n * @name least\n * @alias gte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLeast (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= n\n , 'expected #{this} to have a length at least #{exp} but got #{act}'\n , 'expected #{this} to have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj >= n\n , 'expected #{this} to be at least ' + n\n , 'expected #{this} to be below ' + n\n );\n }\n }\n\n Assertion.addMethod('least', assertLeast);\n Assertion.addMethod('gte', assertLeast);\n\n /**\n * ### .below(value)\n *\n * Asserts that the target is less than `value`.\n *\n * expect(5).to.be.below(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n *\n * @name below\n * @alias lt\n * @alias lessThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertBelow (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len < n\n , 'expected #{this} to have a length below #{exp} but got #{act}'\n , 'expected #{this} to not have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj < n\n , 'expected #{this} to be below ' + n\n , 'expected #{this} to be at least ' + n\n );\n }\n }\n\n Assertion.addMethod('below', assertBelow);\n Assertion.addMethod('lt', assertBelow);\n Assertion.addMethod('lessThan', assertBelow);\n\n /**\n * ### .most(value)\n *\n * Asserts that the target is less than or equal to `value`.\n *\n * expect(5).to.be.at.most(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.most(4);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n *\n * @name most\n * @alias lte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertMost (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len <= n\n , 'expected #{this} to have a length at most #{exp} but got #{act}'\n , 'expected #{this} to have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj <= n\n , 'expected #{this} to be at most ' + n\n , 'expected #{this} to be above ' + n\n );\n }\n }\n\n Assertion.addMethod('most', assertMost);\n Assertion.addMethod('lte', assertMost);\n\n /**\n * ### .within(start, finish)\n *\n * Asserts that the target is within a range.\n *\n * expect(7).to.be.within(5,10);\n *\n * Can also be used in conjunction with `length` to\n * assert a length range. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * @name within\n * @param {Number} start lowerbound inclusive\n * @param {Number} finish upperbound inclusive\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('within', function (start, finish, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , range = start + '..' + finish;\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= start && len <= finish\n , 'expected #{this} to have a length within ' + range\n , 'expected #{this} to not have a length within ' + range\n );\n } else {\n this.assert(\n obj >= start && obj <= finish\n , 'expected #{this} to be within ' + range\n , 'expected #{this} to not be within ' + range\n );\n }\n });\n\n /**\n * ### .instanceof(constructor)\n *\n * Asserts that the target is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , Chai = new Tea('chai');\n *\n * expect(Chai).to.be.an.instanceof(Tea);\n * expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n *\n * @name instanceof\n * @param {Constructor} constructor\n * @param {String} message _optional_\n * @alias instanceOf\n * @namespace BDD\n * @api public\n */\n\n function assertInstanceOf (constructor, msg) {\n if (msg) flag(this, 'message', msg);\n var name = _.getName(constructor);\n this.assert(\n flag(this, 'object') instanceof constructor\n , 'expected #{this} to be an instance of ' + name\n , 'expected #{this} to not be an instance of ' + name\n );\n };\n\n Assertion.addMethod('instanceof', assertInstanceOf);\n Assertion.addMethod('instanceOf', assertInstanceOf);\n\n /**\n * ### .property(name, [value])\n *\n * Asserts that the target has a property `name`, optionally asserting that\n * the value of that property is strictly equal to `value`.\n * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n * references into objects and arrays.\n *\n * // simple referencing\n * var obj = { foo: 'bar' };\n * expect(obj).to.have.property('foo');\n * expect(obj).to.have.property('foo', 'bar');\n *\n * // deep referencing\n * var deepObj = {\n * green: { tea: 'matcha' }\n * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n * };\n *\n * expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n *\n * You can also use an array as the starting point of a `deep.property`\n * assertion, or traverse nested arrays.\n *\n * var arr = [\n * [ 'chai', 'matcha', 'konacha' ]\n * , [ { tea: 'chai' }\n * , { tea: 'matcha' }\n * , { tea: 'konacha' } ]\n * ];\n *\n * expect(arr).to.have.deep.property('[0][1]', 'matcha');\n * expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n *\n * Furthermore, `property` changes the subject of the assertion\n * to be the value of that property from the original object. This\n * permits for further chainable assertions on that property.\n *\n * expect(obj).to.have.property('foo')\n * .that.is.a('string');\n * expect(deepObj).to.have.property('green')\n * .that.is.an('object')\n * .that.deep.equals({ tea: 'matcha' });\n * expect(deepObj).to.have.property('teas')\n * .that.is.an('array')\n * .with.deep.property('[2]')\n * .that.deep.equals({ tea: 'konacha' });\n *\n * Note that dots and bracket in `name` must be backslash-escaped when\n * the `deep` flag is set, while they must NOT be escaped when the `deep`\n * flag is not set.\n *\n * // simple referencing\n * var css = { '.link[target]': 42 };\n * expect(css).to.have.property('.link[target]', 42);\n *\n * // deep referencing\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name property\n * @alias deep.property\n * @param {String} name\n * @param {Mixed} value (optional)\n * @param {String} message _optional_\n * @returns value of property for chaining\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('property', function (name, val, msg) {\n if (msg) flag(this, 'message', msg);\n\n var isDeep = !!flag(this, 'deep')\n , descriptor = isDeep ? 'deep property ' : 'property '\n , negate = flag(this, 'negate')\n , obj = flag(this, 'object')\n , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n , hasProperty = isDeep\n ? pathInfo.exists\n : _.hasProperty(name, obj)\n , value = isDeep\n ? pathInfo.value\n : obj[name];\n\n if (negate && arguments.length > 1) {\n if (undefined === value) {\n msg = (msg != null) ? msg + ': ' : '';\n throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n }\n } else {\n this.assert(\n hasProperty\n , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n }\n\n if (arguments.length > 1) {\n this.assert(\n val === value\n , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n , val\n , value\n );\n }\n\n flag(this, 'object', value);\n });\n\n\n /**\n * ### .ownProperty(name)\n *\n * Asserts that the target has an own property `name`.\n *\n * expect('test').to.have.ownProperty('length');\n *\n * @name ownProperty\n * @alias haveOwnProperty\n * @param {String} name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnProperty (name, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n obj.hasOwnProperty(name)\n , 'expected #{this} to have own property ' + _.inspect(name)\n , 'expected #{this} to not have own property ' + _.inspect(name)\n );\n }\n\n Assertion.addMethod('ownProperty', assertOwnProperty);\n Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n /**\n * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n *\n * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n *\n * expect('test').to.have.ownPropertyDescriptor('length');\n * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n * expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n *\n * @name ownPropertyDescriptor\n * @alias haveOwnPropertyDescriptor\n * @param {String} name\n * @param {Object} descriptor _optional_\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnPropertyDescriptor (name, descriptor, msg) {\n if (typeof descriptor === 'string') {\n msg = descriptor;\n descriptor = null;\n }\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n if (actualDescriptor && descriptor) {\n this.assert(\n _.eql(descriptor, actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n , descriptor\n , actualDescriptor\n , true\n );\n } else {\n this.assert(\n actualDescriptor\n , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n );\n }\n flag(this, 'object', actualDescriptor);\n }\n\n Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n /**\n * ### .length\n *\n * Sets the `doLength` flag later used as a chain precursor to a value\n * comparison for the `length` property.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * *Deprecation notice:* Using `length` as an assertion will be deprecated\n * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n * asserting for `length` property value using `length(value)` should be\n * switched to use `lengthOf(value)` instead.\n *\n * @name length\n * @namespace BDD\n * @api public\n */\n\n /**\n * ### .lengthOf(value[, message])\n *\n * Asserts that the target's `length` property has\n * the expected value.\n *\n * expect([ 1, 2, 3]).to.have.lengthOf(3);\n * expect('foobar').to.have.lengthOf(6);\n *\n * @name lengthOf\n * @param {Number} length\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLengthChain () {\n flag(this, 'doLength', true);\n }\n\n function assertLength (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n\n this.assert(\n len == n\n , 'expected #{this} to have a length of #{exp} but got #{act}'\n , 'expected #{this} to not have a length of #{act}'\n , n\n , len\n );\n }\n\n Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n Assertion.addMethod('lengthOf', assertLength);\n\n /**\n * ### .match(regexp)\n *\n * Asserts that the target matches a regular expression.\n *\n * expect('foobar').to.match(/^foo/);\n *\n * @name match\n * @alias matches\n * @param {RegExp} RegularExpression\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n function assertMatch(re, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n re.exec(obj)\n , 'expected #{this} to match ' + re\n , 'expected #{this} not to match ' + re\n );\n }\n\n Assertion.addMethod('match', assertMatch);\n Assertion.addMethod('matches', assertMatch);\n\n /**\n * ### .string(string)\n *\n * Asserts that the string target contains another string.\n *\n * expect('foobar').to.have.string('bar');\n *\n * @name string\n * @param {String} string\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('string', function (str, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('string');\n\n this.assert(\n ~obj.indexOf(str)\n , 'expected #{this} to contain ' + _.inspect(str)\n , 'expected #{this} to not contain ' + _.inspect(str)\n );\n });\n\n\n /**\n * ### .keys(key1, [key2], [...])\n *\n * Asserts that the target contains any or all of the passed-in keys.\n * Use in combination with `any`, `all`, `contains`, or `have` will affect\n * what will pass.\n *\n * When used in conjunction with `any`, at least one key that is passed\n * in must exist in the target object. This is regardless whether or not\n * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n * should be used in the assertion. If neither are used, the assertion is\n * defaulted to `all`.\n *\n * When both `all` and `contain` are used, the target object must have at\n * least all of the passed-in keys but may have more keys not listed.\n *\n * When both `all` and `have` are used, the target object must both contain\n * all of the passed-in keys AND the number of keys in the target object must\n * match the number of keys passed in (in other words, a target object must\n * have all and only all of the passed-in keys).\n *\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n *\n *\n * @name keys\n * @alias key\n * @param {...String|Array|Object} keys\n * @namespace BDD\n * @api public\n */\n\n function assertKeys (keys) {\n var obj = flag(this, 'object')\n , str\n , ok = true\n , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n switch (_.type(keys)) {\n case \"array\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n break;\n case \"object\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n keys = Object.keys(keys);\n break;\n default:\n keys = Array.prototype.slice.call(arguments);\n }\n\n if (!keys.length) throw new Error('keys required');\n\n var actual = Object.keys(obj)\n , expected = keys\n , len = keys.length\n , any = flag(this, 'any')\n , all = flag(this, 'all');\n\n if (!any && !all) {\n all = true;\n }\n\n // Has any\n if (any) {\n var intersection = expected.filter(function(key) {\n return ~actual.indexOf(key);\n });\n ok = intersection.length > 0;\n }\n\n // Has all\n if (all) {\n ok = keys.every(function(key){\n return ~actual.indexOf(key);\n });\n if (!flag(this, 'negate') && !flag(this, 'contains')) {\n ok = ok && keys.length == actual.length;\n }\n }\n\n // Key string\n if (len > 1) {\n keys = keys.map(function(key){\n return _.inspect(key);\n });\n var last = keys.pop();\n if (all) {\n str = keys.join(', ') + ', and ' + last;\n }\n if (any) {\n str = keys.join(', ') + ', or ' + last;\n }\n } else {\n str = _.inspect(keys[0]);\n }\n\n // Form\n str = (len > 1 ? 'keys ' : 'key ') + str;\n\n // Have / include\n str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n // Assertion\n this.assert(\n ok\n , 'expected #{this} to ' + str\n , 'expected #{this} to not ' + str\n , expected.slice(0).sort()\n , actual.sort()\n , true\n );\n }\n\n Assertion.addMethod('keys', assertKeys);\n Assertion.addMethod('key', assertKeys);\n\n /**\n * ### .throw(constructor)\n *\n * Asserts that the function target will throw a specific error, or specific type of error\n * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n * for the error's message.\n *\n * var err = new ReferenceError('This is a bad function.');\n * var fn = function () { throw err; }\n * expect(fn).to.throw(ReferenceError);\n * expect(fn).to.throw(Error);\n * expect(fn).to.throw(/bad function/);\n * expect(fn).to.not.throw('good function');\n * expect(fn).to.throw(ReferenceError, /bad function/);\n * expect(fn).to.throw(err);\n *\n * Please note that when a throw expectation is negated, it will check each\n * parameter independently, starting with error constructor type. The appropriate way\n * to check for the existence of a type of error but for a message that does not match\n * is to use `and`.\n *\n * expect(fn).to.throw(ReferenceError)\n * .and.not.throw(/good function/);\n *\n * @name throw\n * @alias throws\n * @alias Throw\n * @param {ErrorConstructor} constructor\n * @param {String|RegExp} expected error message\n * @param {String} message _optional_\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @returns error for chaining (null if no error)\n * @namespace BDD\n * @api public\n */\n\n function assertThrows (constructor, errMsg, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('function');\n\n var thrown = false\n , desiredError = null\n , name = null\n , thrownError = null;\n\n if (arguments.length === 0) {\n errMsg = null;\n constructor = null;\n } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n errMsg = constructor;\n constructor = null;\n } else if (constructor && constructor instanceof Error) {\n desiredError = constructor;\n constructor = null;\n errMsg = null;\n } else if (typeof constructor === 'function') {\n name = constructor.prototype.name;\n if (!name || (name === 'Error' && constructor !== Error)) {\n name = constructor.name || (new constructor()).name;\n }\n } else {\n constructor = null;\n }\n\n try {\n obj();\n } catch (err) {\n // first, check desired error\n if (desiredError) {\n this.assert(\n err === desiredError\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp}'\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (err instanceof Error ? err.toString() : err)\n );\n\n flag(this, 'object', err);\n return this;\n }\n\n // next, check constructor\n if (constructor) {\n this.assert(\n err instanceof constructor\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n , name\n , (err instanceof Error ? err.toString() : err)\n );\n\n if (!errMsg) {\n flag(this, 'object', err);\n return this;\n }\n }\n\n // next, check message\n var message = 'error' === _.type(err) && \"message\" in err\n ? err.message\n : '' + err;\n\n if ((message != null) && errMsg && errMsg instanceof RegExp) {\n this.assert(\n errMsg.exec(message)\n , 'expected #{this} to throw error matching #{exp} but got #{act}'\n , 'expected #{this} to throw error not matching #{exp}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n this.assert(\n ~message.indexOf(errMsg)\n , 'expected #{this} to throw error including #{exp} but got #{act}'\n , 'expected #{this} to throw error not including #{act}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else {\n thrown = true;\n thrownError = err;\n }\n }\n\n var actuallyGot = ''\n , expectedThrown = name !== null\n ? name\n : desiredError\n ? '#{exp}' //_.inspect(desiredError)\n : 'an error';\n\n if (thrown) {\n actuallyGot = ' but #{act} was thrown'\n }\n\n this.assert(\n thrown === true\n , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n );\n\n flag(this, 'object', thrownError);\n };\n\n Assertion.addMethod('throw', assertThrows);\n Assertion.addMethod('throws', assertThrows);\n Assertion.addMethod('Throw', assertThrows);\n\n /**\n * ### .respondTo(method)\n *\n * Asserts that the object or class target will respond to a method.\n *\n * Klass.prototype.bar = function(){};\n * expect(Klass).to.respondTo('bar');\n * expect(obj).to.respondTo('bar');\n *\n * To check if a constructor will respond to a static function,\n * set the `itself` flag.\n *\n * Klass.baz = function(){};\n * expect(Klass).itself.to.respondTo('baz');\n *\n * @name respondTo\n * @alias respondsTo\n * @param {String} method\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function respondTo (method, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , itself = flag(this, 'itself')\n , context = ('function' === _.type(obj) && !itself)\n ? obj.prototype[method]\n : obj[method];\n\n this.assert(\n 'function' === typeof context\n , 'expected #{this} to respond to ' + _.inspect(method)\n , 'expected #{this} to not respond to ' + _.inspect(method)\n );\n }\n\n Assertion.addMethod('respondTo', respondTo);\n Assertion.addMethod('respondsTo', respondTo);\n\n /**\n * ### .itself\n *\n * Sets the `itself` flag, later used by the `respondTo` assertion.\n *\n * function Foo() {}\n * Foo.bar = function() {}\n * Foo.prototype.baz = function() {}\n *\n * expect(Foo).itself.to.respondTo('bar');\n * expect(Foo).itself.not.to.respondTo('baz');\n *\n * @name itself\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('itself', function () {\n flag(this, 'itself', true);\n });\n\n /**\n * ### .satisfy(method)\n *\n * Asserts that the target passes a given truth test.\n *\n * expect(1).to.satisfy(function(num) { return num > 0; });\n *\n * @name satisfy\n * @alias satisfies\n * @param {Function} matcher\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function satisfy (matcher, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var result = matcher(obj);\n this.assert(\n result\n , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n , this.negate ? false : true\n , result\n );\n }\n\n Assertion.addMethod('satisfy', satisfy);\n Assertion.addMethod('satisfies', satisfy);\n\n /**\n * ### .closeTo(expected, delta)\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * expect(1.5).to.be.closeTo(1, 0.5);\n *\n * @name closeTo\n * @alias approximately\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function closeTo(expected, delta, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj, msg).is.a('number');\n if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n throw new Error('the arguments to closeTo or approximately must be numbers');\n }\n\n this.assert(\n Math.abs(obj - expected) <= delta\n , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n );\n }\n\n Assertion.addMethod('closeTo', closeTo);\n Assertion.addMethod('approximately', closeTo);\n\n function isSubsetOf(subset, superset, cmp) {\n return subset.every(function(elem) {\n if (!cmp) return superset.indexOf(elem) !== -1;\n\n return superset.some(function(elem2) {\n return cmp(elem, elem2);\n });\n })\n }\n\n /**\n * ### .members(set)\n *\n * Asserts that the target is a superset of `set`,\n * or that the target and `set` have the same strictly-equal (===) members.\n * Alternately, if the `deep` flag is set, set members are compared for deep\n * equality.\n *\n * expect([1, 2, 3]).to.include.members([3, 2]);\n * expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n *\n * expect([4, 2]).to.have.members([2, 4]);\n * expect([5, 2]).to.not.have.members([5, 2, 1]);\n *\n * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n *\n * @name members\n * @param {Array} set\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('members', function (subset, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj).to.be.an('array');\n new Assertion(subset).to.be.an('array');\n\n var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n if (flag(this, 'contains')) {\n return this.assert(\n isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to be a superset of #{act}'\n , 'expected #{this} to not be a superset of #{act}'\n , obj\n , subset\n );\n }\n\n this.assert(\n isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to have the same members as #{act}'\n , 'expected #{this} to not have the same members as #{act}'\n , obj\n , subset\n );\n });\n\n /**\n * ### .oneOf(list)\n *\n * Assert that a value appears somewhere in the top level of array `list`.\n *\n * expect('a').to.be.oneOf(['a', 'b', 'c']);\n * expect(9).to.not.be.oneOf(['z']);\n * expect([3]).to.not.be.oneOf([1, 2, [3]]);\n *\n * var three = [3];\n * // for object-types, contents are not compared\n * expect(three).to.not.be.oneOf([1, 2, [3]]);\n * // comparing references works\n * expect(three).to.be.oneOf([1, 2, three]);\n *\n * @name oneOf\n * @param {Array<*>} list\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function oneOf (list, msg) {\n if (msg) flag(this, 'message', msg);\n var expected = flag(this, 'object');\n new Assertion(list).to.be.an('array');\n\n this.assert(\n list.indexOf(expected) > -1\n , 'expected #{this} to be one of #{exp}'\n , 'expected #{this} to not be one of #{exp}'\n , list\n , expected\n );\n }\n\n Assertion.addMethod('oneOf', oneOf);\n\n\n /**\n * ### .change(function)\n *\n * Asserts that a function changes an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val += 3 };\n * var noChangeFn = function() { return 'foo' + 'bar'; }\n * expect(fn).to.change(obj, 'val');\n * expect(noChangeFn).to.not.change(obj, 'val')\n *\n * @name change\n * @alias changes\n * @alias Change\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertChanges (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n initial !== object[prop]\n , 'expected .' + prop + ' to change'\n , 'expected .' + prop + ' to not change'\n );\n }\n\n Assertion.addChainableMethod('change', assertChanges);\n Assertion.addChainableMethod('changes', assertChanges);\n\n /**\n * ### .increase(function)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * expect(fn).to.increase(obj, 'val');\n *\n * @name increase\n * @alias increases\n * @alias Increase\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertIncreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial > 0\n , 'expected .' + prop + ' to increase'\n , 'expected .' + prop + ' to not increase'\n );\n }\n\n Assertion.addChainableMethod('increase', assertIncreases);\n Assertion.addChainableMethod('increases', assertIncreases);\n\n /**\n * ### .decrease(function)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * expect(fn).to.decrease(obj, 'val');\n *\n * @name decrease\n * @alias decreases\n * @alias Decrease\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertDecreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial < 0\n , 'expected .' + prop + ' to decrease'\n , 'expected .' + prop + ' to not decrease'\n );\n }\n\n Assertion.addChainableMethod('decrease', assertDecreases);\n Assertion.addChainableMethod('decreases', assertDecreases);\n\n /**\n * ### .extensible\n *\n * Asserts that the target is extensible (can have new properties added to\n * it).\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect({}).to.be.extensible;\n * expect(nonExtensibleObject).to.not.be.extensible;\n * expect(sealedObject).to.not.be.extensible;\n * expect(frozenObject).to.not.be.extensible;\n *\n * @name extensible\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('extensible', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isExtensible;\n\n try {\n isExtensible = Object.isExtensible(obj);\n } catch (err) {\n if (err instanceof TypeError) isExtensible = false;\n else throw err;\n }\n\n this.assert(\n isExtensible\n , 'expected #{this} to be extensible'\n , 'expected #{this} to not be extensible'\n );\n });\n\n /**\n * ### .sealed\n *\n * Asserts that the target is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect(sealedObject).to.be.sealed;\n * expect(frozenObject).to.be.sealed;\n * expect({}).to.not.be.sealed;\n *\n * @name sealed\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('sealed', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isSealed;\n\n try {\n isSealed = Object.isSealed(obj);\n } catch (err) {\n if (err instanceof TypeError) isSealed = true;\n else throw err;\n }\n\n this.assert(\n isSealed\n , 'expected #{this} to be sealed'\n , 'expected #{this} to not be sealed'\n );\n });\n\n /**\n * ### .frozen\n *\n * Asserts that the target is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n *\n * expect(frozenObject).to.be.frozen;\n * expect({}).to.not.be.frozen;\n *\n * @name frozen\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('frozen', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isFrozen;\n\n try {\n isFrozen = Object.isFrozen(obj);\n } catch (err) {\n if (err instanceof TypeError) isFrozen = true;\n else throw err;\n }\n\n this.assert(\n isFrozen\n , 'expected #{this} to be frozen'\n , 'expected #{this} to not be frozen'\n );\n });\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n /*!\n * Chai dependencies.\n */\n\n var Assertion = chai.Assertion\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n /**\n * ### assert(expression, message)\n *\n * Write your own test expressions.\n *\n * assert('foo' !== 'bar', 'foo is not bar');\n * assert(Array.isArray([]), 'empty arrays are arrays');\n *\n * @param {Mixed} expression to test for truthiness\n * @param {String} message to display on error\n * @name assert\n * @namespace Assert\n * @api public\n */\n\n var assert = chai.assert = function (express, errmsg) {\n var test = new Assertion(null, null, chai.assert);\n test.assert(\n express\n , errmsg\n , '[ negation message unavailable ]'\n );\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure. Node.js `assert` module-compatible.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Assert\n * @api public\n */\n\n assert.fail = function (actual, expected, message, operator) {\n message = message || 'assert.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, assert.fail);\n };\n\n /**\n * ### .isOk(object, [message])\n *\n * Asserts that `object` is truthy.\n *\n * assert.isOk('everything', 'everything is ok');\n * assert.isOk(false, 'this will fail');\n *\n * @name isOk\n * @alias ok\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isOk = function (val, msg) {\n new Assertion(val, msg).is.ok;\n };\n\n /**\n * ### .isNotOk(object, [message])\n *\n * Asserts that `object` is falsy.\n *\n * assert.isNotOk('everything', 'this will fail');\n * assert.isNotOk(false, 'this will pass');\n *\n * @name isNotOk\n * @alias notOk\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotOk = function (val, msg) {\n new Assertion(val, msg).is.not.ok;\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * assert.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.equal = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.equal);\n\n test.assert(\n exp == flag(test, 'object')\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .notEqual(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * assert.notEqual(3, 4, 'these numbers are not equal');\n *\n * @name notEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notEqual = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.notEqual);\n\n test.assert(\n exp != flag(test, 'object')\n , 'expected #{this} to not equal #{exp}'\n , 'expected #{this} to equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .strictEqual(actual, expected, [message])\n *\n * Asserts strict equality (`===`) of `actual` and `expected`.\n *\n * assert.strictEqual(true, true, 'these booleans are strictly equal');\n *\n * @name strictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.strictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.equal(exp);\n };\n\n /**\n * ### .notStrictEqual(actual, expected, [message])\n *\n * Asserts strict inequality (`!==`) of `actual` and `expected`.\n *\n * assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n *\n * @name notStrictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notStrictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.equal(exp);\n };\n\n /**\n * ### .deepEqual(actual, expected, [message])\n *\n * Asserts that `actual` is deeply equal to `expected`.\n *\n * assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n *\n * @name deepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.eql(exp);\n };\n\n /**\n * ### .notDeepEqual(actual, expected, [message])\n *\n * Assert that `actual` is not deeply equal to `expected`.\n *\n * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n *\n * @name notDeepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.eql(exp);\n };\n\n /**\n * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n *\n * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n *\n * assert.isAbove(5, 2, '5 is strictly greater than 2');\n *\n * @name isAbove\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAbove\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAbove = function (val, abv, msg) {\n new Assertion(val, msg).to.be.above(abv);\n };\n\n /**\n * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n *\n * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n *\n * assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n * assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n *\n * @name isAtLeast\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtLeast\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtLeast = function (val, atlst, msg) {\n new Assertion(val, msg).to.be.least(atlst);\n };\n\n /**\n * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n *\n * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n *\n * assert.isBelow(3, 6, '3 is strictly less than 6');\n *\n * @name isBelow\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeBelow\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBelow = function (val, blw, msg) {\n new Assertion(val, msg).to.be.below(blw);\n };\n\n /**\n * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n *\n * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n *\n * assert.isAtMost(3, 6, '3 is less than or equal to 6');\n * assert.isAtMost(4, 4, '4 is less than or equal to 4');\n *\n * @name isAtMost\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtMost\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtMost = function (val, atmst, msg) {\n new Assertion(val, msg).to.be.most(atmst);\n };\n\n /**\n * ### .isTrue(value, [message])\n *\n * Asserts that `value` is true.\n *\n * var teaServed = true;\n * assert.isTrue(teaServed, 'the tea has been served');\n *\n * @name isTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isTrue = function (val, msg) {\n new Assertion(val, msg).is['true'];\n };\n\n /**\n * ### .isNotTrue(value, [message])\n *\n * Asserts that `value` is not true.\n *\n * var tea = 'tasty chai';\n * assert.isNotTrue(tea, 'great, time for tea!');\n *\n * @name isNotTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotTrue = function (val, msg) {\n new Assertion(val, msg).to.not.equal(true);\n };\n\n /**\n * ### .isFalse(value, [message])\n *\n * Asserts that `value` is false.\n *\n * var teaServed = false;\n * assert.isFalse(teaServed, 'no tea yet? hmm...');\n *\n * @name isFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFalse = function (val, msg) {\n new Assertion(val, msg).is['false'];\n };\n\n /**\n * ### .isNotFalse(value, [message])\n *\n * Asserts that `value` is not false.\n *\n * var tea = 'tasty chai';\n * assert.isNotFalse(tea, 'great, time for tea!');\n *\n * @name isNotFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFalse = function (val, msg) {\n new Assertion(val, msg).to.not.equal(false);\n };\n\n /**\n * ### .isNull(value, [message])\n *\n * Asserts that `value` is null.\n *\n * assert.isNull(err, 'there was no error');\n *\n * @name isNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNull = function (val, msg) {\n new Assertion(val, msg).to.equal(null);\n };\n\n /**\n * ### .isNotNull(value, [message])\n *\n * Asserts that `value` is not null.\n *\n * var tea = 'tasty chai';\n * assert.isNotNull(tea, 'great, time for tea!');\n *\n * @name isNotNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNull = function (val, msg) {\n new Assertion(val, msg).to.not.equal(null);\n };\n\n /**\n * ### .isNaN\n * Asserts that value is NaN\n *\n * assert.isNaN('foo', 'foo is NaN');\n *\n * @name isNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNaN = function (val, msg) {\n new Assertion(val, msg).to.be.NaN;\n };\n\n /**\n * ### .isNotNaN\n * Asserts that value is not NaN\n *\n * assert.isNotNaN(4, '4 is not NaN');\n *\n * @name isNotNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n assert.isNotNaN = function (val, msg) {\n new Assertion(val, msg).not.to.be.NaN;\n };\n\n /**\n * ### .isUndefined(value, [message])\n *\n * Asserts that `value` is `undefined`.\n *\n * var tea;\n * assert.isUndefined(tea, 'no tea defined');\n *\n * @name isUndefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isUndefined = function (val, msg) {\n new Assertion(val, msg).to.equal(undefined);\n };\n\n /**\n * ### .isDefined(value, [message])\n *\n * Asserts that `value` is not `undefined`.\n *\n * var tea = 'cup of chai';\n * assert.isDefined(tea, 'tea has been defined');\n *\n * @name isDefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isDefined = function (val, msg) {\n new Assertion(val, msg).to.not.equal(undefined);\n };\n\n /**\n * ### .isFunction(value, [message])\n *\n * Asserts that `value` is a function.\n *\n * function serveTea() { return 'cup of tea'; };\n * assert.isFunction(serveTea, 'great, we can have tea now');\n *\n * @name isFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFunction = function (val, msg) {\n new Assertion(val, msg).to.be.a('function');\n };\n\n /**\n * ### .isNotFunction(value, [message])\n *\n * Asserts that `value` is _not_ a function.\n *\n * var serveTea = [ 'heat', 'pour', 'sip' ];\n * assert.isNotFunction(serveTea, 'great, we have listed the steps');\n *\n * @name isNotFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFunction = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('function');\n };\n\n /**\n * ### .isObject(value, [message])\n *\n * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n * _The assertion does not match subclassed objects._\n *\n * var selection = { name: 'Chai', serve: 'with spices' };\n * assert.isObject(selection, 'tea selection is an object');\n *\n * @name isObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isObject = function (val, msg) {\n new Assertion(val, msg).to.be.a('object');\n };\n\n /**\n * ### .isNotObject(value, [message])\n *\n * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n *\n * var selection = 'chai'\n * assert.isNotObject(selection, 'tea selection is not an object');\n * assert.isNotObject(null, 'null is not an object');\n *\n * @name isNotObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotObject = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('object');\n };\n\n /**\n * ### .isArray(value, [message])\n *\n * Asserts that `value` is an array.\n *\n * var menu = [ 'green', 'chai', 'oolong' ];\n * assert.isArray(menu, 'what kind of tea do we want?');\n *\n * @name isArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isArray = function (val, msg) {\n new Assertion(val, msg).to.be.an('array');\n };\n\n /**\n * ### .isNotArray(value, [message])\n *\n * Asserts that `value` is _not_ an array.\n *\n * var menu = 'green|chai|oolong';\n * assert.isNotArray(menu, 'what kind of tea do we want?');\n *\n * @name isNotArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotArray = function (val, msg) {\n new Assertion(val, msg).to.not.be.an('array');\n };\n\n /**\n * ### .isString(value, [message])\n *\n * Asserts that `value` is a string.\n *\n * var teaOrder = 'chai';\n * assert.isString(teaOrder, 'order placed');\n *\n * @name isString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isString = function (val, msg) {\n new Assertion(val, msg).to.be.a('string');\n };\n\n /**\n * ### .isNotString(value, [message])\n *\n * Asserts that `value` is _not_ a string.\n *\n * var teaOrder = 4;\n * assert.isNotString(teaOrder, 'order placed');\n *\n * @name isNotString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotString = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('string');\n };\n\n /**\n * ### .isNumber(value, [message])\n *\n * Asserts that `value` is a number.\n *\n * var cups = 2;\n * assert.isNumber(cups, 'how many cups');\n *\n * @name isNumber\n * @param {Number} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNumber = function (val, msg) {\n new Assertion(val, msg).to.be.a('number');\n };\n\n /**\n * ### .isNotNumber(value, [message])\n *\n * Asserts that `value` is _not_ a number.\n *\n * var cups = '2 cups please';\n * assert.isNotNumber(cups, 'how many cups');\n *\n * @name isNotNumber\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNumber = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('number');\n };\n\n /**\n * ### .isBoolean(value, [message])\n *\n * Asserts that `value` is a boolean.\n *\n * var teaReady = true\n * , teaServed = false;\n *\n * assert.isBoolean(teaReady, 'is the tea ready');\n * assert.isBoolean(teaServed, 'has tea been served');\n *\n * @name isBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBoolean = function (val, msg) {\n new Assertion(val, msg).to.be.a('boolean');\n };\n\n /**\n * ### .isNotBoolean(value, [message])\n *\n * Asserts that `value` is _not_ a boolean.\n *\n * var teaReady = 'yep'\n * , teaServed = 'nope';\n *\n * assert.isNotBoolean(teaReady, 'is the tea ready');\n * assert.isNotBoolean(teaServed, 'has tea been served');\n *\n * @name isNotBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotBoolean = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('boolean');\n };\n\n /**\n * ### .typeOf(value, name, [message])\n *\n * Asserts that `value`'s type is `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n * assert.typeOf('tea', 'string', 'we have a string');\n * assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n * assert.typeOf(null, 'null', 'we have a null');\n * assert.typeOf(undefined, 'undefined', 'we have an undefined');\n *\n * @name typeOf\n * @param {Mixed} value\n * @param {String} name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.typeOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.a(type);\n };\n\n /**\n * ### .notTypeOf(value, name, [message])\n *\n * Asserts that `value`'s type is _not_ `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.notTypeOf('tea', 'number', 'strings are not numbers');\n *\n * @name notTypeOf\n * @param {Mixed} value\n * @param {String} typeof name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notTypeOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.a(type);\n };\n\n /**\n * ### .instanceOf(object, constructor, [message])\n *\n * Asserts that `value` is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new Tea('chai');\n *\n * assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n *\n * @name instanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.instanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.instanceOf(type);\n };\n\n /**\n * ### .notInstanceOf(object, constructor, [message])\n *\n * Asserts `value` is not an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new String('chai');\n *\n * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n *\n * @name notInstanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInstanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.instanceOf(type);\n };\n\n /**\n * ### .include(haystack, needle, [message])\n *\n * Asserts that `haystack` includes `needle`. Works\n * for strings and arrays.\n *\n * assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n * assert.include([ 1, 2, 3 ], 3, 'array contains value');\n *\n * @name include\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.include = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.include).include(inc);\n };\n\n /**\n * ### .notInclude(haystack, needle, [message])\n *\n * Asserts that `haystack` does not include `needle`. Works\n * for strings and arrays.\n *\n * assert.notInclude('foobar', 'baz', 'string not include substring');\n * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n *\n * @name notInclude\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInclude = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.notInclude).not.include(inc);\n };\n\n /**\n * ### .match(value, regexp, [message])\n *\n * Asserts that `value` matches the regular expression `regexp`.\n *\n * assert.match('foobar', /^foo/, 'regexp matches');\n *\n * @name match\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.match = function (exp, re, msg) {\n new Assertion(exp, msg).to.match(re);\n };\n\n /**\n * ### .notMatch(value, regexp, [message])\n *\n * Asserts that `value` does not match the regular expression `regexp`.\n *\n * assert.notMatch('foobar', /^foo/, 'regexp does not match');\n *\n * @name notMatch\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notMatch = function (exp, re, msg) {\n new Assertion(exp, msg).to.not.match(re);\n };\n\n /**\n * ### .property(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`.\n *\n * assert.property({ tea: { green: 'matcha' }}, 'tea');\n *\n * @name property\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.property = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.property(prop);\n };\n\n /**\n * ### .notProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`.\n *\n * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n *\n * @name notProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.property(prop);\n };\n\n /**\n * ### .deepProperty(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`, which can be a\n * string using dot- and bracket-notation for deep reference.\n *\n * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n *\n * @name deepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop);\n };\n\n /**\n * ### .notDeepProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`, which\n * can be a string using dot- and bracket-notation for deep reference.\n *\n * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n *\n * @name notDeepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop);\n };\n\n /**\n * ### .propertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`.\n *\n * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n *\n * @name propertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.property(prop, val);\n };\n\n /**\n * ### .propertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`.\n *\n * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n *\n * @name propertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.property(prop, val);\n };\n\n /**\n * ### .deepPropertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`. `property` can use dot- and bracket-notation for deep\n * reference.\n *\n * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n *\n * @name deepPropertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop, val);\n };\n\n /**\n * ### .deepPropertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`. `property` can use dot- and\n * bracket-notation for deep reference.\n *\n * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n *\n * @name deepPropertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n };\n\n /**\n * ### .lengthOf(object, length, [message])\n *\n * Asserts that `object` has a `length` property with the expected value.\n *\n * assert.lengthOf([1,2,3], 3, 'array has length of 3');\n * assert.lengthOf('foobar', 6, 'string has length of 6');\n *\n * @name lengthOf\n * @param {Mixed} object\n * @param {Number} length\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.lengthOf = function (exp, len, msg) {\n new Assertion(exp, msg).to.have.length(len);\n };\n\n /**\n * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * assert.throws(fn, 'function throws a reference error');\n * assert.throws(fn, /function throws a reference error/);\n * assert.throws(fn, ReferenceError);\n * assert.throws(fn, ReferenceError, 'function throws a reference error');\n * assert.throws(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throws\n * @alias throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.throws = function (fn, errt, errs, msg) {\n if ('string' === typeof errt || errt instanceof RegExp) {\n errs = errt;\n errt = null;\n }\n\n var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n return flag(assertErr, 'object');\n };\n\n /**\n * ### .doesNotThrow(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * assert.doesNotThrow(fn, Error, 'function does not throw');\n *\n * @name doesNotThrow\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotThrow = function (fn, type, msg) {\n if ('string' === typeof type) {\n msg = type;\n type = null;\n }\n\n new Assertion(fn, msg).to.not.Throw(type);\n };\n\n /**\n * ### .operator(val1, operator, val2, [message])\n *\n * Compares two values using `operator`.\n *\n * assert.operator(1, '<', 2, 'everything is ok');\n * assert.operator(1, '>', 2, 'this will fail');\n *\n * @name operator\n * @param {Mixed} val1\n * @param {String} operator\n * @param {Mixed} val2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.operator = function (val, operator, val2, msg) {\n var ok;\n switch(operator) {\n case '==':\n ok = val == val2;\n break;\n case '===':\n ok = val === val2;\n break;\n case '>':\n ok = val > val2;\n break;\n case '>=':\n ok = val >= val2;\n break;\n case '<':\n ok = val < val2;\n break;\n case '<=':\n ok = val <= val2;\n break;\n case '!=':\n ok = val != val2;\n break;\n case '!==':\n ok = val !== val2;\n break;\n default:\n throw new Error('Invalid operator \"' + operator + '\"');\n }\n var test = new Assertion(ok, msg);\n test.assert(\n true === flag(test, 'object')\n , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n };\n\n /**\n * ### .closeTo(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n *\n * @name closeTo\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.closeTo = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.closeTo(exp, delta);\n };\n\n /**\n * ### .approximately(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.approximately(1.5, 1, 0.5, 'numbers are close');\n *\n * @name approximately\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.approximately = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.approximately(exp, delta);\n };\n\n /**\n * ### .sameMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members.\n * Order is not taken into account.\n *\n * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n *\n * @name sameMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.members(set2);\n }\n\n /**\n * ### .sameDeepMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n * Order is not taken into account.\n *\n * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n *\n * @name sameDeepMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameDeepMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.deep.members(set2);\n }\n\n /**\n * ### .includeMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset`.\n * Order is not taken into account.\n *\n * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n *\n * @name includeMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.members(subset);\n }\n\n /**\n * ### .includeDeepMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset` - using deep equality checking.\n * Order is not taken into account.\n * Duplicates are ignored.\n *\n * assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n *\n * @name includeDeepMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeDeepMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.deep.members(subset);\n }\n\n /**\n * ### .oneOf(inList, list, [message])\n *\n * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n *\n * assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n *\n * @name oneOf\n * @param {*} inList\n * @param {Array<*>} list\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.oneOf = function (inList, list, msg) {\n new Assertion(inList, msg).to.be.oneOf(list);\n }\n\n /**\n * ### .changes(function, object, property)\n *\n * Asserts that a function changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 22 };\n * assert.changes(fn, obj, 'val');\n *\n * @name changes\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.changes = function (fn, obj, prop) {\n new Assertion(fn).to.change(obj, prop);\n }\n\n /**\n * ### .doesNotChange(function, object, property)\n *\n * Asserts that a function does not changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { console.log('foo'); };\n * assert.doesNotChange(fn, obj, 'val');\n *\n * @name doesNotChange\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotChange = function (fn, obj, prop) {\n new Assertion(fn).to.not.change(obj, prop);\n }\n\n /**\n * ### .increases(function, object, property)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 13 };\n * assert.increases(fn, obj, 'val');\n *\n * @name increases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.increases = function (fn, obj, prop) {\n new Assertion(fn).to.increase(obj, prop);\n }\n\n /**\n * ### .doesNotIncrease(function, object, property)\n *\n * Asserts that a function does not increase object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 8 };\n * assert.doesNotIncrease(fn, obj, 'val');\n *\n * @name doesNotIncrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotIncrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.increase(obj, prop);\n }\n\n /**\n * ### .decreases(function, object, property)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * assert.decreases(fn, obj, 'val');\n *\n * @name decreases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.decreases = function (fn, obj, prop) {\n new Assertion(fn).to.decrease(obj, prop);\n }\n\n /**\n * ### .doesNotDecrease(function, object, property)\n *\n * Asserts that a function does not decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * assert.doesNotDecrease(fn, obj, 'val');\n *\n * @name doesNotDecrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotDecrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.decrease(obj, prop);\n }\n\n /*!\n * ### .ifError(object)\n *\n * Asserts if value is not a false value, and throws if it is a true value.\n * This is added to allow for chai to be a drop-in replacement for Node's\n * assert class.\n *\n * var err = new Error('I am a custom error');\n * assert.ifError(err); // Rethrows err!\n *\n * @name ifError\n * @param {Object} object\n * @namespace Assert\n * @api public\n */\n\n assert.ifError = function (val) {\n if (val) {\n throw(val);\n }\n };\n\n /**\n * ### .isExtensible(object)\n *\n * Asserts that `object` is extensible (can have new properties added to it).\n *\n * assert.isExtensible({});\n *\n * @name isExtensible\n * @alias extensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.be.extensible;\n };\n\n /**\n * ### .isNotExtensible(object)\n *\n * Asserts that `object` is _not_ extensible.\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freese({});\n *\n * assert.isNotExtensible(nonExtensibleObject);\n * assert.isNotExtensible(sealedObject);\n * assert.isNotExtensible(frozenObject);\n *\n * @name isNotExtensible\n * @alias notExtensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.extensible;\n };\n\n /**\n * ### .isSealed(object)\n *\n * Asserts that `object` is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.seal({});\n *\n * assert.isSealed(sealedObject);\n * assert.isSealed(frozenObject);\n *\n * @name isSealed\n * @alias sealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isSealed = function (obj, msg) {\n new Assertion(obj, msg).to.be.sealed;\n };\n\n /**\n * ### .isNotSealed(object)\n *\n * Asserts that `object` is _not_ sealed.\n *\n * assert.isNotSealed({});\n *\n * @name isNotSealed\n * @alias notSealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotSealed = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.sealed;\n };\n\n /**\n * ### .isFrozen(object)\n *\n * Asserts that `object` is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n * assert.frozen(frozenObject);\n *\n * @name isFrozen\n * @alias frozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.be.frozen;\n };\n\n /**\n * ### .isNotFrozen(object)\n *\n * Asserts that `object` is _not_ frozen.\n *\n * assert.isNotFrozen({});\n *\n * @name isNotFrozen\n * @alias notFrozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.frozen;\n };\n\n /*!\n * Aliases.\n */\n\n (function alias(name, as){\n assert[as] = assert[name];\n return alias;\n })\n ('isOk', 'ok')\n ('isNotOk', 'notOk')\n ('throws', 'throw')\n ('throws', 'Throw')\n ('isExtensible', 'extensible')\n ('isNotExtensible', 'notExtensible')\n ('isSealed', 'sealed')\n ('isNotSealed', 'notSealed')\n ('isFrozen', 'frozen')\n ('isNotFrozen', 'notFrozen');\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n chai.expect = function (val, message) {\n return new chai.Assertion(val, message);\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Expect\n * @api public\n */\n\n chai.expect.fail = function (actual, expected, message, operator) {\n message = message || 'expect.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, chai.expect.fail);\n };\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n var Assertion = chai.Assertion;\n\n function loadShould () {\n // explicitly define this method as function as to have it's name to include as `ssfi`\n function shouldGetter() {\n if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n return new Assertion(this.valueOf(), null, shouldGetter);\n }\n return new Assertion(this, null, shouldGetter);\n }\n function shouldSetter(value) {\n // See https://github.com/chaijs/chai/issues/86: this makes\n // `whatever.should = someValue` actually set `someValue`, which is\n // especially useful for `global.should = require('chai').should()`.\n //\n // Note that we have to use [[DefineProperty]] instead of [[Put]]\n // since otherwise we would trigger this very setter!\n Object.defineProperty(this, 'should', {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n }\n // modify Object.prototype to have `should`\n Object.defineProperty(Object.prototype, 'should', {\n set: shouldSetter\n , get: shouldGetter\n , configurable: true\n });\n\n var should = {};\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Should\n * @api public\n */\n\n should.fail = function (actual, expected, message, operator) {\n message = message || 'should.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, should.fail);\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * should.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * should.throw(fn, 'function throws a reference error');\n * should.throw(fn, /function throws a reference error/);\n * should.throw(fn, ReferenceError);\n * should.throw(fn, ReferenceError, 'function throws a reference error');\n * should.throw(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.Throw(errt, errs);\n };\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi';\n *\n * should.exist(foo, 'foo exists');\n *\n * @name exist\n * @namespace Should\n * @api public\n */\n\n should.exist = function (val, msg) {\n new Assertion(val, msg).to.exist;\n }\n\n // negation\n should.not = {}\n\n /**\n * ### .not.equal(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * should.not.equal(3, 4, 'these numbers are not equal');\n *\n * @name not.equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.not.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.not.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * should.not.throw(fn, Error, 'function does not throw');\n *\n * @name not.throw\n * @alias not.Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.not.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.not.Throw(errt, errs);\n };\n\n /**\n * ### .not.exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var bar = null;\n *\n * should.not.exist(bar, 'bar does not exist');\n *\n * @name not.exist\n * @namespace Should\n * @api public\n */\n\n should.not.exist = function (val, msg) {\n new Assertion(val, msg).to.not.exist;\n }\n\n should['throw'] = should['Throw'];\n should.not['throw'] = should.not['Throw'];\n\n return should;\n };\n\n chai.should = loadShould;\n chai.Should = loadShould;\n};\n","/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call = Function.prototype.call,\n apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n * expect(fooStr).to.be.foo('bar');\n * expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n if (typeof chainingBehavior !== 'function') {\n chainingBehavior = function () { };\n }\n\n var chainableBehavior = {\n method: method\n , chainingBehavior: chainingBehavior\n };\n\n // save the methods so we can overwrite them later, if we need to.\n if (!ctx.__methods) {\n ctx.__methods = {};\n }\n ctx.__methods[name] = chainableBehavior;\n\n Object.defineProperty(ctx, name,\n { get: function () {\n chainableBehavior.chainingBehavior.call(this);\n\n var assert = function assert() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', assert);\n var result = chainableBehavior.method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n\n // Use `__proto__` if available\n if (hasProtoSupport) {\n // Inherit all properties from the object by replacing the `Function` prototype\n var prototype = assert.__proto__ = Object.create(this);\n // Restore the `call` and `apply` methods from `Function`\n prototype.call = call;\n prototype.apply = apply;\n }\n // Otherwise, redefine all properties (slow!)\n else {\n var asserterNames = Object.getOwnPropertyNames(ctx);\n asserterNames.forEach(function (asserterName) {\n if (!excludeNames.test(asserterName)) {\n var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n Object.defineProperty(assert, asserterName, pd);\n }\n });\n }\n\n transferFlags(this, assert);\n return assert;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n ctx[name] = function () {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', ctx[name]);\n var result = method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n * utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.instanceof(Foo);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n Object.defineProperty(ctx, name,\n { get: function addProperty() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', addProperty);\n\n var result = getter.call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n * utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n var obj = flag(obj, 'object');\n types = types.map(function (t) { return t.toLowerCase(); });\n types.sort();\n\n // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n var str = types.map(function (t, index) {\n var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n return or + art + ' ' + t;\n }).join(', ');\n\n if (!types.some(function (expected) { return type(obj) === expected; })) {\n throw new AssertionError(\n 'object tested must be ' + str + ', but ' + type(obj) + ' given'\n );\n }\n};\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n * utils.flag(this, 'foo', 'bar'); // setter\n * utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n var flags = obj.__flags || (obj.__flags = Object.create(null));\n if (arguments.length === 3) {\n flags[key] = value;\n } else {\n return flags[key];\n }\n};\n","/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n return args.length > 4 ? args[4] : obj._obj;\n};\n","/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n var result = [];\n for (var name in object) {\n result.push(name);\n }\n return result;\n};\n","/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n , getActual = require('./getActual')\n , inspect = require('./inspect')\n , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , val = flag(obj, 'object')\n , expected = args[3]\n , actual = getActual(obj, args)\n , msg = negate ? args[2] : args[1]\n , flagMsg = flag(obj, 'message');\n\n if(typeof msg === \"function\") msg = msg();\n msg = msg || '';\n msg = msg\n .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n","/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n if (func.name) return func.name;\n\n var match = /^\\s?function ([^(]*)\\(/.exec(func);\n return match && match[1] ? match[1] : \"\";\n};\n","/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n var parsed = parsePath(path),\n last = parsed[parsed.length - 1];\n\n var info = {\n parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n name: last.p || last.i,\n value: _getPathValue(parsed, obj)\n };\n info.exists = hasProperty(info.name, info.parent);\n\n return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n * var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n return parts.map(function (value) {\n var re = /^\\[(\\d+)\\]$/\n , mArr = re.exec(value);\n if (mArr) return { i: parseFloat(mArr[1]) };\n else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n * var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n var tmp = obj\n , res;\n\n index = (index === undefined ? parsed.length : index);\n\n for (var i = 0, l = index; i < l; i++) {\n var part = parsed[i];\n if (tmp) {\n if ('undefined' !== typeof part.p)\n tmp = tmp[part.p];\n else if ('undefined' !== typeof part.i)\n tmp = tmp[part.i];\n if (i == (l - 1)) res = tmp;\n } else {\n res = undefined;\n }\n }\n return res;\n}\n","/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer \n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n * var obj = {\n * prop1: {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n * , prop2: {\n * arr: [ { nested: 'Universe' } ]\n * , str: 'Hello again!'\n * }\n * }\n *\n * The following would be the results.\n *\n * getPathValue('prop1.str', obj); // Hello\n * getPathValue('prop1.att[2]', obj); // b\n * getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n var info = getPathInfo(path, obj);\n return info.value;\n};\n","/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n var result = Object.getOwnPropertyNames(object);\n\n function addProperty(property) {\n if (result.indexOf(property) === -1) {\n result.push(property);\n }\n }\n\n var proto = Object.getPrototypeOf(object);\n while (proto !== null) {\n Object.getOwnPropertyNames(proto).forEach(addProperty);\n proto = Object.getPrototypeOf(proto);\n }\n\n return result;\n};\n","/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n * var obj = {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n *\n * The following would be the results.\n *\n * hasProperty('str', obj); // true\n * hasProperty('constructor', obj); // true\n * hasProperty('bar', obj); // false\n *\n * hasProperty('length', obj.str); // true\n * hasProperty(1, obj.str); // true\n * hasProperty(5, obj.str); // false\n *\n * hasProperty('length', obj.arr); // true\n * hasProperty(2, obj.arr); // true\n * hasProperty(3, obj.arr); // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n 'number': Number\n , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n var ot = type(obj);\n\n // Bad Object, obviously no props at all\n if(ot === 'null' || ot === 'undefined')\n return false;\n\n // The `in` operator does not work with certain literals\n // box these before the check\n if(literals[ot] && typeof obj !== 'object')\n obj = new literals[ot](obj);\n\n return name in obj;\n};\n","/*!\n * chai\n * Copyright(c) 2011 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n","// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n * properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n * output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n var ctx = {\n showHidden: showHidden,\n seen: [],\n stylize: function (str) { return str; }\n };\n return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n if (typeof HTMLElement === 'object') {\n return object instanceof HTMLElement;\n } else {\n return object &&\n typeof object === 'object' &&\n object.nodeType === 1 &&\n typeof object.nodeName === 'string';\n }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (value && typeof value.inspect === 'function' &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes);\n if (typeof ret !== 'string') {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // If this is a DOM element, try to get the outer HTML.\n if (isDOMElement(value)) {\n if ('outerHTML' in value) {\n return value.outerHTML;\n // This value does not have an outerHTML attribute,\n // it could still be an XML element\n } else {\n // Attempt to serialize it\n try {\n if (document.xmlVersion) {\n var xmlSerializer = new XMLSerializer();\n return xmlSerializer.serializeToString(value);\n } else {\n // Firefox 11- do not support outerHTML\n // It does, however, support innerHTML\n // Use the following to render the element\n var ns = \"http://www.w3.org/1999/xhtml\";\n var container = document.createElementNS(ns, '_');\n\n container.appendChild(value.cloneNode(false));\n html = container.innerHTML\n .replace('><', '>' + value.innerHTML + '<');\n container.innerHTML = '';\n return html;\n }\n } catch (err) {\n // This could be a non-native DOM implementation,\n // continue with the normal flow:\n // printing the element as if it is an object.\n }\n }\n }\n\n // Look up the keys of the object.\n var visibleKeys = getEnumerableProperties(value);\n var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n // Some type of object without properties can be shortcutted.\n // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n // a `stack` plus `description` property; ignore those for consistency.\n if (keys.length === 0 || (isError(value) && (\n (keys.length === 1 && keys[0] === 'stack') ||\n (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n ))) {\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n base = ' [Function' + nameSuffix + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n return formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n switch (typeof value) {\n case 'undefined':\n return ctx.stylize('undefined', 'undefined');\n\n case 'string':\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n\n case 'number':\n if (value === 0 && (1/value) === -Infinity) {\n return ctx.stylize('-0', 'number');\n }\n return ctx.stylize('' + value, 'number');\n\n case 'boolean':\n return ctx.stylize('' + value, 'boolean');\n }\n // For some reason typeof null is \"object\", so special case here.\n if (value === null) {\n return ctx.stylize('null', 'null');\n }\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str;\n if (value.__lookupGetter__) {\n if (value.__lookupGetter__(key)) {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n }\n if (visibleKeys.indexOf(key) < 0) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(value[key]) < 0) {\n if (recurseTimes === null) {\n str = formatValue(ctx, value[key], null);\n } else {\n str = formatValue(ctx, value[key], recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (typeof name === 'undefined') {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n return Array.isArray(ar) ||\n (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n var str = inspect(obj)\n , type = Object.prototype.toString.call(obj);\n\n if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n if (type === '[object Function]') {\n return !obj.name || obj.name === ''\n ? '[Function]'\n : '[Function: ' + obj.name + ']';\n } else if (type === '[object Array]') {\n return '[ Array(' + obj.length + ') ]';\n } else if (type === '[object Object]') {\n var keys = Object.keys(obj)\n , kstr = keys.length > 2\n ? keys.splice(0, 2).join(', ') + ', ...'\n : keys.join(', ');\n return '{ Object (' + kstr + ') }';\n } else {\n return str;\n }\n } else {\n return str;\n }\n};\n","/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property. Must return functions to be used for\n * name.\n *\n * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n * function (_super) {\n * }\n * , function (_super) {\n * }\n * );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.have.length(3);\n * expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n var chainableBehavior = ctx.__methods[name];\n\n var _chainingBehavior = chainableBehavior.chainingBehavior;\n chainableBehavior.chainingBehavior = function () {\n var result = chainingBehavior(_chainingBehavior).call(this);\n return result === undefined ? this : result;\n };\n\n var _method = chainableBehavior.method;\n chainableBehavior.method = function () {\n var result = method(_method).apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n * return function (str) {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.value).to.equal(str);\n * } else {\n * _super.apply(this, arguments);\n * }\n * }\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n var _method = ctx[name]\n , _super = function () { return this; };\n\n if (_method && 'function' === typeof _method)\n _super = _method;\n\n ctx[name] = function () {\n var result = method(_super).apply(this, arguments);\n return result === undefined ? this : result;\n }\n};\n","/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n * return function () {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.name).to.equal('bar');\n * } else {\n * _super.call(this);\n * }\n * }\n * });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n var _get = Object.getOwnPropertyDescriptor(ctx, name)\n , _super = function () {};\n\n if (_get && 'function' === typeof _get.get)\n _super = _get.get\n\n Object.defineProperty(ctx, name,\n { get: function () {\n var result = getter(_super).call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , expr = args[0];\n return negate ? !expr : expr;\n};\n","/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n * var newAssertion = new Assertion();\n * utils.transferFlags(assertion, newAssertion);\n *\n * var anotherAsseriton = new Assertion(myObj);\n * utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n if (!object.__flags) {\n object.__flags = Object.create(null);\n }\n\n includeAll = arguments.length === 3 ? includeAll : true;\n\n for (var flag in flags) {\n if (includeAll ||\n (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n object.__flags[flag] = flags[flag];\n }\n }\n};\n","module.exports = require('./lib/eql');\n","/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n Buffer = {};\n Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n if (sameValue(a, b)) {\n return true;\n } else if ('date' === type(a)) {\n return dateEqual(a, b);\n } else if ('regexp' === type(a)) {\n return regexpEqual(a, b);\n } else if (Buffer.isBuffer(a)) {\n return bufferEqual(a, b);\n } else if ('arguments' === type(a)) {\n return argumentsEqual(a, b, m);\n } else if (!typeEqual(a, b)) {\n return false;\n } else if (('object' !== type(a) && 'object' !== type(b))\n && ('array' !== type(a) && 'array' !== type(b))) {\n return sameValue(a, b);\n } else {\n return objectEqual(a, b, m);\n }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n if (a === b) return a !== 0 || 1 / a === 1 / b;\n return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n if ('date' !== type(b)) return false;\n return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n if ('regexp' !== type(b)) return false;\n return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n if ('arguments' !== type(b)) return false;\n a = [].slice.call(a);\n b = [].slice.call(b);\n return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n var res = [];\n for (var key in a) res.push(key);\n return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n if (a.length !== b.length) return false;\n\n var i = 0;\n var match = true;\n\n for (; i < a.length; i++) {\n if (a[i] !== b[i]) {\n match = false;\n break;\n }\n }\n\n return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n if (!Buffer.isBuffer(b)) return false;\n return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n if (!isValue(a) || !isValue(b)) {\n return false;\n }\n\n if (a.prototype !== b.prototype) {\n return false;\n }\n\n var i;\n if (m) {\n for (i = 0; i < m.length; i++) {\n if ((m[i][0] === a && m[i][1] === b)\n || (m[i][0] === b && m[i][1] === a)) {\n return true;\n }\n }\n } else {\n m = [];\n }\n\n try {\n var ka = enumerable(a);\n var kb = enumerable(b);\n } catch (ex) {\n return false;\n }\n\n ka.sort();\n kb.sort();\n\n if (!iterableEqual(ka, kb)) {\n return false;\n }\n\n m.push([ a, b ]);\n\n var key;\n for (i = ka.length - 1; i >= 0; i--) {\n key = ka[i];\n if (!deepEqual(a[key], b[key], m)) {\n return false;\n }\n }\n\n return true;\n}\n","module.exports = require('./lib/type');\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n '[object Array]': 'array'\n , '[object RegExp]': 'regexp'\n , '[object Function]': 'function'\n , '[object Arguments]': 'arguments'\n , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n var str = Object.prototype.toString.call(obj);\n if (natives[str]) return natives[str];\n if (obj === null) return 'null';\n if (obj === undefined) return 'undefined';\n if (obj === Object(obj)) return 'object';\n return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","/*!\n localForage -- Offline Storage, Improved\n Version 1.5.0\n https://localforage.github.io/localForage\n (c) 2013-2017 Mozilla, Apache License 2.0\n*/\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.localforage = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw (f.code=\"MODULE_NOT_FOUND\", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o element; its readystatechange event will be fired asynchronously once it is inserted\n // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.\n var scriptEl = global.document.createElement('script');\n scriptEl.onreadystatechange = function () {\n nextTick();\n\n scriptEl.onreadystatechange = null;\n scriptEl.parentNode.removeChild(scriptEl);\n scriptEl = null;\n };\n global.document.documentElement.appendChild(scriptEl);\n };\n } else {\n scheduleDrain = function () {\n setTimeout(nextTick, 0);\n };\n }\n}\n\nvar draining;\nvar queue = [];\n//named nextTick for less confusing stack traces\nfunction nextTick() {\n draining = true;\n var i, oldQueue;\n var len = queue.length;\n while (len) {\n oldQueue = queue;\n queue = [];\n i = -1;\n while (++i < len) {\n oldQueue[i]();\n }\n len = queue.length;\n }\n draining = false;\n}\n\nmodule.exports = immediate;\nfunction immediate(task) {\n if (queue.push(task) === 1 && !draining) {\n scheduleDrain();\n }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],2:[function(_dereq_,module,exports){\n'use strict';\nvar immediate = _dereq_(1);\n\n/* istanbul ignore next */\nfunction INTERNAL() {}\n\nvar handlers = {};\n\nvar REJECTED = ['REJECTED'];\nvar FULFILLED = ['FULFILLED'];\nvar PENDING = ['PENDING'];\n\nmodule.exports = exports = Promise;\n\nfunction Promise(resolver) {\n if (typeof resolver !== 'function') {\n throw new TypeError('resolver must be a function');\n }\n this.state = PENDING;\n this.queue = [];\n this.outcome = void 0;\n if (resolver !== INTERNAL) {\n safelyResolveThenable(this, resolver);\n }\n}\n\nPromise.prototype[\"catch\"] = function (onRejected) {\n return this.then(null, onRejected);\n};\nPromise.prototype.then = function (onFulfilled, onRejected) {\n if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||\n typeof onRejected !== 'function' && this.state === REJECTED) {\n return this;\n }\n var promise = new this.constructor(INTERNAL);\n if (this.state !== PENDING) {\n var resolver = this.state === FULFILLED ? onFulfilled : onRejected;\n unwrap(promise, resolver, this.outcome);\n } else {\n this.queue.push(new QueueItem(promise, onFulfilled, onRejected));\n }\n\n return promise;\n};\nfunction QueueItem(promise, onFulfilled, onRejected) {\n this.promise = promise;\n if (typeof onFulfilled === 'function') {\n this.onFulfilled = onFulfilled;\n this.callFulfilled = this.otherCallFulfilled;\n }\n if (typeof onRejected === 'function') {\n this.onRejected = onRejected;\n this.callRejected = this.otherCallRejected;\n }\n}\nQueueItem.prototype.callFulfilled = function (value) {\n handlers.resolve(this.promise, value);\n};\nQueueItem.prototype.otherCallFulfilled = function (value) {\n unwrap(this.promise, this.onFulfilled, value);\n};\nQueueItem.prototype.callRejected = function (value) {\n handlers.reject(this.promise, value);\n};\nQueueItem.prototype.otherCallRejected = function (value) {\n unwrap(this.promise, this.onRejected, value);\n};\n\nfunction unwrap(promise, func, value) {\n immediate(function () {\n var returnValue;\n try {\n returnValue = func(value);\n } catch (e) {\n return handlers.reject(promise, e);\n }\n if (returnValue === promise) {\n handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));\n } else {\n handlers.resolve(promise, returnValue);\n }\n });\n}\n\nhandlers.resolve = function (self, value) {\n var result = tryCatch(getThen, value);\n if (result.status === 'error') {\n return handlers.reject(self, result.value);\n }\n var thenable = result.value;\n\n if (thenable) {\n safelyResolveThenable(self, thenable);\n } else {\n self.state = FULFILLED;\n self.outcome = value;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callFulfilled(value);\n }\n }\n return self;\n};\nhandlers.reject = function (self, error) {\n self.state = REJECTED;\n self.outcome = error;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callRejected(error);\n }\n return self;\n};\n\nfunction getThen(obj) {\n // Make sure we only access the accessor once as required by the spec\n var then = obj && obj.then;\n if (obj && typeof obj === 'object' && typeof then === 'function') {\n return function appyThen() {\n then.apply(obj, arguments);\n };\n }\n}\n\nfunction safelyResolveThenable(self, thenable) {\n // Either fulfill, reject or reject with error\n var called = false;\n function onError(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.reject(self, value);\n }\n\n function onSuccess(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.resolve(self, value);\n }\n\n function tryToUnwrap() {\n thenable(onSuccess, onError);\n }\n\n var result = tryCatch(tryToUnwrap);\n if (result.status === 'error') {\n onError(result.value);\n }\n}\n\nfunction tryCatch(func, value) {\n var out = {};\n try {\n out.value = func(value);\n out.status = 'success';\n } catch (e) {\n out.status = 'error';\n out.value = e;\n }\n return out;\n}\n\nexports.resolve = resolve;\nfunction resolve(value) {\n if (value instanceof this) {\n return value;\n }\n return handlers.resolve(new this(INTERNAL), value);\n}\n\nexports.reject = reject;\nfunction reject(reason) {\n var promise = new this(INTERNAL);\n return handlers.reject(promise, reason);\n}\n\nexports.all = all;\nfunction all(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var values = new Array(len);\n var resolved = 0;\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n allResolver(iterable[i], i);\n }\n return promise;\n function allResolver(value, i) {\n self.resolve(value).then(resolveFromAll, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n function resolveFromAll(outValue) {\n values[i] = outValue;\n if (++resolved === len && !called) {\n called = true;\n handlers.resolve(promise, values);\n }\n }\n }\n}\n\nexports.race = race;\nfunction race(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n resolver(iterable[i]);\n }\n return promise;\n function resolver(value) {\n self.resolve(value).then(function (response) {\n if (!called) {\n called = true;\n handlers.resolve(promise, response);\n }\n }, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n }\n}\n\n},{\"1\":1}],3:[function(_dereq_,module,exports){\n(function (global){\n'use strict';\nif (typeof global.Promise !== 'function') {\n global.Promise = _dereq_(2);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"2\":2}],4:[function(_dereq_,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction getIDB() {\n /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */\n try {\n if (typeof indexedDB !== 'undefined') {\n return indexedDB;\n }\n if (typeof webkitIndexedDB !== 'undefined') {\n return webkitIndexedDB;\n }\n if (typeof mozIndexedDB !== 'undefined') {\n return mozIndexedDB;\n }\n if (typeof OIndexedDB !== 'undefined') {\n return OIndexedDB;\n }\n if (typeof msIndexedDB !== 'undefined') {\n return msIndexedDB;\n }\n } catch (e) {}\n}\n\nvar idb = getIDB();\n\nfunction isIndexedDBValid() {\n try {\n // Initialize IndexedDB; fall back to vendor-prefixed versions\n // if needed.\n if (!idb) {\n return false;\n }\n // We mimic PouchDB here;\n //\n // We test for openDatabase because IE Mobile identifies itself\n // as Safari. Oh the lulz...\n var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform);\n\n var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1;\n\n // Safari <10.1 does not meet our requirements for IDB support (#5572)\n // since Safari 10.1 shipped with fetch, we can use that to detect it\n return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' &&\n // some outdated implementations of IDB that appear on Samsung\n // and HTC Android devices <4.4 are missing IDBKeyRange\n typeof IDBKeyRange !== 'undefined';\n } catch (e) {\n return false;\n }\n}\n\nfunction isWebSQLValid() {\n return typeof openDatabase === 'function';\n}\n\nfunction isLocalStorageValid() {\n try {\n return typeof localStorage !== 'undefined' && 'setItem' in localStorage && localStorage.setItem;\n } catch (e) {\n return false;\n }\n}\n\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\nfunction createBlob(parts, properties) {\n /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */\n parts = parts || [];\n properties = properties || {};\n try {\n return new Blob(parts, properties);\n } catch (e) {\n if (e.name !== 'TypeError') {\n throw e;\n }\n var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder;\n var builder = new Builder();\n for (var i = 0; i < parts.length; i += 1) {\n builder.append(parts[i]);\n }\n return builder.getBlob(properties.type);\n }\n}\n\n// This is CommonJS because lie is an external dependency, so Rollup\n// can just ignore it.\nif (typeof Promise === 'undefined') {\n // In the \"nopromises\" build this will just throw if you don't have\n // a global promise object, but it would throw anyway later.\n _dereq_(3);\n}\nvar Promise$1 = Promise;\n\nfunction executeCallback(promise, callback) {\n if (callback) {\n promise.then(function (result) {\n callback(null, result);\n }, function (error) {\n callback(error);\n });\n }\n}\n\nfunction executeTwoCallbacks(promise, callback, errorCallback) {\n if (typeof callback === 'function') {\n promise.then(callback);\n }\n\n if (typeof errorCallback === 'function') {\n promise[\"catch\"](errorCallback);\n }\n}\n\n// Some code originally from async_storage.js in\n// [Gaia](https://github.com/mozilla-b2g/gaia).\n\nvar DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support';\nvar supportsBlobs;\nvar dbContexts;\nvar toString = Object.prototype.toString;\n\n// Transform a binary string to an array buffer, because otherwise\n// weird stuff happens when you try to work with the binary string directly.\n// It is known.\n// From http://stackoverflow.com/questions/14967647/ (continues on next line)\n// encode-decode-image-with-base64-breaks-image (2013-04-21)\nfunction _binStringToArrayBuffer(bin) {\n var length = bin.length;\n var buf = new ArrayBuffer(length);\n var arr = new Uint8Array(buf);\n for (var i = 0; i < length; i++) {\n arr[i] = bin.charCodeAt(i);\n }\n return buf;\n}\n\n//\n// Blobs are not supported in all versions of IndexedDB, notably\n// Chrome <37 and Android <5. In those versions, storing a blob will throw.\n//\n// Various other blob bugs exist in Chrome v37-42 (inclusive).\n// Detecting them is expensive and confusing to users, and Chrome 37-42\n// is at very low usage worldwide, so we do a hacky userAgent check instead.\n//\n// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120\n// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916\n// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836\n//\n// Code borrowed from PouchDB. See:\n// https://github.com/pouchdb/pouchdb/blob/master/packages/node_modules/pouchdb-adapter-idb/src/blobSupport.js\n//\nfunction _checkBlobSupportWithoutCaching(idb) {\n return new Promise$1(function (resolve) {\n var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, 'readwrite');\n var blob = createBlob(['']);\n txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');\n\n txn.onabort = function (e) {\n // If the transaction aborts now its due to not being able to\n // write to the database, likely due to the disk being full\n e.preventDefault();\n e.stopPropagation();\n resolve(false);\n };\n\n txn.oncomplete = function () {\n var matchedChrome = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n var matchedEdge = navigator.userAgent.match(/Edge\\//);\n // MS Edge pretends to be Chrome 42:\n // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx\n resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43);\n };\n })[\"catch\"](function () {\n return false; // error, so assume unsupported\n });\n}\n\nfunction _checkBlobSupport(idb) {\n if (typeof supportsBlobs === 'boolean') {\n return Promise$1.resolve(supportsBlobs);\n }\n return _checkBlobSupportWithoutCaching(idb).then(function (value) {\n supportsBlobs = value;\n return supportsBlobs;\n });\n}\n\nfunction _deferReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Create a deferred object representing the current database operation.\n var deferredOperation = {};\n\n deferredOperation.promise = new Promise$1(function (resolve) {\n deferredOperation.resolve = resolve;\n });\n\n // Enqueue the deferred operation.\n dbContext.deferredOperations.push(deferredOperation);\n\n // Chain its promise to the database readiness.\n if (!dbContext.dbReady) {\n dbContext.dbReady = deferredOperation.promise;\n } else {\n dbContext.dbReady = dbContext.dbReady.then(function () {\n return deferredOperation.promise;\n });\n }\n}\n\nfunction _advanceReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Dequeue a deferred operation.\n var deferredOperation = dbContext.deferredOperations.pop();\n\n // Resolve its promise (which is part of the database readiness\n // chain of promises).\n if (deferredOperation) {\n deferredOperation.resolve();\n }\n}\n\nfunction _getConnection(dbInfo, upgradeNeeded) {\n return new Promise$1(function (resolve, reject) {\n\n if (dbInfo.db) {\n if (upgradeNeeded) {\n _deferReadiness(dbInfo);\n dbInfo.db.close();\n } else {\n return resolve(dbInfo.db);\n }\n }\n\n var dbArgs = [dbInfo.name];\n\n if (upgradeNeeded) {\n dbArgs.push(dbInfo.version);\n }\n\n var openreq = idb.open.apply(idb, dbArgs);\n\n if (upgradeNeeded) {\n openreq.onupgradeneeded = function (e) {\n var db = openreq.result;\n try {\n db.createObjectStore(dbInfo.storeName);\n if (e.oldVersion <= 1) {\n // Added when support for blob shims was added\n db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);\n }\n } catch (ex) {\n if (ex.name === 'ConstraintError') {\n console.warn('The database \"' + dbInfo.name + '\"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage \"' + dbInfo.storeName + '\" already exists.');\n } else {\n throw ex;\n }\n }\n };\n }\n\n openreq.onerror = function (e) {\n e.preventDefault();\n reject(openreq.error);\n };\n\n openreq.onsuccess = function () {\n resolve(openreq.result);\n _advanceReadiness(dbInfo);\n };\n });\n}\n\nfunction _getOriginalConnection(dbInfo) {\n return _getConnection(dbInfo, false);\n}\n\nfunction _getUpgradedConnection(dbInfo) {\n return _getConnection(dbInfo, true);\n}\n\nfunction _isUpgradeNeeded(dbInfo, defaultVersion) {\n if (!dbInfo.db) {\n return true;\n }\n\n var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName);\n var isDowngrade = dbInfo.version < dbInfo.db.version;\n var isUpgrade = dbInfo.version > dbInfo.db.version;\n\n if (isDowngrade) {\n // If the version is not the default one\n // then warn for impossible downgrade.\n if (dbInfo.version !== defaultVersion) {\n console.warn('The database \"' + dbInfo.name + '\"' + ' can\\'t be downgraded from version ' + dbInfo.db.version + ' to version ' + dbInfo.version + '.');\n }\n // Align the versions to prevent errors.\n dbInfo.version = dbInfo.db.version;\n }\n\n if (isUpgrade || isNewStore) {\n // If the store is new then increment the version (if needed).\n // This will trigger an \"upgradeneeded\" event which is required\n // for creating a store.\n if (isNewStore) {\n var incVersion = dbInfo.db.version + 1;\n if (incVersion > dbInfo.version) {\n dbInfo.version = incVersion;\n }\n }\n\n return true;\n }\n\n return false;\n}\n\n// encode a blob for indexeddb engines that don't support blobs\nfunction _encodeBlob(blob) {\n return new Promise$1(function (resolve, reject) {\n var reader = new FileReader();\n reader.onerror = reject;\n reader.onloadend = function (e) {\n var base64 = btoa(e.target.result || '');\n resolve({\n __local_forage_encoded_blob: true,\n data: base64,\n type: blob.type\n });\n };\n reader.readAsBinaryString(blob);\n });\n}\n\n// decode an encoded blob\nfunction _decodeBlob(encodedBlob) {\n var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data));\n return createBlob([arrayBuff], { type: encodedBlob.type });\n}\n\n// is this one of our fancy encoded blobs?\nfunction _isEncodedBlob(value) {\n return value && value.__local_forage_encoded_blob;\n}\n\n// Specialize the default `ready()` function by making it dependent\n// on the current database operations. Thus, the driver will be actually\n// ready when it's been initialized (default) *and* there are no pending\n// operations on the database (initiated by some other instances).\nfunction _fullyReady(callback) {\n var self = this;\n\n var promise = self._initReady().then(function () {\n var dbContext = dbContexts[self._dbInfo.name];\n\n if (dbContext && dbContext.dbReady) {\n return dbContext.dbReady;\n }\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n}\n\n// Open the IndexedDB database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n // Initialize a singleton container for all running localForages.\n if (!dbContexts) {\n dbContexts = {};\n }\n\n // Get the current context of the database;\n var dbContext = dbContexts[dbInfo.name];\n\n // ...or create a new context.\n if (!dbContext) {\n dbContext = {\n // Running localForages sharing a database.\n forages: [],\n // Shared database.\n db: null,\n // Database readiness (promise).\n dbReady: null,\n // Deferred operations on the database.\n deferredOperations: []\n };\n // Register the new context in the global container.\n dbContexts[dbInfo.name] = dbContext;\n }\n\n // Register itself as a running localForage in the current context.\n dbContext.forages.push(self);\n\n // Replace the default `ready()` function with the specialized one.\n if (!self._initReady) {\n self._initReady = self.ready;\n self.ready = _fullyReady;\n }\n\n // Create an array of initialization states of the related localForages.\n var initPromises = [];\n\n function ignoreErrors() {\n // Don't handle errors here,\n // just makes sure related localForages aren't pending.\n return Promise$1.resolve();\n }\n\n for (var j = 0; j < dbContext.forages.length; j++) {\n var forage = dbContext.forages[j];\n if (forage !== self) {\n // Don't wait for itself...\n initPromises.push(forage._initReady()[\"catch\"](ignoreErrors));\n }\n }\n\n // Take a snapshot of the related localForages.\n var forages = dbContext.forages.slice(0);\n\n // Initialize the connection process only when\n // all the related localForages aren't pending.\n return Promise$1.all(initPromises).then(function () {\n dbInfo.db = dbContext.db;\n // Get the connection or open a new one without upgrade.\n return _getOriginalConnection(dbInfo);\n }).then(function (db) {\n dbInfo.db = db;\n if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) {\n // Reopen the database for upgrading.\n return _getUpgradedConnection(dbInfo);\n }\n return db;\n }).then(function (db) {\n dbInfo.db = dbContext.db = db;\n self._dbInfo = dbInfo;\n // Share the final connection amongst related localForages.\n for (var k = 0; k < forages.length; k++) {\n var forage = forages[k];\n if (forage !== self) {\n // Self is already up-to-date.\n forage._dbInfo.db = dbInfo.db;\n forage._dbInfo.version = dbInfo.version;\n }\n }\n });\n}\n\nfunction getItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.get(key);\n\n req.onsuccess = function () {\n var value = req.result;\n if (value === undefined) {\n value = null;\n }\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n resolve(value);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items stored in database.\nfunction iterate(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var iterationNumber = 1;\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (cursor) {\n var value = cursor.value;\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n var result = iterator(value, cursor.key, iterationNumber++);\n\n if (result !== void 0) {\n resolve(result);\n } else {\n cursor[\"continue\"]();\n }\n } else {\n resolve();\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n\n return promise;\n}\n\nfunction setItem(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n var dbInfo;\n self.ready().then(function () {\n dbInfo = self._dbInfo;\n if (toString.call(value) === '[object Blob]') {\n return _checkBlobSupport(dbInfo.db).then(function (blobSupport) {\n if (blobSupport) {\n return value;\n }\n return _encodeBlob(value);\n });\n }\n return value;\n }).then(function (value) {\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.put(value, key);\n\n // The reason we don't _save_ null is because IE 10 does\n // not support saving the `null` type in IndexedDB. How\n // ironic, given the bug below!\n // See: https://github.com/mozilla/localForage/issues/161\n if (value === null) {\n value = undefined;\n }\n\n transaction.oncomplete = function () {\n // Cast to undefined so the value passed to\n // callback/promise is the same as what one would get out\n // of `getItem()` later. This leads to some weirdness\n // (setItem('foo', undefined) will return `null`), but\n // it's not my fault localStorage is our baseline and that\n // it's weird.\n if (value === undefined) {\n value = null;\n }\n\n resolve(value);\n };\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction removeItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n\n // We use a Grunt task to make this safe for IE and some\n // versions of Android (including those used by Cordova).\n // Normally IE won't like `.delete()` and will insist on\n // using `['delete']()`, but we have a build step that\n // fixes this for us now.\n var req = store[\"delete\"](key);\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onerror = function () {\n reject(req.error);\n };\n\n // The request will be also be aborted if we've exceeded our storage\n // space.\n transaction.onabort = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction clear(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.clear();\n\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction length(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.count();\n\n req.onsuccess = function () {\n resolve(req.result);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction key(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n if (n < 0) {\n resolve(null);\n\n return;\n }\n\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var advanced = false;\n var req = store.openCursor();\n req.onsuccess = function () {\n var cursor = req.result;\n if (!cursor) {\n // this means there weren't enough keys\n resolve(null);\n\n return;\n }\n\n if (n === 0) {\n // We have the first key, return it if that's what they\n // wanted.\n resolve(cursor.key);\n } else {\n if (!advanced) {\n // Otherwise, ask the cursor to skip ahead n\n // records.\n advanced = true;\n cursor.advance(n);\n } else {\n // When we get here, we've got the nth key.\n resolve(cursor.key);\n }\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var keys = [];\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (!cursor) {\n resolve(keys);\n return;\n }\n\n keys.push(cursor.key);\n cursor[\"continue\"]();\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar asyncStorage = {\n _driver: 'asyncStorage',\n _initStorage: _initStorage,\n iterate: iterate,\n getItem: getItem,\n setItem: setItem,\n removeItem: removeItem,\n clear: clear,\n length: length,\n key: key,\n keys: keys\n};\n\n// Sadly, the best way to save binary data in WebSQL/localStorage is serializing\n// it to Base64, so this is how we store it to prevent very strange errors with less\n// verbose ways of binary <-> string data storage.\nvar BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\nvar BLOB_TYPE_PREFIX = '~~local_forage_type~';\nvar BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;\n\nvar SERIALIZED_MARKER = '__lfsc__:';\nvar SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;\n\n// OMG the serializations!\nvar TYPE_ARRAYBUFFER = 'arbf';\nvar TYPE_BLOB = 'blob';\nvar TYPE_INT8ARRAY = 'si08';\nvar TYPE_UINT8ARRAY = 'ui08';\nvar TYPE_UINT8CLAMPEDARRAY = 'uic8';\nvar TYPE_INT16ARRAY = 'si16';\nvar TYPE_INT32ARRAY = 'si32';\nvar TYPE_UINT16ARRAY = 'ur16';\nvar TYPE_UINT32ARRAY = 'ui32';\nvar TYPE_FLOAT32ARRAY = 'fl32';\nvar TYPE_FLOAT64ARRAY = 'fl64';\nvar TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;\n\nvar toString$1 = Object.prototype.toString;\n\nfunction stringToBuffer(serializedString) {\n // Fill the string into a ArrayBuffer.\n var bufferLength = serializedString.length * 0.75;\n var len = serializedString.length;\n var i;\n var p = 0;\n var encoded1, encoded2, encoded3, encoded4;\n\n if (serializedString[serializedString.length - 1] === '=') {\n bufferLength--;\n if (serializedString[serializedString.length - 2] === '=') {\n bufferLength--;\n }\n }\n\n var buffer = new ArrayBuffer(bufferLength);\n var bytes = new Uint8Array(buffer);\n\n for (i = 0; i < len; i += 4) {\n encoded1 = BASE_CHARS.indexOf(serializedString[i]);\n encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);\n encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);\n encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);\n\n /*jslint bitwise: true */\n bytes[p++] = encoded1 << 2 | encoded2 >> 4;\n bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;\n bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;\n }\n return buffer;\n}\n\n// Converts a buffer to a string to store, serialized, in the backend\n// storage library.\nfunction bufferToString(buffer) {\n // base64-arraybuffer\n var bytes = new Uint8Array(buffer);\n var base64String = '';\n var i;\n\n for (i = 0; i < bytes.length; i += 3) {\n /*jslint bitwise: true */\n base64String += BASE_CHARS[bytes[i] >> 2];\n base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];\n base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];\n base64String += BASE_CHARS[bytes[i + 2] & 63];\n }\n\n if (bytes.length % 3 === 2) {\n base64String = base64String.substring(0, base64String.length - 1) + '=';\n } else if (bytes.length % 3 === 1) {\n base64String = base64String.substring(0, base64String.length - 2) + '==';\n }\n\n return base64String;\n}\n\n// Serialize a value, afterwards executing a callback (which usually\n// instructs the `setItem()` callback/promise to be executed). This is how\n// we store binary data with localStorage.\nfunction serialize(value, callback) {\n var valueType = '';\n if (value) {\n valueType = toString$1.call(value);\n }\n\n // Cannot use `value instanceof ArrayBuffer` or such here, as these\n // checks fail when running the tests using casper.js...\n //\n // TODO: See why those tests fail and use a better solution.\n if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) {\n // Convert binary arrays to a string and prefix the string with\n // a special marker.\n var buffer;\n var marker = SERIALIZED_MARKER;\n\n if (value instanceof ArrayBuffer) {\n buffer = value;\n marker += TYPE_ARRAYBUFFER;\n } else {\n buffer = value.buffer;\n\n if (valueType === '[object Int8Array]') {\n marker += TYPE_INT8ARRAY;\n } else if (valueType === '[object Uint8Array]') {\n marker += TYPE_UINT8ARRAY;\n } else if (valueType === '[object Uint8ClampedArray]') {\n marker += TYPE_UINT8CLAMPEDARRAY;\n } else if (valueType === '[object Int16Array]') {\n marker += TYPE_INT16ARRAY;\n } else if (valueType === '[object Uint16Array]') {\n marker += TYPE_UINT16ARRAY;\n } else if (valueType === '[object Int32Array]') {\n marker += TYPE_INT32ARRAY;\n } else if (valueType === '[object Uint32Array]') {\n marker += TYPE_UINT32ARRAY;\n } else if (valueType === '[object Float32Array]') {\n marker += TYPE_FLOAT32ARRAY;\n } else if (valueType === '[object Float64Array]') {\n marker += TYPE_FLOAT64ARRAY;\n } else {\n callback(new Error('Failed to get type for BinaryArray'));\n }\n }\n\n callback(marker + bufferToString(buffer));\n } else if (valueType === '[object Blob]') {\n // Conver the blob to a binaryArray and then to a string.\n var fileReader = new FileReader();\n\n fileReader.onload = function () {\n // Backwards-compatible prefix for the blob type.\n var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result);\n\n callback(SERIALIZED_MARKER + TYPE_BLOB + str);\n };\n\n fileReader.readAsArrayBuffer(value);\n } else {\n try {\n callback(JSON.stringify(value));\n } catch (e) {\n console.error(\"Couldn't convert value into a JSON string: \", value);\n\n callback(null, e);\n }\n }\n}\n\n// Deserialize data we've inserted into a value column/field. We place\n// special markers into our strings to mark them as encoded; this isn't\n// as nice as a meta field, but it's the only sane thing we can do whilst\n// keeping localStorage support intact.\n//\n// Oftentimes this will just deserialize JSON content, but if we have a\n// special marker (SERIALIZED_MARKER, defined above), we will extract\n// some kind of arraybuffer/binary data/typed array out of the string.\nfunction deserialize(value) {\n // If we haven't marked this string as being specially serialized (i.e.\n // something other than serialized JSON), we can just return it and be\n // done with it.\n if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {\n return JSON.parse(value);\n }\n\n // The following code deals with deserializing some kind of Blob or\n // TypedArray. First we separate out the type of data we're dealing\n // with from the data itself.\n var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);\n var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH);\n\n var blobType;\n // Backwards-compatible blob type serialization strategy.\n // DBs created with older versions of localForage will simply not have the blob type.\n if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {\n var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);\n blobType = matcher[1];\n serializedString = serializedString.substring(matcher[0].length);\n }\n var buffer = stringToBuffer(serializedString);\n\n // Return the right type based on the code/type set during\n // serialization.\n switch (type) {\n case TYPE_ARRAYBUFFER:\n return buffer;\n case TYPE_BLOB:\n return createBlob([buffer], { type: blobType });\n case TYPE_INT8ARRAY:\n return new Int8Array(buffer);\n case TYPE_UINT8ARRAY:\n return new Uint8Array(buffer);\n case TYPE_UINT8CLAMPEDARRAY:\n return new Uint8ClampedArray(buffer);\n case TYPE_INT16ARRAY:\n return new Int16Array(buffer);\n case TYPE_UINT16ARRAY:\n return new Uint16Array(buffer);\n case TYPE_INT32ARRAY:\n return new Int32Array(buffer);\n case TYPE_UINT32ARRAY:\n return new Uint32Array(buffer);\n case TYPE_FLOAT32ARRAY:\n return new Float32Array(buffer);\n case TYPE_FLOAT64ARRAY:\n return new Float64Array(buffer);\n default:\n throw new Error('Unkown type: ' + type);\n }\n}\n\nvar localforageSerializer = {\n serialize: serialize,\n deserialize: deserialize,\n stringToBuffer: stringToBuffer,\n bufferToString: bufferToString\n};\n\n/*\n * Includes code from:\n *\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n// Open the WebSQL database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage$1(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i];\n }\n }\n\n var dbInfoPromise = new Promise$1(function (resolve, reject) {\n // Open the database; the openDatabase API will automatically\n // create it for us if it doesn't exist.\n try {\n dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size);\n } catch (e) {\n return reject(e);\n }\n\n // Create our key/value table if it doesn't exist.\n dbInfo.db.transaction(function (t) {\n t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' (id INTEGER PRIMARY KEY, key unique, value)', [], function () {\n self._dbInfo = dbInfo;\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n });\n\n dbInfo.serializer = localforageSerializer;\n return dbInfoPromise;\n}\n\nfunction getItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).value : null;\n\n // Check to see if this is serialized content we need to\n // unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction iterate$1(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName, [], function (t, results) {\n var rows = results.rows;\n var length = rows.length;\n\n for (var i = 0; i < length; i++) {\n var item = rows.item(i);\n var result = item.value;\n\n // Check to see if this is serialized content\n // we need to unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n result = iterator(result, item.key, i + 1);\n\n // void(0) prevents problems with redefinition\n // of `undefined`.\n if (result !== void 0) {\n resolve(result);\n return;\n }\n }\n\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction _setItem(key, value, callback, retriesLeft) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n // The localStorage API doesn't return undefined values in an\n // \"expected\" way, so undefined is always cast to null in all\n // drivers. See: https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n dbInfo.db.transaction(function (t) {\n t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + ' (key, value) VALUES (?, ?)', [key, value], function () {\n resolve(originalValue);\n }, function (t, error) {\n reject(error);\n });\n }, function (sqlError) {\n // The transaction failed; check\n // to see if it's a quota error.\n if (sqlError.code === sqlError.QUOTA_ERR) {\n // We reject the callback outright for now, but\n // it's worth trying to re-run the transaction.\n // Even if the user accepts the prompt to use\n // more storage on Safari, this error will\n // be called.\n //\n // Try to re-run the transaction.\n if (retriesLeft > 0) {\n resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1]));\n return;\n }\n reject(sqlError);\n }\n });\n }\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction setItem$1(key, value, callback) {\n return _setItem.apply(this, [key, value, callback, 1]);\n}\n\nfunction removeItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () {\n resolve();\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Deletes every item in the table.\n// TODO: Find out if this resets the AUTO_INCREMENT number.\nfunction clear$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function () {\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Does a simple `COUNT(key)` to get the number of items stored in\n// localForage.\nfunction length$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n // Ahhh, SQL makes this one soooooo easy.\n t.executeSql('SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) {\n var result = results.rows.item(0).c;\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Return the key located at key index X; essentially gets the key from a\n// `WHERE id = ?`. This is the most efficient way I can think to implement\n// this rarely-used (in my experience) part of the API, but it can seem\n// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so\n// the ID of each key will change every time it's updated. Perhaps a stored\n// procedure for the `setItem()` SQL would solve this problem?\n// TODO: Don't change ID on `setItem()`.\nfunction key$1(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).key : null;\n resolve(result);\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName, [], function (t, results) {\n var keys = [];\n\n for (var i = 0; i < results.rows.length; i++) {\n keys.push(results.rows.item(i).key);\n }\n\n resolve(keys);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar webSQLStorage = {\n _driver: 'webSQLStorage',\n _initStorage: _initStorage$1,\n iterate: iterate$1,\n getItem: getItem$1,\n setItem: setItem$1,\n removeItem: removeItem$1,\n clear: clear$1,\n length: length$1,\n key: key$1,\n keys: keys$1\n};\n\n// Config the localStorage backend, using options set in the config.\nfunction _initStorage$2(options) {\n var self = this;\n var dbInfo = {};\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n dbInfo.keyPrefix = dbInfo.name + '/';\n\n if (dbInfo.storeName !== self._defaultConfig.storeName) {\n dbInfo.keyPrefix += dbInfo.storeName + '/';\n }\n\n self._dbInfo = dbInfo;\n dbInfo.serializer = localforageSerializer;\n\n return Promise$1.resolve();\n}\n\n// Remove all keys from the datastore, effectively destroying all data in\n// the app's key/value store!\nfunction clear$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var keyPrefix = self._dbInfo.keyPrefix;\n\n for (var i = localStorage.length - 1; i >= 0; i--) {\n var key = localStorage.key(i);\n\n if (key.indexOf(keyPrefix) === 0) {\n localStorage.removeItem(key);\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Retrieve an item from the store. Unlike the original async_storage\n// library in Gaia, we don't modify return values at all. If a key's value\n// is `undefined`, we pass that value to the callback function.\nfunction getItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result = localStorage.getItem(dbInfo.keyPrefix + key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the key\n // is likely undefined and we'll pass it straight to the\n // callback.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items in the store.\nfunction iterate$2(iterator, callback) {\n var self = this;\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var keyPrefix = dbInfo.keyPrefix;\n var keyPrefixLength = keyPrefix.length;\n var length = localStorage.length;\n\n // We use a dedicated iterator instead of the `i` variable below\n // so other keys we fetch in localStorage aren't counted in\n // the `iterationNumber` argument passed to the `iterate()`\n // callback.\n //\n // See: github.com/mozilla/localForage/pull/435#discussion_r38061530\n var iterationNumber = 1;\n\n for (var i = 0; i < length; i++) {\n var key = localStorage.key(i);\n if (key.indexOf(keyPrefix) !== 0) {\n continue;\n }\n var value = localStorage.getItem(key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the\n // key is likely undefined and we'll pass it straight\n // to the iterator.\n if (value) {\n value = dbInfo.serializer.deserialize(value);\n }\n\n value = iterator(value, key.substring(keyPrefixLength), iterationNumber++);\n\n if (value !== void 0) {\n return value;\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Same as localStorage's key() method, except takes a callback.\nfunction key$2(n, callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result;\n try {\n result = localStorage.key(n);\n } catch (error) {\n result = null;\n }\n\n // Remove the prefix from the key, if a key is found.\n if (result) {\n result = result.substring(dbInfo.keyPrefix.length);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var length = localStorage.length;\n var keys = [];\n\n for (var i = 0; i < length; i++) {\n if (localStorage.key(i).indexOf(dbInfo.keyPrefix) === 0) {\n keys.push(localStorage.key(i).substring(dbInfo.keyPrefix.length));\n }\n }\n\n return keys;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Supply the number of keys in the datastore to the callback function.\nfunction length$2(callback) {\n var self = this;\n var promise = self.keys().then(function (keys) {\n return keys.length;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Remove an item from the store, nice and simple.\nfunction removeItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n localStorage.removeItem(dbInfo.keyPrefix + key);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Set a key's value and run an optional callback once the value is set.\n// Unlike Gaia's implementation, the callback function is passed the value,\n// in case you want to operate on that value only after you're sure it\n// saved, or something like that.\nfunction setItem$2(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n // Convert undefined values to null.\n // https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n return new Promise$1(function (resolve, reject) {\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n try {\n localStorage.setItem(dbInfo.keyPrefix + key, value);\n resolve(originalValue);\n } catch (e) {\n // localStorage capacity exceeded.\n // TODO: Make this a specific error/event.\n if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {\n reject(e);\n }\n reject(e);\n }\n }\n });\n });\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar localStorageWrapper = {\n _driver: 'localStorageWrapper',\n _initStorage: _initStorage$2,\n // Default API, from Gaia/localStorage.\n iterate: iterate$2,\n getItem: getItem$2,\n setItem: setItem$2,\n removeItem: removeItem$2,\n clear: clear$2,\n length: length$2,\n key: key$2,\n keys: keys$2\n};\n\n// Custom drivers are stored here when `defineDriver()` is called.\n// They are shared across all instances of localForage.\nvar CustomDrivers = {};\n\nvar DriverType = {\n INDEXEDDB: 'asyncStorage',\n LOCALSTORAGE: 'localStorageWrapper',\n WEBSQL: 'webSQLStorage'\n};\n\nvar DefaultDriverOrder = [DriverType.INDEXEDDB, DriverType.WEBSQL, DriverType.LOCALSTORAGE];\n\nvar LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem'];\n\nvar DefaultConfig = {\n description: '',\n driver: DefaultDriverOrder.slice(),\n name: 'localforage',\n // Default DB size is _JUST UNDER_ 5MB, as it's the highest size\n // we can use without a prompt.\n size: 4980736,\n storeName: 'keyvaluepairs',\n version: 1.0\n};\n\nvar driverSupport = {};\n// Check to see if IndexedDB is available and if it is the latest\n// implementation; it's our preferred backend library. We use \"_spec_test\"\n// as the name of the database because it's not the one we'll operate on,\n// but it's useful to make sure its using the right spec.\n// See: https://github.com/mozilla/localForage/issues/128\ndriverSupport[DriverType.INDEXEDDB] = isIndexedDBValid();\n\ndriverSupport[DriverType.WEBSQL] = isWebSQLValid();\n\ndriverSupport[DriverType.LOCALSTORAGE] = isLocalStorageValid();\n\nvar isArray = Array.isArray || function (arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n};\n\nfunction callWhenReady(localForageInstance, libraryMethod) {\n localForageInstance[libraryMethod] = function () {\n var _args = arguments;\n return localForageInstance.ready().then(function () {\n return localForageInstance[libraryMethod].apply(localForageInstance, _args);\n });\n };\n}\n\nfunction extend() {\n for (var i = 1; i < arguments.length; i++) {\n var arg = arguments[i];\n\n if (arg) {\n for (var key in arg) {\n if (arg.hasOwnProperty(key)) {\n if (isArray(arg[key])) {\n arguments[0][key] = arg[key].slice();\n } else {\n arguments[0][key] = arg[key];\n }\n }\n }\n }\n }\n\n return arguments[0];\n}\n\nfunction isLibraryDriver(driverName) {\n for (var driver in DriverType) {\n if (DriverType.hasOwnProperty(driver) && DriverType[driver] === driverName) {\n return true;\n }\n }\n\n return false;\n}\n\nvar LocalForage = function () {\n function LocalForage(options) {\n _classCallCheck(this, LocalForage);\n\n this.INDEXEDDB = DriverType.INDEXEDDB;\n this.LOCALSTORAGE = DriverType.LOCALSTORAGE;\n this.WEBSQL = DriverType.WEBSQL;\n\n this._defaultConfig = extend({}, DefaultConfig);\n this._config = extend({}, this._defaultConfig, options);\n this._driverSet = null;\n this._initDriver = null;\n this._ready = false;\n this._dbInfo = null;\n\n this._wrapLibraryMethodsWithReady();\n this.setDriver(this._config.driver)[\"catch\"](function () {});\n }\n\n // Set any config values for localForage; can be called anytime before\n // the first API call (e.g. `getItem`, `setItem`).\n // We loop through options so we don't overwrite existing config\n // values.\n\n\n LocalForage.prototype.config = function config(options) {\n // If the options argument is an object, we use it to set values.\n // Otherwise, we return either a specified config value or all\n // config values.\n if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {\n // If localforage is ready and fully initialized, we can't set\n // any new configuration values. Instead, we return an error.\n if (this._ready) {\n return new Error(\"Can't call config() after localforage \" + 'has been used.');\n }\n\n for (var i in options) {\n if (i === 'storeName') {\n options[i] = options[i].replace(/\\W/g, '_');\n }\n\n if (i === 'version' && typeof options[i] !== 'number') {\n return new Error('Database version must be a number.');\n }\n\n this._config[i] = options[i];\n }\n\n // after all config options are set and\n // the driver option is used, try setting it\n if ('driver' in options && options.driver) {\n return this.setDriver(this._config.driver);\n }\n\n return true;\n } else if (typeof options === 'string') {\n return this._config[options];\n } else {\n return this._config;\n }\n };\n\n // Used to define a custom driver, shared across all instances of\n // localForage.\n\n\n LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) {\n var promise = new Promise$1(function (resolve, reject) {\n try {\n var driverName = driverObject._driver;\n var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver');\n var namingError = new Error('Custom driver name already in use: ' + driverObject._driver);\n\n // A driver name should be defined and not overlap with the\n // library-defined, default drivers.\n if (!driverObject._driver) {\n reject(complianceError);\n return;\n }\n if (isLibraryDriver(driverObject._driver)) {\n reject(namingError);\n return;\n }\n\n var customDriverMethods = LibraryMethods.concat('_initStorage');\n for (var i = 0; i < customDriverMethods.length; i++) {\n var customDriverMethod = customDriverMethods[i];\n if (!customDriverMethod || !driverObject[customDriverMethod] || typeof driverObject[customDriverMethod] !== 'function') {\n reject(complianceError);\n return;\n }\n }\n\n var supportPromise = Promise$1.resolve(true);\n if ('_support' in driverObject) {\n if (driverObject._support && typeof driverObject._support === 'function') {\n supportPromise = driverObject._support();\n } else {\n supportPromise = Promise$1.resolve(!!driverObject._support);\n }\n }\n\n supportPromise.then(function (supportResult) {\n driverSupport[driverName] = supportResult;\n CustomDrivers[driverName] = driverObject;\n resolve();\n }, reject);\n } catch (e) {\n reject(e);\n }\n });\n\n executeTwoCallbacks(promise, callback, errorCallback);\n return promise;\n };\n\n LocalForage.prototype.driver = function driver() {\n return this._driver || null;\n };\n\n LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) {\n var self = this;\n var getDriverPromise = Promise$1.resolve().then(function () {\n if (isLibraryDriver(driverName)) {\n switch (driverName) {\n case self.INDEXEDDB:\n return asyncStorage;\n case self.LOCALSTORAGE:\n return localStorageWrapper;\n case self.WEBSQL:\n return webSQLStorage;\n }\n } else if (CustomDrivers[driverName]) {\n return CustomDrivers[driverName];\n } else {\n throw new Error('Driver not found.');\n }\n });\n executeTwoCallbacks(getDriverPromise, callback, errorCallback);\n return getDriverPromise;\n };\n\n LocalForage.prototype.getSerializer = function getSerializer(callback) {\n var serializerPromise = Promise$1.resolve(localforageSerializer);\n executeTwoCallbacks(serializerPromise, callback);\n return serializerPromise;\n };\n\n LocalForage.prototype.ready = function ready(callback) {\n var self = this;\n\n var promise = self._driverSet.then(function () {\n if (self._ready === null) {\n self._ready = self._initDriver();\n }\n\n return self._ready;\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n };\n\n LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) {\n var self = this;\n\n if (!isArray(drivers)) {\n drivers = [drivers];\n }\n\n var supportedDrivers = this._getSupportedDrivers(drivers);\n\n function setDriverToConfig() {\n self._config.driver = self.driver();\n }\n\n function extendSelfWithDriver(driver) {\n self._extend(driver);\n setDriverToConfig();\n\n self._ready = self._initStorage(self._config);\n return self._ready;\n }\n\n function initDriver(supportedDrivers) {\n return function () {\n var currentDriverIndex = 0;\n\n function driverPromiseLoop() {\n while (currentDriverIndex < supportedDrivers.length) {\n var driverName = supportedDrivers[currentDriverIndex];\n currentDriverIndex++;\n\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(extendSelfWithDriver)[\"catch\"](driverPromiseLoop);\n }\n\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n }\n\n return driverPromiseLoop();\n };\n }\n\n // There might be a driver initialization in progress\n // so wait for it to finish in order to avoid a possible\n // race condition to set _dbInfo\n var oldDriverSetDone = this._driverSet !== null ? this._driverSet[\"catch\"](function () {\n return Promise$1.resolve();\n }) : Promise$1.resolve();\n\n this._driverSet = oldDriverSetDone.then(function () {\n var driverName = supportedDrivers[0];\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(function (driver) {\n self._driver = driver._driver;\n setDriverToConfig();\n self._wrapLibraryMethodsWithReady();\n self._initDriver = initDriver(supportedDrivers);\n });\n })[\"catch\"](function () {\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n });\n\n executeTwoCallbacks(this._driverSet, callback, errorCallback);\n return this._driverSet;\n };\n\n LocalForage.prototype.supports = function supports(driverName) {\n return !!driverSupport[driverName];\n };\n\n LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) {\n extend(this, libraryMethodsAndProperties);\n };\n\n LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) {\n var supportedDrivers = [];\n for (var i = 0, len = drivers.length; i < len; i++) {\n var driverName = drivers[i];\n if (this.supports(driverName)) {\n supportedDrivers.push(driverName);\n }\n }\n return supportedDrivers;\n };\n\n LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() {\n // Add a stub for each driver API method that delays the call to the\n // corresponding driver method until localForage is ready. These stubs\n // will be replaced by the driver methods as soon as the driver is\n // loaded, so there is no performance impact.\n for (var i = 0; i < LibraryMethods.length; i++) {\n callWhenReady(this, LibraryMethods[i]);\n }\n };\n\n LocalForage.prototype.createInstance = function createInstance(options) {\n return new LocalForage(options);\n };\n\n return LocalForage;\n}();\n\n// The actual localForage object that we expose as a module or via a\n// global. It's extended by pulling in one of our other libraries.\n\n\nvar localforage_js = new LocalForage();\n\nmodule.exports = localforage_js;\n\n},{\"3\":3}]},{},[4])(4)\n});","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n // Let \"new String('')\" return 'object'\n if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n // PhantomJS has type \"DOMWindow\" for null\n if (obj === null) return 'null';\n // PhantomJS has type \"DOMWindow\" for undefined\n if (obj === undefined) return 'undefined';\n return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n if (!(this instanceof Library)) return new Library();\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","(function (document, window) {\n // DEPENDENCIES\n // ============================================================\n const localforage = require('localforage');\n\n // PROBLEMS\n // ============================================================\n const problems = require('../problems/arrays.js');\n\n // CONFIG\n // ============================================================\n\n // Hoist current problem\n let currentProblem;\n\n // Keys to ignore while user is navigating around the textarea but not changing any code\n const ignoreKeyCodes = [\n 9, // Tab\n 37, // Left arrow\n 39, // Right arrow\n 38, // Up arrow\n 40 // Down arrow\n ];\n\n let config = {\n shuffle: true,\n timer: false,\n currentIndex: 0\n };\n\n // Pull config from localforage\n localforage\n .getItem('js_practice_config')\n .then(val => {\n // console.log('localforage val:', val);\n if (val) {\n config = val;\n }\n loadApp(config);\n })\n .catch(err => {\n console.log('localforage err:', err);\n loadApp(config);\n });\n\n function updateLocalstore(config) {\n return localforage\n .setItem('js_practice_config', config)\n .then(val => {\n // console.log('Settings updated:', val);\n })\n .catch(err => {\n console.log('Settings update error:', err);\n });\n }\n\n // HELPERS\n // ============================================================\n\n function debounce(func, wait, immediate) {\n let timeout;\n return function () {\n const context = this;\n const args = arguments;\n const later = function () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n };\n const callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) {\n func.apply(context, args);\n }\n };\n }\n\n // UI\n // ============================================================\n\n // elements\n const problemEl = document.getElementById('problem');\n const codeEl = document.getElementById('code');\n const testSuiteEl = document.getElementById('test-suite');\n const testTotalEl = document.getElementById('test-total');\n const evalConsoleEl = document.getElementById('eval-output');\n const assertConsoleEl = document.getElementById('assert-output');\n const shuffleProblemsButtonEl = document.getElementById('shuffle-problems');\n const previousProblemButtonEl = document.getElementById('prev-problem');\n const nextProblemButtonEl = document.getElementById('next-problem');\n\n // Get indexes\n function getRandomIndex(problemsArr) {\n const ind = Math.floor(Math.random() * problemsArr.length);\n config.currentIndex = ind;\n updateLocalstore(config);\n return ind;\n }\n\n function getPreviousIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at beginning, go to end\n if (currentIndex === 0) {\n probInd = problemsArr.length - 1;\n } else {\n probInd = currentIndex - 1;\n }\n return probInd;\n }\n\n function getNextIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at end or invalid, restart series\n if (currentIndex >= problemsArr.length - 1 || currentIndex < 0) {\n probInd = 0;\n } else {\n probInd = currentIndex + 1;\n }\n return probInd;\n }\n\n // Get problems\n function getCurrentProblem(problemsArr) {\n return problemsArr[config.currentIndex];\n }\n\n function previousProblem() {\n console.log('previousProblem!');\n // Activate back button, for visual queue of nav feedback\n previousProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getPreviousIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function nextProblem() {\n console.log('nextProblem!');\n // Activate next button, for visual queue of nav feedback\n nextProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getNextIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function toggleShuffle() {\n console.log('toggle shuffle!');\n config.shuffle = !config.shuffle; // Flip it\n shuffleProblemsButtonEl.classList.toggle('active');\n previousProblemButtonEl.parentNode.classList.toggle('hidden');\n updateLocalstore(config);\n }\n\n function loadProblem(problemObj) {\n currentProblem = problemObj;\n // Prob question\n problemEl.innerText = problemObj.prompt;\n // Prob given code\n if (problemObj.given) {\n codeEl.value = problemObj.given;\n }\n // Seed the tests, pass (init = true) as second param\n testSuite(null, true);\n }\n\n // TODO: Build the assert errors into the test dom on each update.\n function updateTests(testStatus, init) {\n if (init === true) {\n buildTests(currentProblem.tests);\n }\n updateTestStatus(testStatus);\n }\n\n function buildTests(tests) {\n if (tests) {\n const testsDom = tests\n .map(test => {\n return `
\n
[✘]
\n
${test.name}
\n
`;\n })\n .join('');\n testSuiteEl.innerHTML = testsDom;\n }\n }\n\n function updateTestStatus(testStatuses) {\n if (!testStatuses) {\n throw new Error('No testStatuses provided.');\n }\n // Find out if all tests have passed or not\n let allPassed = true;\n testStatuses.forEach(testPassed => {\n if (testPassed !== true) {\n allPassed = false;\n }\n });\n const testEls = [].slice.call(testSuiteEl.querySelectorAll('.test-state'));\n testEls.forEach((testStatusEl, iter) => {\n if (testStatuses[iter] === true) {\n testStatusEl.innerHTML = '[✓]';\n testStatusEl.classList.remove('fail');\n testStatusEl.classList.add('pass');\n } else {\n testStatusEl.innerHTML = '[✘]';\n testStatusEl.classList.remove('pass');\n testStatusEl.classList.add('fail');\n }\n });\n\n if (allPassed === true) {\n testTotalEl.innerText = 'PASS';\n testTotalEl.classList.remove('fail');\n testTotalEl.classList.add('pass');\n } else {\n testTotalEl.innerText = 'FAIL';\n testTotalEl.classList.remove('pass');\n testTotalEl.classList.add('fail');\n }\n }\n\n function printAssertError(errObj) {\n // Make element string\n let inner = '';\n if (errObj !== null) {\n inner = `\n
\n Expected: ${JSON.stringify(errObj.expected)}\n Actual: ${JSON.stringify(errObj.actual)}\n
`;\n }\n\n // Prepend element\n assertConsoleEl.innerHTML = inner;\n }\n\n function printEvalOutput(errObj, output) {\n // Make element string\n let inner = '';\n if (errObj && errObj.message !== undefined) {\n inner = `\n
\n Syntax Error: ${JSON.stringify(errObj.message)}\n
`;\n } else if (output) {\n inner = `\n
\n Output: ${JSON.stringify(output)}\n
`;\n }\n // Prepend element\n evalConsoleEl.innerHTML = inner;\n }\n\n // VERIFICATION LOGIC\n // ============================================================\n\n function testSuite(init) {\n // Show 'working' indicator\n testTotalEl.classList.toggle('working');\n // Run stuff\n const output = getOutput(codeEl.value);\n // Run tests on code, return object/array of test results\n const tested = runTests(output);\n // Hide 'working' indicator\n testTotalEl.classList.toggle('working');\n // Update UI with results\n updateTests(tested, init);\n }\n\n function getOutput(code) {\n let evald = false;\n try {\n evald = eval(`(function(){${code}})()`); // eslint-disable-line no-eval\n printEvalOutput(null, evald); // Print current output\n } catch (err) {\n printEvalOutput(err);\n }\n return evald;\n }\n\n function runTests(output) {\n let tested = false;\n tested = currentProblem.tests.map(test => {\n let testOutcome = false;\n try {\n if (output) {\n testOutcome = test.test(output);\n }\n printAssertError(null);\n } catch (err) {\n printAssertError(err);\n }\n return testOutcome;\n });\n return tested;\n }\n\n // Wrapped to prevent race with local config retrieval\n function loadApp(config) {\n console.log('loading app!');\n\n // Show current toggle state\n if (config.shuffle === true) {\n shuffleProblemsButtonEl.classList.add('active');\n previousProblemButtonEl.parentNode.classList.add('hidden');\n }\n\n // Keybinding stuff\n // ============================================================\n\n // Debounced code validation\n const debouncedInputValidation = debounce(e => {\n // If not arrow keys or other non-character keys\n if (ignoreKeyCodes.indexOf(e.keyCode) === -1) {\n // Run test suite\n testSuite();\n }\n }, 200);\n\n function problemNav(e) {\n // Go to previous problem keybinding\n // If CMD/CTRL + SHIFT + RETURN/ENTER\n if (config.shuffle === false && e.keyCode === 13 && e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem\n previousProblem();\n } else if (e.keyCode === 13 && !e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem keybinding\n // If CMD/CTRL + RETURN/ENTER\n // Go to next problem\n nextProblem();\n }\n }\n\n // Event Bindings\n // ============================================================\n\n // Bind it up\n codeEl.addEventListener('keydown', debouncedInputValidation);\n document.addEventListener('keydown', problemNav);\n shuffleProblemsButtonEl.addEventListener('click', toggleShuffle);\n previousProblemButtonEl.addEventListener('click', previousProblem);\n nextProblemButtonEl.addEventListener('click', nextProblem);\n\n // Start it up!\n // Load current problem\n const currProb = getCurrentProblem(problems);\n loadProblem(currProb);\n // Initalized test suite with starting failures\n testSuite(true);\n }\n})(document, window);\n","const assert = require('chai').assert;\n\nmodule.exports = [\n {\n name: 'Create Array',\n time: 10,\n prompt: 'Create and return an array that contains \\'apple\\' and \\'banana\\'',\n given: `const fruits = [];\\rreturn fruits;`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, ['apple', 'banana']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Access Array by index (first)',\n time: 10,\n prompt: 'Return the first value of the Array',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits[0];`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 'apple') === undefined;\n }\n },\n {\n name: 'Returns a String',\n test(output) {\n return assert.isString(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Access Array by index (last)',\n time: 10,\n prompt: 'Return the last value of the Array',\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n return fruits[fruits.length - 1];`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 'orange') === undefined;\n }\n },\n {\n name: 'Returns a String',\n test(output) {\n return assert.isString(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Access Array by index (second)',\n time: 10,\n prompt: 'Return the second value of the Array',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits[1];`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 'banana') === undefined;\n }\n },\n {\n name: 'Returns a String',\n test(output) {\n return assert.isString(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.forEach()',\n time: 20,\n prompt: 'Loop over the array, add an \\'x\\' to the end of each name, push each fruit into a new array, then return the new array.',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n const newFruits = [];\n fruits.forEach(function(item) {\n newFruits.push(item+'x');\n });\n return newFruits;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, ['applex', 'bananax']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.push()',\n time: 10,\n prompt: `Add 'orange' to the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n fruits.push('orange');\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return (assert.deepEqual(output, ['apple', 'banana', 'orange']) === undefined);\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 3 items',\n test(output) {\n return assert.lengthOf(output, 3) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.pop()',\n time: 10,\n prompt: `Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, ['apple', 'banana']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.shift()',\n time: 10,\n prompt: `Remove 'apple' from the front of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.shift();\n return fruits;`,\n tests: [\n {\n name: 'Output must be correct',\n test(output) {\n return assert.deepEqual(output, ['banana', 'orange']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.unshift()',\n time: 10,\n prompt: `Add 'strawberry' to the front of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.unshift('strawberry');\n return fruits;`,\n tests: [\n {\n name: 'Output must be correct',\n test(output) {\n return (\n assert.deepEqual(output, [\n 'strawberry',\n 'apple',\n 'banana',\n 'orange'\n ]) === undefined\n );\n }\n },\n {\n name: 'Must return an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 4 items',\n test(output) {\n return assert.lengthOf(output, 4) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.indexOf()',\n time: 10,\n prompt: `Return the index of 'banana' in the Array.`,\n given: `const fruits = ['strawberry', 'banana', 'mango'];\\r`,\n answer: `const fruits = ['strawberry', 'banana', 'mango'];\n const ind = fruits.indexOf('banana');\n return ind;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 1) === undefined;\n }\n },\n {\n name: 'Returns a Number',\n test(output) {\n return assert.isNumber(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.concat()',\n time: 10,\n prompt: `Merge the two arrays using Array's 'concat()' method. Return the resulting array.`,\n given: `const fruits = ['strawberry', 'banana'];\\rconst otherFruits = ['pear','peach'];\\r`,\n answer: `const fruits = ['strawberry', 'banana'];\n const otherFruits = ['pear','peach'];\n const allTheFruits = fruits.concat(otherFruits);\n return allTheFruits;\\r`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return (\n assert.deepEqual(output, [\n 'strawberry',\n 'banana',\n 'pear',\n 'peach'\n ]) === undefined\n );\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 4 items',\n test(output) {\n return assert.lengthOf(output, 4) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.join()',\n time: 10,\n prompt: `Mix the two flavors with a '-' using Array's 'join' method. Return the resulting hybrid flavor.`,\n given: `const fruits = ['strawberry', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'banana'];\n const hybrid = fruits.join('-');\n return hybrid;\\r`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 'strawberry-banana') === undefined;\n }\n },\n {\n name: 'Returns a String',\n test(output) {\n return assert.isString(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.slice()',\n time: 20,\n prompt: `Return just the citrus fruits from the 'fruits' array using 'Array.slice()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const citrus = fruits.slice(1, 3);\n return citrus;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, ['orange', 'lemon']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.reverse()',\n time: 10,\n prompt: `Reverse the order of the 'fruit' array using 'Array.reverse()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const stiurf = fruits.reverse();\n return stiurf;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return (\n assert.deepEqual(output, [\n 'banana',\n 'lemon',\n 'orange',\n 'strawberry'\n ]) === undefined\n );\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 4 items',\n test(output) {\n return assert.lengthOf(output, 4) === undefined;\n }\n },\n {\n name: `First item is 'banana'`,\n test(output) {\n return assert.deepEqual(output[0], 'banana') === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.sort()',\n time: 10,\n prompt: `Sort the order of the 'fruit' array using 'Array.sort()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const orderlyFruit = fruits.sort();\n return orderlyFruit;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return (\n assert.deepEqual(output, [\n 'banana',\n 'lemon',\n 'orange',\n 'strawberry'\n ]) === undefined\n );\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 4 items',\n test(output) {\n return assert.lengthOf(output, 4) === undefined;\n }\n },\n {\n name: `First item is 'banana'`,\n test(output) {\n return assert.deepEqual(output[0], 'banana') === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.lastIndexOf()',\n time: 10,\n prompt: `Return the index of the last 'peach' instance in the 'fruit' array using 'Array.lastIndexOf()'`,\n given: `const fruits = ['peach', 'orange', 'lemon', 'peach'];\\r`,\n answer: `const fruits = ['peach', 'orange', 'lemon', 'peach'];\n const wheresTheLastPeach = fruits.lastIndexOf('peach');\n return wheresTheLastPeach;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 3) === undefined;\n }\n },\n {\n name: 'Returns a Number',\n test(output) {\n return assert.isNumber(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.filter()',\n time: 10,\n prompt: `Return an array of the numbers greater than 5 in 'numbers' using 'Array.filter()'`,\n given: `const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\\r`,\n answer: `const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\n const overFive = numbers.filter(num => num > 5);\n return overFive;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, [8, 13, 21]) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 3 items',\n test(output) {\n return assert.lengthOf(output, 3) === undefined;\n }\n },\n {\n name: `First item is 8`,\n test(output) {\n return assert.deepEqual(output[0], 8) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.map()',\n time: 10,\n prompt: `Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,\n given: `const numbers = [25, 121, 169];\\r`,\n answer: `const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, [5, 11, 13]) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 3 items',\n test(output) {\n return assert.lengthOf(output, 3) === undefined;\n }\n },\n {\n name: `First item is 5`,\n test(output) {\n return assert.deepEqual(output[0], 5) === undefined;\n }\n },\n {\n name: `Last item is 13`,\n test(output) {\n return assert.deepEqual(output[output.length - 1], 13) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.every()',\n time: 10,\n prompt: `Return object that returns whether each array contains all even numbers using Array.every().`,\n given: `\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 5, 6, 8];\nfunction isEven(element) {\n\n}\nreturn {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n};`,\n answer: `\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 5, 6, 8];\nfunction isEven(element) {\n return element % 2 === 0\n}\nreturn {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n};`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;\n }\n },\n {\n name: 'Returns an Object',\n test(output) {\n return assert.isObject(output) === undefined;\n }\n },\n {\n name: 'Object has 2 items',\n test(output) {\n return assert.lengthOf(Object.keys(output), 2) === undefined;\n }\n },\n {\n name: `First value is true`,\n test(output) {\n return assert.isTrue(output.evenNumbers) === undefined;\n }\n },\n {\n name: `Second value is false`,\n test(output) {\n return assert.isFalse(output.someOddNumbers) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.some()',\n time: 10,\n prompt: `Return object that returns whether each array contains some odd numbers using Array.some().`,\n given: `\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 4, 7, 8];\nfunction isOdd(element) {\n\n}\nreturn {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n};`,\n answer: `\nconst evenNumbers = [1, 3, 5, 7];\nconst someOddNumbers = [1, 3, 6, 7];\nfunction isOdd(element) {\n return element % 2 !== 0;\n}\nreturn {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n};`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;\n }\n },\n {\n name: 'Returns an Object',\n test(output) {\n return assert.isObject(output) === undefined;\n }\n },\n {\n name: 'Object has 2 items',\n test(output) {\n return assert.lengthOf(Object.keys(output), 2) === undefined;\n }\n },\n {\n name: `First value is false`,\n test(output) {\n return assert.isFalse(output.evenNumbers) === undefined;\n }\n },\n {\n name: `Second value is true`,\n test(output) {\n return assert.isTrue(output.someOddNumbers) === undefined;\n }\n }\n ]\n }\n // Next problems to create:\n // forEach? fix one above that tried, but can't verify forEach was used\n // some\n // reduce\n // reduceRight\n // Array.from and other ways to turn array-like into array\n];\n"]} \ No newline at end of file +<<<<<<< HEAD +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/assertion-error/index.js","node_modules/chai/index.js","node_modules/chai/lib/chai.js","node_modules/chai/lib/chai/assertion.js","node_modules/chai/lib/chai/config.js","node_modules/chai/lib/chai/core/assertions.js","node_modules/chai/lib/chai/interface/assert.js","node_modules/chai/lib/chai/interface/expect.js","node_modules/chai/lib/chai/interface/should.js","node_modules/chai/lib/chai/utils/addChainableMethod.js","node_modules/chai/lib/chai/utils/addMethod.js","node_modules/chai/lib/chai/utils/addProperty.js","node_modules/chai/lib/chai/utils/expectTypes.js","node_modules/chai/lib/chai/utils/flag.js","node_modules/chai/lib/chai/utils/getActual.js","node_modules/chai/lib/chai/utils/getEnumerableProperties.js","node_modules/chai/lib/chai/utils/getMessage.js","node_modules/chai/lib/chai/utils/getName.js","node_modules/chai/lib/chai/utils/getPathInfo.js","node_modules/chai/lib/chai/utils/getPathValue.js","node_modules/chai/lib/chai/utils/getProperties.js","node_modules/chai/lib/chai/utils/hasProperty.js","node_modules/chai/lib/chai/utils/index.js","node_modules/chai/lib/chai/utils/inspect.js","node_modules/chai/lib/chai/utils/objDisplay.js","node_modules/chai/lib/chai/utils/overwriteChainableMethod.js","node_modules/chai/lib/chai/utils/overwriteMethod.js","node_modules/chai/lib/chai/utils/overwriteProperty.js","node_modules/chai/lib/chai/utils/test.js","node_modules/chai/lib/chai/utils/transferFlags.js","node_modules/deep-eql/index.js","node_modules/deep-eql/lib/eql.js","node_modules/deep-eql/node_modules/type-detect/index.js","node_modules/deep-eql/node_modules/type-detect/lib/type.js","node_modules/localforage/dist/localforage.js","node_modules/type-detect/lib/type.js","src/js/index.js","src/problems/arrays.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length","1","module","exclude","excludeProps","res","obj","Object","keys","forEach","key","excludes","indexOf","slice","arguments","args","AssertionError","message","_props","ssf","extend","props","this","showDiff","callee","captureStackTrace","stack","prototype","create","name","constructor","toJSON","used","version","util","use","fn","push","config","assertion","core","expect","should","assert","_chai","Assertion","msg","flag","defineProperty","get","console","warn","includeStack","set","value","addProperty","addMethod","addChainableMethod","chainingBehavior","overwriteProperty","overwriteMethod","overwriteChainableMethod","expr","negateMsg","expected","_actual","ok","test","getMessage","actual","getActual","val","truncateThreshold","chai","_","an","type","toLowerCase","article","charAt","includeChainingBehavior","include","expectTypes","eql","k","property","subset","undefined","inspect","checkArguments","toString","assertEqual","_obj","assertEql","assertAbove","to","have","len","assertLeast","assertBelow","assertMost","assertInstanceOf","getName","assertOwnProperty","hasOwnProperty","assertOwnPropertyDescriptor","descriptor","actualDescriptor","getOwnPropertyDescriptor","assertLengthChain","assertLength","assertMatch","re","exec","assertKeys","str","mixedArgsMsg","Array","any","all","filter","every","map","last","pop","join","sort","assertThrows","errMsg","is","thrown","desiredError","thrownError","RegExp","err","actuallyGot","expectedThrown","respondTo","method","itself","context","satisfy","matcher","result","objDisplay","negate","closeTo","delta","Math","abs","isSubsetOf","superset","cmp","elem","some","elem2","oneOf","list","be","assertChanges","object","prop","initial","assertIncreases","assertDecreases","chain","isNaN","isArray","start","finish","range","isDeep","pathInfo","getPathInfo","hasProperty","exists","isExtensible","TypeError","isSealed","isFrozen","express","errmsg","fail","operator","isOk","isNotOk","not","equal","act","exp","notEqual","strictEqual","notStrictEqual","deepEqual","notDeepEqual","isAbove","abv","above","isAtLeast","atlst","least","isBelow","blw","below","isAtMost","atmst","most","isTrue","isNotTrue","isFalse","isNotFalse","isNull","isNotNull","NaN","isNotNaN","isUndefined","isDefined","isFunction","isNotFunction","isObject","isNotObject","isNotArray","isString","isNotString","isNumber","isNotNumber","isBoolean","isNotBoolean","typeOf","notTypeOf","instanceOf","notInstanceOf","inc","notInclude","match","notMatch","notProperty","deepProperty","deep","notDeepProperty","propertyVal","propertyNotVal","deepPropertyVal","deepPropertyNotVal","lengthOf","throws","errt","errs","assertErr","throw","doesNotThrow","Throw","val2","approximately","sameMembers","set1","set2","same","members","sameDeepMembers","includeMembers","includeDeepMembers","inList","changes","change","doesNotChange","increases","increase","doesNotIncrease","decreases","decrease","doesNotDecrease","ifError","extensible","isNotExtensible","sealed","isNotSealed","frozen","isNotFrozen","alias","as","loadShould","shouldGetter","String","Number","Boolean","valueOf","shouldSetter","enumerable","configurable","writable","val1","exist","Should","transferFlags","hasProtoSupport","excludeNames","Function","apply","ctx","chainableBehavior","__methods","__proto__","getOwnPropertyNames","asserterName","pd","getter","types","index","art","flags","__flags","flagMsg","replace","func","parsePath","path","mArr","parseFloat","p","_getPathValue","parsed","tmp","part","info","parent","proto","getPrototypeOf","literals","number","string","ot","getPathValue","showHidden","depth","colors","formatValue","seen","stylize","recurseTimes","ret","primitive","formatPrimitive","isDOMElement","outerHTML","document","xmlVersion","XMLSerializer","serializeToString","container","createElementNS","appendChild","cloneNode","html","innerHTML","visibleKeys","getEnumerableProperties","getProperties","isError","nameSuffix","isRegExp","isDate","Date","toUTCString","formatError","base","array","braces","output","formatArray","formatProperty","reduceToSingleString","simple","JSON","stringify","Infinity","__lookupGetter__","__lookupSetter__","split","line","substr","numLinesEst","reduce","prev","cur","ar","objectToString","d","HTMLElement","nodeType","nodeName","splice","_chainingBehavior","_method","_super","_get","includeAll","b","m","sameValue","dateEqual","regexpEqual","Buffer","isBuffer","bufferEqual","argumentsEqual","typeEqual","objectEqual","getTime","iterableEqual","isValue","ka","kb","ex","getType","natives","Library","tests","[object Array]","[object RegExp]","[object Function]","[object Arguments]","[object Date]","of","define","ReferenceError","amd","g","window","global","self","localforage","_dereq_","nextTick","draining","oldQueue","queue","immediate","task","scheduleDrain","Mutation","MutationObserver","WebKitMutationObserver","called","observer","element","createTextNode","observe","characterData","data","setImmediate","MessageChannel","createElement","scriptEl","onreadystatechange","parentNode","removeChild","documentElement","setTimeout","channel","port1","onmessage","port2","postMessage","2","INTERNAL","Promise","resolver","state","PENDING","outcome","safelyResolveThenable","QueueItem","promise","onFulfilled","onRejected","callFulfilled","otherCallFulfilled","callRejected","otherCallRejected","unwrap","returnValue","handlers","reject","resolve","getThen","then","thenable","onError","onSuccess","tryToUnwrap","tryCatch","status","out","reason","iterable","values","resolved","resolveFromAll","outValue","error","race","response","REJECTED","FULFILLED","3","4","_classCallCheck","instance","Constructor","createBlob","parts","properties","Blob","Builder","BlobBuilder","MSBlobBuilder","MozBlobBuilder","WebKitBlobBuilder","builder","append","getBlob","executeCallback","callback","executeTwoCallbacks","errorCallback","_binStringToArrayBuffer","bin","buf","ArrayBuffer","arr","Uint8Array","charCodeAt","_checkBlobSupportWithoutCaching","idb","Promise$1","txn","transaction","DETECT_BLOB_SUPPORT_STORE","blob","objectStore","put","onabort","preventDefault","stopPropagation","oncomplete","matchedChrome","navigator","userAgent","matchedEdge","parseInt","_checkBlobSupport","supportsBlobs","_deferReadiness","dbInfo","dbContext","dbContexts","deferredOperation","deferredOperations","dbReady","_advanceReadiness","_getConnection","upgradeNeeded","db","close","dbArgs","openreq","open","onupgradeneeded","createObjectStore","storeName","oldVersion","newVersion","onerror","onsuccess","_getOriginalConnection","_getUpgradedConnection","_isUpgradeNeeded","defaultVersion","isNewStore","objectStoreNames","contains","isDowngrade","isUpgrade","incVersion","_encodeBlob","reader","FileReader","onloadend","base64","btoa","target","__local_forage_encoded_blob","readAsBinaryString","_decodeBlob","encodedBlob","atob","_isEncodedBlob","_fullyReady","_initReady","_dbInfo","_initStorage","options","ignoreErrors","forages","ready","initPromises","j","forage","_defaultConfig","getItem","store","req","iterate","iterator","openCursor","iterationNumber","cursor","setItem","blobSupport","removeItem","clear","count","advanced","advance","stringToBuffer","serializedString","encoded1","encoded2","encoded3","encoded4","bufferLength","buffer","bytes","BASE_CHARS","bufferToString","base64String","substring","serialize","valueType","toString$1","marker","SERIALIZED_MARKER","TYPE_ARRAYBUFFER","TYPE_INT8ARRAY","TYPE_UINT8ARRAY","TYPE_UINT8CLAMPEDARRAY","TYPE_INT16ARRAY","TYPE_UINT16ARRAY","TYPE_INT32ARRAY","TYPE_UINT32ARRAY","TYPE_FLOAT32ARRAY","TYPE_FLOAT64ARRAY","fileReader","onload","BLOB_TYPE_PREFIX","TYPE_BLOB","readAsArrayBuffer","deserialize","SERIALIZED_MARKER_LENGTH","parse","blobType","TYPE_SERIALIZED_MARKER_LENGTH","BLOB_TYPE_PREFIX_REGEX","Int8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","_initStorage$1","dbInfoPromise","openDatabase","description","size","executeSql","serializer","localforageSerializer","getItem$1","results","rows","item","iterate$1","_setItem","retriesLeft","originalValue","sqlError","QUOTA_ERR","setItem$1","removeItem$1","clear$1","length$1","c","key$1","keys$1","_initStorage$2","keyPrefix","clear$2","localStorage","getItem$2","iterate$2","keyPrefixLength","key$2","keys$2","length$2","removeItem$2","setItem$2","callWhenReady","localForageInstance","libraryMethod","_args","arg","isLibraryDriver","driverName","driver","DriverType","_typeof","Symbol","indexedDB","webkitIndexedDB","mozIndexedDB","OIndexedDB","msIndexedDB","asyncStorage","_driver","webSQLStorage","localStorageWrapper","CustomDrivers","INDEXEDDB","LOCALSTORAGE","WEBSQL","DefaultDriverOrder","LibraryMethods","DefaultConfig","driverSupport","isSafari","platform","hasFetch","fetch","IDBKeyRange","LocalForage","_config","_driverSet","_initDriver","_ready","_wrapLibraryMethodsWithReady","setDriver","defineDriver","driverObject","complianceError","namingError","customDriverMethods","concat","customDriverMethod","supportPromise","_support","supportResult","getDriver","getDriverPromise","getSerializer","serializerPromise","drivers","setDriverToConfig","extendSelfWithDriver","_extend","initDriver","supportedDrivers","driverPromiseLoop","currentDriverIndex","_getSupportedDrivers","oldDriverSetDone","supports","libraryMethodsAndProperties","createInstance","localforage_js","objectTypeRegexp","updateLocalstore","catch","log","debounce","wait","timeout","later","callNow","clearTimeout","getRandomIndex","problemsArr","ind","floor","random","currentIndex","getPreviousIndex","getNextIndex","getCurrentProblem","previousProblem","previousProblemButtonEl","classList","add","shuffle","problems","location","reload","nextProblem","nextProblemButtonEl","toggleShuffle","shuffleProblemsButtonEl","toggle","loadProblem","problemObj","currentProblem","problemEl","innerText","prompt","given","codeEl","testSuite","updateTests","testStatus","init","buildTests","updateTestStatus","testsDom","testSuiteEl","testStatuses","allPassed","testPassed","querySelectorAll","testStatusEl","iter","remove","testTotalEl","printAssertError","errObj","inner","assertConsoleEl","printEvalOutput","evalConsoleEl","getOutput","tested","runTests","evald","eval","testOutcome","loadApp","problemNav","keyCode","shiftKey","metaKey","ctrlKey","debouncedInputValidation","ignoreKeyCodes","addEventListener","timer","getElementById","time","answer","evenNumbers","someOddNumbers"],"mappings":"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","file":"bundle.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o\n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n var excludes = [].slice.call(arguments);\n\n function excludeProps (res, obj) {\n Object.keys(obj).forEach(function (key) {\n if (!~excludes.indexOf(key)) res[key] = obj[key];\n });\n }\n\n return function extendExclude () {\n var args = [].slice.call(arguments)\n , i = 0\n , res = {};\n\n for (; i < args.length; i++) {\n excludeProps(res, args[i]);\n }\n\n return res;\n };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n , props = extend(_props || {});\n\n // default values\n this.message = message || 'Unspecified AssertionError';\n this.showDiff = false;\n\n // copy from properties\n for (var key in props) {\n this[key] = props[key];\n }\n\n // capture stack trace\n ssf = ssf || arguments.callee;\n if (ssf && Error.captureStackTrace) {\n Error.captureStackTrace(this, ssf);\n } else {\n try {\n throw new Error();\n } catch(e) {\n this.stack = e.stack;\n }\n }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n var extend = exclude('constructor', 'toJSON', 'stack')\n , props = extend({ name: this.name }, this);\n\n // include stack if exists and not turned off\n if (false !== stack && this.stack) {\n props.stack = this.stack;\n }\n\n return props;\n};\n","module.exports = require('./lib/chai');\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar used = []\n , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n if (!~used.indexOf(fn)) {\n fn(this, util);\n used.push(fn);\n }\n\n return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n /*!\n * Module dependencies.\n */\n\n var AssertionError = _chai.AssertionError\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n _chai.Assertion = Assertion;\n\n /*!\n * Assertion Constructor\n *\n * Creates object for chaining.\n *\n * @api private\n */\n\n function Assertion (obj, msg, stack) {\n flag(this, 'ssfi', stack || arguments.callee);\n flag(this, 'object', obj);\n flag(this, 'message', msg);\n }\n\n Object.defineProperty(Assertion, 'includeStack', {\n get: function() {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n return config.includeStack;\n },\n set: function(value) {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n config.includeStack = value;\n }\n });\n\n Object.defineProperty(Assertion, 'showDiff', {\n get: function() {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n return config.showDiff;\n },\n set: function(value) {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n config.showDiff = value;\n }\n });\n\n Assertion.addProperty = function (name, fn) {\n util.addProperty(this.prototype, name, fn);\n };\n\n Assertion.addMethod = function (name, fn) {\n util.addMethod(this.prototype, name, fn);\n };\n\n Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n Assertion.overwriteProperty = function (name, fn) {\n util.overwriteProperty(this.prototype, name, fn);\n };\n\n Assertion.overwriteMethod = function (name, fn) {\n util.overwriteMethod(this.prototype, name, fn);\n };\n\n Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n /**\n * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n *\n * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n *\n * @name assert\n * @param {Philosophical} expression to be tested\n * @param {String|Function} message or function that returns message to display if expression fails\n * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n * @param {Mixed} expected value (remember to check for negation)\n * @param {Mixed} actual (optional) will default to `this.obj`\n * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n * @api private\n */\n\n Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n var ok = util.test(this, arguments);\n if (true !== showDiff) showDiff = false;\n if (true !== config.showDiff) showDiff = false;\n\n if (!ok) {\n var msg = util.getMessage(this, arguments)\n , actual = util.getActual(this, arguments);\n throw new AssertionError(msg, {\n actual: actual\n , expected: expected\n , showDiff: showDiff\n }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n }\n };\n\n /*!\n * ### ._obj\n *\n * Quick reference to stored `actual` value for plugin developers.\n *\n * @api private\n */\n\n Object.defineProperty(Assertion.prototype, '_obj',\n { get: function () {\n return flag(this, 'object');\n }\n , set: function (val) {\n flag(this, 'object', val);\n }\n });\n};\n","module.exports = {\n\n /**\n * ### config.includeStack\n *\n * User configurable property, influences whether stack trace\n * is included in Assertion error message. Default of false\n * suppresses stack trace in the error message.\n *\n * chai.config.includeStack = true; // enable stack on error\n *\n * @param {Boolean}\n * @api public\n */\n\n includeStack: false,\n\n /**\n * ### config.showDiff\n *\n * User configurable property, influences whether or not\n * the `showDiff` flag should be included in the thrown\n * AssertionErrors. `false` will always be `false`; `true`\n * will be true when the assertion has requested a diff\n * be shown.\n *\n * @param {Boolean}\n * @api public\n */\n\n showDiff: true,\n\n /**\n * ### config.truncateThreshold\n *\n * User configurable property, sets length threshold for actual and\n * expected values in assertion errors. If this threshold is exceeded, for\n * example for large data structures, the value is replaced with something\n * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n *\n * Set it to zero if you want to disable truncating altogether.\n *\n * This is especially userful when doing assertions on arrays: having this\n * set to a reasonable large value makes the failure messages readily\n * inspectable.\n *\n * chai.config.truncateThreshold = 0; // disable truncating\n *\n * @param {Number}\n * @api public\n */\n\n truncateThreshold: 40\n\n};\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n var Assertion = chai.Assertion\n , toString = Object.prototype.toString\n , flag = _.flag;\n\n /**\n * ### Language Chains\n *\n * The following are provided as chainable getters to\n * improve the readability of your assertions. They\n * do not provide testing capabilities unless they\n * have been overwritten by a plugin.\n *\n * **Chains**\n *\n * - to\n * - be\n * - been\n * - is\n * - that\n * - which\n * - and\n * - has\n * - have\n * - with\n * - at\n * - of\n * - same\n *\n * @name language chains\n * @namespace BDD\n * @api public\n */\n\n [ 'to', 'be', 'been'\n , 'is', 'and', 'has', 'have'\n , 'with', 'that', 'which', 'at'\n , 'of', 'same' ].forEach(function (chain) {\n Assertion.addProperty(chain, function () {\n return this;\n });\n });\n\n /**\n * ### .not\n *\n * Negates any of assertions following in the chain.\n *\n * expect(foo).to.not.equal('bar');\n * expect(goodFn).to.not.throw(Error);\n * expect({ foo: 'baz' }).to.have.property('foo')\n * .and.not.equal('bar');\n *\n * @name not\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('not', function () {\n flag(this, 'negate', true);\n });\n\n /**\n * ### .deep\n *\n * Sets the `deep` flag, later used by the `equal` and\n * `property` assertions.\n *\n * expect(foo).to.deep.equal({ bar: 'baz' });\n * expect({ foo: { bar: { baz: 'quux' } } })\n * .to.have.deep.property('foo.bar.baz', 'quux');\n *\n * `.deep.property` special characters can be escaped\n * by adding two slashes before the `.` or `[]`.\n *\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name deep\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('deep', function () {\n flag(this, 'deep', true);\n });\n\n /**\n * ### .any\n *\n * Sets the `any` flag, (opposite of the `all` flag)\n * later used in the `keys` assertion.\n *\n * expect(foo).to.have.any.keys('bar', 'baz');\n *\n * @name any\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('any', function () {\n flag(this, 'any', true);\n flag(this, 'all', false)\n });\n\n\n /**\n * ### .all\n *\n * Sets the `all` flag (opposite of the `any` flag)\n * later used by the `keys` assertion.\n *\n * expect(foo).to.have.all.keys('bar', 'baz');\n *\n * @name all\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('all', function () {\n flag(this, 'all', true);\n flag(this, 'any', false);\n });\n\n /**\n * ### .a(type)\n *\n * The `a` and `an` assertions are aliases that can be\n * used either as language chains or to assert a value's\n * type.\n *\n * // typeof\n * expect('test').to.be.a('string');\n * expect({ foo: 'bar' }).to.be.an('object');\n * expect(null).to.be.a('null');\n * expect(undefined).to.be.an('undefined');\n * expect(new Error).to.be.an('error');\n * expect(new Promise).to.be.a('promise');\n * expect(new Float32Array()).to.be.a('float32array');\n * expect(Symbol()).to.be.a('symbol');\n *\n * // es6 overrides\n * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n *\n * // language chain\n * expect(foo).to.be.an.instanceof(Foo);\n *\n * @name a\n * @alias an\n * @param {String} type\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function an (type, msg) {\n if (msg) flag(this, 'message', msg);\n type = type.toLowerCase();\n var obj = flag(this, 'object')\n , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n this.assert(\n type === _.type(obj)\n , 'expected #{this} to be ' + article + type\n , 'expected #{this} not to be ' + article + type\n );\n }\n\n Assertion.addChainableMethod('an', an);\n Assertion.addChainableMethod('a', an);\n\n /**\n * ### .include(value)\n *\n * The `include` and `contain` assertions can be used as either property\n * based language chains or as methods to assert the inclusion of an object\n * in an array or a substring in a string. When used as language chains,\n * they toggle the `contains` flag for the `keys` assertion.\n *\n * expect([1,2,3]).to.include(2);\n * expect('foobar').to.contain('foo');\n * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n *\n * @name include\n * @alias contain\n * @alias includes\n * @alias contains\n * @param {Object|String|Number} obj\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function includeChainingBehavior () {\n flag(this, 'contains', true);\n }\n\n function include (val, msg) {\n _.expectTypes(this, ['array', 'object', 'string']);\n\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var expected = false;\n\n if (_.type(obj) === 'array' && _.type(val) === 'object') {\n for (var i in obj) {\n if (_.eql(obj[i], val)) {\n expected = true;\n break;\n }\n }\n } else if (_.type(val) === 'object') {\n if (!flag(this, 'negate')) {\n for (var k in val) new Assertion(obj).property(k, val[k]);\n return;\n }\n var subset = {};\n for (var k in val) subset[k] = obj[k];\n expected = _.eql(subset, val);\n } else {\n expected = (obj != undefined) && ~obj.indexOf(val);\n }\n this.assert(\n expected\n , 'expected #{this} to include ' + _.inspect(val)\n , 'expected #{this} to not include ' + _.inspect(val));\n }\n\n Assertion.addChainableMethod('include', include, includeChainingBehavior);\n Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n /**\n * ### .ok\n *\n * Asserts that the target is truthy.\n *\n * expect('everything').to.be.ok;\n * expect(1).to.be.ok;\n * expect(false).to.not.be.ok;\n * expect(undefined).to.not.be.ok;\n * expect(null).to.not.be.ok;\n *\n * @name ok\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('ok', function () {\n this.assert(\n flag(this, 'object')\n , 'expected #{this} to be truthy'\n , 'expected #{this} to be falsy');\n });\n\n /**\n * ### .true\n *\n * Asserts that the target is `true`.\n *\n * expect(true).to.be.true;\n * expect(1).to.not.be.true;\n *\n * @name true\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('true', function () {\n this.assert(\n true === flag(this, 'object')\n , 'expected #{this} to be true'\n , 'expected #{this} to be false'\n , this.negate ? false : true\n );\n });\n\n /**\n * ### .false\n *\n * Asserts that the target is `false`.\n *\n * expect(false).to.be.false;\n * expect(0).to.not.be.false;\n *\n * @name false\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('false', function () {\n this.assert(\n false === flag(this, 'object')\n , 'expected #{this} to be false'\n , 'expected #{this} to be true'\n , this.negate ? true : false\n );\n });\n\n /**\n * ### .null\n *\n * Asserts that the target is `null`.\n *\n * expect(null).to.be.null;\n * expect(undefined).to.not.be.null;\n *\n * @name null\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('null', function () {\n this.assert(\n null === flag(this, 'object')\n , 'expected #{this} to be null'\n , 'expected #{this} not to be null'\n );\n });\n\n /**\n * ### .undefined\n *\n * Asserts that the target is `undefined`.\n *\n * expect(undefined).to.be.undefined;\n * expect(null).to.not.be.undefined;\n *\n * @name undefined\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('undefined', function () {\n this.assert(\n undefined === flag(this, 'object')\n , 'expected #{this} to be undefined'\n , 'expected #{this} not to be undefined'\n );\n });\n\n /**\n * ### .NaN\n * Asserts that the target is `NaN`.\n *\n * expect('foo').to.be.NaN;\n * expect(4).not.to.be.NaN;\n *\n * @name NaN\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('NaN', function () {\n this.assert(\n isNaN(flag(this, 'object'))\n , 'expected #{this} to be NaN'\n , 'expected #{this} not to be NaN'\n );\n });\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi'\n * , bar = null\n * , baz;\n *\n * expect(foo).to.exist;\n * expect(bar).to.not.exist;\n * expect(baz).to.not.exist;\n *\n * @name exist\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('exist', function () {\n this.assert(\n null != flag(this, 'object')\n , 'expected #{this} to exist'\n , 'expected #{this} to not exist'\n );\n });\n\n\n /**\n * ### .empty\n *\n * Asserts that the target's length is `0`. For arrays and strings, it checks\n * the `length` property. For objects, it gets the count of\n * enumerable keys.\n *\n * expect([]).to.be.empty;\n * expect('').to.be.empty;\n * expect({}).to.be.empty;\n *\n * @name empty\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('empty', function () {\n var obj = flag(this, 'object')\n , expected = obj;\n\n if (Array.isArray(obj) || 'string' === typeof object) {\n expected = obj.length;\n } else if (typeof obj === 'object') {\n expected = Object.keys(obj).length;\n }\n\n this.assert(\n !expected\n , 'expected #{this} to be empty'\n , 'expected #{this} not to be empty'\n );\n });\n\n /**\n * ### .arguments\n *\n * Asserts that the target is an arguments object.\n *\n * function test () {\n * expect(arguments).to.be.arguments;\n * }\n *\n * @name arguments\n * @alias Arguments\n * @namespace BDD\n * @api public\n */\n\n function checkArguments () {\n var obj = flag(this, 'object')\n , type = Object.prototype.toString.call(obj);\n this.assert(\n '[object Arguments]' === type\n , 'expected #{this} to be arguments but got ' + type\n , 'expected #{this} to not be arguments'\n );\n }\n\n Assertion.addProperty('arguments', checkArguments);\n Assertion.addProperty('Arguments', checkArguments);\n\n /**\n * ### .equal(value)\n *\n * Asserts that the target is strictly equal (`===`) to `value`.\n * Alternately, if the `deep` flag is set, asserts that\n * the target is deeply equal to `value`.\n *\n * expect('hello').to.equal('hello');\n * expect(42).to.equal(42);\n * expect(1).to.not.equal(true);\n * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n *\n * @name equal\n * @alias equals\n * @alias eq\n * @alias deep.equal\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEqual (val, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'deep')) {\n return this.eql(val);\n } else {\n this.assert(\n val === obj\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{exp}'\n , val\n , this._obj\n , true\n );\n }\n }\n\n Assertion.addMethod('equal', assertEqual);\n Assertion.addMethod('equals', assertEqual);\n Assertion.addMethod('eq', assertEqual);\n\n /**\n * ### .eql(value)\n *\n * Asserts that the target is deeply equal to `value`.\n *\n * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n *\n * @name eql\n * @alias eqls\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEql(obj, msg) {\n if (msg) flag(this, 'message', msg);\n this.assert(\n _.eql(obj, flag(this, 'object'))\n , 'expected #{this} to deeply equal #{exp}'\n , 'expected #{this} to not deeply equal #{exp}'\n , obj\n , this._obj\n , true\n );\n }\n\n Assertion.addMethod('eql', assertEql);\n Assertion.addMethod('eqls', assertEql);\n\n /**\n * ### .above(value)\n *\n * Asserts that the target is greater than `value`.\n *\n * expect(10).to.be.above(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n *\n * @name above\n * @alias gt\n * @alias greaterThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertAbove (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len > n\n , 'expected #{this} to have a length above #{exp} but got #{act}'\n , 'expected #{this} to not have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj > n\n , 'expected #{this} to be above ' + n\n , 'expected #{this} to be at most ' + n\n );\n }\n }\n\n Assertion.addMethod('above', assertAbove);\n Assertion.addMethod('gt', assertAbove);\n Assertion.addMethod('greaterThan', assertAbove);\n\n /**\n * ### .least(value)\n *\n * Asserts that the target is greater than or equal to `value`.\n *\n * expect(10).to.be.at.least(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.least(2);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n *\n * @name least\n * @alias gte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLeast (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= n\n , 'expected #{this} to have a length at least #{exp} but got #{act}'\n , 'expected #{this} to have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj >= n\n , 'expected #{this} to be at least ' + n\n , 'expected #{this} to be below ' + n\n );\n }\n }\n\n Assertion.addMethod('least', assertLeast);\n Assertion.addMethod('gte', assertLeast);\n\n /**\n * ### .below(value)\n *\n * Asserts that the target is less than `value`.\n *\n * expect(5).to.be.below(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n *\n * @name below\n * @alias lt\n * @alias lessThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertBelow (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len < n\n , 'expected #{this} to have a length below #{exp} but got #{act}'\n , 'expected #{this} to not have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj < n\n , 'expected #{this} to be below ' + n\n , 'expected #{this} to be at least ' + n\n );\n }\n }\n\n Assertion.addMethod('below', assertBelow);\n Assertion.addMethod('lt', assertBelow);\n Assertion.addMethod('lessThan', assertBelow);\n\n /**\n * ### .most(value)\n *\n * Asserts that the target is less than or equal to `value`.\n *\n * expect(5).to.be.at.most(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.most(4);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n *\n * @name most\n * @alias lte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertMost (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len <= n\n , 'expected #{this} to have a length at most #{exp} but got #{act}'\n , 'expected #{this} to have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj <= n\n , 'expected #{this} to be at most ' + n\n , 'expected #{this} to be above ' + n\n );\n }\n }\n\n Assertion.addMethod('most', assertMost);\n Assertion.addMethod('lte', assertMost);\n\n /**\n * ### .within(start, finish)\n *\n * Asserts that the target is within a range.\n *\n * expect(7).to.be.within(5,10);\n *\n * Can also be used in conjunction with `length` to\n * assert a length range. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * @name within\n * @param {Number} start lowerbound inclusive\n * @param {Number} finish upperbound inclusive\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('within', function (start, finish, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , range = start + '..' + finish;\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= start && len <= finish\n , 'expected #{this} to have a length within ' + range\n , 'expected #{this} to not have a length within ' + range\n );\n } else {\n this.assert(\n obj >= start && obj <= finish\n , 'expected #{this} to be within ' + range\n , 'expected #{this} to not be within ' + range\n );\n }\n });\n\n /**\n * ### .instanceof(constructor)\n *\n * Asserts that the target is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , Chai = new Tea('chai');\n *\n * expect(Chai).to.be.an.instanceof(Tea);\n * expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n *\n * @name instanceof\n * @param {Constructor} constructor\n * @param {String} message _optional_\n * @alias instanceOf\n * @namespace BDD\n * @api public\n */\n\n function assertInstanceOf (constructor, msg) {\n if (msg) flag(this, 'message', msg);\n var name = _.getName(constructor);\n this.assert(\n flag(this, 'object') instanceof constructor\n , 'expected #{this} to be an instance of ' + name\n , 'expected #{this} to not be an instance of ' + name\n );\n };\n\n Assertion.addMethod('instanceof', assertInstanceOf);\n Assertion.addMethod('instanceOf', assertInstanceOf);\n\n /**\n * ### .property(name, [value])\n *\n * Asserts that the target has a property `name`, optionally asserting that\n * the value of that property is strictly equal to `value`.\n * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n * references into objects and arrays.\n *\n * // simple referencing\n * var obj = { foo: 'bar' };\n * expect(obj).to.have.property('foo');\n * expect(obj).to.have.property('foo', 'bar');\n *\n * // deep referencing\n * var deepObj = {\n * green: { tea: 'matcha' }\n * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n * };\n *\n * expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n *\n * You can also use an array as the starting point of a `deep.property`\n * assertion, or traverse nested arrays.\n *\n * var arr = [\n * [ 'chai', 'matcha', 'konacha' ]\n * , [ { tea: 'chai' }\n * , { tea: 'matcha' }\n * , { tea: 'konacha' } ]\n * ];\n *\n * expect(arr).to.have.deep.property('[0][1]', 'matcha');\n * expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n *\n * Furthermore, `property` changes the subject of the assertion\n * to be the value of that property from the original object. This\n * permits for further chainable assertions on that property.\n *\n * expect(obj).to.have.property('foo')\n * .that.is.a('string');\n * expect(deepObj).to.have.property('green')\n * .that.is.an('object')\n * .that.deep.equals({ tea: 'matcha' });\n * expect(deepObj).to.have.property('teas')\n * .that.is.an('array')\n * .with.deep.property('[2]')\n * .that.deep.equals({ tea: 'konacha' });\n *\n * Note that dots and bracket in `name` must be backslash-escaped when\n * the `deep` flag is set, while they must NOT be escaped when the `deep`\n * flag is not set.\n *\n * // simple referencing\n * var css = { '.link[target]': 42 };\n * expect(css).to.have.property('.link[target]', 42);\n *\n * // deep referencing\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name property\n * @alias deep.property\n * @param {String} name\n * @param {Mixed} value (optional)\n * @param {String} message _optional_\n * @returns value of property for chaining\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('property', function (name, val, msg) {\n if (msg) flag(this, 'message', msg);\n\n var isDeep = !!flag(this, 'deep')\n , descriptor = isDeep ? 'deep property ' : 'property '\n , negate = flag(this, 'negate')\n , obj = flag(this, 'object')\n , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n , hasProperty = isDeep\n ? pathInfo.exists\n : _.hasProperty(name, obj)\n , value = isDeep\n ? pathInfo.value\n : obj[name];\n\n if (negate && arguments.length > 1) {\n if (undefined === value) {\n msg = (msg != null) ? msg + ': ' : '';\n throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n }\n } else {\n this.assert(\n hasProperty\n , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n }\n\n if (arguments.length > 1) {\n this.assert(\n val === value\n , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n , val\n , value\n );\n }\n\n flag(this, 'object', value);\n });\n\n\n /**\n * ### .ownProperty(name)\n *\n * Asserts that the target has an own property `name`.\n *\n * expect('test').to.have.ownProperty('length');\n *\n * @name ownProperty\n * @alias haveOwnProperty\n * @param {String} name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnProperty (name, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n obj.hasOwnProperty(name)\n , 'expected #{this} to have own property ' + _.inspect(name)\n , 'expected #{this} to not have own property ' + _.inspect(name)\n );\n }\n\n Assertion.addMethod('ownProperty', assertOwnProperty);\n Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n /**\n * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n *\n * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n *\n * expect('test').to.have.ownPropertyDescriptor('length');\n * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n * expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n *\n * @name ownPropertyDescriptor\n * @alias haveOwnPropertyDescriptor\n * @param {String} name\n * @param {Object} descriptor _optional_\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnPropertyDescriptor (name, descriptor, msg) {\n if (typeof descriptor === 'string') {\n msg = descriptor;\n descriptor = null;\n }\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n if (actualDescriptor && descriptor) {\n this.assert(\n _.eql(descriptor, actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n , descriptor\n , actualDescriptor\n , true\n );\n } else {\n this.assert(\n actualDescriptor\n , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n );\n }\n flag(this, 'object', actualDescriptor);\n }\n\n Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n /**\n * ### .length\n *\n * Sets the `doLength` flag later used as a chain precursor to a value\n * comparison for the `length` property.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * *Deprecation notice:* Using `length` as an assertion will be deprecated\n * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n * asserting for `length` property value using `length(value)` should be\n * switched to use `lengthOf(value)` instead.\n *\n * @name length\n * @namespace BDD\n * @api public\n */\n\n /**\n * ### .lengthOf(value[, message])\n *\n * Asserts that the target's `length` property has\n * the expected value.\n *\n * expect([ 1, 2, 3]).to.have.lengthOf(3);\n * expect('foobar').to.have.lengthOf(6);\n *\n * @name lengthOf\n * @param {Number} length\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLengthChain () {\n flag(this, 'doLength', true);\n }\n\n function assertLength (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n\n this.assert(\n len == n\n , 'expected #{this} to have a length of #{exp} but got #{act}'\n , 'expected #{this} to not have a length of #{act}'\n , n\n , len\n );\n }\n\n Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n Assertion.addMethod('lengthOf', assertLength);\n\n /**\n * ### .match(regexp)\n *\n * Asserts that the target matches a regular expression.\n *\n * expect('foobar').to.match(/^foo/);\n *\n * @name match\n * @alias matches\n * @param {RegExp} RegularExpression\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n function assertMatch(re, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n re.exec(obj)\n , 'expected #{this} to match ' + re\n , 'expected #{this} not to match ' + re\n );\n }\n\n Assertion.addMethod('match', assertMatch);\n Assertion.addMethod('matches', assertMatch);\n\n /**\n * ### .string(string)\n *\n * Asserts that the string target contains another string.\n *\n * expect('foobar').to.have.string('bar');\n *\n * @name string\n * @param {String} string\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('string', function (str, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('string');\n\n this.assert(\n ~obj.indexOf(str)\n , 'expected #{this} to contain ' + _.inspect(str)\n , 'expected #{this} to not contain ' + _.inspect(str)\n );\n });\n\n\n /**\n * ### .keys(key1, [key2], [...])\n *\n * Asserts that the target contains any or all of the passed-in keys.\n * Use in combination with `any`, `all`, `contains`, or `have` will affect\n * what will pass.\n *\n * When used in conjunction with `any`, at least one key that is passed\n * in must exist in the target object. This is regardless whether or not\n * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n * should be used in the assertion. If neither are used, the assertion is\n * defaulted to `all`.\n *\n * When both `all` and `contain` are used, the target object must have at\n * least all of the passed-in keys but may have more keys not listed.\n *\n * When both `all` and `have` are used, the target object must both contain\n * all of the passed-in keys AND the number of keys in the target object must\n * match the number of keys passed in (in other words, a target object must\n * have all and only all of the passed-in keys).\n *\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n *\n *\n * @name keys\n * @alias key\n * @param {...String|Array|Object} keys\n * @namespace BDD\n * @api public\n */\n\n function assertKeys (keys) {\n var obj = flag(this, 'object')\n , str\n , ok = true\n , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n switch (_.type(keys)) {\n case \"array\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n break;\n case \"object\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n keys = Object.keys(keys);\n break;\n default:\n keys = Array.prototype.slice.call(arguments);\n }\n\n if (!keys.length) throw new Error('keys required');\n\n var actual = Object.keys(obj)\n , expected = keys\n , len = keys.length\n , any = flag(this, 'any')\n , all = flag(this, 'all');\n\n if (!any && !all) {\n all = true;\n }\n\n // Has any\n if (any) {\n var intersection = expected.filter(function(key) {\n return ~actual.indexOf(key);\n });\n ok = intersection.length > 0;\n }\n\n // Has all\n if (all) {\n ok = keys.every(function(key){\n return ~actual.indexOf(key);\n });\n if (!flag(this, 'negate') && !flag(this, 'contains')) {\n ok = ok && keys.length == actual.length;\n }\n }\n\n // Key string\n if (len > 1) {\n keys = keys.map(function(key){\n return _.inspect(key);\n });\n var last = keys.pop();\n if (all) {\n str = keys.join(', ') + ', and ' + last;\n }\n if (any) {\n str = keys.join(', ') + ', or ' + last;\n }\n } else {\n str = _.inspect(keys[0]);\n }\n\n // Form\n str = (len > 1 ? 'keys ' : 'key ') + str;\n\n // Have / include\n str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n // Assertion\n this.assert(\n ok\n , 'expected #{this} to ' + str\n , 'expected #{this} to not ' + str\n , expected.slice(0).sort()\n , actual.sort()\n , true\n );\n }\n\n Assertion.addMethod('keys', assertKeys);\n Assertion.addMethod('key', assertKeys);\n\n /**\n * ### .throw(constructor)\n *\n * Asserts that the function target will throw a specific error, or specific type of error\n * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n * for the error's message.\n *\n * var err = new ReferenceError('This is a bad function.');\n * var fn = function () { throw err; }\n * expect(fn).to.throw(ReferenceError);\n * expect(fn).to.throw(Error);\n * expect(fn).to.throw(/bad function/);\n * expect(fn).to.not.throw('good function');\n * expect(fn).to.throw(ReferenceError, /bad function/);\n * expect(fn).to.throw(err);\n *\n * Please note that when a throw expectation is negated, it will check each\n * parameter independently, starting with error constructor type. The appropriate way\n * to check for the existence of a type of error but for a message that does not match\n * is to use `and`.\n *\n * expect(fn).to.throw(ReferenceError)\n * .and.not.throw(/good function/);\n *\n * @name throw\n * @alias throws\n * @alias Throw\n * @param {ErrorConstructor} constructor\n * @param {String|RegExp} expected error message\n * @param {String} message _optional_\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @returns error for chaining (null if no error)\n * @namespace BDD\n * @api public\n */\n\n function assertThrows (constructor, errMsg, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('function');\n\n var thrown = false\n , desiredError = null\n , name = null\n , thrownError = null;\n\n if (arguments.length === 0) {\n errMsg = null;\n constructor = null;\n } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n errMsg = constructor;\n constructor = null;\n } else if (constructor && constructor instanceof Error) {\n desiredError = constructor;\n constructor = null;\n errMsg = null;\n } else if (typeof constructor === 'function') {\n name = constructor.prototype.name;\n if (!name || (name === 'Error' && constructor !== Error)) {\n name = constructor.name || (new constructor()).name;\n }\n } else {\n constructor = null;\n }\n\n try {\n obj();\n } catch (err) {\n // first, check desired error\n if (desiredError) {\n this.assert(\n err === desiredError\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp}'\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (err instanceof Error ? err.toString() : err)\n );\n\n flag(this, 'object', err);\n return this;\n }\n\n // next, check constructor\n if (constructor) {\n this.assert(\n err instanceof constructor\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n , name\n , (err instanceof Error ? err.toString() : err)\n );\n\n if (!errMsg) {\n flag(this, 'object', err);\n return this;\n }\n }\n\n // next, check message\n var message = 'error' === _.type(err) && \"message\" in err\n ? err.message\n : '' + err;\n\n if ((message != null) && errMsg && errMsg instanceof RegExp) {\n this.assert(\n errMsg.exec(message)\n , 'expected #{this} to throw error matching #{exp} but got #{act}'\n , 'expected #{this} to throw error not matching #{exp}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n this.assert(\n ~message.indexOf(errMsg)\n , 'expected #{this} to throw error including #{exp} but got #{act}'\n , 'expected #{this} to throw error not including #{act}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else {\n thrown = true;\n thrownError = err;\n }\n }\n\n var actuallyGot = ''\n , expectedThrown = name !== null\n ? name\n : desiredError\n ? '#{exp}' //_.inspect(desiredError)\n : 'an error';\n\n if (thrown) {\n actuallyGot = ' but #{act} was thrown'\n }\n\n this.assert(\n thrown === true\n , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n );\n\n flag(this, 'object', thrownError);\n };\n\n Assertion.addMethod('throw', assertThrows);\n Assertion.addMethod('throws', assertThrows);\n Assertion.addMethod('Throw', assertThrows);\n\n /**\n * ### .respondTo(method)\n *\n * Asserts that the object or class target will respond to a method.\n *\n * Klass.prototype.bar = function(){};\n * expect(Klass).to.respondTo('bar');\n * expect(obj).to.respondTo('bar');\n *\n * To check if a constructor will respond to a static function,\n * set the `itself` flag.\n *\n * Klass.baz = function(){};\n * expect(Klass).itself.to.respondTo('baz');\n *\n * @name respondTo\n * @alias respondsTo\n * @param {String} method\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function respondTo (method, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , itself = flag(this, 'itself')\n , context = ('function' === _.type(obj) && !itself)\n ? obj.prototype[method]\n : obj[method];\n\n this.assert(\n 'function' === typeof context\n , 'expected #{this} to respond to ' + _.inspect(method)\n , 'expected #{this} to not respond to ' + _.inspect(method)\n );\n }\n\n Assertion.addMethod('respondTo', respondTo);\n Assertion.addMethod('respondsTo', respondTo);\n\n /**\n * ### .itself\n *\n * Sets the `itself` flag, later used by the `respondTo` assertion.\n *\n * function Foo() {}\n * Foo.bar = function() {}\n * Foo.prototype.baz = function() {}\n *\n * expect(Foo).itself.to.respondTo('bar');\n * expect(Foo).itself.not.to.respondTo('baz');\n *\n * @name itself\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('itself', function () {\n flag(this, 'itself', true);\n });\n\n /**\n * ### .satisfy(method)\n *\n * Asserts that the target passes a given truth test.\n *\n * expect(1).to.satisfy(function(num) { return num > 0; });\n *\n * @name satisfy\n * @alias satisfies\n * @param {Function} matcher\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function satisfy (matcher, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var result = matcher(obj);\n this.assert(\n result\n , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n , this.negate ? false : true\n , result\n );\n }\n\n Assertion.addMethod('satisfy', satisfy);\n Assertion.addMethod('satisfies', satisfy);\n\n /**\n * ### .closeTo(expected, delta)\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * expect(1.5).to.be.closeTo(1, 0.5);\n *\n * @name closeTo\n * @alias approximately\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function closeTo(expected, delta, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj, msg).is.a('number');\n if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n throw new Error('the arguments to closeTo or approximately must be numbers');\n }\n\n this.assert(\n Math.abs(obj - expected) <= delta\n , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n );\n }\n\n Assertion.addMethod('closeTo', closeTo);\n Assertion.addMethod('approximately', closeTo);\n\n function isSubsetOf(subset, superset, cmp) {\n return subset.every(function(elem) {\n if (!cmp) return superset.indexOf(elem) !== -1;\n\n return superset.some(function(elem2) {\n return cmp(elem, elem2);\n });\n })\n }\n\n /**\n * ### .members(set)\n *\n * Asserts that the target is a superset of `set`,\n * or that the target and `set` have the same strictly-equal (===) members.\n * Alternately, if the `deep` flag is set, set members are compared for deep\n * equality.\n *\n * expect([1, 2, 3]).to.include.members([3, 2]);\n * expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n *\n * expect([4, 2]).to.have.members([2, 4]);\n * expect([5, 2]).to.not.have.members([5, 2, 1]);\n *\n * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n *\n * @name members\n * @param {Array} set\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('members', function (subset, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj).to.be.an('array');\n new Assertion(subset).to.be.an('array');\n\n var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n if (flag(this, 'contains')) {\n return this.assert(\n isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to be a superset of #{act}'\n , 'expected #{this} to not be a superset of #{act}'\n , obj\n , subset\n );\n }\n\n this.assert(\n isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to have the same members as #{act}'\n , 'expected #{this} to not have the same members as #{act}'\n , obj\n , subset\n );\n });\n\n /**\n * ### .oneOf(list)\n *\n * Assert that a value appears somewhere in the top level of array `list`.\n *\n * expect('a').to.be.oneOf(['a', 'b', 'c']);\n * expect(9).to.not.be.oneOf(['z']);\n * expect([3]).to.not.be.oneOf([1, 2, [3]]);\n *\n * var three = [3];\n * // for object-types, contents are not compared\n * expect(three).to.not.be.oneOf([1, 2, [3]]);\n * // comparing references works\n * expect(three).to.be.oneOf([1, 2, three]);\n *\n * @name oneOf\n * @param {Array<*>} list\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function oneOf (list, msg) {\n if (msg) flag(this, 'message', msg);\n var expected = flag(this, 'object');\n new Assertion(list).to.be.an('array');\n\n this.assert(\n list.indexOf(expected) > -1\n , 'expected #{this} to be one of #{exp}'\n , 'expected #{this} to not be one of #{exp}'\n , list\n , expected\n );\n }\n\n Assertion.addMethod('oneOf', oneOf);\n\n\n /**\n * ### .change(function)\n *\n * Asserts that a function changes an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val += 3 };\n * var noChangeFn = function() { return 'foo' + 'bar'; }\n * expect(fn).to.change(obj, 'val');\n * expect(noChangeFn).to.not.change(obj, 'val')\n *\n * @name change\n * @alias changes\n * @alias Change\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertChanges (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n initial !== object[prop]\n , 'expected .' + prop + ' to change'\n , 'expected .' + prop + ' to not change'\n );\n }\n\n Assertion.addChainableMethod('change', assertChanges);\n Assertion.addChainableMethod('changes', assertChanges);\n\n /**\n * ### .increase(function)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * expect(fn).to.increase(obj, 'val');\n *\n * @name increase\n * @alias increases\n * @alias Increase\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertIncreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial > 0\n , 'expected .' + prop + ' to increase'\n , 'expected .' + prop + ' to not increase'\n );\n }\n\n Assertion.addChainableMethod('increase', assertIncreases);\n Assertion.addChainableMethod('increases', assertIncreases);\n\n /**\n * ### .decrease(function)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * expect(fn).to.decrease(obj, 'val');\n *\n * @name decrease\n * @alias decreases\n * @alias Decrease\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertDecreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial < 0\n , 'expected .' + prop + ' to decrease'\n , 'expected .' + prop + ' to not decrease'\n );\n }\n\n Assertion.addChainableMethod('decrease', assertDecreases);\n Assertion.addChainableMethod('decreases', assertDecreases);\n\n /**\n * ### .extensible\n *\n * Asserts that the target is extensible (can have new properties added to\n * it).\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect({}).to.be.extensible;\n * expect(nonExtensibleObject).to.not.be.extensible;\n * expect(sealedObject).to.not.be.extensible;\n * expect(frozenObject).to.not.be.extensible;\n *\n * @name extensible\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('extensible', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isExtensible;\n\n try {\n isExtensible = Object.isExtensible(obj);\n } catch (err) {\n if (err instanceof TypeError) isExtensible = false;\n else throw err;\n }\n\n this.assert(\n isExtensible\n , 'expected #{this} to be extensible'\n , 'expected #{this} to not be extensible'\n );\n });\n\n /**\n * ### .sealed\n *\n * Asserts that the target is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect(sealedObject).to.be.sealed;\n * expect(frozenObject).to.be.sealed;\n * expect({}).to.not.be.sealed;\n *\n * @name sealed\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('sealed', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isSealed;\n\n try {\n isSealed = Object.isSealed(obj);\n } catch (err) {\n if (err instanceof TypeError) isSealed = true;\n else throw err;\n }\n\n this.assert(\n isSealed\n , 'expected #{this} to be sealed'\n , 'expected #{this} to not be sealed'\n );\n });\n\n /**\n * ### .frozen\n *\n * Asserts that the target is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n *\n * expect(frozenObject).to.be.frozen;\n * expect({}).to.not.be.frozen;\n *\n * @name frozen\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('frozen', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isFrozen;\n\n try {\n isFrozen = Object.isFrozen(obj);\n } catch (err) {\n if (err instanceof TypeError) isFrozen = true;\n else throw err;\n }\n\n this.assert(\n isFrozen\n , 'expected #{this} to be frozen'\n , 'expected #{this} to not be frozen'\n );\n });\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n /*!\n * Chai dependencies.\n */\n\n var Assertion = chai.Assertion\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n /**\n * ### assert(expression, message)\n *\n * Write your own test expressions.\n *\n * assert('foo' !== 'bar', 'foo is not bar');\n * assert(Array.isArray([]), 'empty arrays are arrays');\n *\n * @param {Mixed} expression to test for truthiness\n * @param {String} message to display on error\n * @name assert\n * @namespace Assert\n * @api public\n */\n\n var assert = chai.assert = function (express, errmsg) {\n var test = new Assertion(null, null, chai.assert);\n test.assert(\n express\n , errmsg\n , '[ negation message unavailable ]'\n );\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure. Node.js `assert` module-compatible.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Assert\n * @api public\n */\n\n assert.fail = function (actual, expected, message, operator) {\n message = message || 'assert.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, assert.fail);\n };\n\n /**\n * ### .isOk(object, [message])\n *\n * Asserts that `object` is truthy.\n *\n * assert.isOk('everything', 'everything is ok');\n * assert.isOk(false, 'this will fail');\n *\n * @name isOk\n * @alias ok\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isOk = function (val, msg) {\n new Assertion(val, msg).is.ok;\n };\n\n /**\n * ### .isNotOk(object, [message])\n *\n * Asserts that `object` is falsy.\n *\n * assert.isNotOk('everything', 'this will fail');\n * assert.isNotOk(false, 'this will pass');\n *\n * @name isNotOk\n * @alias notOk\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotOk = function (val, msg) {\n new Assertion(val, msg).is.not.ok;\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * assert.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.equal = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.equal);\n\n test.assert(\n exp == flag(test, 'object')\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .notEqual(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * assert.notEqual(3, 4, 'these numbers are not equal');\n *\n * @name notEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notEqual = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.notEqual);\n\n test.assert(\n exp != flag(test, 'object')\n , 'expected #{this} to not equal #{exp}'\n , 'expected #{this} to equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .strictEqual(actual, expected, [message])\n *\n * Asserts strict equality (`===`) of `actual` and `expected`.\n *\n * assert.strictEqual(true, true, 'these booleans are strictly equal');\n *\n * @name strictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.strictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.equal(exp);\n };\n\n /**\n * ### .notStrictEqual(actual, expected, [message])\n *\n * Asserts strict inequality (`!==`) of `actual` and `expected`.\n *\n * assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n *\n * @name notStrictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notStrictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.equal(exp);\n };\n\n /**\n * ### .deepEqual(actual, expected, [message])\n *\n * Asserts that `actual` is deeply equal to `expected`.\n *\n * assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n *\n * @name deepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.eql(exp);\n };\n\n /**\n * ### .notDeepEqual(actual, expected, [message])\n *\n * Assert that `actual` is not deeply equal to `expected`.\n *\n * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n *\n * @name notDeepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.eql(exp);\n };\n\n /**\n * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n *\n * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n *\n * assert.isAbove(5, 2, '5 is strictly greater than 2');\n *\n * @name isAbove\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAbove\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAbove = function (val, abv, msg) {\n new Assertion(val, msg).to.be.above(abv);\n };\n\n /**\n * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n *\n * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n *\n * assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n * assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n *\n * @name isAtLeast\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtLeast\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtLeast = function (val, atlst, msg) {\n new Assertion(val, msg).to.be.least(atlst);\n };\n\n /**\n * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n *\n * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n *\n * assert.isBelow(3, 6, '3 is strictly less than 6');\n *\n * @name isBelow\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeBelow\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBelow = function (val, blw, msg) {\n new Assertion(val, msg).to.be.below(blw);\n };\n\n /**\n * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n *\n * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n *\n * assert.isAtMost(3, 6, '3 is less than or equal to 6');\n * assert.isAtMost(4, 4, '4 is less than or equal to 4');\n *\n * @name isAtMost\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtMost\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtMost = function (val, atmst, msg) {\n new Assertion(val, msg).to.be.most(atmst);\n };\n\n /**\n * ### .isTrue(value, [message])\n *\n * Asserts that `value` is true.\n *\n * var teaServed = true;\n * assert.isTrue(teaServed, 'the tea has been served');\n *\n * @name isTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isTrue = function (val, msg) {\n new Assertion(val, msg).is['true'];\n };\n\n /**\n * ### .isNotTrue(value, [message])\n *\n * Asserts that `value` is not true.\n *\n * var tea = 'tasty chai';\n * assert.isNotTrue(tea, 'great, time for tea!');\n *\n * @name isNotTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotTrue = function (val, msg) {\n new Assertion(val, msg).to.not.equal(true);\n };\n\n /**\n * ### .isFalse(value, [message])\n *\n * Asserts that `value` is false.\n *\n * var teaServed = false;\n * assert.isFalse(teaServed, 'no tea yet? hmm...');\n *\n * @name isFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFalse = function (val, msg) {\n new Assertion(val, msg).is['false'];\n };\n\n /**\n * ### .isNotFalse(value, [message])\n *\n * Asserts that `value` is not false.\n *\n * var tea = 'tasty chai';\n * assert.isNotFalse(tea, 'great, time for tea!');\n *\n * @name isNotFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFalse = function (val, msg) {\n new Assertion(val, msg).to.not.equal(false);\n };\n\n /**\n * ### .isNull(value, [message])\n *\n * Asserts that `value` is null.\n *\n * assert.isNull(err, 'there was no error');\n *\n * @name isNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNull = function (val, msg) {\n new Assertion(val, msg).to.equal(null);\n };\n\n /**\n * ### .isNotNull(value, [message])\n *\n * Asserts that `value` is not null.\n *\n * var tea = 'tasty chai';\n * assert.isNotNull(tea, 'great, time for tea!');\n *\n * @name isNotNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNull = function (val, msg) {\n new Assertion(val, msg).to.not.equal(null);\n };\n\n /**\n * ### .isNaN\n * Asserts that value is NaN\n *\n * assert.isNaN('foo', 'foo is NaN');\n *\n * @name isNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNaN = function (val, msg) {\n new Assertion(val, msg).to.be.NaN;\n };\n\n /**\n * ### .isNotNaN\n * Asserts that value is not NaN\n *\n * assert.isNotNaN(4, '4 is not NaN');\n *\n * @name isNotNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n assert.isNotNaN = function (val, msg) {\n new Assertion(val, msg).not.to.be.NaN;\n };\n\n /**\n * ### .isUndefined(value, [message])\n *\n * Asserts that `value` is `undefined`.\n *\n * var tea;\n * assert.isUndefined(tea, 'no tea defined');\n *\n * @name isUndefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isUndefined = function (val, msg) {\n new Assertion(val, msg).to.equal(undefined);\n };\n\n /**\n * ### .isDefined(value, [message])\n *\n * Asserts that `value` is not `undefined`.\n *\n * var tea = 'cup of chai';\n * assert.isDefined(tea, 'tea has been defined');\n *\n * @name isDefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isDefined = function (val, msg) {\n new Assertion(val, msg).to.not.equal(undefined);\n };\n\n /**\n * ### .isFunction(value, [message])\n *\n * Asserts that `value` is a function.\n *\n * function serveTea() { return 'cup of tea'; };\n * assert.isFunction(serveTea, 'great, we can have tea now');\n *\n * @name isFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFunction = function (val, msg) {\n new Assertion(val, msg).to.be.a('function');\n };\n\n /**\n * ### .isNotFunction(value, [message])\n *\n * Asserts that `value` is _not_ a function.\n *\n * var serveTea = [ 'heat', 'pour', 'sip' ];\n * assert.isNotFunction(serveTea, 'great, we have listed the steps');\n *\n * @name isNotFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFunction = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('function');\n };\n\n /**\n * ### .isObject(value, [message])\n *\n * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n * _The assertion does not match subclassed objects._\n *\n * var selection = { name: 'Chai', serve: 'with spices' };\n * assert.isObject(selection, 'tea selection is an object');\n *\n * @name isObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isObject = function (val, msg) {\n new Assertion(val, msg).to.be.a('object');\n };\n\n /**\n * ### .isNotObject(value, [message])\n *\n * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n *\n * var selection = 'chai'\n * assert.isNotObject(selection, 'tea selection is not an object');\n * assert.isNotObject(null, 'null is not an object');\n *\n * @name isNotObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotObject = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('object');\n };\n\n /**\n * ### .isArray(value, [message])\n *\n * Asserts that `value` is an array.\n *\n * var menu = [ 'green', 'chai', 'oolong' ];\n * assert.isArray(menu, 'what kind of tea do we want?');\n *\n * @name isArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isArray = function (val, msg) {\n new Assertion(val, msg).to.be.an('array');\n };\n\n /**\n * ### .isNotArray(value, [message])\n *\n * Asserts that `value` is _not_ an array.\n *\n * var menu = 'green|chai|oolong';\n * assert.isNotArray(menu, 'what kind of tea do we want?');\n *\n * @name isNotArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotArray = function (val, msg) {\n new Assertion(val, msg).to.not.be.an('array');\n };\n\n /**\n * ### .isString(value, [message])\n *\n * Asserts that `value` is a string.\n *\n * var teaOrder = 'chai';\n * assert.isString(teaOrder, 'order placed');\n *\n * @name isString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isString = function (val, msg) {\n new Assertion(val, msg).to.be.a('string');\n };\n\n /**\n * ### .isNotString(value, [message])\n *\n * Asserts that `value` is _not_ a string.\n *\n * var teaOrder = 4;\n * assert.isNotString(teaOrder, 'order placed');\n *\n * @name isNotString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotString = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('string');\n };\n\n /**\n * ### .isNumber(value, [message])\n *\n * Asserts that `value` is a number.\n *\n * var cups = 2;\n * assert.isNumber(cups, 'how many cups');\n *\n * @name isNumber\n * @param {Number} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNumber = function (val, msg) {\n new Assertion(val, msg).to.be.a('number');\n };\n\n /**\n * ### .isNotNumber(value, [message])\n *\n * Asserts that `value` is _not_ a number.\n *\n * var cups = '2 cups please';\n * assert.isNotNumber(cups, 'how many cups');\n *\n * @name isNotNumber\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNumber = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('number');\n };\n\n /**\n * ### .isBoolean(value, [message])\n *\n * Asserts that `value` is a boolean.\n *\n * var teaReady = true\n * , teaServed = false;\n *\n * assert.isBoolean(teaReady, 'is the tea ready');\n * assert.isBoolean(teaServed, 'has tea been served');\n *\n * @name isBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBoolean = function (val, msg) {\n new Assertion(val, msg).to.be.a('boolean');\n };\n\n /**\n * ### .isNotBoolean(value, [message])\n *\n * Asserts that `value` is _not_ a boolean.\n *\n * var teaReady = 'yep'\n * , teaServed = 'nope';\n *\n * assert.isNotBoolean(teaReady, 'is the tea ready');\n * assert.isNotBoolean(teaServed, 'has tea been served');\n *\n * @name isNotBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotBoolean = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('boolean');\n };\n\n /**\n * ### .typeOf(value, name, [message])\n *\n * Asserts that `value`'s type is `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n * assert.typeOf('tea', 'string', 'we have a string');\n * assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n * assert.typeOf(null, 'null', 'we have a null');\n * assert.typeOf(undefined, 'undefined', 'we have an undefined');\n *\n * @name typeOf\n * @param {Mixed} value\n * @param {String} name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.typeOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.a(type);\n };\n\n /**\n * ### .notTypeOf(value, name, [message])\n *\n * Asserts that `value`'s type is _not_ `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.notTypeOf('tea', 'number', 'strings are not numbers');\n *\n * @name notTypeOf\n * @param {Mixed} value\n * @param {String} typeof name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notTypeOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.a(type);\n };\n\n /**\n * ### .instanceOf(object, constructor, [message])\n *\n * Asserts that `value` is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new Tea('chai');\n *\n * assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n *\n * @name instanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.instanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.instanceOf(type);\n };\n\n /**\n * ### .notInstanceOf(object, constructor, [message])\n *\n * Asserts `value` is not an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new String('chai');\n *\n * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n *\n * @name notInstanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInstanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.instanceOf(type);\n };\n\n /**\n * ### .include(haystack, needle, [message])\n *\n * Asserts that `haystack` includes `needle`. Works\n * for strings and arrays.\n *\n * assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n * assert.include([ 1, 2, 3 ], 3, 'array contains value');\n *\n * @name include\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.include = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.include).include(inc);\n };\n\n /**\n * ### .notInclude(haystack, needle, [message])\n *\n * Asserts that `haystack` does not include `needle`. Works\n * for strings and arrays.\n *\n * assert.notInclude('foobar', 'baz', 'string not include substring');\n * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n *\n * @name notInclude\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInclude = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.notInclude).not.include(inc);\n };\n\n /**\n * ### .match(value, regexp, [message])\n *\n * Asserts that `value` matches the regular expression `regexp`.\n *\n * assert.match('foobar', /^foo/, 'regexp matches');\n *\n * @name match\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.match = function (exp, re, msg) {\n new Assertion(exp, msg).to.match(re);\n };\n\n /**\n * ### .notMatch(value, regexp, [message])\n *\n * Asserts that `value` does not match the regular expression `regexp`.\n *\n * assert.notMatch('foobar', /^foo/, 'regexp does not match');\n *\n * @name notMatch\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notMatch = function (exp, re, msg) {\n new Assertion(exp, msg).to.not.match(re);\n };\n\n /**\n * ### .property(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`.\n *\n * assert.property({ tea: { green: 'matcha' }}, 'tea');\n *\n * @name property\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.property = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.property(prop);\n };\n\n /**\n * ### .notProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`.\n *\n * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n *\n * @name notProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.property(prop);\n };\n\n /**\n * ### .deepProperty(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`, which can be a\n * string using dot- and bracket-notation for deep reference.\n *\n * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n *\n * @name deepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop);\n };\n\n /**\n * ### .notDeepProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`, which\n * can be a string using dot- and bracket-notation for deep reference.\n *\n * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n *\n * @name notDeepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop);\n };\n\n /**\n * ### .propertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`.\n *\n * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n *\n * @name propertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.property(prop, val);\n };\n\n /**\n * ### .propertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`.\n *\n * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n *\n * @name propertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.property(prop, val);\n };\n\n /**\n * ### .deepPropertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`. `property` can use dot- and bracket-notation for deep\n * reference.\n *\n * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n *\n * @name deepPropertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop, val);\n };\n\n /**\n * ### .deepPropertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`. `property` can use dot- and\n * bracket-notation for deep reference.\n *\n * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n *\n * @name deepPropertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n };\n\n /**\n * ### .lengthOf(object, length, [message])\n *\n * Asserts that `object` has a `length` property with the expected value.\n *\n * assert.lengthOf([1,2,3], 3, 'array has length of 3');\n * assert.lengthOf('foobar', 6, 'string has length of 6');\n *\n * @name lengthOf\n * @param {Mixed} object\n * @param {Number} length\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.lengthOf = function (exp, len, msg) {\n new Assertion(exp, msg).to.have.length(len);\n };\n\n /**\n * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * assert.throws(fn, 'function throws a reference error');\n * assert.throws(fn, /function throws a reference error/);\n * assert.throws(fn, ReferenceError);\n * assert.throws(fn, ReferenceError, 'function throws a reference error');\n * assert.throws(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throws\n * @alias throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.throws = function (fn, errt, errs, msg) {\n if ('string' === typeof errt || errt instanceof RegExp) {\n errs = errt;\n errt = null;\n }\n\n var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n return flag(assertErr, 'object');\n };\n\n /**\n * ### .doesNotThrow(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * assert.doesNotThrow(fn, Error, 'function does not throw');\n *\n * @name doesNotThrow\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotThrow = function (fn, type, msg) {\n if ('string' === typeof type) {\n msg = type;\n type = null;\n }\n\n new Assertion(fn, msg).to.not.Throw(type);\n };\n\n /**\n * ### .operator(val1, operator, val2, [message])\n *\n * Compares two values using `operator`.\n *\n * assert.operator(1, '<', 2, 'everything is ok');\n * assert.operator(1, '>', 2, 'this will fail');\n *\n * @name operator\n * @param {Mixed} val1\n * @param {String} operator\n * @param {Mixed} val2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.operator = function (val, operator, val2, msg) {\n var ok;\n switch(operator) {\n case '==':\n ok = val == val2;\n break;\n case '===':\n ok = val === val2;\n break;\n case '>':\n ok = val > val2;\n break;\n case '>=':\n ok = val >= val2;\n break;\n case '<':\n ok = val < val2;\n break;\n case '<=':\n ok = val <= val2;\n break;\n case '!=':\n ok = val != val2;\n break;\n case '!==':\n ok = val !== val2;\n break;\n default:\n throw new Error('Invalid operator \"' + operator + '\"');\n }\n var test = new Assertion(ok, msg);\n test.assert(\n true === flag(test, 'object')\n , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n };\n\n /**\n * ### .closeTo(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n *\n * @name closeTo\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.closeTo = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.closeTo(exp, delta);\n };\n\n /**\n * ### .approximately(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.approximately(1.5, 1, 0.5, 'numbers are close');\n *\n * @name approximately\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.approximately = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.approximately(exp, delta);\n };\n\n /**\n * ### .sameMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members.\n * Order is not taken into account.\n *\n * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n *\n * @name sameMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.members(set2);\n }\n\n /**\n * ### .sameDeepMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n * Order is not taken into account.\n *\n * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n *\n * @name sameDeepMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameDeepMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.deep.members(set2);\n }\n\n /**\n * ### .includeMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset`.\n * Order is not taken into account.\n *\n * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n *\n * @name includeMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.members(subset);\n }\n\n /**\n * ### .includeDeepMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset` - using deep equality checking.\n * Order is not taken into account.\n * Duplicates are ignored.\n *\n * assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n *\n * @name includeDeepMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeDeepMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.deep.members(subset);\n }\n\n /**\n * ### .oneOf(inList, list, [message])\n *\n * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n *\n * assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n *\n * @name oneOf\n * @param {*} inList\n * @param {Array<*>} list\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.oneOf = function (inList, list, msg) {\n new Assertion(inList, msg).to.be.oneOf(list);\n }\n\n /**\n * ### .changes(function, object, property)\n *\n * Asserts that a function changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 22 };\n * assert.changes(fn, obj, 'val');\n *\n * @name changes\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.changes = function (fn, obj, prop) {\n new Assertion(fn).to.change(obj, prop);\n }\n\n /**\n * ### .doesNotChange(function, object, property)\n *\n * Asserts that a function does not changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { console.log('foo'); };\n * assert.doesNotChange(fn, obj, 'val');\n *\n * @name doesNotChange\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotChange = function (fn, obj, prop) {\n new Assertion(fn).to.not.change(obj, prop);\n }\n\n /**\n * ### .increases(function, object, property)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 13 };\n * assert.increases(fn, obj, 'val');\n *\n * @name increases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.increases = function (fn, obj, prop) {\n new Assertion(fn).to.increase(obj, prop);\n }\n\n /**\n * ### .doesNotIncrease(function, object, property)\n *\n * Asserts that a function does not increase object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 8 };\n * assert.doesNotIncrease(fn, obj, 'val');\n *\n * @name doesNotIncrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotIncrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.increase(obj, prop);\n }\n\n /**\n * ### .decreases(function, object, property)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * assert.decreases(fn, obj, 'val');\n *\n * @name decreases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.decreases = function (fn, obj, prop) {\n new Assertion(fn).to.decrease(obj, prop);\n }\n\n /**\n * ### .doesNotDecrease(function, object, property)\n *\n * Asserts that a function does not decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * assert.doesNotDecrease(fn, obj, 'val');\n *\n * @name doesNotDecrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotDecrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.decrease(obj, prop);\n }\n\n /*!\n * ### .ifError(object)\n *\n * Asserts if value is not a false value, and throws if it is a true value.\n * This is added to allow for chai to be a drop-in replacement for Node's\n * assert class.\n *\n * var err = new Error('I am a custom error');\n * assert.ifError(err); // Rethrows err!\n *\n * @name ifError\n * @param {Object} object\n * @namespace Assert\n * @api public\n */\n\n assert.ifError = function (val) {\n if (val) {\n throw(val);\n }\n };\n\n /**\n * ### .isExtensible(object)\n *\n * Asserts that `object` is extensible (can have new properties added to it).\n *\n * assert.isExtensible({});\n *\n * @name isExtensible\n * @alias extensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.be.extensible;\n };\n\n /**\n * ### .isNotExtensible(object)\n *\n * Asserts that `object` is _not_ extensible.\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freese({});\n *\n * assert.isNotExtensible(nonExtensibleObject);\n * assert.isNotExtensible(sealedObject);\n * assert.isNotExtensible(frozenObject);\n *\n * @name isNotExtensible\n * @alias notExtensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.extensible;\n };\n\n /**\n * ### .isSealed(object)\n *\n * Asserts that `object` is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.seal({});\n *\n * assert.isSealed(sealedObject);\n * assert.isSealed(frozenObject);\n *\n * @name isSealed\n * @alias sealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isSealed = function (obj, msg) {\n new Assertion(obj, msg).to.be.sealed;\n };\n\n /**\n * ### .isNotSealed(object)\n *\n * Asserts that `object` is _not_ sealed.\n *\n * assert.isNotSealed({});\n *\n * @name isNotSealed\n * @alias notSealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotSealed = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.sealed;\n };\n\n /**\n * ### .isFrozen(object)\n *\n * Asserts that `object` is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n * assert.frozen(frozenObject);\n *\n * @name isFrozen\n * @alias frozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.be.frozen;\n };\n\n /**\n * ### .isNotFrozen(object)\n *\n * Asserts that `object` is _not_ frozen.\n *\n * assert.isNotFrozen({});\n *\n * @name isNotFrozen\n * @alias notFrozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.frozen;\n };\n\n /*!\n * Aliases.\n */\n\n (function alias(name, as){\n assert[as] = assert[name];\n return alias;\n })\n ('isOk', 'ok')\n ('isNotOk', 'notOk')\n ('throws', 'throw')\n ('throws', 'Throw')\n ('isExtensible', 'extensible')\n ('isNotExtensible', 'notExtensible')\n ('isSealed', 'sealed')\n ('isNotSealed', 'notSealed')\n ('isFrozen', 'frozen')\n ('isNotFrozen', 'notFrozen');\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n chai.expect = function (val, message) {\n return new chai.Assertion(val, message);\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Expect\n * @api public\n */\n\n chai.expect.fail = function (actual, expected, message, operator) {\n message = message || 'expect.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, chai.expect.fail);\n };\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n var Assertion = chai.Assertion;\n\n function loadShould () {\n // explicitly define this method as function as to have it's name to include as `ssfi`\n function shouldGetter() {\n if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n return new Assertion(this.valueOf(), null, shouldGetter);\n }\n return new Assertion(this, null, shouldGetter);\n }\n function shouldSetter(value) {\n // See https://github.com/chaijs/chai/issues/86: this makes\n // `whatever.should = someValue` actually set `someValue`, which is\n // especially useful for `global.should = require('chai').should()`.\n //\n // Note that we have to use [[DefineProperty]] instead of [[Put]]\n // since otherwise we would trigger this very setter!\n Object.defineProperty(this, 'should', {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n }\n // modify Object.prototype to have `should`\n Object.defineProperty(Object.prototype, 'should', {\n set: shouldSetter\n , get: shouldGetter\n , configurable: true\n });\n\n var should = {};\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Should\n * @api public\n */\n\n should.fail = function (actual, expected, message, operator) {\n message = message || 'should.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, should.fail);\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * should.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * should.throw(fn, 'function throws a reference error');\n * should.throw(fn, /function throws a reference error/);\n * should.throw(fn, ReferenceError);\n * should.throw(fn, ReferenceError, 'function throws a reference error');\n * should.throw(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.Throw(errt, errs);\n };\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi';\n *\n * should.exist(foo, 'foo exists');\n *\n * @name exist\n * @namespace Should\n * @api public\n */\n\n should.exist = function (val, msg) {\n new Assertion(val, msg).to.exist;\n }\n\n // negation\n should.not = {}\n\n /**\n * ### .not.equal(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * should.not.equal(3, 4, 'these numbers are not equal');\n *\n * @name not.equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.not.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.not.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * should.not.throw(fn, Error, 'function does not throw');\n *\n * @name not.throw\n * @alias not.Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.not.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.not.Throw(errt, errs);\n };\n\n /**\n * ### .not.exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var bar = null;\n *\n * should.not.exist(bar, 'bar does not exist');\n *\n * @name not.exist\n * @namespace Should\n * @api public\n */\n\n should.not.exist = function (val, msg) {\n new Assertion(val, msg).to.not.exist;\n }\n\n should['throw'] = should['Throw'];\n should.not['throw'] = should.not['Throw'];\n\n return should;\n };\n\n chai.should = loadShould;\n chai.Should = loadShould;\n};\n","/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call = Function.prototype.call,\n apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n * expect(fooStr).to.be.foo('bar');\n * expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n if (typeof chainingBehavior !== 'function') {\n chainingBehavior = function () { };\n }\n\n var chainableBehavior = {\n method: method\n , chainingBehavior: chainingBehavior\n };\n\n // save the methods so we can overwrite them later, if we need to.\n if (!ctx.__methods) {\n ctx.__methods = {};\n }\n ctx.__methods[name] = chainableBehavior;\n\n Object.defineProperty(ctx, name,\n { get: function () {\n chainableBehavior.chainingBehavior.call(this);\n\n var assert = function assert() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', assert);\n var result = chainableBehavior.method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n\n // Use `__proto__` if available\n if (hasProtoSupport) {\n // Inherit all properties from the object by replacing the `Function` prototype\n var prototype = assert.__proto__ = Object.create(this);\n // Restore the `call` and `apply` methods from `Function`\n prototype.call = call;\n prototype.apply = apply;\n }\n // Otherwise, redefine all properties (slow!)\n else {\n var asserterNames = Object.getOwnPropertyNames(ctx);\n asserterNames.forEach(function (asserterName) {\n if (!excludeNames.test(asserterName)) {\n var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n Object.defineProperty(assert, asserterName, pd);\n }\n });\n }\n\n transferFlags(this, assert);\n return assert;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n ctx[name] = function () {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', ctx[name]);\n var result = method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n * utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.instanceof(Foo);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n Object.defineProperty(ctx, name,\n { get: function addProperty() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', addProperty);\n\n var result = getter.call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n * utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n var obj = flag(obj, 'object');\n types = types.map(function (t) { return t.toLowerCase(); });\n types.sort();\n\n // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n var str = types.map(function (t, index) {\n var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n return or + art + ' ' + t;\n }).join(', ');\n\n if (!types.some(function (expected) { return type(obj) === expected; })) {\n throw new AssertionError(\n 'object tested must be ' + str + ', but ' + type(obj) + ' given'\n );\n }\n};\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n * utils.flag(this, 'foo', 'bar'); // setter\n * utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n var flags = obj.__flags || (obj.__flags = Object.create(null));\n if (arguments.length === 3) {\n flags[key] = value;\n } else {\n return flags[key];\n }\n};\n","/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n return args.length > 4 ? args[4] : obj._obj;\n};\n","/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n var result = [];\n for (var name in object) {\n result.push(name);\n }\n return result;\n};\n","/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n , getActual = require('./getActual')\n , inspect = require('./inspect')\n , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , val = flag(obj, 'object')\n , expected = args[3]\n , actual = getActual(obj, args)\n , msg = negate ? args[2] : args[1]\n , flagMsg = flag(obj, 'message');\n\n if(typeof msg === \"function\") msg = msg();\n msg = msg || '';\n msg = msg\n .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n","/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n if (func.name) return func.name;\n\n var match = /^\\s?function ([^(]*)\\(/.exec(func);\n return match && match[1] ? match[1] : \"\";\n};\n","/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n var parsed = parsePath(path),\n last = parsed[parsed.length - 1];\n\n var info = {\n parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n name: last.p || last.i,\n value: _getPathValue(parsed, obj)\n };\n info.exists = hasProperty(info.name, info.parent);\n\n return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n * var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n return parts.map(function (value) {\n var re = /^\\[(\\d+)\\]$/\n , mArr = re.exec(value);\n if (mArr) return { i: parseFloat(mArr[1]) };\n else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n * var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n var tmp = obj\n , res;\n\n index = (index === undefined ? parsed.length : index);\n\n for (var i = 0, l = index; i < l; i++) {\n var part = parsed[i];\n if (tmp) {\n if ('undefined' !== typeof part.p)\n tmp = tmp[part.p];\n else if ('undefined' !== typeof part.i)\n tmp = tmp[part.i];\n if (i == (l - 1)) res = tmp;\n } else {\n res = undefined;\n }\n }\n return res;\n}\n","/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer \n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n * var obj = {\n * prop1: {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n * , prop2: {\n * arr: [ { nested: 'Universe' } ]\n * , str: 'Hello again!'\n * }\n * }\n *\n * The following would be the results.\n *\n * getPathValue('prop1.str', obj); // Hello\n * getPathValue('prop1.att[2]', obj); // b\n * getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n var info = getPathInfo(path, obj);\n return info.value;\n};\n","/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n var result = Object.getOwnPropertyNames(object);\n\n function addProperty(property) {\n if (result.indexOf(property) === -1) {\n result.push(property);\n }\n }\n\n var proto = Object.getPrototypeOf(object);\n while (proto !== null) {\n Object.getOwnPropertyNames(proto).forEach(addProperty);\n proto = Object.getPrototypeOf(proto);\n }\n\n return result;\n};\n","/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n * var obj = {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n *\n * The following would be the results.\n *\n * hasProperty('str', obj); // true\n * hasProperty('constructor', obj); // true\n * hasProperty('bar', obj); // false\n *\n * hasProperty('length', obj.str); // true\n * hasProperty(1, obj.str); // true\n * hasProperty(5, obj.str); // false\n *\n * hasProperty('length', obj.arr); // true\n * hasProperty(2, obj.arr); // true\n * hasProperty(3, obj.arr); // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n 'number': Number\n , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n var ot = type(obj);\n\n // Bad Object, obviously no props at all\n if(ot === 'null' || ot === 'undefined')\n return false;\n\n // The `in` operator does not work with certain literals\n // box these before the check\n if(literals[ot] && typeof obj !== 'object')\n obj = new literals[ot](obj);\n\n return name in obj;\n};\n","/*!\n * chai\n * Copyright(c) 2011 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n","// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n * properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n * output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n var ctx = {\n showHidden: showHidden,\n seen: [],\n stylize: function (str) { return str; }\n };\n return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n if (typeof HTMLElement === 'object') {\n return object instanceof HTMLElement;\n } else {\n return object &&\n typeof object === 'object' &&\n object.nodeType === 1 &&\n typeof object.nodeName === 'string';\n }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (value && typeof value.inspect === 'function' &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes);\n if (typeof ret !== 'string') {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // If this is a DOM element, try to get the outer HTML.\n if (isDOMElement(value)) {\n if ('outerHTML' in value) {\n return value.outerHTML;\n // This value does not have an outerHTML attribute,\n // it could still be an XML element\n } else {\n // Attempt to serialize it\n try {\n if (document.xmlVersion) {\n var xmlSerializer = new XMLSerializer();\n return xmlSerializer.serializeToString(value);\n } else {\n // Firefox 11- do not support outerHTML\n // It does, however, support innerHTML\n // Use the following to render the element\n var ns = \"http://www.w3.org/1999/xhtml\";\n var container = document.createElementNS(ns, '_');\n\n container.appendChild(value.cloneNode(false));\n html = container.innerHTML\n .replace('><', '>' + value.innerHTML + '<');\n container.innerHTML = '';\n return html;\n }\n } catch (err) {\n // This could be a non-native DOM implementation,\n // continue with the normal flow:\n // printing the element as if it is an object.\n }\n }\n }\n\n // Look up the keys of the object.\n var visibleKeys = getEnumerableProperties(value);\n var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n // Some type of object without properties can be shortcutted.\n // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n // a `stack` plus `description` property; ignore those for consistency.\n if (keys.length === 0 || (isError(value) && (\n (keys.length === 1 && keys[0] === 'stack') ||\n (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n ))) {\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n base = ' [Function' + nameSuffix + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n return formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n switch (typeof value) {\n case 'undefined':\n return ctx.stylize('undefined', 'undefined');\n\n case 'string':\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n\n case 'number':\n if (value === 0 && (1/value) === -Infinity) {\n return ctx.stylize('-0', 'number');\n }\n return ctx.stylize('' + value, 'number');\n\n case 'boolean':\n return ctx.stylize('' + value, 'boolean');\n }\n // For some reason typeof null is \"object\", so special case here.\n if (value === null) {\n return ctx.stylize('null', 'null');\n }\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str;\n if (value.__lookupGetter__) {\n if (value.__lookupGetter__(key)) {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n }\n if (visibleKeys.indexOf(key) < 0) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(value[key]) < 0) {\n if (recurseTimes === null) {\n str = formatValue(ctx, value[key], null);\n } else {\n str = formatValue(ctx, value[key], recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (typeof name === 'undefined') {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n return Array.isArray(ar) ||\n (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n var str = inspect(obj)\n , type = Object.prototype.toString.call(obj);\n\n if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n if (type === '[object Function]') {\n return !obj.name || obj.name === ''\n ? '[Function]'\n : '[Function: ' + obj.name + ']';\n } else if (type === '[object Array]') {\n return '[ Array(' + obj.length + ') ]';\n } else if (type === '[object Object]') {\n var keys = Object.keys(obj)\n , kstr = keys.length > 2\n ? keys.splice(0, 2).join(', ') + ', ...'\n : keys.join(', ');\n return '{ Object (' + kstr + ') }';\n } else {\n return str;\n }\n } else {\n return str;\n }\n};\n","/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property. Must return functions to be used for\n * name.\n *\n * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n * function (_super) {\n * }\n * , function (_super) {\n * }\n * );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.have.length(3);\n * expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n var chainableBehavior = ctx.__methods[name];\n\n var _chainingBehavior = chainableBehavior.chainingBehavior;\n chainableBehavior.chainingBehavior = function () {\n var result = chainingBehavior(_chainingBehavior).call(this);\n return result === undefined ? this : result;\n };\n\n var _method = chainableBehavior.method;\n chainableBehavior.method = function () {\n var result = method(_method).apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n * return function (str) {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.value).to.equal(str);\n * } else {\n * _super.apply(this, arguments);\n * }\n * }\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n var _method = ctx[name]\n , _super = function () { return this; };\n\n if (_method && 'function' === typeof _method)\n _super = _method;\n\n ctx[name] = function () {\n var result = method(_super).apply(this, arguments);\n return result === undefined ? this : result;\n }\n};\n","/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n * return function () {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.name).to.equal('bar');\n * } else {\n * _super.call(this);\n * }\n * }\n * });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n var _get = Object.getOwnPropertyDescriptor(ctx, name)\n , _super = function () {};\n\n if (_get && 'function' === typeof _get.get)\n _super = _get.get\n\n Object.defineProperty(ctx, name,\n { get: function () {\n var result = getter(_super).call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , expr = args[0];\n return negate ? !expr : expr;\n};\n","/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n * var newAssertion = new Assertion();\n * utils.transferFlags(assertion, newAssertion);\n *\n * var anotherAsseriton = new Assertion(myObj);\n * utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n if (!object.__flags) {\n object.__flags = Object.create(null);\n }\n\n includeAll = arguments.length === 3 ? includeAll : true;\n\n for (var flag in flags) {\n if (includeAll ||\n (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n object.__flags[flag] = flags[flag];\n }\n }\n};\n","module.exports = require('./lib/eql');\n","/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n Buffer = {};\n Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n if (sameValue(a, b)) {\n return true;\n } else if ('date' === type(a)) {\n return dateEqual(a, b);\n } else if ('regexp' === type(a)) {\n return regexpEqual(a, b);\n } else if (Buffer.isBuffer(a)) {\n return bufferEqual(a, b);\n } else if ('arguments' === type(a)) {\n return argumentsEqual(a, b, m);\n } else if (!typeEqual(a, b)) {\n return false;\n } else if (('object' !== type(a) && 'object' !== type(b))\n && ('array' !== type(a) && 'array' !== type(b))) {\n return sameValue(a, b);\n } else {\n return objectEqual(a, b, m);\n }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n if (a === b) return a !== 0 || 1 / a === 1 / b;\n return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n if ('date' !== type(b)) return false;\n return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n if ('regexp' !== type(b)) return false;\n return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n if ('arguments' !== type(b)) return false;\n a = [].slice.call(a);\n b = [].slice.call(b);\n return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n var res = [];\n for (var key in a) res.push(key);\n return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n if (a.length !== b.length) return false;\n\n var i = 0;\n var match = true;\n\n for (; i < a.length; i++) {\n if (a[i] !== b[i]) {\n match = false;\n break;\n }\n }\n\n return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n if (!Buffer.isBuffer(b)) return false;\n return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n if (!isValue(a) || !isValue(b)) {\n return false;\n }\n\n if (a.prototype !== b.prototype) {\n return false;\n }\n\n var i;\n if (m) {\n for (i = 0; i < m.length; i++) {\n if ((m[i][0] === a && m[i][1] === b)\n || (m[i][0] === b && m[i][1] === a)) {\n return true;\n }\n }\n } else {\n m = [];\n }\n\n try {\n var ka = enumerable(a);\n var kb = enumerable(b);\n } catch (ex) {\n return false;\n }\n\n ka.sort();\n kb.sort();\n\n if (!iterableEqual(ka, kb)) {\n return false;\n }\n\n m.push([ a, b ]);\n\n var key;\n for (i = ka.length - 1; i >= 0; i--) {\n key = ka[i];\n if (!deepEqual(a[key], b[key], m)) {\n return false;\n }\n }\n\n return true;\n}\n","module.exports = require('./lib/type');\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n '[object Array]': 'array'\n , '[object RegExp]': 'regexp'\n , '[object Function]': 'function'\n , '[object Arguments]': 'arguments'\n , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n var str = Object.prototype.toString.call(obj);\n if (natives[str]) return natives[str];\n if (obj === null) return 'null';\n if (obj === undefined) return 'undefined';\n if (obj === Object(obj)) return 'object';\n return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","/*!\n localForage -- Offline Storage, Improved\n Version 1.5.0\n https://localforage.github.io/localForage\n (c) 2013-2017 Mozilla, Apache License 2.0\n*/\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.localforage = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw (f.code=\"MODULE_NOT_FOUND\", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o element; its readystatechange event will be fired asynchronously once it is inserted\n // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.\n var scriptEl = global.document.createElement('script');\n scriptEl.onreadystatechange = function () {\n nextTick();\n\n scriptEl.onreadystatechange = null;\n scriptEl.parentNode.removeChild(scriptEl);\n scriptEl = null;\n };\n global.document.documentElement.appendChild(scriptEl);\n };\n } else {\n scheduleDrain = function () {\n setTimeout(nextTick, 0);\n };\n }\n}\n\nvar draining;\nvar queue = [];\n//named nextTick for less confusing stack traces\nfunction nextTick() {\n draining = true;\n var i, oldQueue;\n var len = queue.length;\n while (len) {\n oldQueue = queue;\n queue = [];\n i = -1;\n while (++i < len) {\n oldQueue[i]();\n }\n len = queue.length;\n }\n draining = false;\n}\n\nmodule.exports = immediate;\nfunction immediate(task) {\n if (queue.push(task) === 1 && !draining) {\n scheduleDrain();\n }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],2:[function(_dereq_,module,exports){\n'use strict';\nvar immediate = _dereq_(1);\n\n/* istanbul ignore next */\nfunction INTERNAL() {}\n\nvar handlers = {};\n\nvar REJECTED = ['REJECTED'];\nvar FULFILLED = ['FULFILLED'];\nvar PENDING = ['PENDING'];\n\nmodule.exports = exports = Promise;\n\nfunction Promise(resolver) {\n if (typeof resolver !== 'function') {\n throw new TypeError('resolver must be a function');\n }\n this.state = PENDING;\n this.queue = [];\n this.outcome = void 0;\n if (resolver !== INTERNAL) {\n safelyResolveThenable(this, resolver);\n }\n}\n\nPromise.prototype[\"catch\"] = function (onRejected) {\n return this.then(null, onRejected);\n};\nPromise.prototype.then = function (onFulfilled, onRejected) {\n if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||\n typeof onRejected !== 'function' && this.state === REJECTED) {\n return this;\n }\n var promise = new this.constructor(INTERNAL);\n if (this.state !== PENDING) {\n var resolver = this.state === FULFILLED ? onFulfilled : onRejected;\n unwrap(promise, resolver, this.outcome);\n } else {\n this.queue.push(new QueueItem(promise, onFulfilled, onRejected));\n }\n\n return promise;\n};\nfunction QueueItem(promise, onFulfilled, onRejected) {\n this.promise = promise;\n if (typeof onFulfilled === 'function') {\n this.onFulfilled = onFulfilled;\n this.callFulfilled = this.otherCallFulfilled;\n }\n if (typeof onRejected === 'function') {\n this.onRejected = onRejected;\n this.callRejected = this.otherCallRejected;\n }\n}\nQueueItem.prototype.callFulfilled = function (value) {\n handlers.resolve(this.promise, value);\n};\nQueueItem.prototype.otherCallFulfilled = function (value) {\n unwrap(this.promise, this.onFulfilled, value);\n};\nQueueItem.prototype.callRejected = function (value) {\n handlers.reject(this.promise, value);\n};\nQueueItem.prototype.otherCallRejected = function (value) {\n unwrap(this.promise, this.onRejected, value);\n};\n\nfunction unwrap(promise, func, value) {\n immediate(function () {\n var returnValue;\n try {\n returnValue = func(value);\n } catch (e) {\n return handlers.reject(promise, e);\n }\n if (returnValue === promise) {\n handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));\n } else {\n handlers.resolve(promise, returnValue);\n }\n });\n}\n\nhandlers.resolve = function (self, value) {\n var result = tryCatch(getThen, value);\n if (result.status === 'error') {\n return handlers.reject(self, result.value);\n }\n var thenable = result.value;\n\n if (thenable) {\n safelyResolveThenable(self, thenable);\n } else {\n self.state = FULFILLED;\n self.outcome = value;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callFulfilled(value);\n }\n }\n return self;\n};\nhandlers.reject = function (self, error) {\n self.state = REJECTED;\n self.outcome = error;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callRejected(error);\n }\n return self;\n};\n\nfunction getThen(obj) {\n // Make sure we only access the accessor once as required by the spec\n var then = obj && obj.then;\n if (obj && typeof obj === 'object' && typeof then === 'function') {\n return function appyThen() {\n then.apply(obj, arguments);\n };\n }\n}\n\nfunction safelyResolveThenable(self, thenable) {\n // Either fulfill, reject or reject with error\n var called = false;\n function onError(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.reject(self, value);\n }\n\n function onSuccess(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.resolve(self, value);\n }\n\n function tryToUnwrap() {\n thenable(onSuccess, onError);\n }\n\n var result = tryCatch(tryToUnwrap);\n if (result.status === 'error') {\n onError(result.value);\n }\n}\n\nfunction tryCatch(func, value) {\n var out = {};\n try {\n out.value = func(value);\n out.status = 'success';\n } catch (e) {\n out.status = 'error';\n out.value = e;\n }\n return out;\n}\n\nexports.resolve = resolve;\nfunction resolve(value) {\n if (value instanceof this) {\n return value;\n }\n return handlers.resolve(new this(INTERNAL), value);\n}\n\nexports.reject = reject;\nfunction reject(reason) {\n var promise = new this(INTERNAL);\n return handlers.reject(promise, reason);\n}\n\nexports.all = all;\nfunction all(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var values = new Array(len);\n var resolved = 0;\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n allResolver(iterable[i], i);\n }\n return promise;\n function allResolver(value, i) {\n self.resolve(value).then(resolveFromAll, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n function resolveFromAll(outValue) {\n values[i] = outValue;\n if (++resolved === len && !called) {\n called = true;\n handlers.resolve(promise, values);\n }\n }\n }\n}\n\nexports.race = race;\nfunction race(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n resolver(iterable[i]);\n }\n return promise;\n function resolver(value) {\n self.resolve(value).then(function (response) {\n if (!called) {\n called = true;\n handlers.resolve(promise, response);\n }\n }, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n }\n}\n\n},{\"1\":1}],3:[function(_dereq_,module,exports){\n(function (global){\n'use strict';\nif (typeof global.Promise !== 'function') {\n global.Promise = _dereq_(2);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"2\":2}],4:[function(_dereq_,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction getIDB() {\n /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */\n try {\n if (typeof indexedDB !== 'undefined') {\n return indexedDB;\n }\n if (typeof webkitIndexedDB !== 'undefined') {\n return webkitIndexedDB;\n }\n if (typeof mozIndexedDB !== 'undefined') {\n return mozIndexedDB;\n }\n if (typeof OIndexedDB !== 'undefined') {\n return OIndexedDB;\n }\n if (typeof msIndexedDB !== 'undefined') {\n return msIndexedDB;\n }\n } catch (e) {}\n}\n\nvar idb = getIDB();\n\nfunction isIndexedDBValid() {\n try {\n // Initialize IndexedDB; fall back to vendor-prefixed versions\n // if needed.\n if (!idb) {\n return false;\n }\n // We mimic PouchDB here;\n //\n // We test for openDatabase because IE Mobile identifies itself\n // as Safari. Oh the lulz...\n var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform);\n\n var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1;\n\n // Safari <10.1 does not meet our requirements for IDB support (#5572)\n // since Safari 10.1 shipped with fetch, we can use that to detect it\n return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' &&\n // some outdated implementations of IDB that appear on Samsung\n // and HTC Android devices <4.4 are missing IDBKeyRange\n typeof IDBKeyRange !== 'undefined';\n } catch (e) {\n return false;\n }\n}\n\nfunction isWebSQLValid() {\n return typeof openDatabase === 'function';\n}\n\nfunction isLocalStorageValid() {\n try {\n return typeof localStorage !== 'undefined' && 'setItem' in localStorage && localStorage.setItem;\n } catch (e) {\n return false;\n }\n}\n\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\nfunction createBlob(parts, properties) {\n /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */\n parts = parts || [];\n properties = properties || {};\n try {\n return new Blob(parts, properties);\n } catch (e) {\n if (e.name !== 'TypeError') {\n throw e;\n }\n var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder;\n var builder = new Builder();\n for (var i = 0; i < parts.length; i += 1) {\n builder.append(parts[i]);\n }\n return builder.getBlob(properties.type);\n }\n}\n\n// This is CommonJS because lie is an external dependency, so Rollup\n// can just ignore it.\nif (typeof Promise === 'undefined') {\n // In the \"nopromises\" build this will just throw if you don't have\n // a global promise object, but it would throw anyway later.\n _dereq_(3);\n}\nvar Promise$1 = Promise;\n\nfunction executeCallback(promise, callback) {\n if (callback) {\n promise.then(function (result) {\n callback(null, result);\n }, function (error) {\n callback(error);\n });\n }\n}\n\nfunction executeTwoCallbacks(promise, callback, errorCallback) {\n if (typeof callback === 'function') {\n promise.then(callback);\n }\n\n if (typeof errorCallback === 'function') {\n promise[\"catch\"](errorCallback);\n }\n}\n\n// Some code originally from async_storage.js in\n// [Gaia](https://github.com/mozilla-b2g/gaia).\n\nvar DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support';\nvar supportsBlobs;\nvar dbContexts;\nvar toString = Object.prototype.toString;\n\n// Transform a binary string to an array buffer, because otherwise\n// weird stuff happens when you try to work with the binary string directly.\n// It is known.\n// From http://stackoverflow.com/questions/14967647/ (continues on next line)\n// encode-decode-image-with-base64-breaks-image (2013-04-21)\nfunction _binStringToArrayBuffer(bin) {\n var length = bin.length;\n var buf = new ArrayBuffer(length);\n var arr = new Uint8Array(buf);\n for (var i = 0; i < length; i++) {\n arr[i] = bin.charCodeAt(i);\n }\n return buf;\n}\n\n//\n// Blobs are not supported in all versions of IndexedDB, notably\n// Chrome <37 and Android <5. In those versions, storing a blob will throw.\n//\n// Various other blob bugs exist in Chrome v37-42 (inclusive).\n// Detecting them is expensive and confusing to users, and Chrome 37-42\n// is at very low usage worldwide, so we do a hacky userAgent check instead.\n//\n// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120\n// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916\n// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836\n//\n// Code borrowed from PouchDB. See:\n// https://github.com/pouchdb/pouchdb/blob/master/packages/node_modules/pouchdb-adapter-idb/src/blobSupport.js\n//\nfunction _checkBlobSupportWithoutCaching(idb) {\n return new Promise$1(function (resolve) {\n var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, 'readwrite');\n var blob = createBlob(['']);\n txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');\n\n txn.onabort = function (e) {\n // If the transaction aborts now its due to not being able to\n // write to the database, likely due to the disk being full\n e.preventDefault();\n e.stopPropagation();\n resolve(false);\n };\n\n txn.oncomplete = function () {\n var matchedChrome = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n var matchedEdge = navigator.userAgent.match(/Edge\\//);\n // MS Edge pretends to be Chrome 42:\n // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx\n resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43);\n };\n })[\"catch\"](function () {\n return false; // error, so assume unsupported\n });\n}\n\nfunction _checkBlobSupport(idb) {\n if (typeof supportsBlobs === 'boolean') {\n return Promise$1.resolve(supportsBlobs);\n }\n return _checkBlobSupportWithoutCaching(idb).then(function (value) {\n supportsBlobs = value;\n return supportsBlobs;\n });\n}\n\nfunction _deferReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Create a deferred object representing the current database operation.\n var deferredOperation = {};\n\n deferredOperation.promise = new Promise$1(function (resolve) {\n deferredOperation.resolve = resolve;\n });\n\n // Enqueue the deferred operation.\n dbContext.deferredOperations.push(deferredOperation);\n\n // Chain its promise to the database readiness.\n if (!dbContext.dbReady) {\n dbContext.dbReady = deferredOperation.promise;\n } else {\n dbContext.dbReady = dbContext.dbReady.then(function () {\n return deferredOperation.promise;\n });\n }\n}\n\nfunction _advanceReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Dequeue a deferred operation.\n var deferredOperation = dbContext.deferredOperations.pop();\n\n // Resolve its promise (which is part of the database readiness\n // chain of promises).\n if (deferredOperation) {\n deferredOperation.resolve();\n }\n}\n\nfunction _getConnection(dbInfo, upgradeNeeded) {\n return new Promise$1(function (resolve, reject) {\n\n if (dbInfo.db) {\n if (upgradeNeeded) {\n _deferReadiness(dbInfo);\n dbInfo.db.close();\n } else {\n return resolve(dbInfo.db);\n }\n }\n\n var dbArgs = [dbInfo.name];\n\n if (upgradeNeeded) {\n dbArgs.push(dbInfo.version);\n }\n\n var openreq = idb.open.apply(idb, dbArgs);\n\n if (upgradeNeeded) {\n openreq.onupgradeneeded = function (e) {\n var db = openreq.result;\n try {\n db.createObjectStore(dbInfo.storeName);\n if (e.oldVersion <= 1) {\n // Added when support for blob shims was added\n db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);\n }\n } catch (ex) {\n if (ex.name === 'ConstraintError') {\n console.warn('The database \"' + dbInfo.name + '\"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage \"' + dbInfo.storeName + '\" already exists.');\n } else {\n throw ex;\n }\n }\n };\n }\n\n openreq.onerror = function (e) {\n e.preventDefault();\n reject(openreq.error);\n };\n\n openreq.onsuccess = function () {\n resolve(openreq.result);\n _advanceReadiness(dbInfo);\n };\n });\n}\n\nfunction _getOriginalConnection(dbInfo) {\n return _getConnection(dbInfo, false);\n}\n\nfunction _getUpgradedConnection(dbInfo) {\n return _getConnection(dbInfo, true);\n}\n\nfunction _isUpgradeNeeded(dbInfo, defaultVersion) {\n if (!dbInfo.db) {\n return true;\n }\n\n var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName);\n var isDowngrade = dbInfo.version < dbInfo.db.version;\n var isUpgrade = dbInfo.version > dbInfo.db.version;\n\n if (isDowngrade) {\n // If the version is not the default one\n // then warn for impossible downgrade.\n if (dbInfo.version !== defaultVersion) {\n console.warn('The database \"' + dbInfo.name + '\"' + ' can\\'t be downgraded from version ' + dbInfo.db.version + ' to version ' + dbInfo.version + '.');\n }\n // Align the versions to prevent errors.\n dbInfo.version = dbInfo.db.version;\n }\n\n if (isUpgrade || isNewStore) {\n // If the store is new then increment the version (if needed).\n // This will trigger an \"upgradeneeded\" event which is required\n // for creating a store.\n if (isNewStore) {\n var incVersion = dbInfo.db.version + 1;\n if (incVersion > dbInfo.version) {\n dbInfo.version = incVersion;\n }\n }\n\n return true;\n }\n\n return false;\n}\n\n// encode a blob for indexeddb engines that don't support blobs\nfunction _encodeBlob(blob) {\n return new Promise$1(function (resolve, reject) {\n var reader = new FileReader();\n reader.onerror = reject;\n reader.onloadend = function (e) {\n var base64 = btoa(e.target.result || '');\n resolve({\n __local_forage_encoded_blob: true,\n data: base64,\n type: blob.type\n });\n };\n reader.readAsBinaryString(blob);\n });\n}\n\n// decode an encoded blob\nfunction _decodeBlob(encodedBlob) {\n var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data));\n return createBlob([arrayBuff], { type: encodedBlob.type });\n}\n\n// is this one of our fancy encoded blobs?\nfunction _isEncodedBlob(value) {\n return value && value.__local_forage_encoded_blob;\n}\n\n// Specialize the default `ready()` function by making it dependent\n// on the current database operations. Thus, the driver will be actually\n// ready when it's been initialized (default) *and* there are no pending\n// operations on the database (initiated by some other instances).\nfunction _fullyReady(callback) {\n var self = this;\n\n var promise = self._initReady().then(function () {\n var dbContext = dbContexts[self._dbInfo.name];\n\n if (dbContext && dbContext.dbReady) {\n return dbContext.dbReady;\n }\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n}\n\n// Open the IndexedDB database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n // Initialize a singleton container for all running localForages.\n if (!dbContexts) {\n dbContexts = {};\n }\n\n // Get the current context of the database;\n var dbContext = dbContexts[dbInfo.name];\n\n // ...or create a new context.\n if (!dbContext) {\n dbContext = {\n // Running localForages sharing a database.\n forages: [],\n // Shared database.\n db: null,\n // Database readiness (promise).\n dbReady: null,\n // Deferred operations on the database.\n deferredOperations: []\n };\n // Register the new context in the global container.\n dbContexts[dbInfo.name] = dbContext;\n }\n\n // Register itself as a running localForage in the current context.\n dbContext.forages.push(self);\n\n // Replace the default `ready()` function with the specialized one.\n if (!self._initReady) {\n self._initReady = self.ready;\n self.ready = _fullyReady;\n }\n\n // Create an array of initialization states of the related localForages.\n var initPromises = [];\n\n function ignoreErrors() {\n // Don't handle errors here,\n // just makes sure related localForages aren't pending.\n return Promise$1.resolve();\n }\n\n for (var j = 0; j < dbContext.forages.length; j++) {\n var forage = dbContext.forages[j];\n if (forage !== self) {\n // Don't wait for itself...\n initPromises.push(forage._initReady()[\"catch\"](ignoreErrors));\n }\n }\n\n // Take a snapshot of the related localForages.\n var forages = dbContext.forages.slice(0);\n\n // Initialize the connection process only when\n // all the related localForages aren't pending.\n return Promise$1.all(initPromises).then(function () {\n dbInfo.db = dbContext.db;\n // Get the connection or open a new one without upgrade.\n return _getOriginalConnection(dbInfo);\n }).then(function (db) {\n dbInfo.db = db;\n if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) {\n // Reopen the database for upgrading.\n return _getUpgradedConnection(dbInfo);\n }\n return db;\n }).then(function (db) {\n dbInfo.db = dbContext.db = db;\n self._dbInfo = dbInfo;\n // Share the final connection amongst related localForages.\n for (var k = 0; k < forages.length; k++) {\n var forage = forages[k];\n if (forage !== self) {\n // Self is already up-to-date.\n forage._dbInfo.db = dbInfo.db;\n forage._dbInfo.version = dbInfo.version;\n }\n }\n });\n}\n\nfunction getItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.get(key);\n\n req.onsuccess = function () {\n var value = req.result;\n if (value === undefined) {\n value = null;\n }\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n resolve(value);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items stored in database.\nfunction iterate(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var iterationNumber = 1;\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (cursor) {\n var value = cursor.value;\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n var result = iterator(value, cursor.key, iterationNumber++);\n\n if (result !== void 0) {\n resolve(result);\n } else {\n cursor[\"continue\"]();\n }\n } else {\n resolve();\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n\n return promise;\n}\n\nfunction setItem(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n var dbInfo;\n self.ready().then(function () {\n dbInfo = self._dbInfo;\n if (toString.call(value) === '[object Blob]') {\n return _checkBlobSupport(dbInfo.db).then(function (blobSupport) {\n if (blobSupport) {\n return value;\n }\n return _encodeBlob(value);\n });\n }\n return value;\n }).then(function (value) {\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.put(value, key);\n\n // The reason we don't _save_ null is because IE 10 does\n // not support saving the `null` type in IndexedDB. How\n // ironic, given the bug below!\n // See: https://github.com/mozilla/localForage/issues/161\n if (value === null) {\n value = undefined;\n }\n\n transaction.oncomplete = function () {\n // Cast to undefined so the value passed to\n // callback/promise is the same as what one would get out\n // of `getItem()` later. This leads to some weirdness\n // (setItem('foo', undefined) will return `null`), but\n // it's not my fault localStorage is our baseline and that\n // it's weird.\n if (value === undefined) {\n value = null;\n }\n\n resolve(value);\n };\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction removeItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n\n // We use a Grunt task to make this safe for IE and some\n // versions of Android (including those used by Cordova).\n // Normally IE won't like `.delete()` and will insist on\n // using `['delete']()`, but we have a build step that\n // fixes this for us now.\n var req = store[\"delete\"](key);\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onerror = function () {\n reject(req.error);\n };\n\n // The request will be also be aborted if we've exceeded our storage\n // space.\n transaction.onabort = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction clear(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.clear();\n\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction length(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.count();\n\n req.onsuccess = function () {\n resolve(req.result);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction key(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n if (n < 0) {\n resolve(null);\n\n return;\n }\n\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var advanced = false;\n var req = store.openCursor();\n req.onsuccess = function () {\n var cursor = req.result;\n if (!cursor) {\n // this means there weren't enough keys\n resolve(null);\n\n return;\n }\n\n if (n === 0) {\n // We have the first key, return it if that's what they\n // wanted.\n resolve(cursor.key);\n } else {\n if (!advanced) {\n // Otherwise, ask the cursor to skip ahead n\n // records.\n advanced = true;\n cursor.advance(n);\n } else {\n // When we get here, we've got the nth key.\n resolve(cursor.key);\n }\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var keys = [];\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (!cursor) {\n resolve(keys);\n return;\n }\n\n keys.push(cursor.key);\n cursor[\"continue\"]();\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar asyncStorage = {\n _driver: 'asyncStorage',\n _initStorage: _initStorage,\n iterate: iterate,\n getItem: getItem,\n setItem: setItem,\n removeItem: removeItem,\n clear: clear,\n length: length,\n key: key,\n keys: keys\n};\n\n// Sadly, the best way to save binary data in WebSQL/localStorage is serializing\n// it to Base64, so this is how we store it to prevent very strange errors with less\n// verbose ways of binary <-> string data storage.\nvar BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\nvar BLOB_TYPE_PREFIX = '~~local_forage_type~';\nvar BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;\n\nvar SERIALIZED_MARKER = '__lfsc__:';\nvar SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;\n\n// OMG the serializations!\nvar TYPE_ARRAYBUFFER = 'arbf';\nvar TYPE_BLOB = 'blob';\nvar TYPE_INT8ARRAY = 'si08';\nvar TYPE_UINT8ARRAY = 'ui08';\nvar TYPE_UINT8CLAMPEDARRAY = 'uic8';\nvar TYPE_INT16ARRAY = 'si16';\nvar TYPE_INT32ARRAY = 'si32';\nvar TYPE_UINT16ARRAY = 'ur16';\nvar TYPE_UINT32ARRAY = 'ui32';\nvar TYPE_FLOAT32ARRAY = 'fl32';\nvar TYPE_FLOAT64ARRAY = 'fl64';\nvar TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;\n\nvar toString$1 = Object.prototype.toString;\n\nfunction stringToBuffer(serializedString) {\n // Fill the string into a ArrayBuffer.\n var bufferLength = serializedString.length * 0.75;\n var len = serializedString.length;\n var i;\n var p = 0;\n var encoded1, encoded2, encoded3, encoded4;\n\n if (serializedString[serializedString.length - 1] === '=') {\n bufferLength--;\n if (serializedString[serializedString.length - 2] === '=') {\n bufferLength--;\n }\n }\n\n var buffer = new ArrayBuffer(bufferLength);\n var bytes = new Uint8Array(buffer);\n\n for (i = 0; i < len; i += 4) {\n encoded1 = BASE_CHARS.indexOf(serializedString[i]);\n encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);\n encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);\n encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);\n\n /*jslint bitwise: true */\n bytes[p++] = encoded1 << 2 | encoded2 >> 4;\n bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;\n bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;\n }\n return buffer;\n}\n\n// Converts a buffer to a string to store, serialized, in the backend\n// storage library.\nfunction bufferToString(buffer) {\n // base64-arraybuffer\n var bytes = new Uint8Array(buffer);\n var base64String = '';\n var i;\n\n for (i = 0; i < bytes.length; i += 3) {\n /*jslint bitwise: true */\n base64String += BASE_CHARS[bytes[i] >> 2];\n base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];\n base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];\n base64String += BASE_CHARS[bytes[i + 2] & 63];\n }\n\n if (bytes.length % 3 === 2) {\n base64String = base64String.substring(0, base64String.length - 1) + '=';\n } else if (bytes.length % 3 === 1) {\n base64String = base64String.substring(0, base64String.length - 2) + '==';\n }\n\n return base64String;\n}\n\n// Serialize a value, afterwards executing a callback (which usually\n// instructs the `setItem()` callback/promise to be executed). This is how\n// we store binary data with localStorage.\nfunction serialize(value, callback) {\n var valueType = '';\n if (value) {\n valueType = toString$1.call(value);\n }\n\n // Cannot use `value instanceof ArrayBuffer` or such here, as these\n // checks fail when running the tests using casper.js...\n //\n // TODO: See why those tests fail and use a better solution.\n if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) {\n // Convert binary arrays to a string and prefix the string with\n // a special marker.\n var buffer;\n var marker = SERIALIZED_MARKER;\n\n if (value instanceof ArrayBuffer) {\n buffer = value;\n marker += TYPE_ARRAYBUFFER;\n } else {\n buffer = value.buffer;\n\n if (valueType === '[object Int8Array]') {\n marker += TYPE_INT8ARRAY;\n } else if (valueType === '[object Uint8Array]') {\n marker += TYPE_UINT8ARRAY;\n } else if (valueType === '[object Uint8ClampedArray]') {\n marker += TYPE_UINT8CLAMPEDARRAY;\n } else if (valueType === '[object Int16Array]') {\n marker += TYPE_INT16ARRAY;\n } else if (valueType === '[object Uint16Array]') {\n marker += TYPE_UINT16ARRAY;\n } else if (valueType === '[object Int32Array]') {\n marker += TYPE_INT32ARRAY;\n } else if (valueType === '[object Uint32Array]') {\n marker += TYPE_UINT32ARRAY;\n } else if (valueType === '[object Float32Array]') {\n marker += TYPE_FLOAT32ARRAY;\n } else if (valueType === '[object Float64Array]') {\n marker += TYPE_FLOAT64ARRAY;\n } else {\n callback(new Error('Failed to get type for BinaryArray'));\n }\n }\n\n callback(marker + bufferToString(buffer));\n } else if (valueType === '[object Blob]') {\n // Conver the blob to a binaryArray and then to a string.\n var fileReader = new FileReader();\n\n fileReader.onload = function () {\n // Backwards-compatible prefix for the blob type.\n var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result);\n\n callback(SERIALIZED_MARKER + TYPE_BLOB + str);\n };\n\n fileReader.readAsArrayBuffer(value);\n } else {\n try {\n callback(JSON.stringify(value));\n } catch (e) {\n console.error(\"Couldn't convert value into a JSON string: \", value);\n\n callback(null, e);\n }\n }\n}\n\n// Deserialize data we've inserted into a value column/field. We place\n// special markers into our strings to mark them as encoded; this isn't\n// as nice as a meta field, but it's the only sane thing we can do whilst\n// keeping localStorage support intact.\n//\n// Oftentimes this will just deserialize JSON content, but if we have a\n// special marker (SERIALIZED_MARKER, defined above), we will extract\n// some kind of arraybuffer/binary data/typed array out of the string.\nfunction deserialize(value) {\n // If we haven't marked this string as being specially serialized (i.e.\n // something other than serialized JSON), we can just return it and be\n // done with it.\n if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {\n return JSON.parse(value);\n }\n\n // The following code deals with deserializing some kind of Blob or\n // TypedArray. First we separate out the type of data we're dealing\n // with from the data itself.\n var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);\n var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH);\n\n var blobType;\n // Backwards-compatible blob type serialization strategy.\n // DBs created with older versions of localForage will simply not have the blob type.\n if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {\n var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);\n blobType = matcher[1];\n serializedString = serializedString.substring(matcher[0].length);\n }\n var buffer = stringToBuffer(serializedString);\n\n // Return the right type based on the code/type set during\n // serialization.\n switch (type) {\n case TYPE_ARRAYBUFFER:\n return buffer;\n case TYPE_BLOB:\n return createBlob([buffer], { type: blobType });\n case TYPE_INT8ARRAY:\n return new Int8Array(buffer);\n case TYPE_UINT8ARRAY:\n return new Uint8Array(buffer);\n case TYPE_UINT8CLAMPEDARRAY:\n return new Uint8ClampedArray(buffer);\n case TYPE_INT16ARRAY:\n return new Int16Array(buffer);\n case TYPE_UINT16ARRAY:\n return new Uint16Array(buffer);\n case TYPE_INT32ARRAY:\n return new Int32Array(buffer);\n case TYPE_UINT32ARRAY:\n return new Uint32Array(buffer);\n case TYPE_FLOAT32ARRAY:\n return new Float32Array(buffer);\n case TYPE_FLOAT64ARRAY:\n return new Float64Array(buffer);\n default:\n throw new Error('Unkown type: ' + type);\n }\n}\n\nvar localforageSerializer = {\n serialize: serialize,\n deserialize: deserialize,\n stringToBuffer: stringToBuffer,\n bufferToString: bufferToString\n};\n\n/*\n * Includes code from:\n *\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n// Open the WebSQL database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage$1(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i];\n }\n }\n\n var dbInfoPromise = new Promise$1(function (resolve, reject) {\n // Open the database; the openDatabase API will automatically\n // create it for us if it doesn't exist.\n try {\n dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size);\n } catch (e) {\n return reject(e);\n }\n\n // Create our key/value table if it doesn't exist.\n dbInfo.db.transaction(function (t) {\n t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' (id INTEGER PRIMARY KEY, key unique, value)', [], function () {\n self._dbInfo = dbInfo;\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n });\n\n dbInfo.serializer = localforageSerializer;\n return dbInfoPromise;\n}\n\nfunction getItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).value : null;\n\n // Check to see if this is serialized content we need to\n // unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction iterate$1(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName, [], function (t, results) {\n var rows = results.rows;\n var length = rows.length;\n\n for (var i = 0; i < length; i++) {\n var item = rows.item(i);\n var result = item.value;\n\n // Check to see if this is serialized content\n // we need to unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n result = iterator(result, item.key, i + 1);\n\n // void(0) prevents problems with redefinition\n // of `undefined`.\n if (result !== void 0) {\n resolve(result);\n return;\n }\n }\n\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction _setItem(key, value, callback, retriesLeft) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n // The localStorage API doesn't return undefined values in an\n // \"expected\" way, so undefined is always cast to null in all\n // drivers. See: https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n dbInfo.db.transaction(function (t) {\n t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + ' (key, value) VALUES (?, ?)', [key, value], function () {\n resolve(originalValue);\n }, function (t, error) {\n reject(error);\n });\n }, function (sqlError) {\n // The transaction failed; check\n // to see if it's a quota error.\n if (sqlError.code === sqlError.QUOTA_ERR) {\n // We reject the callback outright for now, but\n // it's worth trying to re-run the transaction.\n // Even if the user accepts the prompt to use\n // more storage on Safari, this error will\n // be called.\n //\n // Try to re-run the transaction.\n if (retriesLeft > 0) {\n resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1]));\n return;\n }\n reject(sqlError);\n }\n });\n }\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction setItem$1(key, value, callback) {\n return _setItem.apply(this, [key, value, callback, 1]);\n}\n\nfunction removeItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () {\n resolve();\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Deletes every item in the table.\n// TODO: Find out if this resets the AUTO_INCREMENT number.\nfunction clear$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function () {\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Does a simple `COUNT(key)` to get the number of items stored in\n// localForage.\nfunction length$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n // Ahhh, SQL makes this one soooooo easy.\n t.executeSql('SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) {\n var result = results.rows.item(0).c;\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Return the key located at key index X; essentially gets the key from a\n// `WHERE id = ?`. This is the most efficient way I can think to implement\n// this rarely-used (in my experience) part of the API, but it can seem\n// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so\n// the ID of each key will change every time it's updated. Perhaps a stored\n// procedure for the `setItem()` SQL would solve this problem?\n// TODO: Don't change ID on `setItem()`.\nfunction key$1(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).key : null;\n resolve(result);\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName, [], function (t, results) {\n var keys = [];\n\n for (var i = 0; i < results.rows.length; i++) {\n keys.push(results.rows.item(i).key);\n }\n\n resolve(keys);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar webSQLStorage = {\n _driver: 'webSQLStorage',\n _initStorage: _initStorage$1,\n iterate: iterate$1,\n getItem: getItem$1,\n setItem: setItem$1,\n removeItem: removeItem$1,\n clear: clear$1,\n length: length$1,\n key: key$1,\n keys: keys$1\n};\n\n// Config the localStorage backend, using options set in the config.\nfunction _initStorage$2(options) {\n var self = this;\n var dbInfo = {};\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n dbInfo.keyPrefix = dbInfo.name + '/';\n\n if (dbInfo.storeName !== self._defaultConfig.storeName) {\n dbInfo.keyPrefix += dbInfo.storeName + '/';\n }\n\n self._dbInfo = dbInfo;\n dbInfo.serializer = localforageSerializer;\n\n return Promise$1.resolve();\n}\n\n// Remove all keys from the datastore, effectively destroying all data in\n// the app's key/value store!\nfunction clear$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var keyPrefix = self._dbInfo.keyPrefix;\n\n for (var i = localStorage.length - 1; i >= 0; i--) {\n var key = localStorage.key(i);\n\n if (key.indexOf(keyPrefix) === 0) {\n localStorage.removeItem(key);\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Retrieve an item from the store. Unlike the original async_storage\n// library in Gaia, we don't modify return values at all. If a key's value\n// is `undefined`, we pass that value to the callback function.\nfunction getItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result = localStorage.getItem(dbInfo.keyPrefix + key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the key\n // is likely undefined and we'll pass it straight to the\n // callback.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items in the store.\nfunction iterate$2(iterator, callback) {\n var self = this;\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var keyPrefix = dbInfo.keyPrefix;\n var keyPrefixLength = keyPrefix.length;\n var length = localStorage.length;\n\n // We use a dedicated iterator instead of the `i` variable below\n // so other keys we fetch in localStorage aren't counted in\n // the `iterationNumber` argument passed to the `iterate()`\n // callback.\n //\n // See: github.com/mozilla/localForage/pull/435#discussion_r38061530\n var iterationNumber = 1;\n\n for (var i = 0; i < length; i++) {\n var key = localStorage.key(i);\n if (key.indexOf(keyPrefix) !== 0) {\n continue;\n }\n var value = localStorage.getItem(key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the\n // key is likely undefined and we'll pass it straight\n // to the iterator.\n if (value) {\n value = dbInfo.serializer.deserialize(value);\n }\n\n value = iterator(value, key.substring(keyPrefixLength), iterationNumber++);\n\n if (value !== void 0) {\n return value;\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Same as localStorage's key() method, except takes a callback.\nfunction key$2(n, callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result;\n try {\n result = localStorage.key(n);\n } catch (error) {\n result = null;\n }\n\n // Remove the prefix from the key, if a key is found.\n if (result) {\n result = result.substring(dbInfo.keyPrefix.length);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var length = localStorage.length;\n var keys = [];\n\n for (var i = 0; i < length; i++) {\n if (localStorage.key(i).indexOf(dbInfo.keyPrefix) === 0) {\n keys.push(localStorage.key(i).substring(dbInfo.keyPrefix.length));\n }\n }\n\n return keys;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Supply the number of keys in the datastore to the callback function.\nfunction length$2(callback) {\n var self = this;\n var promise = self.keys().then(function (keys) {\n return keys.length;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Remove an item from the store, nice and simple.\nfunction removeItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n localStorage.removeItem(dbInfo.keyPrefix + key);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Set a key's value and run an optional callback once the value is set.\n// Unlike Gaia's implementation, the callback function is passed the value,\n// in case you want to operate on that value only after you're sure it\n// saved, or something like that.\nfunction setItem$2(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n // Convert undefined values to null.\n // https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n return new Promise$1(function (resolve, reject) {\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n try {\n localStorage.setItem(dbInfo.keyPrefix + key, value);\n resolve(originalValue);\n } catch (e) {\n // localStorage capacity exceeded.\n // TODO: Make this a specific error/event.\n if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {\n reject(e);\n }\n reject(e);\n }\n }\n });\n });\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar localStorageWrapper = {\n _driver: 'localStorageWrapper',\n _initStorage: _initStorage$2,\n // Default API, from Gaia/localStorage.\n iterate: iterate$2,\n getItem: getItem$2,\n setItem: setItem$2,\n removeItem: removeItem$2,\n clear: clear$2,\n length: length$2,\n key: key$2,\n keys: keys$2\n};\n\n// Custom drivers are stored here when `defineDriver()` is called.\n// They are shared across all instances of localForage.\nvar CustomDrivers = {};\n\nvar DriverType = {\n INDEXEDDB: 'asyncStorage',\n LOCALSTORAGE: 'localStorageWrapper',\n WEBSQL: 'webSQLStorage'\n};\n\nvar DefaultDriverOrder = [DriverType.INDEXEDDB, DriverType.WEBSQL, DriverType.LOCALSTORAGE];\n\nvar LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem'];\n\nvar DefaultConfig = {\n description: '',\n driver: DefaultDriverOrder.slice(),\n name: 'localforage',\n // Default DB size is _JUST UNDER_ 5MB, as it's the highest size\n // we can use without a prompt.\n size: 4980736,\n storeName: 'keyvaluepairs',\n version: 1.0\n};\n\nvar driverSupport = {};\n// Check to see if IndexedDB is available and if it is the latest\n// implementation; it's our preferred backend library. We use \"_spec_test\"\n// as the name of the database because it's not the one we'll operate on,\n// but it's useful to make sure its using the right spec.\n// See: https://github.com/mozilla/localForage/issues/128\ndriverSupport[DriverType.INDEXEDDB] = isIndexedDBValid();\n\ndriverSupport[DriverType.WEBSQL] = isWebSQLValid();\n\ndriverSupport[DriverType.LOCALSTORAGE] = isLocalStorageValid();\n\nvar isArray = Array.isArray || function (arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n};\n\nfunction callWhenReady(localForageInstance, libraryMethod) {\n localForageInstance[libraryMethod] = function () {\n var _args = arguments;\n return localForageInstance.ready().then(function () {\n return localForageInstance[libraryMethod].apply(localForageInstance, _args);\n });\n };\n}\n\nfunction extend() {\n for (var i = 1; i < arguments.length; i++) {\n var arg = arguments[i];\n\n if (arg) {\n for (var key in arg) {\n if (arg.hasOwnProperty(key)) {\n if (isArray(arg[key])) {\n arguments[0][key] = arg[key].slice();\n } else {\n arguments[0][key] = arg[key];\n }\n }\n }\n }\n }\n\n return arguments[0];\n}\n\nfunction isLibraryDriver(driverName) {\n for (var driver in DriverType) {\n if (DriverType.hasOwnProperty(driver) && DriverType[driver] === driverName) {\n return true;\n }\n }\n\n return false;\n}\n\nvar LocalForage = function () {\n function LocalForage(options) {\n _classCallCheck(this, LocalForage);\n\n this.INDEXEDDB = DriverType.INDEXEDDB;\n this.LOCALSTORAGE = DriverType.LOCALSTORAGE;\n this.WEBSQL = DriverType.WEBSQL;\n\n this._defaultConfig = extend({}, DefaultConfig);\n this._config = extend({}, this._defaultConfig, options);\n this._driverSet = null;\n this._initDriver = null;\n this._ready = false;\n this._dbInfo = null;\n\n this._wrapLibraryMethodsWithReady();\n this.setDriver(this._config.driver)[\"catch\"](function () {});\n }\n\n // Set any config values for localForage; can be called anytime before\n // the first API call (e.g. `getItem`, `setItem`).\n // We loop through options so we don't overwrite existing config\n // values.\n\n\n LocalForage.prototype.config = function config(options) {\n // If the options argument is an object, we use it to set values.\n // Otherwise, we return either a specified config value or all\n // config values.\n if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {\n // If localforage is ready and fully initialized, we can't set\n // any new configuration values. Instead, we return an error.\n if (this._ready) {\n return new Error(\"Can't call config() after localforage \" + 'has been used.');\n }\n\n for (var i in options) {\n if (i === 'storeName') {\n options[i] = options[i].replace(/\\W/g, '_');\n }\n\n if (i === 'version' && typeof options[i] !== 'number') {\n return new Error('Database version must be a number.');\n }\n\n this._config[i] = options[i];\n }\n\n // after all config options are set and\n // the driver option is used, try setting it\n if ('driver' in options && options.driver) {\n return this.setDriver(this._config.driver);\n }\n\n return true;\n } else if (typeof options === 'string') {\n return this._config[options];\n } else {\n return this._config;\n }\n };\n\n // Used to define a custom driver, shared across all instances of\n // localForage.\n\n\n LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) {\n var promise = new Promise$1(function (resolve, reject) {\n try {\n var driverName = driverObject._driver;\n var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver');\n var namingError = new Error('Custom driver name already in use: ' + driverObject._driver);\n\n // A driver name should be defined and not overlap with the\n // library-defined, default drivers.\n if (!driverObject._driver) {\n reject(complianceError);\n return;\n }\n if (isLibraryDriver(driverObject._driver)) {\n reject(namingError);\n return;\n }\n\n var customDriverMethods = LibraryMethods.concat('_initStorage');\n for (var i = 0; i < customDriverMethods.length; i++) {\n var customDriverMethod = customDriverMethods[i];\n if (!customDriverMethod || !driverObject[customDriverMethod] || typeof driverObject[customDriverMethod] !== 'function') {\n reject(complianceError);\n return;\n }\n }\n\n var supportPromise = Promise$1.resolve(true);\n if ('_support' in driverObject) {\n if (driverObject._support && typeof driverObject._support === 'function') {\n supportPromise = driverObject._support();\n } else {\n supportPromise = Promise$1.resolve(!!driverObject._support);\n }\n }\n\n supportPromise.then(function (supportResult) {\n driverSupport[driverName] = supportResult;\n CustomDrivers[driverName] = driverObject;\n resolve();\n }, reject);\n } catch (e) {\n reject(e);\n }\n });\n\n executeTwoCallbacks(promise, callback, errorCallback);\n return promise;\n };\n\n LocalForage.prototype.driver = function driver() {\n return this._driver || null;\n };\n\n LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) {\n var self = this;\n var getDriverPromise = Promise$1.resolve().then(function () {\n if (isLibraryDriver(driverName)) {\n switch (driverName) {\n case self.INDEXEDDB:\n return asyncStorage;\n case self.LOCALSTORAGE:\n return localStorageWrapper;\n case self.WEBSQL:\n return webSQLStorage;\n }\n } else if (CustomDrivers[driverName]) {\n return CustomDrivers[driverName];\n } else {\n throw new Error('Driver not found.');\n }\n });\n executeTwoCallbacks(getDriverPromise, callback, errorCallback);\n return getDriverPromise;\n };\n\n LocalForage.prototype.getSerializer = function getSerializer(callback) {\n var serializerPromise = Promise$1.resolve(localforageSerializer);\n executeTwoCallbacks(serializerPromise, callback);\n return serializerPromise;\n };\n\n LocalForage.prototype.ready = function ready(callback) {\n var self = this;\n\n var promise = self._driverSet.then(function () {\n if (self._ready === null) {\n self._ready = self._initDriver();\n }\n\n return self._ready;\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n };\n\n LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) {\n var self = this;\n\n if (!isArray(drivers)) {\n drivers = [drivers];\n }\n\n var supportedDrivers = this._getSupportedDrivers(drivers);\n\n function setDriverToConfig() {\n self._config.driver = self.driver();\n }\n\n function extendSelfWithDriver(driver) {\n self._extend(driver);\n setDriverToConfig();\n\n self._ready = self._initStorage(self._config);\n return self._ready;\n }\n\n function initDriver(supportedDrivers) {\n return function () {\n var currentDriverIndex = 0;\n\n function driverPromiseLoop() {\n while (currentDriverIndex < supportedDrivers.length) {\n var driverName = supportedDrivers[currentDriverIndex];\n currentDriverIndex++;\n\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(extendSelfWithDriver)[\"catch\"](driverPromiseLoop);\n }\n\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n }\n\n return driverPromiseLoop();\n };\n }\n\n // There might be a driver initialization in progress\n // so wait for it to finish in order to avoid a possible\n // race condition to set _dbInfo\n var oldDriverSetDone = this._driverSet !== null ? this._driverSet[\"catch\"](function () {\n return Promise$1.resolve();\n }) : Promise$1.resolve();\n\n this._driverSet = oldDriverSetDone.then(function () {\n var driverName = supportedDrivers[0];\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(function (driver) {\n self._driver = driver._driver;\n setDriverToConfig();\n self._wrapLibraryMethodsWithReady();\n self._initDriver = initDriver(supportedDrivers);\n });\n })[\"catch\"](function () {\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n });\n\n executeTwoCallbacks(this._driverSet, callback, errorCallback);\n return this._driverSet;\n };\n\n LocalForage.prototype.supports = function supports(driverName) {\n return !!driverSupport[driverName];\n };\n\n LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) {\n extend(this, libraryMethodsAndProperties);\n };\n\n LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) {\n var supportedDrivers = [];\n for (var i = 0, len = drivers.length; i < len; i++) {\n var driverName = drivers[i];\n if (this.supports(driverName)) {\n supportedDrivers.push(driverName);\n }\n }\n return supportedDrivers;\n };\n\n LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() {\n // Add a stub for each driver API method that delays the call to the\n // corresponding driver method until localForage is ready. These stubs\n // will be replaced by the driver methods as soon as the driver is\n // loaded, so there is no performance impact.\n for (var i = 0; i < LibraryMethods.length; i++) {\n callWhenReady(this, LibraryMethods[i]);\n }\n };\n\n LocalForage.prototype.createInstance = function createInstance(options) {\n return new LocalForage(options);\n };\n\n return LocalForage;\n}();\n\n// The actual localForage object that we expose as a module or via a\n// global. It's extended by pulling in one of our other libraries.\n\n\nvar localforage_js = new LocalForage();\n\nmodule.exports = localforage_js;\n\n},{\"3\":3}]},{},[4])(4)\n});","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n // Let \"new String('')\" return 'object'\n if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n // PhantomJS has type \"DOMWindow\" for null\n if (obj === null) return 'null';\n // PhantomJS has type \"DOMWindow\" for undefined\n if (obj === undefined) return 'undefined';\n return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n if (!(this instanceof Library)) return new Library();\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","(function (document, window) {\n // DEPENDENCIES\n // ============================================================\n const localforage = require('localforage');\n\n // PROBLEMS\n // ============================================================\n const problems = require('../problems/arrays.js');\n\n // CONFIG\n // ============================================================\n\n // Hoist current problem\n let currentProblem;\n\n // Keys to ignore while user is navigating around the textarea but not changing any code\n const ignoreKeyCodes = [\n 9, // Tab\n 37, // Left arrow\n 39, // Right arrow\n 38, // Up arrow\n 40 // Down arrow\n ];\n\n let config = {\n shuffle: true,\n timer: false,\n currentIndex: 0\n };\n\n // Pull config from localforage\n localforage\n .getItem('js_practice_config')\n .then(val => {\n // console.log('localforage val:', val);\n if (val) {\n config = val;\n }\n loadApp(config);\n })\n .catch(err => {\n console.log('localforage err:', err);\n loadApp(config);\n });\n\n function updateLocalstore(config) {\n return localforage\n .setItem('js_practice_config', config)\n .then(val => {\n // console.log('Settings updated:', val);\n })\n .catch(err => {\n console.log('Settings update error:', err);\n });\n }\n\n // HELPERS\n // ============================================================\n\n function debounce(func, wait, immediate) {\n let timeout;\n return function () {\n const context = this;\n const args = arguments;\n const later = function () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n };\n const callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) {\n func.apply(context, args);\n }\n };\n }\n\n // UI\n // ============================================================\n\n // elements\n const problemEl = document.getElementById('problem');\n const codeEl = document.getElementById('code');\n const testSuiteEl = document.getElementById('test-suite');\n const testTotalEl = document.getElementById('test-total');\n const evalConsoleEl = document.getElementById('eval-output');\n const assertConsoleEl = document.getElementById('assert-output');\n const shuffleProblemsButtonEl = document.getElementById('shuffle-problems');\n const previousProblemButtonEl = document.getElementById('prev-problem');\n const nextProblemButtonEl = document.getElementById('next-problem');\n\n // Get indexes\n function getRandomIndex(problemsArr) {\n const ind = Math.floor(Math.random() * problemsArr.length);\n config.currentIndex = ind;\n updateLocalstore(config);\n return ind;\n }\n\n function getPreviousIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at beginning, go to end\n if (currentIndex === 0) {\n probInd = problemsArr.length - 1;\n } else {\n probInd = currentIndex - 1;\n }\n return probInd;\n }\n\n function getNextIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at end or invalid, restart series\n if (currentIndex >= problemsArr.length - 1 || currentIndex < 0) {\n probInd = 0;\n } else {\n probInd = currentIndex + 1;\n }\n return probInd;\n }\n\n // Get problems\n function getCurrentProblem(problemsArr) {\n return problemsArr[config.currentIndex];\n }\n\n function previousProblem() {\n console.log('previousProblem!');\n // Activate back button, for visual queue of nav feedback\n previousProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getPreviousIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function nextProblem() {\n console.log('nextProblem!');\n // Activate next button, for visual queue of nav feedback\n nextProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getNextIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function toggleShuffle() {\n console.log('toggle shuffle!');\n config.shuffle = !config.shuffle; // Flip it\n shuffleProblemsButtonEl.classList.toggle('active');\n previousProblemButtonEl.parentNode.classList.toggle('hidden');\n updateLocalstore(config);\n }\n\n function loadProblem(problemObj) {\n currentProblem = problemObj;\n // Prob question\n problemEl.innerText = problemObj.prompt;\n // Prob given code\n if (problemObj.given) {\n codeEl.value = problemObj.given;\n }\n // Seed the tests, pass (init = true) as second param\n testSuite(null, true);\n }\n\n // TODO: Build the assert errors into the test dom on each update.\n function updateTests(testStatus, init) {\n if (init === true) {\n buildTests(currentProblem.tests);\n }\n updateTestStatus(testStatus);\n }\n\n function buildTests(tests) {\n if (tests) {\n const testsDom = tests\n .map(test => {\n return `
\n
[✘]
\n
${test.name}
\n
`;\n })\n .join('');\n testSuiteEl.innerHTML = testsDom;\n }\n }\n\n function updateTestStatus(testStatuses) {\n if (!testStatuses) {\n throw new Error('No testStatuses provided.');\n }\n // Find out if all tests have passed or not\n let allPassed = true;\n testStatuses.forEach(testPassed => {\n if (testPassed !== true) {\n allPassed = false;\n }\n });\n const testEls = [].slice.call(testSuiteEl.querySelectorAll('.test-state'));\n testEls.forEach((testStatusEl, iter) => {\n if (testStatuses[iter] === true) {\n testStatusEl.innerHTML = '[✓]';\n testStatusEl.classList.remove('fail');\n testStatusEl.classList.add('pass');\n } else {\n testStatusEl.innerHTML = '[✘]';\n testStatusEl.classList.remove('pass');\n testStatusEl.classList.add('fail');\n }\n });\n\n if (allPassed === true) {\n testTotalEl.innerText = 'PASS';\n testTotalEl.classList.remove('fail');\n testTotalEl.classList.add('pass');\n } else {\n testTotalEl.innerText = 'FAIL';\n testTotalEl.classList.remove('pass');\n testTotalEl.classList.add('fail');\n }\n }\n\n function printAssertError(errObj) {\n // Make element string\n let inner = '';\n if (errObj !== null) {\n inner = `\n
\n Expected: ${JSON.stringify(errObj.expected)}\n Actual: ${JSON.stringify(errObj.actual)}\n
`;\n }\n\n // Prepend element\n assertConsoleEl.innerHTML = inner;\n }\n\n function printEvalOutput(errObj, output) {\n // Make element string\n let inner = '';\n if (errObj && errObj.message !== undefined) {\n inner = `\n
\n Syntax Error: ${JSON.stringify(errObj.message)}\n
`;\n } else if (output) {\n inner = `\n
\n Output: ${JSON.stringify(output)}\n
`;\n }\n // Prepend element\n evalConsoleEl.innerHTML = inner;\n }\n\n // VERIFICATION LOGIC\n // ============================================================\n\n function testSuite(init) {\n // Show 'working' indicator\n testTotalEl.classList.toggle('working');\n // Run stuff\n const output = getOutput(codeEl.value);\n // Run tests on code, return object/array of test results\n const tested = runTests(output);\n // Hide 'working' indicator\n testTotalEl.classList.toggle('working');\n // Update UI with results\n updateTests(tested, init);\n }\n\n function getOutput(code) {\n let evald = false;\n try {\n evald = eval(`(function(){${code}})()`); // eslint-disable-line no-eval\n printEvalOutput(null, evald); // Print current output\n } catch (err) {\n printEvalOutput(err);\n }\n return evald;\n }\n\n function runTests(output) {\n let tested = false;\n tested = currentProblem.tests.map(test => {\n let testOutcome = false;\n try {\n if (output) {\n testOutcome = test.test(output);\n }\n printAssertError(null);\n } catch (err) {\n printAssertError(err);\n }\n return testOutcome;\n });\n return tested;\n }\n\n // Wrapped to prevent race with local config retrieval\n function loadApp(config) {\n console.log('loading app!');\n\n // Show current toggle state\n if (config.shuffle === true) {\n shuffleProblemsButtonEl.classList.add('active');\n previousProblemButtonEl.parentNode.classList.add('hidden');\n }\n\n // Keybinding stuff\n // ============================================================\n\n // Debounced code validation\n const debouncedInputValidation = debounce(e => {\n // If not arrow keys or other non-character keys\n if (ignoreKeyCodes.indexOf(e.keyCode) === -1) {\n // Run test suite\n testSuite();\n }\n }, 200);\n\n function problemNav(e) {\n // Go to previous problem keybinding\n // If CMD/CTRL + SHIFT + RETURN/ENTER\n if (config.shuffle === false && e.keyCode === 13 && e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem\n previousProblem();\n } else if (e.keyCode === 13 && !e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem keybinding\n // If CMD/CTRL + RETURN/ENTER\n // Go to next problem\n nextProblem();\n }\n }\n\n // Event Bindings\n // ============================================================\n\n // Bind it up\n codeEl.addEventListener('keydown', debouncedInputValidation);\n document.addEventListener('keydown', problemNav);\n shuffleProblemsButtonEl.addEventListener('click', toggleShuffle);\n previousProblemButtonEl.addEventListener('click', previousProblem);\n nextProblemButtonEl.addEventListener('click', nextProblem);\n\n // Start it up!\n // Load current problem\n const currProb = getCurrentProblem(problems);\n loadProblem(currProb);\n // Initalized test suite with starting failures\n testSuite(true);\n }\n})(document, window);\n","const assert = require('chai').assert;\n\nmodule.exports = [\n {\n name: 'Create Array',\n time: 10,\n prompt: 'Create and return an array that contains \\'apple\\' and \\'banana\\'',\n given: `const fruits = [];\\rreturn fruits;`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, ['apple', 'banana']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Access Array by index (first)',\n time: 10,\n prompt: 'Return the first value of the Array',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits[0];`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 'apple') === undefined;\n }\n },\n {\n name: 'Returns a String',\n test(output) {\n return assert.isString(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Access Array by index (last)',\n time: 10,\n prompt: 'Return the last value of the Array',\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n return fruits[fruits.length - 1];`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 'orange') === undefined;\n }\n },\n {\n name: 'Returns a String',\n test(output) {\n return assert.isString(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Access Array by index (second)',\n time: 10,\n prompt: 'Return the second value of the Array',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits[1];`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 'banana') === undefined;\n }\n },\n {\n name: 'Returns a String',\n test(output) {\n return assert.isString(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.forEach()',\n time: 20,\n prompt: 'Loop over the array, add an \\'x\\' to the end of each name, push each fruit into a new array, then return the new array.',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n const newFruits = [];\n fruits.forEach(function(item) {\n newFruits.push(item+'x');\n });\n return newFruits;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, ['applex', 'bananax']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.push()',\n time: 10,\n prompt: `Add 'orange' to the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n fruits.push('orange');\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return (assert.deepEqual(output, ['apple', 'banana', 'orange']) === undefined);\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 3 items',\n test(output) {\n return assert.lengthOf(output, 3) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.pop()',\n time: 10,\n prompt: `Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, ['apple', 'banana']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.shift()',\n time: 10,\n prompt: `Remove 'apple' from the front of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.shift();\n return fruits;`,\n tests: [\n {\n name: 'Output must be correct',\n test(output) {\n return assert.deepEqual(output, ['banana', 'orange']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.unshift()',\n time: 10,\n prompt: `Add 'strawberry' to the front of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.unshift('strawberry');\n return fruits;`,\n tests: [\n {\n name: 'Output must be correct',\n test(output) {\n return (\n assert.deepEqual(output, [\n 'strawberry',\n 'apple',\n 'banana',\n 'orange'\n ]) === undefined\n );\n }\n },\n {\n name: 'Must return an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 4 items',\n test(output) {\n return assert.lengthOf(output, 4) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.indexOf()',\n time: 10,\n prompt: `Return the index of 'banana' in the Array.`,\n given: `const fruits = ['strawberry', 'banana', 'mango'];\\r`,\n answer: `const fruits = ['strawberry', 'banana', 'mango'];\n const ind = fruits.indexOf('banana');\n return ind;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 1) === undefined;\n }\n },\n {\n name: 'Returns a Number',\n test(output) {\n return assert.isNumber(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.concat()',\n time: 10,\n prompt: `Merge the two arrays using Array's 'concat()' method. Return the resulting array.`,\n given: `const fruits = ['strawberry', 'banana'];\\rconst otherFruits = ['pear','peach'];\\r`,\n answer: `const fruits = ['strawberry', 'banana'];\n const otherFruits = ['pear','peach'];\n const allTheFruits = fruits.concat(otherFruits);\n return allTheFruits;\\r`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return (\n assert.deepEqual(output, [\n 'strawberry',\n 'banana',\n 'pear',\n 'peach'\n ]) === undefined\n );\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 4 items',\n test(output) {\n return assert.lengthOf(output, 4) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.join()',\n time: 10,\n prompt: `Mix the two flavors with a '-' using Array's 'join' method. Return the resulting hybrid flavor.`,\n given: `const fruits = ['strawberry', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'banana'];\n const hybrid = fruits.join('-');\n return hybrid;\\r`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 'strawberry-banana') === undefined;\n }\n },\n {\n name: 'Returns a String',\n test(output) {\n return assert.isString(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.slice()',\n time: 20,\n prompt: `Return just the citrus fruits from the 'fruits' array using 'Array.slice()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const citrus = fruits.slice(1, 3);\n return citrus;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, ['orange', 'lemon']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.reverse()',\n time: 10,\n prompt: `Reverse the order of the 'fruit' array using 'Array.reverse()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const stiurf = fruits.reverse();\n return stiurf;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return (\n assert.deepEqual(output, [\n 'banana',\n 'lemon',\n 'orange',\n 'strawberry'\n ]) === undefined\n );\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 4 items',\n test(output) {\n return assert.lengthOf(output, 4) === undefined;\n }\n },\n {\n name: `First item is 'banana'`,\n test(output) {\n return assert.deepEqual(output[0], 'banana') === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.sort()',\n time: 10,\n prompt: `Sort the order of the 'fruit' array using 'Array.sort()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const orderlyFruit = fruits.sort();\n return orderlyFruit;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return (\n assert.deepEqual(output, [\n 'banana',\n 'lemon',\n 'orange',\n 'strawberry'\n ]) === undefined\n );\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 4 items',\n test(output) {\n return assert.lengthOf(output, 4) === undefined;\n }\n },\n {\n name: `First item is 'banana'`,\n test(output) {\n return assert.deepEqual(output[0], 'banana') === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.lastIndexOf()',\n time: 10,\n prompt: `Return the index of the last 'peach' instance in the 'fruit' array using 'Array.lastIndexOf()'`,\n given: `const fruits = ['peach', 'orange', 'lemon', 'peach'];\\r`,\n answer: `const fruits = ['peach', 'orange', 'lemon', 'peach'];\n const wheresTheLastPeach = fruits.lastIndexOf('peach');\n return wheresTheLastPeach;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 3) === undefined;\n }\n },\n {\n name: 'Returns a Number',\n test(output) {\n return assert.isNumber(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.filter()',\n time: 10,\n prompt: `Return an array of the numbers greater than 5 in 'numbers' using 'Array.filter()'`,\n given: `const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\\r`,\n answer: `const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\n const overFive = numbers.filter(num => num > 5);\n return overFive;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, [8, 13, 21]) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 3 items',\n test(output) {\n return assert.lengthOf(output, 3) === undefined;\n }\n },\n {\n name: `First item is 8`,\n test(output) {\n return assert.deepEqual(output[0], 8) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.map()',\n time: 10,\n prompt: `Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,\n given: `const numbers = [25, 121, 169];\\r`,\n answer: `const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, [5, 11, 13]) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 3 items',\n test(output) {\n return assert.lengthOf(output, 3) === undefined;\n }\n },\n {\n name: `First item is 5`,\n test(output) {\n return assert.deepEqual(output[0], 5) === undefined;\n }\n },\n {\n name: `Last item is 13`,\n test(output) {\n return assert.deepEqual(output[output.length - 1], 13) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.every()',\n time: 10,\n prompt: `Return object that returns whether each array contains all even numbers using Array.every().`,\n given: `\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 5, 6, 8];\nfunction isEven(element) {\n\n}\nreturn {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n};`,\n answer: `\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 5, 6, 8];\nfunction isEven(element) {\n return element % 2 === 0\n}\nreturn {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n};`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;\n }\n },\n {\n name: 'Returns an Object',\n test(output) {\n return assert.isObject(output) === undefined;\n }\n },\n {\n name: 'Object has 2 items',\n test(output) {\n return assert.lengthOf(Object.keys(output), 2) === undefined;\n }\n },\n {\n name: `First value is true`,\n test(output) {\n return assert.isTrue(output.evenNumbers) === undefined;\n }\n },\n {\n name: `Second value is false`,\n test(output) {\n return assert.isFalse(output.someOddNumbers) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.some()',\n time: 10,\n prompt: `Return object that returns whether each array contains some odd numbers using Array.some().`,\n given: `\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 4, 7, 8];\nfunction isOdd(element) {\n\n}\nreturn {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n};`,\n answer: `\nconst evenNumbers = [1, 3, 5, 7];\nconst someOddNumbers = [1, 3, 6, 7];\nfunction isOdd(element) {\n return element % 2 !== 0;\n}\nreturn {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n};`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;\n }\n },\n {\n name: 'Returns an Object',\n test(output) {\n return assert.isObject(output) === undefined;\n }\n },\n {\n name: 'Object has 2 items',\n test(output) {\n return assert.lengthOf(Object.keys(output), 2) === undefined;\n }\n },\n {\n name: `First value is false`,\n test(output) {\n return assert.isFalse(output.evenNumbers) === undefined;\n }\n },\n {\n name: `Second value is true`,\n test(output) {\n return assert.isTrue(output.someOddNumbers) === undefined;\n }\n }\n ]\n }\n // Next problems to create:\n // forEach? fix one above that tried, but can't verify forEach was used\n // some\n // reduce\n // reduceRight\n // Array.from and other ways to turn array-like into array\n];\n"]} +======= +{"version":3,"sources":["node_modules/.registry.npmjs.org/browser-pack/6.0.2/node_modules/browser-pack/_prelude.js","node_modules/.github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916/node_modules/pjs-problems/index.js","node_modules/.github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916/node_modules/pjs-problems/problems/arrays.js","node_modules/.github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916/node_modules/pjs-problems/problems/initial.js","node_modules/.registry.npmjs.org/assertion-error/1.0.2/node_modules/assertion-error/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/assertion.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/config.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/core/assertions.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/assert.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/expect.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/should.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addChainableMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/expectTypes.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/flag.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getActual.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getEnumerableProperties.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getMessage.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getName.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getPathInfo.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getPathValue.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getProperties.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/hasProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/inspect.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/objDisplay.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/test.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/transferFlags.js","node_modules/.registry.npmjs.org/dedent/0.7.0/node_modules/dedent/dist/dedent.js","node_modules/.registry.npmjs.org/deep-eql/0.1.3/node_modules/deep-eql/index.js","node_modules/.registry.npmjs.org/deep-eql/0.1.3/node_modules/deep-eql/lib/eql.js","node_modules/.registry.npmjs.org/localforage/1.5.0/node_modules/localforage/dist/node_modules/localforage/dist/localforage.js","node_modules/.registry.npmjs.org/type-detect/0.1.1/node_modules/type-detect/index.js","node_modules/.registry.npmjs.org/type-detect/0.1.1/node_modules/type-detect/lib/type.js","node_modules/.registry.npmjs.org/type-detect/1.0.0/node_modules/type-detect/lib/type.js","src/js/index.js"],"names":[],"mappings":"AAAA;ACAA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1eA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpHA;AACA;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACp0DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7mDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/UA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3DA;AACA;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACjQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACxwEA;AACA;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACtIA,CAAC,UAAU,QAAV,EAAoB,MAApB,EAA4B;AAC3B;AACA;;AAEA,MAAM,cAAc,QAAQ,aAAR,CAApB;AACA,MAAM,QAAQ,QAAQ,cAAR,CAAd;AACA,MAAM,SAAS,QAAQ,QAAR,CAAf;AACA,MAAM,SAAS,QAAQ,MAAR,EAAgB,MAA/B;;AAEA;AACA;;AAEA,WAAS,aAAT,CAAuB,QAAvB,EAAiC;AAC/B,WAAO,SAAS,GAAT,CAAa,gBAAQ;AAC1B,WAAK,KAAL,GAAa,OAAO,KAAK,KAAZ,CAAb;AACA,WAAK,MAAL,GAAc,OAAO,KAAK,MAAZ,CAAd;AACA,aAAO,IAAP;AACD,KAJM,CAAP;AAKD;;AAGD;AACA;;AAEA,MAAI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","file":"bundle.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o num > 5);\n return overFive;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, [8, 13, 21]) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n },\n {\n name: `First item is 8`,\n test: `assert.deepEqual(output[0], 8) === undefined;`\n }\n ]\n },\n {\n name: 'Array.map()',\n time: 10,\n prompt: `Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,\n given: `const numbers = [25, 121, 169];\\r`,\n answer: `const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, [5, 11, 13]) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n },\n {\n name: `First item is 5`,\n test: `assert.deepEqual(output[0], 5) === undefined;`\n },\n {\n name: `Last item is 13`,\n test: `assert.deepEqual(output[output.length - 1], 13) === undefined;`\n }\n ]\n },\n {\n name: 'Array.every()',\n time: 10,\n prompt: `Return object that returns whether each array contains all even numbers using Array.every().`,\n given: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,\n answer: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n return element % 2 === 0\n }\n return {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n };`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;`\n },\n {\n name: 'Returns an Object',\n test: `assert.isObject(output) === undefined;`\n },\n {\n name: 'Object has 2 items',\n test: `assert.lengthOf(Object.keys(output), 2) === undefined;`\n },\n {\n name: `First value is true`,\n test: `assert.isTrue(output.evenNumbers) === undefined;`\n },\n {\n name: `Second value is false`,\n test: `assert.isFalse(output.someOddNumbers) === undefined;`\n }\n ]\n },\n {\n name: 'Array.some()',\n time: 10,\n prompt: `Return 'Object' that returns whether each array contains some odd numbers using 'Array.some()'.`,\n given: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 4, 7, 8];\n function isOdd(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,\n answer: `const evenNumbers = [1, 3, 5, 7];\n const someOddNumbers = [1, 3, 6, 7];\n function isOdd(element) {\n return element % 2 !== 0;\n }\n return {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n };`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;`\n },\n {\n name: 'Returns an Object',\n test: `assert.isObject(output) === undefined;`\n },\n {\n name: 'Object has 2 items',\n test: `assert.lengthOf(Object.keys(output), 2) === undefined;`\n },\n {\n name: `First value is false`,\n test: `assert.isFalse(output.evenNumbers) === undefined;`\n },\n {\n name: `Second value is true`,\n test: `assert.isTrue(output.someOddNumbers) === undefined;`\n }\n ]\n }\n // Next problems to create:\n // forEach? fix one above that tried, but can't verify forEach was used\n // some\n // reduce\n // reduceRight\n // Array.from and other ways to turn array-like into array\n];\n","module.exports = [\n {\n name: 'Create Array',\n time: 10,\n prompt: 'Create and return an array that contains \\'apple\\' and \\'banana\\'',\n given: `const fruits = [];\\rreturn fruits;`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.pop()',\n time: 10,\n prompt: `Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n]\n","/*!\n * assertion-error\n * Copyright(c) 2013 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n var excludes = [].slice.call(arguments);\n\n function excludeProps (res, obj) {\n Object.keys(obj).forEach(function (key) {\n if (!~excludes.indexOf(key)) res[key] = obj[key];\n });\n }\n\n return function extendExclude () {\n var args = [].slice.call(arguments)\n , i = 0\n , res = {};\n\n for (; i < args.length; i++) {\n excludeProps(res, args[i]);\n }\n\n return res;\n };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n , props = extend(_props || {});\n\n // default values\n this.message = message || 'Unspecified AssertionError';\n this.showDiff = false;\n\n // copy from properties\n for (var key in props) {\n this[key] = props[key];\n }\n\n // capture stack trace\n ssf = ssf || arguments.callee;\n if (ssf && Error.captureStackTrace) {\n Error.captureStackTrace(this, ssf);\n } else {\n try {\n throw new Error();\n } catch(e) {\n this.stack = e.stack;\n }\n }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n var extend = exclude('constructor', 'toJSON', 'stack')\n , props = extend({ name: this.name }, this);\n\n // include stack if exists and not turned off\n if (false !== stack && this.stack) {\n props.stack = this.stack;\n }\n\n return props;\n};\n","module.exports = require('./lib/chai');\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar used = []\n , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n if (!~used.indexOf(fn)) {\n fn(this, util);\n used.push(fn);\n }\n\n return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n /*!\n * Module dependencies.\n */\n\n var AssertionError = _chai.AssertionError\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n _chai.Assertion = Assertion;\n\n /*!\n * Assertion Constructor\n *\n * Creates object for chaining.\n *\n * @api private\n */\n\n function Assertion (obj, msg, stack) {\n flag(this, 'ssfi', stack || arguments.callee);\n flag(this, 'object', obj);\n flag(this, 'message', msg);\n }\n\n Object.defineProperty(Assertion, 'includeStack', {\n get: function() {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n return config.includeStack;\n },\n set: function(value) {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n config.includeStack = value;\n }\n });\n\n Object.defineProperty(Assertion, 'showDiff', {\n get: function() {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n return config.showDiff;\n },\n set: function(value) {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n config.showDiff = value;\n }\n });\n\n Assertion.addProperty = function (name, fn) {\n util.addProperty(this.prototype, name, fn);\n };\n\n Assertion.addMethod = function (name, fn) {\n util.addMethod(this.prototype, name, fn);\n };\n\n Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n Assertion.overwriteProperty = function (name, fn) {\n util.overwriteProperty(this.prototype, name, fn);\n };\n\n Assertion.overwriteMethod = function (name, fn) {\n util.overwriteMethod(this.prototype, name, fn);\n };\n\n Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n /**\n * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n *\n * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n *\n * @name assert\n * @param {Philosophical} expression to be tested\n * @param {String|Function} message or function that returns message to display if expression fails\n * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n * @param {Mixed} expected value (remember to check for negation)\n * @param {Mixed} actual (optional) will default to `this.obj`\n * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n * @api private\n */\n\n Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n var ok = util.test(this, arguments);\n if (true !== showDiff) showDiff = false;\n if (true !== config.showDiff) showDiff = false;\n\n if (!ok) {\n var msg = util.getMessage(this, arguments)\n , actual = util.getActual(this, arguments);\n throw new AssertionError(msg, {\n actual: actual\n , expected: expected\n , showDiff: showDiff\n }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n }\n };\n\n /*!\n * ### ._obj\n *\n * Quick reference to stored `actual` value for plugin developers.\n *\n * @api private\n */\n\n Object.defineProperty(Assertion.prototype, '_obj',\n { get: function () {\n return flag(this, 'object');\n }\n , set: function (val) {\n flag(this, 'object', val);\n }\n });\n};\n","module.exports = {\n\n /**\n * ### config.includeStack\n *\n * User configurable property, influences whether stack trace\n * is included in Assertion error message. Default of false\n * suppresses stack trace in the error message.\n *\n * chai.config.includeStack = true; // enable stack on error\n *\n * @param {Boolean}\n * @api public\n */\n\n includeStack: false,\n\n /**\n * ### config.showDiff\n *\n * User configurable property, influences whether or not\n * the `showDiff` flag should be included in the thrown\n * AssertionErrors. `false` will always be `false`; `true`\n * will be true when the assertion has requested a diff\n * be shown.\n *\n * @param {Boolean}\n * @api public\n */\n\n showDiff: true,\n\n /**\n * ### config.truncateThreshold\n *\n * User configurable property, sets length threshold for actual and\n * expected values in assertion errors. If this threshold is exceeded, for\n * example for large data structures, the value is replaced with something\n * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n *\n * Set it to zero if you want to disable truncating altogether.\n *\n * This is especially userful when doing assertions on arrays: having this\n * set to a reasonable large value makes the failure messages readily\n * inspectable.\n *\n * chai.config.truncateThreshold = 0; // disable truncating\n *\n * @param {Number}\n * @api public\n */\n\n truncateThreshold: 40\n\n};\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n var Assertion = chai.Assertion\n , toString = Object.prototype.toString\n , flag = _.flag;\n\n /**\n * ### Language Chains\n *\n * The following are provided as chainable getters to\n * improve the readability of your assertions. They\n * do not provide testing capabilities unless they\n * have been overwritten by a plugin.\n *\n * **Chains**\n *\n * - to\n * - be\n * - been\n * - is\n * - that\n * - which\n * - and\n * - has\n * - have\n * - with\n * - at\n * - of\n * - same\n *\n * @name language chains\n * @namespace BDD\n * @api public\n */\n\n [ 'to', 'be', 'been'\n , 'is', 'and', 'has', 'have'\n , 'with', 'that', 'which', 'at'\n , 'of', 'same' ].forEach(function (chain) {\n Assertion.addProperty(chain, function () {\n return this;\n });\n });\n\n /**\n * ### .not\n *\n * Negates any of assertions following in the chain.\n *\n * expect(foo).to.not.equal('bar');\n * expect(goodFn).to.not.throw(Error);\n * expect({ foo: 'baz' }).to.have.property('foo')\n * .and.not.equal('bar');\n *\n * @name not\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('not', function () {\n flag(this, 'negate', true);\n });\n\n /**\n * ### .deep\n *\n * Sets the `deep` flag, later used by the `equal` and\n * `property` assertions.\n *\n * expect(foo).to.deep.equal({ bar: 'baz' });\n * expect({ foo: { bar: { baz: 'quux' } } })\n * .to.have.deep.property('foo.bar.baz', 'quux');\n *\n * `.deep.property` special characters can be escaped\n * by adding two slashes before the `.` or `[]`.\n *\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name deep\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('deep', function () {\n flag(this, 'deep', true);\n });\n\n /**\n * ### .any\n *\n * Sets the `any` flag, (opposite of the `all` flag)\n * later used in the `keys` assertion.\n *\n * expect(foo).to.have.any.keys('bar', 'baz');\n *\n * @name any\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('any', function () {\n flag(this, 'any', true);\n flag(this, 'all', false)\n });\n\n\n /**\n * ### .all\n *\n * Sets the `all` flag (opposite of the `any` flag)\n * later used by the `keys` assertion.\n *\n * expect(foo).to.have.all.keys('bar', 'baz');\n *\n * @name all\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('all', function () {\n flag(this, 'all', true);\n flag(this, 'any', false);\n });\n\n /**\n * ### .a(type)\n *\n * The `a` and `an` assertions are aliases that can be\n * used either as language chains or to assert a value's\n * type.\n *\n * // typeof\n * expect('test').to.be.a('string');\n * expect({ foo: 'bar' }).to.be.an('object');\n * expect(null).to.be.a('null');\n * expect(undefined).to.be.an('undefined');\n * expect(new Error).to.be.an('error');\n * expect(new Promise).to.be.a('promise');\n * expect(new Float32Array()).to.be.a('float32array');\n * expect(Symbol()).to.be.a('symbol');\n *\n * // es6 overrides\n * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n *\n * // language chain\n * expect(foo).to.be.an.instanceof(Foo);\n *\n * @name a\n * @alias an\n * @param {String} type\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function an (type, msg) {\n if (msg) flag(this, 'message', msg);\n type = type.toLowerCase();\n var obj = flag(this, 'object')\n , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n this.assert(\n type === _.type(obj)\n , 'expected #{this} to be ' + article + type\n , 'expected #{this} not to be ' + article + type\n );\n }\n\n Assertion.addChainableMethod('an', an);\n Assertion.addChainableMethod('a', an);\n\n /**\n * ### .include(value)\n *\n * The `include` and `contain` assertions can be used as either property\n * based language chains or as methods to assert the inclusion of an object\n * in an array or a substring in a string. When used as language chains,\n * they toggle the `contains` flag for the `keys` assertion.\n *\n * expect([1,2,3]).to.include(2);\n * expect('foobar').to.contain('foo');\n * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n *\n * @name include\n * @alias contain\n * @alias includes\n * @alias contains\n * @param {Object|String|Number} obj\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function includeChainingBehavior () {\n flag(this, 'contains', true);\n }\n\n function include (val, msg) {\n _.expectTypes(this, ['array', 'object', 'string']);\n\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var expected = false;\n\n if (_.type(obj) === 'array' && _.type(val) === 'object') {\n for (var i in obj) {\n if (_.eql(obj[i], val)) {\n expected = true;\n break;\n }\n }\n } else if (_.type(val) === 'object') {\n if (!flag(this, 'negate')) {\n for (var k in val) new Assertion(obj).property(k, val[k]);\n return;\n }\n var subset = {};\n for (var k in val) subset[k] = obj[k];\n expected = _.eql(subset, val);\n } else {\n expected = (obj != undefined) && ~obj.indexOf(val);\n }\n this.assert(\n expected\n , 'expected #{this} to include ' + _.inspect(val)\n , 'expected #{this} to not include ' + _.inspect(val));\n }\n\n Assertion.addChainableMethod('include', include, includeChainingBehavior);\n Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n /**\n * ### .ok\n *\n * Asserts that the target is truthy.\n *\n * expect('everything').to.be.ok;\n * expect(1).to.be.ok;\n * expect(false).to.not.be.ok;\n * expect(undefined).to.not.be.ok;\n * expect(null).to.not.be.ok;\n *\n * @name ok\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('ok', function () {\n this.assert(\n flag(this, 'object')\n , 'expected #{this} to be truthy'\n , 'expected #{this} to be falsy');\n });\n\n /**\n * ### .true\n *\n * Asserts that the target is `true`.\n *\n * expect(true).to.be.true;\n * expect(1).to.not.be.true;\n *\n * @name true\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('true', function () {\n this.assert(\n true === flag(this, 'object')\n , 'expected #{this} to be true'\n , 'expected #{this} to be false'\n , this.negate ? false : true\n );\n });\n\n /**\n * ### .false\n *\n * Asserts that the target is `false`.\n *\n * expect(false).to.be.false;\n * expect(0).to.not.be.false;\n *\n * @name false\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('false', function () {\n this.assert(\n false === flag(this, 'object')\n , 'expected #{this} to be false'\n , 'expected #{this} to be true'\n , this.negate ? true : false\n );\n });\n\n /**\n * ### .null\n *\n * Asserts that the target is `null`.\n *\n * expect(null).to.be.null;\n * expect(undefined).to.not.be.null;\n *\n * @name null\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('null', function () {\n this.assert(\n null === flag(this, 'object')\n , 'expected #{this} to be null'\n , 'expected #{this} not to be null'\n );\n });\n\n /**\n * ### .undefined\n *\n * Asserts that the target is `undefined`.\n *\n * expect(undefined).to.be.undefined;\n * expect(null).to.not.be.undefined;\n *\n * @name undefined\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('undefined', function () {\n this.assert(\n undefined === flag(this, 'object')\n , 'expected #{this} to be undefined'\n , 'expected #{this} not to be undefined'\n );\n });\n\n /**\n * ### .NaN\n * Asserts that the target is `NaN`.\n *\n * expect('foo').to.be.NaN;\n * expect(4).not.to.be.NaN;\n *\n * @name NaN\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('NaN', function () {\n this.assert(\n isNaN(flag(this, 'object'))\n , 'expected #{this} to be NaN'\n , 'expected #{this} not to be NaN'\n );\n });\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi'\n * , bar = null\n * , baz;\n *\n * expect(foo).to.exist;\n * expect(bar).to.not.exist;\n * expect(baz).to.not.exist;\n *\n * @name exist\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('exist', function () {\n this.assert(\n null != flag(this, 'object')\n , 'expected #{this} to exist'\n , 'expected #{this} to not exist'\n );\n });\n\n\n /**\n * ### .empty\n *\n * Asserts that the target's length is `0`. For arrays and strings, it checks\n * the `length` property. For objects, it gets the count of\n * enumerable keys.\n *\n * expect([]).to.be.empty;\n * expect('').to.be.empty;\n * expect({}).to.be.empty;\n *\n * @name empty\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('empty', function () {\n var obj = flag(this, 'object')\n , expected = obj;\n\n if (Array.isArray(obj) || 'string' === typeof object) {\n expected = obj.length;\n } else if (typeof obj === 'object') {\n expected = Object.keys(obj).length;\n }\n\n this.assert(\n !expected\n , 'expected #{this} to be empty'\n , 'expected #{this} not to be empty'\n );\n });\n\n /**\n * ### .arguments\n *\n * Asserts that the target is an arguments object.\n *\n * function test () {\n * expect(arguments).to.be.arguments;\n * }\n *\n * @name arguments\n * @alias Arguments\n * @namespace BDD\n * @api public\n */\n\n function checkArguments () {\n var obj = flag(this, 'object')\n , type = Object.prototype.toString.call(obj);\n this.assert(\n '[object Arguments]' === type\n , 'expected #{this} to be arguments but got ' + type\n , 'expected #{this} to not be arguments'\n );\n }\n\n Assertion.addProperty('arguments', checkArguments);\n Assertion.addProperty('Arguments', checkArguments);\n\n /**\n * ### .equal(value)\n *\n * Asserts that the target is strictly equal (`===`) to `value`.\n * Alternately, if the `deep` flag is set, asserts that\n * the target is deeply equal to `value`.\n *\n * expect('hello').to.equal('hello');\n * expect(42).to.equal(42);\n * expect(1).to.not.equal(true);\n * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n *\n * @name equal\n * @alias equals\n * @alias eq\n * @alias deep.equal\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEqual (val, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'deep')) {\n return this.eql(val);\n } else {\n this.assert(\n val === obj\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{exp}'\n , val\n , this._obj\n , true\n );\n }\n }\n\n Assertion.addMethod('equal', assertEqual);\n Assertion.addMethod('equals', assertEqual);\n Assertion.addMethod('eq', assertEqual);\n\n /**\n * ### .eql(value)\n *\n * Asserts that the target is deeply equal to `value`.\n *\n * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n *\n * @name eql\n * @alias eqls\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEql(obj, msg) {\n if (msg) flag(this, 'message', msg);\n this.assert(\n _.eql(obj, flag(this, 'object'))\n , 'expected #{this} to deeply equal #{exp}'\n , 'expected #{this} to not deeply equal #{exp}'\n , obj\n , this._obj\n , true\n );\n }\n\n Assertion.addMethod('eql', assertEql);\n Assertion.addMethod('eqls', assertEql);\n\n /**\n * ### .above(value)\n *\n * Asserts that the target is greater than `value`.\n *\n * expect(10).to.be.above(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n *\n * @name above\n * @alias gt\n * @alias greaterThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertAbove (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len > n\n , 'expected #{this} to have a length above #{exp} but got #{act}'\n , 'expected #{this} to not have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj > n\n , 'expected #{this} to be above ' + n\n , 'expected #{this} to be at most ' + n\n );\n }\n }\n\n Assertion.addMethod('above', assertAbove);\n Assertion.addMethod('gt', assertAbove);\n Assertion.addMethod('greaterThan', assertAbove);\n\n /**\n * ### .least(value)\n *\n * Asserts that the target is greater than or equal to `value`.\n *\n * expect(10).to.be.at.least(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.least(2);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n *\n * @name least\n * @alias gte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLeast (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= n\n , 'expected #{this} to have a length at least #{exp} but got #{act}'\n , 'expected #{this} to have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj >= n\n , 'expected #{this} to be at least ' + n\n , 'expected #{this} to be below ' + n\n );\n }\n }\n\n Assertion.addMethod('least', assertLeast);\n Assertion.addMethod('gte', assertLeast);\n\n /**\n * ### .below(value)\n *\n * Asserts that the target is less than `value`.\n *\n * expect(5).to.be.below(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n *\n * @name below\n * @alias lt\n * @alias lessThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertBelow (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len < n\n , 'expected #{this} to have a length below #{exp} but got #{act}'\n , 'expected #{this} to not have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj < n\n , 'expected #{this} to be below ' + n\n , 'expected #{this} to be at least ' + n\n );\n }\n }\n\n Assertion.addMethod('below', assertBelow);\n Assertion.addMethod('lt', assertBelow);\n Assertion.addMethod('lessThan', assertBelow);\n\n /**\n * ### .most(value)\n *\n * Asserts that the target is less than or equal to `value`.\n *\n * expect(5).to.be.at.most(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.most(4);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n *\n * @name most\n * @alias lte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertMost (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len <= n\n , 'expected #{this} to have a length at most #{exp} but got #{act}'\n , 'expected #{this} to have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj <= n\n , 'expected #{this} to be at most ' + n\n , 'expected #{this} to be above ' + n\n );\n }\n }\n\n Assertion.addMethod('most', assertMost);\n Assertion.addMethod('lte', assertMost);\n\n /**\n * ### .within(start, finish)\n *\n * Asserts that the target is within a range.\n *\n * expect(7).to.be.within(5,10);\n *\n * Can also be used in conjunction with `length` to\n * assert a length range. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * @name within\n * @param {Number} start lowerbound inclusive\n * @param {Number} finish upperbound inclusive\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('within', function (start, finish, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , range = start + '..' + finish;\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= start && len <= finish\n , 'expected #{this} to have a length within ' + range\n , 'expected #{this} to not have a length within ' + range\n );\n } else {\n this.assert(\n obj >= start && obj <= finish\n , 'expected #{this} to be within ' + range\n , 'expected #{this} to not be within ' + range\n );\n }\n });\n\n /**\n * ### .instanceof(constructor)\n *\n * Asserts that the target is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , Chai = new Tea('chai');\n *\n * expect(Chai).to.be.an.instanceof(Tea);\n * expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n *\n * @name instanceof\n * @param {Constructor} constructor\n * @param {String} message _optional_\n * @alias instanceOf\n * @namespace BDD\n * @api public\n */\n\n function assertInstanceOf (constructor, msg) {\n if (msg) flag(this, 'message', msg);\n var name = _.getName(constructor);\n this.assert(\n flag(this, 'object') instanceof constructor\n , 'expected #{this} to be an instance of ' + name\n , 'expected #{this} to not be an instance of ' + name\n );\n };\n\n Assertion.addMethod('instanceof', assertInstanceOf);\n Assertion.addMethod('instanceOf', assertInstanceOf);\n\n /**\n * ### .property(name, [value])\n *\n * Asserts that the target has a property `name`, optionally asserting that\n * the value of that property is strictly equal to `value`.\n * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n * references into objects and arrays.\n *\n * // simple referencing\n * var obj = { foo: 'bar' };\n * expect(obj).to.have.property('foo');\n * expect(obj).to.have.property('foo', 'bar');\n *\n * // deep referencing\n * var deepObj = {\n * green: { tea: 'matcha' }\n * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n * };\n *\n * expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n *\n * You can also use an array as the starting point of a `deep.property`\n * assertion, or traverse nested arrays.\n *\n * var arr = [\n * [ 'chai', 'matcha', 'konacha' ]\n * , [ { tea: 'chai' }\n * , { tea: 'matcha' }\n * , { tea: 'konacha' } ]\n * ];\n *\n * expect(arr).to.have.deep.property('[0][1]', 'matcha');\n * expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n *\n * Furthermore, `property` changes the subject of the assertion\n * to be the value of that property from the original object. This\n * permits for further chainable assertions on that property.\n *\n * expect(obj).to.have.property('foo')\n * .that.is.a('string');\n * expect(deepObj).to.have.property('green')\n * .that.is.an('object')\n * .that.deep.equals({ tea: 'matcha' });\n * expect(deepObj).to.have.property('teas')\n * .that.is.an('array')\n * .with.deep.property('[2]')\n * .that.deep.equals({ tea: 'konacha' });\n *\n * Note that dots and bracket in `name` must be backslash-escaped when\n * the `deep` flag is set, while they must NOT be escaped when the `deep`\n * flag is not set.\n *\n * // simple referencing\n * var css = { '.link[target]': 42 };\n * expect(css).to.have.property('.link[target]', 42);\n *\n * // deep referencing\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name property\n * @alias deep.property\n * @param {String} name\n * @param {Mixed} value (optional)\n * @param {String} message _optional_\n * @returns value of property for chaining\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('property', function (name, val, msg) {\n if (msg) flag(this, 'message', msg);\n\n var isDeep = !!flag(this, 'deep')\n , descriptor = isDeep ? 'deep property ' : 'property '\n , negate = flag(this, 'negate')\n , obj = flag(this, 'object')\n , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n , hasProperty = isDeep\n ? pathInfo.exists\n : _.hasProperty(name, obj)\n , value = isDeep\n ? pathInfo.value\n : obj[name];\n\n if (negate && arguments.length > 1) {\n if (undefined === value) {\n msg = (msg != null) ? msg + ': ' : '';\n throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n }\n } else {\n this.assert(\n hasProperty\n , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n }\n\n if (arguments.length > 1) {\n this.assert(\n val === value\n , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n , val\n , value\n );\n }\n\n flag(this, 'object', value);\n });\n\n\n /**\n * ### .ownProperty(name)\n *\n * Asserts that the target has an own property `name`.\n *\n * expect('test').to.have.ownProperty('length');\n *\n * @name ownProperty\n * @alias haveOwnProperty\n * @param {String} name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnProperty (name, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n obj.hasOwnProperty(name)\n , 'expected #{this} to have own property ' + _.inspect(name)\n , 'expected #{this} to not have own property ' + _.inspect(name)\n );\n }\n\n Assertion.addMethod('ownProperty', assertOwnProperty);\n Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n /**\n * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n *\n * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n *\n * expect('test').to.have.ownPropertyDescriptor('length');\n * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n * expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n *\n * @name ownPropertyDescriptor\n * @alias haveOwnPropertyDescriptor\n * @param {String} name\n * @param {Object} descriptor _optional_\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnPropertyDescriptor (name, descriptor, msg) {\n if (typeof descriptor === 'string') {\n msg = descriptor;\n descriptor = null;\n }\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n if (actualDescriptor && descriptor) {\n this.assert(\n _.eql(descriptor, actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n , descriptor\n , actualDescriptor\n , true\n );\n } else {\n this.assert(\n actualDescriptor\n , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n );\n }\n flag(this, 'object', actualDescriptor);\n }\n\n Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n /**\n * ### .length\n *\n * Sets the `doLength` flag later used as a chain precursor to a value\n * comparison for the `length` property.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * *Deprecation notice:* Using `length` as an assertion will be deprecated\n * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n * asserting for `length` property value using `length(value)` should be\n * switched to use `lengthOf(value)` instead.\n *\n * @name length\n * @namespace BDD\n * @api public\n */\n\n /**\n * ### .lengthOf(value[, message])\n *\n * Asserts that the target's `length` property has\n * the expected value.\n *\n * expect([ 1, 2, 3]).to.have.lengthOf(3);\n * expect('foobar').to.have.lengthOf(6);\n *\n * @name lengthOf\n * @param {Number} length\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLengthChain () {\n flag(this, 'doLength', true);\n }\n\n function assertLength (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n\n this.assert(\n len == n\n , 'expected #{this} to have a length of #{exp} but got #{act}'\n , 'expected #{this} to not have a length of #{act}'\n , n\n , len\n );\n }\n\n Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n Assertion.addMethod('lengthOf', assertLength);\n\n /**\n * ### .match(regexp)\n *\n * Asserts that the target matches a regular expression.\n *\n * expect('foobar').to.match(/^foo/);\n *\n * @name match\n * @alias matches\n * @param {RegExp} RegularExpression\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n function assertMatch(re, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n re.exec(obj)\n , 'expected #{this} to match ' + re\n , 'expected #{this} not to match ' + re\n );\n }\n\n Assertion.addMethod('match', assertMatch);\n Assertion.addMethod('matches', assertMatch);\n\n /**\n * ### .string(string)\n *\n * Asserts that the string target contains another string.\n *\n * expect('foobar').to.have.string('bar');\n *\n * @name string\n * @param {String} string\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('string', function (str, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('string');\n\n this.assert(\n ~obj.indexOf(str)\n , 'expected #{this} to contain ' + _.inspect(str)\n , 'expected #{this} to not contain ' + _.inspect(str)\n );\n });\n\n\n /**\n * ### .keys(key1, [key2], [...])\n *\n * Asserts that the target contains any or all of the passed-in keys.\n * Use in combination with `any`, `all`, `contains`, or `have` will affect\n * what will pass.\n *\n * When used in conjunction with `any`, at least one key that is passed\n * in must exist in the target object. This is regardless whether or not\n * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n * should be used in the assertion. If neither are used, the assertion is\n * defaulted to `all`.\n *\n * When both `all` and `contain` are used, the target object must have at\n * least all of the passed-in keys but may have more keys not listed.\n *\n * When both `all` and `have` are used, the target object must both contain\n * all of the passed-in keys AND the number of keys in the target object must\n * match the number of keys passed in (in other words, a target object must\n * have all and only all of the passed-in keys).\n *\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n *\n *\n * @name keys\n * @alias key\n * @param {...String|Array|Object} keys\n * @namespace BDD\n * @api public\n */\n\n function assertKeys (keys) {\n var obj = flag(this, 'object')\n , str\n , ok = true\n , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n switch (_.type(keys)) {\n case \"array\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n break;\n case \"object\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n keys = Object.keys(keys);\n break;\n default:\n keys = Array.prototype.slice.call(arguments);\n }\n\n if (!keys.length) throw new Error('keys required');\n\n var actual = Object.keys(obj)\n , expected = keys\n , len = keys.length\n , any = flag(this, 'any')\n , all = flag(this, 'all');\n\n if (!any && !all) {\n all = true;\n }\n\n // Has any\n if (any) {\n var intersection = expected.filter(function(key) {\n return ~actual.indexOf(key);\n });\n ok = intersection.length > 0;\n }\n\n // Has all\n if (all) {\n ok = keys.every(function(key){\n return ~actual.indexOf(key);\n });\n if (!flag(this, 'negate') && !flag(this, 'contains')) {\n ok = ok && keys.length == actual.length;\n }\n }\n\n // Key string\n if (len > 1) {\n keys = keys.map(function(key){\n return _.inspect(key);\n });\n var last = keys.pop();\n if (all) {\n str = keys.join(', ') + ', and ' + last;\n }\n if (any) {\n str = keys.join(', ') + ', or ' + last;\n }\n } else {\n str = _.inspect(keys[0]);\n }\n\n // Form\n str = (len > 1 ? 'keys ' : 'key ') + str;\n\n // Have / include\n str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n // Assertion\n this.assert(\n ok\n , 'expected #{this} to ' + str\n , 'expected #{this} to not ' + str\n , expected.slice(0).sort()\n , actual.sort()\n , true\n );\n }\n\n Assertion.addMethod('keys', assertKeys);\n Assertion.addMethod('key', assertKeys);\n\n /**\n * ### .throw(constructor)\n *\n * Asserts that the function target will throw a specific error, or specific type of error\n * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n * for the error's message.\n *\n * var err = new ReferenceError('This is a bad function.');\n * var fn = function () { throw err; }\n * expect(fn).to.throw(ReferenceError);\n * expect(fn).to.throw(Error);\n * expect(fn).to.throw(/bad function/);\n * expect(fn).to.not.throw('good function');\n * expect(fn).to.throw(ReferenceError, /bad function/);\n * expect(fn).to.throw(err);\n *\n * Please note that when a throw expectation is negated, it will check each\n * parameter independently, starting with error constructor type. The appropriate way\n * to check for the existence of a type of error but for a message that does not match\n * is to use `and`.\n *\n * expect(fn).to.throw(ReferenceError)\n * .and.not.throw(/good function/);\n *\n * @name throw\n * @alias throws\n * @alias Throw\n * @param {ErrorConstructor} constructor\n * @param {String|RegExp} expected error message\n * @param {String} message _optional_\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @returns error for chaining (null if no error)\n * @namespace BDD\n * @api public\n */\n\n function assertThrows (constructor, errMsg, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('function');\n\n var thrown = false\n , desiredError = null\n , name = null\n , thrownError = null;\n\n if (arguments.length === 0) {\n errMsg = null;\n constructor = null;\n } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n errMsg = constructor;\n constructor = null;\n } else if (constructor && constructor instanceof Error) {\n desiredError = constructor;\n constructor = null;\n errMsg = null;\n } else if (typeof constructor === 'function') {\n name = constructor.prototype.name;\n if (!name || (name === 'Error' && constructor !== Error)) {\n name = constructor.name || (new constructor()).name;\n }\n } else {\n constructor = null;\n }\n\n try {\n obj();\n } catch (err) {\n // first, check desired error\n if (desiredError) {\n this.assert(\n err === desiredError\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp}'\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (err instanceof Error ? err.toString() : err)\n );\n\n flag(this, 'object', err);\n return this;\n }\n\n // next, check constructor\n if (constructor) {\n this.assert(\n err instanceof constructor\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n , name\n , (err instanceof Error ? err.toString() : err)\n );\n\n if (!errMsg) {\n flag(this, 'object', err);\n return this;\n }\n }\n\n // next, check message\n var message = 'error' === _.type(err) && \"message\" in err\n ? err.message\n : '' + err;\n\n if ((message != null) && errMsg && errMsg instanceof RegExp) {\n this.assert(\n errMsg.exec(message)\n , 'expected #{this} to throw error matching #{exp} but got #{act}'\n , 'expected #{this} to throw error not matching #{exp}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n this.assert(\n ~message.indexOf(errMsg)\n , 'expected #{this} to throw error including #{exp} but got #{act}'\n , 'expected #{this} to throw error not including #{act}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else {\n thrown = true;\n thrownError = err;\n }\n }\n\n var actuallyGot = ''\n , expectedThrown = name !== null\n ? name\n : desiredError\n ? '#{exp}' //_.inspect(desiredError)\n : 'an error';\n\n if (thrown) {\n actuallyGot = ' but #{act} was thrown'\n }\n\n this.assert(\n thrown === true\n , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n );\n\n flag(this, 'object', thrownError);\n };\n\n Assertion.addMethod('throw', assertThrows);\n Assertion.addMethod('throws', assertThrows);\n Assertion.addMethod('Throw', assertThrows);\n\n /**\n * ### .respondTo(method)\n *\n * Asserts that the object or class target will respond to a method.\n *\n * Klass.prototype.bar = function(){};\n * expect(Klass).to.respondTo('bar');\n * expect(obj).to.respondTo('bar');\n *\n * To check if a constructor will respond to a static function,\n * set the `itself` flag.\n *\n * Klass.baz = function(){};\n * expect(Klass).itself.to.respondTo('baz');\n *\n * @name respondTo\n * @alias respondsTo\n * @param {String} method\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function respondTo (method, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , itself = flag(this, 'itself')\n , context = ('function' === _.type(obj) && !itself)\n ? obj.prototype[method]\n : obj[method];\n\n this.assert(\n 'function' === typeof context\n , 'expected #{this} to respond to ' + _.inspect(method)\n , 'expected #{this} to not respond to ' + _.inspect(method)\n );\n }\n\n Assertion.addMethod('respondTo', respondTo);\n Assertion.addMethod('respondsTo', respondTo);\n\n /**\n * ### .itself\n *\n * Sets the `itself` flag, later used by the `respondTo` assertion.\n *\n * function Foo() {}\n * Foo.bar = function() {}\n * Foo.prototype.baz = function() {}\n *\n * expect(Foo).itself.to.respondTo('bar');\n * expect(Foo).itself.not.to.respondTo('baz');\n *\n * @name itself\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('itself', function () {\n flag(this, 'itself', true);\n });\n\n /**\n * ### .satisfy(method)\n *\n * Asserts that the target passes a given truth test.\n *\n * expect(1).to.satisfy(function(num) { return num > 0; });\n *\n * @name satisfy\n * @alias satisfies\n * @param {Function} matcher\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function satisfy (matcher, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var result = matcher(obj);\n this.assert(\n result\n , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n , this.negate ? false : true\n , result\n );\n }\n\n Assertion.addMethod('satisfy', satisfy);\n Assertion.addMethod('satisfies', satisfy);\n\n /**\n * ### .closeTo(expected, delta)\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * expect(1.5).to.be.closeTo(1, 0.5);\n *\n * @name closeTo\n * @alias approximately\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function closeTo(expected, delta, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj, msg).is.a('number');\n if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n throw new Error('the arguments to closeTo or approximately must be numbers');\n }\n\n this.assert(\n Math.abs(obj - expected) <= delta\n , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n );\n }\n\n Assertion.addMethod('closeTo', closeTo);\n Assertion.addMethod('approximately', closeTo);\n\n function isSubsetOf(subset, superset, cmp) {\n return subset.every(function(elem) {\n if (!cmp) return superset.indexOf(elem) !== -1;\n\n return superset.some(function(elem2) {\n return cmp(elem, elem2);\n });\n })\n }\n\n /**\n * ### .members(set)\n *\n * Asserts that the target is a superset of `set`,\n * or that the target and `set` have the same strictly-equal (===) members.\n * Alternately, if the `deep` flag is set, set members are compared for deep\n * equality.\n *\n * expect([1, 2, 3]).to.include.members([3, 2]);\n * expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n *\n * expect([4, 2]).to.have.members([2, 4]);\n * expect([5, 2]).to.not.have.members([5, 2, 1]);\n *\n * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n *\n * @name members\n * @param {Array} set\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('members', function (subset, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj).to.be.an('array');\n new Assertion(subset).to.be.an('array');\n\n var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n if (flag(this, 'contains')) {\n return this.assert(\n isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to be a superset of #{act}'\n , 'expected #{this} to not be a superset of #{act}'\n , obj\n , subset\n );\n }\n\n this.assert(\n isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to have the same members as #{act}'\n , 'expected #{this} to not have the same members as #{act}'\n , obj\n , subset\n );\n });\n\n /**\n * ### .oneOf(list)\n *\n * Assert that a value appears somewhere in the top level of array `list`.\n *\n * expect('a').to.be.oneOf(['a', 'b', 'c']);\n * expect(9).to.not.be.oneOf(['z']);\n * expect([3]).to.not.be.oneOf([1, 2, [3]]);\n *\n * var three = [3];\n * // for object-types, contents are not compared\n * expect(three).to.not.be.oneOf([1, 2, [3]]);\n * // comparing references works\n * expect(three).to.be.oneOf([1, 2, three]);\n *\n * @name oneOf\n * @param {Array<*>} list\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function oneOf (list, msg) {\n if (msg) flag(this, 'message', msg);\n var expected = flag(this, 'object');\n new Assertion(list).to.be.an('array');\n\n this.assert(\n list.indexOf(expected) > -1\n , 'expected #{this} to be one of #{exp}'\n , 'expected #{this} to not be one of #{exp}'\n , list\n , expected\n );\n }\n\n Assertion.addMethod('oneOf', oneOf);\n\n\n /**\n * ### .change(function)\n *\n * Asserts that a function changes an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val += 3 };\n * var noChangeFn = function() { return 'foo' + 'bar'; }\n * expect(fn).to.change(obj, 'val');\n * expect(noChangeFn).to.not.change(obj, 'val')\n *\n * @name change\n * @alias changes\n * @alias Change\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertChanges (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n initial !== object[prop]\n , 'expected .' + prop + ' to change'\n , 'expected .' + prop + ' to not change'\n );\n }\n\n Assertion.addChainableMethod('change', assertChanges);\n Assertion.addChainableMethod('changes', assertChanges);\n\n /**\n * ### .increase(function)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * expect(fn).to.increase(obj, 'val');\n *\n * @name increase\n * @alias increases\n * @alias Increase\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertIncreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial > 0\n , 'expected .' + prop + ' to increase'\n , 'expected .' + prop + ' to not increase'\n );\n }\n\n Assertion.addChainableMethod('increase', assertIncreases);\n Assertion.addChainableMethod('increases', assertIncreases);\n\n /**\n * ### .decrease(function)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * expect(fn).to.decrease(obj, 'val');\n *\n * @name decrease\n * @alias decreases\n * @alias Decrease\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertDecreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial < 0\n , 'expected .' + prop + ' to decrease'\n , 'expected .' + prop + ' to not decrease'\n );\n }\n\n Assertion.addChainableMethod('decrease', assertDecreases);\n Assertion.addChainableMethod('decreases', assertDecreases);\n\n /**\n * ### .extensible\n *\n * Asserts that the target is extensible (can have new properties added to\n * it).\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect({}).to.be.extensible;\n * expect(nonExtensibleObject).to.not.be.extensible;\n * expect(sealedObject).to.not.be.extensible;\n * expect(frozenObject).to.not.be.extensible;\n *\n * @name extensible\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('extensible', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isExtensible;\n\n try {\n isExtensible = Object.isExtensible(obj);\n } catch (err) {\n if (err instanceof TypeError) isExtensible = false;\n else throw err;\n }\n\n this.assert(\n isExtensible\n , 'expected #{this} to be extensible'\n , 'expected #{this} to not be extensible'\n );\n });\n\n /**\n * ### .sealed\n *\n * Asserts that the target is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect(sealedObject).to.be.sealed;\n * expect(frozenObject).to.be.sealed;\n * expect({}).to.not.be.sealed;\n *\n * @name sealed\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('sealed', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isSealed;\n\n try {\n isSealed = Object.isSealed(obj);\n } catch (err) {\n if (err instanceof TypeError) isSealed = true;\n else throw err;\n }\n\n this.assert(\n isSealed\n , 'expected #{this} to be sealed'\n , 'expected #{this} to not be sealed'\n );\n });\n\n /**\n * ### .frozen\n *\n * Asserts that the target is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n *\n * expect(frozenObject).to.be.frozen;\n * expect({}).to.not.be.frozen;\n *\n * @name frozen\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('frozen', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isFrozen;\n\n try {\n isFrozen = Object.isFrozen(obj);\n } catch (err) {\n if (err instanceof TypeError) isFrozen = true;\n else throw err;\n }\n\n this.assert(\n isFrozen\n , 'expected #{this} to be frozen'\n , 'expected #{this} to not be frozen'\n );\n });\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n /*!\n * Chai dependencies.\n */\n\n var Assertion = chai.Assertion\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n /**\n * ### assert(expression, message)\n *\n * Write your own test expressions.\n *\n * assert('foo' !== 'bar', 'foo is not bar');\n * assert(Array.isArray([]), 'empty arrays are arrays');\n *\n * @param {Mixed} expression to test for truthiness\n * @param {String} message to display on error\n * @name assert\n * @namespace Assert\n * @api public\n */\n\n var assert = chai.assert = function (express, errmsg) {\n var test = new Assertion(null, null, chai.assert);\n test.assert(\n express\n , errmsg\n , '[ negation message unavailable ]'\n );\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure. Node.js `assert` module-compatible.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Assert\n * @api public\n */\n\n assert.fail = function (actual, expected, message, operator) {\n message = message || 'assert.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, assert.fail);\n };\n\n /**\n * ### .isOk(object, [message])\n *\n * Asserts that `object` is truthy.\n *\n * assert.isOk('everything', 'everything is ok');\n * assert.isOk(false, 'this will fail');\n *\n * @name isOk\n * @alias ok\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isOk = function (val, msg) {\n new Assertion(val, msg).is.ok;\n };\n\n /**\n * ### .isNotOk(object, [message])\n *\n * Asserts that `object` is falsy.\n *\n * assert.isNotOk('everything', 'this will fail');\n * assert.isNotOk(false, 'this will pass');\n *\n * @name isNotOk\n * @alias notOk\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotOk = function (val, msg) {\n new Assertion(val, msg).is.not.ok;\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * assert.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.equal = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.equal);\n\n test.assert(\n exp == flag(test, 'object')\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .notEqual(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * assert.notEqual(3, 4, 'these numbers are not equal');\n *\n * @name notEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notEqual = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.notEqual);\n\n test.assert(\n exp != flag(test, 'object')\n , 'expected #{this} to not equal #{exp}'\n , 'expected #{this} to equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .strictEqual(actual, expected, [message])\n *\n * Asserts strict equality (`===`) of `actual` and `expected`.\n *\n * assert.strictEqual(true, true, 'these booleans are strictly equal');\n *\n * @name strictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.strictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.equal(exp);\n };\n\n /**\n * ### .notStrictEqual(actual, expected, [message])\n *\n * Asserts strict inequality (`!==`) of `actual` and `expected`.\n *\n * assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n *\n * @name notStrictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notStrictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.equal(exp);\n };\n\n /**\n * ### .deepEqual(actual, expected, [message])\n *\n * Asserts that `actual` is deeply equal to `expected`.\n *\n * assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n *\n * @name deepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.eql(exp);\n };\n\n /**\n * ### .notDeepEqual(actual, expected, [message])\n *\n * Assert that `actual` is not deeply equal to `expected`.\n *\n * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n *\n * @name notDeepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.eql(exp);\n };\n\n /**\n * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n *\n * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n *\n * assert.isAbove(5, 2, '5 is strictly greater than 2');\n *\n * @name isAbove\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAbove\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAbove = function (val, abv, msg) {\n new Assertion(val, msg).to.be.above(abv);\n };\n\n /**\n * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n *\n * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n *\n * assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n * assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n *\n * @name isAtLeast\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtLeast\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtLeast = function (val, atlst, msg) {\n new Assertion(val, msg).to.be.least(atlst);\n };\n\n /**\n * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n *\n * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n *\n * assert.isBelow(3, 6, '3 is strictly less than 6');\n *\n * @name isBelow\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeBelow\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBelow = function (val, blw, msg) {\n new Assertion(val, msg).to.be.below(blw);\n };\n\n /**\n * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n *\n * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n *\n * assert.isAtMost(3, 6, '3 is less than or equal to 6');\n * assert.isAtMost(4, 4, '4 is less than or equal to 4');\n *\n * @name isAtMost\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtMost\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtMost = function (val, atmst, msg) {\n new Assertion(val, msg).to.be.most(atmst);\n };\n\n /**\n * ### .isTrue(value, [message])\n *\n * Asserts that `value` is true.\n *\n * var teaServed = true;\n * assert.isTrue(teaServed, 'the tea has been served');\n *\n * @name isTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isTrue = function (val, msg) {\n new Assertion(val, msg).is['true'];\n };\n\n /**\n * ### .isNotTrue(value, [message])\n *\n * Asserts that `value` is not true.\n *\n * var tea = 'tasty chai';\n * assert.isNotTrue(tea, 'great, time for tea!');\n *\n * @name isNotTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotTrue = function (val, msg) {\n new Assertion(val, msg).to.not.equal(true);\n };\n\n /**\n * ### .isFalse(value, [message])\n *\n * Asserts that `value` is false.\n *\n * var teaServed = false;\n * assert.isFalse(teaServed, 'no tea yet? hmm...');\n *\n * @name isFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFalse = function (val, msg) {\n new Assertion(val, msg).is['false'];\n };\n\n /**\n * ### .isNotFalse(value, [message])\n *\n * Asserts that `value` is not false.\n *\n * var tea = 'tasty chai';\n * assert.isNotFalse(tea, 'great, time for tea!');\n *\n * @name isNotFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFalse = function (val, msg) {\n new Assertion(val, msg).to.not.equal(false);\n };\n\n /**\n * ### .isNull(value, [message])\n *\n * Asserts that `value` is null.\n *\n * assert.isNull(err, 'there was no error');\n *\n * @name isNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNull = function (val, msg) {\n new Assertion(val, msg).to.equal(null);\n };\n\n /**\n * ### .isNotNull(value, [message])\n *\n * Asserts that `value` is not null.\n *\n * var tea = 'tasty chai';\n * assert.isNotNull(tea, 'great, time for tea!');\n *\n * @name isNotNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNull = function (val, msg) {\n new Assertion(val, msg).to.not.equal(null);\n };\n\n /**\n * ### .isNaN\n * Asserts that value is NaN\n *\n * assert.isNaN('foo', 'foo is NaN');\n *\n * @name isNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNaN = function (val, msg) {\n new Assertion(val, msg).to.be.NaN;\n };\n\n /**\n * ### .isNotNaN\n * Asserts that value is not NaN\n *\n * assert.isNotNaN(4, '4 is not NaN');\n *\n * @name isNotNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n assert.isNotNaN = function (val, msg) {\n new Assertion(val, msg).not.to.be.NaN;\n };\n\n /**\n * ### .isUndefined(value, [message])\n *\n * Asserts that `value` is `undefined`.\n *\n * var tea;\n * assert.isUndefined(tea, 'no tea defined');\n *\n * @name isUndefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isUndefined = function (val, msg) {\n new Assertion(val, msg).to.equal(undefined);\n };\n\n /**\n * ### .isDefined(value, [message])\n *\n * Asserts that `value` is not `undefined`.\n *\n * var tea = 'cup of chai';\n * assert.isDefined(tea, 'tea has been defined');\n *\n * @name isDefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isDefined = function (val, msg) {\n new Assertion(val, msg).to.not.equal(undefined);\n };\n\n /**\n * ### .isFunction(value, [message])\n *\n * Asserts that `value` is a function.\n *\n * function serveTea() { return 'cup of tea'; };\n * assert.isFunction(serveTea, 'great, we can have tea now');\n *\n * @name isFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFunction = function (val, msg) {\n new Assertion(val, msg).to.be.a('function');\n };\n\n /**\n * ### .isNotFunction(value, [message])\n *\n * Asserts that `value` is _not_ a function.\n *\n * var serveTea = [ 'heat', 'pour', 'sip' ];\n * assert.isNotFunction(serveTea, 'great, we have listed the steps');\n *\n * @name isNotFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFunction = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('function');\n };\n\n /**\n * ### .isObject(value, [message])\n *\n * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n * _The assertion does not match subclassed objects._\n *\n * var selection = { name: 'Chai', serve: 'with spices' };\n * assert.isObject(selection, 'tea selection is an object');\n *\n * @name isObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isObject = function (val, msg) {\n new Assertion(val, msg).to.be.a('object');\n };\n\n /**\n * ### .isNotObject(value, [message])\n *\n * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n *\n * var selection = 'chai'\n * assert.isNotObject(selection, 'tea selection is not an object');\n * assert.isNotObject(null, 'null is not an object');\n *\n * @name isNotObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotObject = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('object');\n };\n\n /**\n * ### .isArray(value, [message])\n *\n * Asserts that `value` is an array.\n *\n * var menu = [ 'green', 'chai', 'oolong' ];\n * assert.isArray(menu, 'what kind of tea do we want?');\n *\n * @name isArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isArray = function (val, msg) {\n new Assertion(val, msg).to.be.an('array');\n };\n\n /**\n * ### .isNotArray(value, [message])\n *\n * Asserts that `value` is _not_ an array.\n *\n * var menu = 'green|chai|oolong';\n * assert.isNotArray(menu, 'what kind of tea do we want?');\n *\n * @name isNotArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotArray = function (val, msg) {\n new Assertion(val, msg).to.not.be.an('array');\n };\n\n /**\n * ### .isString(value, [message])\n *\n * Asserts that `value` is a string.\n *\n * var teaOrder = 'chai';\n * assert.isString(teaOrder, 'order placed');\n *\n * @name isString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isString = function (val, msg) {\n new Assertion(val, msg).to.be.a('string');\n };\n\n /**\n * ### .isNotString(value, [message])\n *\n * Asserts that `value` is _not_ a string.\n *\n * var teaOrder = 4;\n * assert.isNotString(teaOrder, 'order placed');\n *\n * @name isNotString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotString = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('string');\n };\n\n /**\n * ### .isNumber(value, [message])\n *\n * Asserts that `value` is a number.\n *\n * var cups = 2;\n * assert.isNumber(cups, 'how many cups');\n *\n * @name isNumber\n * @param {Number} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNumber = function (val, msg) {\n new Assertion(val, msg).to.be.a('number');\n };\n\n /**\n * ### .isNotNumber(value, [message])\n *\n * Asserts that `value` is _not_ a number.\n *\n * var cups = '2 cups please';\n * assert.isNotNumber(cups, 'how many cups');\n *\n * @name isNotNumber\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNumber = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('number');\n };\n\n /**\n * ### .isBoolean(value, [message])\n *\n * Asserts that `value` is a boolean.\n *\n * var teaReady = true\n * , teaServed = false;\n *\n * assert.isBoolean(teaReady, 'is the tea ready');\n * assert.isBoolean(teaServed, 'has tea been served');\n *\n * @name isBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBoolean = function (val, msg) {\n new Assertion(val, msg).to.be.a('boolean');\n };\n\n /**\n * ### .isNotBoolean(value, [message])\n *\n * Asserts that `value` is _not_ a boolean.\n *\n * var teaReady = 'yep'\n * , teaServed = 'nope';\n *\n * assert.isNotBoolean(teaReady, 'is the tea ready');\n * assert.isNotBoolean(teaServed, 'has tea been served');\n *\n * @name isNotBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotBoolean = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('boolean');\n };\n\n /**\n * ### .typeOf(value, name, [message])\n *\n * Asserts that `value`'s type is `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n * assert.typeOf('tea', 'string', 'we have a string');\n * assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n * assert.typeOf(null, 'null', 'we have a null');\n * assert.typeOf(undefined, 'undefined', 'we have an undefined');\n *\n * @name typeOf\n * @param {Mixed} value\n * @param {String} name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.typeOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.a(type);\n };\n\n /**\n * ### .notTypeOf(value, name, [message])\n *\n * Asserts that `value`'s type is _not_ `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.notTypeOf('tea', 'number', 'strings are not numbers');\n *\n * @name notTypeOf\n * @param {Mixed} value\n * @param {String} typeof name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notTypeOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.a(type);\n };\n\n /**\n * ### .instanceOf(object, constructor, [message])\n *\n * Asserts that `value` is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new Tea('chai');\n *\n * assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n *\n * @name instanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.instanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.instanceOf(type);\n };\n\n /**\n * ### .notInstanceOf(object, constructor, [message])\n *\n * Asserts `value` is not an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new String('chai');\n *\n * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n *\n * @name notInstanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInstanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.instanceOf(type);\n };\n\n /**\n * ### .include(haystack, needle, [message])\n *\n * Asserts that `haystack` includes `needle`. Works\n * for strings and arrays.\n *\n * assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n * assert.include([ 1, 2, 3 ], 3, 'array contains value');\n *\n * @name include\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.include = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.include).include(inc);\n };\n\n /**\n * ### .notInclude(haystack, needle, [message])\n *\n * Asserts that `haystack` does not include `needle`. Works\n * for strings and arrays.\n *\n * assert.notInclude('foobar', 'baz', 'string not include substring');\n * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n *\n * @name notInclude\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInclude = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.notInclude).not.include(inc);\n };\n\n /**\n * ### .match(value, regexp, [message])\n *\n * Asserts that `value` matches the regular expression `regexp`.\n *\n * assert.match('foobar', /^foo/, 'regexp matches');\n *\n * @name match\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.match = function (exp, re, msg) {\n new Assertion(exp, msg).to.match(re);\n };\n\n /**\n * ### .notMatch(value, regexp, [message])\n *\n * Asserts that `value` does not match the regular expression `regexp`.\n *\n * assert.notMatch('foobar', /^foo/, 'regexp does not match');\n *\n * @name notMatch\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notMatch = function (exp, re, msg) {\n new Assertion(exp, msg).to.not.match(re);\n };\n\n /**\n * ### .property(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`.\n *\n * assert.property({ tea: { green: 'matcha' }}, 'tea');\n *\n * @name property\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.property = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.property(prop);\n };\n\n /**\n * ### .notProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`.\n *\n * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n *\n * @name notProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.property(prop);\n };\n\n /**\n * ### .deepProperty(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`, which can be a\n * string using dot- and bracket-notation for deep reference.\n *\n * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n *\n * @name deepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop);\n };\n\n /**\n * ### .notDeepProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`, which\n * can be a string using dot- and bracket-notation for deep reference.\n *\n * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n *\n * @name notDeepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop);\n };\n\n /**\n * ### .propertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`.\n *\n * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n *\n * @name propertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.property(prop, val);\n };\n\n /**\n * ### .propertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`.\n *\n * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n *\n * @name propertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.property(prop, val);\n };\n\n /**\n * ### .deepPropertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`. `property` can use dot- and bracket-notation for deep\n * reference.\n *\n * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n *\n * @name deepPropertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop, val);\n };\n\n /**\n * ### .deepPropertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`. `property` can use dot- and\n * bracket-notation for deep reference.\n *\n * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n *\n * @name deepPropertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n };\n\n /**\n * ### .lengthOf(object, length, [message])\n *\n * Asserts that `object` has a `length` property with the expected value.\n *\n * assert.lengthOf([1,2,3], 3, 'array has length of 3');\n * assert.lengthOf('foobar', 6, 'string has length of 6');\n *\n * @name lengthOf\n * @param {Mixed} object\n * @param {Number} length\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.lengthOf = function (exp, len, msg) {\n new Assertion(exp, msg).to.have.length(len);\n };\n\n /**\n * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * assert.throws(fn, 'function throws a reference error');\n * assert.throws(fn, /function throws a reference error/);\n * assert.throws(fn, ReferenceError);\n * assert.throws(fn, ReferenceError, 'function throws a reference error');\n * assert.throws(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throws\n * @alias throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.throws = function (fn, errt, errs, msg) {\n if ('string' === typeof errt || errt instanceof RegExp) {\n errs = errt;\n errt = null;\n }\n\n var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n return flag(assertErr, 'object');\n };\n\n /**\n * ### .doesNotThrow(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * assert.doesNotThrow(fn, Error, 'function does not throw');\n *\n * @name doesNotThrow\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotThrow = function (fn, type, msg) {\n if ('string' === typeof type) {\n msg = type;\n type = null;\n }\n\n new Assertion(fn, msg).to.not.Throw(type);\n };\n\n /**\n * ### .operator(val1, operator, val2, [message])\n *\n * Compares two values using `operator`.\n *\n * assert.operator(1, '<', 2, 'everything is ok');\n * assert.operator(1, '>', 2, 'this will fail');\n *\n * @name operator\n * @param {Mixed} val1\n * @param {String} operator\n * @param {Mixed} val2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.operator = function (val, operator, val2, msg) {\n var ok;\n switch(operator) {\n case '==':\n ok = val == val2;\n break;\n case '===':\n ok = val === val2;\n break;\n case '>':\n ok = val > val2;\n break;\n case '>=':\n ok = val >= val2;\n break;\n case '<':\n ok = val < val2;\n break;\n case '<=':\n ok = val <= val2;\n break;\n case '!=':\n ok = val != val2;\n break;\n case '!==':\n ok = val !== val2;\n break;\n default:\n throw new Error('Invalid operator \"' + operator + '\"');\n }\n var test = new Assertion(ok, msg);\n test.assert(\n true === flag(test, 'object')\n , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n };\n\n /**\n * ### .closeTo(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n *\n * @name closeTo\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.closeTo = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.closeTo(exp, delta);\n };\n\n /**\n * ### .approximately(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.approximately(1.5, 1, 0.5, 'numbers are close');\n *\n * @name approximately\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.approximately = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.approximately(exp, delta);\n };\n\n /**\n * ### .sameMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members.\n * Order is not taken into account.\n *\n * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n *\n * @name sameMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.members(set2);\n }\n\n /**\n * ### .sameDeepMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n * Order is not taken into account.\n *\n * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n *\n * @name sameDeepMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameDeepMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.deep.members(set2);\n }\n\n /**\n * ### .includeMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset`.\n * Order is not taken into account.\n *\n * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n *\n * @name includeMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.members(subset);\n }\n\n /**\n * ### .includeDeepMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset` - using deep equality checking.\n * Order is not taken into account.\n * Duplicates are ignored.\n *\n * assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n *\n * @name includeDeepMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeDeepMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.deep.members(subset);\n }\n\n /**\n * ### .oneOf(inList, list, [message])\n *\n * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n *\n * assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n *\n * @name oneOf\n * @param {*} inList\n * @param {Array<*>} list\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.oneOf = function (inList, list, msg) {\n new Assertion(inList, msg).to.be.oneOf(list);\n }\n\n /**\n * ### .changes(function, object, property)\n *\n * Asserts that a function changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 22 };\n * assert.changes(fn, obj, 'val');\n *\n * @name changes\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.changes = function (fn, obj, prop) {\n new Assertion(fn).to.change(obj, prop);\n }\n\n /**\n * ### .doesNotChange(function, object, property)\n *\n * Asserts that a function does not changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { console.log('foo'); };\n * assert.doesNotChange(fn, obj, 'val');\n *\n * @name doesNotChange\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotChange = function (fn, obj, prop) {\n new Assertion(fn).to.not.change(obj, prop);\n }\n\n /**\n * ### .increases(function, object, property)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 13 };\n * assert.increases(fn, obj, 'val');\n *\n * @name increases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.increases = function (fn, obj, prop) {\n new Assertion(fn).to.increase(obj, prop);\n }\n\n /**\n * ### .doesNotIncrease(function, object, property)\n *\n * Asserts that a function does not increase object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 8 };\n * assert.doesNotIncrease(fn, obj, 'val');\n *\n * @name doesNotIncrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotIncrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.increase(obj, prop);\n }\n\n /**\n * ### .decreases(function, object, property)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * assert.decreases(fn, obj, 'val');\n *\n * @name decreases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.decreases = function (fn, obj, prop) {\n new Assertion(fn).to.decrease(obj, prop);\n }\n\n /**\n * ### .doesNotDecrease(function, object, property)\n *\n * Asserts that a function does not decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * assert.doesNotDecrease(fn, obj, 'val');\n *\n * @name doesNotDecrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotDecrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.decrease(obj, prop);\n }\n\n /*!\n * ### .ifError(object)\n *\n * Asserts if value is not a false value, and throws if it is a true value.\n * This is added to allow for chai to be a drop-in replacement for Node's\n * assert class.\n *\n * var err = new Error('I am a custom error');\n * assert.ifError(err); // Rethrows err!\n *\n * @name ifError\n * @param {Object} object\n * @namespace Assert\n * @api public\n */\n\n assert.ifError = function (val) {\n if (val) {\n throw(val);\n }\n };\n\n /**\n * ### .isExtensible(object)\n *\n * Asserts that `object` is extensible (can have new properties added to it).\n *\n * assert.isExtensible({});\n *\n * @name isExtensible\n * @alias extensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.be.extensible;\n };\n\n /**\n * ### .isNotExtensible(object)\n *\n * Asserts that `object` is _not_ extensible.\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freese({});\n *\n * assert.isNotExtensible(nonExtensibleObject);\n * assert.isNotExtensible(sealedObject);\n * assert.isNotExtensible(frozenObject);\n *\n * @name isNotExtensible\n * @alias notExtensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.extensible;\n };\n\n /**\n * ### .isSealed(object)\n *\n * Asserts that `object` is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.seal({});\n *\n * assert.isSealed(sealedObject);\n * assert.isSealed(frozenObject);\n *\n * @name isSealed\n * @alias sealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isSealed = function (obj, msg) {\n new Assertion(obj, msg).to.be.sealed;\n };\n\n /**\n * ### .isNotSealed(object)\n *\n * Asserts that `object` is _not_ sealed.\n *\n * assert.isNotSealed({});\n *\n * @name isNotSealed\n * @alias notSealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotSealed = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.sealed;\n };\n\n /**\n * ### .isFrozen(object)\n *\n * Asserts that `object` is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n * assert.frozen(frozenObject);\n *\n * @name isFrozen\n * @alias frozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.be.frozen;\n };\n\n /**\n * ### .isNotFrozen(object)\n *\n * Asserts that `object` is _not_ frozen.\n *\n * assert.isNotFrozen({});\n *\n * @name isNotFrozen\n * @alias notFrozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.frozen;\n };\n\n /*!\n * Aliases.\n */\n\n (function alias(name, as){\n assert[as] = assert[name];\n return alias;\n })\n ('isOk', 'ok')\n ('isNotOk', 'notOk')\n ('throws', 'throw')\n ('throws', 'Throw')\n ('isExtensible', 'extensible')\n ('isNotExtensible', 'notExtensible')\n ('isSealed', 'sealed')\n ('isNotSealed', 'notSealed')\n ('isFrozen', 'frozen')\n ('isNotFrozen', 'notFrozen');\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n chai.expect = function (val, message) {\n return new chai.Assertion(val, message);\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Expect\n * @api public\n */\n\n chai.expect.fail = function (actual, expected, message, operator) {\n message = message || 'expect.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, chai.expect.fail);\n };\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n var Assertion = chai.Assertion;\n\n function loadShould () {\n // explicitly define this method as function as to have it's name to include as `ssfi`\n function shouldGetter() {\n if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n return new Assertion(this.valueOf(), null, shouldGetter);\n }\n return new Assertion(this, null, shouldGetter);\n }\n function shouldSetter(value) {\n // See https://github.com/chaijs/chai/issues/86: this makes\n // `whatever.should = someValue` actually set `someValue`, which is\n // especially useful for `global.should = require('chai').should()`.\n //\n // Note that we have to use [[DefineProperty]] instead of [[Put]]\n // since otherwise we would trigger this very setter!\n Object.defineProperty(this, 'should', {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n }\n // modify Object.prototype to have `should`\n Object.defineProperty(Object.prototype, 'should', {\n set: shouldSetter\n , get: shouldGetter\n , configurable: true\n });\n\n var should = {};\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Should\n * @api public\n */\n\n should.fail = function (actual, expected, message, operator) {\n message = message || 'should.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, should.fail);\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * should.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * should.throw(fn, 'function throws a reference error');\n * should.throw(fn, /function throws a reference error/);\n * should.throw(fn, ReferenceError);\n * should.throw(fn, ReferenceError, 'function throws a reference error');\n * should.throw(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.Throw(errt, errs);\n };\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi';\n *\n * should.exist(foo, 'foo exists');\n *\n * @name exist\n * @namespace Should\n * @api public\n */\n\n should.exist = function (val, msg) {\n new Assertion(val, msg).to.exist;\n }\n\n // negation\n should.not = {}\n\n /**\n * ### .not.equal(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * should.not.equal(3, 4, 'these numbers are not equal');\n *\n * @name not.equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.not.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.not.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * should.not.throw(fn, Error, 'function does not throw');\n *\n * @name not.throw\n * @alias not.Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.not.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.not.Throw(errt, errs);\n };\n\n /**\n * ### .not.exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var bar = null;\n *\n * should.not.exist(bar, 'bar does not exist');\n *\n * @name not.exist\n * @namespace Should\n * @api public\n */\n\n should.not.exist = function (val, msg) {\n new Assertion(val, msg).to.not.exist;\n }\n\n should['throw'] = should['Throw'];\n should.not['throw'] = should.not['Throw'];\n\n return should;\n };\n\n chai.should = loadShould;\n chai.Should = loadShould;\n};\n","/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call = Function.prototype.call,\n apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n * expect(fooStr).to.be.foo('bar');\n * expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n if (typeof chainingBehavior !== 'function') {\n chainingBehavior = function () { };\n }\n\n var chainableBehavior = {\n method: method\n , chainingBehavior: chainingBehavior\n };\n\n // save the methods so we can overwrite them later, if we need to.\n if (!ctx.__methods) {\n ctx.__methods = {};\n }\n ctx.__methods[name] = chainableBehavior;\n\n Object.defineProperty(ctx, name,\n { get: function () {\n chainableBehavior.chainingBehavior.call(this);\n\n var assert = function assert() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', assert);\n var result = chainableBehavior.method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n\n // Use `__proto__` if available\n if (hasProtoSupport) {\n // Inherit all properties from the object by replacing the `Function` prototype\n var prototype = assert.__proto__ = Object.create(this);\n // Restore the `call` and `apply` methods from `Function`\n prototype.call = call;\n prototype.apply = apply;\n }\n // Otherwise, redefine all properties (slow!)\n else {\n var asserterNames = Object.getOwnPropertyNames(ctx);\n asserterNames.forEach(function (asserterName) {\n if (!excludeNames.test(asserterName)) {\n var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n Object.defineProperty(assert, asserterName, pd);\n }\n });\n }\n\n transferFlags(this, assert);\n return assert;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n ctx[name] = function () {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', ctx[name]);\n var result = method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n * utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.instanceof(Foo);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n Object.defineProperty(ctx, name,\n { get: function addProperty() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', addProperty);\n\n var result = getter.call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n * utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n var obj = flag(obj, 'object');\n types = types.map(function (t) { return t.toLowerCase(); });\n types.sort();\n\n // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n var str = types.map(function (t, index) {\n var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n return or + art + ' ' + t;\n }).join(', ');\n\n if (!types.some(function (expected) { return type(obj) === expected; })) {\n throw new AssertionError(\n 'object tested must be ' + str + ', but ' + type(obj) + ' given'\n );\n }\n};\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n * utils.flag(this, 'foo', 'bar'); // setter\n * utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n var flags = obj.__flags || (obj.__flags = Object.create(null));\n if (arguments.length === 3) {\n flags[key] = value;\n } else {\n return flags[key];\n }\n};\n","/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n return args.length > 4 ? args[4] : obj._obj;\n};\n","/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n var result = [];\n for (var name in object) {\n result.push(name);\n }\n return result;\n};\n","/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n , getActual = require('./getActual')\n , inspect = require('./inspect')\n , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , val = flag(obj, 'object')\n , expected = args[3]\n , actual = getActual(obj, args)\n , msg = negate ? args[2] : args[1]\n , flagMsg = flag(obj, 'message');\n\n if(typeof msg === \"function\") msg = msg();\n msg = msg || '';\n msg = msg\n .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n","/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n if (func.name) return func.name;\n\n var match = /^\\s?function ([^(]*)\\(/.exec(func);\n return match && match[1] ? match[1] : \"\";\n};\n","/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n var parsed = parsePath(path),\n last = parsed[parsed.length - 1];\n\n var info = {\n parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n name: last.p || last.i,\n value: _getPathValue(parsed, obj)\n };\n info.exists = hasProperty(info.name, info.parent);\n\n return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n * var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n return parts.map(function (value) {\n var re = /^\\[(\\d+)\\]$/\n , mArr = re.exec(value);\n if (mArr) return { i: parseFloat(mArr[1]) };\n else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n * var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n var tmp = obj\n , res;\n\n index = (index === undefined ? parsed.length : index);\n\n for (var i = 0, l = index; i < l; i++) {\n var part = parsed[i];\n if (tmp) {\n if ('undefined' !== typeof part.p)\n tmp = tmp[part.p];\n else if ('undefined' !== typeof part.i)\n tmp = tmp[part.i];\n if (i == (l - 1)) res = tmp;\n } else {\n res = undefined;\n }\n }\n return res;\n}\n","/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer \n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n * var obj = {\n * prop1: {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n * , prop2: {\n * arr: [ { nested: 'Universe' } ]\n * , str: 'Hello again!'\n * }\n * }\n *\n * The following would be the results.\n *\n * getPathValue('prop1.str', obj); // Hello\n * getPathValue('prop1.att[2]', obj); // b\n * getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n var info = getPathInfo(path, obj);\n return info.value;\n};\n","/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n var result = Object.getOwnPropertyNames(object);\n\n function addProperty(property) {\n if (result.indexOf(property) === -1) {\n result.push(property);\n }\n }\n\n var proto = Object.getPrototypeOf(object);\n while (proto !== null) {\n Object.getOwnPropertyNames(proto).forEach(addProperty);\n proto = Object.getPrototypeOf(proto);\n }\n\n return result;\n};\n","/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n * var obj = {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n *\n * The following would be the results.\n *\n * hasProperty('str', obj); // true\n * hasProperty('constructor', obj); // true\n * hasProperty('bar', obj); // false\n *\n * hasProperty('length', obj.str); // true\n * hasProperty(1, obj.str); // true\n * hasProperty(5, obj.str); // false\n *\n * hasProperty('length', obj.arr); // true\n * hasProperty(2, obj.arr); // true\n * hasProperty(3, obj.arr); // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n 'number': Number\n , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n var ot = type(obj);\n\n // Bad Object, obviously no props at all\n if(ot === 'null' || ot === 'undefined')\n return false;\n\n // The `in` operator does not work with certain literals\n // box these before the check\n if(literals[ot] && typeof obj !== 'object')\n obj = new literals[ot](obj);\n\n return name in obj;\n};\n","/*!\n * chai\n * Copyright(c) 2011 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n","// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n * properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n * output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n var ctx = {\n showHidden: showHidden,\n seen: [],\n stylize: function (str) { return str; }\n };\n return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n if (typeof HTMLElement === 'object') {\n return object instanceof HTMLElement;\n } else {\n return object &&\n typeof object === 'object' &&\n object.nodeType === 1 &&\n typeof object.nodeName === 'string';\n }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (value && typeof value.inspect === 'function' &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes);\n if (typeof ret !== 'string') {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // If this is a DOM element, try to get the outer HTML.\n if (isDOMElement(value)) {\n if ('outerHTML' in value) {\n return value.outerHTML;\n // This value does not have an outerHTML attribute,\n // it could still be an XML element\n } else {\n // Attempt to serialize it\n try {\n if (document.xmlVersion) {\n var xmlSerializer = new XMLSerializer();\n return xmlSerializer.serializeToString(value);\n } else {\n // Firefox 11- do not support outerHTML\n // It does, however, support innerHTML\n // Use the following to render the element\n var ns = \"http://www.w3.org/1999/xhtml\";\n var container = document.createElementNS(ns, '_');\n\n container.appendChild(value.cloneNode(false));\n html = container.innerHTML\n .replace('><', '>' + value.innerHTML + '<');\n container.innerHTML = '';\n return html;\n }\n } catch (err) {\n // This could be a non-native DOM implementation,\n // continue with the normal flow:\n // printing the element as if it is an object.\n }\n }\n }\n\n // Look up the keys of the object.\n var visibleKeys = getEnumerableProperties(value);\n var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n // Some type of object without properties can be shortcutted.\n // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n // a `stack` plus `description` property; ignore those for consistency.\n if (keys.length === 0 || (isError(value) && (\n (keys.length === 1 && keys[0] === 'stack') ||\n (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n ))) {\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n base = ' [Function' + nameSuffix + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n return formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n switch (typeof value) {\n case 'undefined':\n return ctx.stylize('undefined', 'undefined');\n\n case 'string':\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n\n case 'number':\n if (value === 0 && (1/value) === -Infinity) {\n return ctx.stylize('-0', 'number');\n }\n return ctx.stylize('' + value, 'number');\n\n case 'boolean':\n return ctx.stylize('' + value, 'boolean');\n }\n // For some reason typeof null is \"object\", so special case here.\n if (value === null) {\n return ctx.stylize('null', 'null');\n }\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str;\n if (value.__lookupGetter__) {\n if (value.__lookupGetter__(key)) {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n }\n if (visibleKeys.indexOf(key) < 0) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(value[key]) < 0) {\n if (recurseTimes === null) {\n str = formatValue(ctx, value[key], null);\n } else {\n str = formatValue(ctx, value[key], recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (typeof name === 'undefined') {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n return Array.isArray(ar) ||\n (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n var str = inspect(obj)\n , type = Object.prototype.toString.call(obj);\n\n if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n if (type === '[object Function]') {\n return !obj.name || obj.name === ''\n ? '[Function]'\n : '[Function: ' + obj.name + ']';\n } else if (type === '[object Array]') {\n return '[ Array(' + obj.length + ') ]';\n } else if (type === '[object Object]') {\n var keys = Object.keys(obj)\n , kstr = keys.length > 2\n ? keys.splice(0, 2).join(', ') + ', ...'\n : keys.join(', ');\n return '{ Object (' + kstr + ') }';\n } else {\n return str;\n }\n } else {\n return str;\n }\n};\n","/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property. Must return functions to be used for\n * name.\n *\n * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n * function (_super) {\n * }\n * , function (_super) {\n * }\n * );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.have.length(3);\n * expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n var chainableBehavior = ctx.__methods[name];\n\n var _chainingBehavior = chainableBehavior.chainingBehavior;\n chainableBehavior.chainingBehavior = function () {\n var result = chainingBehavior(_chainingBehavior).call(this);\n return result === undefined ? this : result;\n };\n\n var _method = chainableBehavior.method;\n chainableBehavior.method = function () {\n var result = method(_method).apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n * return function (str) {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.value).to.equal(str);\n * } else {\n * _super.apply(this, arguments);\n * }\n * }\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n var _method = ctx[name]\n , _super = function () { return this; };\n\n if (_method && 'function' === typeof _method)\n _super = _method;\n\n ctx[name] = function () {\n var result = method(_super).apply(this, arguments);\n return result === undefined ? this : result;\n }\n};\n","/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n * return function () {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.name).to.equal('bar');\n * } else {\n * _super.call(this);\n * }\n * }\n * });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n var _get = Object.getOwnPropertyDescriptor(ctx, name)\n , _super = function () {};\n\n if (_get && 'function' === typeof _get.get)\n _super = _get.get\n\n Object.defineProperty(ctx, name,\n { get: function () {\n var result = getter(_super).call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , expr = args[0];\n return negate ? !expr : expr;\n};\n","/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n * var newAssertion = new Assertion();\n * utils.transferFlags(assertion, newAssertion);\n *\n * var anotherAsseriton = new Assertion(myObj);\n * utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n if (!object.__flags) {\n object.__flags = Object.create(null);\n }\n\n includeAll = arguments.length === 3 ? includeAll : true;\n\n for (var flag in flags) {\n if (includeAll ||\n (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n object.__flags[flag] = flags[flag];\n }\n }\n};\n","\"use strict\";\n\nfunction dedent(strings) {\n\n var raw = void 0;\n if (typeof strings === \"string\") {\n // dedent can be used as a plain function\n raw = [strings];\n } else {\n raw = strings.raw;\n }\n\n // first, perform interpolation\n var result = \"\";\n for (var i = 0; i < raw.length; i++) {\n result += raw[i].\n // join lines when there is a suppressed newline\n replace(/\\\\\\n[ \\t]*/g, \"\").\n\n // handle escaped backticks\n replace(/\\\\`/g, \"`\");\n\n if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) {\n result += arguments.length <= i + 1 ? undefined : arguments[i + 1];\n }\n }\n\n // now strip indentation\n var lines = result.split(\"\\n\");\n var mindent = null;\n lines.forEach(function (l) {\n var m = l.match(/^(\\s+)\\S+/);\n if (m) {\n var indent = m[1].length;\n if (!mindent) {\n // this is the first indented line\n mindent = indent;\n } else {\n mindent = Math.min(mindent, indent);\n }\n }\n });\n\n if (mindent !== null) {\n result = lines.map(function (l) {\n return l[0] === \" \" ? l.slice(mindent) : l;\n }).join(\"\\n\");\n }\n\n // dedent eats leading and trailing whitespace too\n result = result.trim();\n\n // handle escaped newlines at the end to ensure they don't get stripped too\n return result.replace(/\\\\n/g, \"\\n\");\n}\n\nif (typeof module !== \"undefined\") {\n module.exports = dedent;\n}\n","module.exports = require('./lib/eql');\n","/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n Buffer = {};\n Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n if (sameValue(a, b)) {\n return true;\n } else if ('date' === type(a)) {\n return dateEqual(a, b);\n } else if ('regexp' === type(a)) {\n return regexpEqual(a, b);\n } else if (Buffer.isBuffer(a)) {\n return bufferEqual(a, b);\n } else if ('arguments' === type(a)) {\n return argumentsEqual(a, b, m);\n } else if (!typeEqual(a, b)) {\n return false;\n } else if (('object' !== type(a) && 'object' !== type(b))\n && ('array' !== type(a) && 'array' !== type(b))) {\n return sameValue(a, b);\n } else {\n return objectEqual(a, b, m);\n }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n if (a === b) return a !== 0 || 1 / a === 1 / b;\n return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n if ('date' !== type(b)) return false;\n return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n if ('regexp' !== type(b)) return false;\n return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n if ('arguments' !== type(b)) return false;\n a = [].slice.call(a);\n b = [].slice.call(b);\n return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n var res = [];\n for (var key in a) res.push(key);\n return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n if (a.length !== b.length) return false;\n\n var i = 0;\n var match = true;\n\n for (; i < a.length; i++) {\n if (a[i] !== b[i]) {\n match = false;\n break;\n }\n }\n\n return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n if (!Buffer.isBuffer(b)) return false;\n return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n if (!isValue(a) || !isValue(b)) {\n return false;\n }\n\n if (a.prototype !== b.prototype) {\n return false;\n }\n\n var i;\n if (m) {\n for (i = 0; i < m.length; i++) {\n if ((m[i][0] === a && m[i][1] === b)\n || (m[i][0] === b && m[i][1] === a)) {\n return true;\n }\n }\n } else {\n m = [];\n }\n\n try {\n var ka = enumerable(a);\n var kb = enumerable(b);\n } catch (ex) {\n return false;\n }\n\n ka.sort();\n kb.sort();\n\n if (!iterableEqual(ka, kb)) {\n return false;\n }\n\n m.push([ a, b ]);\n\n var key;\n for (i = ka.length - 1; i >= 0; i--) {\n key = ka[i];\n if (!deepEqual(a[key], b[key], m)) {\n return false;\n }\n }\n\n return true;\n}\n","/*!\n localForage -- Offline Storage, Improved\n Version 1.5.0\n https://localforage.github.io/localForage\n (c) 2013-2017 Mozilla, Apache License 2.0\n*/\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.localforage = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw (f.code=\"MODULE_NOT_FOUND\", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o element; its readystatechange event will be fired asynchronously once it is inserted\n // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.\n var scriptEl = global.document.createElement('script');\n scriptEl.onreadystatechange = function () {\n nextTick();\n\n scriptEl.onreadystatechange = null;\n scriptEl.parentNode.removeChild(scriptEl);\n scriptEl = null;\n };\n global.document.documentElement.appendChild(scriptEl);\n };\n } else {\n scheduleDrain = function () {\n setTimeout(nextTick, 0);\n };\n }\n}\n\nvar draining;\nvar queue = [];\n//named nextTick for less confusing stack traces\nfunction nextTick() {\n draining = true;\n var i, oldQueue;\n var len = queue.length;\n while (len) {\n oldQueue = queue;\n queue = [];\n i = -1;\n while (++i < len) {\n oldQueue[i]();\n }\n len = queue.length;\n }\n draining = false;\n}\n\nmodule.exports = immediate;\nfunction immediate(task) {\n if (queue.push(task) === 1 && !draining) {\n scheduleDrain();\n }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],2:[function(_dereq_,module,exports){\n'use strict';\nvar immediate = _dereq_(1);\n\n/* istanbul ignore next */\nfunction INTERNAL() {}\n\nvar handlers = {};\n\nvar REJECTED = ['REJECTED'];\nvar FULFILLED = ['FULFILLED'];\nvar PENDING = ['PENDING'];\n\nmodule.exports = exports = Promise;\n\nfunction Promise(resolver) {\n if (typeof resolver !== 'function') {\n throw new TypeError('resolver must be a function');\n }\n this.state = PENDING;\n this.queue = [];\n this.outcome = void 0;\n if (resolver !== INTERNAL) {\n safelyResolveThenable(this, resolver);\n }\n}\n\nPromise.prototype[\"catch\"] = function (onRejected) {\n return this.then(null, onRejected);\n};\nPromise.prototype.then = function (onFulfilled, onRejected) {\n if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||\n typeof onRejected !== 'function' && this.state === REJECTED) {\n return this;\n }\n var promise = new this.constructor(INTERNAL);\n if (this.state !== PENDING) {\n var resolver = this.state === FULFILLED ? onFulfilled : onRejected;\n unwrap(promise, resolver, this.outcome);\n } else {\n this.queue.push(new QueueItem(promise, onFulfilled, onRejected));\n }\n\n return promise;\n};\nfunction QueueItem(promise, onFulfilled, onRejected) {\n this.promise = promise;\n if (typeof onFulfilled === 'function') {\n this.onFulfilled = onFulfilled;\n this.callFulfilled = this.otherCallFulfilled;\n }\n if (typeof onRejected === 'function') {\n this.onRejected = onRejected;\n this.callRejected = this.otherCallRejected;\n }\n}\nQueueItem.prototype.callFulfilled = function (value) {\n handlers.resolve(this.promise, value);\n};\nQueueItem.prototype.otherCallFulfilled = function (value) {\n unwrap(this.promise, this.onFulfilled, value);\n};\nQueueItem.prototype.callRejected = function (value) {\n handlers.reject(this.promise, value);\n};\nQueueItem.prototype.otherCallRejected = function (value) {\n unwrap(this.promise, this.onRejected, value);\n};\n\nfunction unwrap(promise, func, value) {\n immediate(function () {\n var returnValue;\n try {\n returnValue = func(value);\n } catch (e) {\n return handlers.reject(promise, e);\n }\n if (returnValue === promise) {\n handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));\n } else {\n handlers.resolve(promise, returnValue);\n }\n });\n}\n\nhandlers.resolve = function (self, value) {\n var result = tryCatch(getThen, value);\n if (result.status === 'error') {\n return handlers.reject(self, result.value);\n }\n var thenable = result.value;\n\n if (thenable) {\n safelyResolveThenable(self, thenable);\n } else {\n self.state = FULFILLED;\n self.outcome = value;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callFulfilled(value);\n }\n }\n return self;\n};\nhandlers.reject = function (self, error) {\n self.state = REJECTED;\n self.outcome = error;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callRejected(error);\n }\n return self;\n};\n\nfunction getThen(obj) {\n // Make sure we only access the accessor once as required by the spec\n var then = obj && obj.then;\n if (obj && typeof obj === 'object' && typeof then === 'function') {\n return function appyThen() {\n then.apply(obj, arguments);\n };\n }\n}\n\nfunction safelyResolveThenable(self, thenable) {\n // Either fulfill, reject or reject with error\n var called = false;\n function onError(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.reject(self, value);\n }\n\n function onSuccess(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.resolve(self, value);\n }\n\n function tryToUnwrap() {\n thenable(onSuccess, onError);\n }\n\n var result = tryCatch(tryToUnwrap);\n if (result.status === 'error') {\n onError(result.value);\n }\n}\n\nfunction tryCatch(func, value) {\n var out = {};\n try {\n out.value = func(value);\n out.status = 'success';\n } catch (e) {\n out.status = 'error';\n out.value = e;\n }\n return out;\n}\n\nexports.resolve = resolve;\nfunction resolve(value) {\n if (value instanceof this) {\n return value;\n }\n return handlers.resolve(new this(INTERNAL), value);\n}\n\nexports.reject = reject;\nfunction reject(reason) {\n var promise = new this(INTERNAL);\n return handlers.reject(promise, reason);\n}\n\nexports.all = all;\nfunction all(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var values = new Array(len);\n var resolved = 0;\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n allResolver(iterable[i], i);\n }\n return promise;\n function allResolver(value, i) {\n self.resolve(value).then(resolveFromAll, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n function resolveFromAll(outValue) {\n values[i] = outValue;\n if (++resolved === len && !called) {\n called = true;\n handlers.resolve(promise, values);\n }\n }\n }\n}\n\nexports.race = race;\nfunction race(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n resolver(iterable[i]);\n }\n return promise;\n function resolver(value) {\n self.resolve(value).then(function (response) {\n if (!called) {\n called = true;\n handlers.resolve(promise, response);\n }\n }, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n }\n}\n\n},{\"1\":1}],3:[function(_dereq_,module,exports){\n(function (global){\n'use strict';\nif (typeof global.Promise !== 'function') {\n global.Promise = _dereq_(2);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"2\":2}],4:[function(_dereq_,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction getIDB() {\n /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */\n try {\n if (typeof indexedDB !== 'undefined') {\n return indexedDB;\n }\n if (typeof webkitIndexedDB !== 'undefined') {\n return webkitIndexedDB;\n }\n if (typeof mozIndexedDB !== 'undefined') {\n return mozIndexedDB;\n }\n if (typeof OIndexedDB !== 'undefined') {\n return OIndexedDB;\n }\n if (typeof msIndexedDB !== 'undefined') {\n return msIndexedDB;\n }\n } catch (e) {}\n}\n\nvar idb = getIDB();\n\nfunction isIndexedDBValid() {\n try {\n // Initialize IndexedDB; fall back to vendor-prefixed versions\n // if needed.\n if (!idb) {\n return false;\n }\n // We mimic PouchDB here;\n //\n // We test for openDatabase because IE Mobile identifies itself\n // as Safari. Oh the lulz...\n var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform);\n\n var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1;\n\n // Safari <10.1 does not meet our requirements for IDB support (#5572)\n // since Safari 10.1 shipped with fetch, we can use that to detect it\n return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' &&\n // some outdated implementations of IDB that appear on Samsung\n // and HTC Android devices <4.4 are missing IDBKeyRange\n typeof IDBKeyRange !== 'undefined';\n } catch (e) {\n return false;\n }\n}\n\nfunction isWebSQLValid() {\n return typeof openDatabase === 'function';\n}\n\nfunction isLocalStorageValid() {\n try {\n return typeof localStorage !== 'undefined' && 'setItem' in localStorage && localStorage.setItem;\n } catch (e) {\n return false;\n }\n}\n\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\nfunction createBlob(parts, properties) {\n /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */\n parts = parts || [];\n properties = properties || {};\n try {\n return new Blob(parts, properties);\n } catch (e) {\n if (e.name !== 'TypeError') {\n throw e;\n }\n var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder;\n var builder = new Builder();\n for (var i = 0; i < parts.length; i += 1) {\n builder.append(parts[i]);\n }\n return builder.getBlob(properties.type);\n }\n}\n\n// This is CommonJS because lie is an external dependency, so Rollup\n// can just ignore it.\nif (typeof Promise === 'undefined') {\n // In the \"nopromises\" build this will just throw if you don't have\n // a global promise object, but it would throw anyway later.\n _dereq_(3);\n}\nvar Promise$1 = Promise;\n\nfunction executeCallback(promise, callback) {\n if (callback) {\n promise.then(function (result) {\n callback(null, result);\n }, function (error) {\n callback(error);\n });\n }\n}\n\nfunction executeTwoCallbacks(promise, callback, errorCallback) {\n if (typeof callback === 'function') {\n promise.then(callback);\n }\n\n if (typeof errorCallback === 'function') {\n promise[\"catch\"](errorCallback);\n }\n}\n\n// Some code originally from async_storage.js in\n// [Gaia](https://github.com/mozilla-b2g/gaia).\n\nvar DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support';\nvar supportsBlobs;\nvar dbContexts;\nvar toString = Object.prototype.toString;\n\n// Transform a binary string to an array buffer, because otherwise\n// weird stuff happens when you try to work with the binary string directly.\n// It is known.\n// From http://stackoverflow.com/questions/14967647/ (continues on next line)\n// encode-decode-image-with-base64-breaks-image (2013-04-21)\nfunction _binStringToArrayBuffer(bin) {\n var length = bin.length;\n var buf = new ArrayBuffer(length);\n var arr = new Uint8Array(buf);\n for (var i = 0; i < length; i++) {\n arr[i] = bin.charCodeAt(i);\n }\n return buf;\n}\n\n//\n// Blobs are not supported in all versions of IndexedDB, notably\n// Chrome <37 and Android <5. In those versions, storing a blob will throw.\n//\n// Various other blob bugs exist in Chrome v37-42 (inclusive).\n// Detecting them is expensive and confusing to users, and Chrome 37-42\n// is at very low usage worldwide, so we do a hacky userAgent check instead.\n//\n// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120\n// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916\n// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836\n//\n// Code borrowed from PouchDB. See:\n// https://github.com/pouchdb/pouchdb/blob/master/packages/node_modules/pouchdb-adapter-idb/src/blobSupport.js\n//\nfunction _checkBlobSupportWithoutCaching(idb) {\n return new Promise$1(function (resolve) {\n var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, 'readwrite');\n var blob = createBlob(['']);\n txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');\n\n txn.onabort = function (e) {\n // If the transaction aborts now its due to not being able to\n // write to the database, likely due to the disk being full\n e.preventDefault();\n e.stopPropagation();\n resolve(false);\n };\n\n txn.oncomplete = function () {\n var matchedChrome = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n var matchedEdge = navigator.userAgent.match(/Edge\\//);\n // MS Edge pretends to be Chrome 42:\n // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx\n resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43);\n };\n })[\"catch\"](function () {\n return false; // error, so assume unsupported\n });\n}\n\nfunction _checkBlobSupport(idb) {\n if (typeof supportsBlobs === 'boolean') {\n return Promise$1.resolve(supportsBlobs);\n }\n return _checkBlobSupportWithoutCaching(idb).then(function (value) {\n supportsBlobs = value;\n return supportsBlobs;\n });\n}\n\nfunction _deferReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Create a deferred object representing the current database operation.\n var deferredOperation = {};\n\n deferredOperation.promise = new Promise$1(function (resolve) {\n deferredOperation.resolve = resolve;\n });\n\n // Enqueue the deferred operation.\n dbContext.deferredOperations.push(deferredOperation);\n\n // Chain its promise to the database readiness.\n if (!dbContext.dbReady) {\n dbContext.dbReady = deferredOperation.promise;\n } else {\n dbContext.dbReady = dbContext.dbReady.then(function () {\n return deferredOperation.promise;\n });\n }\n}\n\nfunction _advanceReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Dequeue a deferred operation.\n var deferredOperation = dbContext.deferredOperations.pop();\n\n // Resolve its promise (which is part of the database readiness\n // chain of promises).\n if (deferredOperation) {\n deferredOperation.resolve();\n }\n}\n\nfunction _getConnection(dbInfo, upgradeNeeded) {\n return new Promise$1(function (resolve, reject) {\n\n if (dbInfo.db) {\n if (upgradeNeeded) {\n _deferReadiness(dbInfo);\n dbInfo.db.close();\n } else {\n return resolve(dbInfo.db);\n }\n }\n\n var dbArgs = [dbInfo.name];\n\n if (upgradeNeeded) {\n dbArgs.push(dbInfo.version);\n }\n\n var openreq = idb.open.apply(idb, dbArgs);\n\n if (upgradeNeeded) {\n openreq.onupgradeneeded = function (e) {\n var db = openreq.result;\n try {\n db.createObjectStore(dbInfo.storeName);\n if (e.oldVersion <= 1) {\n // Added when support for blob shims was added\n db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);\n }\n } catch (ex) {\n if (ex.name === 'ConstraintError') {\n console.warn('The database \"' + dbInfo.name + '\"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage \"' + dbInfo.storeName + '\" already exists.');\n } else {\n throw ex;\n }\n }\n };\n }\n\n openreq.onerror = function (e) {\n e.preventDefault();\n reject(openreq.error);\n };\n\n openreq.onsuccess = function () {\n resolve(openreq.result);\n _advanceReadiness(dbInfo);\n };\n });\n}\n\nfunction _getOriginalConnection(dbInfo) {\n return _getConnection(dbInfo, false);\n}\n\nfunction _getUpgradedConnection(dbInfo) {\n return _getConnection(dbInfo, true);\n}\n\nfunction _isUpgradeNeeded(dbInfo, defaultVersion) {\n if (!dbInfo.db) {\n return true;\n }\n\n var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName);\n var isDowngrade = dbInfo.version < dbInfo.db.version;\n var isUpgrade = dbInfo.version > dbInfo.db.version;\n\n if (isDowngrade) {\n // If the version is not the default one\n // then warn for impossible downgrade.\n if (dbInfo.version !== defaultVersion) {\n console.warn('The database \"' + dbInfo.name + '\"' + ' can\\'t be downgraded from version ' + dbInfo.db.version + ' to version ' + dbInfo.version + '.');\n }\n // Align the versions to prevent errors.\n dbInfo.version = dbInfo.db.version;\n }\n\n if (isUpgrade || isNewStore) {\n // If the store is new then increment the version (if needed).\n // This will trigger an \"upgradeneeded\" event which is required\n // for creating a store.\n if (isNewStore) {\n var incVersion = dbInfo.db.version + 1;\n if (incVersion > dbInfo.version) {\n dbInfo.version = incVersion;\n }\n }\n\n return true;\n }\n\n return false;\n}\n\n// encode a blob for indexeddb engines that don't support blobs\nfunction _encodeBlob(blob) {\n return new Promise$1(function (resolve, reject) {\n var reader = new FileReader();\n reader.onerror = reject;\n reader.onloadend = function (e) {\n var base64 = btoa(e.target.result || '');\n resolve({\n __local_forage_encoded_blob: true,\n data: base64,\n type: blob.type\n });\n };\n reader.readAsBinaryString(blob);\n });\n}\n\n// decode an encoded blob\nfunction _decodeBlob(encodedBlob) {\n var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data));\n return createBlob([arrayBuff], { type: encodedBlob.type });\n}\n\n// is this one of our fancy encoded blobs?\nfunction _isEncodedBlob(value) {\n return value && value.__local_forage_encoded_blob;\n}\n\n// Specialize the default `ready()` function by making it dependent\n// on the current database operations. Thus, the driver will be actually\n// ready when it's been initialized (default) *and* there are no pending\n// operations on the database (initiated by some other instances).\nfunction _fullyReady(callback) {\n var self = this;\n\n var promise = self._initReady().then(function () {\n var dbContext = dbContexts[self._dbInfo.name];\n\n if (dbContext && dbContext.dbReady) {\n return dbContext.dbReady;\n }\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n}\n\n// Open the IndexedDB database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n // Initialize a singleton container for all running localForages.\n if (!dbContexts) {\n dbContexts = {};\n }\n\n // Get the current context of the database;\n var dbContext = dbContexts[dbInfo.name];\n\n // ...or create a new context.\n if (!dbContext) {\n dbContext = {\n // Running localForages sharing a database.\n forages: [],\n // Shared database.\n db: null,\n // Database readiness (promise).\n dbReady: null,\n // Deferred operations on the database.\n deferredOperations: []\n };\n // Register the new context in the global container.\n dbContexts[dbInfo.name] = dbContext;\n }\n\n // Register itself as a running localForage in the current context.\n dbContext.forages.push(self);\n\n // Replace the default `ready()` function with the specialized one.\n if (!self._initReady) {\n self._initReady = self.ready;\n self.ready = _fullyReady;\n }\n\n // Create an array of initialization states of the related localForages.\n var initPromises = [];\n\n function ignoreErrors() {\n // Don't handle errors here,\n // just makes sure related localForages aren't pending.\n return Promise$1.resolve();\n }\n\n for (var j = 0; j < dbContext.forages.length; j++) {\n var forage = dbContext.forages[j];\n if (forage !== self) {\n // Don't wait for itself...\n initPromises.push(forage._initReady()[\"catch\"](ignoreErrors));\n }\n }\n\n // Take a snapshot of the related localForages.\n var forages = dbContext.forages.slice(0);\n\n // Initialize the connection process only when\n // all the related localForages aren't pending.\n return Promise$1.all(initPromises).then(function () {\n dbInfo.db = dbContext.db;\n // Get the connection or open a new one without upgrade.\n return _getOriginalConnection(dbInfo);\n }).then(function (db) {\n dbInfo.db = db;\n if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) {\n // Reopen the database for upgrading.\n return _getUpgradedConnection(dbInfo);\n }\n return db;\n }).then(function (db) {\n dbInfo.db = dbContext.db = db;\n self._dbInfo = dbInfo;\n // Share the final connection amongst related localForages.\n for (var k = 0; k < forages.length; k++) {\n var forage = forages[k];\n if (forage !== self) {\n // Self is already up-to-date.\n forage._dbInfo.db = dbInfo.db;\n forage._dbInfo.version = dbInfo.version;\n }\n }\n });\n}\n\nfunction getItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.get(key);\n\n req.onsuccess = function () {\n var value = req.result;\n if (value === undefined) {\n value = null;\n }\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n resolve(value);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items stored in database.\nfunction iterate(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var iterationNumber = 1;\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (cursor) {\n var value = cursor.value;\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n var result = iterator(value, cursor.key, iterationNumber++);\n\n if (result !== void 0) {\n resolve(result);\n } else {\n cursor[\"continue\"]();\n }\n } else {\n resolve();\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n\n return promise;\n}\n\nfunction setItem(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n var dbInfo;\n self.ready().then(function () {\n dbInfo = self._dbInfo;\n if (toString.call(value) === '[object Blob]') {\n return _checkBlobSupport(dbInfo.db).then(function (blobSupport) {\n if (blobSupport) {\n return value;\n }\n return _encodeBlob(value);\n });\n }\n return value;\n }).then(function (value) {\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.put(value, key);\n\n // The reason we don't _save_ null is because IE 10 does\n // not support saving the `null` type in IndexedDB. How\n // ironic, given the bug below!\n // See: https://github.com/mozilla/localForage/issues/161\n if (value === null) {\n value = undefined;\n }\n\n transaction.oncomplete = function () {\n // Cast to undefined so the value passed to\n // callback/promise is the same as what one would get out\n // of `getItem()` later. This leads to some weirdness\n // (setItem('foo', undefined) will return `null`), but\n // it's not my fault localStorage is our baseline and that\n // it's weird.\n if (value === undefined) {\n value = null;\n }\n\n resolve(value);\n };\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction removeItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n\n // We use a Grunt task to make this safe for IE and some\n // versions of Android (including those used by Cordova).\n // Normally IE won't like `.delete()` and will insist on\n // using `['delete']()`, but we have a build step that\n // fixes this for us now.\n var req = store[\"delete\"](key);\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onerror = function () {\n reject(req.error);\n };\n\n // The request will be also be aborted if we've exceeded our storage\n // space.\n transaction.onabort = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction clear(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.clear();\n\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction length(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.count();\n\n req.onsuccess = function () {\n resolve(req.result);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction key(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n if (n < 0) {\n resolve(null);\n\n return;\n }\n\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var advanced = false;\n var req = store.openCursor();\n req.onsuccess = function () {\n var cursor = req.result;\n if (!cursor) {\n // this means there weren't enough keys\n resolve(null);\n\n return;\n }\n\n if (n === 0) {\n // We have the first key, return it if that's what they\n // wanted.\n resolve(cursor.key);\n } else {\n if (!advanced) {\n // Otherwise, ask the cursor to skip ahead n\n // records.\n advanced = true;\n cursor.advance(n);\n } else {\n // When we get here, we've got the nth key.\n resolve(cursor.key);\n }\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var keys = [];\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (!cursor) {\n resolve(keys);\n return;\n }\n\n keys.push(cursor.key);\n cursor[\"continue\"]();\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar asyncStorage = {\n _driver: 'asyncStorage',\n _initStorage: _initStorage,\n iterate: iterate,\n getItem: getItem,\n setItem: setItem,\n removeItem: removeItem,\n clear: clear,\n length: length,\n key: key,\n keys: keys\n};\n\n// Sadly, the best way to save binary data in WebSQL/localStorage is serializing\n// it to Base64, so this is how we store it to prevent very strange errors with less\n// verbose ways of binary <-> string data storage.\nvar BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\nvar BLOB_TYPE_PREFIX = '~~local_forage_type~';\nvar BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;\n\nvar SERIALIZED_MARKER = '__lfsc__:';\nvar SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;\n\n// OMG the serializations!\nvar TYPE_ARRAYBUFFER = 'arbf';\nvar TYPE_BLOB = 'blob';\nvar TYPE_INT8ARRAY = 'si08';\nvar TYPE_UINT8ARRAY = 'ui08';\nvar TYPE_UINT8CLAMPEDARRAY = 'uic8';\nvar TYPE_INT16ARRAY = 'si16';\nvar TYPE_INT32ARRAY = 'si32';\nvar TYPE_UINT16ARRAY = 'ur16';\nvar TYPE_UINT32ARRAY = 'ui32';\nvar TYPE_FLOAT32ARRAY = 'fl32';\nvar TYPE_FLOAT64ARRAY = 'fl64';\nvar TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;\n\nvar toString$1 = Object.prototype.toString;\n\nfunction stringToBuffer(serializedString) {\n // Fill the string into a ArrayBuffer.\n var bufferLength = serializedString.length * 0.75;\n var len = serializedString.length;\n var i;\n var p = 0;\n var encoded1, encoded2, encoded3, encoded4;\n\n if (serializedString[serializedString.length - 1] === '=') {\n bufferLength--;\n if (serializedString[serializedString.length - 2] === '=') {\n bufferLength--;\n }\n }\n\n var buffer = new ArrayBuffer(bufferLength);\n var bytes = new Uint8Array(buffer);\n\n for (i = 0; i < len; i += 4) {\n encoded1 = BASE_CHARS.indexOf(serializedString[i]);\n encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);\n encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);\n encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);\n\n /*jslint bitwise: true */\n bytes[p++] = encoded1 << 2 | encoded2 >> 4;\n bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;\n bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;\n }\n return buffer;\n}\n\n// Converts a buffer to a string to store, serialized, in the backend\n// storage library.\nfunction bufferToString(buffer) {\n // base64-arraybuffer\n var bytes = new Uint8Array(buffer);\n var base64String = '';\n var i;\n\n for (i = 0; i < bytes.length; i += 3) {\n /*jslint bitwise: true */\n base64String += BASE_CHARS[bytes[i] >> 2];\n base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];\n base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];\n base64String += BASE_CHARS[bytes[i + 2] & 63];\n }\n\n if (bytes.length % 3 === 2) {\n base64String = base64String.substring(0, base64String.length - 1) + '=';\n } else if (bytes.length % 3 === 1) {\n base64String = base64String.substring(0, base64String.length - 2) + '==';\n }\n\n return base64String;\n}\n\n// Serialize a value, afterwards executing a callback (which usually\n// instructs the `setItem()` callback/promise to be executed). This is how\n// we store binary data with localStorage.\nfunction serialize(value, callback) {\n var valueType = '';\n if (value) {\n valueType = toString$1.call(value);\n }\n\n // Cannot use `value instanceof ArrayBuffer` or such here, as these\n // checks fail when running the tests using casper.js...\n //\n // TODO: See why those tests fail and use a better solution.\n if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) {\n // Convert binary arrays to a string and prefix the string with\n // a special marker.\n var buffer;\n var marker = SERIALIZED_MARKER;\n\n if (value instanceof ArrayBuffer) {\n buffer = value;\n marker += TYPE_ARRAYBUFFER;\n } else {\n buffer = value.buffer;\n\n if (valueType === '[object Int8Array]') {\n marker += TYPE_INT8ARRAY;\n } else if (valueType === '[object Uint8Array]') {\n marker += TYPE_UINT8ARRAY;\n } else if (valueType === '[object Uint8ClampedArray]') {\n marker += TYPE_UINT8CLAMPEDARRAY;\n } else if (valueType === '[object Int16Array]') {\n marker += TYPE_INT16ARRAY;\n } else if (valueType === '[object Uint16Array]') {\n marker += TYPE_UINT16ARRAY;\n } else if (valueType === '[object Int32Array]') {\n marker += TYPE_INT32ARRAY;\n } else if (valueType === '[object Uint32Array]') {\n marker += TYPE_UINT32ARRAY;\n } else if (valueType === '[object Float32Array]') {\n marker += TYPE_FLOAT32ARRAY;\n } else if (valueType === '[object Float64Array]') {\n marker += TYPE_FLOAT64ARRAY;\n } else {\n callback(new Error('Failed to get type for BinaryArray'));\n }\n }\n\n callback(marker + bufferToString(buffer));\n } else if (valueType === '[object Blob]') {\n // Conver the blob to a binaryArray and then to a string.\n var fileReader = new FileReader();\n\n fileReader.onload = function () {\n // Backwards-compatible prefix for the blob type.\n var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result);\n\n callback(SERIALIZED_MARKER + TYPE_BLOB + str);\n };\n\n fileReader.readAsArrayBuffer(value);\n } else {\n try {\n callback(JSON.stringify(value));\n } catch (e) {\n console.error(\"Couldn't convert value into a JSON string: \", value);\n\n callback(null, e);\n }\n }\n}\n\n// Deserialize data we've inserted into a value column/field. We place\n// special markers into our strings to mark them as encoded; this isn't\n// as nice as a meta field, but it's the only sane thing we can do whilst\n// keeping localStorage support intact.\n//\n// Oftentimes this will just deserialize JSON content, but if we have a\n// special marker (SERIALIZED_MARKER, defined above), we will extract\n// some kind of arraybuffer/binary data/typed array out of the string.\nfunction deserialize(value) {\n // If we haven't marked this string as being specially serialized (i.e.\n // something other than serialized JSON), we can just return it and be\n // done with it.\n if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {\n return JSON.parse(value);\n }\n\n // The following code deals with deserializing some kind of Blob or\n // TypedArray. First we separate out the type of data we're dealing\n // with from the data itself.\n var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);\n var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH);\n\n var blobType;\n // Backwards-compatible blob type serialization strategy.\n // DBs created with older versions of localForage will simply not have the blob type.\n if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {\n var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);\n blobType = matcher[1];\n serializedString = serializedString.substring(matcher[0].length);\n }\n var buffer = stringToBuffer(serializedString);\n\n // Return the right type based on the code/type set during\n // serialization.\n switch (type) {\n case TYPE_ARRAYBUFFER:\n return buffer;\n case TYPE_BLOB:\n return createBlob([buffer], { type: blobType });\n case TYPE_INT8ARRAY:\n return new Int8Array(buffer);\n case TYPE_UINT8ARRAY:\n return new Uint8Array(buffer);\n case TYPE_UINT8CLAMPEDARRAY:\n return new Uint8ClampedArray(buffer);\n case TYPE_INT16ARRAY:\n return new Int16Array(buffer);\n case TYPE_UINT16ARRAY:\n return new Uint16Array(buffer);\n case TYPE_INT32ARRAY:\n return new Int32Array(buffer);\n case TYPE_UINT32ARRAY:\n return new Uint32Array(buffer);\n case TYPE_FLOAT32ARRAY:\n return new Float32Array(buffer);\n case TYPE_FLOAT64ARRAY:\n return new Float64Array(buffer);\n default:\n throw new Error('Unkown type: ' + type);\n }\n}\n\nvar localforageSerializer = {\n serialize: serialize,\n deserialize: deserialize,\n stringToBuffer: stringToBuffer,\n bufferToString: bufferToString\n};\n\n/*\n * Includes code from:\n *\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n// Open the WebSQL database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage$1(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i];\n }\n }\n\n var dbInfoPromise = new Promise$1(function (resolve, reject) {\n // Open the database; the openDatabase API will automatically\n // create it for us if it doesn't exist.\n try {\n dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size);\n } catch (e) {\n return reject(e);\n }\n\n // Create our key/value table if it doesn't exist.\n dbInfo.db.transaction(function (t) {\n t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' (id INTEGER PRIMARY KEY, key unique, value)', [], function () {\n self._dbInfo = dbInfo;\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n });\n\n dbInfo.serializer = localforageSerializer;\n return dbInfoPromise;\n}\n\nfunction getItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).value : null;\n\n // Check to see if this is serialized content we need to\n // unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction iterate$1(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName, [], function (t, results) {\n var rows = results.rows;\n var length = rows.length;\n\n for (var i = 0; i < length; i++) {\n var item = rows.item(i);\n var result = item.value;\n\n // Check to see if this is serialized content\n // we need to unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n result = iterator(result, item.key, i + 1);\n\n // void(0) prevents problems with redefinition\n // of `undefined`.\n if (result !== void 0) {\n resolve(result);\n return;\n }\n }\n\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction _setItem(key, value, callback, retriesLeft) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n // The localStorage API doesn't return undefined values in an\n // \"expected\" way, so undefined is always cast to null in all\n // drivers. See: https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n dbInfo.db.transaction(function (t) {\n t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + ' (key, value) VALUES (?, ?)', [key, value], function () {\n resolve(originalValue);\n }, function (t, error) {\n reject(error);\n });\n }, function (sqlError) {\n // The transaction failed; check\n // to see if it's a quota error.\n if (sqlError.code === sqlError.QUOTA_ERR) {\n // We reject the callback outright for now, but\n // it's worth trying to re-run the transaction.\n // Even if the user accepts the prompt to use\n // more storage on Safari, this error will\n // be called.\n //\n // Try to re-run the transaction.\n if (retriesLeft > 0) {\n resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1]));\n return;\n }\n reject(sqlError);\n }\n });\n }\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction setItem$1(key, value, callback) {\n return _setItem.apply(this, [key, value, callback, 1]);\n}\n\nfunction removeItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () {\n resolve();\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Deletes every item in the table.\n// TODO: Find out if this resets the AUTO_INCREMENT number.\nfunction clear$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function () {\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Does a simple `COUNT(key)` to get the number of items stored in\n// localForage.\nfunction length$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n // Ahhh, SQL makes this one soooooo easy.\n t.executeSql('SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) {\n var result = results.rows.item(0).c;\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Return the key located at key index X; essentially gets the key from a\n// `WHERE id = ?`. This is the most efficient way I can think to implement\n// this rarely-used (in my experience) part of the API, but it can seem\n// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so\n// the ID of each key will change every time it's updated. Perhaps a stored\n// procedure for the `setItem()` SQL would solve this problem?\n// TODO: Don't change ID on `setItem()`.\nfunction key$1(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).key : null;\n resolve(result);\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName, [], function (t, results) {\n var keys = [];\n\n for (var i = 0; i < results.rows.length; i++) {\n keys.push(results.rows.item(i).key);\n }\n\n resolve(keys);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar webSQLStorage = {\n _driver: 'webSQLStorage',\n _initStorage: _initStorage$1,\n iterate: iterate$1,\n getItem: getItem$1,\n setItem: setItem$1,\n removeItem: removeItem$1,\n clear: clear$1,\n length: length$1,\n key: key$1,\n keys: keys$1\n};\n\n// Config the localStorage backend, using options set in the config.\nfunction _initStorage$2(options) {\n var self = this;\n var dbInfo = {};\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n dbInfo.keyPrefix = dbInfo.name + '/';\n\n if (dbInfo.storeName !== self._defaultConfig.storeName) {\n dbInfo.keyPrefix += dbInfo.storeName + '/';\n }\n\n self._dbInfo = dbInfo;\n dbInfo.serializer = localforageSerializer;\n\n return Promise$1.resolve();\n}\n\n// Remove all keys from the datastore, effectively destroying all data in\n// the app's key/value store!\nfunction clear$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var keyPrefix = self._dbInfo.keyPrefix;\n\n for (var i = localStorage.length - 1; i >= 0; i--) {\n var key = localStorage.key(i);\n\n if (key.indexOf(keyPrefix) === 0) {\n localStorage.removeItem(key);\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Retrieve an item from the store. Unlike the original async_storage\n// library in Gaia, we don't modify return values at all. If a key's value\n// is `undefined`, we pass that value to the callback function.\nfunction getItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result = localStorage.getItem(dbInfo.keyPrefix + key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the key\n // is likely undefined and we'll pass it straight to the\n // callback.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items in the store.\nfunction iterate$2(iterator, callback) {\n var self = this;\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var keyPrefix = dbInfo.keyPrefix;\n var keyPrefixLength = keyPrefix.length;\n var length = localStorage.length;\n\n // We use a dedicated iterator instead of the `i` variable below\n // so other keys we fetch in localStorage aren't counted in\n // the `iterationNumber` argument passed to the `iterate()`\n // callback.\n //\n // See: github.com/mozilla/localForage/pull/435#discussion_r38061530\n var iterationNumber = 1;\n\n for (var i = 0; i < length; i++) {\n var key = localStorage.key(i);\n if (key.indexOf(keyPrefix) !== 0) {\n continue;\n }\n var value = localStorage.getItem(key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the\n // key is likely undefined and we'll pass it straight\n // to the iterator.\n if (value) {\n value = dbInfo.serializer.deserialize(value);\n }\n\n value = iterator(value, key.substring(keyPrefixLength), iterationNumber++);\n\n if (value !== void 0) {\n return value;\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Same as localStorage's key() method, except takes a callback.\nfunction key$2(n, callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result;\n try {\n result = localStorage.key(n);\n } catch (error) {\n result = null;\n }\n\n // Remove the prefix from the key, if a key is found.\n if (result) {\n result = result.substring(dbInfo.keyPrefix.length);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var length = localStorage.length;\n var keys = [];\n\n for (var i = 0; i < length; i++) {\n if (localStorage.key(i).indexOf(dbInfo.keyPrefix) === 0) {\n keys.push(localStorage.key(i).substring(dbInfo.keyPrefix.length));\n }\n }\n\n return keys;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Supply the number of keys in the datastore to the callback function.\nfunction length$2(callback) {\n var self = this;\n var promise = self.keys().then(function (keys) {\n return keys.length;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Remove an item from the store, nice and simple.\nfunction removeItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n localStorage.removeItem(dbInfo.keyPrefix + key);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Set a key's value and run an optional callback once the value is set.\n// Unlike Gaia's implementation, the callback function is passed the value,\n// in case you want to operate on that value only after you're sure it\n// saved, or something like that.\nfunction setItem$2(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n // Convert undefined values to null.\n // https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n return new Promise$1(function (resolve, reject) {\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n try {\n localStorage.setItem(dbInfo.keyPrefix + key, value);\n resolve(originalValue);\n } catch (e) {\n // localStorage capacity exceeded.\n // TODO: Make this a specific error/event.\n if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {\n reject(e);\n }\n reject(e);\n }\n }\n });\n });\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar localStorageWrapper = {\n _driver: 'localStorageWrapper',\n _initStorage: _initStorage$2,\n // Default API, from Gaia/localStorage.\n iterate: iterate$2,\n getItem: getItem$2,\n setItem: setItem$2,\n removeItem: removeItem$2,\n clear: clear$2,\n length: length$2,\n key: key$2,\n keys: keys$2\n};\n\n// Custom drivers are stored here when `defineDriver()` is called.\n// They are shared across all instances of localForage.\nvar CustomDrivers = {};\n\nvar DriverType = {\n INDEXEDDB: 'asyncStorage',\n LOCALSTORAGE: 'localStorageWrapper',\n WEBSQL: 'webSQLStorage'\n};\n\nvar DefaultDriverOrder = [DriverType.INDEXEDDB, DriverType.WEBSQL, DriverType.LOCALSTORAGE];\n\nvar LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem'];\n\nvar DefaultConfig = {\n description: '',\n driver: DefaultDriverOrder.slice(),\n name: 'localforage',\n // Default DB size is _JUST UNDER_ 5MB, as it's the highest size\n // we can use without a prompt.\n size: 4980736,\n storeName: 'keyvaluepairs',\n version: 1.0\n};\n\nvar driverSupport = {};\n// Check to see if IndexedDB is available and if it is the latest\n// implementation; it's our preferred backend library. We use \"_spec_test\"\n// as the name of the database because it's not the one we'll operate on,\n// but it's useful to make sure its using the right spec.\n// See: https://github.com/mozilla/localForage/issues/128\ndriverSupport[DriverType.INDEXEDDB] = isIndexedDBValid();\n\ndriverSupport[DriverType.WEBSQL] = isWebSQLValid();\n\ndriverSupport[DriverType.LOCALSTORAGE] = isLocalStorageValid();\n\nvar isArray = Array.isArray || function (arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n};\n\nfunction callWhenReady(localForageInstance, libraryMethod) {\n localForageInstance[libraryMethod] = function () {\n var _args = arguments;\n return localForageInstance.ready().then(function () {\n return localForageInstance[libraryMethod].apply(localForageInstance, _args);\n });\n };\n}\n\nfunction extend() {\n for (var i = 1; i < arguments.length; i++) {\n var arg = arguments[i];\n\n if (arg) {\n for (var key in arg) {\n if (arg.hasOwnProperty(key)) {\n if (isArray(arg[key])) {\n arguments[0][key] = arg[key].slice();\n } else {\n arguments[0][key] = arg[key];\n }\n }\n }\n }\n }\n\n return arguments[0];\n}\n\nfunction isLibraryDriver(driverName) {\n for (var driver in DriverType) {\n if (DriverType.hasOwnProperty(driver) && DriverType[driver] === driverName) {\n return true;\n }\n }\n\n return false;\n}\n\nvar LocalForage = function () {\n function LocalForage(options) {\n _classCallCheck(this, LocalForage);\n\n this.INDEXEDDB = DriverType.INDEXEDDB;\n this.LOCALSTORAGE = DriverType.LOCALSTORAGE;\n this.WEBSQL = DriverType.WEBSQL;\n\n this._defaultConfig = extend({}, DefaultConfig);\n this._config = extend({}, this._defaultConfig, options);\n this._driverSet = null;\n this._initDriver = null;\n this._ready = false;\n this._dbInfo = null;\n\n this._wrapLibraryMethodsWithReady();\n this.setDriver(this._config.driver)[\"catch\"](function () {});\n }\n\n // Set any config values for localForage; can be called anytime before\n // the first API call (e.g. `getItem`, `setItem`).\n // We loop through options so we don't overwrite existing config\n // values.\n\n\n LocalForage.prototype.config = function config(options) {\n // If the options argument is an object, we use it to set values.\n // Otherwise, we return either a specified config value or all\n // config values.\n if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {\n // If localforage is ready and fully initialized, we can't set\n // any new configuration values. Instead, we return an error.\n if (this._ready) {\n return new Error(\"Can't call config() after localforage \" + 'has been used.');\n }\n\n for (var i in options) {\n if (i === 'storeName') {\n options[i] = options[i].replace(/\\W/g, '_');\n }\n\n if (i === 'version' && typeof options[i] !== 'number') {\n return new Error('Database version must be a number.');\n }\n\n this._config[i] = options[i];\n }\n\n // after all config options are set and\n // the driver option is used, try setting it\n if ('driver' in options && options.driver) {\n return this.setDriver(this._config.driver);\n }\n\n return true;\n } else if (typeof options === 'string') {\n return this._config[options];\n } else {\n return this._config;\n }\n };\n\n // Used to define a custom driver, shared across all instances of\n // localForage.\n\n\n LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) {\n var promise = new Promise$1(function (resolve, reject) {\n try {\n var driverName = driverObject._driver;\n var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver');\n var namingError = new Error('Custom driver name already in use: ' + driverObject._driver);\n\n // A driver name should be defined and not overlap with the\n // library-defined, default drivers.\n if (!driverObject._driver) {\n reject(complianceError);\n return;\n }\n if (isLibraryDriver(driverObject._driver)) {\n reject(namingError);\n return;\n }\n\n var customDriverMethods = LibraryMethods.concat('_initStorage');\n for (var i = 0; i < customDriverMethods.length; i++) {\n var customDriverMethod = customDriverMethods[i];\n if (!customDriverMethod || !driverObject[customDriverMethod] || typeof driverObject[customDriverMethod] !== 'function') {\n reject(complianceError);\n return;\n }\n }\n\n var supportPromise = Promise$1.resolve(true);\n if ('_support' in driverObject) {\n if (driverObject._support && typeof driverObject._support === 'function') {\n supportPromise = driverObject._support();\n } else {\n supportPromise = Promise$1.resolve(!!driverObject._support);\n }\n }\n\n supportPromise.then(function (supportResult) {\n driverSupport[driverName] = supportResult;\n CustomDrivers[driverName] = driverObject;\n resolve();\n }, reject);\n } catch (e) {\n reject(e);\n }\n });\n\n executeTwoCallbacks(promise, callback, errorCallback);\n return promise;\n };\n\n LocalForage.prototype.driver = function driver() {\n return this._driver || null;\n };\n\n LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) {\n var self = this;\n var getDriverPromise = Promise$1.resolve().then(function () {\n if (isLibraryDriver(driverName)) {\n switch (driverName) {\n case self.INDEXEDDB:\n return asyncStorage;\n case self.LOCALSTORAGE:\n return localStorageWrapper;\n case self.WEBSQL:\n return webSQLStorage;\n }\n } else if (CustomDrivers[driverName]) {\n return CustomDrivers[driverName];\n } else {\n throw new Error('Driver not found.');\n }\n });\n executeTwoCallbacks(getDriverPromise, callback, errorCallback);\n return getDriverPromise;\n };\n\n LocalForage.prototype.getSerializer = function getSerializer(callback) {\n var serializerPromise = Promise$1.resolve(localforageSerializer);\n executeTwoCallbacks(serializerPromise, callback);\n return serializerPromise;\n };\n\n LocalForage.prototype.ready = function ready(callback) {\n var self = this;\n\n var promise = self._driverSet.then(function () {\n if (self._ready === null) {\n self._ready = self._initDriver();\n }\n\n return self._ready;\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n };\n\n LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) {\n var self = this;\n\n if (!isArray(drivers)) {\n drivers = [drivers];\n }\n\n var supportedDrivers = this._getSupportedDrivers(drivers);\n\n function setDriverToConfig() {\n self._config.driver = self.driver();\n }\n\n function extendSelfWithDriver(driver) {\n self._extend(driver);\n setDriverToConfig();\n\n self._ready = self._initStorage(self._config);\n return self._ready;\n }\n\n function initDriver(supportedDrivers) {\n return function () {\n var currentDriverIndex = 0;\n\n function driverPromiseLoop() {\n while (currentDriverIndex < supportedDrivers.length) {\n var driverName = supportedDrivers[currentDriverIndex];\n currentDriverIndex++;\n\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(extendSelfWithDriver)[\"catch\"](driverPromiseLoop);\n }\n\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n }\n\n return driverPromiseLoop();\n };\n }\n\n // There might be a driver initialization in progress\n // so wait for it to finish in order to avoid a possible\n // race condition to set _dbInfo\n var oldDriverSetDone = this._driverSet !== null ? this._driverSet[\"catch\"](function () {\n return Promise$1.resolve();\n }) : Promise$1.resolve();\n\n this._driverSet = oldDriverSetDone.then(function () {\n var driverName = supportedDrivers[0];\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(function (driver) {\n self._driver = driver._driver;\n setDriverToConfig();\n self._wrapLibraryMethodsWithReady();\n self._initDriver = initDriver(supportedDrivers);\n });\n })[\"catch\"](function () {\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n });\n\n executeTwoCallbacks(this._driverSet, callback, errorCallback);\n return this._driverSet;\n };\n\n LocalForage.prototype.supports = function supports(driverName) {\n return !!driverSupport[driverName];\n };\n\n LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) {\n extend(this, libraryMethodsAndProperties);\n };\n\n LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) {\n var supportedDrivers = [];\n for (var i = 0, len = drivers.length; i < len; i++) {\n var driverName = drivers[i];\n if (this.supports(driverName)) {\n supportedDrivers.push(driverName);\n }\n }\n return supportedDrivers;\n };\n\n LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() {\n // Add a stub for each driver API method that delays the call to the\n // corresponding driver method until localForage is ready. These stubs\n // will be replaced by the driver methods as soon as the driver is\n // loaded, so there is no performance impact.\n for (var i = 0; i < LibraryMethods.length; i++) {\n callWhenReady(this, LibraryMethods[i]);\n }\n };\n\n LocalForage.prototype.createInstance = function createInstance(options) {\n return new LocalForage(options);\n };\n\n return LocalForage;\n}();\n\n// The actual localForage object that we expose as a module or via a\n// global. It's extended by pulling in one of our other libraries.\n\n\nvar localforage_js = new LocalForage();\n\nmodule.exports = localforage_js;\n\n},{\"3\":3}]},{},[4])(4)\n});","module.exports = require('./lib/type');\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n '[object Array]': 'array'\n , '[object RegExp]': 'regexp'\n , '[object Function]': 'function'\n , '[object Arguments]': 'arguments'\n , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n var str = Object.prototype.toString.call(obj);\n if (natives[str]) return natives[str];\n if (obj === null) return 'null';\n if (obj === undefined) return 'undefined';\n if (obj === Object(obj)) return 'object';\n return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n // Let \"new String('')\" return 'object'\n if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n // PhantomJS has type \"DOMWindow\" for null\n if (obj === null) return 'null';\n // PhantomJS has type \"DOMWindow\" for undefined\n if (obj === undefined) return 'undefined';\n return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n if (!(this instanceof Library)) return new Library();\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","(function (document, window) {\n // DEPENDENCIES\n // ============================================================\n\n const localforage = require('localforage');\n const probs = require('pjs-problems');\n const dedent = require('dedent');\n const assert = require('chai').assert;\n\n // PROBLEM TEMPLATE NICE-IFICATION\n // ============================================================\n\n function dedentStrings(problems) {\n return problems.map(prob => {\n prob.given = dedent(prob.given)\n prob.answer = dedent(prob.answer)\n return prob\n });\n }\n\n\n // PROBLEMS\n // ============================================================\n\n let problems = [];\n Object.keys(probs).forEach(subject => {\n problems.push(...probs[subject]);\n });\n problems = dedentStrings(problems)\n console.log('problems:', problems);\n\n\n\n // CONFIG\n // ============================================================\n\n // Hoist current problem\n let currentProblem;\n // Keys to ignore while user is navigating around the textarea but not changing any code\n const ignoreKeyCodes = [\n 9, // Tab\n 37, // Left arrow\n 39, // Right arrow\n 38, // Up arrow\n 40 // Down arrow\n ];\n\n let config = {\n shuffle: true,\n timer: false,\n currentIndex: 0\n };\n\n // Pull config from localforage\n localforage\n .getItem('js_practice_config')\n .then(val => {\n console.log('localforage val:', val);\n if (val) {\n config = val;\n }\n loadApp(config);\n })\n .catch(err => {\n console.log('localforage err:', err);\n loadApp(config);\n });\n\n function updateLocalstore(config) {\n return localforage\n .setItem('js_practice_config', config)\n .then(val => {\n console.log('Settings updated:', val);\n })\n .catch(err => {\n console.log('Settings update error:', err);\n });\n }\n\n\n // UI\n // ============================================================\n\n // elements\n const problemEl = document.getElementById('problem');\n const codeEl = document.getElementById('code');\n const testSuiteEl = document.getElementById('test-suite');\n const testTotalEl = document.getElementById('test-total');\n const evalConsoleEl = document.getElementById('eval-output');\n const assertConsoleEl = document.getElementById('assert-output');\n const shuffleProblemsButtonEl = document.getElementById('shuffle-problems');\n const previousProblemButtonEl = document.getElementById('prev-problem');\n const nextProblemButtonEl = document.getElementById('next-problem');\n\n // Get indexes\n function getRandomIndex(problemsArr) {\n const ind = Math.floor(Math.random() * problemsArr.length);\n config.currentIndex = ind;\n updateLocalstore(config);\n return ind;\n }\n\n function getPreviousIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at beginning, go to end\n if (currentIndex === 0) {\n probInd = problemsArr.length - 1;\n } else {\n probInd = currentIndex - 1;\n }\n return probInd;\n }\n\n function getNextIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at end or invalid, restart series\n if (currentIndex >= problemsArr.length - 1 || currentIndex < 0) {\n probInd = 0;\n } else {\n probInd = currentIndex + 1;\n }\n return probInd;\n }\n\n // Get problems\n function getCurrentProblem(problemsArr) {\n return problemsArr[config.currentIndex];\n }\n\n function previousProblem() {\n console.log('previousProblem!');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getPreviousIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function nextProblem() {\n console.log('nextProblem!');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getNextIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function toggleShuffle() {\n console.log('toggle shuffle!');\n config.shuffle = !config.shuffle; // Flip it\n shuffleProblemsButtonEl.classList.toggle('active');\n updateLocalstore(config);\n }\n\n function loadProblem(problemObj) {\n currentProblem = problemObj;\n // Prob question\n problemEl.innerText = problemObj.prompt;\n // Prob given code\n if (problemObj.given) {\n codeEl.value = problemObj.given;\n }\n // Seed the tests, pass (init = true) as second param\n testSuite(null, true);\n }\n\n function updateTests(testStatus, init) {\n if (init === true) {\n buildTests(currentProblem.tests);\n }\n updateTestStatus(testStatus);\n }\n\n function buildTests(tests) {\n if (tests) {\n const testsDom = tests\n .map(test => {\n return `
\n
[✘]
\n
${test.name}
\n
`;\n })\n .join('');\n testSuiteEl.innerHTML = testsDom;\n }\n }\n\n function updateTestStatus(testStatuses) {\n if (!testStatuses) {\n throw new Error('No testStatuses provided.');\n }\n // Find out if all tests have passed or not\n let allPassed = true;\n testStatuses.forEach(testPassed => {\n if (testPassed !== true) {\n allPassed = false;\n }\n });\n const testEls = Array.from(testSuiteEl.querySelectorAll('.test-state'));\n testEls.forEach((testStatusEl, iter) => {\n if (testStatuses[iter] === true) {\n testStatusEl.innerHTML = '[✓]';\n testStatusEl.classList.remove('fail');\n testStatusEl.classList.add('pass');\n } else {\n testStatusEl.innerHTML = '[✘]';\n testStatusEl.classList.remove('pass');\n testStatusEl.classList.add('fail');\n }\n });\n\n if (allPassed === true) {\n testTotalEl.innerText = 'PASS';\n testTotalEl.classList.remove('fail');\n testTotalEl.classList.add('pass');\n } else {\n testTotalEl.innerText = 'FAIL';\n testTotalEl.classList.remove('pass');\n testTotalEl.classList.add('fail');\n }\n }\n\n function printAssertError(errObj) {\n // Make element string\n let inner = '';\n if (errObj !== null) {\n inner = `\n
\n Expected: ${JSON.stringify(errObj.expected)}\n Actual: ${JSON.stringify(errObj.actual)}\n
`;\n }\n\n // Prepend element\n assertConsoleEl.innerHTML = inner;\n }\n\n function printEvalOutput(errObj, output) {\n // Make element string\n let inner = '';\n if (errObj && errObj.message !== undefined) {\n inner = `\n
\n Syntax Error: ${JSON.stringify(errObj.message)}\n
`;\n } else if (output) {\n inner = `\n
\n Output: ${JSON.stringify(output)}\n
`;\n }\n // Prepend element\n evalConsoleEl.innerHTML = inner;\n }\n\n\n // VERIFICATION LOGIC\n // ============================================================\n\n function testSuite(init) {\n // Run stuff\n const output = getOutput(codeEl.value);\n // Run tests on code, return object/array of test results\n const tested = runTests(output);\n // Update UI with results\n updateTests(tested, init);\n }\n\n function getOutput(code) {\n let evald = false;\n try {\n evald = eval(`(function(){${code}})()`); // eslint-disable-line no-eval\n printEvalOutput(null, evald); // Print current output\n } catch (err) {\n printEvalOutput(err);\n }\n return evald;\n }\n\n function runTests(output) {\n let tested = false;\n tested = currentProblem.tests.map(test => {\n let testOutcome = false;\n try {\n if (output) {\n // const testEval = eval(test.test);\n\n testOutcome = eval(test.test);\n console.log('testOutcome:', testOutcome);\n\n }\n printAssertError(null);\n } catch (err) {\n printAssertError(err);\n }\n return testOutcome;\n });\n return tested;\n }\n\n // Wrapped to prevent race with local config retrieval\n function loadApp(config) {\n console.log('loading app!');\n\n // Show current toggle state\n if (config.shuffle === true) {\n shuffleProblemsButtonEl.classList.add('active');\n }\n\n // Bind it up\n codeEl.addEventListener('keyup', e => {\n // If not arrow keys or other non-character keys\n if (ignoreKeyCodes.indexOf(e.keyCode) === -1) {\n // Run test suite\n testSuite();\n }\n });\n shuffleProblemsButtonEl.addEventListener('click', toggleShuffle);\n previousProblemButtonEl.addEventListener('click', previousProblem);\n nextProblemButtonEl.addEventListener('click', nextProblem);\n\n // Start it up!\n // Load current problem\n const currProb = getCurrentProblem(problems);\n loadProblem(currProb);\n // Initalized test suite with starting failures\n testSuite(true);\n }\n})(document, window);\n"],"preExistingComment":"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2Jyb3dzZXItcGFjay82LjAuMi9ub2RlX21vZHVsZXMvYnJvd3Nlci1wYWNrL19wcmVsdWRlLmpzIiwibm9kZV9tb2R1bGVzLy5naXRodWIuY29tL3ByYWN0aWNlamF2YXNjcmlwdC9wanMtcHJvYmxlbXMvMDgyM2NjMWNmZmI5OTkzNTJlM2YwY2FlZDI5NWRmODYzM2YxMzkxNi9ub2RlX21vZHVsZXMvcGpzLXByb2JsZW1zL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzLy5naXRodWIuY29tL3ByYWN0aWNlamF2YXNjcmlwdC9wanMtcHJvYmxlbXMvMDgyM2NjMWNmZmI5OTkzNTJlM2YwY2FlZDI5NWRmODYzM2YxMzkxNi9ub2RlX21vZHVsZXMvcGpzLXByb2JsZW1zL3Byb2JsZW1zL2FycmF5cy5qcyIsIm5vZGVfbW9kdWxlcy8uZ2l0aHViLmNvbS9wcmFjdGljZWphdmFzY3JpcHQvcGpzLXByb2JsZW1zLzA4MjNjYzFjZmZiOTk5MzUyZTNmMGNhZWQyOTVkZjg2MzNmMTM5MTYvbm9kZV9tb2R1bGVzL3Bqcy1wcm9ibGVtcy9wcm9ibGVtcy9pbml0aWFsLmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvYXNzZXJ0aW9uLWVycm9yLzEuMC4yL25vZGVfbW9kdWxlcy9hc3NlcnRpb24tZXJyb3IvaW5kZXguanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvYXNzZXJ0aW9uLmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS9jb25maWcuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL2NvcmUvYXNzZXJ0aW9ucy5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvaW50ZXJmYWNlL2Fzc2VydC5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvaW50ZXJmYWNlL2V4cGVjdC5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvaW50ZXJmYWNlL3Nob3VsZC5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvYWRkQ2hhaW5hYmxlTWV0aG9kLmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9hZGRNZXRob2QuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2FkZFByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9leHBlY3RUeXBlcy5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZmxhZy5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0QWN0dWFsLmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9nZXRFbnVtZXJhYmxlUHJvcGVydGllcy5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0TWVzc2FnZS5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0TmFtZS5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0UGF0aEluZm8uanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2dldFBhdGhWYWx1ZS5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0UHJvcGVydGllcy5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvaGFzUHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9pbnNwZWN0LmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9vYmpEaXNwbGF5LmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL292ZXJ3cml0ZU1ldGhvZC5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvb3ZlcndyaXRlUHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL3Rlc3QuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL3RyYW5zZmVyRmxhZ3MuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9kZWRlbnQvMC43LjAvbm9kZV9tb2R1bGVzL2RlZGVudC9kaXN0L2RlZGVudC5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2RlZXAtZXFsLzAuMS4zL25vZGVfbW9kdWxlcy9kZWVwLWVxbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2RlZXAtZXFsLzAuMS4zL25vZGVfbW9kdWxlcy9kZWVwLWVxbC9saWIvZXFsLmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvbG9jYWxmb3JhZ2UvMS41LjAvbm9kZV9tb2R1bGVzL2xvY2FsZm9yYWdlL2Rpc3Qvbm9kZV9tb2R1bGVzL2xvY2FsZm9yYWdlL2Rpc3QvbG9jYWxmb3JhZ2UuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy90eXBlLWRldGVjdC8wLjEuMS9ub2RlX21vZHVsZXMvdHlwZS1kZXRlY3QvaW5kZXguanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy90eXBlLWRldGVjdC8wLjEuMS9ub2RlX21vZHVsZXMvdHlwZS1kZXRlY3QvbGliL3R5cGUuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy90eXBlLWRldGVjdC8xLjAuMC9ub2RlX21vZHVsZXMvdHlwZS1kZXRlY3QvbGliL3R5cGUuanMiLCJzcmMvanMvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFlQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSEE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25JQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwMERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN21EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9VQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3REQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNEQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDalFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3h3RUE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDOUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0FDdElBLENBQUMsVUFBVSxRQUFWLEVBQW9CLE1BQXBCLEVBQTRCO0FBQzNCO0FBQ0E7O0FBRUEsTUFBTSxjQUFjLFFBQVEsYUFBUixDQUFwQjtBQUNBLE1BQU0sUUFBUSxRQUFRLGNBQVIsQ0FBZDtBQUNBLE1BQU0sU0FBUyxRQUFRLFFBQVIsQ0FBZjtBQUNBLE1BQU0sU0FBUyxRQUFRLE1BQVIsRUFBZ0IsTUFBL0I7O0FBRUE7QUFDQTs7QUFFQSxXQUFTLGFBQVQsQ0FBdUIsUUFBdkIsRUFBaUM7QUFDL0IsV0FBTyxTQUFTLEdBQVQsQ0FBYSxnQkFBUTtBQUMxQixXQUFLLEtBQUwsR0FBYSxPQUFPLEtBQUssS0FBWixDQUFi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QSxXQUFPLGdCQUFQLENBQXdCLE9BQXhCLEVBQWlDLGFBQUs7QUFDcEM7QUFDQSxVQUFJLGVBQWUsT0FBZixDQUF1QixFQUFFLE9BQXpCLE1BQXNDLENBQUMsQ0FBM0MsRUFBOEM7QUFDNUM7QUFDQTtBQUNEO0FBQ0YsS0FORDtBQU9BLDRCQUF3QixnQkFBeEIsQ0FBeUMsT0FBekMsRUFBa0QsYUFBbEQ7QUFDQSw0QkFBd0IsZ0JBQXhCLENBQXlDLE9BQXpDLEVBQWtELGVBQWxEO0FBQ0Esd0JBQW9CLGdCQUFwQixDQUFxQyxPQUFyQyxFQUE4QyxXQUE5Qzs7QUFFQTtBQUNBO0FBQ0EsUUFBTSxXQUFXLGtCQUFrQixRQUFsQixDQUFqQjtBQUNBLGdCQUFZLFFBQVo7QUFDQTtBQUNBLGNBQVUsSUFBVjtBQUNEO0FBQ0YsQ0E1VUQsRUE0VUcsUUE1VUgsRUE0VWEsTUE1VWIiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIGluaXRpYWw6IHJlcXVpcmUoJy4vcHJvYmxlbXMvaW5pdGlhbCcpLFxuICBhcnJheXM6IHJlcXVpcmUoJy4vcHJvYmxlbXMvYXJyYXlzJylcbn07IiwibW9kdWxlLmV4cG9ydHMgPSBbXG4gIHtcbiAgICBuYW1lOiAnQWNjZXNzIEFycmF5IGJ5IGluZGV4IChmaXJzdCknLFxuICAgIHRpbWU6IDEwLFxuICAgIHByb21wdDogJ1JldHVybiB0aGUgZmlyc3QgdmFsdWUgb2YgdGhlIEFycmF5JyxcbiAgICBnaXZlbjogYGNvbnN0IGZydWl0cyA9IFsnYXBwbGUnLCAnYmFuYW5hJ107XFxyYCxcbiAgICBhbnN3ZXI6IGBjb25zdCBmcnVpdHMgPSBbJ2FwcGxlJywgJ2JhbmFuYSddO1xuICAgICAgICAgICAgIHJldHVybiBmcnVpdHNbMF07YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiAnYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXQsIFxcJ2FwcGxlXFwnKSA9PT0gdW5kZWZpbmVkJ1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ1JldHVybnMgYSBTdHJpbmcnLFxuICAgICAgICB0ZXN0OiAnYXNzZXJ0LmlzU3RyaW5nKG91dHB1dCkgPT09IHVuZGVmaW5lZCdcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQWNjZXNzIEFycmF5IGJ5IGluZGV4IChsYXN0KScsXG4gICAgdGltZTogMTAsXG4gICAgcHJvbXB0OiAnUmV0dXJuIHRoZSBsYXN0IHZhbHVlIG9mIHRoZSBBcnJheScsXG4gICAgZ2l2ZW46IGBjb25zdCBmcnVpdHMgPSBbJ2FwcGxlJywgJ2JhbmFuYScsICdvcmFuZ2UnXTtcXHJgLFxuICAgIGFuc3dlcjogYGNvbnN0IGZydWl0cyA9IFsnYXBwbGUnLCAnYmFuYW5hJywgJ29yYW5nZSddO1xuICAgICAgICAgICAgIHJldHVybiBmcnVpdHNbZnJ1aXRzLmxlbmd0aCAtIDFdO2AsXG4gICAgdGVzdHM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0NvcnJlY3Qgb3V0cHV0JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCAnb3JhbmdlJykgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnUmV0dXJucyBhIFN0cmluZycsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuaXNTdHJpbmcob3V0cHV0KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQWNjZXNzIEFycmF5IGJ5IGluZGV4IChzZWNvbmQpJyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6ICdSZXR1cm4gdGhlIHNlY29uZCB2YWx1ZSBvZiB0aGUgQXJyYXknLFxuICAgIGdpdmVuOiBgY29uc3QgZnJ1aXRzID0gWydhcHBsZScsICdiYW5hbmEnXTtcXHJgLFxuICAgIGFuc3dlcjogYGNvbnN0IGZydWl0cyA9IFsnYXBwbGUnLCAnYmFuYW5hJ107XG4gICAgICAgICAgICAgcmV0dXJuIGZydWl0c1sxXTtgLFxuICAgIHRlc3RzOiBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdDb3JyZWN0IG91dHB1dCcsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuZGVlcEVxdWFsKG91dHB1dCwgJ2JhbmFuYScpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ1JldHVybnMgYSBTdHJpbmcnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzU3RyaW5nKG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9XG4gICAgXVxuICB9LFxuICB7XG4gICAgbmFtZTogJ0FycmF5LmZvckVhY2goKScsXG4gICAgdGltZTogMjAsXG4gICAgcHJvbXB0OiAnTG9vcCBvdmVyIHRoZSBhcnJheSwgYWRkIGFuIFxcJ3hcXCcgdG8gdGhlIGVuZCBvZiBlYWNoIG5hbWUsIHB1c2ggZWFjaCBmcnVpdCBpbnRvIGEgbmV3IGFycmF5LCB0aGVuIHJldHVybiB0aGUgbmV3IGFycmF5LicsXG4gICAgZ2l2ZW46IGBjb25zdCBmcnVpdHMgPSBbJ2FwcGxlJywgJ2JhbmFuYSddO1xccmAsXG4gICAgYW5zd2VyOiBgY29uc3QgZnJ1aXRzID0gWydhcHBsZScsICdiYW5hbmEnXTtcbiAgICAgICAgICAgICBjb25zdCBuZXdGcnVpdHMgPSBbXTtcbiAgICAgICAgICAgICBmcnVpdHMuZm9yRWFjaChmdW5jdGlvbihpdGVtKSB7XG4gICAgICAgICAgICAgICBuZXdGcnVpdHMucHVzaChpdGVtKyd4Jyk7XG4gICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgcmV0dXJuIG5ld0ZydWl0cztgLFxuICAgIHRlc3RzOiBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdDb3JyZWN0IG91dHB1dCcsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuZGVlcEVxdWFsKG91dHB1dCwgWydhcHBsZXgnLCAnYmFuYW5heCddKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGFuIEFycmF5JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc0FycmF5KG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnQXJyYXkgaGFzIDIgaXRlbXMnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0Lmxlbmd0aE9mKG91dHB1dCwgMikgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9XG4gICAgXVxuICB9LFxuICB7XG4gICAgbmFtZTogJ0FycmF5LnB1c2goKScsXG4gICAgdGltZTogMTAsXG4gICAgcHJvbXB0OiBgQWRkICdvcmFuZ2UnIHRvIHRoZSBlbmQgb2YgdGhlICdmcnVpdHMnIGFycmF5IGFuZCByZXR1cm4gJ2ZydWl0cycuYCxcbiAgICBnaXZlbjogYGNvbnN0IGZydWl0cyA9IFsnYXBwbGUnLCAnYmFuYW5hJ107XFxyYCxcbiAgICBhbnN3ZXI6IGBjb25zdCBmcnVpdHMgPSBbJ2FwcGxlJywgJ2JhbmFuYSddO1xuICAgICAgICAgICAgIGZydWl0cy5wdXNoKCdvcmFuZ2UnKTtcbiAgICAgICAgICAgICByZXR1cm4gZnJ1aXRzO2AsXG4gICAgdGVzdHM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0NvcnJlY3Qgb3V0cHV0JyxcbiAgICAgICAgdGVzdDogYChhc3NlcnQuZGVlcEVxdWFsKG91dHB1dCwgWydhcHBsZScsICdiYW5hbmEnLCAnb3JhbmdlJ10pID09PSB1bmRlZmluZWQpO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGFuIEFycmF5JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc0FycmF5KG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnQXJyYXkgaGFzIDMgaXRlbXMnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0Lmxlbmd0aE9mKG91dHB1dCwgMykgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9XG4gICAgXVxuICB9LFxuICB7XG4gICAgbmFtZTogJ0FycmF5LnNoaWZ0KCknLFxuICAgIHRpbWU6IDEwLFxuICAgIHByb21wdDogYFJlbW92ZSAnYXBwbGUnIGZyb20gdGhlIGZyb250IG9mIHRoZSAnZnJ1aXRzJyBhcnJheSBhbmQgcmV0dXJuICdmcnVpdHMnLmAsXG4gICAgZ2l2ZW46IGBjb25zdCBmcnVpdHMgPSBbJ2FwcGxlJywgJ2JhbmFuYScsICdvcmFuZ2UnXTtcXHJgLFxuICAgIGFuc3dlcjogYGNvbnN0IGZydWl0cyA9IFsnYXBwbGUnLCAnYmFuYW5hJywgJ29yYW5nZSddO1xuICAgICAgICAgICAgIGZydWl0cy5zaGlmdCgpO1xuICAgICAgICAgICAgIHJldHVybiBmcnVpdHM7YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnT3V0cHV0IG11c3QgYmUgY29ycmVjdCcsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuZGVlcEVxdWFsKG91dHB1dCwgWydiYW5hbmEnLCAnb3JhbmdlJ10pID09PSB1bmRlZmluZWQ7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ1JldHVybnMgYW4gQXJyYXknLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzQXJyYXkob3V0cHV0KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdBcnJheSBoYXMgMiBpdGVtcycsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQubGVuZ3RoT2Yob3V0cHV0LCAyKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQXJyYXkudW5zaGlmdCgpJyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6IGBBZGQgJ3N0cmF3YmVycnknIHRvIHRoZSBmcm9udCBvZiB0aGUgJ2ZydWl0cycgYXJyYXkgYW5kIHJldHVybiAnZnJ1aXRzJy5gLFxuICAgIGdpdmVuOiBgY29uc3QgZnJ1aXRzID0gWydhcHBsZScsICdiYW5hbmEnLCAnb3JhbmdlJ107XFxyYCxcbiAgICBhbnN3ZXI6IGBjb25zdCBmcnVpdHMgPSBbJ2FwcGxlJywgJ2JhbmFuYScsICdvcmFuZ2UnXTtcbiAgICAgICAgICAgICBmcnVpdHMudW5zaGlmdCgnc3RyYXdiZXJyeScpO1xuICAgICAgICAgICAgIHJldHVybiBmcnVpdHM7YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnT3V0cHV0IG11c3QgYmUgY29ycmVjdCcsXG4gICAgICAgIHRlc3Q6IGAoYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXQsIFtcbiAgICAgICAgICAgICAgICAgICdzdHJhd2JlcnJ5JyxcbiAgICAgICAgICAgICAgICAgICdhcHBsZScsXG4gICAgICAgICAgICAgICAgICAnYmFuYW5hJyxcbiAgICAgICAgICAgICAgICAgICdvcmFuZ2UnXG4gICAgICAgICAgICAgICAgXSkgPT09IHVuZGVmaW5lZClgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnTXVzdCByZXR1cm4gYW4gQXJyYXknLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzQXJyYXkob3V0cHV0KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdBcnJheSBoYXMgNCBpdGVtcycsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQubGVuZ3RoT2Yob3V0cHV0LCA0KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQXJyYXkuaW5kZXhPZigpJyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6IGBSZXR1cm4gdGhlIGluZGV4IG9mICdiYW5hbmEnIGluIHRoZSBBcnJheS5gLFxuICAgIGdpdmVuOiBgY29uc3QgZnJ1aXRzID0gWydzdHJhd2JlcnJ5JywgJ2JhbmFuYScsICdtYW5nbyddO1xccmAsXG4gICAgYW5zd2VyOiBgY29uc3QgZnJ1aXRzID0gWydzdHJhd2JlcnJ5JywgJ2JhbmFuYScsICdtYW5nbyddO1xuICAgICAgICAgICAgIGNvbnN0IGluZCA9IGZydWl0cy5pbmRleE9mKCdiYW5hbmEnKTtcbiAgICAgICAgICAgICByZXR1cm4gaW5kO2AsXG4gICAgdGVzdHM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0NvcnJlY3Qgb3V0cHV0JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCAxKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGEgTnVtYmVyJyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc051bWJlcihvdXRwdXQpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIG5hbWU6ICdBcnJheS5jb25jYXQoKScsXG4gICAgdGltZTogMTAsXG4gICAgcHJvbXB0OiBgTWVyZ2UgdGhlIHR3byBhcnJheXMgdXNpbmcgQXJyYXkncyAnY29uY2F0KCknIG1ldGhvZC4gUmV0dXJuIHRoZSByZXN1bHRpbmcgYXJyYXkuYCxcbiAgICBnaXZlbjogYGNvbnN0IGZydWl0cyA9IFsnc3RyYXdiZXJyeScsICdiYW5hbmEnXTtcXHJjb25zdCBvdGhlckZydWl0cyA9IFsncGVhcicsJ3BlYWNoJ107XFxyYCxcbiAgICBhbnN3ZXI6IGBjb25zdCBmcnVpdHMgPSBbJ3N0cmF3YmVycnknLCAnYmFuYW5hJ107XG4gICAgICAgICAgICBjb25zdCBvdGhlckZydWl0cyA9IFsncGVhcicsJ3BlYWNoJ107XG4gICAgICAgICAgICBjb25zdCBhbGxUaGVGcnVpdHMgPSBmcnVpdHMuY29uY2F0KG90aGVyRnJ1aXRzKTtcbiAgICAgICAgICAgIHJldHVybiBhbGxUaGVGcnVpdHM7XFxyYCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiBgKGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCBbXG4gICAgICAgICAgICAgICAgICAnc3RyYXdiZXJyeScsXG4gICAgICAgICAgICAgICAgICAnYmFuYW5hJyxcbiAgICAgICAgICAgICAgICAgICdwZWFyJyxcbiAgICAgICAgICAgICAgICAgICdwZWFjaCdcbiAgICAgICAgICAgICAgICBdKSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICk7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ1JldHVybnMgYW4gQXJyYXknLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzQXJyYXkob3V0cHV0KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdBcnJheSBoYXMgNCBpdGVtcycsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQubGVuZ3RoT2Yob3V0cHV0LCA0KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQXJyYXkuam9pbigpJyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6IGBNaXggdGhlIHR3byBmbGF2b3JzIHdpdGggYSAnLScgdXNpbmcgQXJyYXkncyAnam9pbicgbWV0aG9kLiBSZXR1cm4gdGhlIHJlc3VsdGluZyBoeWJyaWQgZmxhdm9yLmAsXG4gICAgZ2l2ZW46IGBjb25zdCBmcnVpdHMgPSBbJ3N0cmF3YmVycnknLCAnYmFuYW5hJ107XFxyYCxcbiAgICBhbnN3ZXI6IGBjb25zdCBmcnVpdHMgPSBbJ3N0cmF3YmVycnknLCAnYmFuYW5hJ107XG4gICAgICAgICAgICAgY29uc3QgaHlicmlkID0gZnJ1aXRzLmpvaW4oJy0nKTtcbiAgICAgICAgICAgICByZXR1cm4gaHlicmlkO1xccmAsXG4gICAgdGVzdHM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0NvcnJlY3Qgb3V0cHV0JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCAnc3RyYXdiZXJyeS1iYW5hbmEnKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGEgU3RyaW5nJyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc1N0cmluZyhvdXRwdXQpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIG5hbWU6ICdBcnJheS5zbGljZSgpJyxcbiAgICB0aW1lOiAyMCxcbiAgICBwcm9tcHQ6IGBSZXR1cm4ganVzdCB0aGUgY2l0cnVzIGZydWl0cyBmcm9tIHRoZSAnZnJ1aXRzJyBhcnJheSB1c2luZyAnQXJyYXkuc2xpY2UoKSdgLFxuICAgIGdpdmVuOiBgY29uc3QgZnJ1aXRzID0gWydzdHJhd2JlcnJ5JywgJ29yYW5nZScsICdsZW1vbicsICdiYW5hbmEnXTtcXHJgLFxuICAgIGFuc3dlcjogYGNvbnN0IGZydWl0cyA9IFsnc3RyYXdiZXJyeScsICdvcmFuZ2UnLCAnbGVtb24nLCAnYmFuYW5hJ107XG4gICAgICAgICAgICAgY29uc3QgY2l0cnVzID0gZnJ1aXRzLnNsaWNlKDEsIDMpO1xuICAgICAgICAgICAgIHJldHVybiBjaXRydXM7YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXQsIFsnb3JhbmdlJywgJ2xlbW9uJ10pID09PSB1bmRlZmluZWQ7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ1JldHVybnMgYW4gQXJyYXknLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzQXJyYXkob3V0cHV0KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdBcnJheSBoYXMgMiBpdGVtcycsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQubGVuZ3RoT2Yob3V0cHV0LCAyKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQXJyYXkucmV2ZXJzZSgpJyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6IGBSZXZlcnNlIHRoZSBvcmRlciBvZiB0aGUgJ2ZydWl0JyBhcnJheSB1c2luZyAnQXJyYXkucmV2ZXJzZSgpJ2AsXG4gICAgZ2l2ZW46IGBjb25zdCBmcnVpdHMgPSBbJ3N0cmF3YmVycnknLCAnb3JhbmdlJywgJ2xlbW9uJywgJ2JhbmFuYSddO1xccmAsXG4gICAgYW5zd2VyOiBgY29uc3QgZnJ1aXRzID0gWydzdHJhd2JlcnJ5JywgJ29yYW5nZScsICdsZW1vbicsICdiYW5hbmEnXTtcbiAgICAgICAgICAgICBjb25zdCBzdGl1cmYgPSBmcnVpdHMucmV2ZXJzZSgpO1xuICAgICAgICAgICAgIHJldHVybiBzdGl1cmY7YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiBgKGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCBbXG4gICAgICAgICAgICAgICAgICAnYmFuYW5hJyxcbiAgICAgICAgICAgICAgICAgICdsZW1vbicsXG4gICAgICAgICAgICAgICAgICAnb3JhbmdlJyxcbiAgICAgICAgICAgICAgICAgICdzdHJhd2JlcnJ5J1xuICAgICAgICAgICAgICAgIF0pID09PSB1bmRlZmluZWQpO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGFuIEFycmF5JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc0FycmF5KG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnQXJyYXkgaGFzIDQgaXRlbXMnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0Lmxlbmd0aE9mKG91dHB1dCwgNCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiBgRmlyc3QgaXRlbSBpcyAnYmFuYW5hJ2AsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuZGVlcEVxdWFsKG91dHB1dFswXSwgJ2JhbmFuYScpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIG5hbWU6ICdBcnJheS5zb3J0KCknLFxuICAgIHRpbWU6IDEwLFxuICAgIHByb21wdDogYFJldHVybiB0aGUgJ2ZydWl0cycgQXJyYXkgYWZ0ZXIgc29ydGluZyB0aGVtIHVzaW5nICdBcnJheS5zb3J0KCknLmAsXG4gICAgZ2l2ZW46IGBjb25zdCBmcnVpdHMgPSBbJ3N0cmF3YmVycnknLCAnb3JhbmdlJywgJ2xlbW9uJywgJ2JhbmFuYSddO1xccmAsXG4gICAgYW5zd2VyOiBgY29uc3QgZnJ1aXRzID0gWydzdHJhd2JlcnJ5JywgJ29yYW5nZScsICdsZW1vbicsICdiYW5hbmEnXTtcbiAgICAgICAgICAgICBjb25zdCBvcmRlcmx5RnJ1aXQgPSBmcnVpdHMuc29ydCgpO1xuICAgICAgICAgICAgIHJldHVybiBvcmRlcmx5RnJ1aXQ7YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiBgKGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCBbXG4gICAgICAgICAgICAgICAgICAnYmFuYW5hJyxcbiAgICAgICAgICAgICAgICAgICdsZW1vbicsXG4gICAgICAgICAgICAgICAgICAnb3JhbmdlJyxcbiAgICAgICAgICAgICAgICAgICdzdHJhd2JlcnJ5J1xuICAgICAgICAgICAgICAgIF0pID09PSB1bmRlZmluZWQpO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGFuIEFycmF5JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc0FycmF5KG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnQXJyYXkgaGFzIDQgaXRlbXMnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0Lmxlbmd0aE9mKG91dHB1dCwgNCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiBgRmlyc3QgaXRlbSBpcyAnYmFuYW5hJ2AsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuZGVlcEVxdWFsKG91dHB1dFswXSwgJ2JhbmFuYScpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIG5hbWU6ICdBcnJheS5sYXN0SW5kZXhPZigpJyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6IGBSZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBsYXN0ICdwZWFjaCcgaW5zdGFuY2UgaW4gdGhlICdmcnVpdCcgYXJyYXkgdXNpbmcgJ0FycmF5Lmxhc3RJbmRleE9mKCknYCxcbiAgICBnaXZlbjogYGNvbnN0IGZydWl0cyA9IFsncGVhY2gnLCAnb3JhbmdlJywgJ2xlbW9uJywgJ3BlYWNoJ107XFxyYCxcbiAgICBhbnN3ZXI6IGBjb25zdCBmcnVpdHMgPSBbJ3BlYWNoJywgJ29yYW5nZScsICdsZW1vbicsICdwZWFjaCddO1xuICAgICAgICAgICAgIGNvbnN0IHdoZXJlc1RoZUxhc3RQZWFjaCA9IGZydWl0cy5sYXN0SW5kZXhPZigncGVhY2gnKTtcbiAgICAgICAgICAgICByZXR1cm4gd2hlcmVzVGhlTGFzdFBlYWNoO2AsXG4gICAgdGVzdHM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0NvcnJlY3Qgb3V0cHV0JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCAzKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGEgTnVtYmVyJyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc051bWJlcihvdXRwdXQpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIG5hbWU6ICdBcnJheS5maWx0ZXIoKScsXG4gICAgdGltZTogMTAsXG4gICAgcHJvbXB0OiBgUmV0dXJuIGFuIGFycmF5IG9mIHRoZSBudW1iZXJzIGdyZWF0ZXIgdGhhbiA1IGluICdudW1iZXJzJyB1c2luZyAnQXJyYXkuZmlsdGVyKCknYCxcbiAgICBnaXZlbjogYGNvbnN0IG51bWJlcnMgPSBbMSwgMSwgMiwgMywgNSwgOCwgMTMsIDIxXTtcXHJgLFxuICAgIGFuc3dlcjogYGNvbnN0IG51bWJlcnMgPSBbMSwgMSwgMiwgMywgNSwgOCwgMTMsIDIxXTtcbiAgICAgICAgICAgICBjb25zdCBvdmVyRml2ZSA9IG51bWJlcnMuZmlsdGVyKG51bSA9PiBudW0gPiA1KTtcbiAgICAgICAgICAgICByZXR1cm4gb3ZlckZpdmU7YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXQsIFs4LCAxMywgMjFdKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGFuIEFycmF5JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc0FycmF5KG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnQXJyYXkgaGFzIDMgaXRlbXMnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0Lmxlbmd0aE9mKG91dHB1dCwgMykgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiBgRmlyc3QgaXRlbSBpcyA4YCxcbiAgICAgICAgdGVzdDogYGFzc2VydC5kZWVwRXF1YWwob3V0cHV0WzBdLCA4KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQXJyYXkubWFwKCknLFxuICAgIHRpbWU6IDEwLFxuICAgIHByb21wdDogYFJldHVybiBhbiBhcnJheSBvZiAnbnVtYmVycycgYXJyYXkncyBzcXVhcmUgcm9vdHMsIHVzaW5nICdBcnJheS5tYXAoKScgYW5kICdNYXRoLnNxcnQoKSdgLFxuICAgIGdpdmVuOiBgY29uc3QgbnVtYmVycyA9IFsyNSwgMTIxLCAxNjldO1xccmAsXG4gICAgYW5zd2VyOiBgY29uc3QgbnVtYmVycyA9IFsyNSwgMTIxLCAxNjldO1xuICAgICAgICAgICAgIGNvbnN0IHJvb3RzID0gbnVtYmVycy5tYXAobnVtID0+IE1hdGguc3FydChudW0pKTtcbiAgICAgICAgICAgICByZXR1cm4gcm9vdHM7YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXQsIFs1LCAxMSwgMTNdKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGFuIEFycmF5JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc0FycmF5KG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnQXJyYXkgaGFzIDMgaXRlbXMnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0Lmxlbmd0aE9mKG91dHB1dCwgMykgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiBgRmlyc3QgaXRlbSBpcyA1YCxcbiAgICAgICAgdGVzdDogYGFzc2VydC5kZWVwRXF1YWwob3V0cHV0WzBdLCA1KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6IGBMYXN0IGl0ZW0gaXMgMTNgLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXRbb3V0cHV0Lmxlbmd0aCAtIDFdLCAxMykgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9XG4gICAgXVxuICB9LFxuICB7XG4gICAgbmFtZTogJ0FycmF5LmV2ZXJ5KCknLFxuICAgIHRpbWU6IDEwLFxuICAgIHByb21wdDogYFJldHVybiBvYmplY3QgdGhhdCByZXR1cm5zIHdoZXRoZXIgZWFjaCBhcnJheSBjb250YWlucyBhbGwgZXZlbiBudW1iZXJzIHVzaW5nIEFycmF5LmV2ZXJ5KCkuYCxcbiAgICBnaXZlbjogYGNvbnN0IGV2ZW5OdW1iZXJzID0gWzIsIDQsIDYsIDhdO1xuICAgICAgICAgICAgY29uc3Qgc29tZU9kZE51bWJlcnMgPSBbMiwgNSwgNiwgOF07XG4gICAgICAgICAgICBmdW5jdGlvbiBpc0V2ZW4oZWxlbWVudCkge1xuICAgICAgICAgICAgXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBldmVuTnVtYmVyczogZXZlbk51bWJlcnMuLFxuICAgICAgICAgICAgICBzb21lT2RkTnVtYmVyczogc29tZU9kZE51bWJlcnMuXG4gICAgICAgICAgICB9O2AsXG4gICAgYW5zd2VyOiBgY29uc3QgZXZlbk51bWJlcnMgPSBbMiwgNCwgNiwgOF07XG4gICAgICAgICAgICAgY29uc3Qgc29tZU9kZE51bWJlcnMgPSBbMiwgNSwgNiwgOF07XG4gICAgICAgICAgICAgZnVuY3Rpb24gaXNFdmVuKGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50ICUgMiA9PT0gMFxuICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgZXZlbk51bWJlcnM6IGV2ZW5OdW1iZXJzLmV2ZXJ5KGlzRXZlbiksXG4gICAgICAgICAgICAgICBzb21lT2RkTnVtYmVyczogc29tZU9kZE51bWJlcnMuZXZlcnkoaXNFdmVuKVxuICAgICAgICAgICAgIH07YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXQsIHtcbiAgICAgICAgICAgIGV2ZW5OdW1iZXJzOiB0cnVlLFxuICAgICAgICAgICAgc29tZU9kZE51bWJlcnM6IGZhbHNlXG4gICAgICAgICAgfSkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnUmV0dXJucyBhbiBPYmplY3QnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzT2JqZWN0KG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnT2JqZWN0IGhhcyAyIGl0ZW1zJyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5sZW5ndGhPZihPYmplY3Qua2V5cyhvdXRwdXQpLCAyKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6IGBGaXJzdCB2YWx1ZSBpcyB0cnVlYCxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc1RydWUob3V0cHV0LmV2ZW5OdW1iZXJzKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6IGBTZWNvbmQgdmFsdWUgaXMgZmFsc2VgLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzRmFsc2Uob3V0cHV0LnNvbWVPZGROdW1iZXJzKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQXJyYXkuc29tZSgpJyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6IGBSZXR1cm4gJ09iamVjdCcgdGhhdCByZXR1cm5zIHdoZXRoZXIgZWFjaCBhcnJheSBjb250YWlucyBzb21lIG9kZCBudW1iZXJzIHVzaW5nICdBcnJheS5zb21lKCknLmAsXG4gICAgZ2l2ZW46IGBjb25zdCBldmVuTnVtYmVycyA9IFsyLCA0LCA2LCA4XTtcbiAgICAgICAgICAgIGNvbnN0IHNvbWVPZGROdW1iZXJzID0gWzIsIDQsIDcsIDhdO1xuICAgICAgICAgICAgZnVuY3Rpb24gaXNPZGQoZWxlbWVudCkge1xuICAgICAgICAgICAgICBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGV2ZW5OdW1iZXJzOiBldmVuTnVtYmVycy4sXG4gICAgICAgICAgICAgIHNvbWVPZGROdW1iZXJzOiBzb21lT2RkTnVtYmVycy5cbiAgICAgICAgICAgIH07YCxcbiAgICBhbnN3ZXI6IGBjb25zdCBldmVuTnVtYmVycyA9IFsxLCAzLCA1LCA3XTtcbiAgICAgICAgICAgICBjb25zdCBzb21lT2RkTnVtYmVycyA9IFsxLCAzLCA2LCA3XTtcbiAgICAgICAgICAgICBmdW5jdGlvbiBpc09kZChlbGVtZW50KSB7XG4gICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudCAlIDIgIT09IDA7XG4gICAgICAgICAgICAgfVxuICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICBldmVuTnVtYmVyczogZXZlbk51bWJlcnMuc29tZShpc09kZCksXG4gICAgICAgICAgICAgICBzb21lT2RkTnVtYmVyczogc29tZU9kZE51bWJlcnMuc29tZShpc09kZClcbiAgICAgICAgICAgICB9O2AsXG4gICAgdGVzdHM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0NvcnJlY3Qgb3V0cHV0JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCB7XG4gICAgICAgICAgICBldmVuTnVtYmVyczogZmFsc2UsXG4gICAgICAgICAgICBzb21lT2RkTnVtYmVyczogdHJ1ZVxuICAgICAgICAgIH0pID09PSB1bmRlZmluZWQ7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ1JldHVybnMgYW4gT2JqZWN0JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc09iamVjdChvdXRwdXQpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ09iamVjdCBoYXMgMiBpdGVtcycsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQubGVuZ3RoT2YoT2JqZWN0LmtleXMob3V0cHV0KSwgMikgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiBgRmlyc3QgdmFsdWUgaXMgZmFsc2VgLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzRmFsc2Uob3V0cHV0LmV2ZW5OdW1iZXJzKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6IGBTZWNvbmQgdmFsdWUgaXMgdHJ1ZWAsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuaXNUcnVlKG91dHB1dC5zb21lT2RkTnVtYmVycykgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9XG4gICAgXVxuICB9XG4gIC8vIE5leHQgcHJvYmxlbXMgdG8gY3JlYXRlOlxuICAvLyBmb3JFYWNoPyBmaXggb25lIGFib3ZlIHRoYXQgdHJpZWQsIGJ1dCBjYW4ndCB2ZXJpZnkgZm9yRWFjaCB3YXMgdXNlZFxuICAvLyBzb21lXG4gIC8vIHJlZHVjZVxuICAvLyByZWR1Y2VSaWdodFxuICAvLyBBcnJheS5mcm9tIGFuZCBvdGhlciB3YXlzIHRvIHR1cm4gYXJyYXktbGlrZSBpbnRvIGFycmF5XG5dO1xuIiwibW9kdWxlLmV4cG9ydHMgPSBbXG4gIHtcbiAgICBuYW1lOiAnQ3JlYXRlIEFycmF5JyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6ICdDcmVhdGUgYW5kIHJldHVybiBhbiBhcnJheSB0aGF0IGNvbnRhaW5zIFxcJ2FwcGxlXFwnIGFuZCBcXCdiYW5hbmFcXCcnLFxuICAgIGdpdmVuOiBgY29uc3QgZnJ1aXRzID0gW107XFxycmV0dXJuIGZydWl0cztgLFxuICAgIGFuc3dlcjogYGNvbnN0IGZydWl0cyA9IFsnYXBwbGUnLCAnYmFuYW5hJ107XG4gICAgICAgICAgICAgcmV0dXJuIGZydWl0cztgLFxuICAgIHRlc3RzOiBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdDb3JyZWN0IG91dHB1dCcsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuZGVlcEVxdWFsKG91dHB1dCwgWydhcHBsZScsICdiYW5hbmEnXSkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnUmV0dXJucyBhbiBBcnJheScsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuaXNBcnJheShvdXRwdXQpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0FycmF5IGhhcyAyIGl0ZW1zJyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5sZW5ndGhPZihvdXRwdXQsIDIpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIG5hbWU6ICdBcnJheS5wb3AoKScsXG4gICAgdGltZTogMTAsXG4gICAgcHJvbXB0OiBgUmVtb3ZlICdvcmFuZ2UnIGZyb20gdGhlIGVuZCBvZiB0aGUgJ2ZydWl0cycgYXJyYXkgYW5kIHJldHVybiAnZnJ1aXRzJy5gLFxuICAgIGdpdmVuOiBgY29uc3QgZnJ1aXRzID0gWydhcHBsZScsICdiYW5hbmEnLCAnb3JhbmdlJ107XFxyYCxcbiAgICBhbnN3ZXI6IGBjb25zdCBmcnVpdHMgPSBbJ2FwcGxlJywgJ2JhbmFuYScsICdvcmFuZ2UnXTtcbiAgICAgICAgICAgICBmcnVpdHMucG9wKCk7XG4gICAgICAgICAgICAgcmV0dXJuIGZydWl0cztgLFxuICAgIHRlc3RzOiBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdDb3JyZWN0IG91dHB1dCcsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuZGVlcEVxdWFsKG91dHB1dCwgWydhcHBsZScsICdiYW5hbmEnXSkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnUmV0dXJucyBhbiBBcnJheScsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuaXNBcnJheShvdXRwdXQpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0FycmF5IGhhcyAyIGl0ZW1zJyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5sZW5ndGhPZihvdXRwdXQsIDIpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfVxuICAgIF1cbiAgfSxcbl1cbiIsIi8qIVxuICogYXNzZXJ0aW9uLWVycm9yXG4gKiBDb3B5cmlnaHQoYykgMjAxMyBKYWtlIEx1ZXIgPGpha2VAcXVhbGlhbmN5LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qIVxuICogUmV0dXJuIGEgZnVuY3Rpb24gdGhhdCB3aWxsIGNvcHkgcHJvcGVydGllcyBmcm9tXG4gKiBvbmUgb2JqZWN0IHRvIGFub3RoZXIgZXhjbHVkaW5nIGFueSBvcmlnaW5hbGx5XG4gKiBsaXN0ZWQuIFJldHVybmVkIGZ1bmN0aW9uIHdpbGwgY3JlYXRlIGEgbmV3IGB7fWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV4Y2x1ZGVkIHByb3BlcnRpZXMgLi4uXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuXG5mdW5jdGlvbiBleGNsdWRlICgpIHtcbiAgdmFyIGV4Y2x1ZGVzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXG4gIGZ1bmN0aW9uIGV4Y2x1ZGVQcm9wcyAocmVzLCBvYmopIHtcbiAgICBPYmplY3Qua2V5cyhvYmopLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgaWYgKCF+ZXhjbHVkZXMuaW5kZXhPZihrZXkpKSByZXNba2V5XSA9IG9ialtrZXldO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIGV4dGVuZEV4Y2x1ZGUgKCkge1xuICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMpXG4gICAgICAsIGkgPSAwXG4gICAgICAsIHJlcyA9IHt9O1xuXG4gICAgZm9yICg7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBleGNsdWRlUHJvcHMocmVzLCBhcmdzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9O1xufTtcblxuLyohXG4gKiBQcmltYXJ5IEV4cG9ydHNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFzc2VydGlvbkVycm9yO1xuXG4vKipcbiAqICMjIyBBc3NlcnRpb25FcnJvclxuICpcbiAqIEFuIGV4dGVuc2lvbiBvZiB0aGUgSmF2YVNjcmlwdCBgRXJyb3JgIGNvbnN0cnVjdG9yIGZvclxuICogYXNzZXJ0aW9uIGFuZCB2YWxpZGF0aW9uIHNjZW5hcmlvcy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICogQHBhcmFtIHtPYmplY3R9IHByb3BlcnRpZXMgdG8gaW5jbHVkZSAob3B0aW9uYWwpXG4gKiBAcGFyYW0ge2NhbGxlZX0gc3RhcnQgc3RhY2sgZnVuY3Rpb24gKG9wdGlvbmFsKVxuICovXG5cbmZ1bmN0aW9uIEFzc2VydGlvbkVycm9yIChtZXNzYWdlLCBfcHJvcHMsIHNzZikge1xuICB2YXIgZXh0ZW5kID0gZXhjbHVkZSgnbmFtZScsICdtZXNzYWdlJywgJ3N0YWNrJywgJ2NvbnN0cnVjdG9yJywgJ3RvSlNPTicpXG4gICAgLCBwcm9wcyA9IGV4dGVuZChfcHJvcHMgfHwge30pO1xuXG4gIC8vIGRlZmF1bHQgdmFsdWVzXG4gIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2UgfHwgJ1Vuc3BlY2lmaWVkIEFzc2VydGlvbkVycm9yJztcbiAgdGhpcy5zaG93RGlmZiA9IGZhbHNlO1xuXG4gIC8vIGNvcHkgZnJvbSBwcm9wZXJ0aWVzXG4gIGZvciAodmFyIGtleSBpbiBwcm9wcykge1xuICAgIHRoaXNba2V5XSA9IHByb3BzW2tleV07XG4gIH1cblxuICAvLyBjYXB0dXJlIHN0YWNrIHRyYWNlXG4gIHNzZiA9IHNzZiB8fCBhcmd1bWVudHMuY2FsbGVlO1xuICBpZiAoc3NmICYmIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgc3NmKTtcbiAgfSBlbHNlIHtcbiAgICB0cnkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgfSBjYXRjaChlKSB7XG4gICAgICB0aGlzLnN0YWNrID0gZS5zdGFjaztcbiAgICB9XG4gIH1cbn1cblxuLyohXG4gKiBJbmhlcml0IGZyb20gRXJyb3IucHJvdG90eXBlXG4gKi9cblxuQXNzZXJ0aW9uRXJyb3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShFcnJvci5wcm90b3R5cGUpO1xuXG4vKiFcbiAqIFN0YXRpY2FsbHkgc2V0IG5hbWVcbiAqL1xuXG5Bc3NlcnRpb25FcnJvci5wcm90b3R5cGUubmFtZSA9ICdBc3NlcnRpb25FcnJvcic7XG5cbi8qIVxuICogRW5zdXJlIGNvcnJlY3QgY29uc3RydWN0b3JcbiAqL1xuXG5Bc3NlcnRpb25FcnJvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBBc3NlcnRpb25FcnJvcjtcblxuLyoqXG4gKiBBbGxvdyBlcnJvcnMgdG8gYmUgY29udmVydGVkIHRvIEpTT04gZm9yIHN0YXRpYyB0cmFuc2Zlci5cbiAqXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGluY2x1ZGUgc3RhY2sgKGRlZmF1bHQ6IGB0cnVlYClcbiAqIEByZXR1cm4ge09iamVjdH0gb2JqZWN0IHRoYXQgY2FuIGJlIGBKU09OLnN0cmluZ2lmeWBcbiAqL1xuXG5Bc3NlcnRpb25FcnJvci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gKHN0YWNrKSB7XG4gIHZhciBleHRlbmQgPSBleGNsdWRlKCdjb25zdHJ1Y3RvcicsICd0b0pTT04nLCAnc3RhY2snKVxuICAgICwgcHJvcHMgPSBleHRlbmQoeyBuYW1lOiB0aGlzLm5hbWUgfSwgdGhpcyk7XG5cbiAgLy8gaW5jbHVkZSBzdGFjayBpZiBleGlzdHMgYW5kIG5vdCB0dXJuZWQgb2ZmXG4gIGlmIChmYWxzZSAhPT0gc3RhY2sgJiYgdGhpcy5zdGFjaykge1xuICAgIHByb3BzLnN0YWNrID0gdGhpcy5zdGFjaztcbiAgfVxuXG4gIHJldHVybiBwcm9wcztcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL2NoYWknKTtcbiIsIi8qIVxuICogY2hhaVxuICogQ29weXJpZ2h0KGMpIDIwMTEtMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbnZhciB1c2VkID0gW11cbiAgLCBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLyohXG4gKiBDaGFpIHZlcnNpb25cbiAqL1xuXG5leHBvcnRzLnZlcnNpb24gPSAnMy41LjAnO1xuXG4vKiFcbiAqIEFzc2VydGlvbiBFcnJvclxuICovXG5cbmV4cG9ydHMuQXNzZXJ0aW9uRXJyb3IgPSByZXF1aXJlKCdhc3NlcnRpb24tZXJyb3InKTtcblxuLyohXG4gKiBVdGlscyBmb3IgcGx1Z2lucyAobm90IGV4cG9ydGVkKVxuICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi9jaGFpL3V0aWxzJyk7XG5cbi8qKlxuICogIyAudXNlKGZ1bmN0aW9uKVxuICpcbiAqIFByb3ZpZGVzIGEgd2F5IHRvIGV4dGVuZCB0aGUgaW50ZXJuYWxzIG9mIENoYWlcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufVxuICogQHJldHVybnMge3RoaXN9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnVzZSA9IGZ1bmN0aW9uIChmbikge1xuICBpZiAoIX51c2VkLmluZGV4T2YoZm4pKSB7XG4gICAgZm4odGhpcywgdXRpbCk7XG4gICAgdXNlZC5wdXNoKGZuKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyohXG4gKiBVdGlsaXR5IEZ1bmN0aW9uc1xuICovXG5cbmV4cG9ydHMudXRpbCA9IHV0aWw7XG5cbi8qIVxuICogQ29uZmlndXJhdGlvblxuICovXG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuL2NoYWkvY29uZmlnJyk7XG5leHBvcnRzLmNvbmZpZyA9IGNvbmZpZztcblxuLyohXG4gKiBQcmltYXJ5IGBBc3NlcnRpb25gIHByb3RvdHlwZVxuICovXG5cbnZhciBhc3NlcnRpb24gPSByZXF1aXJlKCcuL2NoYWkvYXNzZXJ0aW9uJyk7XG5leHBvcnRzLnVzZShhc3NlcnRpb24pO1xuXG4vKiFcbiAqIENvcmUgQXNzZXJ0aW9uc1xuICovXG5cbnZhciBjb3JlID0gcmVxdWlyZSgnLi9jaGFpL2NvcmUvYXNzZXJ0aW9ucycpO1xuZXhwb3J0cy51c2UoY29yZSk7XG5cbi8qIVxuICogRXhwZWN0IGludGVyZmFjZVxuICovXG5cbnZhciBleHBlY3QgPSByZXF1aXJlKCcuL2NoYWkvaW50ZXJmYWNlL2V4cGVjdCcpO1xuZXhwb3J0cy51c2UoZXhwZWN0KTtcblxuLyohXG4gKiBTaG91bGQgaW50ZXJmYWNlXG4gKi9cblxudmFyIHNob3VsZCA9IHJlcXVpcmUoJy4vY2hhaS9pbnRlcmZhY2Uvc2hvdWxkJyk7XG5leHBvcnRzLnVzZShzaG91bGQpO1xuXG4vKiFcbiAqIEFzc2VydCBpbnRlcmZhY2VcbiAqL1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnLi9jaGFpL2ludGVyZmFjZS9hc3NlcnQnKTtcbmV4cG9ydHMudXNlKGFzc2VydCk7XG4iLCIvKiFcbiAqIGNoYWlcbiAqIGh0dHA6Ly9jaGFpanMuY29tXG4gKiBDb3B5cmlnaHQoYykgMjAxMS0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKF9jaGFpLCB1dGlsKSB7XG4gIC8qIVxuICAgKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICAgKi9cblxuICB2YXIgQXNzZXJ0aW9uRXJyb3IgPSBfY2hhaS5Bc3NlcnRpb25FcnJvclxuICAgICwgZmxhZyA9IHV0aWwuZmxhZztcblxuICAvKiFcbiAgICogTW9kdWxlIGV4cG9ydC5cbiAgICovXG5cbiAgX2NoYWkuQXNzZXJ0aW9uID0gQXNzZXJ0aW9uO1xuXG4gIC8qIVxuICAgKiBBc3NlcnRpb24gQ29uc3RydWN0b3JcbiAgICpcbiAgICogQ3JlYXRlcyBvYmplY3QgZm9yIGNoYWluaW5nLlxuICAgKlxuICAgKiBAYXBpIHByaXZhdGVcbiAgICovXG5cbiAgZnVuY3Rpb24gQXNzZXJ0aW9uIChvYmosIG1zZywgc3RhY2spIHtcbiAgICBmbGFnKHRoaXMsICdzc2ZpJywgc3RhY2sgfHwgYXJndW1lbnRzLmNhbGxlZSk7XG4gICAgZmxhZyh0aGlzLCAnb2JqZWN0Jywgb2JqKTtcbiAgICBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgfVxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShBc3NlcnRpb24sICdpbmNsdWRlU3RhY2snLCB7XG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnNvbGUud2FybignQXNzZXJ0aW9uLmluY2x1ZGVTdGFjayBpcyBkZXByZWNhdGVkLCB1c2UgY2hhaS5jb25maWcuaW5jbHVkZVN0YWNrIGluc3RlYWQuJyk7XG4gICAgICByZXR1cm4gY29uZmlnLmluY2x1ZGVTdGFjaztcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGNvbnNvbGUud2FybignQXNzZXJ0aW9uLmluY2x1ZGVTdGFjayBpcyBkZXByZWNhdGVkLCB1c2UgY2hhaS5jb25maWcuaW5jbHVkZVN0YWNrIGluc3RlYWQuJyk7XG4gICAgICBjb25maWcuaW5jbHVkZVN0YWNrID0gdmFsdWU7XG4gICAgfVxuICB9KTtcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQXNzZXJ0aW9uLCAnc2hvd0RpZmYnLCB7XG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnNvbGUud2FybignQXNzZXJ0aW9uLnNob3dEaWZmIGlzIGRlcHJlY2F0ZWQsIHVzZSBjaGFpLmNvbmZpZy5zaG93RGlmZiBpbnN0ZWFkLicpO1xuICAgICAgcmV0dXJuIGNvbmZpZy5zaG93RGlmZjtcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGNvbnNvbGUud2FybignQXNzZXJ0aW9uLnNob3dEaWZmIGlzIGRlcHJlY2F0ZWQsIHVzZSBjaGFpLmNvbmZpZy5zaG93RGlmZiBpbnN0ZWFkLicpO1xuICAgICAgY29uZmlnLnNob3dEaWZmID0gdmFsdWU7XG4gICAgfVxuICB9KTtcblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkgPSBmdW5jdGlvbiAobmFtZSwgZm4pIHtcbiAgICB1dGlsLmFkZFByb3BlcnR5KHRoaXMucHJvdG90eXBlLCBuYW1lLCBmbik7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCA9IGZ1bmN0aW9uIChuYW1lLCBmbikge1xuICAgIHV0aWwuYWRkTWV0aG9kKHRoaXMucHJvdG90eXBlLCBuYW1lLCBmbik7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCA9IGZ1bmN0aW9uIChuYW1lLCBmbiwgY2hhaW5pbmdCZWhhdmlvcikge1xuICAgIHV0aWwuYWRkQ2hhaW5hYmxlTWV0aG9kKHRoaXMucHJvdG90eXBlLCBuYW1lLCBmbiwgY2hhaW5pbmdCZWhhdmlvcik7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLm92ZXJ3cml0ZVByb3BlcnR5ID0gZnVuY3Rpb24gKG5hbWUsIGZuKSB7XG4gICAgdXRpbC5vdmVyd3JpdGVQcm9wZXJ0eSh0aGlzLnByb3RvdHlwZSwgbmFtZSwgZm4pO1xuICB9O1xuXG4gIEFzc2VydGlvbi5vdmVyd3JpdGVNZXRob2QgPSBmdW5jdGlvbiAobmFtZSwgZm4pIHtcbiAgICB1dGlsLm92ZXJ3cml0ZU1ldGhvZCh0aGlzLnByb3RvdHlwZSwgbmFtZSwgZm4pO1xuICB9O1xuXG4gIEFzc2VydGlvbi5vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QgPSBmdW5jdGlvbiAobmFtZSwgZm4sIGNoYWluaW5nQmVoYXZpb3IpIHtcbiAgICB1dGlsLm92ZXJ3cml0ZUNoYWluYWJsZU1ldGhvZCh0aGlzLnByb3RvdHlwZSwgbmFtZSwgZm4sIGNoYWluaW5nQmVoYXZpb3IpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmFzc2VydChleHByZXNzaW9uLCBtZXNzYWdlLCBuZWdhdGVNZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsLCBzaG93RGlmZilcbiAgICpcbiAgICogRXhlY3V0ZXMgYW4gZXhwcmVzc2lvbiBhbmQgY2hlY2sgZXhwZWN0YXRpb25zLiBUaHJvd3MgQXNzZXJ0aW9uRXJyb3IgZm9yIHJlcG9ydGluZyBpZiB0ZXN0IGRvZXNuJ3QgcGFzcy5cbiAgICpcbiAgICogQG5hbWUgYXNzZXJ0XG4gICAqIEBwYXJhbSB7UGhpbG9zb3BoaWNhbH0gZXhwcmVzc2lvbiB0byBiZSB0ZXN0ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IG1lc3NhZ2Ugb3IgZnVuY3Rpb24gdGhhdCByZXR1cm5zIG1lc3NhZ2UgdG8gZGlzcGxheSBpZiBleHByZXNzaW9uIGZhaWxzXG4gICAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSBuZWdhdGVkTWVzc2FnZSBvciBmdW5jdGlvbiB0aGF0IHJldHVybnMgbmVnYXRlZE1lc3NhZ2UgdG8gZGlzcGxheSBpZiBuZWdhdGVkIGV4cHJlc3Npb24gZmFpbHNcbiAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWQgdmFsdWUgKHJlbWVtYmVyIHRvIGNoZWNrIGZvciBuZWdhdGlvbilcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsIChvcHRpb25hbCkgd2lsbCBkZWZhdWx0IHRvIGB0aGlzLm9iamBcbiAgICogQHBhcmFtIHtCb29sZWFufSBzaG93RGlmZiAob3B0aW9uYWwpIHdoZW4gc2V0IHRvIGB0cnVlYCwgYXNzZXJ0IHdpbGwgZGlzcGxheSBhIGRpZmYgaW4gYWRkaXRpb24gdG8gdGhlIG1lc3NhZ2UgaWYgZXhwcmVzc2lvbiBmYWlsc1xuICAgKiBAYXBpIHByaXZhdGVcbiAgICovXG5cbiAgQXNzZXJ0aW9uLnByb3RvdHlwZS5hc3NlcnQgPSBmdW5jdGlvbiAoZXhwciwgbXNnLCBuZWdhdGVNc2csIGV4cGVjdGVkLCBfYWN0dWFsLCBzaG93RGlmZikge1xuICAgIHZhciBvayA9IHV0aWwudGVzdCh0aGlzLCBhcmd1bWVudHMpO1xuICAgIGlmICh0cnVlICE9PSBzaG93RGlmZikgc2hvd0RpZmYgPSBmYWxzZTtcbiAgICBpZiAodHJ1ZSAhPT0gY29uZmlnLnNob3dEaWZmKSBzaG93RGlmZiA9IGZhbHNlO1xuXG4gICAgaWYgKCFvaykge1xuICAgICAgdmFyIG1zZyA9IHV0aWwuZ2V0TWVzc2FnZSh0aGlzLCBhcmd1bWVudHMpXG4gICAgICAgICwgYWN0dWFsID0gdXRpbC5nZXRBY3R1YWwodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtc2csIHtcbiAgICAgICAgICBhY3R1YWw6IGFjdHVhbFxuICAgICAgICAsIGV4cGVjdGVkOiBleHBlY3RlZFxuICAgICAgICAsIHNob3dEaWZmOiBzaG93RGlmZlxuICAgICAgfSwgKGNvbmZpZy5pbmNsdWRlU3RhY2spID8gdGhpcy5hc3NlcnQgOiBmbGFnKHRoaXMsICdzc2ZpJykpO1xuICAgIH1cbiAgfTtcblxuICAvKiFcbiAgICogIyMjIC5fb2JqXG4gICAqXG4gICAqIFF1aWNrIHJlZmVyZW5jZSB0byBzdG9yZWQgYGFjdHVhbGAgdmFsdWUgZm9yIHBsdWdpbiBkZXZlbG9wZXJzLlxuICAgKlxuICAgKiBAYXBpIHByaXZhdGVcbiAgICovXG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFzc2VydGlvbi5wcm90b3R5cGUsICdfb2JqJyxcbiAgICB7IGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgICB9XG4gICAgLCBzZXQ6IGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgZmxhZyh0aGlzLCAnb2JqZWN0JywgdmFsKTtcbiAgICAgIH1cbiAgfSk7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG5cbiAgLyoqXG4gICAqICMjIyBjb25maWcuaW5jbHVkZVN0YWNrXG4gICAqXG4gICAqIFVzZXIgY29uZmlndXJhYmxlIHByb3BlcnR5LCBpbmZsdWVuY2VzIHdoZXRoZXIgc3RhY2sgdHJhY2VcbiAgICogaXMgaW5jbHVkZWQgaW4gQXNzZXJ0aW9uIGVycm9yIG1lc3NhZ2UuIERlZmF1bHQgb2YgZmFsc2VcbiAgICogc3VwcHJlc3NlcyBzdGFjayB0cmFjZSBpbiB0aGUgZXJyb3IgbWVzc2FnZS5cbiAgICpcbiAgICogICAgIGNoYWkuY29uZmlnLmluY2x1ZGVTdGFjayA9IHRydWU7ICAvLyBlbmFibGUgc3RhY2sgb24gZXJyb3JcbiAgICpcbiAgICogQHBhcmFtIHtCb29sZWFufVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICAgaW5jbHVkZVN0YWNrOiBmYWxzZSxcblxuICAvKipcbiAgICogIyMjIGNvbmZpZy5zaG93RGlmZlxuICAgKlxuICAgKiBVc2VyIGNvbmZpZ3VyYWJsZSBwcm9wZXJ0eSwgaW5mbHVlbmNlcyB3aGV0aGVyIG9yIG5vdFxuICAgKiB0aGUgYHNob3dEaWZmYCBmbGFnIHNob3VsZCBiZSBpbmNsdWRlZCBpbiB0aGUgdGhyb3duXG4gICAqIEFzc2VydGlvbkVycm9ycy4gYGZhbHNlYCB3aWxsIGFsd2F5cyBiZSBgZmFsc2VgOyBgdHJ1ZWBcbiAgICogd2lsbCBiZSB0cnVlIHdoZW4gdGhlIGFzc2VydGlvbiBoYXMgcmVxdWVzdGVkIGEgZGlmZlxuICAgKiBiZSBzaG93bi5cbiAgICpcbiAgICogQHBhcmFtIHtCb29sZWFufVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBzaG93RGlmZjogdHJ1ZSxcblxuICAvKipcbiAgICogIyMjIGNvbmZpZy50cnVuY2F0ZVRocmVzaG9sZFxuICAgKlxuICAgKiBVc2VyIGNvbmZpZ3VyYWJsZSBwcm9wZXJ0eSwgc2V0cyBsZW5ndGggdGhyZXNob2xkIGZvciBhY3R1YWwgYW5kXG4gICAqIGV4cGVjdGVkIHZhbHVlcyBpbiBhc3NlcnRpb24gZXJyb3JzLiBJZiB0aGlzIHRocmVzaG9sZCBpcyBleGNlZWRlZCwgZm9yXG4gICAqIGV4YW1wbGUgZm9yIGxhcmdlIGRhdGEgc3RydWN0dXJlcywgdGhlIHZhbHVlIGlzIHJlcGxhY2VkIHdpdGggc29tZXRoaW5nXG4gICAqIGxpa2UgYFsgQXJyYXkoMykgXWAgb3IgYHsgT2JqZWN0IChwcm9wMSwgcHJvcDIpIH1gLlxuICAgKlxuICAgKiBTZXQgaXQgdG8gemVybyBpZiB5b3Ugd2FudCB0byBkaXNhYmxlIHRydW5jYXRpbmcgYWx0b2dldGhlci5cbiAgICpcbiAgICogVGhpcyBpcyBlc3BlY2lhbGx5IHVzZXJmdWwgd2hlbiBkb2luZyBhc3NlcnRpb25zIG9uIGFycmF5czogaGF2aW5nIHRoaXNcbiAgICogc2V0IHRvIGEgcmVhc29uYWJsZSBsYXJnZSB2YWx1ZSBtYWtlcyB0aGUgZmFpbHVyZSBtZXNzYWdlcyByZWFkaWx5XG4gICAqIGluc3BlY3RhYmxlLlxuICAgKlxuICAgKiAgICAgY2hhaS5jb25maWcudHJ1bmNhdGVUaHJlc2hvbGQgPSAwOyAgLy8gZGlzYWJsZSB0cnVuY2F0aW5nXG4gICAqXG4gICAqIEBwYXJhbSB7TnVtYmVyfVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICB0cnVuY2F0ZVRocmVzaG9sZDogNDBcblxufTtcbiIsIi8qIVxuICogY2hhaVxuICogaHR0cDovL2NoYWlqcy5jb21cbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjaGFpLCBfKSB7XG4gIHZhciBBc3NlcnRpb24gPSBjaGFpLkFzc2VydGlvblxuICAgICwgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nXG4gICAgLCBmbGFnID0gXy5mbGFnO1xuXG4gIC8qKlxuICAgKiAjIyMgTGFuZ3VhZ2UgQ2hhaW5zXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgYXJlIHByb3ZpZGVkIGFzIGNoYWluYWJsZSBnZXR0ZXJzIHRvXG4gICAqIGltcHJvdmUgdGhlIHJlYWRhYmlsaXR5IG9mIHlvdXIgYXNzZXJ0aW9ucy4gVGhleVxuICAgKiBkbyBub3QgcHJvdmlkZSB0ZXN0aW5nIGNhcGFiaWxpdGllcyB1bmxlc3MgdGhleVxuICAgKiBoYXZlIGJlZW4gb3ZlcndyaXR0ZW4gYnkgYSBwbHVnaW4uXG4gICAqXG4gICAqICoqQ2hhaW5zKipcbiAgICpcbiAgICogLSB0b1xuICAgKiAtIGJlXG4gICAqIC0gYmVlblxuICAgKiAtIGlzXG4gICAqIC0gdGhhdFxuICAgKiAtIHdoaWNoXG4gICAqIC0gYW5kXG4gICAqIC0gaGFzXG4gICAqIC0gaGF2ZVxuICAgKiAtIHdpdGhcbiAgICogLSBhdFxuICAgKiAtIG9mXG4gICAqIC0gc2FtZVxuICAgKlxuICAgKiBAbmFtZSBsYW5ndWFnZSBjaGFpbnNcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgWyAndG8nLCAnYmUnLCAnYmVlbidcbiAgLCAnaXMnLCAnYW5kJywgJ2hhcycsICdoYXZlJ1xuICAsICd3aXRoJywgJ3RoYXQnLCAnd2hpY2gnLCAnYXQnXG4gICwgJ29mJywgJ3NhbWUnIF0uZm9yRWFjaChmdW5jdGlvbiAoY2hhaW4pIHtcbiAgICBBc3NlcnRpb24uYWRkUHJvcGVydHkoY2hhaW4sIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0pO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5ub3RcbiAgICpcbiAgICogTmVnYXRlcyBhbnkgb2YgYXNzZXJ0aW9ucyBmb2xsb3dpbmcgaW4gdGhlIGNoYWluLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KGZvbykudG8ubm90LmVxdWFsKCdiYXInKTtcbiAgICogICAgIGV4cGVjdChnb29kRm4pLnRvLm5vdC50aHJvdyhFcnJvcik7XG4gICAqICAgICBleHBlY3QoeyBmb286ICdiYXonIH0pLnRvLmhhdmUucHJvcGVydHkoJ2ZvbycpXG4gICAqICAgICAgIC5hbmQubm90LmVxdWFsKCdiYXInKTtcbiAgICpcbiAgICogQG5hbWUgbm90XG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnbm90JywgZnVuY3Rpb24gKCkge1xuICAgIGZsYWcodGhpcywgJ25lZ2F0ZScsIHRydWUpO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5kZWVwXG4gICAqXG4gICAqIFNldHMgdGhlIGBkZWVwYCBmbGFnLCBsYXRlciB1c2VkIGJ5IHRoZSBgZXF1YWxgIGFuZFxuICAgKiBgcHJvcGVydHlgIGFzc2VydGlvbnMuXG4gICAqXG4gICAqICAgICBleHBlY3QoZm9vKS50by5kZWVwLmVxdWFsKHsgYmFyOiAnYmF6JyB9KTtcbiAgICogICAgIGV4cGVjdCh7IGZvbzogeyBiYXI6IHsgYmF6OiAncXV1eCcgfSB9IH0pXG4gICAqICAgICAgIC50by5oYXZlLmRlZXAucHJvcGVydHkoJ2Zvby5iYXIuYmF6JywgJ3F1dXgnKTtcbiAgICpcbiAgICogYC5kZWVwLnByb3BlcnR5YCBzcGVjaWFsIGNoYXJhY3RlcnMgY2FuIGJlIGVzY2FwZWRcbiAgICogYnkgYWRkaW5nIHR3byBzbGFzaGVzIGJlZm9yZSB0aGUgYC5gIG9yIGBbXWAuXG4gICAqXG4gICAqICAgICB2YXIgZGVlcENzcyA9IHsgJy5saW5rJzogeyAnW3RhcmdldF0nOiA0MiB9fTtcbiAgICogICAgIGV4cGVjdChkZWVwQ3NzKS50by5oYXZlLmRlZXAucHJvcGVydHkoJ1xcXFwubGluay5cXFxcW3RhcmdldFxcXFxdJywgNDIpO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZGVlcCcsIGZ1bmN0aW9uICgpIHtcbiAgICBmbGFnKHRoaXMsICdkZWVwJywgdHJ1ZSk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmFueVxuICAgKlxuICAgKiBTZXRzIHRoZSBgYW55YCBmbGFnLCAob3Bwb3NpdGUgb2YgdGhlIGBhbGxgIGZsYWcpXG4gICAqIGxhdGVyIHVzZWQgaW4gdGhlIGBrZXlzYCBhc3NlcnRpb24uXG4gICAqXG4gICAqICAgICBleHBlY3QoZm9vKS50by5oYXZlLmFueS5rZXlzKCdiYXInLCAnYmF6Jyk7XG4gICAqXG4gICAqIEBuYW1lIGFueVxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2FueScsIGZ1bmN0aW9uICgpIHtcbiAgICBmbGFnKHRoaXMsICdhbnknLCB0cnVlKTtcbiAgICBmbGFnKHRoaXMsICdhbGwnLCBmYWxzZSlcbiAgfSk7XG5cblxuICAvKipcbiAgICogIyMjIC5hbGxcbiAgICpcbiAgICogU2V0cyB0aGUgYGFsbGAgZmxhZyAob3Bwb3NpdGUgb2YgdGhlIGBhbnlgIGZsYWcpXG4gICAqIGxhdGVyIHVzZWQgYnkgdGhlIGBrZXlzYCBhc3NlcnRpb24uXG4gICAqXG4gICAqICAgICBleHBlY3QoZm9vKS50by5oYXZlLmFsbC5rZXlzKCdiYXInLCAnYmF6Jyk7XG4gICAqXG4gICAqIEBuYW1lIGFsbFxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2FsbCcsIGZ1bmN0aW9uICgpIHtcbiAgICBmbGFnKHRoaXMsICdhbGwnLCB0cnVlKTtcbiAgICBmbGFnKHRoaXMsICdhbnknLCBmYWxzZSk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmEodHlwZSlcbiAgICpcbiAgICogVGhlIGBhYCBhbmQgYGFuYCBhc3NlcnRpb25zIGFyZSBhbGlhc2VzIHRoYXQgY2FuIGJlXG4gICAqIHVzZWQgZWl0aGVyIGFzIGxhbmd1YWdlIGNoYWlucyBvciB0byBhc3NlcnQgYSB2YWx1ZSdzXG4gICAqIHR5cGUuXG4gICAqXG4gICAqICAgICAvLyB0eXBlb2ZcbiAgICogICAgIGV4cGVjdCgndGVzdCcpLnRvLmJlLmEoJ3N0cmluZycpO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAnYmFyJyB9KS50by5iZS5hbignb2JqZWN0Jyk7XG4gICAqICAgICBleHBlY3QobnVsbCkudG8uYmUuYSgnbnVsbCcpO1xuICAgKiAgICAgZXhwZWN0KHVuZGVmaW5lZCkudG8uYmUuYW4oJ3VuZGVmaW5lZCcpO1xuICAgKiAgICAgZXhwZWN0KG5ldyBFcnJvcikudG8uYmUuYW4oJ2Vycm9yJyk7XG4gICAqICAgICBleHBlY3QobmV3IFByb21pc2UpLnRvLmJlLmEoJ3Byb21pc2UnKTtcbiAgICogICAgIGV4cGVjdChuZXcgRmxvYXQzMkFycmF5KCkpLnRvLmJlLmEoJ2Zsb2F0MzJhcnJheScpO1xuICAgKiAgICAgZXhwZWN0KFN5bWJvbCgpKS50by5iZS5hKCdzeW1ib2wnKTtcbiAgICpcbiAgICogICAgIC8vIGVzNiBvdmVycmlkZXNcbiAgICogICAgIGV4cGVjdCh7W1N5bWJvbC50b1N0cmluZ1RhZ106KCk9Pidmb28nfSkudG8uYmUuYSgnZm9vJyk7XG4gICAqXG4gICAqICAgICAvLyBsYW5ndWFnZSBjaGFpblxuICAgKiAgICAgZXhwZWN0KGZvbykudG8uYmUuYW4uaW5zdGFuY2VvZihGb28pO1xuICAgKlxuICAgKiBAbmFtZSBhXG4gICAqIEBhbGlhcyBhblxuICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFuICh0eXBlLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB0eXBlID0gdHlwZS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBhcnRpY2xlID0gflsgJ2EnLCAnZScsICdpJywgJ28nLCAndScgXS5pbmRleE9mKHR5cGUuY2hhckF0KDApKSA/ICdhbiAnIDogJ2EgJztcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICB0eXBlID09PSBfLnR5cGUob2JqKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSAnICsgYXJ0aWNsZSArIHR5cGVcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIGJlICcgKyBhcnRpY2xlICsgdHlwZVxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdhbicsIGFuKTtcbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnYScsIGFuKTtcblxuICAvKipcbiAgICogIyMjIC5pbmNsdWRlKHZhbHVlKVxuICAgKlxuICAgKiBUaGUgYGluY2x1ZGVgIGFuZCBgY29udGFpbmAgYXNzZXJ0aW9ucyBjYW4gYmUgdXNlZCBhcyBlaXRoZXIgcHJvcGVydHlcbiAgICogYmFzZWQgbGFuZ3VhZ2UgY2hhaW5zIG9yIGFzIG1ldGhvZHMgdG8gYXNzZXJ0IHRoZSBpbmNsdXNpb24gb2YgYW4gb2JqZWN0XG4gICAqIGluIGFuIGFycmF5IG9yIGEgc3Vic3RyaW5nIGluIGEgc3RyaW5nLiBXaGVuIHVzZWQgYXMgbGFuZ3VhZ2UgY2hhaW5zLFxuICAgKiB0aGV5IHRvZ2dsZSB0aGUgYGNvbnRhaW5zYCBmbGFnIGZvciB0aGUgYGtleXNgIGFzc2VydGlvbi5cbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwyLDNdKS50by5pbmNsdWRlKDIpO1xuICAgKiAgICAgZXhwZWN0KCdmb29iYXInKS50by5jb250YWluKCdmb28nKTtcbiAgICogICAgIGV4cGVjdCh7IGZvbzogJ2JhcicsIGhlbGxvOiAndW5pdmVyc2UnIH0pLnRvLmluY2x1ZGUua2V5cygnZm9vJyk7XG4gICAqXG4gICAqIEBuYW1lIGluY2x1ZGVcbiAgICogQGFsaWFzIGNvbnRhaW5cbiAgICogQGFsaWFzIGluY2x1ZGVzXG4gICAqIEBhbGlhcyBjb250YWluc1xuICAgKiBAcGFyYW0ge09iamVjdHxTdHJpbmd8TnVtYmVyfSBvYmpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBpbmNsdWRlQ2hhaW5pbmdCZWhhdmlvciAoKSB7XG4gICAgZmxhZyh0aGlzLCAnY29udGFpbnMnLCB0cnVlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluY2x1ZGUgKHZhbCwgbXNnKSB7XG4gICAgXy5leHBlY3RUeXBlcyh0aGlzLCBbJ2FycmF5JywgJ29iamVjdCcsICdzdHJpbmcnXSk7XG5cbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgdmFyIGV4cGVjdGVkID0gZmFsc2U7XG5cbiAgICBpZiAoXy50eXBlKG9iaikgPT09ICdhcnJheScgJiYgXy50eXBlKHZhbCkgPT09ICdvYmplY3QnKSB7XG4gICAgICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgICAgICBpZiAoXy5lcWwob2JqW2ldLCB2YWwpKSB7XG4gICAgICAgICAgZXhwZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChfLnR5cGUodmFsKSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmICghZmxhZyh0aGlzLCAnbmVnYXRlJykpIHtcbiAgICAgICAgZm9yICh2YXIgayBpbiB2YWwpIG5ldyBBc3NlcnRpb24ob2JqKS5wcm9wZXJ0eShrLCB2YWxba10pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgc3Vic2V0ID0ge307XG4gICAgICBmb3IgKHZhciBrIGluIHZhbCkgc3Vic2V0W2tdID0gb2JqW2tdO1xuICAgICAgZXhwZWN0ZWQgPSBfLmVxbChzdWJzZXQsIHZhbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4cGVjdGVkID0gKG9iaiAhPSB1bmRlZmluZWQpICYmIH5vYmouaW5kZXhPZih2YWwpO1xuICAgIH1cbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgZXhwZWN0ZWRcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gaW5jbHVkZSAnICsgXy5pbnNwZWN0KHZhbClcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGluY2x1ZGUgJyArIF8uaW5zcGVjdCh2YWwpKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2luY2x1ZGUnLCBpbmNsdWRlLCBpbmNsdWRlQ2hhaW5pbmdCZWhhdmlvcik7XG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2NvbnRhaW4nLCBpbmNsdWRlLCBpbmNsdWRlQ2hhaW5pbmdCZWhhdmlvcik7XG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2NvbnRhaW5zJywgaW5jbHVkZSwgaW5jbHVkZUNoYWluaW5nQmVoYXZpb3IpO1xuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdpbmNsdWRlcycsIGluY2x1ZGUsIGluY2x1ZGVDaGFpbmluZ0JlaGF2aW9yKTtcblxuICAvKipcbiAgICogIyMjIC5va1xuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyB0cnV0aHkuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2V2ZXJ5dGhpbmcnKS50by5iZS5vaztcbiAgICogICAgIGV4cGVjdCgxKS50by5iZS5vaztcbiAgICogICAgIGV4cGVjdChmYWxzZSkudG8ubm90LmJlLm9rO1xuICAgKiAgICAgZXhwZWN0KHVuZGVmaW5lZCkudG8ubm90LmJlLm9rO1xuICAgKiAgICAgZXhwZWN0KG51bGwpLnRvLm5vdC5iZS5vaztcbiAgICpcbiAgICogQG5hbWUgb2tcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdvaycsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgdHJ1dGh5J1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBmYWxzeScpO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC50cnVlXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGB0cnVlYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh0cnVlKS50by5iZS50cnVlO1xuICAgKiAgICAgZXhwZWN0KDEpLnRvLm5vdC5iZS50cnVlO1xuICAgKlxuICAgKiBAbmFtZSB0cnVlXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgndHJ1ZScsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgdHJ1ZSA9PT0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgdHJ1ZSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgZmFsc2UnXG4gICAgICAsIHRoaXMubmVnYXRlID8gZmFsc2UgOiB0cnVlXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuZmFsc2VcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgYGZhbHNlYC5cbiAgICpcbiAgICogICAgIGV4cGVjdChmYWxzZSkudG8uYmUuZmFsc2U7XG4gICAqICAgICBleHBlY3QoMCkudG8ubm90LmJlLmZhbHNlO1xuICAgKlxuICAgKiBAbmFtZSBmYWxzZVxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2ZhbHNlJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBmYWxzZSA9PT0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgZmFsc2UnXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIHRydWUnXG4gICAgICAsIHRoaXMubmVnYXRlID8gdHJ1ZSA6IGZhbHNlXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAubnVsbFxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBgbnVsbGAuXG4gICAqXG4gICAqICAgICBleHBlY3QobnVsbCkudG8uYmUubnVsbDtcbiAgICogICAgIGV4cGVjdCh1bmRlZmluZWQpLnRvLm5vdC5iZS5udWxsO1xuICAgKlxuICAgKiBAbmFtZSBudWxsXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnbnVsbCcsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgbnVsbCA9PT0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgbnVsbCdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIGJlIG51bGwnXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAudW5kZWZpbmVkXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGB1bmRlZmluZWRgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHVuZGVmaW5lZCkudG8uYmUudW5kZWZpbmVkO1xuICAgKiAgICAgZXhwZWN0KG51bGwpLnRvLm5vdC5iZS51bmRlZmluZWQ7XG4gICAqXG4gICAqIEBuYW1lIHVuZGVmaW5lZFxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ3VuZGVmaW5lZCcsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgdW5kZWZpbmVkID09PSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSB1bmRlZmluZWQnXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSB1bmRlZmluZWQnXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuTmFOXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGBOYU5gLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5iZS5OYU47XG4gICAqICAgICBleHBlY3QoNCkubm90LnRvLmJlLk5hTjtcbiAgICpcbiAgICogQG5hbWUgTmFOXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnTmFOJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBpc05hTihmbGFnKHRoaXMsICdvYmplY3QnKSlcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBOYU4nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIGJlIE5hTidcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5leGlzdFxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBuZWl0aGVyIGBudWxsYCBub3IgYHVuZGVmaW5lZGAuXG4gICAqXG4gICAqICAgICB2YXIgZm9vID0gJ2hpJ1xuICAgKiAgICAgICAsIGJhciA9IG51bGxcbiAgICogICAgICAgLCBiYXo7XG4gICAqXG4gICAqICAgICBleHBlY3QoZm9vKS50by5leGlzdDtcbiAgICogICAgIGV4cGVjdChiYXIpLnRvLm5vdC5leGlzdDtcbiAgICogICAgIGV4cGVjdChiYXopLnRvLm5vdC5leGlzdDtcbiAgICpcbiAgICogQG5hbWUgZXhpc3RcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdleGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgbnVsbCAhPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBleGlzdCdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGV4aXN0J1xuICAgICk7XG4gIH0pO1xuXG5cbiAgLyoqXG4gICAqICMjIyAuZW1wdHlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQncyBsZW5ndGggaXMgYDBgLiBGb3IgYXJyYXlzIGFuZCBzdHJpbmdzLCBpdCBjaGVja3NcbiAgICogdGhlIGBsZW5ndGhgIHByb3BlcnR5LiBGb3Igb2JqZWN0cywgaXQgZ2V0cyB0aGUgY291bnQgb2ZcbiAgICogZW51bWVyYWJsZSBrZXlzLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFtdKS50by5iZS5lbXB0eTtcbiAgICogICAgIGV4cGVjdCgnJykudG8uYmUuZW1wdHk7XG4gICAqICAgICBleHBlY3Qoe30pLnRvLmJlLmVtcHR5O1xuICAgKlxuICAgKiBAbmFtZSBlbXB0eVxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2VtcHR5JywgZnVuY3Rpb24gKCkge1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBleHBlY3RlZCA9IG9iajtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikgfHwgJ3N0cmluZycgPT09IHR5cGVvZiBvYmplY3QpIHtcbiAgICAgIGV4cGVjdGVkID0gb2JqLmxlbmd0aDtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnKSB7XG4gICAgICBleHBlY3RlZCA9IE9iamVjdC5rZXlzKG9iaikubGVuZ3RoO1xuICAgIH1cblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAhZXhwZWN0ZWRcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgZW1wdHknXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSBlbXB0eSdcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5hcmd1bWVudHNcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgYW4gYXJndW1lbnRzIG9iamVjdC5cbiAgICpcbiAgICogICAgIGZ1bmN0aW9uIHRlc3QgKCkge1xuICAgKiAgICAgICBleHBlY3QoYXJndW1lbnRzKS50by5iZS5hcmd1bWVudHM7XG4gICAqICAgICB9XG4gICAqXG4gICAqIEBuYW1lIGFyZ3VtZW50c1xuICAgKiBAYWxpYXMgQXJndW1lbnRzXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGNoZWNrQXJndW1lbnRzICgpIHtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgdHlwZSA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopO1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAnW29iamVjdCBBcmd1bWVudHNdJyA9PT0gdHlwZVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBhcmd1bWVudHMgYnV0IGdvdCAnICsgdHlwZVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgYXJndW1lbnRzJ1xuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2FyZ3VtZW50cycsIGNoZWNrQXJndW1lbnRzKTtcbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdBcmd1bWVudHMnLCBjaGVja0FyZ3VtZW50cyk7XG5cbiAgLyoqXG4gICAqICMjIyAuZXF1YWwodmFsdWUpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIHN0cmljdGx5IGVxdWFsIChgPT09YCkgdG8gYHZhbHVlYC5cbiAgICogQWx0ZXJuYXRlbHksIGlmIHRoZSBgZGVlcGAgZmxhZyBpcyBzZXQsIGFzc2VydHMgdGhhdFxuICAgKiB0aGUgdGFyZ2V0IGlzIGRlZXBseSBlcXVhbCB0byBgdmFsdWVgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdoZWxsbycpLnRvLmVxdWFsKCdoZWxsbycpO1xuICAgKiAgICAgZXhwZWN0KDQyKS50by5lcXVhbCg0Mik7XG4gICAqICAgICBleHBlY3QoMSkudG8ubm90LmVxdWFsKHRydWUpO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAnYmFyJyB9KS50by5ub3QuZXF1YWwoeyBmb286ICdiYXInIH0pO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAnYmFyJyB9KS50by5kZWVwLmVxdWFsKHsgZm9vOiAnYmFyJyB9KTtcbiAgICpcbiAgICogQG5hbWUgZXF1YWxcbiAgICogQGFsaWFzIGVxdWFsc1xuICAgKiBAYWxpYXMgZXFcbiAgICogQGFsaWFzIGRlZXAuZXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRFcXVhbCAodmFsLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgaWYgKGZsYWcodGhpcywgJ2RlZXAnKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZXFsKHZhbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIHZhbCA9PT0gb2JqXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gZXF1YWwgI3tleHB9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBlcXVhbCAje2V4cH0nXG4gICAgICAgICwgdmFsXG4gICAgICAgICwgdGhpcy5fb2JqXG4gICAgICAgICwgdHJ1ZVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdlcXVhbCcsIGFzc2VydEVxdWFsKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZXF1YWxzJywgYXNzZXJ0RXF1YWwpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdlcScsIGFzc2VydEVxdWFsKTtcblxuICAvKipcbiAgICogIyMjIC5lcWwodmFsdWUpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGRlZXBseSBlcXVhbCB0byBgdmFsdWVgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAnYmFyJyB9KS50by5lcWwoeyBmb286ICdiYXInIH0pO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5lcWwoWyAxLCAyLCAzIF0pO1xuICAgKlxuICAgKiBAbmFtZSBlcWxcbiAgICogQGFsaWFzIGVxbHNcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRFcWwob2JqLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgXy5lcWwob2JqLCBmbGFnKHRoaXMsICdvYmplY3QnKSlcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gZGVlcGx5IGVxdWFsICN7ZXhwfSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGRlZXBseSBlcXVhbCAje2V4cH0nXG4gICAgICAsIG9ialxuICAgICAgLCB0aGlzLl9vYmpcbiAgICAgICwgdHJ1ZVxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdlcWwnLCBhc3NlcnRFcWwpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdlcWxzJywgYXNzZXJ0RXFsKTtcblxuICAvKipcbiAgICogIyMjIC5hYm92ZSh2YWx1ZSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgZ3JlYXRlciB0aGFuIGB2YWx1ZWAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMTApLnRvLmJlLmFib3ZlKDUpO1xuICAgKlxuICAgKiBDYW4gYWxzbyBiZSB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggYGxlbmd0aGAgdG9cbiAgICogYXNzZXJ0IGEgbWluaW11bSBsZW5ndGguIFRoZSBiZW5lZml0IGJlaW5nIGFcbiAgICogbW9yZSBpbmZvcm1hdGl2ZSBlcnJvciBtZXNzYWdlIHRoYW4gaWYgdGhlIGxlbmd0aFxuICAgKiB3YXMgc3VwcGxpZWQgZGlyZWN0bHkuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoLmFib3ZlKDIpO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5oYXZlLmxlbmd0aC5hYm92ZSgyKTtcbiAgICpcbiAgICogQG5hbWUgYWJvdmVcbiAgICogQGFsaWFzIGd0XG4gICAqIEBhbGlhcyBncmVhdGVyVGhhblxuICAgKiBAcGFyYW0ge051bWJlcn0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRBYm92ZSAobiwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIGlmIChmbGFnKHRoaXMsICdkb0xlbmd0aCcpKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICAgIHZhciBsZW4gPSBvYmoubGVuZ3RoO1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgbGVuID4gblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSBsZW5ndGggYWJvdmUgI3tleHB9IGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlIGEgbGVuZ3RoIGFib3ZlICN7ZXhwfSdcbiAgICAgICAgLCBuXG4gICAgICAgICwgbGVuXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBvYmogPiBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYWJvdmUgJyArIG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBhdCBtb3N0ICcgKyBuXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2Fib3ZlJywgYXNzZXJ0QWJvdmUpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdndCcsIGFzc2VydEFib3ZlKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZ3JlYXRlclRoYW4nLCBhc3NlcnRBYm92ZSk7XG5cbiAgLyoqXG4gICAqICMjIyAubGVhc3QodmFsdWUpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBgdmFsdWVgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEwKS50by5iZS5hdC5sZWFzdCgxMCk7XG4gICAqXG4gICAqIENhbiBhbHNvIGJlIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCBgbGVuZ3RoYCB0b1xuICAgKiBhc3NlcnQgYSBtaW5pbXVtIGxlbmd0aC4gVGhlIGJlbmVmaXQgYmVpbmcgYVxuICAgKiBtb3JlIGluZm9ybWF0aXZlIGVycm9yIG1lc3NhZ2UgdGhhbiBpZiB0aGUgbGVuZ3RoXG4gICAqIHdhcyBzdXBwbGllZCBkaXJlY3RseS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGgub2YuYXQubGVhc3QoMik7XG4gICAqICAgICBleHBlY3QoWyAxLCAyLCAzIF0pLnRvLmhhdmUubGVuZ3RoLm9mLmF0LmxlYXN0KDMpO1xuICAgKlxuICAgKiBAbmFtZSBsZWFzdFxuICAgKiBAYWxpYXMgZ3RlXG4gICAqIEBwYXJhbSB7TnVtYmVyfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydExlYXN0IChuLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgaWYgKGZsYWcodGhpcywgJ2RvTGVuZ3RoJykpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLnRvLmhhdmUucHJvcGVydHkoJ2xlbmd0aCcpO1xuICAgICAgdmFyIGxlbiA9IG9iai5sZW5ndGg7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBsZW4gPj0gblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSBsZW5ndGggYXQgbGVhc3QgI3tleHB9IGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSBsZW5ndGggYmVsb3cgI3tleHB9J1xuICAgICAgICAsIG5cbiAgICAgICAgLCBsZW5cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIG9iaiA+PSBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYXQgbGVhc3QgJyArIG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBiZWxvdyAnICsgblxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdsZWFzdCcsIGFzc2VydExlYXN0KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZ3RlJywgYXNzZXJ0TGVhc3QpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmJlbG93KHZhbHVlKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBsZXNzIHRoYW4gYHZhbHVlYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCg1KS50by5iZS5iZWxvdygxMCk7XG4gICAqXG4gICAqIENhbiBhbHNvIGJlIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCBgbGVuZ3RoYCB0b1xuICAgKiBhc3NlcnQgYSBtYXhpbXVtIGxlbmd0aC4gVGhlIGJlbmVmaXQgYmVpbmcgYVxuICAgKiBtb3JlIGluZm9ybWF0aXZlIGVycm9yIG1lc3NhZ2UgdGhhbiBpZiB0aGUgbGVuZ3RoXG4gICAqIHdhcyBzdXBwbGllZCBkaXJlY3RseS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGguYmVsb3coNCk7XG4gICAqICAgICBleHBlY3QoWyAxLCAyLCAzIF0pLnRvLmhhdmUubGVuZ3RoLmJlbG93KDQpO1xuICAgKlxuICAgKiBAbmFtZSBiZWxvd1xuICAgKiBAYWxpYXMgbHRcbiAgICogQGFsaWFzIGxlc3NUaGFuXG4gICAqIEBwYXJhbSB7TnVtYmVyfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydEJlbG93IChuLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgaWYgKGZsYWcodGhpcywgJ2RvTGVuZ3RoJykpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLnRvLmhhdmUucHJvcGVydHkoJ2xlbmd0aCcpO1xuICAgICAgdmFyIGxlbiA9IG9iai5sZW5ndGg7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBsZW4gPCBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSBhIGxlbmd0aCBiZWxvdyAje2V4cH0gYnV0IGdvdCAje2FjdH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgYSBsZW5ndGggYmVsb3cgI3tleHB9J1xuICAgICAgICAsIG5cbiAgICAgICAgLCBsZW5cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIG9iaiA8IG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBiZWxvdyAnICsgblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGF0IGxlYXN0ICcgKyBuXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2JlbG93JywgYXNzZXJ0QmVsb3cpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdsdCcsIGFzc2VydEJlbG93KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbGVzc1RoYW4nLCBhc3NlcnRCZWxvdyk7XG5cbiAgLyoqXG4gICAqICMjIyAubW9zdCh2YWx1ZSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGB2YWx1ZWAuXG4gICAqXG4gICAqICAgICBleHBlY3QoNSkudG8uYmUuYXQubW9zdCg1KTtcbiAgICpcbiAgICogQ2FuIGFsc28gYmUgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGBsZW5ndGhgIHRvXG4gICAqIGFzc2VydCBhIG1heGltdW0gbGVuZ3RoLiBUaGUgYmVuZWZpdCBiZWluZyBhXG4gICAqIG1vcmUgaW5mb3JtYXRpdmUgZXJyb3IgbWVzc2FnZSB0aGFuIGlmIHRoZSBsZW5ndGhcbiAgICogd2FzIHN1cHBsaWVkIGRpcmVjdGx5LlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5oYXZlLmxlbmd0aC5vZi5hdC5tb3N0KDQpO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5oYXZlLmxlbmd0aC5vZi5hdC5tb3N0KDMpO1xuICAgKlxuICAgKiBAbmFtZSBtb3N0XG4gICAqIEBhbGlhcyBsdGVcbiAgICogQHBhcmFtIHtOdW1iZXJ9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0TW9zdCAobiwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIGlmIChmbGFnKHRoaXMsICdkb0xlbmd0aCcpKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICAgIHZhciBsZW4gPSBvYmoubGVuZ3RoO1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgbGVuIDw9IG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgbGVuZ3RoIGF0IG1vc3QgI3tleHB9IGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSBsZW5ndGggYWJvdmUgI3tleHB9J1xuICAgICAgICAsIG5cbiAgICAgICAgLCBsZW5cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIG9iaiA8PSBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYXQgbW9zdCAnICsgblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGFib3ZlICcgKyBuXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ21vc3QnLCBhc3NlcnRNb3N0KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbHRlJywgYXNzZXJ0TW9zdCk7XG5cbiAgLyoqXG4gICAqICMjIyAud2l0aGluKHN0YXJ0LCBmaW5pc2gpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIHdpdGhpbiBhIHJhbmdlLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDcpLnRvLmJlLndpdGhpbig1LDEwKTtcbiAgICpcbiAgICogQ2FuIGFsc28gYmUgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGBsZW5ndGhgIHRvXG4gICAqIGFzc2VydCBhIGxlbmd0aCByYW5nZS4gVGhlIGJlbmVmaXQgYmVpbmcgYVxuICAgKiBtb3JlIGluZm9ybWF0aXZlIGVycm9yIG1lc3NhZ2UgdGhhbiBpZiB0aGUgbGVuZ3RoXG4gICAqIHdhcyBzdXBwbGllZCBkaXJlY3RseS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGgud2l0aGluKDIsNCk7XG4gICAqICAgICBleHBlY3QoWyAxLCAyLCAzIF0pLnRvLmhhdmUubGVuZ3RoLndpdGhpbigyLDQpO1xuICAgKlxuICAgKiBAbmFtZSB3aXRoaW5cbiAgICogQHBhcmFtIHtOdW1iZXJ9IHN0YXJ0IGxvd2VyYm91bmQgaW5jbHVzaXZlXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBmaW5pc2ggdXBwZXJib3VuZCBpbmNsdXNpdmVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCd3aXRoaW4nLCBmdW5jdGlvbiAoc3RhcnQsIGZpbmlzaCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIHJhbmdlID0gc3RhcnQgKyAnLi4nICsgZmluaXNoO1xuICAgIGlmIChmbGFnKHRoaXMsICdkb0xlbmd0aCcpKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICAgIHZhciBsZW4gPSBvYmoubGVuZ3RoO1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgbGVuID49IHN0YXJ0ICYmIGxlbiA8PSBmaW5pc2hcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgbGVuZ3RoIHdpdGhpbiAnICsgcmFuZ2VcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgaGF2ZSBhIGxlbmd0aCB3aXRoaW4gJyArIHJhbmdlXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBvYmogPj0gc3RhcnQgJiYgb2JqIDw9IGZpbmlzaFxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIHdpdGhpbiAnICsgcmFuZ2VcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgd2l0aGluICcgKyByYW5nZVxuICAgICAgKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmluc3RhbmNlb2YoY29uc3RydWN0b3IpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGFuIGluc3RhbmNlIG9mIGBjb25zdHJ1Y3RvcmAuXG4gICAqXG4gICAqICAgICB2YXIgVGVhID0gZnVuY3Rpb24gKG5hbWUpIHsgdGhpcy5uYW1lID0gbmFtZTsgfVxuICAgKiAgICAgICAsIENoYWkgPSBuZXcgVGVhKCdjaGFpJyk7XG4gICAqXG4gICAqICAgICBleHBlY3QoQ2hhaSkudG8uYmUuYW4uaW5zdGFuY2VvZihUZWEpO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5iZS5pbnN0YW5jZW9mKEFycmF5KTtcbiAgICpcbiAgICogQG5hbWUgaW5zdGFuY2VvZlxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yfSBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBhbGlhcyBpbnN0YW5jZU9mXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydEluc3RhbmNlT2YgKGNvbnN0cnVjdG9yLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgbmFtZSA9IF8uZ2V0TmFtZShjb25zdHJ1Y3Rvcik7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIGZsYWcodGhpcywgJ29iamVjdCcpIGluc3RhbmNlb2YgY29uc3RydWN0b3JcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYW4gaW5zdGFuY2Ugb2YgJyArIG5hbWVcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIGFuIGluc3RhbmNlIG9mICcgKyBuYW1lXG4gICAgKTtcbiAgfTtcblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdpbnN0YW5jZW9mJywgYXNzZXJ0SW5zdGFuY2VPZik7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2luc3RhbmNlT2YnLCBhc3NlcnRJbnN0YW5jZU9mKTtcblxuICAvKipcbiAgICogIyMjIC5wcm9wZXJ0eShuYW1lLCBbdmFsdWVdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBoYXMgYSBwcm9wZXJ0eSBgbmFtZWAsIG9wdGlvbmFsbHkgYXNzZXJ0aW5nIHRoYXRcbiAgICogdGhlIHZhbHVlIG9mIHRoYXQgcHJvcGVydHkgaXMgc3RyaWN0bHkgZXF1YWwgdG8gIGB2YWx1ZWAuXG4gICAqIElmIHRoZSBgZGVlcGAgZmxhZyBpcyBzZXQsIHlvdSBjYW4gdXNlIGRvdC0gYW5kIGJyYWNrZXQtbm90YXRpb24gZm9yIGRlZXBcbiAgICogcmVmZXJlbmNlcyBpbnRvIG9iamVjdHMgYW5kIGFycmF5cy5cbiAgICpcbiAgICogICAgIC8vIHNpbXBsZSByZWZlcmVuY2luZ1xuICAgKiAgICAgdmFyIG9iaiA9IHsgZm9vOiAnYmFyJyB9O1xuICAgKiAgICAgZXhwZWN0KG9iaikudG8uaGF2ZS5wcm9wZXJ0eSgnZm9vJyk7XG4gICAqICAgICBleHBlY3Qob2JqKS50by5oYXZlLnByb3BlcnR5KCdmb28nLCAnYmFyJyk7XG4gICAqXG4gICAqICAgICAvLyBkZWVwIHJlZmVyZW5jaW5nXG4gICAqICAgICB2YXIgZGVlcE9iaiA9IHtcbiAgICogICAgICAgICBncmVlbjogeyB0ZWE6ICdtYXRjaGEnIH1cbiAgICogICAgICAgLCB0ZWFzOiBbICdjaGFpJywgJ21hdGNoYScsIHsgdGVhOiAna29uYWNoYScgfSBdXG4gICAqICAgICB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGRlZXBPYmopLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eSgnZ3JlZW4udGVhJywgJ21hdGNoYScpO1xuICAgKiAgICAgZXhwZWN0KGRlZXBPYmopLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eSgndGVhc1sxXScsICdtYXRjaGEnKTtcbiAgICogICAgIGV4cGVjdChkZWVwT2JqKS50by5oYXZlLmRlZXAucHJvcGVydHkoJ3RlYXNbMl0udGVhJywgJ2tvbmFjaGEnKTtcbiAgICpcbiAgICogWW91IGNhbiBhbHNvIHVzZSBhbiBhcnJheSBhcyB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgYSBgZGVlcC5wcm9wZXJ0eWBcbiAgICogYXNzZXJ0aW9uLCBvciB0cmF2ZXJzZSBuZXN0ZWQgYXJyYXlzLlxuICAgKlxuICAgKiAgICAgdmFyIGFyciA9IFtcbiAgICogICAgICAgICBbICdjaGFpJywgJ21hdGNoYScsICdrb25hY2hhJyBdXG4gICAqICAgICAgICwgWyB7IHRlYTogJ2NoYWknIH1cbiAgICogICAgICAgICAsIHsgdGVhOiAnbWF0Y2hhJyB9XG4gICAqICAgICAgICAgLCB7IHRlYTogJ2tvbmFjaGEnIH0gXVxuICAgKiAgICAgXTtcbiAgICpcbiAgICogICAgIGV4cGVjdChhcnIpLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eSgnWzBdWzFdJywgJ21hdGNoYScpO1xuICAgKiAgICAgZXhwZWN0KGFycikudG8uaGF2ZS5kZWVwLnByb3BlcnR5KCdbMV1bMl0udGVhJywgJ2tvbmFjaGEnKTtcbiAgICpcbiAgICogRnVydGhlcm1vcmUsIGBwcm9wZXJ0eWAgY2hhbmdlcyB0aGUgc3ViamVjdCBvZiB0aGUgYXNzZXJ0aW9uXG4gICAqIHRvIGJlIHRoZSB2YWx1ZSBvZiB0aGF0IHByb3BlcnR5IGZyb20gdGhlIG9yaWdpbmFsIG9iamVjdC4gVGhpc1xuICAgKiBwZXJtaXRzIGZvciBmdXJ0aGVyIGNoYWluYWJsZSBhc3NlcnRpb25zIG9uIHRoYXQgcHJvcGVydHkuXG4gICAqXG4gICAqICAgICBleHBlY3Qob2JqKS50by5oYXZlLnByb3BlcnR5KCdmb28nKVxuICAgKiAgICAgICAudGhhdC5pcy5hKCdzdHJpbmcnKTtcbiAgICogICAgIGV4cGVjdChkZWVwT2JqKS50by5oYXZlLnByb3BlcnR5KCdncmVlbicpXG4gICAqICAgICAgIC50aGF0LmlzLmFuKCdvYmplY3QnKVxuICAgKiAgICAgICAudGhhdC5kZWVwLmVxdWFscyh7IHRlYTogJ21hdGNoYScgfSk7XG4gICAqICAgICBleHBlY3QoZGVlcE9iaikudG8uaGF2ZS5wcm9wZXJ0eSgndGVhcycpXG4gICAqICAgICAgIC50aGF0LmlzLmFuKCdhcnJheScpXG4gICAqICAgICAgIC53aXRoLmRlZXAucHJvcGVydHkoJ1syXScpXG4gICAqICAgICAgICAgLnRoYXQuZGVlcC5lcXVhbHMoeyB0ZWE6ICdrb25hY2hhJyB9KTtcbiAgICpcbiAgICogTm90ZSB0aGF0IGRvdHMgYW5kIGJyYWNrZXQgaW4gYG5hbWVgIG11c3QgYmUgYmFja3NsYXNoLWVzY2FwZWQgd2hlblxuICAgKiB0aGUgYGRlZXBgIGZsYWcgaXMgc2V0LCB3aGlsZSB0aGV5IG11c3QgTk9UIGJlIGVzY2FwZWQgd2hlbiB0aGUgYGRlZXBgXG4gICAqIGZsYWcgaXMgbm90IHNldC5cbiAgICpcbiAgICogICAgIC8vIHNpbXBsZSByZWZlcmVuY2luZ1xuICAgKiAgICAgdmFyIGNzcyA9IHsgJy5saW5rW3RhcmdldF0nOiA0MiB9O1xuICAgKiAgICAgZXhwZWN0KGNzcykudG8uaGF2ZS5wcm9wZXJ0eSgnLmxpbmtbdGFyZ2V0XScsIDQyKTtcbiAgICpcbiAgICogICAgIC8vIGRlZXAgcmVmZXJlbmNpbmdcbiAgICogICAgIHZhciBkZWVwQ3NzID0geyAnLmxpbmsnOiB7ICdbdGFyZ2V0XSc6IDQyIH19O1xuICAgKiAgICAgZXhwZWN0KGRlZXBDc3MpLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eSgnXFxcXC5saW5rLlxcXFxbdGFyZ2V0XFxcXF0nLCA0Mik7XG4gICAqXG4gICAqIEBuYW1lIHByb3BlcnR5XG4gICAqIEBhbGlhcyBkZWVwLnByb3BlcnR5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlIChvcHRpb25hbClcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAcmV0dXJucyB2YWx1ZSBvZiBwcm9wZXJ0eSBmb3IgY2hhaW5pbmdcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgncHJvcGVydHknLCBmdW5jdGlvbiAobmFtZSwgdmFsLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcblxuICAgIHZhciBpc0RlZXAgPSAhIWZsYWcodGhpcywgJ2RlZXAnKVxuICAgICAgLCBkZXNjcmlwdG9yID0gaXNEZWVwID8gJ2RlZXAgcHJvcGVydHkgJyA6ICdwcm9wZXJ0eSAnXG4gICAgICAsIG5lZ2F0ZSA9IGZsYWcodGhpcywgJ25lZ2F0ZScpXG4gICAgICAsIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIHBhdGhJbmZvID0gaXNEZWVwID8gXy5nZXRQYXRoSW5mbyhuYW1lLCBvYmopIDogbnVsbFxuICAgICAgLCBoYXNQcm9wZXJ0eSA9IGlzRGVlcFxuICAgICAgICA/IHBhdGhJbmZvLmV4aXN0c1xuICAgICAgICA6IF8uaGFzUHJvcGVydHkobmFtZSwgb2JqKVxuICAgICAgLCB2YWx1ZSA9IGlzRGVlcFxuICAgICAgICA/IHBhdGhJbmZvLnZhbHVlXG4gICAgICAgIDogb2JqW25hbWVdO1xuXG4gICAgaWYgKG5lZ2F0ZSAmJiBhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgaWYgKHVuZGVmaW5lZCA9PT0gdmFsdWUpIHtcbiAgICAgICAgbXNnID0gKG1zZyAhPSBudWxsKSA/IG1zZyArICc6ICcgOiAnJztcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyArIF8uaW5zcGVjdChvYmopICsgJyBoYXMgbm8gJyArIGRlc2NyaXB0b3IgKyBfLmluc3BlY3QobmFtZSkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBoYXNQcm9wZXJ0eVxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSAnICsgZGVzY3JpcHRvciArIF8uaW5zcGVjdChuYW1lKVxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlICcgKyBkZXNjcmlwdG9yICsgXy5pbnNwZWN0KG5hbWUpKTtcbiAgICB9XG5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIHZhbCA9PT0gdmFsdWVcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgJyArIGRlc2NyaXB0b3IgKyBfLmluc3BlY3QobmFtZSkgKyAnIG9mICN7ZXhwfSwgYnV0IGdvdCAje2FjdH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgYSAnICsgZGVzY3JpcHRvciArIF8uaW5zcGVjdChuYW1lKSArICcgb2YgI3thY3R9J1xuICAgICAgICAsIHZhbFxuICAgICAgICAsIHZhbHVlXG4gICAgICApO1xuICAgIH1cblxuICAgIGZsYWcodGhpcywgJ29iamVjdCcsIHZhbHVlKTtcbiAgfSk7XG5cblxuICAvKipcbiAgICogIyMjIC5vd25Qcm9wZXJ0eShuYW1lKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBoYXMgYW4gb3duIHByb3BlcnR5IGBuYW1lYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgndGVzdCcpLnRvLmhhdmUub3duUHJvcGVydHkoJ2xlbmd0aCcpO1xuICAgKlxuICAgKiBAbmFtZSBvd25Qcm9wZXJ0eVxuICAgKiBAYWxpYXMgaGF2ZU93blByb3BlcnR5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0T3duUHJvcGVydHkgKG5hbWUsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgb2JqLmhhc093blByb3BlcnR5KG5hbWUpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgb3duIHByb3BlcnR5ICcgKyBfLmluc3BlY3QobmFtZSlcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgb3duIHByb3BlcnR5ICcgKyBfLmluc3BlY3QobmFtZSlcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnb3duUHJvcGVydHknLCBhc3NlcnRPd25Qcm9wZXJ0eSk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2hhdmVPd25Qcm9wZXJ0eScsIGFzc2VydE93blByb3BlcnR5KTtcblxuICAvKipcbiAgICogIyMjIC5vd25Qcm9wZXJ0eURlc2NyaXB0b3IobmFtZVssIGRlc2NyaXB0b3JbLCBtZXNzYWdlXV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGhhcyBhbiBvd24gcHJvcGVydHkgZGVzY3JpcHRvciBgbmFtZWAsIHRoYXQgb3B0aW9uYWxseSBtYXRjaGVzIGBkZXNjcmlwdG9yYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgndGVzdCcpLnRvLmhhdmUub3duUHJvcGVydHlEZXNjcmlwdG9yKCdsZW5ndGgnKTtcbiAgICogICAgIGV4cGVjdCgndGVzdCcpLnRvLmhhdmUub3duUHJvcGVydHlEZXNjcmlwdG9yKCdsZW5ndGgnLCB7IGVudW1lcmFibGU6IGZhbHNlLCBjb25maWd1cmFibGU6IGZhbHNlLCB3cml0YWJsZTogZmFsc2UsIHZhbHVlOiA0IH0pO1xuICAgKiAgICAgZXhwZWN0KCd0ZXN0Jykubm90LnRvLmhhdmUub3duUHJvcGVydHlEZXNjcmlwdG9yKCdsZW5ndGgnLCB7IGVudW1lcmFibGU6IGZhbHNlLCBjb25maWd1cmFibGU6IGZhbHNlLCB3cml0YWJsZTogZmFsc2UsIHZhbHVlOiAzIH0pO1xuICAgKiAgICAgZXhwZWN0KCd0ZXN0Jykub3duUHJvcGVydHlEZXNjcmlwdG9yKCdsZW5ndGgnKS50by5oYXZlLnByb3BlcnR5KCdlbnVtZXJhYmxlJywgZmFsc2UpO1xuICAgKiAgICAgZXhwZWN0KCd0ZXN0Jykub3duUHJvcGVydHlEZXNjcmlwdG9yKCdsZW5ndGgnKS50by5oYXZlLmtleXMoJ3ZhbHVlJyk7XG4gICAqXG4gICAqIEBuYW1lIG93blByb3BlcnR5RGVzY3JpcHRvclxuICAgKiBAYWxpYXMgaGF2ZU93blByb3BlcnR5RGVzY3JpcHRvclxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciBfb3B0aW9uYWxfXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0T3duUHJvcGVydHlEZXNjcmlwdG9yIChuYW1lLCBkZXNjcmlwdG9yLCBtc2cpIHtcbiAgICBpZiAodHlwZW9mIGRlc2NyaXB0b3IgPT09ICdzdHJpbmcnKSB7XG4gICAgICBtc2cgPSBkZXNjcmlwdG9yO1xuICAgICAgZGVzY3JpcHRvciA9IG51bGw7XG4gICAgfVxuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICB2YXIgYWN0dWFsRGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoT2JqZWN0KG9iaiksIG5hbWUpO1xuICAgIGlmIChhY3R1YWxEZXNjcmlwdG9yICYmIGRlc2NyaXB0b3IpIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIF8uZXFsKGRlc2NyaXB0b3IsIGFjdHVhbERlc2NyaXB0b3IpXG4gICAgICAgICwgJ2V4cGVjdGVkIHRoZSBvd24gcHJvcGVydHkgZGVzY3JpcHRvciBmb3IgJyArIF8uaW5zcGVjdChuYW1lKSArICcgb24gI3t0aGlzfSB0byBtYXRjaCAnICsgXy5pbnNwZWN0KGRlc2NyaXB0b3IpICsgJywgZ290ICcgKyBfLmluc3BlY3QoYWN0dWFsRGVzY3JpcHRvcilcbiAgICAgICAgLCAnZXhwZWN0ZWQgdGhlIG93biBwcm9wZXJ0eSBkZXNjcmlwdG9yIGZvciAnICsgXy5pbnNwZWN0KG5hbWUpICsgJyBvbiAje3RoaXN9IHRvIG5vdCBtYXRjaCAnICsgXy5pbnNwZWN0KGRlc2NyaXB0b3IpXG4gICAgICAgICwgZGVzY3JpcHRvclxuICAgICAgICAsIGFjdHVhbERlc2NyaXB0b3JcbiAgICAgICAgLCB0cnVlXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBhY3R1YWxEZXNjcmlwdG9yXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSBhbiBvd24gcHJvcGVydHkgZGVzY3JpcHRvciBmb3IgJyArIF8uaW5zcGVjdChuYW1lKVxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlIGFuIG93biBwcm9wZXJ0eSBkZXNjcmlwdG9yIGZvciAnICsgXy5pbnNwZWN0KG5hbWUpXG4gICAgICApO1xuICAgIH1cbiAgICBmbGFnKHRoaXMsICdvYmplY3QnLCBhY3R1YWxEZXNjcmlwdG9yKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ293blByb3BlcnR5RGVzY3JpcHRvcicsIGFzc2VydE93blByb3BlcnR5RGVzY3JpcHRvcik7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2hhdmVPd25Qcm9wZXJ0eURlc2NyaXB0b3InLCBhc3NlcnRPd25Qcm9wZXJ0eURlc2NyaXB0b3IpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmxlbmd0aFxuICAgKlxuICAgKiBTZXRzIHRoZSBgZG9MZW5ndGhgIGZsYWcgbGF0ZXIgdXNlZCBhcyBhIGNoYWluIHByZWN1cnNvciB0byBhIHZhbHVlXG4gICAqIGNvbXBhcmlzb24gZm9yIHRoZSBgbGVuZ3RoYCBwcm9wZXJ0eS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGguYWJvdmUoMik7XG4gICAqICAgICBleHBlY3QoWyAxLCAyLCAzIF0pLnRvLmhhdmUubGVuZ3RoLmFib3ZlKDIpO1xuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5oYXZlLmxlbmd0aC5iZWxvdyg0KTtcbiAgICogICAgIGV4cGVjdChbIDEsIDIsIDMgXSkudG8uaGF2ZS5sZW5ndGguYmVsb3coNCk7XG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoLndpdGhpbigyLDQpO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5oYXZlLmxlbmd0aC53aXRoaW4oMiw0KTtcbiAgICpcbiAgICogKkRlcHJlY2F0aW9uIG5vdGljZToqIFVzaW5nIGBsZW5ndGhgIGFzIGFuIGFzc2VydGlvbiB3aWxsIGJlIGRlcHJlY2F0ZWRcbiAgICogaW4gdmVyc2lvbiAyLjQuMCBhbmQgcmVtb3ZlZCBpbiAzLjAuMC4gQ29kZSB1c2luZyB0aGUgb2xkIHN0eWxlIG9mXG4gICAqIGFzc2VydGluZyBmb3IgYGxlbmd0aGAgcHJvcGVydHkgdmFsdWUgdXNpbmcgYGxlbmd0aCh2YWx1ZSlgIHNob3VsZCBiZVxuICAgKiBzd2l0Y2hlZCB0byB1c2UgYGxlbmd0aE9mKHZhbHVlKWAgaW5zdGVhZC5cbiAgICpcbiAgICogQG5hbWUgbGVuZ3RoXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIC8qKlxuICAgKiAjIyMgLmxlbmd0aE9mKHZhbHVlWywgbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0J3MgYGxlbmd0aGAgcHJvcGVydHkgaGFzXG4gICAqIHRoZSBleHBlY3RlZCB2YWx1ZS5cbiAgICpcbiAgICogICAgIGV4cGVjdChbIDEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mKDMpO1xuICAgKiAgICAgZXhwZWN0KCdmb29iYXInKS50by5oYXZlLmxlbmd0aE9mKDYpO1xuICAgKlxuICAgKiBAbmFtZSBsZW5ndGhPZlxuICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0TGVuZ3RoQ2hhaW4gKCkge1xuICAgIGZsYWcodGhpcywgJ2RvTGVuZ3RoJywgdHJ1ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBhc3NlcnRMZW5ndGggKG4sIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICB2YXIgbGVuID0gb2JqLmxlbmd0aDtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBsZW4gPT0gblxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgbGVuZ3RoIG9mICN7ZXhwfSBidXQgZ290ICN7YWN0fSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgYSBsZW5ndGggb2YgI3thY3R9J1xuICAgICAgLCBuXG4gICAgICAsIGxlblxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdsZW5ndGgnLCBhc3NlcnRMZW5ndGgsIGFzc2VydExlbmd0aENoYWluKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbGVuZ3RoT2YnLCBhc3NlcnRMZW5ndGgpO1xuXG4gIC8qKlxuICAgKiAjIyMgLm1hdGNoKHJlZ2V4cClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgbWF0Y2hlcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbi5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vYmFyJykudG8ubWF0Y2goL15mb28vKTtcbiAgICpcbiAgICogQG5hbWUgbWF0Y2hcbiAgICogQGFsaWFzIG1hdGNoZXNcbiAgICogQHBhcmFtIHtSZWdFeHB9IFJlZ3VsYXJFeHByZXNzaW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG4gIGZ1bmN0aW9uIGFzc2VydE1hdGNoKHJlLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIHJlLmV4ZWMob2JqKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBtYXRjaCAnICsgcmVcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIG1hdGNoICcgKyByZVxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdtYXRjaCcsIGFzc2VydE1hdGNoKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbWF0Y2hlcycsIGFzc2VydE1hdGNoKTtcblxuICAvKipcbiAgICogIyMjIC5zdHJpbmcoc3RyaW5nKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHN0cmluZyB0YXJnZXQgY29udGFpbnMgYW5vdGhlciBzdHJpbmcuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2Zvb2JhcicpLnRvLmhhdmUuc3RyaW5nKCdiYXInKTtcbiAgICpcbiAgICogQG5hbWUgc3RyaW5nXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHJpbmdcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdzdHJpbmcnLCBmdW5jdGlvbiAoc3RyLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykuaXMuYSgnc3RyaW5nJyk7XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgfm9iai5pbmRleE9mKHN0cilcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gY29udGFpbiAnICsgXy5pbnNwZWN0KHN0cilcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGNvbnRhaW4gJyArIF8uaW5zcGVjdChzdHIpXG4gICAgKTtcbiAgfSk7XG5cblxuICAvKipcbiAgICogIyMjIC5rZXlzKGtleTEsIFtrZXkyXSwgWy4uLl0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGNvbnRhaW5zIGFueSBvciBhbGwgb2YgdGhlIHBhc3NlZC1pbiBrZXlzLlxuICAgKiBVc2UgaW4gY29tYmluYXRpb24gd2l0aCBgYW55YCwgYGFsbGAsIGBjb250YWluc2AsIG9yIGBoYXZlYCB3aWxsIGFmZmVjdFxuICAgKiB3aGF0IHdpbGwgcGFzcy5cbiAgICpcbiAgICogV2hlbiB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggYGFueWAsIGF0IGxlYXN0IG9uZSBrZXkgdGhhdCBpcyBwYXNzZWRcbiAgICogaW4gbXVzdCBleGlzdCBpbiB0aGUgdGFyZ2V0IG9iamVjdC4gVGhpcyBpcyByZWdhcmRsZXNzIHdoZXRoZXIgb3Igbm90XG4gICAqIHRoZSBgaGF2ZWAgb3IgYGNvbnRhaW5gIHF1YWxpZmllcnMgYXJlIHVzZWQuIE5vdGUsIGVpdGhlciBgYW55YCBvciBgYWxsYFxuICAgKiBzaG91bGQgYmUgdXNlZCBpbiB0aGUgYXNzZXJ0aW9uLiBJZiBuZWl0aGVyIGFyZSB1c2VkLCB0aGUgYXNzZXJ0aW9uIGlzXG4gICAqIGRlZmF1bHRlZCB0byBgYWxsYC5cbiAgICpcbiAgICogV2hlbiBib3RoIGBhbGxgIGFuZCBgY29udGFpbmAgYXJlIHVzZWQsIHRoZSB0YXJnZXQgb2JqZWN0IG11c3QgaGF2ZSBhdFxuICAgKiBsZWFzdCBhbGwgb2YgdGhlIHBhc3NlZC1pbiBrZXlzIGJ1dCBtYXkgaGF2ZSBtb3JlIGtleXMgbm90IGxpc3RlZC5cbiAgICpcbiAgICogV2hlbiBib3RoIGBhbGxgIGFuZCBgaGF2ZWAgYXJlIHVzZWQsIHRoZSB0YXJnZXQgb2JqZWN0IG11c3QgYm90aCBjb250YWluXG4gICAqIGFsbCBvZiB0aGUgcGFzc2VkLWluIGtleXMgQU5EIHRoZSBudW1iZXIgb2Yga2V5cyBpbiB0aGUgdGFyZ2V0IG9iamVjdCBtdXN0XG4gICAqIG1hdGNoIHRoZSBudW1iZXIgb2Yga2V5cyBwYXNzZWQgaW4gKGluIG90aGVyIHdvcmRzLCBhIHRhcmdldCBvYmplY3QgbXVzdFxuICAgKiBoYXZlIGFsbCBhbmQgb25seSBhbGwgb2YgdGhlIHBhc3NlZC1pbiBrZXlzKS5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7IGZvbzogMSwgYmFyOiAyIH0pLnRvLmhhdmUuYW55LmtleXMoJ2ZvbycsICdiYXonKTtcbiAgICogICAgIGV4cGVjdCh7IGZvbzogMSwgYmFyOiAyIH0pLnRvLmhhdmUuYW55LmtleXMoJ2ZvbycpO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAxLCBiYXI6IDIgfSkudG8uY29udGFpbi5hbnkua2V5cygnYmFyJywgJ2JheicpO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAxLCBiYXI6IDIgfSkudG8uY29udGFpbi5hbnkua2V5cyhbJ2ZvbyddKTtcbiAgICogICAgIGV4cGVjdCh7IGZvbzogMSwgYmFyOiAyIH0pLnRvLmNvbnRhaW4uYW55LmtleXMoeydmb28nOiA2fSk7XG4gICAqICAgICBleHBlY3QoeyBmb286IDEsIGJhcjogMiB9KS50by5oYXZlLmFsbC5rZXlzKFsnYmFyJywgJ2ZvbyddKTtcbiAgICogICAgIGV4cGVjdCh7IGZvbzogMSwgYmFyOiAyIH0pLnRvLmhhdmUuYWxsLmtleXMoeydiYXInOiA2LCAnZm9vJzogN30pO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAxLCBiYXI6IDIsIGJhejogMyB9KS50by5jb250YWluLmFsbC5rZXlzKFsnYmFyJywgJ2ZvbyddKTtcbiAgICogICAgIGV4cGVjdCh7IGZvbzogMSwgYmFyOiAyLCBiYXo6IDMgfSkudG8uY29udGFpbi5hbGwua2V5cyh7J2Jhcic6IDZ9KTtcbiAgICpcbiAgICpcbiAgICogQG5hbWUga2V5c1xuICAgKiBAYWxpYXMga2V5XG4gICAqIEBwYXJhbSB7Li4uU3RyaW5nfEFycmF5fE9iamVjdH0ga2V5c1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRLZXlzIChrZXlzKSB7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIHN0clxuICAgICAgLCBvayA9IHRydWVcbiAgICAgICwgbWl4ZWRBcmdzTXNnID0gJ2tleXMgbXVzdCBiZSBnaXZlbiBzaW5nbGUgYXJndW1lbnQgb2YgQXJyYXl8T2JqZWN0fFN0cmluZywgb3IgbXVsdGlwbGUgU3RyaW5nIGFyZ3VtZW50cyc7XG5cbiAgICBzd2l0Y2ggKF8udHlwZShrZXlzKSkge1xuICAgICAgY2FzZSBcImFycmF5XCI6XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkgdGhyb3cgKG5ldyBFcnJvcihtaXhlZEFyZ3NNc2cpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkgdGhyb3cgKG5ldyBFcnJvcihtaXhlZEFyZ3NNc2cpKTtcbiAgICAgICAga2V5cyA9IE9iamVjdC5rZXlzKGtleXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGtleXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIGlmICgha2V5cy5sZW5ndGgpIHRocm93IG5ldyBFcnJvcigna2V5cyByZXF1aXJlZCcpO1xuXG4gICAgdmFyIGFjdHVhbCA9IE9iamVjdC5rZXlzKG9iailcbiAgICAgICwgZXhwZWN0ZWQgPSBrZXlzXG4gICAgICAsIGxlbiA9IGtleXMubGVuZ3RoXG4gICAgICAsIGFueSA9IGZsYWcodGhpcywgJ2FueScpXG4gICAgICAsIGFsbCA9IGZsYWcodGhpcywgJ2FsbCcpO1xuXG4gICAgaWYgKCFhbnkgJiYgIWFsbCkge1xuICAgICAgYWxsID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBIYXMgYW55XG4gICAgaWYgKGFueSkge1xuICAgICAgdmFyIGludGVyc2VjdGlvbiA9IGV4cGVjdGVkLmZpbHRlcihmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgcmV0dXJuIH5hY3R1YWwuaW5kZXhPZihrZXkpO1xuICAgICAgfSk7XG4gICAgICBvayA9IGludGVyc2VjdGlvbi5sZW5ndGggPiAwO1xuICAgIH1cblxuICAgIC8vIEhhcyBhbGxcbiAgICBpZiAoYWxsKSB7XG4gICAgICBvayA9IGtleXMuZXZlcnkoZnVuY3Rpb24oa2V5KXtcbiAgICAgICAgcmV0dXJuIH5hY3R1YWwuaW5kZXhPZihrZXkpO1xuICAgICAgfSk7XG4gICAgICBpZiAoIWZsYWcodGhpcywgJ25lZ2F0ZScpICYmICFmbGFnKHRoaXMsICdjb250YWlucycpKSB7XG4gICAgICAgIG9rID0gb2sgJiYga2V5cy5sZW5ndGggPT0gYWN0dWFsLmxlbmd0aDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBLZXkgc3RyaW5nXG4gICAgaWYgKGxlbiA+IDEpIHtcbiAgICAgIGtleXMgPSBrZXlzLm1hcChmdW5jdGlvbihrZXkpe1xuICAgICAgICByZXR1cm4gXy5pbnNwZWN0KGtleSk7XG4gICAgICB9KTtcbiAgICAgIHZhciBsYXN0ID0ga2V5cy5wb3AoKTtcbiAgICAgIGlmIChhbGwpIHtcbiAgICAgICAgc3RyID0ga2V5cy5qb2luKCcsICcpICsgJywgYW5kICcgKyBsYXN0O1xuICAgICAgfVxuICAgICAgaWYgKGFueSkge1xuICAgICAgICBzdHIgPSBrZXlzLmpvaW4oJywgJykgKyAnLCBvciAnICsgbGFzdDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gXy5pbnNwZWN0KGtleXNbMF0pO1xuICAgIH1cblxuICAgIC8vIEZvcm1cbiAgICBzdHIgPSAobGVuID4gMSA/ICdrZXlzICcgOiAna2V5ICcpICsgc3RyO1xuXG4gICAgLy8gSGF2ZSAvIGluY2x1ZGVcbiAgICBzdHIgPSAoZmxhZyh0aGlzLCAnY29udGFpbnMnKSA/ICdjb250YWluICcgOiAnaGF2ZSAnKSArIHN0cjtcblxuICAgIC8vIEFzc2VydGlvblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBva1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byAnICsgc3RyXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCAnICsgc3RyXG4gICAgICAsIGV4cGVjdGVkLnNsaWNlKDApLnNvcnQoKVxuICAgICAgLCBhY3R1YWwuc29ydCgpXG4gICAgICAsIHRydWVcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgna2V5cycsIGFzc2VydEtleXMpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdrZXknLCBhc3NlcnRLZXlzKTtcblxuICAvKipcbiAgICogIyMjIC50aHJvdyhjb25zdHJ1Y3RvcilcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSBmdW5jdGlvbiB0YXJnZXQgd2lsbCB0aHJvdyBhIHNwZWNpZmljIGVycm9yLCBvciBzcGVjaWZpYyB0eXBlIG9mIGVycm9yXG4gICAqIChhcyBkZXRlcm1pbmVkIHVzaW5nIGBpbnN0YW5jZW9mYCksIG9wdGlvbmFsbHkgd2l0aCBhIFJlZ0V4cCBvciBzdHJpbmcgaW5jbHVzaW9uIHRlc3RcbiAgICogZm9yIHRoZSBlcnJvcidzIG1lc3NhZ2UuXG4gICAqXG4gICAqICAgICB2YXIgZXJyID0gbmV3IFJlZmVyZW5jZUVycm9yKCdUaGlzIGlzIGEgYmFkIGZ1bmN0aW9uLicpO1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24gKCkgeyB0aHJvdyBlcnI7IH1cbiAgICogICAgIGV4cGVjdChmbikudG8udGhyb3coUmVmZXJlbmNlRXJyb3IpO1xuICAgKiAgICAgZXhwZWN0KGZuKS50by50aHJvdyhFcnJvcik7XG4gICAqICAgICBleHBlY3QoZm4pLnRvLnRocm93KC9iYWQgZnVuY3Rpb24vKTtcbiAgICogICAgIGV4cGVjdChmbikudG8ubm90LnRocm93KCdnb29kIGZ1bmN0aW9uJyk7XG4gICAqICAgICBleHBlY3QoZm4pLnRvLnRocm93KFJlZmVyZW5jZUVycm9yLCAvYmFkIGZ1bmN0aW9uLyk7XG4gICAqICAgICBleHBlY3QoZm4pLnRvLnRocm93KGVycik7XG4gICAqXG4gICAqIFBsZWFzZSBub3RlIHRoYXQgd2hlbiBhIHRocm93IGV4cGVjdGF0aW9uIGlzIG5lZ2F0ZWQsIGl0IHdpbGwgY2hlY2sgZWFjaFxuICAgKiBwYXJhbWV0ZXIgaW5kZXBlbmRlbnRseSwgc3RhcnRpbmcgd2l0aCBlcnJvciBjb25zdHJ1Y3RvciB0eXBlLiBUaGUgYXBwcm9wcmlhdGUgd2F5XG4gICAqIHRvIGNoZWNrIGZvciB0aGUgZXhpc3RlbmNlIG9mIGEgdHlwZSBvZiBlcnJvciBidXQgZm9yIGEgbWVzc2FnZSB0aGF0IGRvZXMgbm90IG1hdGNoXG4gICAqIGlzIHRvIHVzZSBgYW5kYC5cbiAgICpcbiAgICogICAgIGV4cGVjdChmbikudG8udGhyb3coUmVmZXJlbmNlRXJyb3IpXG4gICAqICAgICAgICAuYW5kLm5vdC50aHJvdygvZ29vZCBmdW5jdGlvbi8pO1xuICAgKlxuICAgKiBAbmFtZSB0aHJvd1xuICAgKiBAYWxpYXMgdGhyb3dzXG4gICAqIEBhbGlhcyBUaHJvd1xuICAgKiBAcGFyYW0ge0Vycm9yQ29uc3RydWN0b3J9IGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXhwZWN0ZWQgZXJyb3IgbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRXJyb3IjRXJyb3JfdHlwZXNcbiAgICogQHJldHVybnMgZXJyb3IgZm9yIGNoYWluaW5nIChudWxsIGlmIG5vIGVycm9yKVxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRUaHJvd3MgKGNvbnN0cnVjdG9yLCBlcnJNc2csIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS5pcy5hKCdmdW5jdGlvbicpO1xuXG4gICAgdmFyIHRocm93biA9IGZhbHNlXG4gICAgICAsIGRlc2lyZWRFcnJvciA9IG51bGxcbiAgICAgICwgbmFtZSA9IG51bGxcbiAgICAgICwgdGhyb3duRXJyb3IgPSBudWxsO1xuXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGVyck1zZyA9IG51bGw7XG4gICAgICBjb25zdHJ1Y3RvciA9IG51bGw7XG4gICAgfSBlbHNlIGlmIChjb25zdHJ1Y3RvciAmJiAoY29uc3RydWN0b3IgaW5zdGFuY2VvZiBSZWdFeHAgfHwgJ3N0cmluZycgPT09IHR5cGVvZiBjb25zdHJ1Y3RvcikpIHtcbiAgICAgIGVyck1zZyA9IGNvbnN0cnVjdG9yO1xuICAgICAgY29uc3RydWN0b3IgPSBudWxsO1xuICAgIH0gZWxzZSBpZiAoY29uc3RydWN0b3IgJiYgY29uc3RydWN0b3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgZGVzaXJlZEVycm9yID0gY29uc3RydWN0b3I7XG4gICAgICBjb25zdHJ1Y3RvciA9IG51bGw7XG4gICAgICBlcnJNc2cgPSBudWxsO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGNvbnN0cnVjdG9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBuYW1lID0gY29uc3RydWN0b3IucHJvdG90eXBlLm5hbWU7XG4gICAgICBpZiAoIW5hbWUgfHwgKG5hbWUgPT09ICdFcnJvcicgJiYgY29uc3RydWN0b3IgIT09IEVycm9yKSkge1xuICAgICAgICBuYW1lID0gY29uc3RydWN0b3IubmFtZSB8fCAobmV3IGNvbnN0cnVjdG9yKCkpLm5hbWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0cnVjdG9yID0gbnVsbDtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgb2JqKCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBmaXJzdCwgY2hlY2sgZGVzaXJlZCBlcnJvclxuICAgICAgaWYgKGRlc2lyZWRFcnJvcikge1xuICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgIGVyciA9PT0gZGVzaXJlZEVycm9yXG4gICAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byB0aHJvdyAje2V4cH0gYnV0ICN7YWN0fSB3YXMgdGhyb3duJ1xuICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IHRocm93ICN7ZXhwfSdcbiAgICAgICAgICAsIChkZXNpcmVkRXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGRlc2lyZWRFcnJvci50b1N0cmluZygpIDogZGVzaXJlZEVycm9yKVxuICAgICAgICAgICwgKGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLnRvU3RyaW5nKCkgOiBlcnIpXG4gICAgICAgICk7XG5cbiAgICAgICAgZmxhZyh0aGlzLCAnb2JqZWN0JywgZXJyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIG5leHQsIGNoZWNrIGNvbnN0cnVjdG9yXG4gICAgICBpZiAoY29uc3RydWN0b3IpIHtcbiAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICBlcnIgaW5zdGFuY2VvZiBjb25zdHJ1Y3RvclxuICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gdGhyb3cgI3tleHB9IGJ1dCAje2FjdH0gd2FzIHRocm93bidcbiAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCB0aHJvdyAje2V4cH0gYnV0ICN7YWN0fSB3YXMgdGhyb3duJ1xuICAgICAgICAgICwgbmFtZVxuICAgICAgICAgICwgKGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLnRvU3RyaW5nKCkgOiBlcnIpXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKCFlcnJNc2cpIHtcbiAgICAgICAgICBmbGFnKHRoaXMsICdvYmplY3QnLCBlcnIpO1xuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIG5leHQsIGNoZWNrIG1lc3NhZ2VcbiAgICAgIHZhciBtZXNzYWdlID0gJ2Vycm9yJyA9PT0gXy50eXBlKGVycikgJiYgXCJtZXNzYWdlXCIgaW4gZXJyXG4gICAgICAgID8gZXJyLm1lc3NhZ2VcbiAgICAgICAgOiAnJyArIGVycjtcblxuICAgICAgaWYgKChtZXNzYWdlICE9IG51bGwpICYmIGVyck1zZyAmJiBlcnJNc2cgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICBlcnJNc2cuZXhlYyhtZXNzYWdlKVxuICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gdGhyb3cgZXJyb3IgbWF0Y2hpbmcgI3tleHB9IGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gdGhyb3cgZXJyb3Igbm90IG1hdGNoaW5nICN7ZXhwfSdcbiAgICAgICAgICAsIGVyck1zZ1xuICAgICAgICAgICwgbWVzc2FnZVxuICAgICAgICApO1xuXG4gICAgICAgIGZsYWcodGhpcywgJ29iamVjdCcsIGVycik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfSBlbHNlIGlmICgobWVzc2FnZSAhPSBudWxsKSAmJiBlcnJNc2cgJiYgJ3N0cmluZycgPT09IHR5cGVvZiBlcnJNc2cpIHtcbiAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICB+bWVzc2FnZS5pbmRleE9mKGVyck1zZylcbiAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIHRocm93IGVycm9yIGluY2x1ZGluZyAje2V4cH0gYnV0IGdvdCAje2FjdH0nXG4gICAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byB0aHJvdyBlcnJvciBub3QgaW5jbHVkaW5nICN7YWN0fSdcbiAgICAgICAgICAsIGVyck1zZ1xuICAgICAgICAgICwgbWVzc2FnZVxuICAgICAgICApO1xuXG4gICAgICAgIGZsYWcodGhpcywgJ29iamVjdCcsIGVycik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3duID0gdHJ1ZTtcbiAgICAgICAgdGhyb3duRXJyb3IgPSBlcnI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGFjdHVhbGx5R290ID0gJydcbiAgICAgICwgZXhwZWN0ZWRUaHJvd24gPSBuYW1lICE9PSBudWxsXG4gICAgICAgID8gbmFtZVxuICAgICAgICA6IGRlc2lyZWRFcnJvclxuICAgICAgICAgID8gJyN7ZXhwfScgLy9fLmluc3BlY3QoZGVzaXJlZEVycm9yKVxuICAgICAgICAgIDogJ2FuIGVycm9yJztcblxuICAgIGlmICh0aHJvd24pIHtcbiAgICAgIGFjdHVhbGx5R290ID0gJyBidXQgI3thY3R9IHdhcyB0aHJvd24nXG4gICAgfVxuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIHRocm93biA9PT0gdHJ1ZVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byB0aHJvdyAnICsgZXhwZWN0ZWRUaHJvd24gKyBhY3R1YWxseUdvdFxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgdGhyb3cgJyArIGV4cGVjdGVkVGhyb3duICsgYWN0dWFsbHlHb3RcbiAgICAgICwgKGRlc2lyZWRFcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZGVzaXJlZEVycm9yLnRvU3RyaW5nKCkgOiBkZXNpcmVkRXJyb3IpXG4gICAgICAsICh0aHJvd25FcnJvciBpbnN0YW5jZW9mIEVycm9yID8gdGhyb3duRXJyb3IudG9TdHJpbmcoKSA6IHRocm93bkVycm9yKVxuICAgICk7XG5cbiAgICBmbGFnKHRoaXMsICdvYmplY3QnLCB0aHJvd25FcnJvcik7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgndGhyb3cnLCBhc3NlcnRUaHJvd3MpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCd0aHJvd3MnLCBhc3NlcnRUaHJvd3MpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdUaHJvdycsIGFzc2VydFRocm93cyk7XG5cbiAgLyoqXG4gICAqICMjIyAucmVzcG9uZFRvKG1ldGhvZClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSBvYmplY3Qgb3IgY2xhc3MgdGFyZ2V0IHdpbGwgcmVzcG9uZCB0byBhIG1ldGhvZC5cbiAgICpcbiAgICogICAgIEtsYXNzLnByb3RvdHlwZS5iYXIgPSBmdW5jdGlvbigpe307XG4gICAqICAgICBleHBlY3QoS2xhc3MpLnRvLnJlc3BvbmRUbygnYmFyJyk7XG4gICAqICAgICBleHBlY3Qob2JqKS50by5yZXNwb25kVG8oJ2JhcicpO1xuICAgKlxuICAgKiBUbyBjaGVjayBpZiBhIGNvbnN0cnVjdG9yIHdpbGwgcmVzcG9uZCB0byBhIHN0YXRpYyBmdW5jdGlvbixcbiAgICogc2V0IHRoZSBgaXRzZWxmYCBmbGFnLlxuICAgKlxuICAgKiAgICAgS2xhc3MuYmF6ID0gZnVuY3Rpb24oKXt9O1xuICAgKiAgICAgZXhwZWN0KEtsYXNzKS5pdHNlbGYudG8ucmVzcG9uZFRvKCdiYXonKTtcbiAgICpcbiAgICogQG5hbWUgcmVzcG9uZFRvXG4gICAqIEBhbGlhcyByZXNwb25kc1RvXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiByZXNwb25kVG8gKG1ldGhvZCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIGl0c2VsZiA9IGZsYWcodGhpcywgJ2l0c2VsZicpXG4gICAgICAsIGNvbnRleHQgPSAoJ2Z1bmN0aW9uJyA9PT0gXy50eXBlKG9iaikgJiYgIWl0c2VsZilcbiAgICAgICAgPyBvYmoucHJvdG90eXBlW21ldGhvZF1cbiAgICAgICAgOiBvYmpbbWV0aG9kXTtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAnZnVuY3Rpb24nID09PSB0eXBlb2YgY29udGV4dFxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byByZXNwb25kIHRvICcgKyBfLmluc3BlY3QobWV0aG9kKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgcmVzcG9uZCB0byAnICsgXy5pbnNwZWN0KG1ldGhvZClcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgncmVzcG9uZFRvJywgcmVzcG9uZFRvKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgncmVzcG9uZHNUbycsIHJlc3BvbmRUbyk7XG5cbiAgLyoqXG4gICAqICMjIyAuaXRzZWxmXG4gICAqXG4gICAqIFNldHMgdGhlIGBpdHNlbGZgIGZsYWcsIGxhdGVyIHVzZWQgYnkgdGhlIGByZXNwb25kVG9gIGFzc2VydGlvbi5cbiAgICpcbiAgICogICAgIGZ1bmN0aW9uIEZvbygpIHt9XG4gICAqICAgICBGb28uYmFyID0gZnVuY3Rpb24oKSB7fVxuICAgKiAgICAgRm9vLnByb3RvdHlwZS5iYXogPSBmdW5jdGlvbigpIHt9XG4gICAqXG4gICAqICAgICBleHBlY3QoRm9vKS5pdHNlbGYudG8ucmVzcG9uZFRvKCdiYXInKTtcbiAgICogICAgIGV4cGVjdChGb28pLml0c2VsZi5ub3QudG8ucmVzcG9uZFRvKCdiYXonKTtcbiAgICpcbiAgICogQG5hbWUgaXRzZWxmXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnaXRzZWxmJywgZnVuY3Rpb24gKCkge1xuICAgIGZsYWcodGhpcywgJ2l0c2VsZicsIHRydWUpO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5zYXRpc2Z5KG1ldGhvZClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgcGFzc2VzIGEgZ2l2ZW4gdHJ1dGggdGVzdC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5zYXRpc2Z5KGZ1bmN0aW9uKG51bSkgeyByZXR1cm4gbnVtID4gMDsgfSk7XG4gICAqXG4gICAqIEBuYW1lIHNhdGlzZnlcbiAgICogQGFsaWFzIHNhdGlzZmllc1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtYXRjaGVyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gc2F0aXNmeSAobWF0Y2hlciwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIHZhciByZXN1bHQgPSBtYXRjaGVyKG9iaik7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIHJlc3VsdFxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBzYXRpc2Z5ICcgKyBfLm9iakRpc3BsYXkobWF0Y2hlcilcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IHNhdGlzZnknICsgXy5vYmpEaXNwbGF5KG1hdGNoZXIpXG4gICAgICAsIHRoaXMubmVnYXRlID8gZmFsc2UgOiB0cnVlXG4gICAgICAsIHJlc3VsdFxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdzYXRpc2Z5Jywgc2F0aXNmeSk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ3NhdGlzZmllcycsIHNhdGlzZnkpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmNsb3NlVG8oZXhwZWN0ZWQsIGRlbHRhKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCBgZXhwZWN0ZWRgLCB0byB3aXRoaW4gYSArLy0gYGRlbHRhYCByYW5nZS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxLjUpLnRvLmJlLmNsb3NlVG8oMSwgMC41KTtcbiAgICpcbiAgICogQG5hbWUgY2xvc2VUb1xuICAgKiBAYWxpYXMgYXBwcm94aW1hdGVseVxuICAgKiBAcGFyYW0ge051bWJlcn0gZXhwZWN0ZWRcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGRlbHRhXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gY2xvc2VUbyhleHBlY3RlZCwgZGVsdGEsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcblxuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLmlzLmEoJ251bWJlcicpO1xuICAgIGlmIChfLnR5cGUoZXhwZWN0ZWQpICE9PSAnbnVtYmVyJyB8fCBfLnR5cGUoZGVsdGEpICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgYXJndW1lbnRzIHRvIGNsb3NlVG8gb3IgYXBwcm94aW1hdGVseSBtdXN0IGJlIG51bWJlcnMnKTtcbiAgICB9XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgTWF0aC5hYnMob2JqIC0gZXhwZWN0ZWQpIDw9IGRlbHRhXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGNsb3NlIHRvICcgKyBleHBlY3RlZCArICcgKy8tICcgKyBkZWx0YVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgY2xvc2UgdG8gJyArIGV4cGVjdGVkICsgJyArLy0gJyArIGRlbHRhXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2Nsb3NlVG8nLCBjbG9zZVRvKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnYXBwcm94aW1hdGVseScsIGNsb3NlVG8pO1xuXG4gIGZ1bmN0aW9uIGlzU3Vic2V0T2Yoc3Vic2V0LCBzdXBlcnNldCwgY21wKSB7XG4gICAgcmV0dXJuIHN1YnNldC5ldmVyeShmdW5jdGlvbihlbGVtKSB7XG4gICAgICBpZiAoIWNtcCkgcmV0dXJuIHN1cGVyc2V0LmluZGV4T2YoZWxlbSkgIT09IC0xO1xuXG4gICAgICByZXR1cm4gc3VwZXJzZXQuc29tZShmdW5jdGlvbihlbGVtMikge1xuICAgICAgICByZXR1cm4gY21wKGVsZW0sIGVsZW0yKTtcbiAgICAgIH0pO1xuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogIyMjIC5tZW1iZXJzKHNldClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgYSBzdXBlcnNldCBvZiBgc2V0YCxcbiAgICogb3IgdGhhdCB0aGUgdGFyZ2V0IGFuZCBgc2V0YCBoYXZlIHRoZSBzYW1lIHN0cmljdGx5LWVxdWFsICg9PT0pIG1lbWJlcnMuXG4gICAqIEFsdGVybmF0ZWx5LCBpZiB0aGUgYGRlZXBgIGZsYWcgaXMgc2V0LCBzZXQgbWVtYmVycyBhcmUgY29tcGFyZWQgZm9yIGRlZXBcbiAgICogZXF1YWxpdHkuXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5pbmNsdWRlLm1lbWJlcnMoWzMsIDJdKTtcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLm5vdC5pbmNsdWRlLm1lbWJlcnMoWzMsIDIsIDhdKTtcbiAgICpcbiAgICogICAgIGV4cGVjdChbNCwgMl0pLnRvLmhhdmUubWVtYmVycyhbMiwgNF0pO1xuICAgKiAgICAgZXhwZWN0KFs1LCAyXSkudG8ubm90LmhhdmUubWVtYmVycyhbNSwgMiwgMV0pO1xuICAgKlxuICAgKiAgICAgZXhwZWN0KFt7IGlkOiAxIH1dKS50by5kZWVwLmluY2x1ZGUubWVtYmVycyhbeyBpZDogMSB9XSk7XG4gICAqXG4gICAqIEBuYW1lIG1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbWVtYmVycycsIGZ1bmN0aW9uIChzdWJzZXQsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcblxuICAgIG5ldyBBc3NlcnRpb24ob2JqKS50by5iZS5hbignYXJyYXknKTtcbiAgICBuZXcgQXNzZXJ0aW9uKHN1YnNldCkudG8uYmUuYW4oJ2FycmF5Jyk7XG5cbiAgICB2YXIgY21wID0gZmxhZyh0aGlzLCAnZGVlcCcpID8gXy5lcWwgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAoZmxhZyh0aGlzLCAnY29udGFpbnMnKSkge1xuICAgICAgcmV0dXJuIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIGlzU3Vic2V0T2Yoc3Vic2V0LCBvYmosIGNtcClcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBhIHN1cGVyc2V0IG9mICN7YWN0fSdcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgYSBzdXBlcnNldCBvZiAje2FjdH0nXG4gICAgICAgICwgb2JqXG4gICAgICAgICwgc3Vic2V0XG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBpc1N1YnNldE9mKG9iaiwgc3Vic2V0LCBjbXApICYmIGlzU3Vic2V0T2Yoc3Vic2V0LCBvYmosIGNtcClcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIHRoZSBzYW1lIG1lbWJlcnMgYXMgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlIHRoZSBzYW1lIG1lbWJlcnMgYXMgI3thY3R9J1xuICAgICAgICAsIG9ialxuICAgICAgICAsIHN1YnNldFxuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLm9uZU9mKGxpc3QpXG4gICAqXG4gICAqIEFzc2VydCB0aGF0IGEgdmFsdWUgYXBwZWFycyBzb21ld2hlcmUgaW4gdGhlIHRvcCBsZXZlbCBvZiBhcnJheSBgbGlzdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2EnKS50by5iZS5vbmVPZihbJ2EnLCAnYicsICdjJ10pO1xuICAgKiAgICAgZXhwZWN0KDkpLnRvLm5vdC5iZS5vbmVPZihbJ3onXSk7XG4gICAqICAgICBleHBlY3QoWzNdKS50by5ub3QuYmUub25lT2YoWzEsIDIsIFszXV0pO1xuICAgKlxuICAgKiAgICAgdmFyIHRocmVlID0gWzNdO1xuICAgKiAgICAgLy8gZm9yIG9iamVjdC10eXBlcywgY29udGVudHMgYXJlIG5vdCBjb21wYXJlZFxuICAgKiAgICAgZXhwZWN0KHRocmVlKS50by5ub3QuYmUub25lT2YoWzEsIDIsIFszXV0pO1xuICAgKiAgICAgLy8gY29tcGFyaW5nIHJlZmVyZW5jZXMgd29ya3NcbiAgICogICAgIGV4cGVjdCh0aHJlZSkudG8uYmUub25lT2YoWzEsIDIsIHRocmVlXSk7XG4gICAqXG4gICAqIEBuYW1lIG9uZU9mXG4gICAqIEBwYXJhbSB7QXJyYXk8Kj59IGxpc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBvbmVPZiAobGlzdCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIGV4cGVjdGVkID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgbmV3IEFzc2VydGlvbihsaXN0KS50by5iZS5hbignYXJyYXknKTtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBsaXN0LmluZGV4T2YoZXhwZWN0ZWQpID4gLTFcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgb25lIG9mICN7ZXhwfSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIG9uZSBvZiAje2V4cH0nXG4gICAgICAsIGxpc3RcbiAgICAgICwgZXhwZWN0ZWRcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnb25lT2YnLCBvbmVPZik7XG5cblxuICAvKipcbiAgICogIyMjIC5jaGFuZ2UoZnVuY3Rpb24pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGNoYW5nZXMgYW4gb2JqZWN0IHByb3BlcnR5XG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCArPSAzIH07XG4gICAqICAgICB2YXIgbm9DaGFuZ2VGbiA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gJ2ZvbycgKyAnYmFyJzsgfVxuICAgKiAgICAgZXhwZWN0KGZuKS50by5jaGFuZ2Uob2JqLCAndmFsJyk7XG4gICAqICAgICBleHBlY3Qobm9DaGFuZ2VGbikudG8ubm90LmNoYW5nZShvYmosICd2YWwnKVxuICAgKlxuICAgKiBAbmFtZSBjaGFuZ2VcbiAgICogQGFsaWFzIGNoYW5nZXNcbiAgICogQGFsaWFzIENoYW5nZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0Q2hhbmdlcyAob2JqZWN0LCBwcm9wLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgZm4gPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iamVjdCwgbXNnKS50by5oYXZlLnByb3BlcnR5KHByb3ApO1xuICAgIG5ldyBBc3NlcnRpb24oZm4pLmlzLmEoJ2Z1bmN0aW9uJyk7XG5cbiAgICB2YXIgaW5pdGlhbCA9IG9iamVjdFtwcm9wXTtcbiAgICBmbigpO1xuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICBpbml0aWFsICE9PSBvYmplY3RbcHJvcF1cbiAgICAgICwgJ2V4cGVjdGVkIC4nICsgcHJvcCArICcgdG8gY2hhbmdlJ1xuICAgICAgLCAnZXhwZWN0ZWQgLicgKyBwcm9wICsgJyB0byBub3QgY2hhbmdlJ1xuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdjaGFuZ2UnLCBhc3NlcnRDaGFuZ2VzKTtcbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnY2hhbmdlcycsIGFzc2VydENoYW5nZXMpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmluY3JlYXNlKGZ1bmN0aW9uKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYSBmdW5jdGlvbiBpbmNyZWFzZXMgYW4gb2JqZWN0IHByb3BlcnR5XG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCA9IDE1IH07XG4gICAqICAgICBleHBlY3QoZm4pLnRvLmluY3JlYXNlKG9iaiwgJ3ZhbCcpO1xuICAgKlxuICAgKiBAbmFtZSBpbmNyZWFzZVxuICAgKiBAYWxpYXMgaW5jcmVhc2VzXG4gICAqIEBhbGlhcyBJbmNyZWFzZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0SW5jcmVhc2VzIChvYmplY3QsIHByb3AsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBmbiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIG5ldyBBc3NlcnRpb24ob2JqZWN0LCBtc2cpLnRvLmhhdmUucHJvcGVydHkocHJvcCk7XG4gICAgbmV3IEFzc2VydGlvbihmbikuaXMuYSgnZnVuY3Rpb24nKTtcblxuICAgIHZhciBpbml0aWFsID0gb2JqZWN0W3Byb3BdO1xuICAgIGZuKCk7XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgIG9iamVjdFtwcm9wXSAtIGluaXRpYWwgPiAwXG4gICAgICAsICdleHBlY3RlZCAuJyArIHByb3AgKyAnIHRvIGluY3JlYXNlJ1xuICAgICAgLCAnZXhwZWN0ZWQgLicgKyBwcm9wICsgJyB0byBub3QgaW5jcmVhc2UnXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2luY3JlYXNlJywgYXNzZXJ0SW5jcmVhc2VzKTtcbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnaW5jcmVhc2VzJywgYXNzZXJ0SW5jcmVhc2VzKTtcblxuICAvKipcbiAgICogIyMjIC5kZWNyZWFzZShmdW5jdGlvbilcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gZGVjcmVhc2VzIGFuIG9iamVjdCBwcm9wZXJ0eVxuICAgKlxuICAgKiAgICAgdmFyIG9iaiA9IHsgdmFsOiAxMCB9O1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7IG9iai52YWwgPSA1IH07XG4gICAqICAgICBleHBlY3QoZm4pLnRvLmRlY3JlYXNlKG9iaiwgJ3ZhbCcpO1xuICAgKlxuICAgKiBAbmFtZSBkZWNyZWFzZVxuICAgKiBAYWxpYXMgZGVjcmVhc2VzXG4gICAqIEBhbGlhcyBEZWNyZWFzZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0RGVjcmVhc2VzIChvYmplY3QsIHByb3AsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBmbiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIG5ldyBBc3NlcnRpb24ob2JqZWN0LCBtc2cpLnRvLmhhdmUucHJvcGVydHkocHJvcCk7XG4gICAgbmV3IEFzc2VydGlvbihmbikuaXMuYSgnZnVuY3Rpb24nKTtcblxuICAgIHZhciBpbml0aWFsID0gb2JqZWN0W3Byb3BdO1xuICAgIGZuKCk7XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgIG9iamVjdFtwcm9wXSAtIGluaXRpYWwgPCAwXG4gICAgICAsICdleHBlY3RlZCAuJyArIHByb3AgKyAnIHRvIGRlY3JlYXNlJ1xuICAgICAgLCAnZXhwZWN0ZWQgLicgKyBwcm9wICsgJyB0byBub3QgZGVjcmVhc2UnXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2RlY3JlYXNlJywgYXNzZXJ0RGVjcmVhc2VzKTtcbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnZGVjcmVhc2VzJywgYXNzZXJ0RGVjcmVhc2VzKTtcblxuICAvKipcbiAgICogIyMjIC5leHRlbnNpYmxlXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGV4dGVuc2libGUgKGNhbiBoYXZlIG5ldyBwcm9wZXJ0aWVzIGFkZGVkIHRvXG4gICAqIGl0KS5cbiAgICpcbiAgICogICAgIHZhciBub25FeHRlbnNpYmxlT2JqZWN0ID0gT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zKHt9KTtcbiAgICogICAgIHZhciBzZWFsZWRPYmplY3QgPSBPYmplY3Quc2VhbCh7fSk7XG4gICAqICAgICB2YXIgZnJvemVuT2JqZWN0ID0gT2JqZWN0LmZyZWV6ZSh7fSk7XG4gICAqXG4gICAqICAgICBleHBlY3Qoe30pLnRvLmJlLmV4dGVuc2libGU7XG4gICAqICAgICBleHBlY3Qobm9uRXh0ZW5zaWJsZU9iamVjdCkudG8ubm90LmJlLmV4dGVuc2libGU7XG4gICAqICAgICBleHBlY3Qoc2VhbGVkT2JqZWN0KS50by5ub3QuYmUuZXh0ZW5zaWJsZTtcbiAgICogICAgIGV4cGVjdChmcm96ZW5PYmplY3QpLnRvLm5vdC5iZS5leHRlbnNpYmxlO1xuICAgKlxuICAgKiBAbmFtZSBleHRlbnNpYmxlXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZXh0ZW5zaWJsZScsIGZ1bmN0aW9uKCkge1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcblxuICAgIC8vIEluIEVTNSwgaWYgdGhlIGFyZ3VtZW50IHRvIHRoaXMgbWV0aG9kIGlzIG5vdCBhbiBvYmplY3QgKGEgcHJpbWl0aXZlKSwgdGhlbiBpdCB3aWxsIGNhdXNlIGEgVHlwZUVycm9yLlxuICAgIC8vIEluIEVTNiwgYSBub24tb2JqZWN0IGFyZ3VtZW50IHdpbGwgYmUgdHJlYXRlZCBhcyBpZiBpdCB3YXMgYSBub24tZXh0ZW5zaWJsZSBvcmRpbmFyeSBvYmplY3QsIHNpbXBseSByZXR1cm4gZmFsc2UuXG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L2lzRXh0ZW5zaWJsZVxuICAgIC8vIFRoZSBmb2xsb3dpbmcgcHJvdmlkZXMgRVM2IGJlaGF2aW9yIHdoZW4gYSBUeXBlRXJyb3IgaXMgdGhyb3duIHVuZGVyIEVTNS5cblxuICAgIHZhciBpc0V4dGVuc2libGU7XG5cbiAgICB0cnkge1xuICAgICAgaXNFeHRlbnNpYmxlID0gT2JqZWN0LmlzRXh0ZW5zaWJsZShvYmopO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIFR5cGVFcnJvcikgaXNFeHRlbnNpYmxlID0gZmFsc2U7XG4gICAgICBlbHNlIHRocm93IGVycjtcbiAgICB9XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgIGlzRXh0ZW5zaWJsZVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBleHRlbnNpYmxlJ1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgZXh0ZW5zaWJsZSdcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5zZWFsZWRcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgc2VhbGVkIChjYW5ub3QgaGF2ZSBuZXcgcHJvcGVydGllcyBhZGRlZCB0byBpdFxuICAgKiBhbmQgaXRzIGV4aXN0aW5nIHByb3BlcnRpZXMgY2Fubm90IGJlIHJlbW92ZWQpLlxuICAgKlxuICAgKiAgICAgdmFyIHNlYWxlZE9iamVjdCA9IE9iamVjdC5zZWFsKHt9KTtcbiAgICogICAgIHZhciBmcm96ZW5PYmplY3QgPSBPYmplY3QuZnJlZXplKHt9KTtcbiAgICpcbiAgICogICAgIGV4cGVjdChzZWFsZWRPYmplY3QpLnRvLmJlLnNlYWxlZDtcbiAgICogICAgIGV4cGVjdChmcm96ZW5PYmplY3QpLnRvLmJlLnNlYWxlZDtcbiAgICogICAgIGV4cGVjdCh7fSkudG8ubm90LmJlLnNlYWxlZDtcbiAgICpcbiAgICogQG5hbWUgc2VhbGVkXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnc2VhbGVkJywgZnVuY3Rpb24oKSB7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuXG4gICAgLy8gSW4gRVM1LCBpZiB0aGUgYXJndW1lbnQgdG8gdGhpcyBtZXRob2QgaXMgbm90IGFuIG9iamVjdCAoYSBwcmltaXRpdmUpLCB0aGVuIGl0IHdpbGwgY2F1c2UgYSBUeXBlRXJyb3IuXG4gICAgLy8gSW4gRVM2LCBhIG5vbi1vYmplY3QgYXJndW1lbnQgd2lsbCBiZSB0cmVhdGVkIGFzIGlmIGl0IHdhcyBhIHNlYWxlZCBvcmRpbmFyeSBvYmplY3QsIHNpbXBseSByZXR1cm4gdHJ1ZS5cbiAgICAvLyBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L2lzU2VhbGVkXG4gICAgLy8gVGhlIGZvbGxvd2luZyBwcm92aWRlcyBFUzYgYmVoYXZpb3Igd2hlbiBhIFR5cGVFcnJvciBpcyB0aHJvd24gdW5kZXIgRVM1LlxuXG4gICAgdmFyIGlzU2VhbGVkO1xuXG4gICAgdHJ5IHtcbiAgICAgIGlzU2VhbGVkID0gT2JqZWN0LmlzU2VhbGVkKG9iaik7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoZXJyIGluc3RhbmNlb2YgVHlwZUVycm9yKSBpc1NlYWxlZCA9IHRydWU7XG4gICAgICBlbHNlIHRocm93IGVycjtcbiAgICB9XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgIGlzU2VhbGVkXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIHNlYWxlZCdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIHNlYWxlZCdcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5mcm96ZW5cbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgZnJvemVuIChjYW5ub3QgaGF2ZSBuZXcgcHJvcGVydGllcyBhZGRlZCB0byBpdFxuICAgKiBhbmQgaXRzIGV4aXN0aW5nIHByb3BlcnRpZXMgY2Fubm90IGJlIG1vZGlmaWVkKS5cbiAgICpcbiAgICogICAgIHZhciBmcm96ZW5PYmplY3QgPSBPYmplY3QuZnJlZXplKHt9KTtcbiAgICpcbiAgICogICAgIGV4cGVjdChmcm96ZW5PYmplY3QpLnRvLmJlLmZyb3plbjtcbiAgICogICAgIGV4cGVjdCh7fSkudG8ubm90LmJlLmZyb3plbjtcbiAgICpcbiAgICogQG5hbWUgZnJvemVuXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZnJvemVuJywgZnVuY3Rpb24oKSB7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuXG4gICAgLy8gSW4gRVM1LCBpZiB0aGUgYXJndW1lbnQgdG8gdGhpcyBtZXRob2QgaXMgbm90IGFuIG9iamVjdCAoYSBwcmltaXRpdmUpLCB0aGVuIGl0IHdpbGwgY2F1c2UgYSBUeXBlRXJyb3IuXG4gICAgLy8gSW4gRVM2LCBhIG5vbi1vYmplY3QgYXJndW1lbnQgd2lsbCBiZSB0cmVhdGVkIGFzIGlmIGl0IHdhcyBhIGZyb3plbiBvcmRpbmFyeSBvYmplY3QsIHNpbXBseSByZXR1cm4gdHJ1ZS5cbiAgICAvLyBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L2lzRnJvemVuXG4gICAgLy8gVGhlIGZvbGxvd2luZyBwcm92aWRlcyBFUzYgYmVoYXZpb3Igd2hlbiBhIFR5cGVFcnJvciBpcyB0aHJvd24gdW5kZXIgRVM1LlxuXG4gICAgdmFyIGlzRnJvemVuO1xuXG4gICAgdHJ5IHtcbiAgICAgIGlzRnJvemVuID0gT2JqZWN0LmlzRnJvemVuKG9iaik7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoZXJyIGluc3RhbmNlb2YgVHlwZUVycm9yKSBpc0Zyb3plbiA9IHRydWU7XG4gICAgICBlbHNlIHRocm93IGVycjtcbiAgICB9XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgIGlzRnJvemVuXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGZyb3plbidcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIGZyb3plbidcbiAgICApO1xuICB9KTtcbn07XG4iLCIvKiFcbiAqIGNoYWlcbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGNoYWksIHV0aWwpIHtcblxuICAvKiFcbiAgICogQ2hhaSBkZXBlbmRlbmNpZXMuXG4gICAqL1xuXG4gIHZhciBBc3NlcnRpb24gPSBjaGFpLkFzc2VydGlvblxuICAgICwgZmxhZyA9IHV0aWwuZmxhZztcblxuICAvKiFcbiAgICogTW9kdWxlIGV4cG9ydC5cbiAgICovXG5cbiAgLyoqXG4gICAqICMjIyBhc3NlcnQoZXhwcmVzc2lvbiwgbWVzc2FnZSlcbiAgICpcbiAgICogV3JpdGUgeW91ciBvd24gdGVzdCBleHByZXNzaW9ucy5cbiAgICpcbiAgICogICAgIGFzc2VydCgnZm9vJyAhPT0gJ2JhcicsICdmb28gaXMgbm90IGJhcicpO1xuICAgKiAgICAgYXNzZXJ0KEFycmF5LmlzQXJyYXkoW10pLCAnZW1wdHkgYXJyYXlzIGFyZSBhcnJheXMnKTtcbiAgICpcbiAgICogQHBhcmFtIHtNaXhlZH0gZXhwcmVzc2lvbiB0byB0ZXN0IGZvciB0cnV0aGluZXNzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIHRvIGRpc3BsYXkgb24gZXJyb3JcbiAgICogQG5hbWUgYXNzZXJ0XG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIHZhciBhc3NlcnQgPSBjaGFpLmFzc2VydCA9IGZ1bmN0aW9uIChleHByZXNzLCBlcnJtc2cpIHtcbiAgICB2YXIgdGVzdCA9IG5ldyBBc3NlcnRpb24obnVsbCwgbnVsbCwgY2hhaS5hc3NlcnQpO1xuICAgIHRlc3QuYXNzZXJ0KFxuICAgICAgICBleHByZXNzXG4gICAgICAsIGVycm1zZ1xuICAgICAgLCAnWyBuZWdhdGlvbiBtZXNzYWdlIHVuYXZhaWxhYmxlIF0nXG4gICAgKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5mYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSwgW29wZXJhdG9yXSlcbiAgICpcbiAgICogVGhyb3cgYSBmYWlsdXJlLiBOb2RlLmpzIGBhc3NlcnRgIG1vZHVsZS1jb21wYXRpYmxlLlxuICAgKlxuICAgKiBAbmFtZSBmYWlsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gb3BlcmF0b3JcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmZhaWwgPSBmdW5jdGlvbiAoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgb3BlcmF0b3IpIHtcbiAgICBtZXNzYWdlID0gbWVzc2FnZSB8fCAnYXNzZXJ0LmZhaWwoKSc7XG4gICAgdGhyb3cgbmV3IGNoYWkuQXNzZXJ0aW9uRXJyb3IobWVzc2FnZSwge1xuICAgICAgICBhY3R1YWw6IGFjdHVhbFxuICAgICAgLCBleHBlY3RlZDogZXhwZWN0ZWRcbiAgICAgICwgb3BlcmF0b3I6IG9wZXJhdG9yXG4gICAgfSwgYXNzZXJ0LmZhaWwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzT2sob2JqZWN0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBpcyB0cnV0aHkuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNPaygnZXZlcnl0aGluZycsICdldmVyeXRoaW5nIGlzIG9rJyk7XG4gICAqICAgICBhc3NlcnQuaXNPayhmYWxzZSwgJ3RoaXMgd2lsbCBmYWlsJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzT2tcbiAgICogQGFsaWFzIG9rXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdCB0byB0ZXN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc09rID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykuaXMub2s7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RPayhvYmplY3QsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGlzIGZhbHN5LlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTm90T2soJ2V2ZXJ5dGhpbmcnLCAndGhpcyB3aWxsIGZhaWwnKTtcbiAgICogICAgIGFzc2VydC5pc05vdE9rKGZhbHNlLCAndGhpcyB3aWxsIHBhc3MnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RPa1xuICAgKiBAYWxpYXMgbm90T2tcbiAgICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0IHRvIHRlc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90T2sgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS5pcy5ub3Qub2s7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIG5vbi1zdHJpY3QgZXF1YWxpdHkgKGA9PWApIG9mIGBhY3R1YWxgIGFuZCBgZXhwZWN0ZWRgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmVxdWFsKDMsICczJywgJz09IGNvZXJjZXMgdmFsdWVzIHRvIHN0cmluZ3MnKTtcbiAgICpcbiAgICogQG5hbWUgZXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5lcXVhbCA9IGZ1bmN0aW9uIChhY3QsIGV4cCwgbXNnKSB7XG4gICAgdmFyIHRlc3QgPSBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnLCBhc3NlcnQuZXF1YWwpO1xuXG4gICAgdGVzdC5hc3NlcnQoXG4gICAgICAgIGV4cCA9PSBmbGFnKHRlc3QsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBlcXVhbCAje2V4cH0nXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBlcXVhbCAje2FjdH0nXG4gICAgICAsIGV4cFxuICAgICAgLCBhY3RcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBub24tc3RyaWN0IGluZXF1YWxpdHkgKGAhPWApIG9mIGBhY3R1YWxgIGFuZCBgZXhwZWN0ZWRgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdEVxdWFsKDMsIDQsICd0aGVzZSBudW1iZXJzIGFyZSBub3QgZXF1YWwnKTtcbiAgICpcbiAgICogQG5hbWUgbm90RXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RFcXVhbCA9IGZ1bmN0aW9uIChhY3QsIGV4cCwgbXNnKSB7XG4gICAgdmFyIHRlc3QgPSBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnLCBhc3NlcnQubm90RXF1YWwpO1xuXG4gICAgdGVzdC5hc3NlcnQoXG4gICAgICAgIGV4cCAhPSBmbGFnKHRlc3QsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgZXF1YWwgI3tleHB9J1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBlcXVhbCAje2FjdH0nXG4gICAgICAsIGV4cFxuICAgICAgLCBhY3RcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLnN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBzdHJpY3QgZXF1YWxpdHkgKGA9PT1gKSBvZiBgYWN0dWFsYCBhbmQgYGV4cGVjdGVkYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0cnVlLCB0cnVlLCAndGhlc2UgYm9vbGVhbnMgYXJlIHN0cmljdGx5IGVxdWFsJyk7XG4gICAqXG4gICAqIEBuYW1lIHN0cmljdEVxdWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuc3RyaWN0RXF1YWwgPSBmdW5jdGlvbiAoYWN0LCBleHAsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oYWN0LCBtc2cpLnRvLmVxdWFsKGV4cCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHN0cmljdCBpbmVxdWFsaXR5IChgIT09YCkgb2YgYGFjdHVhbGAgYW5kIGBleHBlY3RlZGAuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90U3RyaWN0RXF1YWwoMywgJzMnLCAnbm8gY29lcmNpb24gZm9yIHN0cmljdCBlcXVhbGl0eScpO1xuICAgKlxuICAgKiBAbmFtZSBub3RTdHJpY3RFcXVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBhY3R1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsID0gZnVuY3Rpb24gKGFjdCwgZXhwLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnKS50by5ub3QuZXF1YWwoZXhwKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYGFjdHVhbGAgaXMgZGVlcGx5IGVxdWFsIHRvIGBleHBlY3RlZGAuXG4gICAqXG4gICAqICAgICBhc3NlcnQuZGVlcEVxdWFsKHsgdGVhOiAnZ3JlZW4nIH0sIHsgdGVhOiAnZ3JlZW4nIH0pO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwRXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kZWVwRXF1YWwgPSBmdW5jdGlvbiAoYWN0LCBleHAsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oYWN0LCBtc2cpLnRvLmVxbChleHApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydCB0aGF0IGBhY3R1YWxgIGlzIG5vdCBkZWVwbHkgZXF1YWwgdG8gYGV4cGVjdGVkYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3REZWVwRXF1YWwoeyB0ZWE6ICdncmVlbicgfSwgeyB0ZWE6ICdqYXNtaW5lJyB9KTtcbiAgICpcbiAgICogQG5hbWUgbm90RGVlcEVxdWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90RGVlcEVxdWFsID0gZnVuY3Rpb24gKGFjdCwgZXhwLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnKS50by5ub3QuZXFsKGV4cCk7XG4gIH07XG5cbiAgIC8qKlxuICAgKiAjIyMgLmlzQWJvdmUodmFsdWVUb0NoZWNrLCB2YWx1ZVRvQmVBYm92ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIGB2YWx1ZVRvQ2hlY2tgIGlzIHN0cmljdGx5IGdyZWF0ZXIgdGhhbiAoPikgYHZhbHVlVG9CZUFib3ZlYFxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzQWJvdmUoNSwgMiwgJzUgaXMgc3RyaWN0bHkgZ3JlYXRlciB0aGFuIDInKTtcbiAgICpcbiAgICogQG5hbWUgaXNBYm92ZVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVRvQ2hlY2tcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVUb0JlQWJvdmVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzQWJvdmUgPSBmdW5jdGlvbiAodmFsLCBhYnYsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLmFib3ZlKGFidik7XG4gIH07XG5cbiAgIC8qKlxuICAgKiAjIyMgLmlzQXRMZWFzdCh2YWx1ZVRvQ2hlY2ssIHZhbHVlVG9CZUF0TGVhc3QsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBgdmFsdWVUb0NoZWNrYCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gKD49KSBgdmFsdWVUb0JlQXRMZWFzdGBcbiAgICpcbiAgICogICAgIGFzc2VydC5pc0F0TGVhc3QoNSwgMiwgJzUgaXMgZ3JlYXRlciBvciBlcXVhbCB0byAyJyk7XG4gICAqICAgICBhc3NlcnQuaXNBdExlYXN0KDMsIDMsICczIGlzIGdyZWF0ZXIgb3IgZXF1YWwgdG8gMycpO1xuICAgKlxuICAgKiBAbmFtZSBpc0F0TGVhc3RcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVUb0NoZWNrXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlVG9CZUF0TGVhc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzQXRMZWFzdCA9IGZ1bmN0aW9uICh2YWwsIGF0bHN0LCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5iZS5sZWFzdChhdGxzdCk7XG4gIH07XG5cbiAgIC8qKlxuICAgKiAjIyMgLmlzQmVsb3codmFsdWVUb0NoZWNrLCB2YWx1ZVRvQmVCZWxvdywgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIGB2YWx1ZVRvQ2hlY2tgIGlzIHN0cmljdGx5IGxlc3MgdGhhbiAoPCkgYHZhbHVlVG9CZUJlbG93YFxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzQmVsb3coMywgNiwgJzMgaXMgc3RyaWN0bHkgbGVzcyB0aGFuIDYnKTtcbiAgICpcbiAgICogQG5hbWUgaXNCZWxvd1xuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVRvQ2hlY2tcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVUb0JlQmVsb3dcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzQmVsb3cgPSBmdW5jdGlvbiAodmFsLCBibHcsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLmJlbG93KGJsdyk7XG4gIH07XG5cbiAgIC8qKlxuICAgKiAjIyMgLmlzQXRNb3N0KHZhbHVlVG9DaGVjaywgdmFsdWVUb0JlQXRNb3N0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgYHZhbHVlVG9DaGVja2AgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICg8PSkgYHZhbHVlVG9CZUF0TW9zdGBcbiAgICpcbiAgICogICAgIGFzc2VydC5pc0F0TW9zdCgzLCA2LCAnMyBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gNicpO1xuICAgKiAgICAgYXNzZXJ0LmlzQXRNb3N0KDQsIDQsICc0IGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byA0Jyk7XG4gICAqXG4gICAqIEBuYW1lIGlzQXRNb3N0XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlVG9DaGVja1xuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVRvQmVBdE1vc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzQXRNb3N0ID0gZnVuY3Rpb24gKHZhbCwgYXRtc3QsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLm1vc3QoYXRtc3QpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzVHJ1ZSh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyB0cnVlLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYVNlcnZlZCA9IHRydWU7XG4gICAqICAgICBhc3NlcnQuaXNUcnVlKHRlYVNlcnZlZCwgJ3RoZSB0ZWEgaGFzIGJlZW4gc2VydmVkJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzVHJ1ZVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNUcnVlID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykuaXNbJ3RydWUnXTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdFRydWUodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgbm90IHRydWUuXG4gICAqXG4gICAqICAgICB2YXIgdGVhID0gJ3Rhc3R5IGNoYWknO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90VHJ1ZSh0ZWEsICdncmVhdCwgdGltZSBmb3IgdGVhIScpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdFRydWVcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90VHJ1ZSA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLm5vdC5lcXVhbCh0cnVlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0ZhbHNlKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIGZhbHNlLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYVNlcnZlZCA9IGZhbHNlO1xuICAgKiAgICAgYXNzZXJ0LmlzRmFsc2UodGVhU2VydmVkLCAnbm8gdGVhIHlldD8gaG1tLi4uJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzRmFsc2VcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzRmFsc2UgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS5pc1snZmFsc2UnXTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdEZhbHNlKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIG5vdCBmYWxzZS5cbiAgICpcbiAgICogICAgIHZhciB0ZWEgPSAndGFzdHkgY2hhaSc7XG4gICAqICAgICBhc3NlcnQuaXNOb3RGYWxzZSh0ZWEsICdncmVhdCwgdGltZSBmb3IgdGVhIScpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdEZhbHNlXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdEZhbHNlID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmVxdWFsKGZhbHNlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc051bGwodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgbnVsbC5cbiAgICpcbiAgICogICAgIGFzc2VydC5pc051bGwoZXJyLCAndGhlcmUgd2FzIG5vIGVycm9yJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzTnVsbFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOdWxsID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8uZXF1YWwobnVsbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3ROdWxsKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIG5vdCBudWxsLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYSA9ICd0YXN0eSBjaGFpJztcbiAgICogICAgIGFzc2VydC5pc05vdE51bGwodGVhLCAnZ3JlYXQsIHRpbWUgZm9yIHRlYSEnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3ROdWxsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdE51bGwgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5ub3QuZXF1YWwobnVsbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOYU5cbiAgICogQXNzZXJ0cyB0aGF0IHZhbHVlIGlzIE5hTlxuICAgKlxuICAgKiAgICBhc3NlcnQuaXNOYU4oJ2ZvbycsICdmb28gaXMgTmFOJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzTmFOXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05hTiA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLk5hTjtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdE5hTlxuICAgKiBBc3NlcnRzIHRoYXQgdmFsdWUgaXMgbm90IE5hTlxuICAgKlxuICAgKiAgICBhc3NlcnQuaXNOb3ROYU4oNCwgJzQgaXMgbm90IE5hTicpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdE5hTlxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cbiAgYXNzZXJ0LmlzTm90TmFOID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykubm90LnRvLmJlLk5hTjtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc1VuZGVmaW5lZCh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYC5cbiAgICpcbiAgICogICAgIHZhciB0ZWE7XG4gICAqICAgICBhc3NlcnQuaXNVbmRlZmluZWQodGVhLCAnbm8gdGVhIGRlZmluZWQnKTtcbiAgICpcbiAgICogQG5hbWUgaXNVbmRlZmluZWRcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzVW5kZWZpbmVkID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8uZXF1YWwodW5kZWZpbmVkKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0RlZmluZWQodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgbm90IGB1bmRlZmluZWRgLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYSA9ICdjdXAgb2YgY2hhaSc7XG4gICAqICAgICBhc3NlcnQuaXNEZWZpbmVkKHRlYSwgJ3RlYSBoYXMgYmVlbiBkZWZpbmVkJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzRGVmaW5lZFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNEZWZpbmVkID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmVxdWFsKHVuZGVmaW5lZCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNGdW5jdGlvbih2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBhIGZ1bmN0aW9uLlxuICAgKlxuICAgKiAgICAgZnVuY3Rpb24gc2VydmVUZWEoKSB7IHJldHVybiAnY3VwIG9mIHRlYSc7IH07XG4gICAqICAgICBhc3NlcnQuaXNGdW5jdGlvbihzZXJ2ZVRlYSwgJ2dyZWF0LCB3ZSBjYW4gaGF2ZSB0ZWEgbm93Jyk7XG4gICAqXG4gICAqIEBuYW1lIGlzRnVuY3Rpb25cbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzRnVuY3Rpb24gPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5iZS5hKCdmdW5jdGlvbicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90RnVuY3Rpb24odmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgX25vdF8gYSBmdW5jdGlvbi5cbiAgICpcbiAgICogICAgIHZhciBzZXJ2ZVRlYSA9IFsgJ2hlYXQnLCAncG91cicsICdzaXAnIF07XG4gICAqICAgICBhc3NlcnQuaXNOb3RGdW5jdGlvbihzZXJ2ZVRlYSwgJ2dyZWF0LCB3ZSBoYXZlIGxpc3RlZCB0aGUgc3RlcHMnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RGdW5jdGlvblxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RGdW5jdGlvbiA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLm5vdC5iZS5hKCdmdW5jdGlvbicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzT2JqZWN0KHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIGFuIG9iamVjdCBvZiB0eXBlICdPYmplY3QnIChhcyByZXZlYWxlZCBieSBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2ApLlxuICAgKiBfVGhlIGFzc2VydGlvbiBkb2VzIG5vdCBtYXRjaCBzdWJjbGFzc2VkIG9iamVjdHMuX1xuICAgKlxuICAgKiAgICAgdmFyIHNlbGVjdGlvbiA9IHsgbmFtZTogJ0NoYWknLCBzZXJ2ZTogJ3dpdGggc3BpY2VzJyB9O1xuICAgKiAgICAgYXNzZXJ0LmlzT2JqZWN0KHNlbGVjdGlvbiwgJ3RlYSBzZWxlY3Rpb24gaXMgYW4gb2JqZWN0Jyk7XG4gICAqXG4gICAqIEBuYW1lIGlzT2JqZWN0XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc09iamVjdCA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLmEoJ29iamVjdCcpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90T2JqZWN0KHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIF9ub3RfIGFuIG9iamVjdCBvZiB0eXBlICdPYmplY3QnIChhcyByZXZlYWxlZCBieSBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2ApLlxuICAgKlxuICAgKiAgICAgdmFyIHNlbGVjdGlvbiA9ICdjaGFpJ1xuICAgKiAgICAgYXNzZXJ0LmlzTm90T2JqZWN0KHNlbGVjdGlvbiwgJ3RlYSBzZWxlY3Rpb24gaXMgbm90IGFuIG9iamVjdCcpO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90T2JqZWN0KG51bGwsICdudWxsIGlzIG5vdCBhbiBvYmplY3QnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RPYmplY3RcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90T2JqZWN0ID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmJlLmEoJ29iamVjdCcpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzQXJyYXkodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgYW4gYXJyYXkuXG4gICAqXG4gICAqICAgICB2YXIgbWVudSA9IFsgJ2dyZWVuJywgJ2NoYWknLCAnb29sb25nJyBdO1xuICAgKiAgICAgYXNzZXJ0LmlzQXJyYXkobWVudSwgJ3doYXQga2luZCBvZiB0ZWEgZG8gd2Ugd2FudD8nKTtcbiAgICpcbiAgICogQG5hbWUgaXNBcnJheVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNBcnJheSA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLmFuKCdhcnJheScpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90QXJyYXkodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgX25vdF8gYW4gYXJyYXkuXG4gICAqXG4gICAqICAgICB2YXIgbWVudSA9ICdncmVlbnxjaGFpfG9vbG9uZyc7XG4gICAqICAgICBhc3NlcnQuaXNOb3RBcnJheShtZW51LCAnd2hhdCBraW5kIG9mIHRlYSBkbyB3ZSB3YW50PycpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdEFycmF5XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdEFycmF5ID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmJlLmFuKCdhcnJheScpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzU3RyaW5nKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIGEgc3RyaW5nLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYU9yZGVyID0gJ2NoYWknO1xuICAgKiAgICAgYXNzZXJ0LmlzU3RyaW5nKHRlYU9yZGVyLCAnb3JkZXIgcGxhY2VkJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzU3RyaW5nXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc1N0cmluZyA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLmEoJ3N0cmluZycpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90U3RyaW5nKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIF9ub3RfIGEgc3RyaW5nLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYU9yZGVyID0gNDtcbiAgICogICAgIGFzc2VydC5pc05vdFN0cmluZyh0ZWFPcmRlciwgJ29yZGVyIHBsYWNlZCcpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdFN0cmluZ1xuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RTdHJpbmcgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5ub3QuYmUuYSgnc3RyaW5nJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOdW1iZXIodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgYSBudW1iZXIuXG4gICAqXG4gICAqICAgICB2YXIgY3VwcyA9IDI7XG4gICAqICAgICBhc3NlcnQuaXNOdW1iZXIoY3VwcywgJ2hvdyBtYW55IGN1cHMnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOdW1iZXJcbiAgICogQHBhcmFtIHtOdW1iZXJ9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc051bWJlciA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLmEoJ251bWJlcicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90TnVtYmVyKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIF9ub3RfIGEgbnVtYmVyLlxuICAgKlxuICAgKiAgICAgdmFyIGN1cHMgPSAnMiBjdXBzIHBsZWFzZSc7XG4gICAqICAgICBhc3NlcnQuaXNOb3ROdW1iZXIoY3VwcywgJ2hvdyBtYW55IGN1cHMnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3ROdW1iZXJcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90TnVtYmVyID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmJlLmEoJ251bWJlcicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzQm9vbGVhbih2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBhIGJvb2xlYW4uXG4gICAqXG4gICAqICAgICB2YXIgdGVhUmVhZHkgPSB0cnVlXG4gICAqICAgICAgICwgdGVhU2VydmVkID0gZmFsc2U7XG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNCb29sZWFuKHRlYVJlYWR5LCAnaXMgdGhlIHRlYSByZWFkeScpO1xuICAgKiAgICAgYXNzZXJ0LmlzQm9vbGVhbih0ZWFTZXJ2ZWQsICdoYXMgdGVhIGJlZW4gc2VydmVkJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzQm9vbGVhblxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNCb29sZWFuID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8uYmUuYSgnYm9vbGVhbicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90Qm9vbGVhbih2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBfbm90XyBhIGJvb2xlYW4uXG4gICAqXG4gICAqICAgICB2YXIgdGVhUmVhZHkgPSAneWVwJ1xuICAgKiAgICAgICAsIHRlYVNlcnZlZCA9ICdub3BlJztcbiAgICpcbiAgICogICAgIGFzc2VydC5pc05vdEJvb2xlYW4odGVhUmVhZHksICdpcyB0aGUgdGVhIHJlYWR5Jyk7XG4gICAqICAgICBhc3NlcnQuaXNOb3RCb29sZWFuKHRlYVNlcnZlZCwgJ2hhcyB0ZWEgYmVlbiBzZXJ2ZWQnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RCb29sZWFuXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdEJvb2xlYW4gPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5ub3QuYmUuYSgnYm9vbGVhbicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLnR5cGVPZih2YWx1ZSwgbmFtZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCdzIHR5cGUgaXMgYG5hbWVgLCBhcyBkZXRlcm1pbmVkIGJ5XG4gICAqIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYC5cbiAgICpcbiAgICogICAgIGFzc2VydC50eXBlT2YoeyB0ZWE6ICdjaGFpJyB9LCAnb2JqZWN0JywgJ3dlIGhhdmUgYW4gb2JqZWN0Jyk7XG4gICAqICAgICBhc3NlcnQudHlwZU9mKFsnY2hhaScsICdqYXNtaW5lJ10sICdhcnJheScsICd3ZSBoYXZlIGFuIGFycmF5Jyk7XG4gICAqICAgICBhc3NlcnQudHlwZU9mKCd0ZWEnLCAnc3RyaW5nJywgJ3dlIGhhdmUgYSBzdHJpbmcnKTtcbiAgICogICAgIGFzc2VydC50eXBlT2YoL3RlYS8sICdyZWdleHAnLCAnd2UgaGF2ZSBhIHJlZ3VsYXIgZXhwcmVzc2lvbicpO1xuICAgKiAgICAgYXNzZXJ0LnR5cGVPZihudWxsLCAnbnVsbCcsICd3ZSBoYXZlIGEgbnVsbCcpO1xuICAgKiAgICAgYXNzZXJ0LnR5cGVPZih1bmRlZmluZWQsICd1bmRlZmluZWQnLCAnd2UgaGF2ZSBhbiB1bmRlZmluZWQnKTtcbiAgICpcbiAgICogQG5hbWUgdHlwZU9mXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC50eXBlT2YgPSBmdW5jdGlvbiAodmFsLCB0eXBlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5iZS5hKHR5cGUpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdFR5cGVPZih2YWx1ZSwgbmFtZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCdzIHR5cGUgaXMgX25vdF8gYG5hbWVgLCBhcyBkZXRlcm1pbmVkIGJ5XG4gICAqIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RUeXBlT2YoJ3RlYScsICdudW1iZXInLCAnc3RyaW5ncyBhcmUgbm90IG51bWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgbm90VHlwZU9mXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlb2YgbmFtZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90VHlwZU9mID0gZnVuY3Rpb24gKHZhbCwgdHlwZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmJlLmEodHlwZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaW5zdGFuY2VPZihvYmplY3QsIGNvbnN0cnVjdG9yLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIGFuIGluc3RhbmNlIG9mIGBjb25zdHJ1Y3RvcmAuXG4gICAqXG4gICAqICAgICB2YXIgVGVhID0gZnVuY3Rpb24gKG5hbWUpIHsgdGhpcy5uYW1lID0gbmFtZTsgfVxuICAgKiAgICAgICAsIGNoYWkgPSBuZXcgVGVhKCdjaGFpJyk7XG4gICAqXG4gICAqICAgICBhc3NlcnQuaW5zdGFuY2VPZihjaGFpLCBUZWEsICdjaGFpIGlzIGFuIGluc3RhbmNlIG9mIHRlYScpO1xuICAgKlxuICAgKiBAbmFtZSBpbnN0YW5jZU9mXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3Rvcn0gY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lmluc3RhbmNlT2YgPSBmdW5jdGlvbiAodmFsLCB0eXBlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5iZS5pbnN0YW5jZU9mKHR5cGUpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdEluc3RhbmNlT2Yob2JqZWN0LCBjb25zdHJ1Y3RvciwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIGB2YWx1ZWAgaXMgbm90IGFuIGluc3RhbmNlIG9mIGBjb25zdHJ1Y3RvcmAuXG4gICAqXG4gICAqICAgICB2YXIgVGVhID0gZnVuY3Rpb24gKG5hbWUpIHsgdGhpcy5uYW1lID0gbmFtZTsgfVxuICAgKiAgICAgICAsIGNoYWkgPSBuZXcgU3RyaW5nKCdjaGFpJyk7XG4gICAqXG4gICAqICAgICBhc3NlcnQubm90SW5zdGFuY2VPZihjaGFpLCBUZWEsICdjaGFpIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiB0ZWEnKTtcbiAgICpcbiAgICogQG5hbWUgbm90SW5zdGFuY2VPZlxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3J9IGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RJbnN0YW5jZU9mID0gZnVuY3Rpb24gKHZhbCwgdHlwZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmJlLmluc3RhbmNlT2YodHlwZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaW5jbHVkZShoYXlzdGFjaywgbmVlZGxlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgaGF5c3RhY2tgIGluY2x1ZGVzIGBuZWVkbGVgLiBXb3Jrc1xuICAgKiBmb3Igc3RyaW5ncyBhbmQgYXJyYXlzLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmluY2x1ZGUoJ2Zvb2JhcicsICdiYXInLCAnZm9vYmFyIGNvbnRhaW5zIHN0cmluZyBcImJhclwiJyk7XG4gICAqICAgICBhc3NlcnQuaW5jbHVkZShbIDEsIDIsIDMgXSwgMywgJ2FycmF5IGNvbnRhaW5zIHZhbHVlJyk7XG4gICAqXG4gICAqIEBuYW1lIGluY2x1ZGVcbiAgICogQHBhcmFtIHtBcnJheXxTdHJpbmd9IGhheXN0YWNrXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG5lZWRsZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaW5jbHVkZSA9IGZ1bmN0aW9uIChleHAsIGluYywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZywgYXNzZXJ0LmluY2x1ZGUpLmluY2x1ZGUoaW5jKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3RJbmNsdWRlKGhheXN0YWNrLCBuZWVkbGUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBoYXlzdGFja2AgZG9lcyBub3QgaW5jbHVkZSBgbmVlZGxlYC4gV29ya3NcbiAgICogZm9yIHN0cmluZ3MgYW5kIGFycmF5cy5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlKCdmb29iYXInLCAnYmF6JywgJ3N0cmluZyBub3QgaW5jbHVkZSBzdWJzdHJpbmcnKTtcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlKFsgMSwgMiwgMyBdLCA0LCAnYXJyYXkgbm90IGluY2x1ZGUgY29udGFpbiB2YWx1ZScpO1xuICAgKlxuICAgKiBAbmFtZSBub3RJbmNsdWRlXG4gICAqIEBwYXJhbSB7QXJyYXl8U3RyaW5nfSBoYXlzdGFja1xuICAgKiBAcGFyYW0ge01peGVkfSBuZWVkbGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdEluY2x1ZGUgPSBmdW5jdGlvbiAoZXhwLCBpbmMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oZXhwLCBtc2csIGFzc2VydC5ub3RJbmNsdWRlKS5ub3QuaW5jbHVkZShpbmMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm1hdGNoKHZhbHVlLCByZWdleHAsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgbWF0Y2hlcyB0aGUgcmVndWxhciBleHByZXNzaW9uIGByZWdleHBgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm1hdGNoKCdmb29iYXInLCAvXmZvby8sICdyZWdleHAgbWF0Y2hlcycpO1xuICAgKlxuICAgKiBAbmFtZSBtYXRjaFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1JlZ0V4cH0gcmVnZXhwXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5tYXRjaCA9IGZ1bmN0aW9uIChleHAsIHJlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnKS50by5tYXRjaChyZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90TWF0Y2godmFsdWUsIHJlZ2V4cCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBkb2VzIG5vdCBtYXRjaCB0aGUgcmVndWxhciBleHByZXNzaW9uIGByZWdleHBgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdE1hdGNoKCdmb29iYXInLCAvXmZvby8sICdyZWdleHAgZG9lcyBub3QgbWF0Y2gnKTtcbiAgICpcbiAgICogQG5hbWUgbm90TWF0Y2hcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90TWF0Y2ggPSBmdW5jdGlvbiAoZXhwLCByZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZykudG8ubm90Lm1hdGNoKHJlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5wcm9wZXJ0eShvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnByb3BlcnR5KHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9fSwgJ3RlYScpO1xuICAgKlxuICAgKiBAbmFtZSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQucHJvcGVydHkgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KHByb3ApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdFByb3BlcnR5KG9iamVjdCwgcHJvcGVydHksIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGRvZXMgX25vdF8gaGF2ZSBhIHByb3BlcnR5IG5hbWVkIGJ5IGBwcm9wZXJ0eWAuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90UHJvcGVydHkoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH19LCAnY29mZmVlJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdFByb3BlcnR5XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RQcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmosIHByb3AsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLnRvLm5vdC5oYXZlLnByb3BlcnR5KHByb3ApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmRlZXBQcm9wZXJ0eShvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgLCB3aGljaCBjYW4gYmUgYVxuICAgKiBzdHJpbmcgdXNpbmcgZG90LSBhbmQgYnJhY2tldC1ub3RhdGlvbiBmb3IgZGVlcCByZWZlcmVuY2UuXG4gICAqXG4gICAqICAgICBhc3NlcnQuZGVlcFByb3BlcnR5KHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9fSwgJ3RlYS5ncmVlbicpO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwUHJvcGVydHlcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlZXBQcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmosIHByb3AsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eShwcm9wKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3REZWVwUHJvcGVydHkob2JqZWN0LCBwcm9wZXJ0eSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgZG9lcyBfbm90XyBoYXZlIGEgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCwgd2hpY2hcbiAgICogY2FuIGJlIGEgc3RyaW5nIHVzaW5nIGRvdC0gYW5kIGJyYWNrZXQtbm90YXRpb24gZm9yIGRlZXAgcmVmZXJlbmNlLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdERlZXBQcm9wZXJ0eSh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfX0sICd0ZWEub29sb25nJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdERlZXBQcm9wZXJ0eVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90RGVlcFByb3BlcnR5ID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8ubm90LmhhdmUuZGVlcC5wcm9wZXJ0eShwcm9wKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5wcm9wZXJ0eVZhbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGEgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCB3aXRoIHZhbHVlIGdpdmVuXG4gICAqIGJ5IGB2YWx1ZWAuXG4gICAqXG4gICAqICAgICBhc3NlcnQucHJvcGVydHlWYWwoeyB0ZWE6ICdpcyBnb29kJyB9LCAndGVhJywgJ2lzIGdvb2QnKTtcbiAgICpcbiAgICogQG5hbWUgcHJvcGVydHlWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LnByb3BlcnR5VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KHByb3AsIHZhbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAucHJvcGVydHlOb3RWYWwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhIHByb3BlcnR5IG5hbWVkIGJ5IGBwcm9wZXJ0eWAsIGJ1dCB3aXRoIGEgdmFsdWVcbiAgICogZGlmZmVyZW50IGZyb20gdGhhdCBnaXZlbiBieSBgdmFsdWVgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnByb3BlcnR5Tm90VmFsKHsgdGVhOiAnaXMgZ29vZCcgfSwgJ3RlYScsICdpcyBiYWQnKTtcbiAgICpcbiAgICogQG5hbWUgcHJvcGVydHlOb3RWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LnByb3BlcnR5Tm90VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5ub3QuaGF2ZS5wcm9wZXJ0eShwcm9wLCB2YWwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmRlZXBQcm9wZXJ0eVZhbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGEgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCB3aXRoIHZhbHVlIGdpdmVuXG4gICAqIGJ5IGB2YWx1ZWAuIGBwcm9wZXJ0eWAgY2FuIHVzZSBkb3QtIGFuZCBicmFja2V0LW5vdGF0aW9uIGZvciBkZWVwXG4gICAqIHJlZmVyZW5jZS5cbiAgICpcbiAgICogICAgIGFzc2VydC5kZWVwUHJvcGVydHlWYWwoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH19LCAndGVhLmdyZWVuJywgJ21hdGNoYScpO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwUHJvcGVydHlWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlZXBQcm9wZXJ0eVZhbCA9IGZ1bmN0aW9uIChvYmosIHByb3AsIHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8uaGF2ZS5kZWVwLnByb3BlcnR5KHByb3AsIHZhbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZGVlcFByb3BlcnR5Tm90VmFsKG9iamVjdCwgcHJvcGVydHksIHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgLCBidXQgd2l0aCBhIHZhbHVlXG4gICAqIGRpZmZlcmVudCBmcm9tIHRoYXQgZ2l2ZW4gYnkgYHZhbHVlYC4gYHByb3BlcnR5YCBjYW4gdXNlIGRvdC0gYW5kXG4gICAqIGJyYWNrZXQtbm90YXRpb24gZm9yIGRlZXAgcmVmZXJlbmNlLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmRlZXBQcm9wZXJ0eU5vdFZhbCh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfX0sICd0ZWEuZ3JlZW4nLCAna29uYWNoYScpO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwUHJvcGVydHlOb3RWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlZXBQcm9wZXJ0eU5vdFZhbCA9IGZ1bmN0aW9uIChvYmosIHByb3AsIHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8ubm90LmhhdmUuZGVlcC5wcm9wZXJ0eShwcm9wLCB2YWwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmxlbmd0aE9mKG9iamVjdCwgbGVuZ3RoLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBgbGVuZ3RoYCBwcm9wZXJ0eSB3aXRoIHRoZSBleHBlY3RlZCB2YWx1ZS5cbiAgICpcbiAgICogICAgIGFzc2VydC5sZW5ndGhPZihbMSwyLDNdLCAzLCAnYXJyYXkgaGFzIGxlbmd0aCBvZiAzJyk7XG4gICAqICAgICBhc3NlcnQubGVuZ3RoT2YoJ2Zvb2JhcicsIDYsICdzdHJpbmcgaGFzIGxlbmd0aCBvZiA2Jyk7XG4gICAqXG4gICAqIEBuYW1lIGxlbmd0aE9mXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5sZW5ndGhPZiA9IGZ1bmN0aW9uIChleHAsIGxlbiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZykudG8uaGF2ZS5sZW5ndGgobGVuKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC50aHJvd3MoZnVuY3Rpb24sIFtjb25zdHJ1Y3Rvci9zdHJpbmcvcmVnZXhwXSwgW3N0cmluZy9yZWdleHBdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgZnVuY3Rpb25gIHdpbGwgdGhyb3cgYW4gZXJyb3IgdGhhdCBpcyBhbiBpbnN0YW5jZSBvZlxuICAgKiBgY29uc3RydWN0b3JgLCBvciBhbHRlcm5hdGVseSB0aGF0IGl0IHdpbGwgdGhyb3cgYW4gZXJyb3Igd2l0aCBtZXNzYWdlXG4gICAqIG1hdGNoaW5nIGByZWdleHBgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnRocm93cyhmbiwgJ2Z1bmN0aW9uIHRocm93cyBhIHJlZmVyZW5jZSBlcnJvcicpO1xuICAgKiAgICAgYXNzZXJ0LnRocm93cyhmbiwgL2Z1bmN0aW9uIHRocm93cyBhIHJlZmVyZW5jZSBlcnJvci8pO1xuICAgKiAgICAgYXNzZXJ0LnRocm93cyhmbiwgUmVmZXJlbmNlRXJyb3IpO1xuICAgKiAgICAgYXNzZXJ0LnRocm93cyhmbiwgUmVmZXJlbmNlRXJyb3IsICdmdW5jdGlvbiB0aHJvd3MgYSByZWZlcmVuY2UgZXJyb3InKTtcbiAgICogICAgIGFzc2VydC50aHJvd3MoZm4sIFJlZmVyZW5jZUVycm9yLCAvZnVuY3Rpb24gdGhyb3dzIGEgcmVmZXJlbmNlIGVycm9yLyk7XG4gICAqXG4gICAqIEBuYW1lIHRocm93c1xuICAgKiBAYWxpYXMgdGhyb3dcbiAgICogQGFsaWFzIFRocm93XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7RXJyb3JDb25zdHJ1Y3Rvcn0gY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Vycm9yI0Vycm9yX3R5cGVzXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC50aHJvd3MgPSBmdW5jdGlvbiAoZm4sIGVycnQsIGVycnMsIG1zZykge1xuICAgIGlmICgnc3RyaW5nJyA9PT0gdHlwZW9mIGVycnQgfHwgZXJydCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgZXJycyA9IGVycnQ7XG4gICAgICBlcnJ0ID0gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgYXNzZXJ0RXJyID0gbmV3IEFzc2VydGlvbihmbiwgbXNnKS50by50aHJvdyhlcnJ0LCBlcnJzKTtcbiAgICByZXR1cm4gZmxhZyhhc3NlcnRFcnIsICdvYmplY3QnKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5kb2VzTm90VGhyb3coZnVuY3Rpb24sIFtjb25zdHJ1Y3Rvci9yZWdleHBdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgZnVuY3Rpb25gIHdpbGwgX25vdF8gdGhyb3cgYW4gZXJyb3IgdGhhdCBpcyBhbiBpbnN0YW5jZSBvZlxuICAgKiBgY29uc3RydWN0b3JgLCBvciBhbHRlcm5hdGVseSB0aGF0IGl0IHdpbGwgbm90IHRocm93IGFuIGVycm9yIHdpdGggbWVzc2FnZVxuICAgKiBtYXRjaGluZyBgcmVnZXhwYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5kb2VzTm90VGhyb3coZm4sIEVycm9yLCAnZnVuY3Rpb24gZG9lcyBub3QgdGhyb3cnKTtcbiAgICpcbiAgICogQG5hbWUgZG9lc05vdFRocm93XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7RXJyb3JDb25zdHJ1Y3Rvcn0gY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Vycm9yI0Vycm9yX3R5cGVzXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kb2VzTm90VGhyb3cgPSBmdW5jdGlvbiAoZm4sIHR5cGUsIG1zZykge1xuICAgIGlmICgnc3RyaW5nJyA9PT0gdHlwZW9mIHR5cGUpIHtcbiAgICAgIG1zZyA9IHR5cGU7XG4gICAgICB0eXBlID0gbnVsbDtcbiAgICB9XG5cbiAgICBuZXcgQXNzZXJ0aW9uKGZuLCBtc2cpLnRvLm5vdC5UaHJvdyh0eXBlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5vcGVyYXRvcih2YWwxLCBvcGVyYXRvciwgdmFsMiwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBDb21wYXJlcyB0d28gdmFsdWVzIHVzaW5nIGBvcGVyYXRvcmAuXG4gICAqXG4gICAqICAgICBhc3NlcnQub3BlcmF0b3IoMSwgJzwnLCAyLCAnZXZlcnl0aGluZyBpcyBvaycpO1xuICAgKiAgICAgYXNzZXJ0Lm9wZXJhdG9yKDEsICc+JywgMiwgJ3RoaXMgd2lsbCBmYWlsJyk7XG4gICAqXG4gICAqIEBuYW1lIG9wZXJhdG9yXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbDFcbiAgICogQHBhcmFtIHtTdHJpbmd9IG9wZXJhdG9yXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbDJcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm9wZXJhdG9yID0gZnVuY3Rpb24gKHZhbCwgb3BlcmF0b3IsIHZhbDIsIG1zZykge1xuICAgIHZhciBvaztcbiAgICBzd2l0Y2gob3BlcmF0b3IpIHtcbiAgICAgIGNhc2UgJz09JzpcbiAgICAgICAgb2sgPSB2YWwgPT0gdmFsMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICc9PT0nOlxuICAgICAgICBvayA9IHZhbCA9PT0gdmFsMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICc+JzpcbiAgICAgICAgb2sgPSB2YWwgPiB2YWwyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJz49JzpcbiAgICAgICAgb2sgPSB2YWwgPj0gdmFsMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICc8JzpcbiAgICAgICAgb2sgPSB2YWwgPCB2YWwyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzw9JzpcbiAgICAgICAgb2sgPSB2YWwgPD0gdmFsMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICchPSc6XG4gICAgICAgIG9rID0gdmFsICE9IHZhbDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnIT09JzpcbiAgICAgICAgb2sgPSB2YWwgIT09IHZhbDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG9wZXJhdG9yIFwiJyArIG9wZXJhdG9yICsgJ1wiJyk7XG4gICAgfVxuICAgIHZhciB0ZXN0ID0gbmV3IEFzc2VydGlvbihvaywgbXNnKTtcbiAgICB0ZXN0LmFzc2VydChcbiAgICAgICAgdHJ1ZSA9PT0gZmxhZyh0ZXN0LCAnb2JqZWN0JylcbiAgICAgICwgJ2V4cGVjdGVkICcgKyB1dGlsLmluc3BlY3QodmFsKSArICcgdG8gYmUgJyArIG9wZXJhdG9yICsgJyAnICsgdXRpbC5pbnNwZWN0KHZhbDIpXG4gICAgICAsICdleHBlY3RlZCAnICsgdXRpbC5pbnNwZWN0KHZhbCkgKyAnIHRvIG5vdCBiZSAnICsgb3BlcmF0b3IgKyAnICcgKyB1dGlsLmluc3BlY3QodmFsMikgKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5jbG9zZVRvKGFjdHVhbCwgZXhwZWN0ZWQsIGRlbHRhLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGVxdWFsIGBleHBlY3RlZGAsIHRvIHdpdGhpbiBhICsvLSBgZGVsdGFgIHJhbmdlLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmNsb3NlVG8oMS41LCAxLCAwLjUsICdudW1iZXJzIGFyZSBjbG9zZScpO1xuICAgKlxuICAgKiBAbmFtZSBjbG9zZVRvXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBhY3R1YWxcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBkZWx0YVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuY2xvc2VUbyA9IGZ1bmN0aW9uIChhY3QsIGV4cCwgZGVsdGEsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oYWN0LCBtc2cpLnRvLmJlLmNsb3NlVG8oZXhwLCBkZWx0YSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuYXBwcm94aW1hdGVseShhY3R1YWwsIGV4cGVjdGVkLCBkZWx0YSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCBgZXhwZWN0ZWRgLCB0byB3aXRoaW4gYSArLy0gYGRlbHRhYCByYW5nZS5cbiAgICpcbiAgICogICAgIGFzc2VydC5hcHByb3hpbWF0ZWx5KDEuNSwgMSwgMC41LCAnbnVtYmVycyBhcmUgY2xvc2UnKTtcbiAgICpcbiAgICogQG5hbWUgYXBwcm94aW1hdGVseVxuICAgKiBAcGFyYW0ge051bWJlcn0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge051bWJlcn0gZGVsdGFcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmFwcHJveGltYXRlbHkgPSBmdW5jdGlvbiAoYWN0LCBleHAsIGRlbHRhLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnKS50by5iZS5hcHByb3hpbWF0ZWx5KGV4cCwgZGVsdGEpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLnNhbWVNZW1iZXJzKHNldDEsIHNldDIsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBzZXQxYCBhbmQgYHNldDJgIGhhdmUgdGhlIHNhbWUgbWVtYmVycy5cbiAgICogT3JkZXIgaXMgbm90IHRha2VuIGludG8gYWNjb3VudC5cbiAgICpcbiAgICogICAgIGFzc2VydC5zYW1lTWVtYmVycyhbIDEsIDIsIDMgXSwgWyAyLCAxLCAzIF0sICdzYW1lIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgc2FtZU1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MVxuICAgKiBAcGFyYW0ge0FycmF5fSBzZXQyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5zYW1lTWVtYmVycyA9IGZ1bmN0aW9uIChzZXQxLCBzZXQyLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHNldDEsIG1zZykudG8uaGF2ZS5zYW1lLm1lbWJlcnMoc2V0Mik7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5zYW1lRGVlcE1lbWJlcnMoc2V0MSwgc2V0MiwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHNldDFgIGFuZCBgc2V0MmAgaGF2ZSB0aGUgc2FtZSBtZW1iZXJzIC0gdXNpbmcgYSBkZWVwIGVxdWFsaXR5IGNoZWNraW5nLlxuICAgKiBPcmRlciBpcyBub3QgdGFrZW4gaW50byBhY2NvdW50LlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyhbIHtiOiAzfSwge2E6IDJ9LCB7YzogNX0gXSwgWyB7YzogNX0sIHtiOiAzfSwge2E6IDJ9IF0sICdzYW1lIGRlZXAgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBzYW1lRGVlcE1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MVxuICAgKiBAcGFyYW0ge0FycmF5fSBzZXQyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMgPSBmdW5jdGlvbiAoc2V0MSwgc2V0MiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzZXQxLCBtc2cpLnRvLmhhdmUuc2FtZS5kZWVwLm1lbWJlcnMoc2V0Mik7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5pbmNsdWRlTWVtYmVycyhzdXBlcnNldCwgc3Vic2V0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgc3Vic2V0YCBpcyBpbmNsdWRlZCBpbiBgc3VwZXJzZXRgLlxuICAgKiBPcmRlciBpcyBub3QgdGFrZW4gaW50byBhY2NvdW50LlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmluY2x1ZGVNZW1iZXJzKFsgMSwgMiwgMyBdLCBbIDIsIDEgXSwgJ2luY2x1ZGUgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBpbmNsdWRlTWVtYmVyc1xuICAgKiBAcGFyYW0ge0FycmF5fSBzdXBlcnNldFxuICAgKiBAcGFyYW0ge0FycmF5fSBzdWJzZXRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmluY2x1ZGVNZW1iZXJzID0gZnVuY3Rpb24gKHN1cGVyc2V0LCBzdWJzZXQsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc3VwZXJzZXQsIG1zZykudG8uaW5jbHVkZS5tZW1iZXJzKHN1YnNldCk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5pbmNsdWRlRGVlcE1lbWJlcnMoc3VwZXJzZXQsIHN1YnNldCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHN1YnNldGAgaXMgaW5jbHVkZWQgaW4gYHN1cGVyc2V0YCAtIHVzaW5nIGRlZXAgZXF1YWxpdHkgY2hlY2tpbmcuXG4gICAqIE9yZGVyIGlzIG5vdCB0YWtlbiBpbnRvIGFjY291bnQuXG4gICAqIER1cGxpY2F0ZXMgYXJlIGlnbm9yZWQuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKFsge2E6IDF9LCB7YjogMn0sIHtjOiAzfSBdLCBbIHtiOiAyfSwge2E6IDF9LCB7YjogMn0gXSwgJ2luY2x1ZGUgZGVlcCBtZW1iZXJzJyk7XG4gICAqXG4gICAqIEBuYW1lIGluY2x1ZGVEZWVwTWVtYmVyc1xuICAgKiBAcGFyYW0ge0FycmF5fSBzdXBlcnNldFxuICAgKiBAcGFyYW0ge0FycmF5fSBzdWJzZXRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyA9IGZ1bmN0aW9uIChzdXBlcnNldCwgc3Vic2V0LCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHN1cGVyc2V0LCBtc2cpLnRvLmluY2x1ZGUuZGVlcC5tZW1iZXJzKHN1YnNldCk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5vbmVPZihpbkxpc3QsIGxpc3QsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IG5vbi1vYmplY3QsIG5vbi1hcnJheSB2YWx1ZSBgaW5MaXN0YCBhcHBlYXJzIGluIHRoZSBmbGF0IGFycmF5IGBsaXN0YC5cbiAgICpcbiAgICogICAgIGFzc2VydC5vbmVPZigxLCBbIDIsIDEgXSwgJ05vdCBmb3VuZCBpbiBsaXN0Jyk7XG4gICAqXG4gICAqIEBuYW1lIG9uZU9mXG4gICAqIEBwYXJhbSB7Kn0gaW5MaXN0XG4gICAqIEBwYXJhbSB7QXJyYXk8Kj59IGxpc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm9uZU9mID0gZnVuY3Rpb24gKGluTGlzdCwgbGlzdCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihpbkxpc3QsIG1zZykudG8uYmUub25lT2YobGlzdCk7XG4gIH1cblxuICAgLyoqXG4gICAqICMjIyAuY2hhbmdlcyhmdW5jdGlvbiwgb2JqZWN0LCBwcm9wZXJ0eSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gY2hhbmdlcyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eVxuICAgKlxuICAgKiAgICAgdmFyIG9iaiA9IHsgdmFsOiAxMCB9O1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7IG9iai52YWwgPSAyMiB9O1xuICAgKiAgICAgYXNzZXJ0LmNoYW5nZXMoZm4sIG9iaiwgJ3ZhbCcpO1xuICAgKlxuICAgKiBAbmFtZSBjaGFuZ2VzXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG1vZGlmaWVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IG5hbWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuY2hhbmdlcyA9IGZ1bmN0aW9uIChmbiwgb2JqLCBwcm9wKSB7XG4gICAgbmV3IEFzc2VydGlvbihmbikudG8uY2hhbmdlKG9iaiwgcHJvcCk7XG4gIH1cblxuICAgLyoqXG4gICAqICMjIyAuZG9lc05vdENoYW5nZShmdW5jdGlvbiwgb2JqZWN0LCBwcm9wZXJ0eSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gZG9lcyBub3QgY2hhbmdlcyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eVxuICAgKlxuICAgKiAgICAgdmFyIG9iaiA9IHsgdmFsOiAxMCB9O1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7IGNvbnNvbGUubG9nKCdmb28nKTsgfTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90Q2hhbmdlKGZuLCBvYmosICd2YWwnKTtcbiAgICpcbiAgICogQG5hbWUgZG9lc05vdENoYW5nZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtb2RpZmllciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRvZXNOb3RDaGFuZ2UgPSBmdW5jdGlvbiAoZm4sIG9iaiwgcHJvcCkge1xuICAgIG5ldyBBc3NlcnRpb24oZm4pLnRvLm5vdC5jaGFuZ2Uob2JqLCBwcm9wKTtcbiAgfVxuXG4gICAvKipcbiAgICogIyMjIC5pbmNyZWFzZXMoZnVuY3Rpb24sIG9iamVjdCwgcHJvcGVydHkpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGluY3JlYXNlcyBhbiBvYmplY3QgcHJvcGVydHlcbiAgICpcbiAgICogICAgIHZhciBvYmogPSB7IHZhbDogMTAgfTtcbiAgICogICAgIHZhciBmbiA9IGZ1bmN0aW9uKCkgeyBvYmoudmFsID0gMTMgfTtcbiAgICogICAgIGFzc2VydC5pbmNyZWFzZXMoZm4sIG9iaiwgJ3ZhbCcpO1xuICAgKlxuICAgKiBAbmFtZSBpbmNyZWFzZXNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbW9kaWZpZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHkgbmFtZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pbmNyZWFzZXMgPSBmdW5jdGlvbiAoZm4sIG9iaiwgcHJvcCkge1xuICAgIG5ldyBBc3NlcnRpb24oZm4pLnRvLmluY3JlYXNlKG9iaiwgcHJvcCk7XG4gIH1cblxuICAgLyoqXG4gICAqICMjIyAuZG9lc05vdEluY3JlYXNlKGZ1bmN0aW9uLCBvYmplY3QsIHByb3BlcnR5KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYSBmdW5jdGlvbiBkb2VzIG5vdCBpbmNyZWFzZSBvYmplY3QgcHJvcGVydHlcbiAgICpcbiAgICogICAgIHZhciBvYmogPSB7IHZhbDogMTAgfTtcbiAgICogICAgIHZhciBmbiA9IGZ1bmN0aW9uKCkgeyBvYmoudmFsID0gOCB9O1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RJbmNyZWFzZShmbiwgb2JqLCAndmFsJyk7XG4gICAqXG4gICAqIEBuYW1lIGRvZXNOb3RJbmNyZWFzZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtb2RpZmllciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRvZXNOb3RJbmNyZWFzZSA9IGZ1bmN0aW9uIChmbiwgb2JqLCBwcm9wKSB7XG4gICAgbmV3IEFzc2VydGlvbihmbikudG8ubm90LmluY3JlYXNlKG9iaiwgcHJvcCk7XG4gIH1cblxuICAgLyoqXG4gICAqICMjIyAuZGVjcmVhc2VzKGZ1bmN0aW9uLCBvYmplY3QsIHByb3BlcnR5KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYSBmdW5jdGlvbiBkZWNyZWFzZXMgYW4gb2JqZWN0IHByb3BlcnR5XG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCA9IDUgfTtcbiAgICogICAgIGFzc2VydC5kZWNyZWFzZXMoZm4sIG9iaiwgJ3ZhbCcpO1xuICAgKlxuICAgKiBAbmFtZSBkZWNyZWFzZXNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbW9kaWZpZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHkgbmFtZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kZWNyZWFzZXMgPSBmdW5jdGlvbiAoZm4sIG9iaiwgcHJvcCkge1xuICAgIG5ldyBBc3NlcnRpb24oZm4pLnRvLmRlY3JlYXNlKG9iaiwgcHJvcCk7XG4gIH1cblxuICAgLyoqXG4gICAqICMjIyAuZG9lc05vdERlY3JlYXNlKGZ1bmN0aW9uLCBvYmplY3QsIHByb3BlcnR5KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYSBmdW5jdGlvbiBkb2VzIG5vdCBkZWNyZWFzZXMgYW4gb2JqZWN0IHByb3BlcnR5XG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCA9IDE1IH07XG4gICAqICAgICBhc3NlcnQuZG9lc05vdERlY3JlYXNlKGZuLCBvYmosICd2YWwnKTtcbiAgICpcbiAgICogQG5hbWUgZG9lc05vdERlY3JlYXNlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG1vZGlmaWVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IG5hbWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZG9lc05vdERlY3JlYXNlID0gZnVuY3Rpb24gKGZuLCBvYmosIHByb3ApIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGZuKS50by5ub3QuZGVjcmVhc2Uob2JqLCBwcm9wKTtcbiAgfVxuXG4gIC8qIVxuICAgKiAjIyMgLmlmRXJyb3Iob2JqZWN0KVxuICAgKlxuICAgKiBBc3NlcnRzIGlmIHZhbHVlIGlzIG5vdCBhIGZhbHNlIHZhbHVlLCBhbmQgdGhyb3dzIGlmIGl0IGlzIGEgdHJ1ZSB2YWx1ZS5cbiAgICogVGhpcyBpcyBhZGRlZCB0byBhbGxvdyBmb3IgY2hhaSB0byBiZSBhIGRyb3AtaW4gcmVwbGFjZW1lbnQgZm9yIE5vZGUnc1xuICAgKiBhc3NlcnQgY2xhc3MuXG4gICAqXG4gICAqICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdJIGFtIGEgY3VzdG9tIGVycm9yJyk7XG4gICAqICAgICBhc3NlcnQuaWZFcnJvcihlcnIpOyAvLyBSZXRocm93cyBlcnIhXG4gICAqXG4gICAqIEBuYW1lIGlmRXJyb3JcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaWZFcnJvciA9IGZ1bmN0aW9uICh2YWwpIHtcbiAgICBpZiAodmFsKSB7XG4gICAgICB0aHJvdyh2YWwpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0V4dGVuc2libGUob2JqZWN0KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaXMgZXh0ZW5zaWJsZSAoY2FuIGhhdmUgbmV3IHByb3BlcnRpZXMgYWRkZWQgdG8gaXQpLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzRXh0ZW5zaWJsZSh7fSk7XG4gICAqXG4gICAqIEBuYW1lIGlzRXh0ZW5zaWJsZVxuICAgKiBAYWxpYXMgZXh0ZW5zaWJsZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzRXh0ZW5zaWJsZSA9IGZ1bmN0aW9uIChvYmosIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLnRvLmJlLmV4dGVuc2libGU7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RFeHRlbnNpYmxlKG9iamVjdClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGlzIF9ub3RfIGV4dGVuc2libGUuXG4gICAqXG4gICAqICAgICB2YXIgbm9uRXh0ZW5zaWJsZU9iamVjdCA9IE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucyh7fSk7XG4gICAqICAgICB2YXIgc2VhbGVkT2JqZWN0ID0gT2JqZWN0LnNlYWwoe30pO1xuICAgKiAgICAgdmFyIGZyb3plbk9iamVjdCA9IE9iamVjdC5mcmVlc2Uoe30pO1xuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTm90RXh0ZW5zaWJsZShub25FeHRlbnNpYmxlT2JqZWN0KTtcbiAgICogICAgIGFzc2VydC5pc05vdEV4dGVuc2libGUoc2VhbGVkT2JqZWN0KTtcbiAgICogICAgIGFzc2VydC5pc05vdEV4dGVuc2libGUoZnJvemVuT2JqZWN0KTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RFeHRlbnNpYmxlXG4gICAqIEBhbGlhcyBub3RFeHRlbnNpYmxlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RFeHRlbnNpYmxlID0gZnVuY3Rpb24gKG9iaiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8ubm90LmJlLmV4dGVuc2libGU7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNTZWFsZWQob2JqZWN0KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaXMgc2VhbGVkIChjYW5ub3QgaGF2ZSBuZXcgcHJvcGVydGllcyBhZGRlZCB0byBpdFxuICAgKiBhbmQgaXRzIGV4aXN0aW5nIHByb3BlcnRpZXMgY2Fubm90IGJlIHJlbW92ZWQpLlxuICAgKlxuICAgKiAgICAgdmFyIHNlYWxlZE9iamVjdCA9IE9iamVjdC5zZWFsKHt9KTtcbiAgICogICAgIHZhciBmcm96ZW5PYmplY3QgPSBPYmplY3Quc2VhbCh7fSk7XG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNTZWFsZWQoc2VhbGVkT2JqZWN0KTtcbiAgICogICAgIGFzc2VydC5pc1NlYWxlZChmcm96ZW5PYmplY3QpO1xuICAgKlxuICAgKiBAbmFtZSBpc1NlYWxlZFxuICAgKiBAYWxpYXMgc2VhbGVkXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNTZWFsZWQgPSBmdW5jdGlvbiAob2JqLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5iZS5zZWFsZWQ7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RTZWFsZWQob2JqZWN0KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaXMgX25vdF8gc2VhbGVkLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTm90U2VhbGVkKHt9KTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RTZWFsZWRcbiAgICogQGFsaWFzIG5vdFNlYWxlZFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90U2VhbGVkID0gZnVuY3Rpb24gKG9iaiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8ubm90LmJlLnNlYWxlZDtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0Zyb3plbihvYmplY3QpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBpcyBmcm96ZW4gKGNhbm5vdCBoYXZlIG5ldyBwcm9wZXJ0aWVzIGFkZGVkIHRvIGl0XG4gICAqIGFuZCBpdHMgZXhpc3RpbmcgcHJvcGVydGllcyBjYW5ub3QgYmUgbW9kaWZpZWQpLlxuICAgKlxuICAgKiAgICAgdmFyIGZyb3plbk9iamVjdCA9IE9iamVjdC5mcmVlemUoe30pO1xuICAgKiAgICAgYXNzZXJ0LmZyb3plbihmcm96ZW5PYmplY3QpO1xuICAgKlxuICAgKiBAbmFtZSBpc0Zyb3plblxuICAgKiBAYWxpYXMgZnJvemVuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNGcm96ZW4gPSBmdW5jdGlvbiAob2JqLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5iZS5mcm96ZW47XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RGcm96ZW4ob2JqZWN0KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaXMgX25vdF8gZnJvemVuLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTm90RnJvemVuKHt9KTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RGcm96ZW5cbiAgICogQGFsaWFzIG5vdEZyb3plblxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90RnJvemVuID0gZnVuY3Rpb24gKG9iaiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8ubm90LmJlLmZyb3plbjtcbiAgfTtcblxuICAvKiFcbiAgICogQWxpYXNlcy5cbiAgICovXG5cbiAgKGZ1bmN0aW9uIGFsaWFzKG5hbWUsIGFzKXtcbiAgICBhc3NlcnRbYXNdID0gYXNzZXJ0W25hbWVdO1xuICAgIHJldHVybiBhbGlhcztcbiAgfSlcbiAgKCdpc09rJywgJ29rJylcbiAgKCdpc05vdE9rJywgJ25vdE9rJylcbiAgKCd0aHJvd3MnLCAndGhyb3cnKVxuICAoJ3Rocm93cycsICdUaHJvdycpXG4gICgnaXNFeHRlbnNpYmxlJywgJ2V4dGVuc2libGUnKVxuICAoJ2lzTm90RXh0ZW5zaWJsZScsICdub3RFeHRlbnNpYmxlJylcbiAgKCdpc1NlYWxlZCcsICdzZWFsZWQnKVxuICAoJ2lzTm90U2VhbGVkJywgJ25vdFNlYWxlZCcpXG4gICgnaXNGcm96ZW4nLCAnZnJvemVuJylcbiAgKCdpc05vdEZyb3plbicsICdub3RGcm96ZW4nKTtcbn07XG4iLCIvKiFcbiAqIGNoYWlcbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjaGFpLCB1dGlsKSB7XG4gIGNoYWkuZXhwZWN0ID0gZnVuY3Rpb24gKHZhbCwgbWVzc2FnZSkge1xuICAgIHJldHVybiBuZXcgY2hhaS5Bc3NlcnRpb24odmFsLCBtZXNzYWdlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5mYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSwgW29wZXJhdG9yXSlcbiAgICpcbiAgICogVGhyb3cgYSBmYWlsdXJlLlxuICAgKlxuICAgKiBAbmFtZSBmYWlsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gb3BlcmF0b3JcbiAgICogQG5hbWVzcGFjZSBFeHBlY3RcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgY2hhaS5leHBlY3QuZmFpbCA9IGZ1bmN0aW9uIChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCBvcGVyYXRvcikge1xuICAgIG1lc3NhZ2UgPSBtZXNzYWdlIHx8ICdleHBlY3QuZmFpbCgpJztcbiAgICB0aHJvdyBuZXcgY2hhaS5Bc3NlcnRpb25FcnJvcihtZXNzYWdlLCB7XG4gICAgICAgIGFjdHVhbDogYWN0dWFsXG4gICAgICAsIGV4cGVjdGVkOiBleHBlY3RlZFxuICAgICAgLCBvcGVyYXRvcjogb3BlcmF0b3JcbiAgICB9LCBjaGFpLmV4cGVjdC5mYWlsKTtcbiAgfTtcbn07XG4iLCIvKiFcbiAqIGNoYWlcbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjaGFpLCB1dGlsKSB7XG4gIHZhciBBc3NlcnRpb24gPSBjaGFpLkFzc2VydGlvbjtcblxuICBmdW5jdGlvbiBsb2FkU2hvdWxkICgpIHtcbiAgICAvLyBleHBsaWNpdGx5IGRlZmluZSB0aGlzIG1ldGhvZCBhcyBmdW5jdGlvbiBhcyB0byBoYXZlIGl0J3MgbmFtZSB0byBpbmNsdWRlIGFzIGBzc2ZpYFxuICAgIGZ1bmN0aW9uIHNob3VsZEdldHRlcigpIHtcbiAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgU3RyaW5nIHx8IHRoaXMgaW5zdGFuY2VvZiBOdW1iZXIgfHwgdGhpcyBpbnN0YW5jZW9mIEJvb2xlYW4gKSB7XG4gICAgICAgIHJldHVybiBuZXcgQXNzZXJ0aW9uKHRoaXMudmFsdWVPZigpLCBudWxsLCBzaG91bGRHZXR0ZXIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBBc3NlcnRpb24odGhpcywgbnVsbCwgc2hvdWxkR2V0dGVyKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gc2hvdWxkU2V0dGVyKHZhbHVlKSB7XG4gICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYWlqcy9jaGFpL2lzc3Vlcy84NjogdGhpcyBtYWtlc1xuICAgICAgLy8gYHdoYXRldmVyLnNob3VsZCA9IHNvbWVWYWx1ZWAgYWN0dWFsbHkgc2V0IGBzb21lVmFsdWVgLCB3aGljaCBpc1xuICAgICAgLy8gZXNwZWNpYWxseSB1c2VmdWwgZm9yIGBnbG9iYWwuc2hvdWxkID0gcmVxdWlyZSgnY2hhaScpLnNob3VsZCgpYC5cbiAgICAgIC8vXG4gICAgICAvLyBOb3RlIHRoYXQgd2UgaGF2ZSB0byB1c2UgW1tEZWZpbmVQcm9wZXJ0eV1dIGluc3RlYWQgb2YgW1tQdXRdXVxuICAgICAgLy8gc2luY2Ugb3RoZXJ3aXNlIHdlIHdvdWxkIHRyaWdnZXIgdGhpcyB2ZXJ5IHNldHRlciFcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnc2hvdWxkJywge1xuICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWVcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBtb2RpZnkgT2JqZWN0LnByb3RvdHlwZSB0byBoYXZlIGBzaG91bGRgXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5wcm90b3R5cGUsICdzaG91bGQnLCB7XG4gICAgICBzZXQ6IHNob3VsZFNldHRlclxuICAgICAgLCBnZXQ6IHNob3VsZEdldHRlclxuICAgICAgLCBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcblxuICAgIHZhciBzaG91bGQgPSB7fTtcblxuICAgIC8qKlxuICAgICAqICMjIyAuZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0sIFtvcGVyYXRvcl0pXG4gICAgICpcbiAgICAgKiBUaHJvdyBhIGZhaWx1cmUuXG4gICAgICpcbiAgICAgKiBAbmFtZSBmYWlsXG4gICAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBvcGVyYXRvclxuICAgICAqIEBuYW1lc3BhY2UgU2hvdWxkXG4gICAgICogQGFwaSBwdWJsaWNcbiAgICAgKi9cblxuICAgIHNob3VsZC5mYWlsID0gZnVuY3Rpb24gKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wZXJhdG9yKSB7XG4gICAgICBtZXNzYWdlID0gbWVzc2FnZSB8fCAnc2hvdWxkLmZhaWwoKSc7XG4gICAgICB0aHJvdyBuZXcgY2hhaS5Bc3NlcnRpb25FcnJvcihtZXNzYWdlLCB7XG4gICAgICAgICAgYWN0dWFsOiBhY3R1YWxcbiAgICAgICAgLCBleHBlY3RlZDogZXhwZWN0ZWRcbiAgICAgICAgLCBvcGVyYXRvcjogb3BlcmF0b3JcbiAgICAgIH0sIHNob3VsZC5mYWlsKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogIyMjIC5lcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0pXG4gICAgICpcbiAgICAgKiBBc3NlcnRzIG5vbi1zdHJpY3QgZXF1YWxpdHkgKGA9PWApIG9mIGBhY3R1YWxgIGFuZCBgZXhwZWN0ZWRgLlxuICAgICAqXG4gICAgICogICAgIHNob3VsZC5lcXVhbCgzLCAnMycsICc9PSBjb2VyY2VzIHZhbHVlcyB0byBzdHJpbmdzJyk7XG4gICAgICpcbiAgICAgKiBAbmFtZSBlcXVhbFxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICAgKiBAbmFtZXNwYWNlIFNob3VsZFxuICAgICAqIEBhcGkgcHVibGljXG4gICAgICovXG5cbiAgICBzaG91bGQuZXF1YWwgPSBmdW5jdGlvbiAodmFsMSwgdmFsMiwgbXNnKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKHZhbDEsIG1zZykudG8uZXF1YWwodmFsMik7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqICMjIyAudGhyb3coZnVuY3Rpb24sIFtjb25zdHJ1Y3Rvci9zdHJpbmcvcmVnZXhwXSwgW3N0cmluZy9yZWdleHBdLCBbbWVzc2FnZV0pXG4gICAgICpcbiAgICAgKiBBc3NlcnRzIHRoYXQgYGZ1bmN0aW9uYCB3aWxsIHRocm93IGFuIGVycm9yIHRoYXQgaXMgYW4gaW5zdGFuY2Ugb2ZcbiAgICAgKiBgY29uc3RydWN0b3JgLCBvciBhbHRlcm5hdGVseSB0aGF0IGl0IHdpbGwgdGhyb3cgYW4gZXJyb3Igd2l0aCBtZXNzYWdlXG4gICAgICogbWF0Y2hpbmcgYHJlZ2V4cGAuXG4gICAgICpcbiAgICAgKiAgICAgc2hvdWxkLnRocm93KGZuLCAnZnVuY3Rpb24gdGhyb3dzIGEgcmVmZXJlbmNlIGVycm9yJyk7XG4gICAgICogICAgIHNob3VsZC50aHJvdyhmbiwgL2Z1bmN0aW9uIHRocm93cyBhIHJlZmVyZW5jZSBlcnJvci8pO1xuICAgICAqICAgICBzaG91bGQudGhyb3coZm4sIFJlZmVyZW5jZUVycm9yKTtcbiAgICAgKiAgICAgc2hvdWxkLnRocm93KGZuLCBSZWZlcmVuY2VFcnJvciwgJ2Z1bmN0aW9uIHRocm93cyBhIHJlZmVyZW5jZSBlcnJvcicpO1xuICAgICAqICAgICBzaG91bGQudGhyb3coZm4sIFJlZmVyZW5jZUVycm9yLCAvZnVuY3Rpb24gdGhyb3dzIGEgcmVmZXJlbmNlIGVycm9yLyk7XG4gICAgICpcbiAgICAgKiBAbmFtZSB0aHJvd1xuICAgICAqIEBhbGlhcyBUaHJvd1xuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtFcnJvckNvbnN0cnVjdG9yfSBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7UmVnRXhwfSByZWdleHBcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRXJyb3IjRXJyb3JfdHlwZXNcbiAgICAgKiBAbmFtZXNwYWNlIFNob3VsZFxuICAgICAqIEBhcGkgcHVibGljXG4gICAgICovXG5cbiAgICBzaG91bGQuVGhyb3cgPSBmdW5jdGlvbiAoZm4sIGVycnQsIGVycnMsIG1zZykge1xuICAgICAgbmV3IEFzc2VydGlvbihmbiwgbXNnKS50by5UaHJvdyhlcnJ0LCBlcnJzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogIyMjIC5leGlzdFxuICAgICAqXG4gICAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgbmVpdGhlciBgbnVsbGAgbm9yIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogICAgIHZhciBmb28gPSAnaGknO1xuICAgICAqXG4gICAgICogICAgIHNob3VsZC5leGlzdChmb28sICdmb28gZXhpc3RzJyk7XG4gICAgICpcbiAgICAgKiBAbmFtZSBleGlzdFxuICAgICAqIEBuYW1lc3BhY2UgU2hvdWxkXG4gICAgICogQGFwaSBwdWJsaWNcbiAgICAgKi9cblxuICAgIHNob3VsZC5leGlzdCA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8uZXhpc3Q7XG4gICAgfVxuXG4gICAgLy8gbmVnYXRpb25cbiAgICBzaG91bGQubm90ID0ge31cblxuICAgIC8qKlxuICAgICAqICMjIyAubm90LmVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSlcbiAgICAgKlxuICAgICAqIEFzc2VydHMgbm9uLXN0cmljdCBpbmVxdWFsaXR5IChgIT1gKSBvZiBgYWN0dWFsYCBhbmQgYGV4cGVjdGVkYC5cbiAgICAgKlxuICAgICAqICAgICBzaG91bGQubm90LmVxdWFsKDMsIDQsICd0aGVzZSBudW1iZXJzIGFyZSBub3QgZXF1YWwnKTtcbiAgICAgKlxuICAgICAqIEBuYW1lIG5vdC5lcXVhbFxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICAgKiBAbmFtZXNwYWNlIFNob3VsZFxuICAgICAqIEBhcGkgcHVibGljXG4gICAgICovXG5cbiAgICBzaG91bGQubm90LmVxdWFsID0gZnVuY3Rpb24gKHZhbDEsIHZhbDIsIG1zZykge1xuICAgICAgbmV3IEFzc2VydGlvbih2YWwxLCBtc2cpLnRvLm5vdC5lcXVhbCh2YWwyKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogIyMjIC50aHJvdyhmdW5jdGlvbiwgW2NvbnN0cnVjdG9yL3JlZ2V4cF0sIFttZXNzYWdlXSlcbiAgICAgKlxuICAgICAqIEFzc2VydHMgdGhhdCBgZnVuY3Rpb25gIHdpbGwgX25vdF8gdGhyb3cgYW4gZXJyb3IgdGhhdCBpcyBhbiBpbnN0YW5jZSBvZlxuICAgICAqIGBjb25zdHJ1Y3RvcmAsIG9yIGFsdGVybmF0ZWx5IHRoYXQgaXQgd2lsbCBub3QgdGhyb3cgYW4gZXJyb3Igd2l0aCBtZXNzYWdlXG4gICAgICogbWF0Y2hpbmcgYHJlZ2V4cGAuXG4gICAgICpcbiAgICAgKiAgICAgc2hvdWxkLm5vdC50aHJvdyhmbiwgRXJyb3IsICdmdW5jdGlvbiBkb2VzIG5vdCB0aHJvdycpO1xuICAgICAqXG4gICAgICogQG5hbWUgbm90LnRocm93XG4gICAgICogQGFsaWFzIG5vdC5UaHJvd1xuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtFcnJvckNvbnN0cnVjdG9yfSBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7UmVnRXhwfSByZWdleHBcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRXJyb3IjRXJyb3JfdHlwZXNcbiAgICAgKiBAbmFtZXNwYWNlIFNob3VsZFxuICAgICAqIEBhcGkgcHVibGljXG4gICAgICovXG5cbiAgICBzaG91bGQubm90LlRocm93ID0gZnVuY3Rpb24gKGZuLCBlcnJ0LCBlcnJzLCBtc2cpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24oZm4sIG1zZykudG8ubm90LlRocm93KGVycnQsIGVycnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiAjIyMgLm5vdC5leGlzdFxuICAgICAqXG4gICAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgbmVpdGhlciBgbnVsbGAgbm9yIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogICAgIHZhciBiYXIgPSBudWxsO1xuICAgICAqXG4gICAgICogICAgIHNob3VsZC5ub3QuZXhpc3QoYmFyLCAnYmFyIGRvZXMgbm90IGV4aXN0Jyk7XG4gICAgICpcbiAgICAgKiBAbmFtZSBub3QuZXhpc3RcbiAgICAgKiBAbmFtZXNwYWNlIFNob3VsZFxuICAgICAqIEBhcGkgcHVibGljXG4gICAgICovXG5cbiAgICBzaG91bGQubm90LmV4aXN0ID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5ub3QuZXhpc3Q7XG4gICAgfVxuXG4gICAgc2hvdWxkWyd0aHJvdyddID0gc2hvdWxkWydUaHJvdyddO1xuICAgIHNob3VsZC5ub3RbJ3Rocm93J10gPSBzaG91bGQubm90WydUaHJvdyddO1xuXG4gICAgcmV0dXJuIHNob3VsZDtcbiAgfTtcblxuICBjaGFpLnNob3VsZCA9IGxvYWRTaG91bGQ7XG4gIGNoYWkuU2hvdWxkID0gbG9hZFNob3VsZDtcbn07XG4iLCIvKiFcbiAqIENoYWkgLSBhZGRDaGFpbmluZ01ldGhvZCB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzXG4gKi9cblxudmFyIHRyYW5zZmVyRmxhZ3MgPSByZXF1aXJlKCcuL3RyYW5zZmVyRmxhZ3MnKTtcbnZhciBmbGFnID0gcmVxdWlyZSgnLi9mbGFnJyk7XG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJyk7XG5cbi8qIVxuICogTW9kdWxlIHZhcmlhYmxlc1xuICovXG5cbi8vIENoZWNrIHdoZXRoZXIgYF9fcHJvdG9fX2AgaXMgc3VwcG9ydGVkXG52YXIgaGFzUHJvdG9TdXBwb3J0ID0gJ19fcHJvdG9fXycgaW4gT2JqZWN0O1xuXG4vLyBXaXRob3V0IGBfX3Byb3RvX19gIHN1cHBvcnQsIHRoaXMgbW9kdWxlIHdpbGwgbmVlZCB0byBhZGQgcHJvcGVydGllcyB0byBhIGZ1bmN0aW9uLlxuLy8gSG93ZXZlciwgc29tZSBGdW5jdGlvbi5wcm90b3R5cGUgbWV0aG9kcyBjYW5ub3QgYmUgb3ZlcndyaXR0ZW4sXG4vLyBhbmQgdGhlcmUgc2VlbXMgbm8gZWFzeSBjcm9zcy1wbGF0Zm9ybSB3YXkgdG8gZGV0ZWN0IHRoZW0gKEBzZWUgY2hhaWpzL2NoYWkvaXNzdWVzLzY5KS5cbnZhciBleGNsdWRlTmFtZXMgPSAvXig/Omxlbmd0aHxuYW1lfGFyZ3VtZW50c3xjYWxsZXIpJC87XG5cbi8vIENhY2hlIGBGdW5jdGlvbmAgcHJvcGVydGllc1xudmFyIGNhbGwgID0gRnVuY3Rpb24ucHJvdG90eXBlLmNhbGwsXG4gICAgYXBwbHkgPSBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHk7XG5cbi8qKlxuICogIyMjIGFkZENoYWluYWJsZU1ldGhvZCAoY3R4LCBuYW1lLCBtZXRob2QsIGNoYWluaW5nQmVoYXZpb3IpXG4gKlxuICogQWRkcyBhIG1ldGhvZCB0byBhbiBvYmplY3QsIHN1Y2ggdGhhdCB0aGUgbWV0aG9kIGNhbiBhbHNvIGJlIGNoYWluZWQuXG4gKlxuICogICAgIHV0aWxzLmFkZENoYWluYWJsZU1ldGhvZChjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsICdmb28nLCBmdW5jdGlvbiAoc3RyKSB7XG4gKiAgICAgICB2YXIgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gKiAgICAgICBuZXcgY2hhaS5Bc3NlcnRpb24ob2JqKS50by5iZS5lcXVhbChzdHIpO1xuICogICAgIH0pO1xuICpcbiAqIENhbiBhbHNvIGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGZyb20gYGNoYWkuQXNzZXJ0aW9uYC5cbiAqXG4gKiAgICAgY2hhaS5Bc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdmb28nLCBmbiwgY2hhaW5pbmdCZWhhdmlvcik7XG4gKlxuICogVGhlIHJlc3VsdCBjYW4gdGhlbiBiZSB1c2VkIGFzIGJvdGggYSBtZXRob2QgYXNzZXJ0aW9uLCBleGVjdXRpbmcgYm90aCBgbWV0aG9kYCBhbmRcbiAqIGBjaGFpbmluZ0JlaGF2aW9yYCwgb3IgYXMgYSBsYW5ndWFnZSBjaGFpbiwgd2hpY2ggb25seSBleGVjdXRlcyBgY2hhaW5pbmdCZWhhdmlvcmAuXG4gKlxuICogICAgIGV4cGVjdChmb29TdHIpLnRvLmJlLmZvbygnYmFyJyk7XG4gKiAgICAgZXhwZWN0KGZvb1N0cikudG8uYmUuZm9vLmVxdWFsKCdmb28nKTtcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY3R4IG9iamVjdCB0byB3aGljaCB0aGUgbWV0aG9kIGlzIGFkZGVkXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBvZiBtZXRob2QgdG8gYWRkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXRob2QgZnVuY3Rpb24gdG8gYmUgdXNlZCBmb3IgYG5hbWVgLCB3aGVuIGNhbGxlZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2hhaW5pbmdCZWhhdmlvciBmdW5jdGlvbiB0byBiZSBjYWxsZWQgZXZlcnkgdGltZSB0aGUgcHJvcGVydHkgaXMgYWNjZXNzZWRcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGFkZENoYWluYWJsZU1ldGhvZFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjdHgsIG5hbWUsIG1ldGhvZCwgY2hhaW5pbmdCZWhhdmlvcikge1xuICBpZiAodHlwZW9mIGNoYWluaW5nQmVoYXZpb3IgIT09ICdmdW5jdGlvbicpIHtcbiAgICBjaGFpbmluZ0JlaGF2aW9yID0gZnVuY3Rpb24gKCkgeyB9O1xuICB9XG5cbiAgdmFyIGNoYWluYWJsZUJlaGF2aW9yID0ge1xuICAgICAgbWV0aG9kOiBtZXRob2RcbiAgICAsIGNoYWluaW5nQmVoYXZpb3I6IGNoYWluaW5nQmVoYXZpb3JcbiAgfTtcblxuICAvLyBzYXZlIHRoZSBtZXRob2RzIHNvIHdlIGNhbiBvdmVyd3JpdGUgdGhlbSBsYXRlciwgaWYgd2UgbmVlZCB0by5cbiAgaWYgKCFjdHguX19tZXRob2RzKSB7XG4gICAgY3R4Ll9fbWV0aG9kcyA9IHt9O1xuICB9XG4gIGN0eC5fX21ldGhvZHNbbmFtZV0gPSBjaGFpbmFibGVCZWhhdmlvcjtcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBuYW1lLFxuICAgIHsgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNoYWluYWJsZUJlaGF2aW9yLmNoYWluaW5nQmVoYXZpb3IuY2FsbCh0aGlzKTtcblxuICAgICAgICB2YXIgYXNzZXJ0ID0gZnVuY3Rpb24gYXNzZXJ0KCkge1xuICAgICAgICAgIHZhciBvbGRfc3NmaSA9IGZsYWcodGhpcywgJ3NzZmknKTtcbiAgICAgICAgICBpZiAob2xkX3NzZmkgJiYgY29uZmlnLmluY2x1ZGVTdGFjayA9PT0gZmFsc2UpXG4gICAgICAgICAgICBmbGFnKHRoaXMsICdzc2ZpJywgYXNzZXJ0KTtcbiAgICAgICAgICB2YXIgcmVzdWx0ID0gY2hhaW5hYmxlQmVoYXZpb3IubWV0aG9kLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gdGhpcyA6IHJlc3VsdDtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBVc2UgYF9fcHJvdG9fX2AgaWYgYXZhaWxhYmxlXG4gICAgICAgIGlmIChoYXNQcm90b1N1cHBvcnQpIHtcbiAgICAgICAgICAvLyBJbmhlcml0IGFsbCBwcm9wZXJ0aWVzIGZyb20gdGhlIG9iamVjdCBieSByZXBsYWNpbmcgdGhlIGBGdW5jdGlvbmAgcHJvdG90eXBlXG4gICAgICAgICAgdmFyIHByb3RvdHlwZSA9IGFzc2VydC5fX3Byb3RvX18gPSBPYmplY3QuY3JlYXRlKHRoaXMpO1xuICAgICAgICAgIC8vIFJlc3RvcmUgdGhlIGBjYWxsYCBhbmQgYGFwcGx5YCBtZXRob2RzIGZyb20gYEZ1bmN0aW9uYFxuICAgICAgICAgIHByb3RvdHlwZS5jYWxsID0gY2FsbDtcbiAgICAgICAgICBwcm90b3R5cGUuYXBwbHkgPSBhcHBseTtcbiAgICAgICAgfVxuICAgICAgICAvLyBPdGhlcndpc2UsIHJlZGVmaW5lIGFsbCBwcm9wZXJ0aWVzIChzbG93ISlcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdmFyIGFzc2VydGVyTmFtZXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhjdHgpO1xuICAgICAgICAgIGFzc2VydGVyTmFtZXMuZm9yRWFjaChmdW5jdGlvbiAoYXNzZXJ0ZXJOYW1lKSB7XG4gICAgICAgICAgICBpZiAoIWV4Y2x1ZGVOYW1lcy50ZXN0KGFzc2VydGVyTmFtZSkpIHtcbiAgICAgICAgICAgICAgdmFyIHBkID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihjdHgsIGFzc2VydGVyTmFtZSk7XG4gICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhc3NlcnQsIGFzc2VydGVyTmFtZSwgcGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJhbnNmZXJGbGFncyh0aGlzLCBhc3NlcnQpO1xuICAgICAgICByZXR1cm4gYXNzZXJ0O1xuICAgICAgfVxuICAgICwgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pO1xufTtcbiIsIi8qIVxuICogQ2hhaSAtIGFkZE1ldGhvZCB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpO1xuXG4vKipcbiAqICMjIyAuYWRkTWV0aG9kIChjdHgsIG5hbWUsIG1ldGhvZClcbiAqXG4gKiBBZGRzIGEgbWV0aG9kIHRvIHRoZSBwcm90b3R5cGUgb2YgYW4gb2JqZWN0LlxuICpcbiAqICAgICB1dGlscy5hZGRNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCAnZm9vJywgZnVuY3Rpb24gKHN0cikge1xuICogICAgICAgdmFyIG9iaiA9IHV0aWxzLmZsYWcodGhpcywgJ29iamVjdCcpO1xuICogICAgICAgbmV3IGNoYWkuQXNzZXJ0aW9uKG9iaikudG8uYmUuZXF1YWwoc3RyKTtcbiAqICAgICB9KTtcbiAqXG4gKiBDYW4gYWxzbyBiZSBhY2Nlc3NlZCBkaXJlY3RseSBmcm9tIGBjaGFpLkFzc2VydGlvbmAuXG4gKlxuICogICAgIGNoYWkuQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZm9vJywgZm4pO1xuICpcbiAqIFRoZW4gY2FuIGJlIHVzZWQgYXMgYW55IG90aGVyIGFzc2VydGlvbi5cbiAqXG4gKiAgICAgZXhwZWN0KGZvb1N0cikudG8uYmUuZm9vKCdiYXInKTtcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY3R4IG9iamVjdCB0byB3aGljaCB0aGUgbWV0aG9kIGlzIGFkZGVkXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBvZiBtZXRob2QgdG8gYWRkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXRob2QgZnVuY3Rpb24gdG8gYmUgdXNlZCBmb3IgbmFtZVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgYWRkTWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjdHgsIG5hbWUsIG1ldGhvZCkge1xuICBjdHhbbmFtZV0gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG9sZF9zc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpO1xuICAgIGlmIChvbGRfc3NmaSAmJiBjb25maWcuaW5jbHVkZVN0YWNrID09PSBmYWxzZSlcbiAgICAgIGZsYWcodGhpcywgJ3NzZmknLCBjdHhbbmFtZV0pO1xuICAgIHZhciByZXN1bHQgPSBtZXRob2QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICByZXR1cm4gcmVzdWx0ID09PSB1bmRlZmluZWQgPyB0aGlzIDogcmVzdWx0O1xuICB9O1xufTtcbiIsIi8qIVxuICogQ2hhaSAtIGFkZFByb3BlcnR5IHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJyk7XG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpO1xuXG4vKipcbiAqICMjIyBhZGRQcm9wZXJ0eSAoY3R4LCBuYW1lLCBnZXR0ZXIpXG4gKlxuICogQWRkcyBhIHByb3BlcnR5IHRvIHRoZSBwcm90b3R5cGUgb2YgYW4gb2JqZWN0LlxuICpcbiAqICAgICB1dGlscy5hZGRQcm9wZXJ0eShjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsICdmb28nLCBmdW5jdGlvbiAoKSB7XG4gKiAgICAgICB2YXIgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gKiAgICAgICBuZXcgY2hhaS5Bc3NlcnRpb24ob2JqKS50by5iZS5pbnN0YW5jZW9mKEZvbyk7XG4gKiAgICAgfSk7XG4gKlxuICogQ2FuIGFsc28gYmUgYWNjZXNzZWQgZGlyZWN0bHkgZnJvbSBgY2hhaS5Bc3NlcnRpb25gLlxuICpcbiAqICAgICBjaGFpLkFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZm9vJywgZm4pO1xuICpcbiAqIFRoZW4gY2FuIGJlIHVzZWQgYXMgYW55IG90aGVyIGFzc2VydGlvbi5cbiAqXG4gKiAgICAgZXhwZWN0KG15Rm9vKS50by5iZS5mb287XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGN0eCBvYmplY3QgdG8gd2hpY2ggdGhlIHByb3BlcnR5IGlzIGFkZGVkXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBvZiBwcm9wZXJ0eSB0byBhZGRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGdldHRlciBmdW5jdGlvbiB0byBiZSB1c2VkIGZvciBuYW1lXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBhZGRQcm9wZXJ0eVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjdHgsIG5hbWUsIGdldHRlcikge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBuYW1lLFxuICAgIHsgZ2V0OiBmdW5jdGlvbiBhZGRQcm9wZXJ0eSgpIHtcbiAgICAgICAgdmFyIG9sZF9zc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpO1xuICAgICAgICBpZiAob2xkX3NzZmkgJiYgY29uZmlnLmluY2x1ZGVTdGFjayA9PT0gZmFsc2UpXG4gICAgICAgICAgZmxhZyh0aGlzLCAnc3NmaScsIGFkZFByb3BlcnR5KTtcblxuICAgICAgICB2YXIgcmVzdWx0ID0gZ2V0dGVyLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCA/IHRoaXMgOiByZXN1bHQ7XG4gICAgICB9XG4gICAgLCBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gZXhwZWN0VHlwZXMgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIGV4cGVjdFR5cGVzKG9iaiwgdHlwZXMpXG4gKlxuICogRW5zdXJlcyB0aGF0IHRoZSBvYmplY3QgYmVpbmcgdGVzdGVkIGFnYWluc3QgaXMgb2YgYSB2YWxpZCB0eXBlLlxuICpcbiAqICAgICB1dGlscy5leHBlY3RUeXBlcyh0aGlzLCBbJ2FycmF5JywgJ29iamVjdCcsICdzdHJpbmcnXSk7XG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqIGNvbnN0cnVjdGVkIEFzc2VydGlvblxuICogQHBhcmFtIHtBcnJheX0gdHlwZSBBIGxpc3Qgb2YgYWxsb3dlZCB0eXBlcyBmb3IgdGhpcyBhc3NlcnRpb25cbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGV4cGVjdFR5cGVzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnZhciBBc3NlcnRpb25FcnJvciA9IHJlcXVpcmUoJ2Fzc2VydGlvbi1lcnJvcicpO1xudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcbnZhciB0eXBlID0gcmVxdWlyZSgndHlwZS1kZXRlY3QnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqLCB0eXBlcykge1xuICB2YXIgb2JqID0gZmxhZyhvYmosICdvYmplY3QnKTtcbiAgdHlwZXMgPSB0eXBlcy5tYXAoZnVuY3Rpb24gKHQpIHsgcmV0dXJuIHQudG9Mb3dlckNhc2UoKTsgfSk7XG4gIHR5cGVzLnNvcnQoKTtcblxuICAvLyBUcmFuc2Zvcm1zIFsnbG9yZW0nLCAnaXBzdW0nXSBpbnRvICdhIGxpcnVtLCBvciBhbiBpcHN1bSdcbiAgdmFyIHN0ciA9IHR5cGVzLm1hcChmdW5jdGlvbiAodCwgaW5kZXgpIHtcbiAgICB2YXIgYXJ0ID0gflsgJ2EnLCAnZScsICdpJywgJ28nLCAndScgXS5pbmRleE9mKHQuY2hhckF0KDApKSA/ICdhbicgOiAnYSc7XG4gICAgdmFyIG9yID0gdHlwZXMubGVuZ3RoID4gMSAmJiBpbmRleCA9PT0gdHlwZXMubGVuZ3RoIC0gMSA/ICdvciAnIDogJyc7XG4gICAgcmV0dXJuIG9yICsgYXJ0ICsgJyAnICsgdDtcbiAgfSkuam9pbignLCAnKTtcblxuICBpZiAoIXR5cGVzLnNvbWUoZnVuY3Rpb24gKGV4cGVjdGVkKSB7IHJldHVybiB0eXBlKG9iaikgPT09IGV4cGVjdGVkOyB9KSkge1xuICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICAgICdvYmplY3QgdGVzdGVkIG11c3QgYmUgJyArIHN0ciArICcsIGJ1dCAnICsgdHlwZShvYmopICsgJyBnaXZlbidcbiAgICApO1xuICB9XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gZmxhZyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgZmxhZyhvYmplY3QsIGtleSwgW3ZhbHVlXSlcbiAqXG4gKiBHZXQgb3Igc2V0IGEgZmxhZyB2YWx1ZSBvbiBhbiBvYmplY3QuIElmIGFcbiAqIHZhbHVlIGlzIHByb3ZpZGVkIGl0IHdpbGwgYmUgc2V0LCBlbHNlIGl0IHdpbGxcbiAqIHJldHVybiB0aGUgY3VycmVudGx5IHNldCB2YWx1ZSBvciBgdW5kZWZpbmVkYCBpZlxuICogdGhlIHZhbHVlIGlzIG5vdCBzZXQuXG4gKlxuICogICAgIHV0aWxzLmZsYWcodGhpcywgJ2ZvbycsICdiYXInKTsgLy8gc2V0dGVyXG4gKiAgICAgdXRpbHMuZmxhZyh0aGlzLCAnZm9vJyk7IC8vIGdldHRlciwgcmV0dXJucyBgYmFyYFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgY29uc3RydWN0ZWQgQXNzZXJ0aW9uXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gKiBAcGFyYW0ge01peGVkfSB2YWx1ZSAob3B0aW9uYWwpXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBmbGFnXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmosIGtleSwgdmFsdWUpIHtcbiAgdmFyIGZsYWdzID0gb2JqLl9fZmxhZ3MgfHwgKG9iai5fX2ZsYWdzID0gT2JqZWN0LmNyZWF0ZShudWxsKSk7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgZmxhZ3Nba2V5XSA9IHZhbHVlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmbGFnc1trZXldO1xuICB9XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gZ2V0QWN0dWFsIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKipcbiAqICMgZ2V0QWN0dWFsKG9iamVjdCwgW2FjdHVhbF0pXG4gKlxuICogUmV0dXJucyB0aGUgYGFjdHVhbGAgdmFsdWUgZm9yIGFuIEFzc2VydGlvblxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgKGNvbnN0cnVjdGVkIEFzc2VydGlvbilcbiAqIEBwYXJhbSB7QXJndW1lbnRzfSBjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUuYXNzZXJ0IGFyZ3VtZW50c1xuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZ2V0QWN0dWFsXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqLCBhcmdzKSB7XG4gIHJldHVybiBhcmdzLmxlbmd0aCA+IDQgPyBhcmdzWzRdIDogb2JqLl9vYmo7XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gZ2V0RW51bWVyYWJsZVByb3BlcnRpZXMgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIC5nZXRFbnVtZXJhYmxlUHJvcGVydGllcyhvYmplY3QpXG4gKlxuICogVGhpcyBhbGxvd3MgdGhlIHJldHJpZXZhbCBvZiBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGFuIG9iamVjdCxcbiAqIGluaGVyaXRlZCBvciBub3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICogQHJldHVybnMge0FycmF5fVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZ2V0RW51bWVyYWJsZVByb3BlcnRpZXNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRFbnVtZXJhYmxlUHJvcGVydGllcyhvYmplY3QpIHtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBmb3IgKHZhciBuYW1lIGluIG9iamVjdCkge1xuICAgIHJlc3VsdC5wdXNoKG5hbWUpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gbWVzc2FnZSBjb21wb3NpdGlvbiB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNb2R1bGUgZGVwZW5kYW5jaWVzXG4gKi9cblxudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKVxuICAsIGdldEFjdHVhbCA9IHJlcXVpcmUoJy4vZ2V0QWN0dWFsJylcbiAgLCBpbnNwZWN0ID0gcmVxdWlyZSgnLi9pbnNwZWN0JylcbiAgLCBvYmpEaXNwbGF5ID0gcmVxdWlyZSgnLi9vYmpEaXNwbGF5Jyk7XG5cbi8qKlxuICogIyMjIC5nZXRNZXNzYWdlKG9iamVjdCwgbWVzc2FnZSwgbmVnYXRlTWVzc2FnZSlcbiAqXG4gKiBDb25zdHJ1Y3QgdGhlIGVycm9yIG1lc3NhZ2UgYmFzZWQgb24gZmxhZ3NcbiAqIGFuZCB0ZW1wbGF0ZSB0YWdzLiBUZW1wbGF0ZSB0YWdzIHdpbGwgcmV0dXJuXG4gKiBhIHN0cmluZ2lmaWVkIGluc3BlY3Rpb24gb2YgdGhlIG9iamVjdCByZWZlcmVuY2VkLlxuICpcbiAqIE1lc3NhZ2UgdGVtcGxhdGUgdGFnczpcbiAqIC0gYCN7dGhpc31gIGN1cnJlbnQgYXNzZXJ0ZWQgb2JqZWN0XG4gKiAtIGAje2FjdH1gIGFjdHVhbCB2YWx1ZVxuICogLSBgI3tleHB9YCBleHBlY3RlZCB2YWx1ZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgKGNvbnN0cnVjdGVkIEFzc2VydGlvbilcbiAqIEBwYXJhbSB7QXJndW1lbnRzfSBjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUuYXNzZXJ0IGFyZ3VtZW50c1xuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZ2V0TWVzc2FnZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmosIGFyZ3MpIHtcbiAgdmFyIG5lZ2F0ZSA9IGZsYWcob2JqLCAnbmVnYXRlJylcbiAgICAsIHZhbCA9IGZsYWcob2JqLCAnb2JqZWN0JylcbiAgICAsIGV4cGVjdGVkID0gYXJnc1szXVxuICAgICwgYWN0dWFsID0gZ2V0QWN0dWFsKG9iaiwgYXJncylcbiAgICAsIG1zZyA9IG5lZ2F0ZSA/IGFyZ3NbMl0gOiBhcmdzWzFdXG4gICAgLCBmbGFnTXNnID0gZmxhZyhvYmosICdtZXNzYWdlJyk7XG5cbiAgaWYodHlwZW9mIG1zZyA9PT0gXCJmdW5jdGlvblwiKSBtc2cgPSBtc2coKTtcbiAgbXNnID0gbXNnIHx8ICcnO1xuICBtc2cgPSBtc2dcbiAgICAucmVwbGFjZSgvI1xce3RoaXNcXH0vZywgZnVuY3Rpb24gKCkgeyByZXR1cm4gb2JqRGlzcGxheSh2YWwpOyB9KVxuICAgIC5yZXBsYWNlKC8jXFx7YWN0XFx9L2csIGZ1bmN0aW9uICgpIHsgcmV0dXJuIG9iakRpc3BsYXkoYWN0dWFsKTsgfSlcbiAgICAucmVwbGFjZSgvI1xce2V4cFxcfS9nLCBmdW5jdGlvbiAoKSB7IHJldHVybiBvYmpEaXNwbGF5KGV4cGVjdGVkKTsgfSk7XG5cbiAgcmV0dXJuIGZsYWdNc2cgPyBmbGFnTXNnICsgJzogJyArIG1zZyA6IG1zZztcbn07XG4iLCIvKiFcbiAqIENoYWkgLSBnZXROYW1lIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKipcbiAqICMgZ2V0TmFtZShmdW5jKVxuICpcbiAqIEdldHMgdGhlIG5hbWUgb2YgYSBmdW5jdGlvbiwgaW4gYSBjcm9zcy1icm93c2VyIHdheS5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBhIGZ1bmN0aW9uICh1c3VhbGx5IGEgY29uc3RydWN0b3IpXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBnZXROYW1lXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZnVuYykge1xuICBpZiAoZnVuYy5uYW1lKSByZXR1cm4gZnVuYy5uYW1lO1xuXG4gIHZhciBtYXRjaCA9IC9eXFxzP2Z1bmN0aW9uIChbXihdKilcXCgvLmV4ZWMoZnVuYyk7XG4gIHJldHVybiBtYXRjaCAmJiBtYXRjaFsxXSA/IG1hdGNoWzFdIDogXCJcIjtcbn07XG4iLCIvKiFcbiAqIENoYWkgLSBnZXRQYXRoSW5mbyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxudmFyIGhhc1Byb3BlcnR5ID0gcmVxdWlyZSgnLi9oYXNQcm9wZXJ0eScpO1xuXG4vKipcbiAqICMjIyAuZ2V0UGF0aEluZm8ocGF0aCwgb2JqZWN0KVxuICpcbiAqIFRoaXMgYWxsb3dzIHRoZSByZXRyaWV2YWwgb2YgcHJvcGVydHkgaW5mbyBpbiBhblxuICogb2JqZWN0IGdpdmVuIGEgc3RyaW5nIHBhdGguXG4gKlxuICogVGhlIHBhdGggaW5mbyBjb25zaXN0cyBvZiBhbiBvYmplY3Qgd2l0aCB0aGVcbiAqIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICpcbiAqICogcGFyZW50IC0gVGhlIHBhcmVudCBvYmplY3Qgb2YgdGhlIHByb3BlcnR5IHJlZmVyZW5jZWQgYnkgYHBhdGhgXG4gKiAqIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZmluYWwgcHJvcGVydHksIGEgbnVtYmVyIGlmIGl0IHdhcyBhbiBhcnJheSBpbmRleGVyXG4gKiAqIHZhbHVlIC0gVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSwgaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgYHVuZGVmaW5lZGBcbiAqICogZXhpc3RzIC0gV2hldGhlciB0aGUgcHJvcGVydHkgZXhpc3RzIG9yIG5vdFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gKiBAcmV0dXJucyB7T2JqZWN0fSBpbmZvXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBnZXRQYXRoSW5mb1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldFBhdGhJbmZvKHBhdGgsIG9iaikge1xuICB2YXIgcGFyc2VkID0gcGFyc2VQYXRoKHBhdGgpLFxuICAgICAgbGFzdCA9IHBhcnNlZFtwYXJzZWQubGVuZ3RoIC0gMV07XG5cbiAgdmFyIGluZm8gPSB7XG4gICAgcGFyZW50OiBwYXJzZWQubGVuZ3RoID4gMSA/IF9nZXRQYXRoVmFsdWUocGFyc2VkLCBvYmosIHBhcnNlZC5sZW5ndGggLSAxKSA6IG9iaixcbiAgICBuYW1lOiBsYXN0LnAgfHwgbGFzdC5pLFxuICAgIHZhbHVlOiBfZ2V0UGF0aFZhbHVlKHBhcnNlZCwgb2JqKVxuICB9O1xuICBpbmZvLmV4aXN0cyA9IGhhc1Byb3BlcnR5KGluZm8ubmFtZSwgaW5mby5wYXJlbnQpO1xuXG4gIHJldHVybiBpbmZvO1xufTtcblxuXG4vKiFcbiAqICMjIHBhcnNlUGF0aChwYXRoKVxuICpcbiAqIEhlbHBlciBmdW5jdGlvbiB1c2VkIHRvIHBhcnNlIHN0cmluZyBvYmplY3RcbiAqIHBhdGhzLiBVc2UgaW4gY29uanVuY3Rpb24gd2l0aCBgX2dldFBhdGhWYWx1ZWAuXG4gKlxuICogICAgICB2YXIgcGFyc2VkID0gcGFyc2VQYXRoKCdteW9iamVjdC5wcm9wZXJ0eS5zdWJwcm9wJyk7XG4gKlxuICogIyMjIFBhdGhzOlxuICpcbiAqICogQ2FuIGJlIGFzIG5lYXIgaW5maW5pdGVseSBkZWVwIGFuZCBuZXN0ZWRcbiAqICogQXJyYXlzIGFyZSBhbHNvIHZhbGlkIHVzaW5nIHRoZSBmb3JtYWwgYG15b2JqZWN0LmRvY3VtZW50WzNdLnByb3BlcnR5YC5cbiAqICogTGl0ZXJhbCBkb3RzIGFuZCBicmFja2V0cyAobm90IGRlbGltaXRlcikgbXVzdCBiZSBiYWNrc2xhc2gtZXNjYXBlZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcGF0aFxuICogQHJldHVybnMge09iamVjdH0gcGFyc2VkXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBwYXJzZVBhdGggKHBhdGgpIHtcbiAgdmFyIHN0ciA9IHBhdGgucmVwbGFjZSgvKFteXFxcXF0pXFxbL2csICckMS5bJylcbiAgICAsIHBhcnRzID0gc3RyLm1hdGNoKC8oXFxcXFxcLnxbXi5dKz8pKy9nKTtcbiAgcmV0dXJuIHBhcnRzLm1hcChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICB2YXIgcmUgPSAvXlxcWyhcXGQrKVxcXSQvXG4gICAgICAsIG1BcnIgPSByZS5leGVjKHZhbHVlKTtcbiAgICBpZiAobUFycikgcmV0dXJuIHsgaTogcGFyc2VGbG9hdChtQXJyWzFdKSB9O1xuICAgIGVsc2UgcmV0dXJuIHsgcDogdmFsdWUucmVwbGFjZSgvXFxcXChbLlxcW1xcXV0pL2csICckMScpIH07XG4gIH0pO1xufVxuXG5cbi8qIVxuICogIyMgX2dldFBhdGhWYWx1ZShwYXJzZWQsIG9iailcbiAqXG4gKiBIZWxwZXIgY29tcGFuaW9uIGZ1bmN0aW9uIGZvciBgLnBhcnNlUGF0aGAgdGhhdCByZXR1cm5zXG4gKiB0aGUgdmFsdWUgbG9jYXRlZCBhdCB0aGUgcGFyc2VkIGFkZHJlc3MuXG4gKlxuICogICAgICB2YXIgdmFsdWUgPSBnZXRQYXRoVmFsdWUocGFyc2VkLCBvYmopO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYXJzZWQgZGVmaW5pdGlvbiBmcm9tIGBwYXJzZVBhdGhgLlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCB0byBzZWFyY2ggYWdhaW5zdFxuICogQHBhcmFtIHtOdW1iZXJ9IG9iamVjdCB0byBzZWFyY2ggYWdhaW5zdFxuICogQHJldHVybnMge09iamVjdHxVbmRlZmluZWR9IHZhbHVlXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBfZ2V0UGF0aFZhbHVlIChwYXJzZWQsIG9iaiwgaW5kZXgpIHtcbiAgdmFyIHRtcCA9IG9ialxuICAgICwgcmVzO1xuXG4gIGluZGV4ID0gKGluZGV4ID09PSB1bmRlZmluZWQgPyBwYXJzZWQubGVuZ3RoIDogaW5kZXgpO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsID0gaW5kZXg7IGkgPCBsOyBpKyspIHtcbiAgICB2YXIgcGFydCA9IHBhcnNlZFtpXTtcbiAgICBpZiAodG1wKSB7XG4gICAgICBpZiAoJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiBwYXJ0LnApXG4gICAgICAgIHRtcCA9IHRtcFtwYXJ0LnBdO1xuICAgICAgZWxzZSBpZiAoJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiBwYXJ0LmkpXG4gICAgICAgIHRtcCA9IHRtcFtwYXJ0LmldO1xuICAgICAgaWYgKGkgPT0gKGwgLSAxKSkgcmVzID0gdG1wO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXMgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXM7XG59XG4iLCIvKiFcbiAqIENoYWkgLSBnZXRQYXRoVmFsdWUgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2xvZ2ljYWxwYXJhZG94L2ZpbHRyXG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG52YXIgZ2V0UGF0aEluZm8gPSByZXF1aXJlKCcuL2dldFBhdGhJbmZvJyk7XG5cbi8qKlxuICogIyMjIC5nZXRQYXRoVmFsdWUocGF0aCwgb2JqZWN0KVxuICpcbiAqIFRoaXMgYWxsb3dzIHRoZSByZXRyaWV2YWwgb2YgdmFsdWVzIGluIGFuXG4gKiBvYmplY3QgZ2l2ZW4gYSBzdHJpbmcgcGF0aC5cbiAqXG4gKiAgICAgdmFyIG9iaiA9IHtcbiAqICAgICAgICAgcHJvcDE6IHtcbiAqICAgICAgICAgICAgIGFycjogWydhJywgJ2InLCAnYyddXG4gKiAgICAgICAgICAgLCBzdHI6ICdIZWxsbydcbiAqICAgICAgICAgfVxuICogICAgICAgLCBwcm9wMjoge1xuICogICAgICAgICAgICAgYXJyOiBbIHsgbmVzdGVkOiAnVW5pdmVyc2UnIH0gXVxuICogICAgICAgICAgICwgc3RyOiAnSGVsbG8gYWdhaW4hJ1xuICogICAgICAgICB9XG4gKiAgICAgfVxuICpcbiAqIFRoZSBmb2xsb3dpbmcgd291bGQgYmUgdGhlIHJlc3VsdHMuXG4gKlxuICogICAgIGdldFBhdGhWYWx1ZSgncHJvcDEuc3RyJywgb2JqKTsgLy8gSGVsbG9cbiAqICAgICBnZXRQYXRoVmFsdWUoJ3Byb3AxLmF0dFsyXScsIG9iaik7IC8vIGJcbiAqICAgICBnZXRQYXRoVmFsdWUoJ3Byb3AyLmFyclswXS5uZXN0ZWQnLCBvYmopOyAvLyBVbml2ZXJzZVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gKiBAcmV0dXJucyB7T2JqZWN0fSB2YWx1ZSBvciBgdW5kZWZpbmVkYFxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZ2V0UGF0aFZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHBhdGgsIG9iaikge1xuICB2YXIgaW5mbyA9IGdldFBhdGhJbmZvKHBhdGgsIG9iaik7XG4gIHJldHVybiBpbmZvLnZhbHVlO1xufTtcbiIsIi8qIVxuICogQ2hhaSAtIGdldFByb3BlcnRpZXMgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIC5nZXRQcm9wZXJ0aWVzKG9iamVjdClcbiAqXG4gKiBUaGlzIGFsbG93cyB0aGUgcmV0cmlldmFsIG9mIHByb3BlcnR5IG5hbWVzIG9mIGFuIG9iamVjdCwgZW51bWVyYWJsZSBvciBub3QsXG4gKiBpbmhlcml0ZWQgb3Igbm90LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGdldFByb3BlcnRpZXNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRQcm9wZXJ0aWVzKG9iamVjdCkge1xuICB2YXIgcmVzdWx0ID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMob2JqZWN0KTtcblxuICBmdW5jdGlvbiBhZGRQcm9wZXJ0eShwcm9wZXJ0eSkge1xuICAgIGlmIChyZXN1bHQuaW5kZXhPZihwcm9wZXJ0eSkgPT09IC0xKSB7XG4gICAgICByZXN1bHQucHVzaChwcm9wZXJ0eSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdCk7XG4gIHdoaWxlIChwcm90byAhPT0gbnVsbCkge1xuICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHByb3RvKS5mb3JFYWNoKGFkZFByb3BlcnR5KTtcbiAgICBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufTtcbiIsIi8qIVxuICogQ2hhaSAtIGhhc1Byb3BlcnR5IHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG52YXIgdHlwZSA9IHJlcXVpcmUoJ3R5cGUtZGV0ZWN0Jyk7XG5cbi8qKlxuICogIyMjIC5oYXNQcm9wZXJ0eShvYmplY3QsIG5hbWUpXG4gKlxuICogVGhpcyBhbGxvd3MgY2hlY2tpbmcgd2hldGhlciBhbiBvYmplY3QgaGFzXG4gKiBuYW1lZCBwcm9wZXJ0eSBvciBudW1lcmljIGFycmF5IGluZGV4LlxuICpcbiAqIEJhc2ljYWxseSBkb2VzIHRoZSBzYW1lIHRoaW5nIGFzIHRoZSBgaW5gXG4gKiBvcGVyYXRvciBidXQgd29ya3MgcHJvcGVybHkgd2l0aCBuYXRpdmVzXG4gKiBhbmQgbnVsbC91bmRlZmluZWQgdmFsdWVzLlxuICpcbiAqICAgICB2YXIgb2JqID0ge1xuICogICAgICAgICBhcnI6IFsnYScsICdiJywgJ2MnXVxuICogICAgICAgLCBzdHI6ICdIZWxsbydcbiAqICAgICB9XG4gKlxuICogVGhlIGZvbGxvd2luZyB3b3VsZCBiZSB0aGUgcmVzdWx0cy5cbiAqXG4gKiAgICAgaGFzUHJvcGVydHkoJ3N0cicsIG9iaik7ICAvLyB0cnVlXG4gKiAgICAgaGFzUHJvcGVydHkoJ2NvbnN0cnVjdG9yJywgb2JqKTsgIC8vIHRydWVcbiAqICAgICBoYXNQcm9wZXJ0eSgnYmFyJywgb2JqKTsgIC8vIGZhbHNlXG4gKlxuICogICAgIGhhc1Byb3BlcnR5KCdsZW5ndGgnLCBvYmouc3RyKTsgLy8gdHJ1ZVxuICogICAgIGhhc1Byb3BlcnR5KDEsIG9iai5zdHIpOyAgLy8gdHJ1ZVxuICogICAgIGhhc1Byb3BlcnR5KDUsIG9iai5zdHIpOyAgLy8gZmFsc2VcbiAqXG4gKiAgICAgaGFzUHJvcGVydHkoJ2xlbmd0aCcsIG9iai5hcnIpOyAgLy8gdHJ1ZVxuICogICAgIGhhc1Byb3BlcnR5KDIsIG9iai5hcnIpOyAgLy8gdHJ1ZVxuICogICAgIGhhc1Byb3BlcnR5KDMsIG9iai5hcnIpOyAgLy8gZmFsc2VcbiAqXG4gKiBAcGFyYW0ge09ianVlY3R9IG9iamVjdFxuICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSBuYW1lXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gd2hldGhlciBpdCBleGlzdHNcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGdldFBhdGhJbmZvXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnZhciBsaXRlcmFscyA9IHtcbiAgICAnbnVtYmVyJzogTnVtYmVyXG4gICwgJ3N0cmluZyc6IFN0cmluZ1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNQcm9wZXJ0eShuYW1lLCBvYmopIHtcbiAgdmFyIG90ID0gdHlwZShvYmopO1xuXG4gIC8vIEJhZCBPYmplY3QsIG9idmlvdXNseSBubyBwcm9wcyBhdCBhbGxcbiAgaWYob3QgPT09ICdudWxsJyB8fCBvdCA9PT0gJ3VuZGVmaW5lZCcpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIFRoZSBgaW5gIG9wZXJhdG9yIGRvZXMgbm90IHdvcmsgd2l0aCBjZXJ0YWluIGxpdGVyYWxzXG4gIC8vIGJveCB0aGVzZSBiZWZvcmUgdGhlIGNoZWNrXG4gIGlmKGxpdGVyYWxzW290XSAmJiB0eXBlb2Ygb2JqICE9PSAnb2JqZWN0JylcbiAgICBvYmogPSBuZXcgbGl0ZXJhbHNbb3RdKG9iaik7XG5cbiAgcmV0dXJuIG5hbWUgaW4gb2JqO1xufTtcbiIsIi8qIVxuICogY2hhaVxuICogQ29weXJpZ2h0KGMpIDIwMTEgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKiFcbiAqIE1haW4gZXhwb3J0c1xuICovXG5cbnZhciBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLyohXG4gKiB0ZXN0IHV0aWxpdHlcbiAqL1xuXG5leHBvcnRzLnRlc3QgPSByZXF1aXJlKCcuL3Rlc3QnKTtcblxuLyohXG4gKiB0eXBlIHV0aWxpdHlcbiAqL1xuXG5leHBvcnRzLnR5cGUgPSByZXF1aXJlKCd0eXBlLWRldGVjdCcpO1xuXG4vKiFcbiAqIGV4cGVjdFR5cGVzIHV0aWxpdHlcbiAqL1xuZXhwb3J0cy5leHBlY3RUeXBlcyA9IHJlcXVpcmUoJy4vZXhwZWN0VHlwZXMnKTtcblxuLyohXG4gKiBtZXNzYWdlIHV0aWxpdHlcbiAqL1xuXG5leHBvcnRzLmdldE1lc3NhZ2UgPSByZXF1aXJlKCcuL2dldE1lc3NhZ2UnKTtcblxuLyohXG4gKiBhY3R1YWwgdXRpbGl0eVxuICovXG5cbmV4cG9ydHMuZ2V0QWN0dWFsID0gcmVxdWlyZSgnLi9nZXRBY3R1YWwnKTtcblxuLyohXG4gKiBJbnNwZWN0IHV0aWxcbiAqL1xuXG5leHBvcnRzLmluc3BlY3QgPSByZXF1aXJlKCcuL2luc3BlY3QnKTtcblxuLyohXG4gKiBPYmplY3QgRGlzcGxheSB1dGlsXG4gKi9cblxuZXhwb3J0cy5vYmpEaXNwbGF5ID0gcmVxdWlyZSgnLi9vYmpEaXNwbGF5Jyk7XG5cbi8qIVxuICogRmxhZyB1dGlsaXR5XG4gKi9cblxuZXhwb3J0cy5mbGFnID0gcmVxdWlyZSgnLi9mbGFnJyk7XG5cbi8qIVxuICogRmxhZyB0cmFuc2ZlcnJpbmcgdXRpbGl0eVxuICovXG5cbmV4cG9ydHMudHJhbnNmZXJGbGFncyA9IHJlcXVpcmUoJy4vdHJhbnNmZXJGbGFncycpO1xuXG4vKiFcbiAqIERlZXAgZXF1YWwgdXRpbGl0eVxuICovXG5cbmV4cG9ydHMuZXFsID0gcmVxdWlyZSgnZGVlcC1lcWwnKTtcblxuLyohXG4gKiBEZWVwIHBhdGggdmFsdWVcbiAqL1xuXG5leHBvcnRzLmdldFBhdGhWYWx1ZSA9IHJlcXVpcmUoJy4vZ2V0UGF0aFZhbHVlJyk7XG5cbi8qIVxuICogRGVlcCBwYXRoIGluZm9cbiAqL1xuXG5leHBvcnRzLmdldFBhdGhJbmZvID0gcmVxdWlyZSgnLi9nZXRQYXRoSW5mbycpO1xuXG4vKiFcbiAqIENoZWNrIGlmIGEgcHJvcGVydHkgZXhpc3RzXG4gKi9cblxuZXhwb3J0cy5oYXNQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vaGFzUHJvcGVydHknKTtcblxuLyohXG4gKiBGdW5jdGlvbiBuYW1lXG4gKi9cblxuZXhwb3J0cy5nZXROYW1lID0gcmVxdWlyZSgnLi9nZXROYW1lJyk7XG5cbi8qIVxuICogYWRkIFByb3BlcnR5XG4gKi9cblxuZXhwb3J0cy5hZGRQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vYWRkUHJvcGVydHknKTtcblxuLyohXG4gKiBhZGQgTWV0aG9kXG4gKi9cblxuZXhwb3J0cy5hZGRNZXRob2QgPSByZXF1aXJlKCcuL2FkZE1ldGhvZCcpO1xuXG4vKiFcbiAqIG92ZXJ3cml0ZSBQcm9wZXJ0eVxuICovXG5cbmV4cG9ydHMub3ZlcndyaXRlUHJvcGVydHkgPSByZXF1aXJlKCcuL292ZXJ3cml0ZVByb3BlcnR5Jyk7XG5cbi8qIVxuICogb3ZlcndyaXRlIE1ldGhvZFxuICovXG5cbmV4cG9ydHMub3ZlcndyaXRlTWV0aG9kID0gcmVxdWlyZSgnLi9vdmVyd3JpdGVNZXRob2QnKTtcblxuLyohXG4gKiBBZGQgYSBjaGFpbmFibGUgbWV0aG9kXG4gKi9cblxuZXhwb3J0cy5hZGRDaGFpbmFibGVNZXRob2QgPSByZXF1aXJlKCcuL2FkZENoYWluYWJsZU1ldGhvZCcpO1xuXG4vKiFcbiAqIE92ZXJ3cml0ZSBjaGFpbmFibGUgbWV0aG9kXG4gKi9cblxuZXhwb3J0cy5vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QgPSByZXF1aXJlKCcuL292ZXJ3cml0ZUNoYWluYWJsZU1ldGhvZCcpO1xuIiwiLy8gVGhpcyBpcyAoYWxtb3N0KSBkaXJlY3RseSBmcm9tIE5vZGUuanMgdXRpbHNcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9qb3llbnQvbm9kZS9ibG9iL2Y4YzMzNWQwY2FmNDdmMTZkMzE0MTNmODlhYTI4ZWRhMzg3OGUzYWEvbGliL3V0aWwuanNcblxudmFyIGdldE5hbWUgPSByZXF1aXJlKCcuL2dldE5hbWUnKTtcbnZhciBnZXRQcm9wZXJ0aWVzID0gcmVxdWlyZSgnLi9nZXRQcm9wZXJ0aWVzJyk7XG52YXIgZ2V0RW51bWVyYWJsZVByb3BlcnRpZXMgPSByZXF1aXJlKCcuL2dldEVudW1lcmFibGVQcm9wZXJ0aWVzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gaW5zcGVjdDtcblxuLyoqXG4gKiBFY2hvcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJ5cyB0byBwcmludCB0aGUgdmFsdWUgb3V0XG4gKiBpbiB0aGUgYmVzdCB3YXkgcG9zc2libGUgZ2l2ZW4gdGhlIGRpZmZlcmVudCB0eXBlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gcHJpbnQgb3V0LlxuICogQHBhcmFtIHtCb29sZWFufSBzaG93SGlkZGVuIEZsYWcgdGhhdCBzaG93cyBoaWRkZW4gKG5vdCBlbnVtZXJhYmxlKVxuICogICAgcHJvcGVydGllcyBvZiBvYmplY3RzLlxuICogQHBhcmFtIHtOdW1iZXJ9IGRlcHRoIERlcHRoIGluIHdoaWNoIHRvIGRlc2NlbmQgaW4gb2JqZWN0LiBEZWZhdWx0IGlzIDIuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGNvbG9ycyBGbGFnIHRvIHR1cm4gb24gQU5TSSBlc2NhcGUgY29kZXMgdG8gY29sb3IgdGhlXG4gKiAgICBvdXRwdXQuIERlZmF1bHQgaXMgZmFsc2UgKG5vIGNvbG9yaW5nKS5cbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGluc3BlY3RcbiAqL1xuZnVuY3Rpb24gaW5zcGVjdChvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMpIHtcbiAgdmFyIGN0eCA9IHtcbiAgICBzaG93SGlkZGVuOiBzaG93SGlkZGVuLFxuICAgIHNlZW46IFtdLFxuICAgIHN0eWxpemU6IGZ1bmN0aW9uIChzdHIpIHsgcmV0dXJuIHN0cjsgfVxuICB9O1xuICByZXR1cm4gZm9ybWF0VmFsdWUoY3R4LCBvYmosICh0eXBlb2YgZGVwdGggPT09ICd1bmRlZmluZWQnID8gMiA6IGRlcHRoKSk7XG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiBvYmplY3QgaXMgYSBET00gZWxlbWVudC5cbnZhciBpc0RPTUVsZW1lbnQgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgPT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBvYmplY3QgJiZcbiAgICAgIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnICYmXG4gICAgICBvYmplY3Qubm9kZVR5cGUgPT09IDEgJiZcbiAgICAgIHR5cGVvZiBvYmplY3Qubm9kZU5hbWUgPT09ICdzdHJpbmcnO1xuICB9XG59O1xuXG5mdW5jdGlvbiBmb3JtYXRWYWx1ZShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMpIHtcbiAgLy8gUHJvdmlkZSBhIGhvb2sgZm9yIHVzZXItc3BlY2lmaWVkIGluc3BlY3QgZnVuY3Rpb25zLlxuICAvLyBDaGVjayB0aGF0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFuIGluc3BlY3QgZnVuY3Rpb24gb24gaXRcbiAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZS5pbnNwZWN0ID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAvLyBGaWx0ZXIgb3V0IHRoZSB1dGlsIG1vZHVsZSwgaXQncyBpbnNwZWN0IGZ1bmN0aW9uIGlzIHNwZWNpYWxcbiAgICAgIHZhbHVlLmluc3BlY3QgIT09IGV4cG9ydHMuaW5zcGVjdCAmJlxuICAgICAgLy8gQWxzbyBmaWx0ZXIgb3V0IGFueSBwcm90b3R5cGUgb2JqZWN0cyB1c2luZyB0aGUgY2lyY3VsYXIgY2hlY2suXG4gICAgICAhKHZhbHVlLmNvbnN0cnVjdG9yICYmIHZhbHVlLmNvbnN0cnVjdG9yLnByb3RvdHlwZSA9PT0gdmFsdWUpKSB7XG4gICAgdmFyIHJldCA9IHZhbHVlLmluc3BlY3QocmVjdXJzZVRpbWVzKTtcbiAgICBpZiAodHlwZW9mIHJldCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldCA9IGZvcm1hdFZhbHVlKGN0eCwgcmV0LCByZWN1cnNlVGltZXMpO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLy8gUHJpbWl0aXZlIHR5cGVzIGNhbm5vdCBoYXZlIHByb3BlcnRpZXNcbiAgdmFyIHByaW1pdGl2ZSA9IGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKTtcbiAgaWYgKHByaW1pdGl2ZSkge1xuICAgIHJldHVybiBwcmltaXRpdmU7XG4gIH1cblxuICAvLyBJZiB0aGlzIGlzIGEgRE9NIGVsZW1lbnQsIHRyeSB0byBnZXQgdGhlIG91dGVyIEhUTUwuXG4gIGlmIChpc0RPTUVsZW1lbnQodmFsdWUpKSB7XG4gICAgaWYgKCdvdXRlckhUTUwnIGluIHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUub3V0ZXJIVE1MO1xuICAgICAgLy8gVGhpcyB2YWx1ZSBkb2VzIG5vdCBoYXZlIGFuIG91dGVySFRNTCBhdHRyaWJ1dGUsXG4gICAgICAvLyAgIGl0IGNvdWxkIHN0aWxsIGJlIGFuIFhNTCBlbGVtZW50XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEF0dGVtcHQgdG8gc2VyaWFsaXplIGl0XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoZG9jdW1lbnQueG1sVmVyc2lvbikge1xuICAgICAgICAgIHZhciB4bWxTZXJpYWxpemVyID0gbmV3IFhNTFNlcmlhbGl6ZXIoKTtcbiAgICAgICAgICByZXR1cm4geG1sU2VyaWFsaXplci5zZXJpYWxpemVUb1N0cmluZyh2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gRmlyZWZveCAxMS0gZG8gbm90IHN1cHBvcnQgb3V0ZXJIVE1MXG4gICAgICAgICAgLy8gICBJdCBkb2VzLCBob3dldmVyLCBzdXBwb3J0IGlubmVySFRNTFxuICAgICAgICAgIC8vICAgVXNlIHRoZSBmb2xsb3dpbmcgdG8gcmVuZGVyIHRoZSBlbGVtZW50XG4gICAgICAgICAgdmFyIG5zID0gXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI7XG4gICAgICAgICAgdmFyIGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhucywgJ18nKTtcblxuICAgICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCh2YWx1ZS5jbG9uZU5vZGUoZmFsc2UpKTtcbiAgICAgICAgICBodG1sID0gY29udGFpbmVyLmlubmVySFRNTFxuICAgICAgICAgICAgLnJlcGxhY2UoJz48JywgJz4nICsgdmFsdWUuaW5uZXJIVE1MICsgJzwnKTtcbiAgICAgICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gJyc7XG4gICAgICAgICAgcmV0dXJuIGh0bWw7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAvLyBUaGlzIGNvdWxkIGJlIGEgbm9uLW5hdGl2ZSBET00gaW1wbGVtZW50YXRpb24sXG4gICAgICAgIC8vICAgY29udGludWUgd2l0aCB0aGUgbm9ybWFsIGZsb3c6XG4gICAgICAgIC8vICAgcHJpbnRpbmcgdGhlIGVsZW1lbnQgYXMgaWYgaXQgaXMgYW4gb2JqZWN0LlxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIExvb2sgdXAgdGhlIGtleXMgb2YgdGhlIG9iamVjdC5cbiAgdmFyIHZpc2libGVLZXlzID0gZ2V0RW51bWVyYWJsZVByb3BlcnRpZXModmFsdWUpO1xuICB2YXIga2V5cyA9IGN0eC5zaG93SGlkZGVuID8gZ2V0UHJvcGVydGllcyh2YWx1ZSkgOiB2aXNpYmxlS2V5cztcblxuICAvLyBTb21lIHR5cGUgb2Ygb2JqZWN0IHdpdGhvdXQgcHJvcGVydGllcyBjYW4gYmUgc2hvcnRjdXR0ZWQuXG4gIC8vIEluIElFLCBlcnJvcnMgaGF2ZSBhIHNpbmdsZSBgc3RhY2tgIHByb3BlcnR5LCBvciBpZiB0aGV5IGFyZSB2YW5pbGxhIGBFcnJvcmAsXG4gIC8vIGEgYHN0YWNrYCBwbHVzIGBkZXNjcmlwdGlvbmAgcHJvcGVydHk7IGlnbm9yZSB0aG9zZSBmb3IgY29uc2lzdGVuY3kuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCB8fCAoaXNFcnJvcih2YWx1ZSkgJiYgKFxuICAgICAgKGtleXMubGVuZ3RoID09PSAxICYmIGtleXNbMF0gPT09ICdzdGFjaycpIHx8XG4gICAgICAoa2V5cy5sZW5ndGggPT09IDIgJiYga2V5c1swXSA9PT0gJ2Rlc2NyaXB0aW9uJyAmJiBrZXlzWzFdID09PSAnc3RhY2snKVxuICAgICApKSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciBuYW1lID0gZ2V0TmFtZSh2YWx1ZSk7XG4gICAgICB2YXIgbmFtZVN1ZmZpeCA9IG5hbWUgPyAnOiAnICsgbmFtZSA6ICcnO1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbRnVuY3Rpb24nICsgbmFtZVN1ZmZpeCArICddJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9XG4gICAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShEYXRlLnByb3RvdHlwZS50b1VUQ1N0cmluZy5jYWxsKHZhbHVlKSwgJ2RhdGUnKTtcbiAgICB9XG4gICAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBiYXNlID0gJycsIGFycmF5ID0gZmFsc2UsIGJyYWNlcyA9IFsneycsICd9J107XG5cbiAgLy8gTWFrZSBBcnJheSBzYXkgdGhhdCB0aGV5IGFyZSBBcnJheVxuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBhcnJheSA9IHRydWU7XG4gICAgYnJhY2VzID0gWydbJywgJ10nXTtcbiAgfVxuXG4gIC8vIE1ha2UgZnVuY3Rpb25zIHNheSB0aGF0IHRoZXkgYXJlIGZ1bmN0aW9uc1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdmFyIG5hbWUgPSBnZXROYW1lKHZhbHVlKTtcbiAgICB2YXIgbmFtZVN1ZmZpeCA9IG5hbWUgPyAnOiAnICsgbmFtZSA6ICcnO1xuICAgIGJhc2UgPSAnIFtGdW5jdGlvbicgKyBuYW1lU3VmZml4ICsgJ10nO1xuICB9XG5cbiAgLy8gTWFrZSBSZWdFeHBzIHNheSB0aGF0IHRoZXkgYXJlIFJlZ0V4cHNcbiAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBkYXRlcyB3aXRoIHByb3BlcnRpZXMgZmlyc3Qgc2F5IHRoZSBkYXRlXG4gIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIERhdGUucHJvdG90eXBlLnRvVVRDU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBlcnJvciB3aXRoIG1lc3NhZ2UgZmlyc3Qgc2F5IHRoZSBlcnJvclxuICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwICYmICghYXJyYXkgfHwgdmFsdWUubGVuZ3RoID09IDApKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyBicmFjZXNbMV07XG4gIH1cblxuICBpZiAocmVjdXJzZVRpbWVzIDwgMCkge1xuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW09iamVjdF0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuXG4gIGN0eC5zZWVuLnB1c2godmFsdWUpO1xuXG4gIHZhciBvdXRwdXQ7XG4gIGlmIChhcnJheSkge1xuICAgIG91dHB1dCA9IGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpO1xuICB9IGVsc2Uge1xuICAgIG91dHB1dCA9IGtleXMubWFwKGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpO1xuICAgIH0pO1xuICB9XG5cbiAgY3R4LnNlZW4ucG9wKCk7XG5cbiAgcmV0dXJuIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKTtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSkge1xuICBzd2l0Y2ggKHR5cGVvZiB2YWx1ZSkge1xuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcblxuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICB2YXIgc2ltcGxlID0gJ1xcJycgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkucmVwbGFjZSgvXlwifFwiJC9nLCAnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpICsgJ1xcJyc7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoc2ltcGxlLCAnc3RyaW5nJyk7XG5cbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgaWYgKHZhbHVlID09PSAwICYmICgxL3ZhbHVlKSA9PT0gLUluZmluaXR5KSB7XG4gICAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnLTAnLCAnbnVtYmVyJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ251bWJlcicpO1xuXG4gICAgY2FzZSAnYm9vbGVhbic6XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ2Jvb2xlYW4nKTtcbiAgfVxuICAvLyBGb3Igc29tZSByZWFzb24gdHlwZW9mIG51bGwgaXMgXCJvYmplY3RcIiwgc28gc3BlY2lhbCBjYXNlIGhlcmUuXG4gIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnbnVsbCcsICdudWxsJyk7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRFcnJvcih2YWx1ZSkge1xuICByZXR1cm4gJ1snICsgRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpICsgJ10nO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpIHtcbiAgdmFyIG91dHB1dCA9IFtdO1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7ICsraSkge1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIFN0cmluZyhpKSkpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAgU3RyaW5nKGkpLCB0cnVlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICB9XG4gIH1cbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICgha2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBrZXksIHRydWUpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb3V0cHV0O1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpIHtcbiAgdmFyIG5hbWUsIHN0cjtcbiAgaWYgKHZhbHVlLl9fbG9va3VwR2V0dGVyX18pIHtcbiAgICBpZiAodmFsdWUuX19sb29rdXBHZXR0ZXJfXyhrZXkpKSB7XG4gICAgICBpZiAodmFsdWUuX19sb29rdXBTZXR0ZXJfXyhrZXkpKSB7XG4gICAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyL1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHZhbHVlLl9fbG9va3VwU2V0dGVyX18oa2V5KSkge1xuICAgICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAodmlzaWJsZUtleXMuaW5kZXhPZihrZXkpIDwgMCkge1xuICAgIG5hbWUgPSAnWycgKyBrZXkgKyAnXSc7XG4gIH1cbiAgaWYgKCFzdHIpIHtcbiAgICBpZiAoY3R4LnNlZW4uaW5kZXhPZih2YWx1ZVtrZXldKSA8IDApIHtcbiAgICAgIGlmIChyZWN1cnNlVGltZXMgPT09IG51bGwpIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCB2YWx1ZVtrZXldLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgdmFsdWVba2V5XSwgcmVjdXJzZVRpbWVzIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgaWYgKGFycmF5KSB7XG4gICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpLnN1YnN0cigyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdHIgPSAnXFxuJyArIHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAodHlwZW9mIG5hbWUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKGFycmF5ICYmIGtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICAgIG5hbWUgPSBKU09OLnN0cmluZ2lmeSgnJyArIGtleSk7XG4gICAgaWYgKG5hbWUubWF0Y2goL15cIihbYS16QS1aX11bYS16QS1aXzAtOV0qKVwiJC8pKSB7XG4gICAgICBuYW1lID0gbmFtZS5zdWJzdHIoMSwgbmFtZS5sZW5ndGggLSAyKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnbmFtZScpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvKF5cInxcIiQpL2csIFwiJ1wiKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnc3RyaW5nJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5hbWUgKyAnOiAnICsgc3RyO1xufVxuXG5cbmZ1bmN0aW9uIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKSB7XG4gIHZhciBudW1MaW5lc0VzdCA9IDA7XG4gIHZhciBsZW5ndGggPSBvdXRwdXQucmVkdWNlKGZ1bmN0aW9uKHByZXYsIGN1cikge1xuICAgIG51bUxpbmVzRXN0Kys7XG4gICAgaWYgKGN1ci5pbmRleE9mKCdcXG4nKSA+PSAwKSBudW1MaW5lc0VzdCsrO1xuICAgIHJldHVybiBwcmV2ICsgY3VyLmxlbmd0aCArIDE7XG4gIH0sIDApO1xuXG4gIGlmIChsZW5ndGggPiA2MCkge1xuICAgIHJldHVybiBicmFjZXNbMF0gK1xuICAgICAgICAgICAoYmFzZSA9PT0gJycgPyAnJyA6IGJhc2UgKyAnXFxuICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgb3V0cHV0LmpvaW4oJyxcXG4gICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgYnJhY2VzWzFdO1xuICB9XG5cbiAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyAnICcgKyBvdXRwdXQuam9pbignLCAnKSArICcgJyArIGJyYWNlc1sxXTtcbn1cblxuZnVuY3Rpb24gaXNBcnJheShhcikge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheShhcikgfHxcbiAgICAgICAgICh0eXBlb2YgYXIgPT09ICdvYmplY3QnICYmIG9iamVjdFRvU3RyaW5nKGFyKSA9PT0gJ1tvYmplY3QgQXJyYXldJyk7XG59XG5cbmZ1bmN0aW9uIGlzUmVnRXhwKHJlKSB7XG4gIHJldHVybiB0eXBlb2YgcmUgPT09ICdvYmplY3QnICYmIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiB0eXBlb2YgZCA9PT0gJ29iamVjdCcgJiYgb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cblxuZnVuY3Rpb24gaXNFcnJvcihlKSB7XG4gIHJldHVybiB0eXBlb2YgZSA9PT0gJ29iamVjdCcgJiYgb2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXSc7XG59XG5cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cbiIsIi8qIVxuICogQ2hhaSAtIGZsYWcgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qIVxuICogTW9kdWxlIGRlcGVuZGFuY2llc1xuICovXG5cbnZhciBpbnNwZWN0ID0gcmVxdWlyZSgnLi9pbnNwZWN0Jyk7XG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJyk7XG5cbi8qKlxuICogIyMjIC5vYmpEaXNwbGF5IChvYmplY3QpXG4gKlxuICogRGV0ZXJtaW5lcyBpZiBhbiBvYmplY3Qgb3IgYW4gYXJyYXkgbWF0Y2hlc1xuICogY3JpdGVyaWEgdG8gYmUgaW5zcGVjdGVkIGluLWxpbmUgZm9yIGVycm9yXG4gKiBtZXNzYWdlcyBvciBzaG91bGQgYmUgdHJ1bmNhdGVkLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IGphdmFzY3JpcHQgb2JqZWN0IHRvIGluc3BlY3RcbiAqIEBuYW1lIG9iakRpc3BsYXlcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBzdHIgPSBpbnNwZWN0KG9iailcbiAgICAsIHR5cGUgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKTtcblxuICBpZiAoY29uZmlnLnRydW5jYXRlVGhyZXNob2xkICYmIHN0ci5sZW5ndGggPj0gY29uZmlnLnRydW5jYXRlVGhyZXNob2xkKSB7XG4gICAgaWYgKHR5cGUgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXScpIHtcbiAgICAgIHJldHVybiAhb2JqLm5hbWUgfHwgb2JqLm5hbWUgPT09ICcnXG4gICAgICAgID8gJ1tGdW5jdGlvbl0nXG4gICAgICAgIDogJ1tGdW5jdGlvbjogJyArIG9iai5uYW1lICsgJ10nO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ1tvYmplY3QgQXJyYXldJykge1xuICAgICAgcmV0dXJuICdbIEFycmF5KCcgKyBvYmoubGVuZ3RoICsgJykgXSc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnW29iamVjdCBPYmplY3RdJykge1xuICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopXG4gICAgICAgICwga3N0ciA9IGtleXMubGVuZ3RoID4gMlxuICAgICAgICAgID8ga2V5cy5zcGxpY2UoMCwgMikuam9pbignLCAnKSArICcsIC4uLidcbiAgICAgICAgICA6IGtleXMuam9pbignLCAnKTtcbiAgICAgIHJldHVybiAneyBPYmplY3QgKCcgKyBrc3RyICsgJykgfSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbn07XG4iLCIvKiFcbiAqIENoYWkgLSBvdmVyd3JpdGVDaGFpbmFibGVNZXRob2QgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIG92ZXJ3cml0ZUNoYWluYWJsZU1ldGhvZCAoY3R4LCBuYW1lLCBtZXRob2QsIGNoYWluaW5nQmVoYXZpb3IpXG4gKlxuICogT3ZlcndpdGVzIGFuIGFscmVhZHkgZXhpc3RpbmcgY2hhaW5hYmxlIG1ldGhvZFxuICogYW5kIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgcHJldmlvdXMgZnVuY3Rpb24gb3JcbiAqIHByb3BlcnR5LiAgTXVzdCByZXR1cm4gZnVuY3Rpb25zIHRvIGJlIHVzZWQgZm9yXG4gKiBuYW1lLlxuICpcbiAqICAgICB1dGlscy5vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCAnbGVuZ3RoJyxcbiAqICAgICAgIGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAqICAgICAgIH1cbiAqICAgICAsIGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAqICAgICAgIH1cbiAqICAgICApO1xuICpcbiAqIENhbiBhbHNvIGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGZyb20gYGNoYWkuQXNzZXJ0aW9uYC5cbiAqXG4gKiAgICAgY2hhaS5Bc3NlcnRpb24ub3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kKCdmb28nLCBmbiwgZm4pO1xuICpcbiAqIFRoZW4gY2FuIGJlIHVzZWQgYXMgYW55IG90aGVyIGFzc2VydGlvbi5cbiAqXG4gKiAgICAgZXhwZWN0KG15Rm9vKS50by5oYXZlLmxlbmd0aCgzKTtcbiAqICAgICBleHBlY3QobXlGb28pLnRvLmhhdmUubGVuZ3RoLmFib3ZlKDMpO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjdHggb2JqZWN0IHdob3NlIG1ldGhvZCAvIHByb3BlcnR5IGlzIHRvIGJlIG92ZXJ3cml0dGVuXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBvZiBtZXRob2QgLyBwcm9wZXJ0eSB0byBvdmVyd3JpdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG1ldGhvZCBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBmdW5jdGlvbiB0byBiZSB1c2VkIGZvciBuYW1lXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjaGFpbmluZ0JlaGF2aW9yIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIGZ1bmN0aW9uIHRvIGJlIHVzZWQgZm9yIHByb3BlcnR5XG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBvdmVyd3JpdGVDaGFpbmFibGVNZXRob2RcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoY3R4LCBuYW1lLCBtZXRob2QsIGNoYWluaW5nQmVoYXZpb3IpIHtcbiAgdmFyIGNoYWluYWJsZUJlaGF2aW9yID0gY3R4Ll9fbWV0aG9kc1tuYW1lXTtcblxuICB2YXIgX2NoYWluaW5nQmVoYXZpb3IgPSBjaGFpbmFibGVCZWhhdmlvci5jaGFpbmluZ0JlaGF2aW9yO1xuICBjaGFpbmFibGVCZWhhdmlvci5jaGFpbmluZ0JlaGF2aW9yID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciByZXN1bHQgPSBjaGFpbmluZ0JlaGF2aW9yKF9jaGFpbmluZ0JlaGF2aW9yKS5jYWxsKHRoaXMpO1xuICAgIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCA/IHRoaXMgOiByZXN1bHQ7XG4gIH07XG5cbiAgdmFyIF9tZXRob2QgPSBjaGFpbmFibGVCZWhhdmlvci5tZXRob2Q7XG4gIGNoYWluYWJsZUJlaGF2aW9yLm1ldGhvZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcmVzdWx0ID0gbWV0aG9kKF9tZXRob2QpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gdGhpcyA6IHJlc3VsdDtcbiAgfTtcbn07XG4iLCIvKiFcbiAqIENoYWkgLSBvdmVyd3JpdGVNZXRob2QgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIG92ZXJ3cml0ZU1ldGhvZCAoY3R4LCBuYW1lLCBmbilcbiAqXG4gKiBPdmVyd2l0ZXMgYW4gYWxyZWFkeSBleGlzdGluZyBtZXRob2QgYW5kIHByb3ZpZGVzXG4gKiBhY2Nlc3MgdG8gcHJldmlvdXMgZnVuY3Rpb24uIE11c3QgcmV0dXJuIGZ1bmN0aW9uXG4gKiB0byBiZSB1c2VkIGZvciBuYW1lLlxuICpcbiAqICAgICB1dGlscy5vdmVyd3JpdGVNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCAnZXF1YWwnLCBmdW5jdGlvbiAoX3N1cGVyKSB7XG4gKiAgICAgICByZXR1cm4gZnVuY3Rpb24gKHN0cikge1xuICogICAgICAgICB2YXIgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gKiAgICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBGb28pIHtcbiAqICAgICAgICAgICBuZXcgY2hhaS5Bc3NlcnRpb24ob2JqLnZhbHVlKS50by5lcXVhbChzdHIpO1xuICogICAgICAgICB9IGVsc2Uge1xuICogICAgICAgICAgIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICogICAgICAgICB9XG4gKiAgICAgICB9XG4gKiAgICAgfSk7XG4gKlxuICogQ2FuIGFsc28gYmUgYWNjZXNzZWQgZGlyZWN0bHkgZnJvbSBgY2hhaS5Bc3NlcnRpb25gLlxuICpcbiAqICAgICBjaGFpLkFzc2VydGlvbi5vdmVyd3JpdGVNZXRob2QoJ2ZvbycsIGZuKTtcbiAqXG4gKiBUaGVuIGNhbiBiZSB1c2VkIGFzIGFueSBvdGhlciBhc3NlcnRpb24uXG4gKlxuICogICAgIGV4cGVjdChteUZvbykudG8uZXF1YWwoJ2JhcicpO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjdHggb2JqZWN0IHdob3NlIG1ldGhvZCBpcyB0byBiZSBvdmVyd3JpdHRlblxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgbWV0aG9kIHRvIG92ZXJ3cml0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gbWV0aG9kIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIGZ1bmN0aW9uIHRvIGJlIHVzZWQgZm9yIG5hbWVcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIG92ZXJ3cml0ZU1ldGhvZFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjdHgsIG5hbWUsIG1ldGhvZCkge1xuICB2YXIgX21ldGhvZCA9IGN0eFtuYW1lXVxuICAgICwgX3N1cGVyID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfTtcblxuICBpZiAoX21ldGhvZCAmJiAnZnVuY3Rpb24nID09PSB0eXBlb2YgX21ldGhvZClcbiAgICBfc3VwZXIgPSBfbWV0aG9kO1xuXG4gIGN0eFtuYW1lXSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcmVzdWx0ID0gbWV0aG9kKF9zdXBlcikuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICByZXR1cm4gcmVzdWx0ID09PSB1bmRlZmluZWQgPyB0aGlzIDogcmVzdWx0O1xuICB9XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gb3ZlcndyaXRlUHJvcGVydHkgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIG92ZXJ3cml0ZVByb3BlcnR5IChjdHgsIG5hbWUsIGZuKVxuICpcbiAqIE92ZXJ3aXRlcyBhbiBhbHJlYWR5IGV4aXN0aW5nIHByb3BlcnR5IGdldHRlciBhbmQgcHJvdmlkZXNcbiAqIGFjY2VzcyB0byBwcmV2aW91cyB2YWx1ZS4gTXVzdCByZXR1cm4gZnVuY3Rpb24gdG8gdXNlIGFzIGdldHRlci5cbiAqXG4gKiAgICAgdXRpbHMub3ZlcndyaXRlUHJvcGVydHkoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCAnb2snLCBmdW5jdGlvbiAoX3N1cGVyKSB7XG4gKiAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICogICAgICAgICB2YXIgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gKiAgICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBGb28pIHtcbiAqICAgICAgICAgICBuZXcgY2hhaS5Bc3NlcnRpb24ob2JqLm5hbWUpLnRvLmVxdWFsKCdiYXInKTtcbiAqICAgICAgICAgfSBlbHNlIHtcbiAqICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzKTtcbiAqICAgICAgICAgfVxuICogICAgICAgfVxuICogICAgIH0pO1xuICpcbiAqXG4gKiBDYW4gYWxzbyBiZSBhY2Nlc3NlZCBkaXJlY3RseSBmcm9tIGBjaGFpLkFzc2VydGlvbmAuXG4gKlxuICogICAgIGNoYWkuQXNzZXJ0aW9uLm92ZXJ3cml0ZVByb3BlcnR5KCdmb28nLCBmbik7XG4gKlxuICogVGhlbiBjYW4gYmUgdXNlZCBhcyBhbnkgb3RoZXIgYXNzZXJ0aW9uLlxuICpcbiAqICAgICBleHBlY3QobXlGb28pLnRvLmJlLm9rO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjdHggb2JqZWN0IHdob3NlIHByb3BlcnR5IGlzIHRvIGJlIG92ZXJ3cml0dGVuXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBvZiBwcm9wZXJ0eSB0byBvdmVyd3JpdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGdldHRlciBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBnZXR0ZXIgZnVuY3Rpb24gdG8gYmUgdXNlZCBmb3IgbmFtZVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgb3ZlcndyaXRlUHJvcGVydHlcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoY3R4LCBuYW1lLCBnZXR0ZXIpIHtcbiAgdmFyIF9nZXQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGN0eCwgbmFtZSlcbiAgICAsIF9zdXBlciA9IGZ1bmN0aW9uICgpIHt9O1xuXG4gIGlmIChfZ2V0ICYmICdmdW5jdGlvbicgPT09IHR5cGVvZiBfZ2V0LmdldClcbiAgICBfc3VwZXIgPSBfZ2V0LmdldFxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIG5hbWUsXG4gICAgeyBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGdldHRlcihfc3VwZXIpLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCA/IHRoaXMgOiByZXN1bHQ7XG4gICAgICB9XG4gICAgLCBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gdGVzdCB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNb2R1bGUgZGVwZW5kYW5jaWVzXG4gKi9cblxudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcblxuLyoqXG4gKiAjIHRlc3Qob2JqZWN0LCBleHByZXNzaW9uKVxuICpcbiAqIFRlc3QgYW5kIG9iamVjdCBmb3IgZXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IChjb25zdHJ1Y3RlZCBBc3NlcnRpb24pXG4gKiBAcGFyYW0ge0FyZ3VtZW50c30gY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLmFzc2VydCBhcmd1bWVudHNcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIHRlc3RcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmosIGFyZ3MpIHtcbiAgdmFyIG5lZ2F0ZSA9IGZsYWcob2JqLCAnbmVnYXRlJylcbiAgICAsIGV4cHIgPSBhcmdzWzBdO1xuICByZXR1cm4gbmVnYXRlID8gIWV4cHIgOiBleHByO1xufTtcbiIsIi8qIVxuICogQ2hhaSAtIHRyYW5zZmVyRmxhZ3MgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIHRyYW5zZmVyRmxhZ3MoYXNzZXJ0aW9uLCBvYmplY3QsIGluY2x1ZGVBbGwgPSB0cnVlKVxuICpcbiAqIFRyYW5zZmVyIGFsbCB0aGUgZmxhZ3MgZm9yIGBhc3NlcnRpb25gIHRvIGBvYmplY3RgLiBJZlxuICogYGluY2x1ZGVBbGxgIGlzIHNldCB0byBgZmFsc2VgLCB0aGVuIHRoZSBiYXNlIENoYWlcbiAqIGFzc2VydGlvbiBmbGFncyAobmFtZWx5IGBvYmplY3RgLCBgc3NmaWAsIGFuZCBgbWVzc2FnZWApXG4gKiB3aWxsIG5vdCBiZSB0cmFuc2ZlcnJlZC5cbiAqXG4gKlxuICogICAgIHZhciBuZXdBc3NlcnRpb24gPSBuZXcgQXNzZXJ0aW9uKCk7XG4gKiAgICAgdXRpbHMudHJhbnNmZXJGbGFncyhhc3NlcnRpb24sIG5ld0Fzc2VydGlvbik7XG4gKlxuICogICAgIHZhciBhbm90aGVyQXNzZXJpdG9uID0gbmV3IEFzc2VydGlvbihteU9iaik7XG4gKiAgICAgdXRpbHMudHJhbnNmZXJGbGFncyhhc3NlcnRpb24sIGFub3RoZXJBc3NlcnRpb24sIGZhbHNlKTtcbiAqXG4gKiBAcGFyYW0ge0Fzc2VydGlvbn0gYXNzZXJ0aW9uIHRoZSBhc3NlcnRpb24gdG8gdHJhbnNmZXIgdGhlIGZsYWdzIGZyb21cbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgdGhlIG9iamVjdCB0byB0cmFuc2ZlciB0aGUgZmxhZ3MgdG87IHVzdWFsbHkgYSBuZXcgYXNzZXJ0aW9uXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGluY2x1ZGVBbGxcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIHRyYW5zZmVyRmxhZ3NcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGFzc2VydGlvbiwgb2JqZWN0LCBpbmNsdWRlQWxsKSB7XG4gIHZhciBmbGFncyA9IGFzc2VydGlvbi5fX2ZsYWdzIHx8IChhc3NlcnRpb24uX19mbGFncyA9IE9iamVjdC5jcmVhdGUobnVsbCkpO1xuXG4gIGlmICghb2JqZWN0Ll9fZmxhZ3MpIHtcbiAgICBvYmplY3QuX19mbGFncyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIH1cblxuICBpbmNsdWRlQWxsID0gYXJndW1lbnRzLmxlbmd0aCA9PT0gMyA/IGluY2x1ZGVBbGwgOiB0cnVlO1xuXG4gIGZvciAodmFyIGZsYWcgaW4gZmxhZ3MpIHtcbiAgICBpZiAoaW5jbHVkZUFsbCB8fFxuICAgICAgICAoZmxhZyAhPT0gJ29iamVjdCcgJiYgZmxhZyAhPT0gJ3NzZmknICYmIGZsYWcgIT0gJ21lc3NhZ2UnKSkge1xuICAgICAgb2JqZWN0Ll9fZmxhZ3NbZmxhZ10gPSBmbGFnc1tmbGFnXTtcbiAgICB9XG4gIH1cbn07XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuZnVuY3Rpb24gZGVkZW50KHN0cmluZ3MpIHtcblxuICB2YXIgcmF3ID0gdm9pZCAwO1xuICBpZiAodHlwZW9mIHN0cmluZ3MgPT09IFwic3RyaW5nXCIpIHtcbiAgICAvLyBkZWRlbnQgY2FuIGJlIHVzZWQgYXMgYSBwbGFpbiBmdW5jdGlvblxuICAgIHJhdyA9IFtzdHJpbmdzXTtcbiAgfSBlbHNlIHtcbiAgICByYXcgPSBzdHJpbmdzLnJhdztcbiAgfVxuXG4gIC8vIGZpcnN0LCBwZXJmb3JtIGludGVycG9sYXRpb25cbiAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmF3Lmxlbmd0aDsgaSsrKSB7XG4gICAgcmVzdWx0ICs9IHJhd1tpXS5cbiAgICAvLyBqb2luIGxpbmVzIHdoZW4gdGhlcmUgaXMgYSBzdXBwcmVzc2VkIG5ld2xpbmVcbiAgICByZXBsYWNlKC9cXFxcXFxuWyBcXHRdKi9nLCBcIlwiKS5cblxuICAgIC8vIGhhbmRsZSBlc2NhcGVkIGJhY2t0aWNrc1xuICAgIHJlcGxhY2UoL1xcXFxgL2csIFwiYFwiKTtcblxuICAgIGlmIChpIDwgKGFyZ3VtZW50cy5sZW5ndGggPD0gMSA/IDAgOiBhcmd1bWVudHMubGVuZ3RoIC0gMSkpIHtcbiAgICAgIHJlc3VsdCArPSBhcmd1bWVudHMubGVuZ3RoIDw9IGkgKyAxID8gdW5kZWZpbmVkIDogYXJndW1lbnRzW2kgKyAxXTtcbiAgICB9XG4gIH1cblxuICAvLyBub3cgc3RyaXAgaW5kZW50YXRpb25cbiAgdmFyIGxpbmVzID0gcmVzdWx0LnNwbGl0KFwiXFxuXCIpO1xuICB2YXIgbWluZGVudCA9IG51bGw7XG4gIGxpbmVzLmZvckVhY2goZnVuY3Rpb24gKGwpIHtcbiAgICB2YXIgbSA9IGwubWF0Y2goL14oXFxzKylcXFMrLyk7XG4gICAgaWYgKG0pIHtcbiAgICAgIHZhciBpbmRlbnQgPSBtWzFdLmxlbmd0aDtcbiAgICAgIGlmICghbWluZGVudCkge1xuICAgICAgICAvLyB0aGlzIGlzIHRoZSBmaXJzdCBpbmRlbnRlZCBsaW5lXG4gICAgICAgIG1pbmRlbnQgPSBpbmRlbnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtaW5kZW50ID0gTWF0aC5taW4obWluZGVudCwgaW5kZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGlmIChtaW5kZW50ICE9PSBudWxsKSB7XG4gICAgcmVzdWx0ID0gbGluZXMubWFwKGZ1bmN0aW9uIChsKSB7XG4gICAgICByZXR1cm4gbFswXSA9PT0gXCIgXCIgPyBsLnNsaWNlKG1pbmRlbnQpIDogbDtcbiAgICB9KS5qb2luKFwiXFxuXCIpO1xuICB9XG5cbiAgLy8gZGVkZW50IGVhdHMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSB0b29cbiAgcmVzdWx0ID0gcmVzdWx0LnRyaW0oKTtcblxuICAvLyBoYW5kbGUgZXNjYXBlZCBuZXdsaW5lcyBhdCB0aGUgZW5kIHRvIGVuc3VyZSB0aGV5IGRvbid0IGdldCBzdHJpcHBlZCB0b29cbiAgcmV0dXJuIHJlc3VsdC5yZXBsYWNlKC9cXFxcbi9nLCBcIlxcblwiKTtcbn1cblxuaWYgKHR5cGVvZiBtb2R1bGUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBkZWRlbnQ7XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL2VxbCcpO1xuIiwiLyohXG4gKiBkZWVwLWVxbFxuICogQ29weXJpZ2h0KGMpIDIwMTMgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKiFcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXNcbiAqL1xuXG52YXIgdHlwZSA9IHJlcXVpcmUoJ3R5cGUtZGV0ZWN0Jyk7XG5cbi8qIVxuICogQnVmZmVyLmlzQnVmZmVyIGJyb3dzZXIgc2hpbVxuICovXG5cbnZhciBCdWZmZXI7XG50cnkgeyBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7IH1cbmNhdGNoKGV4KSB7XG4gIEJ1ZmZlciA9IHt9O1xuICBCdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbigpIHsgcmV0dXJuIGZhbHNlOyB9XG59XG5cbi8qIVxuICogUHJpbWFyeSBFeHBvcnRcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlZXBFcXVhbDtcblxuLyoqXG4gKiBBc3NlcnQgc3VwZXItc3RyaWN0IChlZ2FsKSBlcXVhbGl0eSBiZXR3ZWVuXG4gKiB0d28gb2JqZWN0cyBvZiBhbnkgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBhXG4gKiBAcGFyYW0ge01peGVkfSBiXG4gKiBAcGFyYW0ge0FycmF5fSBtZW1vaXNlZCAob3B0aW9uYWwpXG4gKiBAcmV0dXJuIHtCb29sZWFufSBlcXVhbCBtYXRjaFxuICovXG5cbmZ1bmN0aW9uIGRlZXBFcXVhbChhLCBiLCBtKSB7XG4gIGlmIChzYW1lVmFsdWUoYSwgYikpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmICgnZGF0ZScgPT09IHR5cGUoYSkpIHtcbiAgICByZXR1cm4gZGF0ZUVxdWFsKGEsIGIpO1xuICB9IGVsc2UgaWYgKCdyZWdleHAnID09PSB0eXBlKGEpKSB7XG4gICAgcmV0dXJuIHJlZ2V4cEVxdWFsKGEsIGIpO1xuICB9IGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcihhKSkge1xuICAgIHJldHVybiBidWZmZXJFcXVhbChhLCBiKTtcbiAgfSBlbHNlIGlmICgnYXJndW1lbnRzJyA9PT0gdHlwZShhKSkge1xuICAgIHJldHVybiBhcmd1bWVudHNFcXVhbChhLCBiLCBtKTtcbiAgfSBlbHNlIGlmICghdHlwZUVxdWFsKGEsIGIpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IGVsc2UgaWYgKCgnb2JqZWN0JyAhPT0gdHlwZShhKSAmJiAnb2JqZWN0JyAhPT0gdHlwZShiKSlcbiAgJiYgKCdhcnJheScgIT09IHR5cGUoYSkgJiYgJ2FycmF5JyAhPT0gdHlwZShiKSkpIHtcbiAgICByZXR1cm4gc2FtZVZhbHVlKGEsIGIpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBvYmplY3RFcXVhbChhLCBiLCBtKTtcbiAgfVxufVxuXG4vKiFcbiAqIFN0cmljdCAoZWdhbCkgZXF1YWxpdHkgdGVzdC4gRW5zdXJlcyB0aGF0IE5hTiBhbHdheXNcbiAqIGVxdWFscyBOYU4gYW5kIGAtMGAgZG9lcyBub3QgZXF1YWwgYCswYC5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBhXG4gKiBAcGFyYW0ge01peGVkfSBiXG4gKiBAcmV0dXJuIHtCb29sZWFufSBlcXVhbCBtYXRjaFxuICovXG5cbmZ1bmN0aW9uIHNhbWVWYWx1ZShhLCBiKSB7XG4gIGlmIChhID09PSBiKSByZXR1cm4gYSAhPT0gMCB8fCAxIC8gYSA9PT0gMSAvIGI7XG4gIHJldHVybiBhICE9PSBhICYmIGIgIT09IGI7XG59XG5cbi8qIVxuICogQ29tcGFyZSB0aGUgdHlwZXMgb2YgdHdvIGdpdmVuIG9iamVjdHMgYW5kXG4gKiByZXR1cm4gaWYgdGhleSBhcmUgZXF1YWwuIE5vdGUgdGhhdCBhbiBBcnJheVxuICogaGFzIGEgdHlwZSBvZiBgYXJyYXlgIChub3QgYG9iamVjdGApIGFuZCBhcmd1bWVudHNcbiAqIGhhdmUgYSB0eXBlIG9mIGBhcmd1bWVudHNgIChub3QgYGFycmF5YC9gb2JqZWN0YCkuXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gYVxuICogQHBhcmFtIHtNaXhlZH0gYlxuICogQHJldHVybiB7Qm9vbGVhbn0gcmVzdWx0XG4gKi9cblxuZnVuY3Rpb24gdHlwZUVxdWFsKGEsIGIpIHtcbiAgcmV0dXJuIHR5cGUoYSkgPT09IHR5cGUoYik7XG59XG5cbi8qIVxuICogQ29tcGFyZSB0d28gRGF0ZSBvYmplY3RzIGJ5IGFzc2VydGluZyB0aGF0XG4gKiB0aGUgdGltZSB2YWx1ZXMgYXJlIGVxdWFsIHVzaW5nIGBzYXZlVmFsdWVgLlxuICpcbiAqIEBwYXJhbSB7RGF0ZX0gYVxuICogQHBhcmFtIHtEYXRlfSBiXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuXG5mdW5jdGlvbiBkYXRlRXF1YWwoYSwgYikge1xuICBpZiAoJ2RhdGUnICE9PSB0eXBlKGIpKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBzYW1lVmFsdWUoYS5nZXRUaW1lKCksIGIuZ2V0VGltZSgpKTtcbn1cblxuLyohXG4gKiBDb21wYXJlIHR3byByZWd1bGFyIGV4cHJlc3Npb25zIGJ5IGNvbnZlcnRpbmcgdGhlbVxuICogdG8gc3RyaW5nIGFuZCBjaGVja2luZyBmb3IgYHNhbWVWYWx1ZWAuXG4gKlxuICogQHBhcmFtIHtSZWdFeHB9IGFcbiAqIEBwYXJhbSB7UmVnRXhwfSBiXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuXG5mdW5jdGlvbiByZWdleHBFcXVhbChhLCBiKSB7XG4gIGlmICgncmVnZXhwJyAhPT0gdHlwZShiKSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gc2FtZVZhbHVlKGEudG9TdHJpbmcoKSwgYi50b1N0cmluZygpKTtcbn1cblxuLyohXG4gKiBBc3NlcnQgZGVlcCBlcXVhbGl0eSBvZiB0d28gYGFyZ3VtZW50c2Agb2JqZWN0cy5cbiAqIFVuZm9ydHVuYXRlbHksIHRoZXNlIG11c3QgYmUgc2xpY2VkIHRvIGFycmF5c1xuICogcHJpb3IgdG8gdGVzdCB0byBlbnN1cmUgbm8gYmFkIGJlaGF2aW9yLlxuICpcbiAqIEBwYXJhbSB7QXJndW1lbnRzfSBhXG4gKiBAcGFyYW0ge0FyZ3VtZW50c30gYlxuICogQHBhcmFtIHtBcnJheX0gbWVtb2l6ZSAob3B0aW9uYWwpXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuXG5mdW5jdGlvbiBhcmd1bWVudHNFcXVhbChhLCBiLCBtKSB7XG4gIGlmICgnYXJndW1lbnRzJyAhPT0gdHlwZShiKSkgcmV0dXJuIGZhbHNlO1xuICBhID0gW10uc2xpY2UuY2FsbChhKTtcbiAgYiA9IFtdLnNsaWNlLmNhbGwoYik7XG4gIHJldHVybiBkZWVwRXF1YWwoYSwgYiwgbSk7XG59XG5cbi8qIVxuICogR2V0IGVudW1lcmFibGUgcHJvcGVydGllcyBvZiBhIGdpdmVuIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gYVxuICogQHJldHVybiB7QXJyYXl9IHByb3BlcnR5IG5hbWVzXG4gKi9cblxuZnVuY3Rpb24gZW51bWVyYWJsZShhKSB7XG4gIHZhciByZXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIGEpIHJlcy5wdXNoKGtleSk7XG4gIHJldHVybiByZXM7XG59XG5cbi8qIVxuICogU2ltcGxlIGVxdWFsaXR5IGZvciBmbGF0IGl0ZXJhYmxlIG9iamVjdHNcbiAqIHN1Y2ggYXMgQXJyYXlzIG9yIE5vZGUuanMgYnVmZmVycy5cbiAqXG4gKiBAcGFyYW0ge0l0ZXJhYmxlfSBhXG4gKiBAcGFyYW0ge0l0ZXJhYmxlfSBiXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuXG5mdW5jdGlvbiBpdGVyYWJsZUVxdWFsKGEsIGIpIHtcbiAgaWYgKGEubGVuZ3RoICE9PSAgYi5sZW5ndGgpIHJldHVybiBmYWxzZTtcblxuICB2YXIgaSA9IDA7XG4gIHZhciBtYXRjaCA9IHRydWU7XG5cbiAgZm9yICg7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIG1hdGNoID0gZmFsc2U7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWF0Y2g7XG59XG5cbi8qIVxuICogRXh0ZW5zaW9uIHRvIGBpdGVyYWJsZUVxdWFsYCBzcGVjaWZpY2FsbHlcbiAqIGZvciBOb2RlLmpzIEJ1ZmZlcnMuXG4gKlxuICogQHBhcmFtIHtCdWZmZXJ9IGFcbiAqIEBwYXJhbSB7TWl4ZWR9IGJcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHJlc3VsdFxuICovXG5cbmZ1bmN0aW9uIGJ1ZmZlckVxdWFsKGEsIGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIGl0ZXJhYmxlRXF1YWwoYSwgYik7XG59XG5cbi8qIVxuICogQmxvY2sgZm9yIGBvYmplY3RFcXVhbGAgZW5zdXJpbmcgbm9uLWV4aXN0aW5nXG4gKiB2YWx1ZXMgZG9uJ3QgZ2V0IGluLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICogQHJldHVybiB7Qm9vbGVhbn0gcmVzdWx0XG4gKi9cblxuZnVuY3Rpb24gaXNWYWx1ZShhKSB7XG4gIHJldHVybiBhICE9PSBudWxsICYmIGEgIT09IHVuZGVmaW5lZDtcbn1cblxuLyohXG4gKiBSZWN1cnNpdmVseSBjaGVjayB0aGUgZXF1YWxpdHkgb2YgdHdvIG9iamVjdHMuXG4gKiBPbmNlIGJhc2ljIHNhbWVuZXNzIGhhcyBiZWVuIGVzdGFibGlzaGVkIGl0IHdpbGxcbiAqIGRlZmVyIHRvIGBkZWVwRXF1YWxgIGZvciBlYWNoIGVudW1lcmFibGUga2V5XG4gKiBpbiB0aGUgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IGFcbiAqIEBwYXJhbSB7TWl4ZWR9IGJcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHJlc3VsdFxuICovXG5cbmZ1bmN0aW9uIG9iamVjdEVxdWFsKGEsIGIsIG0pIHtcbiAgaWYgKCFpc1ZhbHVlKGEpIHx8ICFpc1ZhbHVlKGIpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGEucHJvdG90eXBlICE9PSBiLnByb3RvdHlwZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBpO1xuICBpZiAobSkge1xuICAgIGZvciAoaSA9IDA7IGkgPCBtLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoKG1baV1bMF0gPT09IGEgJiYgbVtpXVsxXSA9PT0gYilcbiAgICAgIHx8ICAobVtpXVswXSA9PT0gYiAmJiBtW2ldWzFdID09PSBhKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgbSA9IFtdO1xuICB9XG5cbiAgdHJ5IHtcbiAgICB2YXIga2EgPSBlbnVtZXJhYmxlKGEpO1xuICAgIHZhciBrYiA9IGVudW1lcmFibGUoYik7XG4gIH0gY2F0Y2ggKGV4KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAga2Euc29ydCgpO1xuICBrYi5zb3J0KCk7XG5cbiAgaWYgKCFpdGVyYWJsZUVxdWFsKGthLCBrYikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBtLnB1c2goWyBhLCBiIF0pO1xuXG4gIHZhciBrZXk7XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAga2V5ID0ga2FbaV07XG4gICAgaWYgKCFkZWVwRXF1YWwoYVtrZXldLCBiW2tleV0sIG0pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG4iLCIvKiFcbiAgICBsb2NhbEZvcmFnZSAtLSBPZmZsaW5lIFN0b3JhZ2UsIEltcHJvdmVkXG4gICAgVmVyc2lvbiAxLjUuMFxuICAgIGh0dHBzOi8vbG9jYWxmb3JhZ2UuZ2l0aHViLmlvL2xvY2FsRm9yYWdlXG4gICAgKGMpIDIwMTMtMjAxNyBNb3ppbGxhLCBBcGFjaGUgTGljZW5zZSAyLjBcbiovXG4oZnVuY3Rpb24oZil7aWYodHlwZW9mIGV4cG9ydHM9PT1cIm9iamVjdFwiJiZ0eXBlb2YgbW9kdWxlIT09XCJ1bmRlZmluZWRcIil7bW9kdWxlLmV4cG9ydHM9ZigpfWVsc2UgaWYodHlwZW9mIGRlZmluZT09PVwiZnVuY3Rpb25cIiYmZGVmaW5lLmFtZCl7ZGVmaW5lKFtdLGYpfWVsc2V7dmFyIGc7aWYodHlwZW9mIHdpbmRvdyE9PVwidW5kZWZpbmVkXCIpe2c9d2luZG93fWVsc2UgaWYodHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCIpe2c9Z2xvYmFsfWVsc2UgaWYodHlwZW9mIHNlbGYhPT1cInVuZGVmaW5lZFwiKXtnPXNlbGZ9ZWxzZXtnPXRoaXN9Zy5sb2NhbGZvcmFnZSA9IGYoKX19KShmdW5jdGlvbigpe3ZhciBkZWZpbmUsbW9kdWxlLGV4cG9ydHM7cmV0dXJuIChmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyAoZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLCBmKX12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pKHsxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbihmdW5jdGlvbiAoZ2xvYmFsKXtcbid1c2Ugc3RyaWN0JztcbnZhciBNdXRhdGlvbiA9IGdsb2JhbC5NdXRhdGlvbk9ic2VydmVyIHx8IGdsb2JhbC5XZWJLaXRNdXRhdGlvbk9ic2VydmVyO1xuXG52YXIgc2NoZWR1bGVEcmFpbjtcblxue1xuICBpZiAoTXV0YXRpb24pIHtcbiAgICB2YXIgY2FsbGVkID0gMDtcbiAgICB2YXIgb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb24obmV4dFRpY2spO1xuICAgIHZhciBlbGVtZW50ID0gZ2xvYmFsLmRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcnKTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKGVsZW1lbnQsIHtcbiAgICAgIGNoYXJhY3RlckRhdGE6IHRydWVcbiAgICB9KTtcbiAgICBzY2hlZHVsZURyYWluID0gZnVuY3Rpb24gKCkge1xuICAgICAgZWxlbWVudC5kYXRhID0gKGNhbGxlZCA9ICsrY2FsbGVkICUgMik7XG4gICAgfTtcbiAgfSBlbHNlIGlmICghZ2xvYmFsLnNldEltbWVkaWF0ZSAmJiB0eXBlb2YgZ2xvYmFsLk1lc3NhZ2VDaGFubmVsICE9PSAndW5kZWZpbmVkJykge1xuICAgIHZhciBjaGFubmVsID0gbmV3IGdsb2JhbC5NZXNzYWdlQ2hhbm5lbCgpO1xuICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gbmV4dFRpY2s7XG4gICAgc2NoZWR1bGVEcmFpbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4gICAgfTtcbiAgfSBlbHNlIGlmICgnZG9jdW1lbnQnIGluIGdsb2JhbCAmJiAnb25yZWFkeXN0YXRlY2hhbmdlJyBpbiBnbG9iYWwuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0JykpIHtcbiAgICBzY2hlZHVsZURyYWluID0gZnVuY3Rpb24gKCkge1xuXG4gICAgICAvLyBDcmVhdGUgYSA8c2NyaXB0PiBlbGVtZW50OyBpdHMgcmVhZHlzdGF0ZWNoYW5nZSBldmVudCB3aWxsIGJlIGZpcmVkIGFzeW5jaHJvbm91c2x5IG9uY2UgaXQgaXMgaW5zZXJ0ZWRcbiAgICAgIC8vIGludG8gdGhlIGRvY3VtZW50LiBEbyBzbywgdGh1cyBxdWV1aW5nIHVwIHRoZSB0YXNrLiBSZW1lbWJlciB0byBjbGVhbiB1cCBvbmNlIGl0J3MgYmVlbiBjYWxsZWQuXG4gICAgICB2YXIgc2NyaXB0RWwgPSBnbG9iYWwuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gICAgICBzY3JpcHRFbC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5leHRUaWNrKCk7XG5cbiAgICAgICAgc2NyaXB0RWwub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbDtcbiAgICAgICAgc2NyaXB0RWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChzY3JpcHRFbCk7XG4gICAgICAgIHNjcmlwdEVsID0gbnVsbDtcbiAgICAgIH07XG4gICAgICBnbG9iYWwuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKHNjcmlwdEVsKTtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHNjaGVkdWxlRHJhaW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICBzZXRUaW1lb3V0KG5leHRUaWNrLCAwKTtcbiAgICB9O1xuICB9XG59XG5cbnZhciBkcmFpbmluZztcbnZhciBxdWV1ZSA9IFtdO1xuLy9uYW1lZCBuZXh0VGljayBmb3IgbGVzcyBjb25mdXNpbmcgc3RhY2sgdHJhY2VzXG5mdW5jdGlvbiBuZXh0VGljaygpIHtcbiAgZHJhaW5pbmcgPSB0cnVlO1xuICB2YXIgaSwgb2xkUXVldWU7XG4gIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gIHdoaWxlIChsZW4pIHtcbiAgICBvbGRRdWV1ZSA9IHF1ZXVlO1xuICAgIHF1ZXVlID0gW107XG4gICAgaSA9IC0xO1xuICAgIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICAgIG9sZFF1ZXVlW2ldKCk7XG4gICAgfVxuICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgfVxuICBkcmFpbmluZyA9IGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGltbWVkaWF0ZTtcbmZ1bmN0aW9uIGltbWVkaWF0ZSh0YXNrKSB7XG4gIGlmIChxdWV1ZS5wdXNoKHRhc2spID09PSAxICYmICFkcmFpbmluZykge1xuICAgIHNjaGVkdWxlRHJhaW4oKTtcbiAgfVxufVxuXG59KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSlcbn0se31dLDI6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xudmFyIGltbWVkaWF0ZSA9IF9kZXJlcV8oMSk7XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBJTlRFUk5BTCgpIHt9XG5cbnZhciBoYW5kbGVycyA9IHt9O1xuXG52YXIgUkVKRUNURUQgPSBbJ1JFSkVDVEVEJ107XG52YXIgRlVMRklMTEVEID0gWydGVUxGSUxMRUQnXTtcbnZhciBQRU5ESU5HID0gWydQRU5ESU5HJ107XG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IFByb21pc2U7XG5cbmZ1bmN0aW9uIFByb21pc2UocmVzb2x2ZXIpIHtcbiAgaWYgKHR5cGVvZiByZXNvbHZlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3Jlc29sdmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB9XG4gIHRoaXMuc3RhdGUgPSBQRU5ESU5HO1xuICB0aGlzLnF1ZXVlID0gW107XG4gIHRoaXMub3V0Y29tZSA9IHZvaWQgMDtcbiAgaWYgKHJlc29sdmVyICE9PSBJTlRFUk5BTCkge1xuICAgIHNhZmVseVJlc29sdmVUaGVuYWJsZSh0aGlzLCByZXNvbHZlcik7XG4gIH1cbn1cblxuUHJvbWlzZS5wcm90b3R5cGVbXCJjYXRjaFwiXSA9IGZ1bmN0aW9uIChvblJlamVjdGVkKSB7XG4gIHJldHVybiB0aGlzLnRoZW4obnVsbCwgb25SZWplY3RlZCk7XG59O1xuUHJvbWlzZS5wcm90b3R5cGUudGhlbiA9IGZ1bmN0aW9uIChvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuICBpZiAodHlwZW9mIG9uRnVsZmlsbGVkICE9PSAnZnVuY3Rpb24nICYmIHRoaXMuc3RhdGUgPT09IEZVTEZJTExFRCB8fFxuICAgIHR5cGVvZiBvblJlamVjdGVkICE9PSAnZnVuY3Rpb24nICYmIHRoaXMuc3RhdGUgPT09IFJFSkVDVEVEKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgdmFyIHByb21pc2UgPSBuZXcgdGhpcy5jb25zdHJ1Y3RvcihJTlRFUk5BTCk7XG4gIGlmICh0aGlzLnN0YXRlICE9PSBQRU5ESU5HKSB7XG4gICAgdmFyIHJlc29sdmVyID0gdGhpcy5zdGF0ZSA9PT0gRlVMRklMTEVEID8gb25GdWxmaWxsZWQgOiBvblJlamVjdGVkO1xuICAgIHVud3JhcChwcm9taXNlLCByZXNvbHZlciwgdGhpcy5vdXRjb21lKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnF1ZXVlLnB1c2gobmV3IFF1ZXVlSXRlbShwcm9taXNlLCBvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkpO1xuICB9XG5cbiAgcmV0dXJuIHByb21pc2U7XG59O1xuZnVuY3Rpb24gUXVldWVJdGVtKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKSB7XG4gIHRoaXMucHJvbWlzZSA9IHByb21pc2U7XG4gIGlmICh0eXBlb2Ygb25GdWxmaWxsZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0aGlzLm9uRnVsZmlsbGVkID0gb25GdWxmaWxsZWQ7XG4gICAgdGhpcy5jYWxsRnVsZmlsbGVkID0gdGhpcy5vdGhlckNhbGxGdWxmaWxsZWQ7XG4gIH1cbiAgaWYgKHR5cGVvZiBvblJlamVjdGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhpcy5vblJlamVjdGVkID0gb25SZWplY3RlZDtcbiAgICB0aGlzLmNhbGxSZWplY3RlZCA9IHRoaXMub3RoZXJDYWxsUmVqZWN0ZWQ7XG4gIH1cbn1cblF1ZXVlSXRlbS5wcm90b3R5cGUuY2FsbEZ1bGZpbGxlZCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICBoYW5kbGVycy5yZXNvbHZlKHRoaXMucHJvbWlzZSwgdmFsdWUpO1xufTtcblF1ZXVlSXRlbS5wcm90b3R5cGUub3RoZXJDYWxsRnVsZmlsbGVkID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gIHVud3JhcCh0aGlzLnByb21pc2UsIHRoaXMub25GdWxmaWxsZWQsIHZhbHVlKTtcbn07XG5RdWV1ZUl0ZW0ucHJvdG90eXBlLmNhbGxSZWplY3RlZCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICBoYW5kbGVycy5yZWplY3QodGhpcy5wcm9taXNlLCB2YWx1ZSk7XG59O1xuUXVldWVJdGVtLnByb3RvdHlwZS5vdGhlckNhbGxSZWplY3RlZCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICB1bndyYXAodGhpcy5wcm9taXNlLCB0aGlzLm9uUmVqZWN0ZWQsIHZhbHVlKTtcbn07XG5cbmZ1bmN0aW9uIHVud3JhcChwcm9taXNlLCBmdW5jLCB2YWx1ZSkge1xuICBpbW1lZGlhdGUoZnVuY3Rpb24gKCkge1xuICAgIHZhciByZXR1cm5WYWx1ZTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuVmFsdWUgPSBmdW5jKHZhbHVlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gaGFuZGxlcnMucmVqZWN0KHByb21pc2UsIGUpO1xuICAgIH1cbiAgICBpZiAocmV0dXJuVmFsdWUgPT09IHByb21pc2UpIHtcbiAgICAgIGhhbmRsZXJzLnJlamVjdChwcm9taXNlLCBuZXcgVHlwZUVycm9yKCdDYW5ub3QgcmVzb2x2ZSBwcm9taXNlIHdpdGggaXRzZWxmJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICBoYW5kbGVycy5yZXNvbHZlKHByb21pc2UsIHJldHVyblZhbHVlKTtcbiAgICB9XG4gIH0pO1xufVxuXG5oYW5kbGVycy5yZXNvbHZlID0gZnVuY3Rpb24gKHNlbGYsIHZhbHVlKSB7XG4gIHZhciByZXN1bHQgPSB0cnlDYXRjaChnZXRUaGVuLCB2YWx1ZSk7XG4gIGlmIChyZXN1bHQuc3RhdHVzID09PSAnZXJyb3InKSB7XG4gICAgcmV0dXJuIGhhbmRsZXJzLnJlamVjdChzZWxmLCByZXN1bHQudmFsdWUpO1xuICB9XG4gIHZhciB0aGVuYWJsZSA9IHJlc3VsdC52YWx1ZTtcblxuICBpZiAodGhlbmFibGUpIHtcbiAgICBzYWZlbHlSZXNvbHZlVGhlbmFibGUoc2VsZiwgdGhlbmFibGUpO1xuICB9IGVsc2Uge1xuICAgIHNlbGYuc3RhdGUgPSBGVUxGSUxMRUQ7XG4gICAgc2VsZi5vdXRjb21lID0gdmFsdWU7XG4gICAgdmFyIGkgPSAtMTtcbiAgICB2YXIgbGVuID0gc2VsZi5xdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgICAgc2VsZi5xdWV1ZVtpXS5jYWxsRnVsZmlsbGVkKHZhbHVlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHNlbGY7XG59O1xuaGFuZGxlcnMucmVqZWN0ID0gZnVuY3Rpb24gKHNlbGYsIGVycm9yKSB7XG4gIHNlbGYuc3RhdGUgPSBSRUpFQ1RFRDtcbiAgc2VsZi5vdXRjb21lID0gZXJyb3I7XG4gIHZhciBpID0gLTE7XG4gIHZhciBsZW4gPSBzZWxmLnF1ZXVlLmxlbmd0aDtcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIHNlbGYucXVldWVbaV0uY2FsbFJlamVjdGVkKGVycm9yKTtcbiAgfVxuICByZXR1cm4gc2VsZjtcbn07XG5cbmZ1bmN0aW9uIGdldFRoZW4ob2JqKSB7XG4gIC8vIE1ha2Ugc3VyZSB3ZSBvbmx5IGFjY2VzcyB0aGUgYWNjZXNzb3Igb25jZSBhcyByZXF1aXJlZCBieSB0aGUgc3BlY1xuICB2YXIgdGhlbiA9IG9iaiAmJiBvYmoudGhlbjtcbiAgaWYgKG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgdGhlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBmdW5jdGlvbiBhcHB5VGhlbigpIHtcbiAgICAgIHRoZW4uYXBwbHkob2JqLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH1cbn1cblxuZnVuY3Rpb24gc2FmZWx5UmVzb2x2ZVRoZW5hYmxlKHNlbGYsIHRoZW5hYmxlKSB7XG4gIC8vIEVpdGhlciBmdWxmaWxsLCByZWplY3Qgb3IgcmVqZWN0IHdpdGggZXJyb3JcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBvbkVycm9yKHZhbHVlKSB7XG4gICAgaWYgKGNhbGxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjYWxsZWQgPSB0cnVlO1xuICAgIGhhbmRsZXJzLnJlamVjdChzZWxmLCB2YWx1ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBvblN1Y2Nlc3ModmFsdWUpIHtcbiAgICBpZiAoY2FsbGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNhbGxlZCA9IHRydWU7XG4gICAgaGFuZGxlcnMucmVzb2x2ZShzZWxmLCB2YWx1ZSk7XG4gIH1cblxuICBmdW5jdGlvbiB0cnlUb1Vud3JhcCgpIHtcbiAgICB0aGVuYWJsZShvblN1Y2Nlc3MsIG9uRXJyb3IpO1xuICB9XG5cbiAgdmFyIHJlc3VsdCA9IHRyeUNhdGNoKHRyeVRvVW53cmFwKTtcbiAgaWYgKHJlc3VsdC5zdGF0dXMgPT09ICdlcnJvcicpIHtcbiAgICBvbkVycm9yKHJlc3VsdC52YWx1ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gdHJ5Q2F0Y2goZnVuYywgdmFsdWUpIHtcbiAgdmFyIG91dCA9IHt9O1xuICB0cnkge1xuICAgIG91dC52YWx1ZSA9IGZ1bmModmFsdWUpO1xuICAgIG91dC5zdGF0dXMgPSAnc3VjY2Vzcyc7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBvdXQuc3RhdHVzID0gJ2Vycm9yJztcbiAgICBvdXQudmFsdWUgPSBlO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbmV4cG9ydHMucmVzb2x2ZSA9IHJlc29sdmU7XG5mdW5jdGlvbiByZXNvbHZlKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIHRoaXMpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIGhhbmRsZXJzLnJlc29sdmUobmV3IHRoaXMoSU5URVJOQUwpLCB2YWx1ZSk7XG59XG5cbmV4cG9ydHMucmVqZWN0ID0gcmVqZWN0O1xuZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICB2YXIgcHJvbWlzZSA9IG5ldyB0aGlzKElOVEVSTkFMKTtcbiAgcmV0dXJuIGhhbmRsZXJzLnJlamVjdChwcm9taXNlLCByZWFzb24pO1xufVxuXG5leHBvcnRzLmFsbCA9IGFsbDtcbmZ1bmN0aW9uIGFsbChpdGVyYWJsZSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaXRlcmFibGUpICE9PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgcmV0dXJuIHRoaXMucmVqZWN0KG5ldyBUeXBlRXJyb3IoJ211c3QgYmUgYW4gYXJyYXknKSk7XG4gIH1cblxuICB2YXIgbGVuID0gaXRlcmFibGUubGVuZ3RoO1xuICB2YXIgY2FsbGVkID0gZmFsc2U7XG4gIGlmICghbGVuKSB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZShbXSk7XG4gIH1cblxuICB2YXIgdmFsdWVzID0gbmV3IEFycmF5KGxlbik7XG4gIHZhciByZXNvbHZlZCA9IDA7XG4gIHZhciBpID0gLTE7XG4gIHZhciBwcm9taXNlID0gbmV3IHRoaXMoSU5URVJOQUwpO1xuXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBhbGxSZXNvbHZlcihpdGVyYWJsZVtpXSwgaSk7XG4gIH1cbiAgcmV0dXJuIHByb21pc2U7XG4gIGZ1bmN0aW9uIGFsbFJlc29sdmVyKHZhbHVlLCBpKSB7XG4gICAgc2VsZi5yZXNvbHZlKHZhbHVlKS50aGVuKHJlc29sdmVGcm9tQWxsLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGlmICghY2FsbGVkKSB7XG4gICAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICAgIGhhbmRsZXJzLnJlamVjdChwcm9taXNlLCBlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgZnVuY3Rpb24gcmVzb2x2ZUZyb21BbGwob3V0VmFsdWUpIHtcbiAgICAgIHZhbHVlc1tpXSA9IG91dFZhbHVlO1xuICAgICAgaWYgKCsrcmVzb2x2ZWQgPT09IGxlbiAmJiAhY2FsbGVkKSB7XG4gICAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICAgIGhhbmRsZXJzLnJlc29sdmUocHJvbWlzZSwgdmFsdWVzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0cy5yYWNlID0gcmFjZTtcbmZ1bmN0aW9uIHJhY2UoaXRlcmFibGUpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGl0ZXJhYmxlKSAhPT0gJ1tvYmplY3QgQXJyYXldJykge1xuICAgIHJldHVybiB0aGlzLnJlamVjdChuZXcgVHlwZUVycm9yKCdtdXN0IGJlIGFuIGFycmF5JykpO1xuICB9XG5cbiAgdmFyIGxlbiA9IGl0ZXJhYmxlLmxlbmd0aDtcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICBpZiAoIWxlbikge1xuICAgIHJldHVybiB0aGlzLnJlc29sdmUoW10pO1xuICB9XG5cbiAgdmFyIGkgPSAtMTtcbiAgdmFyIHByb21pc2UgPSBuZXcgdGhpcyhJTlRFUk5BTCk7XG5cbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIHJlc29sdmVyKGl0ZXJhYmxlW2ldKTtcbiAgfVxuICByZXR1cm4gcHJvbWlzZTtcbiAgZnVuY3Rpb24gcmVzb2x2ZXIodmFsdWUpIHtcbiAgICBzZWxmLnJlc29sdmUodmFsdWUpLnRoZW4oZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICBpZiAoIWNhbGxlZCkge1xuICAgICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgICBoYW5kbGVycy5yZXNvbHZlKHByb21pc2UsIHJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGlmICghY2FsbGVkKSB7XG4gICAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICAgIGhhbmRsZXJzLnJlamVjdChwcm9taXNlLCBlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxufSx7XCIxXCI6MX1dLDM6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuKGZ1bmN0aW9uIChnbG9iYWwpe1xuJ3VzZSBzdHJpY3QnO1xuaWYgKHR5cGVvZiBnbG9iYWwuUHJvbWlzZSAhPT0gJ2Z1bmN0aW9uJykge1xuICBnbG9iYWwuUHJvbWlzZSA9IF9kZXJlcV8oMik7XG59XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KVxufSx7XCIyXCI6Mn1dLDQ6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiID8gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfSA6IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbmZ1bmN0aW9uIGdldElEQigpIHtcbiAgICAvKiBnbG9iYWwgaW5kZXhlZERCLHdlYmtpdEluZGV4ZWREQixtb3pJbmRleGVkREIsT0luZGV4ZWREQixtc0luZGV4ZWREQiAqL1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgaW5kZXhlZERCICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcmV0dXJuIGluZGV4ZWREQjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHdlYmtpdEluZGV4ZWREQiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB3ZWJraXRJbmRleGVkREI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBtb3pJbmRleGVkREIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICByZXR1cm4gbW96SW5kZXhlZERCO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgT0luZGV4ZWREQiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHJldHVybiBPSW5kZXhlZERCO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgbXNJbmRleGVkREIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICByZXR1cm4gbXNJbmRleGVkREI7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7fVxufVxuXG52YXIgaWRiID0gZ2V0SURCKCk7XG5cbmZ1bmN0aW9uIGlzSW5kZXhlZERCVmFsaWQoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBJbmRleGVkREI7IGZhbGwgYmFjayB0byB2ZW5kb3ItcHJlZml4ZWQgdmVyc2lvbnNcbiAgICAgICAgLy8gaWYgbmVlZGVkLlxuICAgICAgICBpZiAoIWlkYikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIC8vIFdlIG1pbWljIFBvdWNoREIgaGVyZTtcbiAgICAgICAgLy9cbiAgICAgICAgLy8gV2UgdGVzdCBmb3Igb3BlbkRhdGFiYXNlIGJlY2F1c2UgSUUgTW9iaWxlIGlkZW50aWZpZXMgaXRzZWxmXG4gICAgICAgIC8vIGFzIFNhZmFyaS4gT2ggdGhlIGx1bHouLi5cbiAgICAgICAgdmFyIGlzU2FmYXJpID0gdHlwZW9mIG9wZW5EYXRhYmFzZSAhPT0gJ3VuZGVmaW5lZCcgJiYgLyhTYWZhcml8aVBob25lfGlQYWR8aVBvZCkvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgJiYgIS9DaHJvbWUvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgJiYgIS9CbGFja0JlcnJ5Ly50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSk7XG5cbiAgICAgICAgdmFyIGhhc0ZldGNoID0gdHlwZW9mIGZldGNoID09PSAnZnVuY3Rpb24nICYmIGZldGNoLnRvU3RyaW5nKCkuaW5kZXhPZignW25hdGl2ZSBjb2RlJykgIT09IC0xO1xuXG4gICAgICAgIC8vIFNhZmFyaSA8MTAuMSBkb2VzIG5vdCBtZWV0IG91ciByZXF1aXJlbWVudHMgZm9yIElEQiBzdXBwb3J0ICgjNTU3MilcbiAgICAgICAgLy8gc2luY2UgU2FmYXJpIDEwLjEgc2hpcHBlZCB3aXRoIGZldGNoLCB3ZSBjYW4gdXNlIHRoYXQgdG8gZGV0ZWN0IGl0XG4gICAgICAgIHJldHVybiAoIWlzU2FmYXJpIHx8IGhhc0ZldGNoKSAmJiB0eXBlb2YgaW5kZXhlZERCICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAvLyBzb21lIG91dGRhdGVkIGltcGxlbWVudGF0aW9ucyBvZiBJREIgdGhhdCBhcHBlYXIgb24gU2Ftc3VuZ1xuICAgICAgICAvLyBhbmQgSFRDIEFuZHJvaWQgZGV2aWNlcyA8NC40IGFyZSBtaXNzaW5nIElEQktleVJhbmdlXG4gICAgICAgIHR5cGVvZiBJREJLZXlSYW5nZSAhPT0gJ3VuZGVmaW5lZCc7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc1dlYlNRTFZhbGlkKCkge1xuICAgIHJldHVybiB0eXBlb2Ygb3BlbkRhdGFiYXNlID09PSAnZnVuY3Rpb24nO1xufVxuXG5mdW5jdGlvbiBpc0xvY2FsU3RvcmFnZVZhbGlkKCkge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgbG9jYWxTdG9yYWdlICE9PSAndW5kZWZpbmVkJyAmJiAnc2V0SXRlbScgaW4gbG9jYWxTdG9yYWdlICYmIGxvY2FsU3RvcmFnZS5zZXRJdGVtO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuLy8gQWJzdHJhY3RzIGNvbnN0cnVjdGluZyBhIEJsb2Igb2JqZWN0LCBzbyBpdCBhbHNvIHdvcmtzIGluIG9sZGVyXG4vLyBicm93c2VycyB0aGF0IGRvbid0IHN1cHBvcnQgdGhlIG5hdGl2ZSBCbG9iIGNvbnN0cnVjdG9yLiAoaS5lLlxuLy8gb2xkIFF0V2ViS2l0IHZlcnNpb25zLCBhdCBsZWFzdCkuXG4vLyBBYnN0cmFjdHMgY29uc3RydWN0aW5nIGEgQmxvYiBvYmplY3QsIHNvIGl0IGFsc28gd29ya3MgaW4gb2xkZXJcbi8vIGJyb3dzZXJzIHRoYXQgZG9uJ3Qgc3VwcG9ydCB0aGUgbmF0aXZlIEJsb2IgY29uc3RydWN0b3IuIChpLmUuXG4vLyBvbGQgUXRXZWJLaXQgdmVyc2lvbnMsIGF0IGxlYXN0KS5cbmZ1bmN0aW9uIGNyZWF0ZUJsb2IocGFydHMsIHByb3BlcnRpZXMpIHtcbiAgICAvKiBnbG9iYWwgQmxvYkJ1aWxkZXIsTVNCbG9iQnVpbGRlcixNb3pCbG9iQnVpbGRlcixXZWJLaXRCbG9iQnVpbGRlciAqL1xuICAgIHBhcnRzID0gcGFydHMgfHwgW107XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgfHwge307XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5ldyBCbG9iKHBhcnRzLCBwcm9wZXJ0aWVzKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChlLm5hbWUgIT09ICdUeXBlRXJyb3InKSB7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBCdWlsZGVyID0gdHlwZW9mIEJsb2JCdWlsZGVyICE9PSAndW5kZWZpbmVkJyA/IEJsb2JCdWlsZGVyIDogdHlwZW9mIE1TQmxvYkJ1aWxkZXIgIT09ICd1bmRlZmluZWQnID8gTVNCbG9iQnVpbGRlciA6IHR5cGVvZiBNb3pCbG9iQnVpbGRlciAhPT0gJ3VuZGVmaW5lZCcgPyBNb3pCbG9iQnVpbGRlciA6IFdlYktpdEJsb2JCdWlsZGVyO1xuICAgICAgICB2YXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKHBhcnRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYnVpbGRlci5nZXRCbG9iKHByb3BlcnRpZXMudHlwZSk7XG4gICAgfVxufVxuXG4vLyBUaGlzIGlzIENvbW1vbkpTIGJlY2F1c2UgbGllIGlzIGFuIGV4dGVybmFsIGRlcGVuZGVuY3ksIHNvIFJvbGx1cFxuLy8gY2FuIGp1c3QgaWdub3JlIGl0LlxuaWYgKHR5cGVvZiBQcm9taXNlID09PSAndW5kZWZpbmVkJykge1xuICAgIC8vIEluIHRoZSBcIm5vcHJvbWlzZXNcIiBidWlsZCB0aGlzIHdpbGwganVzdCB0aHJvdyBpZiB5b3UgZG9uJ3QgaGF2ZVxuICAgIC8vIGEgZ2xvYmFsIHByb21pc2Ugb2JqZWN0LCBidXQgaXQgd291bGQgdGhyb3cgYW55d2F5IGxhdGVyLlxuICAgIF9kZXJlcV8oMyk7XG59XG52YXIgUHJvbWlzZSQxID0gUHJvbWlzZTtcblxuZnVuY3Rpb24gZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgIHByb21pc2UudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgICAgICBjYWxsYmFjayhudWxsLCByZXN1bHQpO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBleGVjdXRlVHdvQ2FsbGJhY2tzKHByb21pc2UsIGNhbGxiYWNrLCBlcnJvckNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwcm9taXNlLnRoZW4oY2FsbGJhY2spO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZXJyb3JDYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwcm9taXNlW1wiY2F0Y2hcIl0oZXJyb3JDYWxsYmFjayk7XG4gICAgfVxufVxuXG4vLyBTb21lIGNvZGUgb3JpZ2luYWxseSBmcm9tIGFzeW5jX3N0b3JhZ2UuanMgaW5cbi8vIFtHYWlhXShodHRwczovL2dpdGh1Yi5jb20vbW96aWxsYS1iMmcvZ2FpYSkuXG5cbnZhciBERVRFQ1RfQkxPQl9TVVBQT1JUX1NUT1JFID0gJ2xvY2FsLWZvcmFnZS1kZXRlY3QtYmxvYi1zdXBwb3J0JztcbnZhciBzdXBwb3J0c0Jsb2JzO1xudmFyIGRiQ29udGV4dHM7XG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vLyBUcmFuc2Zvcm0gYSBiaW5hcnkgc3RyaW5nIHRvIGFuIGFycmF5IGJ1ZmZlciwgYmVjYXVzZSBvdGhlcndpc2Vcbi8vIHdlaXJkIHN0dWZmIGhhcHBlbnMgd2hlbiB5b3UgdHJ5IHRvIHdvcmsgd2l0aCB0aGUgYmluYXJ5IHN0cmluZyBkaXJlY3RseS5cbi8vIEl0IGlzIGtub3duLlxuLy8gRnJvbSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzE0OTY3NjQ3LyAoY29udGludWVzIG9uIG5leHQgbGluZSlcbi8vIGVuY29kZS1kZWNvZGUtaW1hZ2Utd2l0aC1iYXNlNjQtYnJlYWtzLWltYWdlICgyMDEzLTA0LTIxKVxuZnVuY3Rpb24gX2JpblN0cmluZ1RvQXJyYXlCdWZmZXIoYmluKSB7XG4gICAgdmFyIGxlbmd0aCA9IGJpbi5sZW5ndGg7XG4gICAgdmFyIGJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcihsZW5ndGgpO1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheShidWYpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYXJyW2ldID0gYmluLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuICAgIHJldHVybiBidWY7XG59XG5cbi8vXG4vLyBCbG9icyBhcmUgbm90IHN1cHBvcnRlZCBpbiBhbGwgdmVyc2lvbnMgb2YgSW5kZXhlZERCLCBub3RhYmx5XG4vLyBDaHJvbWUgPDM3IGFuZCBBbmRyb2lkIDw1LiBJbiB0aG9zZSB2ZXJzaW9ucywgc3RvcmluZyBhIGJsb2Igd2lsbCB0aHJvdy5cbi8vXG4vLyBWYXJpb3VzIG90aGVyIGJsb2IgYnVncyBleGlzdCBpbiBDaHJvbWUgdjM3LTQyIChpbmNsdXNpdmUpLlxuLy8gRGV0ZWN0aW5nIHRoZW0gaXMgZXhwZW5zaXZlIGFuZCBjb25mdXNpbmcgdG8gdXNlcnMsIGFuZCBDaHJvbWUgMzctNDJcbi8vIGlzIGF0IHZlcnkgbG93IHVzYWdlIHdvcmxkd2lkZSwgc28gd2UgZG8gYSBoYWNreSB1c2VyQWdlbnQgY2hlY2sgaW5zdGVhZC5cbi8vXG4vLyBjb250ZW50LXR5cGUgYnVnOiBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NDA4MTIwXG4vLyA0MDQgYnVnOiBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NDQ3OTE2XG4vLyBGaWxlUmVhZGVyIGJ1ZzogaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTQ0NzgzNlxuLy9cbi8vIENvZGUgYm9ycm93ZWQgZnJvbSBQb3VjaERCLiBTZWU6XG4vLyBodHRwczovL2dpdGh1Yi5jb20vcG91Y2hkYi9wb3VjaGRiL2Jsb2IvbWFzdGVyL3BhY2thZ2VzL25vZGVfbW9kdWxlcy9wb3VjaGRiLWFkYXB0ZXItaWRiL3NyYy9ibG9iU3VwcG9ydC5qc1xuLy9cbmZ1bmN0aW9uIF9jaGVja0Jsb2JTdXBwb3J0V2l0aG91dENhY2hpbmcoaWRiKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgdmFyIHR4biA9IGlkYi50cmFuc2FjdGlvbihERVRFQ1RfQkxPQl9TVVBQT1JUX1NUT1JFLCAncmVhZHdyaXRlJyk7XG4gICAgICAgIHZhciBibG9iID0gY3JlYXRlQmxvYihbJyddKTtcbiAgICAgICAgdHhuLm9iamVjdFN0b3JlKERFVEVDVF9CTE9CX1NVUFBPUlRfU1RPUkUpLnB1dChibG9iLCAna2V5Jyk7XG5cbiAgICAgICAgdHhuLm9uYWJvcnQgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgLy8gSWYgdGhlIHRyYW5zYWN0aW9uIGFib3J0cyBub3cgaXRzIGR1ZSB0byBub3QgYmVpbmcgYWJsZSB0b1xuICAgICAgICAgICAgLy8gd3JpdGUgdG8gdGhlIGRhdGFiYXNlLCBsaWtlbHkgZHVlIHRvIHRoZSBkaXNrIGJlaW5nIGZ1bGxcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgfTtcblxuICAgICAgICB0eG4ub25jb21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBtYXRjaGVkQ2hyb21lID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQ2hyb21lXFwvKFxcZCspLyk7XG4gICAgICAgICAgICB2YXIgbWF0Y2hlZEVkZ2UgPSBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9FZGdlXFwvLyk7XG4gICAgICAgICAgICAvLyBNUyBFZGdlIHByZXRlbmRzIHRvIGJlIENocm9tZSA0MjpcbiAgICAgICAgICAgIC8vIGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaGg4NjkzMDElMjh2PXZzLjg1JTI5LmFzcHhcbiAgICAgICAgICAgIHJlc29sdmUobWF0Y2hlZEVkZ2UgfHwgIW1hdGNoZWRDaHJvbWUgfHwgcGFyc2VJbnQobWF0Y2hlZENocm9tZVsxXSwgMTApID49IDQzKTtcbiAgICAgICAgfTtcbiAgICB9KVtcImNhdGNoXCJdKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBlcnJvciwgc28gYXNzdW1lIHVuc3VwcG9ydGVkXG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIF9jaGVja0Jsb2JTdXBwb3J0KGlkYikge1xuICAgIGlmICh0eXBlb2Ygc3VwcG9ydHNCbG9icyA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlJDEucmVzb2x2ZShzdXBwb3J0c0Jsb2JzKTtcbiAgICB9XG4gICAgcmV0dXJuIF9jaGVja0Jsb2JTdXBwb3J0V2l0aG91dENhY2hpbmcoaWRiKS50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBzdXBwb3J0c0Jsb2JzID0gdmFsdWU7XG4gICAgICAgIHJldHVybiBzdXBwb3J0c0Jsb2JzO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBfZGVmZXJSZWFkaW5lc3MoZGJJbmZvKSB7XG4gICAgdmFyIGRiQ29udGV4dCA9IGRiQ29udGV4dHNbZGJJbmZvLm5hbWVdO1xuXG4gICAgLy8gQ3JlYXRlIGEgZGVmZXJyZWQgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBkYXRhYmFzZSBvcGVyYXRpb24uXG4gICAgdmFyIGRlZmVycmVkT3BlcmF0aW9uID0ge307XG5cbiAgICBkZWZlcnJlZE9wZXJhdGlvbi5wcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICBkZWZlcnJlZE9wZXJhdGlvbi5yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICB9KTtcblxuICAgIC8vIEVucXVldWUgdGhlIGRlZmVycmVkIG9wZXJhdGlvbi5cbiAgICBkYkNvbnRleHQuZGVmZXJyZWRPcGVyYXRpb25zLnB1c2goZGVmZXJyZWRPcGVyYXRpb24pO1xuXG4gICAgLy8gQ2hhaW4gaXRzIHByb21pc2UgdG8gdGhlIGRhdGFiYXNlIHJlYWRpbmVzcy5cbiAgICBpZiAoIWRiQ29udGV4dC5kYlJlYWR5KSB7XG4gICAgICAgIGRiQ29udGV4dC5kYlJlYWR5ID0gZGVmZXJyZWRPcGVyYXRpb24ucHJvbWlzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBkYkNvbnRleHQuZGJSZWFkeSA9IGRiQ29udGV4dC5kYlJlYWR5LnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGRlZmVycmVkT3BlcmF0aW9uLnByb21pc2U7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gX2FkdmFuY2VSZWFkaW5lc3MoZGJJbmZvKSB7XG4gICAgdmFyIGRiQ29udGV4dCA9IGRiQ29udGV4dHNbZGJJbmZvLm5hbWVdO1xuXG4gICAgLy8gRGVxdWV1ZSBhIGRlZmVycmVkIG9wZXJhdGlvbi5cbiAgICB2YXIgZGVmZXJyZWRPcGVyYXRpb24gPSBkYkNvbnRleHQuZGVmZXJyZWRPcGVyYXRpb25zLnBvcCgpO1xuXG4gICAgLy8gUmVzb2x2ZSBpdHMgcHJvbWlzZSAod2hpY2ggaXMgcGFydCBvZiB0aGUgZGF0YWJhc2UgcmVhZGluZXNzXG4gICAgLy8gY2hhaW4gb2YgcHJvbWlzZXMpLlxuICAgIGlmIChkZWZlcnJlZE9wZXJhdGlvbikge1xuICAgICAgICBkZWZlcnJlZE9wZXJhdGlvbi5yZXNvbHZlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBfZ2V0Q29ubmVjdGlvbihkYkluZm8sIHVwZ3JhZGVOZWVkZWQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG5cbiAgICAgICAgaWYgKGRiSW5mby5kYikge1xuICAgICAgICAgICAgaWYgKHVwZ3JhZGVOZWVkZWQpIHtcbiAgICAgICAgICAgICAgICBfZGVmZXJSZWFkaW5lc3MoZGJJbmZvKTtcbiAgICAgICAgICAgICAgICBkYkluZm8uZGIuY2xvc2UoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoZGJJbmZvLmRiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBkYkFyZ3MgPSBbZGJJbmZvLm5hbWVdO1xuXG4gICAgICAgIGlmICh1cGdyYWRlTmVlZGVkKSB7XG4gICAgICAgICAgICBkYkFyZ3MucHVzaChkYkluZm8udmVyc2lvbik7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgb3BlbnJlcSA9IGlkYi5vcGVuLmFwcGx5KGlkYiwgZGJBcmdzKTtcblxuICAgICAgICBpZiAodXBncmFkZU5lZWRlZCkge1xuICAgICAgICAgICAgb3BlbnJlcS5vbnVwZ3JhZGVuZWVkZWQgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIHZhciBkYiA9IG9wZW5yZXEucmVzdWx0O1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGRiLmNyZWF0ZU9iamVjdFN0b3JlKGRiSW5mby5zdG9yZU5hbWUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZS5vbGRWZXJzaW9uIDw9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZGVkIHdoZW4gc3VwcG9ydCBmb3IgYmxvYiBzaGltcyB3YXMgYWRkZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIGRiLmNyZWF0ZU9iamVjdFN0b3JlKERFVEVDVF9CTE9CX1NVUFBPUlRfU1RPUkUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV4Lm5hbWUgPT09ICdDb25zdHJhaW50RXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1RoZSBkYXRhYmFzZSBcIicgKyBkYkluZm8ubmFtZSArICdcIicgKyAnIGhhcyBiZWVuIHVwZ3JhZGVkIGZyb20gdmVyc2lvbiAnICsgZS5vbGRWZXJzaW9uICsgJyB0byB2ZXJzaW9uICcgKyBlLm5ld1ZlcnNpb24gKyAnLCBidXQgdGhlIHN0b3JhZ2UgXCInICsgZGJJbmZvLnN0b3JlTmFtZSArICdcIiBhbHJlYWR5IGV4aXN0cy4nKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGV4O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIG9wZW5yZXEub25lcnJvciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICByZWplY3Qob3BlbnJlcS5lcnJvcik7XG4gICAgICAgIH07XG5cbiAgICAgICAgb3BlbnJlcS5vbnN1Y2Nlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXNvbHZlKG9wZW5yZXEucmVzdWx0KTtcbiAgICAgICAgICAgIF9hZHZhbmNlUmVhZGluZXNzKGRiSW5mbyk7XG4gICAgICAgIH07XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIF9nZXRPcmlnaW5hbENvbm5lY3Rpb24oZGJJbmZvKSB7XG4gICAgcmV0dXJuIF9nZXRDb25uZWN0aW9uKGRiSW5mbywgZmFsc2UpO1xufVxuXG5mdW5jdGlvbiBfZ2V0VXBncmFkZWRDb25uZWN0aW9uKGRiSW5mbykge1xuICAgIHJldHVybiBfZ2V0Q29ubmVjdGlvbihkYkluZm8sIHRydWUpO1xufVxuXG5mdW5jdGlvbiBfaXNVcGdyYWRlTmVlZGVkKGRiSW5mbywgZGVmYXVsdFZlcnNpb24pIHtcbiAgICBpZiAoIWRiSW5mby5kYikge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgaXNOZXdTdG9yZSA9ICFkYkluZm8uZGIub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhkYkluZm8uc3RvcmVOYW1lKTtcbiAgICB2YXIgaXNEb3duZ3JhZGUgPSBkYkluZm8udmVyc2lvbiA8IGRiSW5mby5kYi52ZXJzaW9uO1xuICAgIHZhciBpc1VwZ3JhZGUgPSBkYkluZm8udmVyc2lvbiA+IGRiSW5mby5kYi52ZXJzaW9uO1xuXG4gICAgaWYgKGlzRG93bmdyYWRlKSB7XG4gICAgICAgIC8vIElmIHRoZSB2ZXJzaW9uIGlzIG5vdCB0aGUgZGVmYXVsdCBvbmVcbiAgICAgICAgLy8gdGhlbiB3YXJuIGZvciBpbXBvc3NpYmxlIGRvd25ncmFkZS5cbiAgICAgICAgaWYgKGRiSW5mby52ZXJzaW9uICE9PSBkZWZhdWx0VmVyc2lvbikge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdUaGUgZGF0YWJhc2UgXCInICsgZGJJbmZvLm5hbWUgKyAnXCInICsgJyBjYW5cXCd0IGJlIGRvd25ncmFkZWQgZnJvbSB2ZXJzaW9uICcgKyBkYkluZm8uZGIudmVyc2lvbiArICcgdG8gdmVyc2lvbiAnICsgZGJJbmZvLnZlcnNpb24gKyAnLicpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEFsaWduIHRoZSB2ZXJzaW9ucyB0byBwcmV2ZW50IGVycm9ycy5cbiAgICAgICAgZGJJbmZvLnZlcnNpb24gPSBkYkluZm8uZGIudmVyc2lvbjtcbiAgICB9XG5cbiAgICBpZiAoaXNVcGdyYWRlIHx8IGlzTmV3U3RvcmUpIHtcbiAgICAgICAgLy8gSWYgdGhlIHN0b3JlIGlzIG5ldyB0aGVuIGluY3JlbWVudCB0aGUgdmVyc2lvbiAoaWYgbmVlZGVkKS5cbiAgICAgICAgLy8gVGhpcyB3aWxsIHRyaWdnZXIgYW4gXCJ1cGdyYWRlbmVlZGVkXCIgZXZlbnQgd2hpY2ggaXMgcmVxdWlyZWRcbiAgICAgICAgLy8gZm9yIGNyZWF0aW5nIGEgc3RvcmUuXG4gICAgICAgIGlmIChpc05ld1N0b3JlKSB7XG4gICAgICAgICAgICB2YXIgaW5jVmVyc2lvbiA9IGRiSW5mby5kYi52ZXJzaW9uICsgMTtcbiAgICAgICAgICAgIGlmIChpbmNWZXJzaW9uID4gZGJJbmZvLnZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBkYkluZm8udmVyc2lvbiA9IGluY1ZlcnNpb247XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8vIGVuY29kZSBhIGJsb2IgZm9yIGluZGV4ZWRkYiBlbmdpbmVzIHRoYXQgZG9uJ3Qgc3VwcG9ydCBibG9ic1xuZnVuY3Rpb24gX2VuY29kZUJsb2IoYmxvYikge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICAgIHJlYWRlci5vbmVycm9yID0gcmVqZWN0O1xuICAgICAgICByZWFkZXIub25sb2FkZW5kID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIHZhciBiYXNlNjQgPSBidG9hKGUudGFyZ2V0LnJlc3VsdCB8fCAnJyk7XG4gICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICBfX2xvY2FsX2ZvcmFnZV9lbmNvZGVkX2Jsb2I6IHRydWUsXG4gICAgICAgICAgICAgICAgZGF0YTogYmFzZTY0LFxuICAgICAgICAgICAgICAgIHR5cGU6IGJsb2IudHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIHJlYWRlci5yZWFkQXNCaW5hcnlTdHJpbmcoYmxvYik7XG4gICAgfSk7XG59XG5cbi8vIGRlY29kZSBhbiBlbmNvZGVkIGJsb2JcbmZ1bmN0aW9uIF9kZWNvZGVCbG9iKGVuY29kZWRCbG9iKSB7XG4gICAgdmFyIGFycmF5QnVmZiA9IF9iaW5TdHJpbmdUb0FycmF5QnVmZmVyKGF0b2IoZW5jb2RlZEJsb2IuZGF0YSkpO1xuICAgIHJldHVybiBjcmVhdGVCbG9iKFthcnJheUJ1ZmZdLCB7IHR5cGU6IGVuY29kZWRCbG9iLnR5cGUgfSk7XG59XG5cbi8vIGlzIHRoaXMgb25lIG9mIG91ciBmYW5jeSBlbmNvZGVkIGJsb2JzP1xuZnVuY3Rpb24gX2lzRW5jb2RlZEJsb2IodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgJiYgdmFsdWUuX19sb2NhbF9mb3JhZ2VfZW5jb2RlZF9ibG9iO1xufVxuXG4vLyBTcGVjaWFsaXplIHRoZSBkZWZhdWx0IGByZWFkeSgpYCBmdW5jdGlvbiBieSBtYWtpbmcgaXQgZGVwZW5kZW50XG4vLyBvbiB0aGUgY3VycmVudCBkYXRhYmFzZSBvcGVyYXRpb25zLiBUaHVzLCB0aGUgZHJpdmVyIHdpbGwgYmUgYWN0dWFsbHlcbi8vIHJlYWR5IHdoZW4gaXQncyBiZWVuIGluaXRpYWxpemVkIChkZWZhdWx0KSAqYW5kKiB0aGVyZSBhcmUgbm8gcGVuZGluZ1xuLy8gb3BlcmF0aW9ucyBvbiB0aGUgZGF0YWJhc2UgKGluaXRpYXRlZCBieSBzb21lIG90aGVyIGluc3RhbmNlcykuXG5mdW5jdGlvbiBfZnVsbHlSZWFkeShjYWxsYmFjaykge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBwcm9taXNlID0gc2VsZi5faW5pdFJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkYkNvbnRleHQgPSBkYkNvbnRleHRzW3NlbGYuX2RiSW5mby5uYW1lXTtcblxuICAgICAgICBpZiAoZGJDb250ZXh0ICYmIGRiQ29udGV4dC5kYlJlYWR5KSB7XG4gICAgICAgICAgICByZXR1cm4gZGJDb250ZXh0LmRiUmVhZHk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGV4ZWN1dGVUd29DYWxsYmFja3MocHJvbWlzZSwgY2FsbGJhY2ssIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuLy8gT3BlbiB0aGUgSW5kZXhlZERCIGRhdGFiYXNlIChhdXRvbWF0aWNhbGx5IGNyZWF0ZXMgb25lIGlmIG9uZSBkaWRuJ3Rcbi8vIHByZXZpb3VzbHkgZXhpc3QpLCB1c2luZyBhbnkgb3B0aW9ucyBzZXQgaW4gdGhlIGNvbmZpZy5cbmZ1bmN0aW9uIF9pbml0U3RvcmFnZShvcHRpb25zKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHZhciBkYkluZm8gPSB7XG4gICAgICAgIGRiOiBudWxsXG4gICAgfTtcblxuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICAgIGZvciAodmFyIGkgaW4gb3B0aW9ucykge1xuICAgICAgICAgICAgZGJJbmZvW2ldID0gb3B0aW9uc1tpXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEluaXRpYWxpemUgYSBzaW5nbGV0b24gY29udGFpbmVyIGZvciBhbGwgcnVubmluZyBsb2NhbEZvcmFnZXMuXG4gICAgaWYgKCFkYkNvbnRleHRzKSB7XG4gICAgICAgIGRiQ29udGV4dHMgPSB7fTtcbiAgICB9XG5cbiAgICAvLyBHZXQgdGhlIGN1cnJlbnQgY29udGV4dCBvZiB0aGUgZGF0YWJhc2U7XG4gICAgdmFyIGRiQ29udGV4dCA9IGRiQ29udGV4dHNbZGJJbmZvLm5hbWVdO1xuXG4gICAgLy8gLi4ub3IgY3JlYXRlIGEgbmV3IGNvbnRleHQuXG4gICAgaWYgKCFkYkNvbnRleHQpIHtcbiAgICAgICAgZGJDb250ZXh0ID0ge1xuICAgICAgICAgICAgLy8gUnVubmluZyBsb2NhbEZvcmFnZXMgc2hhcmluZyBhIGRhdGFiYXNlLlxuICAgICAgICAgICAgZm9yYWdlczogW10sXG4gICAgICAgICAgICAvLyBTaGFyZWQgZGF0YWJhc2UuXG4gICAgICAgICAgICBkYjogbnVsbCxcbiAgICAgICAgICAgIC8vIERhdGFiYXNlIHJlYWRpbmVzcyAocHJvbWlzZSkuXG4gICAgICAgICAgICBkYlJlYWR5OiBudWxsLFxuICAgICAgICAgICAgLy8gRGVmZXJyZWQgb3BlcmF0aW9ucyBvbiB0aGUgZGF0YWJhc2UuXG4gICAgICAgICAgICBkZWZlcnJlZE9wZXJhdGlvbnM6IFtdXG4gICAgICAgIH07XG4gICAgICAgIC8vIFJlZ2lzdGVyIHRoZSBuZXcgY29udGV4dCBpbiB0aGUgZ2xvYmFsIGNvbnRhaW5lci5cbiAgICAgICAgZGJDb250ZXh0c1tkYkluZm8ubmFtZV0gPSBkYkNvbnRleHQ7XG4gICAgfVxuXG4gICAgLy8gUmVnaXN0ZXIgaXRzZWxmIGFzIGEgcnVubmluZyBsb2NhbEZvcmFnZSBpbiB0aGUgY3VycmVudCBjb250ZXh0LlxuICAgIGRiQ29udGV4dC5mb3JhZ2VzLnB1c2goc2VsZik7XG5cbiAgICAvLyBSZXBsYWNlIHRoZSBkZWZhdWx0IGByZWFkeSgpYCBmdW5jdGlvbiB3aXRoIHRoZSBzcGVjaWFsaXplZCBvbmUuXG4gICAgaWYgKCFzZWxmLl9pbml0UmVhZHkpIHtcbiAgICAgICAgc2VsZi5faW5pdFJlYWR5ID0gc2VsZi5yZWFkeTtcbiAgICAgICAgc2VsZi5yZWFkeSA9IF9mdWxseVJlYWR5O1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBhbiBhcnJheSBvZiBpbml0aWFsaXphdGlvbiBzdGF0ZXMgb2YgdGhlIHJlbGF0ZWQgbG9jYWxGb3JhZ2VzLlxuICAgIHZhciBpbml0UHJvbWlzZXMgPSBbXTtcblxuICAgIGZ1bmN0aW9uIGlnbm9yZUVycm9ycygpIHtcbiAgICAgICAgLy8gRG9uJ3QgaGFuZGxlIGVycm9ycyBoZXJlLFxuICAgICAgICAvLyBqdXN0IG1ha2VzIHN1cmUgcmVsYXRlZCBsb2NhbEZvcmFnZXMgYXJlbid0IHBlbmRpbmcuXG4gICAgICAgIHJldHVybiBQcm9taXNlJDEucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgZGJDb250ZXh0LmZvcmFnZXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgdmFyIGZvcmFnZSA9IGRiQ29udGV4dC5mb3JhZ2VzW2pdO1xuICAgICAgICBpZiAoZm9yYWdlICE9PSBzZWxmKSB7XG4gICAgICAgICAgICAvLyBEb24ndCB3YWl0IGZvciBpdHNlbGYuLi5cbiAgICAgICAgICAgIGluaXRQcm9taXNlcy5wdXNoKGZvcmFnZS5faW5pdFJlYWR5KClbXCJjYXRjaFwiXShpZ25vcmVFcnJvcnMpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRha2UgYSBzbmFwc2hvdCBvZiB0aGUgcmVsYXRlZCBsb2NhbEZvcmFnZXMuXG4gICAgdmFyIGZvcmFnZXMgPSBkYkNvbnRleHQuZm9yYWdlcy5zbGljZSgwKTtcblxuICAgIC8vIEluaXRpYWxpemUgdGhlIGNvbm5lY3Rpb24gcHJvY2VzcyBvbmx5IHdoZW5cbiAgICAvLyBhbGwgdGhlIHJlbGF0ZWQgbG9jYWxGb3JhZ2VzIGFyZW4ndCBwZW5kaW5nLlxuICAgIHJldHVybiBQcm9taXNlJDEuYWxsKGluaXRQcm9taXNlcykudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRiSW5mby5kYiA9IGRiQ29udGV4dC5kYjtcbiAgICAgICAgLy8gR2V0IHRoZSBjb25uZWN0aW9uIG9yIG9wZW4gYSBuZXcgb25lIHdpdGhvdXQgdXBncmFkZS5cbiAgICAgICAgcmV0dXJuIF9nZXRPcmlnaW5hbENvbm5lY3Rpb24oZGJJbmZvKTtcbiAgICB9KS50aGVuKGZ1bmN0aW9uIChkYikge1xuICAgICAgICBkYkluZm8uZGIgPSBkYjtcbiAgICAgICAgaWYgKF9pc1VwZ3JhZGVOZWVkZWQoZGJJbmZvLCBzZWxmLl9kZWZhdWx0Q29uZmlnLnZlcnNpb24pKSB7XG4gICAgICAgICAgICAvLyBSZW9wZW4gdGhlIGRhdGFiYXNlIGZvciB1cGdyYWRpbmcuXG4gICAgICAgICAgICByZXR1cm4gX2dldFVwZ3JhZGVkQ29ubmVjdGlvbihkYkluZm8pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkYjtcbiAgICB9KS50aGVuKGZ1bmN0aW9uIChkYikge1xuICAgICAgICBkYkluZm8uZGIgPSBkYkNvbnRleHQuZGIgPSBkYjtcbiAgICAgICAgc2VsZi5fZGJJbmZvID0gZGJJbmZvO1xuICAgICAgICAvLyBTaGFyZSB0aGUgZmluYWwgY29ubmVjdGlvbiBhbW9uZ3N0IHJlbGF0ZWQgbG9jYWxGb3JhZ2VzLlxuICAgICAgICBmb3IgKHZhciBrID0gMDsgayA8IGZvcmFnZXMubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICAgIHZhciBmb3JhZ2UgPSBmb3JhZ2VzW2tdO1xuICAgICAgICAgICAgaWYgKGZvcmFnZSAhPT0gc2VsZikge1xuICAgICAgICAgICAgICAgIC8vIFNlbGYgaXMgYWxyZWFkeSB1cC10by1kYXRlLlxuICAgICAgICAgICAgICAgIGZvcmFnZS5fZGJJbmZvLmRiID0gZGJJbmZvLmRiO1xuICAgICAgICAgICAgICAgIGZvcmFnZS5fZGJJbmZvLnZlcnNpb24gPSBkYkluZm8udmVyc2lvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBnZXRJdGVtKGtleSwgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAvLyBDYXN0IHRoZSBrZXkgdG8gYSBzdHJpbmcsIGFzIHRoYXQncyBhbGwgd2UgY2FuIHNldCBhcyBhIGtleS5cbiAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGtleSArICcgdXNlZCBhcyBhIGtleSwgYnV0IGl0IGlzIG5vdCBhIHN0cmluZy4nKTtcbiAgICAgICAga2V5ID0gU3RyaW5nKGtleSk7XG4gICAgfVxuXG4gICAgdmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgc2VsZi5yZWFkeSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgICAgIHZhciBzdG9yZSA9IGRiSW5mby5kYi50cmFuc2FjdGlvbihkYkluZm8uc3RvcmVOYW1lLCAncmVhZG9ubHknKS5vYmplY3RTdG9yZShkYkluZm8uc3RvcmVOYW1lKTtcbiAgICAgICAgICAgIHZhciByZXEgPSBzdG9yZS5nZXQoa2V5KTtcblxuICAgICAgICAgICAgcmVxLm9uc3VjY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSByZXEucmVzdWx0O1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKF9pc0VuY29kZWRCbG9iKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IF9kZWNvZGVCbG9iKHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh2YWx1ZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXEub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZWplY3QocmVxLmVycm9yKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbi8vIEl0ZXJhdGUgb3ZlciBhbGwgaXRlbXMgc3RvcmVkIGluIGRhdGFiYXNlLlxuZnVuY3Rpb24gaXRlcmF0ZShpdGVyYXRvciwgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgZGJJbmZvID0gc2VsZi5fZGJJbmZvO1xuICAgICAgICAgICAgdmFyIHN0b3JlID0gZGJJbmZvLmRiLnRyYW5zYWN0aW9uKGRiSW5mby5zdG9yZU5hbWUsICdyZWFkb25seScpLm9iamVjdFN0b3JlKGRiSW5mby5zdG9yZU5hbWUpO1xuXG4gICAgICAgICAgICB2YXIgcmVxID0gc3RvcmUub3BlbkN1cnNvcigpO1xuICAgICAgICAgICAgdmFyIGl0ZXJhdGlvbk51bWJlciA9IDE7XG5cbiAgICAgICAgICAgIHJlcS5vbnN1Y2Nlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnNvciA9IHJlcS5yZXN1bHQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoY3Vyc29yKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IGN1cnNvci52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc0VuY29kZWRCbG9iKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBfZGVjb2RlQmxvYih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGl0ZXJhdG9yKHZhbHVlLCBjdXJzb3Iua2V5LCBpdGVyYXRpb25OdW1iZXIrKyk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPT0gdm9pZCAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJzb3JbXCJjb250aW51ZVwiXSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHJlcS5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChyZXEuZXJyb3IpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSlbXCJjYXRjaFwiXShyZWplY3QpO1xuICAgIH0pO1xuXG4gICAgZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKTtcblxuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5mdW5jdGlvbiBzZXRJdGVtKGtleSwgdmFsdWUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgLy8gQ2FzdCB0aGUga2V5IHRvIGEgc3RyaW5nLCBhcyB0aGF0J3MgYWxsIHdlIGNhbiBzZXQgYXMgYSBrZXkuXG4gICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihrZXkgKyAnIHVzZWQgYXMgYSBrZXksIGJ1dCBpdCBpcyBub3QgYSBzdHJpbmcuJyk7XG4gICAgICAgIGtleSA9IFN0cmluZyhrZXkpO1xuICAgIH1cblxuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHZhciBkYkluZm87XG4gICAgICAgIHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgICAgIGlmICh0b1N0cmluZy5jYWxsKHZhbHVlKSA9PT0gJ1tvYmplY3QgQmxvYl0nKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jaGVja0Jsb2JTdXBwb3J0KGRiSW5mby5kYikudGhlbihmdW5jdGlvbiAoYmxvYlN1cHBvcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJsb2JTdXBwb3J0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9lbmNvZGVCbG9iKHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSkudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIHZhciB0cmFuc2FjdGlvbiA9IGRiSW5mby5kYi50cmFuc2FjdGlvbihkYkluZm8uc3RvcmVOYW1lLCAncmVhZHdyaXRlJyk7XG4gICAgICAgICAgICB2YXIgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZShkYkluZm8uc3RvcmVOYW1lKTtcbiAgICAgICAgICAgIHZhciByZXEgPSBzdG9yZS5wdXQodmFsdWUsIGtleSk7XG5cbiAgICAgICAgICAgIC8vIFRoZSByZWFzb24gd2UgZG9uJ3QgX3NhdmVfIG51bGwgaXMgYmVjYXVzZSBJRSAxMCBkb2VzXG4gICAgICAgICAgICAvLyBub3Qgc3VwcG9ydCBzYXZpbmcgdGhlIGBudWxsYCB0eXBlIGluIEluZGV4ZWREQi4gSG93XG4gICAgICAgICAgICAvLyBpcm9uaWMsIGdpdmVuIHRoZSBidWcgYmVsb3chXG4gICAgICAgICAgICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9tb3ppbGxhL2xvY2FsRm9yYWdlL2lzc3Vlcy8xNjFcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0cmFuc2FjdGlvbi5vbmNvbXBsZXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIC8vIENhc3QgdG8gdW5kZWZpbmVkIHNvIHRoZSB2YWx1ZSBwYXNzZWQgdG9cbiAgICAgICAgICAgICAgICAvLyBjYWxsYmFjay9wcm9taXNlIGlzIHRoZSBzYW1lIGFzIHdoYXQgb25lIHdvdWxkIGdldCBvdXRcbiAgICAgICAgICAgICAgICAvLyBvZiBgZ2V0SXRlbSgpYCBsYXRlci4gVGhpcyBsZWFkcyB0byBzb21lIHdlaXJkbmVzc1xuICAgICAgICAgICAgICAgIC8vIChzZXRJdGVtKCdmb28nLCB1bmRlZmluZWQpIHdpbGwgcmV0dXJuIGBudWxsYCksIGJ1dFxuICAgICAgICAgICAgICAgIC8vIGl0J3Mgbm90IG15IGZhdWx0IGxvY2FsU3RvcmFnZSBpcyBvdXIgYmFzZWxpbmUgYW5kIHRoYXRcbiAgICAgICAgICAgICAgICAvLyBpdCdzIHdlaXJkLlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0cmFuc2FjdGlvbi5vbmFib3J0ID0gdHJhbnNhY3Rpb24ub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXJyID0gcmVxLmVycm9yID8gcmVxLmVycm9yIDogcmVxLnRyYW5zYWN0aW9uLmVycm9yO1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSlbXCJjYXRjaFwiXShyZWplY3QpO1xuICAgIH0pO1xuXG4gICAgZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlSXRlbShrZXksIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgLy8gQ2FzdCB0aGUga2V5IHRvIGEgc3RyaW5nLCBhcyB0aGF0J3MgYWxsIHdlIGNhbiBzZXQgYXMgYSBrZXkuXG4gICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihrZXkgKyAnIHVzZWQgYXMgYSBrZXksIGJ1dCBpdCBpcyBub3QgYSBzdHJpbmcuJyk7XG4gICAgICAgIGtleSA9IFN0cmluZyhrZXkpO1xuICAgIH1cblxuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgICAgICB2YXIgdHJhbnNhY3Rpb24gPSBkYkluZm8uZGIudHJhbnNhY3Rpb24oZGJJbmZvLnN0b3JlTmFtZSwgJ3JlYWR3cml0ZScpO1xuICAgICAgICAgICAgdmFyIHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUoZGJJbmZvLnN0b3JlTmFtZSk7XG5cbiAgICAgICAgICAgIC8vIFdlIHVzZSBhIEdydW50IHRhc2sgdG8gbWFrZSB0aGlzIHNhZmUgZm9yIElFIGFuZCBzb21lXG4gICAgICAgICAgICAvLyB2ZXJzaW9ucyBvZiBBbmRyb2lkIChpbmNsdWRpbmcgdGhvc2UgdXNlZCBieSBDb3Jkb3ZhKS5cbiAgICAgICAgICAgIC8vIE5vcm1hbGx5IElFIHdvbid0IGxpa2UgYC5kZWxldGUoKWAgYW5kIHdpbGwgaW5zaXN0IG9uXG4gICAgICAgICAgICAvLyB1c2luZyBgWydkZWxldGUnXSgpYCwgYnV0IHdlIGhhdmUgYSBidWlsZCBzdGVwIHRoYXRcbiAgICAgICAgICAgIC8vIGZpeGVzIHRoaXMgZm9yIHVzIG5vdy5cbiAgICAgICAgICAgIHZhciByZXEgPSBzdG9yZVtcImRlbGV0ZVwiXShrZXkpO1xuICAgICAgICAgICAgdHJhbnNhY3Rpb24ub25jb21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0cmFuc2FjdGlvbi5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChyZXEuZXJyb3IpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gVGhlIHJlcXVlc3Qgd2lsbCBiZSBhbHNvIGJlIGFib3J0ZWQgaWYgd2UndmUgZXhjZWVkZWQgb3VyIHN0b3JhZ2VcbiAgICAgICAgICAgIC8vIHNwYWNlLlxuICAgICAgICAgICAgdHJhbnNhY3Rpb24ub25hYm9ydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXJyID0gcmVxLmVycm9yID8gcmVxLmVycm9yIDogcmVxLnRyYW5zYWN0aW9uLmVycm9yO1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSlbXCJjYXRjaFwiXShyZWplY3QpO1xuICAgIH0pO1xuXG4gICAgZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuZnVuY3Rpb24gY2xlYXIoY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgZGJJbmZvID0gc2VsZi5fZGJJbmZvO1xuICAgICAgICAgICAgdmFyIHRyYW5zYWN0aW9uID0gZGJJbmZvLmRiLnRyYW5zYWN0aW9uKGRiSW5mby5zdG9yZU5hbWUsICdyZWFkd3JpdGUnKTtcbiAgICAgICAgICAgIHZhciBzdG9yZSA9IHRyYW5zYWN0aW9uLm9iamVjdFN0b3JlKGRiSW5mby5zdG9yZU5hbWUpO1xuICAgICAgICAgICAgdmFyIHJlcSA9IHN0b3JlLmNsZWFyKCk7XG5cbiAgICAgICAgICAgIHRyYW5zYWN0aW9uLm9uY29tcGxldGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdHJhbnNhY3Rpb24ub25hYm9ydCA9IHRyYW5zYWN0aW9uLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVyciA9IHJlcS5lcnJvciA/IHJlcS5lcnJvciA6IHJlcS50cmFuc2FjdGlvbi5lcnJvcjtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbmZ1bmN0aW9uIGxlbmd0aChjYWxsYmFjaykge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgICAgICB2YXIgc3RvcmUgPSBkYkluZm8uZGIudHJhbnNhY3Rpb24oZGJJbmZvLnN0b3JlTmFtZSwgJ3JlYWRvbmx5Jykub2JqZWN0U3RvcmUoZGJJbmZvLnN0b3JlTmFtZSk7XG4gICAgICAgICAgICB2YXIgcmVxID0gc3RvcmUuY291bnQoKTtcblxuICAgICAgICAgICAgcmVxLm9uc3VjY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHJlcS5yZXN1bHQpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmVxLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KHJlcS5lcnJvcik7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KVtcImNhdGNoXCJdKHJlamVjdCk7XG4gICAgfSk7XG5cbiAgICBleGVjdXRlQ2FsbGJhY2socHJvbWlzZSwgY2FsbGJhY2spO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5mdW5jdGlvbiBrZXkobiwgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBpZiAobiA8IDApIHtcbiAgICAgICAgICAgIHJlc29sdmUobnVsbCk7XG5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgICAgICB2YXIgc3RvcmUgPSBkYkluZm8uZGIudHJhbnNhY3Rpb24oZGJJbmZvLnN0b3JlTmFtZSwgJ3JlYWRvbmx5Jykub2JqZWN0U3RvcmUoZGJJbmZvLnN0b3JlTmFtZSk7XG5cbiAgICAgICAgICAgIHZhciBhZHZhbmNlZCA9IGZhbHNlO1xuICAgICAgICAgICAgdmFyIHJlcSA9IHN0b3JlLm9wZW5DdXJzb3IoKTtcbiAgICAgICAgICAgIHJlcS5vbnN1Y2Nlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnNvciA9IHJlcS5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgaWYgKCFjdXJzb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBtZWFucyB0aGVyZSB3ZXJlbid0IGVub3VnaCBrZXlzXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobnVsbCk7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChuID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdlIGhhdmUgdGhlIGZpcnN0IGtleSwgcmV0dXJuIGl0IGlmIHRoYXQncyB3aGF0IHRoZXlcbiAgICAgICAgICAgICAgICAgICAgLy8gd2FudGVkLlxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGN1cnNvci5rZXkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghYWR2YW5jZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSwgYXNrIHRoZSBjdXJzb3IgdG8gc2tpcCBhaGVhZCBuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyByZWNvcmRzLlxuICAgICAgICAgICAgICAgICAgICAgICAgYWR2YW5jZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3Vyc29yLmFkdmFuY2Uobik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHdlIGdldCBoZXJlLCB3ZSd2ZSBnb3QgdGhlIG50aCBrZXkuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGN1cnNvci5rZXkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmVxLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KHJlcS5lcnJvcik7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KVtcImNhdGNoXCJdKHJlamVjdCk7XG4gICAgfSk7XG5cbiAgICBleGVjdXRlQ2FsbGJhY2socHJvbWlzZSwgY2FsbGJhY2spO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5mdW5jdGlvbiBrZXlzKGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgc2VsZi5yZWFkeSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgICAgIHZhciBzdG9yZSA9IGRiSW5mby5kYi50cmFuc2FjdGlvbihkYkluZm8uc3RvcmVOYW1lLCAncmVhZG9ubHknKS5vYmplY3RTdG9yZShkYkluZm8uc3RvcmVOYW1lKTtcblxuICAgICAgICAgICAgdmFyIHJlcSA9IHN0b3JlLm9wZW5DdXJzb3IoKTtcbiAgICAgICAgICAgIHZhciBrZXlzID0gW107XG5cbiAgICAgICAgICAgIHJlcS5vbnN1Y2Nlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnNvciA9IHJlcS5yZXN1bHQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoIWN1cnNvcikge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGtleXMpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAga2V5cy5wdXNoKGN1cnNvci5rZXkpO1xuICAgICAgICAgICAgICAgIGN1cnNvcltcImNvbnRpbnVlXCJdKCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXEub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZWplY3QocmVxLmVycm9yKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbnZhciBhc3luY1N0b3JhZ2UgPSB7XG4gICAgX2RyaXZlcjogJ2FzeW5jU3RvcmFnZScsXG4gICAgX2luaXRTdG9yYWdlOiBfaW5pdFN0b3JhZ2UsXG4gICAgaXRlcmF0ZTogaXRlcmF0ZSxcbiAgICBnZXRJdGVtOiBnZXRJdGVtLFxuICAgIHNldEl0ZW06IHNldEl0ZW0sXG4gICAgcmVtb3ZlSXRlbTogcmVtb3ZlSXRlbSxcbiAgICBjbGVhcjogY2xlYXIsXG4gICAgbGVuZ3RoOiBsZW5ndGgsXG4gICAga2V5OiBrZXksXG4gICAga2V5czoga2V5c1xufTtcblxuLy8gU2FkbHksIHRoZSBiZXN0IHdheSB0byBzYXZlIGJpbmFyeSBkYXRhIGluIFdlYlNRTC9sb2NhbFN0b3JhZ2UgaXMgc2VyaWFsaXppbmdcbi8vIGl0IHRvIEJhc2U2NCwgc28gdGhpcyBpcyBob3cgd2Ugc3RvcmUgaXQgdG8gcHJldmVudCB2ZXJ5IHN0cmFuZ2UgZXJyb3JzIHdpdGggbGVzc1xuLy8gdmVyYm9zZSB3YXlzIG9mIGJpbmFyeSA8LT4gc3RyaW5nIGRhdGEgc3RvcmFnZS5cbnZhciBCQVNFX0NIQVJTID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXG52YXIgQkxPQl9UWVBFX1BSRUZJWCA9ICd+fmxvY2FsX2ZvcmFnZV90eXBlfic7XG52YXIgQkxPQl9UWVBFX1BSRUZJWF9SRUdFWCA9IC9efn5sb2NhbF9mb3JhZ2VfdHlwZX4oW15+XSspfi87XG5cbnZhciBTRVJJQUxJWkVEX01BUktFUiA9ICdfX2xmc2NfXzonO1xudmFyIFNFUklBTElaRURfTUFSS0VSX0xFTkdUSCA9IFNFUklBTElaRURfTUFSS0VSLmxlbmd0aDtcblxuLy8gT01HIHRoZSBzZXJpYWxpemF0aW9ucyFcbnZhciBUWVBFX0FSUkFZQlVGRkVSID0gJ2FyYmYnO1xudmFyIFRZUEVfQkxPQiA9ICdibG9iJztcbnZhciBUWVBFX0lOVDhBUlJBWSA9ICdzaTA4JztcbnZhciBUWVBFX1VJTlQ4QVJSQVkgPSAndWkwOCc7XG52YXIgVFlQRV9VSU5UOENMQU1QRURBUlJBWSA9ICd1aWM4JztcbnZhciBUWVBFX0lOVDE2QVJSQVkgPSAnc2kxNic7XG52YXIgVFlQRV9JTlQzMkFSUkFZID0gJ3NpMzInO1xudmFyIFRZUEVfVUlOVDE2QVJSQVkgPSAndXIxNic7XG52YXIgVFlQRV9VSU5UMzJBUlJBWSA9ICd1aTMyJztcbnZhciBUWVBFX0ZMT0FUMzJBUlJBWSA9ICdmbDMyJztcbnZhciBUWVBFX0ZMT0FUNjRBUlJBWSA9ICdmbDY0JztcbnZhciBUWVBFX1NFUklBTElaRURfTUFSS0VSX0xFTkdUSCA9IFNFUklBTElaRURfTUFSS0VSX0xFTkdUSCArIFRZUEVfQVJSQVlCVUZGRVIubGVuZ3RoO1xuXG52YXIgdG9TdHJpbmckMSA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbmZ1bmN0aW9uIHN0cmluZ1RvQnVmZmVyKHNlcmlhbGl6ZWRTdHJpbmcpIHtcbiAgICAvLyBGaWxsIHRoZSBzdHJpbmcgaW50byBhIEFycmF5QnVmZmVyLlxuICAgIHZhciBidWZmZXJMZW5ndGggPSBzZXJpYWxpemVkU3RyaW5nLmxlbmd0aCAqIDAuNzU7XG4gICAgdmFyIGxlbiA9IHNlcmlhbGl6ZWRTdHJpbmcubGVuZ3RoO1xuICAgIHZhciBpO1xuICAgIHZhciBwID0gMDtcbiAgICB2YXIgZW5jb2RlZDEsIGVuY29kZWQyLCBlbmNvZGVkMywgZW5jb2RlZDQ7XG5cbiAgICBpZiAoc2VyaWFsaXplZFN0cmluZ1tzZXJpYWxpemVkU3RyaW5nLmxlbmd0aCAtIDFdID09PSAnPScpIHtcbiAgICAgICAgYnVmZmVyTGVuZ3RoLS07XG4gICAgICAgIGlmIChzZXJpYWxpemVkU3RyaW5nW3NlcmlhbGl6ZWRTdHJpbmcubGVuZ3RoIC0gMl0gPT09ICc9Jykge1xuICAgICAgICAgICAgYnVmZmVyTGVuZ3RoLS07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKGJ1ZmZlckxlbmd0aCk7XG4gICAgdmFyIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkgKz0gNCkge1xuICAgICAgICBlbmNvZGVkMSA9IEJBU0VfQ0hBUlMuaW5kZXhPZihzZXJpYWxpemVkU3RyaW5nW2ldKTtcbiAgICAgICAgZW5jb2RlZDIgPSBCQVNFX0NIQVJTLmluZGV4T2Yoc2VyaWFsaXplZFN0cmluZ1tpICsgMV0pO1xuICAgICAgICBlbmNvZGVkMyA9IEJBU0VfQ0hBUlMuaW5kZXhPZihzZXJpYWxpemVkU3RyaW5nW2kgKyAyXSk7XG4gICAgICAgIGVuY29kZWQ0ID0gQkFTRV9DSEFSUy5pbmRleE9mKHNlcmlhbGl6ZWRTdHJpbmdbaSArIDNdKTtcblxuICAgICAgICAvKmpzbGludCBiaXR3aXNlOiB0cnVlICovXG4gICAgICAgIGJ5dGVzW3ArK10gPSBlbmNvZGVkMSA8PCAyIHwgZW5jb2RlZDIgPj4gNDtcbiAgICAgICAgYnl0ZXNbcCsrXSA9IChlbmNvZGVkMiAmIDE1KSA8PCA0IHwgZW5jb2RlZDMgPj4gMjtcbiAgICAgICAgYnl0ZXNbcCsrXSA9IChlbmNvZGVkMyAmIDMpIDw8IDYgfCBlbmNvZGVkNCAmIDYzO1xuICAgIH1cbiAgICByZXR1cm4gYnVmZmVyO1xufVxuXG4vLyBDb252ZXJ0cyBhIGJ1ZmZlciB0byBhIHN0cmluZyB0byBzdG9yZSwgc2VyaWFsaXplZCwgaW4gdGhlIGJhY2tlbmRcbi8vIHN0b3JhZ2UgbGlicmFyeS5cbmZ1bmN0aW9uIGJ1ZmZlclRvU3RyaW5nKGJ1ZmZlcikge1xuICAgIC8vIGJhc2U2NC1hcnJheWJ1ZmZlclxuICAgIHZhciBieXRlcyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XG4gICAgdmFyIGJhc2U2NFN0cmluZyA9ICcnO1xuICAgIHZhciBpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgICAgIC8qanNsaW50IGJpdHdpc2U6IHRydWUgKi9cbiAgICAgICAgYmFzZTY0U3RyaW5nICs9IEJBU0VfQ0hBUlNbYnl0ZXNbaV0gPj4gMl07XG4gICAgICAgIGJhc2U2NFN0cmluZyArPSBCQVNFX0NIQVJTWyhieXRlc1tpXSAmIDMpIDw8IDQgfCBieXRlc1tpICsgMV0gPj4gNF07XG4gICAgICAgIGJhc2U2NFN0cmluZyArPSBCQVNFX0NIQVJTWyhieXRlc1tpICsgMV0gJiAxNSkgPDwgMiB8IGJ5dGVzW2kgKyAyXSA+PiA2XTtcbiAgICAgICAgYmFzZTY0U3RyaW5nICs9IEJBU0VfQ0hBUlNbYnl0ZXNbaSArIDJdICYgNjNdO1xuICAgIH1cblxuICAgIGlmIChieXRlcy5sZW5ndGggJSAzID09PSAyKSB7XG4gICAgICAgIGJhc2U2NFN0cmluZyA9IGJhc2U2NFN0cmluZy5zdWJzdHJpbmcoMCwgYmFzZTY0U3RyaW5nLmxlbmd0aCAtIDEpICsgJz0nO1xuICAgIH0gZWxzZSBpZiAoYnl0ZXMubGVuZ3RoICUgMyA9PT0gMSkge1xuICAgICAgICBiYXNlNjRTdHJpbmcgPSBiYXNlNjRTdHJpbmcuc3Vic3RyaW5nKDAsIGJhc2U2NFN0cmluZy5sZW5ndGggLSAyKSArICc9PSc7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJhc2U2NFN0cmluZztcbn1cblxuLy8gU2VyaWFsaXplIGEgdmFsdWUsIGFmdGVyd2FyZHMgZXhlY3V0aW5nIGEgY2FsbGJhY2sgKHdoaWNoIHVzdWFsbHlcbi8vIGluc3RydWN0cyB0aGUgYHNldEl0ZW0oKWAgY2FsbGJhY2svcHJvbWlzZSB0byBiZSBleGVjdXRlZCkuIFRoaXMgaXMgaG93XG4vLyB3ZSBzdG9yZSBiaW5hcnkgZGF0YSB3aXRoIGxvY2FsU3RvcmFnZS5cbmZ1bmN0aW9uIHNlcmlhbGl6ZSh2YWx1ZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgdmFsdWVUeXBlID0gJyc7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIHZhbHVlVHlwZSA9IHRvU3RyaW5nJDEuY2FsbCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLy8gQ2Fubm90IHVzZSBgdmFsdWUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcmAgb3Igc3VjaCBoZXJlLCBhcyB0aGVzZVxuICAgIC8vIGNoZWNrcyBmYWlsIHdoZW4gcnVubmluZyB0aGUgdGVzdHMgdXNpbmcgY2FzcGVyLmpzLi4uXG4gICAgLy9cbiAgICAvLyBUT0RPOiBTZWUgd2h5IHRob3NlIHRlc3RzIGZhaWwgYW5kIHVzZSBhIGJldHRlciBzb2x1dGlvbi5cbiAgICBpZiAodmFsdWUgJiYgKHZhbHVlVHlwZSA9PT0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyB8fCB2YWx1ZS5idWZmZXIgJiYgdG9TdHJpbmckMS5jYWxsKHZhbHVlLmJ1ZmZlcikgPT09ICdbb2JqZWN0IEFycmF5QnVmZmVyXScpKSB7XG4gICAgICAgIC8vIENvbnZlcnQgYmluYXJ5IGFycmF5cyB0byBhIHN0cmluZyBhbmQgcHJlZml4IHRoZSBzdHJpbmcgd2l0aFxuICAgICAgICAvLyBhIHNwZWNpYWwgbWFya2VyLlxuICAgICAgICB2YXIgYnVmZmVyO1xuICAgICAgICB2YXIgbWFya2VyID0gU0VSSUFMSVpFRF9NQVJLRVI7XG5cbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgICAgICAgIGJ1ZmZlciA9IHZhbHVlO1xuICAgICAgICAgICAgbWFya2VyICs9IFRZUEVfQVJSQVlCVUZGRVI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBidWZmZXIgPSB2YWx1ZS5idWZmZXI7XG5cbiAgICAgICAgICAgIGlmICh2YWx1ZVR5cGUgPT09ICdbb2JqZWN0IEludDhBcnJheV0nKSB7XG4gICAgICAgICAgICAgICAgbWFya2VyICs9IFRZUEVfSU5UOEFSUkFZO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZVR5cGUgPT09ICdbb2JqZWN0IFVpbnQ4QXJyYXldJykge1xuICAgICAgICAgICAgICAgIG1hcmtlciArPSBUWVBFX1VJTlQ4QVJSQVk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlVHlwZSA9PT0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJykge1xuICAgICAgICAgICAgICAgIG1hcmtlciArPSBUWVBFX1VJTlQ4Q0xBTVBFREFSUkFZO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZVR5cGUgPT09ICdbb2JqZWN0IEludDE2QXJyYXldJykge1xuICAgICAgICAgICAgICAgIG1hcmtlciArPSBUWVBFX0lOVDE2QVJSQVk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlVHlwZSA9PT0gJ1tvYmplY3QgVWludDE2QXJyYXldJykge1xuICAgICAgICAgICAgICAgIG1hcmtlciArPSBUWVBFX1VJTlQxNkFSUkFZO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZVR5cGUgPT09ICdbb2JqZWN0IEludDMyQXJyYXldJykge1xuICAgICAgICAgICAgICAgIG1hcmtlciArPSBUWVBFX0lOVDMyQVJSQVk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlVHlwZSA9PT0gJ1tvYmplY3QgVWludDMyQXJyYXldJykge1xuICAgICAgICAgICAgICAgIG1hcmtlciArPSBUWVBFX1VJTlQzMkFSUkFZO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZVR5cGUgPT09ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nKSB7XG4gICAgICAgICAgICAgICAgbWFya2VyICs9IFRZUEVfRkxPQVQzMkFSUkFZO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZVR5cGUgPT09ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nKSB7XG4gICAgICAgICAgICAgICAgbWFya2VyICs9IFRZUEVfRkxPQVQ2NEFSUkFZO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhuZXcgRXJyb3IoJ0ZhaWxlZCB0byBnZXQgdHlwZSBmb3IgQmluYXJ5QXJyYXknKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjYWxsYmFjayhtYXJrZXIgKyBidWZmZXJUb1N0cmluZyhidWZmZXIpKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlVHlwZSA9PT0gJ1tvYmplY3QgQmxvYl0nKSB7XG4gICAgICAgIC8vIENvbnZlciB0aGUgYmxvYiB0byBhIGJpbmFyeUFycmF5IGFuZCB0aGVuIHRvIGEgc3RyaW5nLlxuICAgICAgICB2YXIgZmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG5cbiAgICAgICAgZmlsZVJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBCYWNrd2FyZHMtY29tcGF0aWJsZSBwcmVmaXggZm9yIHRoZSBibG9iIHR5cGUuXG4gICAgICAgICAgICB2YXIgc3RyID0gQkxPQl9UWVBFX1BSRUZJWCArIHZhbHVlLnR5cGUgKyAnficgKyBidWZmZXJUb1N0cmluZyh0aGlzLnJlc3VsdCk7XG5cbiAgICAgICAgICAgIGNhbGxiYWNrKFNFUklBTElaRURfTUFSS0VSICsgVFlQRV9CTE9CICsgc3RyKTtcbiAgICAgICAgfTtcblxuICAgICAgICBmaWxlUmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY2FsbGJhY2soSlNPTi5zdHJpbmdpZnkodmFsdWUpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkNvdWxkbid0IGNvbnZlcnQgdmFsdWUgaW50byBhIEpTT04gc3RyaW5nOiBcIiwgdmFsdWUpO1xuXG4gICAgICAgICAgICBjYWxsYmFjayhudWxsLCBlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy8gRGVzZXJpYWxpemUgZGF0YSB3ZSd2ZSBpbnNlcnRlZCBpbnRvIGEgdmFsdWUgY29sdW1uL2ZpZWxkLiBXZSBwbGFjZVxuLy8gc3BlY2lhbCBtYXJrZXJzIGludG8gb3VyIHN0cmluZ3MgdG8gbWFyayB0aGVtIGFzIGVuY29kZWQ7IHRoaXMgaXNuJ3Rcbi8vIGFzIG5pY2UgYXMgYSBtZXRhIGZpZWxkLCBidXQgaXQncyB0aGUgb25seSBzYW5lIHRoaW5nIHdlIGNhbiBkbyB3aGlsc3Rcbi8vIGtlZXBpbmcgbG9jYWxTdG9yYWdlIHN1cHBvcnQgaW50YWN0LlxuLy9cbi8vIE9mdGVudGltZXMgdGhpcyB3aWxsIGp1c3QgZGVzZXJpYWxpemUgSlNPTiBjb250ZW50LCBidXQgaWYgd2UgaGF2ZSBhXG4vLyBzcGVjaWFsIG1hcmtlciAoU0VSSUFMSVpFRF9NQVJLRVIsIGRlZmluZWQgYWJvdmUpLCB3ZSB3aWxsIGV4dHJhY3Rcbi8vIHNvbWUga2luZCBvZiBhcnJheWJ1ZmZlci9iaW5hcnkgZGF0YS90eXBlZCBhcnJheSBvdXQgb2YgdGhlIHN0cmluZy5cbmZ1bmN0aW9uIGRlc2VyaWFsaXplKHZhbHVlKSB7XG4gICAgLy8gSWYgd2UgaGF2ZW4ndCBtYXJrZWQgdGhpcyBzdHJpbmcgYXMgYmVpbmcgc3BlY2lhbGx5IHNlcmlhbGl6ZWQgKGkuZS5cbiAgICAvLyBzb21ldGhpbmcgb3RoZXIgdGhhbiBzZXJpYWxpemVkIEpTT04pLCB3ZSBjYW4ganVzdCByZXR1cm4gaXQgYW5kIGJlXG4gICAgLy8gZG9uZSB3aXRoIGl0LlxuICAgIGlmICh2YWx1ZS5zdWJzdHJpbmcoMCwgU0VSSUFMSVpFRF9NQVJLRVJfTEVOR1RIKSAhPT0gU0VSSUFMSVpFRF9NQVJLRVIpIHtcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UodmFsdWUpO1xuICAgIH1cblxuICAgIC8vIFRoZSBmb2xsb3dpbmcgY29kZSBkZWFscyB3aXRoIGRlc2VyaWFsaXppbmcgc29tZSBraW5kIG9mIEJsb2Igb3JcbiAgICAvLyBUeXBlZEFycmF5LiBGaXJzdCB3ZSBzZXBhcmF0ZSBvdXQgdGhlIHR5cGUgb2YgZGF0YSB3ZSdyZSBkZWFsaW5nXG4gICAgLy8gd2l0aCBmcm9tIHRoZSBkYXRhIGl0c2VsZi5cbiAgICB2YXIgc2VyaWFsaXplZFN0cmluZyA9IHZhbHVlLnN1YnN0cmluZyhUWVBFX1NFUklBTElaRURfTUFSS0VSX0xFTkdUSCk7XG4gICAgdmFyIHR5cGUgPSB2YWx1ZS5zdWJzdHJpbmcoU0VSSUFMSVpFRF9NQVJLRVJfTEVOR1RILCBUWVBFX1NFUklBTElaRURfTUFSS0VSX0xFTkdUSCk7XG5cbiAgICB2YXIgYmxvYlR5cGU7XG4gICAgLy8gQmFja3dhcmRzLWNvbXBhdGlibGUgYmxvYiB0eXBlIHNlcmlhbGl6YXRpb24gc3RyYXRlZ3kuXG4gICAgLy8gREJzIGNyZWF0ZWQgd2l0aCBvbGRlciB2ZXJzaW9ucyBvZiBsb2NhbEZvcmFnZSB3aWxsIHNpbXBseSBub3QgaGF2ZSB0aGUgYmxvYiB0eXBlLlxuICAgIGlmICh0eXBlID09PSBUWVBFX0JMT0IgJiYgQkxPQl9UWVBFX1BSRUZJWF9SRUdFWC50ZXN0KHNlcmlhbGl6ZWRTdHJpbmcpKSB7XG4gICAgICAgIHZhciBtYXRjaGVyID0gc2VyaWFsaXplZFN0cmluZy5tYXRjaChCTE9CX1RZUEVfUFJFRklYX1JFR0VYKTtcbiAgICAgICAgYmxvYlR5cGUgPSBtYXRjaGVyWzFdO1xuICAgICAgICBzZXJpYWxpemVkU3RyaW5nID0gc2VyaWFsaXplZFN0cmluZy5zdWJzdHJpbmcobWF0Y2hlclswXS5sZW5ndGgpO1xuICAgIH1cbiAgICB2YXIgYnVmZmVyID0gc3RyaW5nVG9CdWZmZXIoc2VyaWFsaXplZFN0cmluZyk7XG5cbiAgICAvLyBSZXR1cm4gdGhlIHJpZ2h0IHR5cGUgYmFzZWQgb24gdGhlIGNvZGUvdHlwZSBzZXQgZHVyaW5nXG4gICAgLy8gc2VyaWFsaXphdGlvbi5cbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSBUWVBFX0FSUkFZQlVGRkVSOlxuICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlcjtcbiAgICAgICAgY2FzZSBUWVBFX0JMT0I6XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlQmxvYihbYnVmZmVyXSwgeyB0eXBlOiBibG9iVHlwZSB9KTtcbiAgICAgICAgY2FzZSBUWVBFX0lOVDhBUlJBWTpcbiAgICAgICAgICAgIHJldHVybiBuZXcgSW50OEFycmF5KGJ1ZmZlcik7XG4gICAgICAgIGNhc2UgVFlQRV9VSU5UOEFSUkFZOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XG4gICAgICAgIGNhc2UgVFlQRV9VSU5UOENMQU1QRURBUlJBWTpcbiAgICAgICAgICAgIHJldHVybiBuZXcgVWludDhDbGFtcGVkQXJyYXkoYnVmZmVyKTtcbiAgICAgICAgY2FzZSBUWVBFX0lOVDE2QVJSQVk6XG4gICAgICAgICAgICByZXR1cm4gbmV3IEludDE2QXJyYXkoYnVmZmVyKTtcbiAgICAgICAgY2FzZSBUWVBFX1VJTlQxNkFSUkFZOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBVaW50MTZBcnJheShidWZmZXIpO1xuICAgICAgICBjYXNlIFRZUEVfSU5UMzJBUlJBWTpcbiAgICAgICAgICAgIHJldHVybiBuZXcgSW50MzJBcnJheShidWZmZXIpO1xuICAgICAgICBjYXNlIFRZUEVfVUlOVDMyQVJSQVk6XG4gICAgICAgICAgICByZXR1cm4gbmV3IFVpbnQzMkFycmF5KGJ1ZmZlcik7XG4gICAgICAgIGNhc2UgVFlQRV9GTE9BVDMyQVJSQVk6XG4gICAgICAgICAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShidWZmZXIpO1xuICAgICAgICBjYXNlIFRZUEVfRkxPQVQ2NEFSUkFZOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBGbG9hdDY0QXJyYXkoYnVmZmVyKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5rb3duIHR5cGU6ICcgKyB0eXBlKTtcbiAgICB9XG59XG5cbnZhciBsb2NhbGZvcmFnZVNlcmlhbGl6ZXIgPSB7XG4gICAgc2VyaWFsaXplOiBzZXJpYWxpemUsXG4gICAgZGVzZXJpYWxpemU6IGRlc2VyaWFsaXplLFxuICAgIHN0cmluZ1RvQnVmZmVyOiBzdHJpbmdUb0J1ZmZlcixcbiAgICBidWZmZXJUb1N0cmluZzogYnVmZmVyVG9TdHJpbmdcbn07XG5cbi8qXG4gKiBJbmNsdWRlcyBjb2RlIGZyb206XG4gKlxuICogYmFzZTY0LWFycmF5YnVmZmVyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vbmlrbGFzdmgvYmFzZTY0LWFycmF5YnVmZmVyXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEyIE5pa2xhcyB2b24gSGVydHplblxuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxuICovXG4vLyBPcGVuIHRoZSBXZWJTUUwgZGF0YWJhc2UgKGF1dG9tYXRpY2FsbHkgY3JlYXRlcyBvbmUgaWYgb25lIGRpZG4ndFxuLy8gcHJldmlvdXNseSBleGlzdCksIHVzaW5nIGFueSBvcHRpb25zIHNldCBpbiB0aGUgY29uZmlnLlxuZnVuY3Rpb24gX2luaXRTdG9yYWdlJDEob3B0aW9ucykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGJJbmZvID0ge1xuICAgICAgICBkYjogbnVsbFxuICAgIH07XG5cbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgICBmb3IgKHZhciBpIGluIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGRiSW5mb1tpXSA9IHR5cGVvZiBvcHRpb25zW2ldICE9PSAnc3RyaW5nJyA/IG9wdGlvbnNbaV0udG9TdHJpbmcoKSA6IG9wdGlvbnNbaV07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZGJJbmZvUHJvbWlzZSA9IG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAvLyBPcGVuIHRoZSBkYXRhYmFzZTsgdGhlIG9wZW5EYXRhYmFzZSBBUEkgd2lsbCBhdXRvbWF0aWNhbGx5XG4gICAgICAgIC8vIGNyZWF0ZSBpdCBmb3IgdXMgaWYgaXQgZG9lc24ndCBleGlzdC5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGRiSW5mby5kYiA9IG9wZW5EYXRhYmFzZShkYkluZm8ubmFtZSwgU3RyaW5nKGRiSW5mby52ZXJzaW9uKSwgZGJJbmZvLmRlc2NyaXB0aW9uLCBkYkluZm8uc2l6ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QoZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgb3VyIGtleS92YWx1ZSB0YWJsZSBpZiBpdCBkb2Vzbid0IGV4aXN0LlxuICAgICAgICBkYkluZm8uZGIudHJhbnNhY3Rpb24oZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgIHQuZXhlY3V0ZVNxbCgnQ1JFQVRFIFRBQkxFIElGIE5PVCBFWElTVFMgJyArIGRiSW5mby5zdG9yZU5hbWUgKyAnIChpZCBJTlRFR0VSIFBSSU1BUlkgS0VZLCBrZXkgdW5pcXVlLCB2YWx1ZSknLCBbXSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNlbGYuX2RiSW5mbyA9IGRiSW5mbztcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAodCwgZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGJJbmZvLnNlcmlhbGl6ZXIgPSBsb2NhbGZvcmFnZVNlcmlhbGl6ZXI7XG4gICAgcmV0dXJuIGRiSW5mb1Byb21pc2U7XG59XG5cbmZ1bmN0aW9uIGdldEl0ZW0kMShrZXksIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgLy8gQ2FzdCB0aGUga2V5IHRvIGEgc3RyaW5nLCBhcyB0aGF0J3MgYWxsIHdlIGNhbiBzZXQgYXMgYSBrZXkuXG4gICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihrZXkgKyAnIHVzZWQgYXMgYSBrZXksIGJ1dCBpdCBpcyBub3QgYSBzdHJpbmcuJyk7XG4gICAgICAgIGtleSA9IFN0cmluZyhrZXkpO1xuICAgIH1cblxuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgICAgICBkYkluZm8uZGIudHJhbnNhY3Rpb24oZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgICAgICB0LmV4ZWN1dGVTcWwoJ1NFTEVDVCAqIEZST00gJyArIGRiSW5mby5zdG9yZU5hbWUgKyAnIFdIRVJFIGtleSA9ID8gTElNSVQgMScsIFtrZXldLCBmdW5jdGlvbiAodCwgcmVzdWx0cykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gcmVzdWx0cy5yb3dzLmxlbmd0aCA/IHJlc3VsdHMucm93cy5pdGVtKDApLnZhbHVlIDogbnVsbDtcblxuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayB0byBzZWUgaWYgdGhpcyBpcyBzZXJpYWxpemVkIGNvbnRlbnQgd2UgbmVlZCB0b1xuICAgICAgICAgICAgICAgICAgICAvLyB1bnBhY2suXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRiSW5mby5zZXJpYWxpemVyLmRlc2VyaWFsaXplKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgfSwgZnVuY3Rpb24gKHQsIGVycm9yKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVtcImNhdGNoXCJdKHJlamVjdCk7XG4gICAgfSk7XG5cbiAgICBleGVjdXRlQ2FsbGJhY2socHJvbWlzZSwgY2FsbGJhY2spO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5mdW5jdGlvbiBpdGVyYXRlJDEoaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgc2VsZi5yZWFkeSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcblxuICAgICAgICAgICAgZGJJbmZvLmRiLnRyYW5zYWN0aW9uKGZ1bmN0aW9uICh0KSB7XG4gICAgICAgICAgICAgICAgdC5leGVjdXRlU3FsKCdTRUxFQ1QgKiBGUk9NICcgKyBkYkluZm8uc3RvcmVOYW1lLCBbXSwgZnVuY3Rpb24gKHQsIHJlc3VsdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJvd3MgPSByZXN1bHRzLnJvd3M7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsZW5ndGggPSByb3dzLmxlbmd0aDtcblxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXRlbSA9IHJvd3MuaXRlbShpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBpdGVtLnZhbHVlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayB0byBzZWUgaWYgdGhpcyBpcyBzZXJpYWxpemVkIGNvbnRlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gdW5wYWNrLlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRiSW5mby5zZXJpYWxpemVyLmRlc2VyaWFsaXplKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGl0ZXJhdG9yKHJlc3VsdCwgaXRlbS5rZXksIGkgKyAxKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdm9pZCgwKSBwcmV2ZW50cyBwcm9ibGVtcyB3aXRoIHJlZGVmaW5pdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gb2YgYHVuZGVmaW5lZGAuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9PSB2b2lkIDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uICh0LCBlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbmZ1bmN0aW9uIF9zZXRJdGVtKGtleSwgdmFsdWUsIGNhbGxiYWNrLCByZXRyaWVzTGVmdCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIC8vIENhc3QgdGhlIGtleSB0byBhIHN0cmluZywgYXMgdGhhdCdzIGFsbCB3ZSBjYW4gc2V0IGFzIGEga2V5LlxuICAgIGlmICh0eXBlb2Yga2V5ICE9PSAnc3RyaW5nJykge1xuICAgICAgICBjb25zb2xlLndhcm4oa2V5ICsgJyB1c2VkIGFzIGEga2V5LCBidXQgaXQgaXMgbm90IGEgc3RyaW5nLicpO1xuICAgICAgICBrZXkgPSBTdHJpbmcoa2V5KTtcbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBUaGUgbG9jYWxTdG9yYWdlIEFQSSBkb2Vzbid0IHJldHVybiB1bmRlZmluZWQgdmFsdWVzIGluIGFuXG4gICAgICAgICAgICAvLyBcImV4cGVjdGVkXCIgd2F5LCBzbyB1bmRlZmluZWQgaXMgYWx3YXlzIGNhc3QgdG8gbnVsbCBpbiBhbGxcbiAgICAgICAgICAgIC8vIGRyaXZlcnMuIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL21vemlsbGEvbG9jYWxGb3JhZ2UvcHVsbC80MlxuICAgICAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNhdmUgdGhlIG9yaWdpbmFsIHZhbHVlIHRvIHBhc3MgdG8gdGhlIGNhbGxiYWNrLlxuICAgICAgICAgICAgdmFyIG9yaWdpbmFsVmFsdWUgPSB2YWx1ZTtcblxuICAgICAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgICAgIGRiSW5mby5zZXJpYWxpemVyLnNlcmlhbGl6ZSh2YWx1ZSwgZnVuY3Rpb24gKHZhbHVlLCBlcnJvcikge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRiSW5mby5kYi50cmFuc2FjdGlvbihmdW5jdGlvbiAodCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdC5leGVjdXRlU3FsKCdJTlNFUlQgT1IgUkVQTEFDRSBJTlRPICcgKyBkYkluZm8uc3RvcmVOYW1lICsgJyAoa2V5LCB2YWx1ZSkgVkFMVUVTICg/LCA/KScsIFtrZXksIHZhbHVlXSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUob3JpZ2luYWxWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBmdW5jdGlvbiAodCwgZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChzcWxFcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHRyYW5zYWN0aW9uIGZhaWxlZDsgY2hlY2tcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRvIHNlZSBpZiBpdCdzIGEgcXVvdGEgZXJyb3IuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3FsRXJyb3IuY29kZSA9PT0gc3FsRXJyb3IuUVVPVEFfRVJSKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UgcmVqZWN0IHRoZSBjYWxsYmFjayBvdXRyaWdodCBmb3Igbm93LCBidXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpdCdzIHdvcnRoIHRyeWluZyB0byByZS1ydW4gdGhlIHRyYW5zYWN0aW9uLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV2ZW4gaWYgdGhlIHVzZXIgYWNjZXB0cyB0aGUgcHJvbXB0IHRvIHVzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1vcmUgc3RvcmFnZSBvbiBTYWZhcmksIHRoaXMgZXJyb3Igd2lsbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJlIGNhbGxlZC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRyeSB0byByZS1ydW4gdGhlIHRyYW5zYWN0aW9uLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXRyaWVzTGVmdCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShfc2V0SXRlbS5hcHBseShzZWxmLCBba2V5LCBvcmlnaW5hbFZhbHVlLCBjYWxsYmFjaywgcmV0cmllc0xlZnQgLSAxXSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChzcWxFcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVtcImNhdGNoXCJdKHJlamVjdCk7XG4gICAgfSk7XG5cbiAgICBleGVjdXRlQ2FsbGJhY2socHJvbWlzZSwgY2FsbGJhY2spO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5mdW5jdGlvbiBzZXRJdGVtJDEoa2V5LCB2YWx1ZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gX3NldEl0ZW0uYXBwbHkodGhpcywgW2tleSwgdmFsdWUsIGNhbGxiYWNrLCAxXSk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUl0ZW0kMShrZXksIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgLy8gQ2FzdCB0aGUga2V5IHRvIGEgc3RyaW5nLCBhcyB0aGF0J3MgYWxsIHdlIGNhbiBzZXQgYXMgYSBrZXkuXG4gICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihrZXkgKyAnIHVzZWQgYXMgYSBrZXksIGJ1dCBpdCBpcyBub3QgYSBzdHJpbmcuJyk7XG4gICAgICAgIGtleSA9IFN0cmluZyhrZXkpO1xuICAgIH1cblxuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgICAgICBkYkluZm8uZGIudHJhbnNhY3Rpb24oZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgICAgICB0LmV4ZWN1dGVTcWwoJ0RFTEVURSBGUk9NICcgKyBkYkluZm8uc3RvcmVOYW1lICsgJyBXSEVSRSBrZXkgPSA/JywgW2tleV0sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uICh0LCBlcnJvcikge1xuXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSlbXCJjYXRjaFwiXShyZWplY3QpO1xuICAgIH0pO1xuXG4gICAgZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuLy8gRGVsZXRlcyBldmVyeSBpdGVtIGluIHRoZSB0YWJsZS5cbi8vIFRPRE86IEZpbmQgb3V0IGlmIHRoaXMgcmVzZXRzIHRoZSBBVVRPX0lOQ1JFTUVOVCBudW1iZXIuXG5mdW5jdGlvbiBjbGVhciQxKGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgc2VsZi5yZWFkeSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgICAgIGRiSW5mby5kYi50cmFuc2FjdGlvbihmdW5jdGlvbiAodCkge1xuICAgICAgICAgICAgICAgIHQuZXhlY3V0ZVNxbCgnREVMRVRFIEZST00gJyArIGRiSW5mby5zdG9yZU5hbWUsIFtdLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9LCBmdW5jdGlvbiAodCwgZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVtcImNhdGNoXCJdKHJlamVjdCk7XG4gICAgfSk7XG5cbiAgICBleGVjdXRlQ2FsbGJhY2socHJvbWlzZSwgY2FsbGJhY2spO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG4vLyBEb2VzIGEgc2ltcGxlIGBDT1VOVChrZXkpYCB0byBnZXQgdGhlIG51bWJlciBvZiBpdGVtcyBzdG9yZWQgaW5cbi8vIGxvY2FsRm9yYWdlLlxuZnVuY3Rpb24gbGVuZ3RoJDEoY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgZGJJbmZvID0gc2VsZi5fZGJJbmZvO1xuICAgICAgICAgICAgZGJJbmZvLmRiLnRyYW5zYWN0aW9uKGZ1bmN0aW9uICh0KSB7XG4gICAgICAgICAgICAgICAgLy8gQWhoaCwgU1FMIG1ha2VzIHRoaXMgb25lIHNvb29vb28gZWFzeS5cbiAgICAgICAgICAgICAgICB0LmV4ZWN1dGVTcWwoJ1NFTEVDVCBDT1VOVChrZXkpIGFzIGMgRlJPTSAnICsgZGJJbmZvLnN0b3JlTmFtZSwgW10sIGZ1bmN0aW9uICh0LCByZXN1bHRzKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSByZXN1bHRzLnJvd3MuaXRlbSgwKS5jO1xuXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9LCBmdW5jdGlvbiAodCwgZXJyb3IpIHtcblxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbi8vIFJldHVybiB0aGUga2V5IGxvY2F0ZWQgYXQga2V5IGluZGV4IFg7IGVzc2VudGlhbGx5IGdldHMgdGhlIGtleSBmcm9tIGFcbi8vIGBXSEVSRSBpZCA9ID9gLiBUaGlzIGlzIHRoZSBtb3N0IGVmZmljaWVudCB3YXkgSSBjYW4gdGhpbmsgdG8gaW1wbGVtZW50XG4vLyB0aGlzIHJhcmVseS11c2VkIChpbiBteSBleHBlcmllbmNlKSBwYXJ0IG9mIHRoZSBBUEksIGJ1dCBpdCBjYW4gc2VlbVxuLy8gaW5jb25zaXN0ZW50LCBiZWNhdXNlIHdlIGRvIGBJTlNFUlQgT1IgUkVQTEFDRSBJTlRPYCBvbiBgc2V0SXRlbSgpYCwgc29cbi8vIHRoZSBJRCBvZiBlYWNoIGtleSB3aWxsIGNoYW5nZSBldmVyeSB0aW1lIGl0J3MgdXBkYXRlZC4gUGVyaGFwcyBhIHN0b3JlZFxuLy8gcHJvY2VkdXJlIGZvciB0aGUgYHNldEl0ZW0oKWAgU1FMIHdvdWxkIHNvbHZlIHRoaXMgcHJvYmxlbT9cbi8vIFRPRE86IERvbid0IGNoYW5nZSBJRCBvbiBgc2V0SXRlbSgpYC5cbmZ1bmN0aW9uIGtleSQxKG4sIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgc2VsZi5yZWFkeSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgICAgIGRiSW5mby5kYi50cmFuc2FjdGlvbihmdW5jdGlvbiAodCkge1xuICAgICAgICAgICAgICAgIHQuZXhlY3V0ZVNxbCgnU0VMRUNUIGtleSBGUk9NICcgKyBkYkluZm8uc3RvcmVOYW1lICsgJyBXSEVSRSBpZCA9ID8gTElNSVQgMScsIFtuICsgMV0sIGZ1bmN0aW9uICh0LCByZXN1bHRzKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSByZXN1bHRzLnJvd3MubGVuZ3RoID8gcmVzdWx0cy5yb3dzLml0ZW0oMCkua2V5IDogbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uICh0LCBlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbmZ1bmN0aW9uIGtleXMkMShjYWxsYmFjaykge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgICAgICBkYkluZm8uZGIudHJhbnNhY3Rpb24oZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgICAgICB0LmV4ZWN1dGVTcWwoJ1NFTEVDVCBrZXkgRlJPTSAnICsgZGJJbmZvLnN0b3JlTmFtZSwgW10sIGZ1bmN0aW9uICh0LCByZXN1bHRzKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBrZXlzID0gW107XG5cbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXN1bHRzLnJvd3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleXMucHVzaChyZXN1bHRzLnJvd3MuaXRlbShpKS5rZXkpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShrZXlzKTtcbiAgICAgICAgICAgICAgICB9LCBmdW5jdGlvbiAodCwgZXJyb3IpIHtcblxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbnZhciB3ZWJTUUxTdG9yYWdlID0ge1xuICAgIF9kcml2ZXI6ICd3ZWJTUUxTdG9yYWdlJyxcbiAgICBfaW5pdFN0b3JhZ2U6IF9pbml0U3RvcmFnZSQxLFxuICAgIGl0ZXJhdGU6IGl0ZXJhdGUkMSxcbiAgICBnZXRJdGVtOiBnZXRJdGVtJDEsXG4gICAgc2V0SXRlbTogc2V0SXRlbSQxLFxuICAgIHJlbW92ZUl0ZW06IHJlbW92ZUl0ZW0kMSxcbiAgICBjbGVhcjogY2xlYXIkMSxcbiAgICBsZW5ndGg6IGxlbmd0aCQxLFxuICAgIGtleToga2V5JDEsXG4gICAga2V5czoga2V5cyQxXG59O1xuXG4vLyBDb25maWcgdGhlIGxvY2FsU3RvcmFnZSBiYWNrZW5kLCB1c2luZyBvcHRpb25zIHNldCBpbiB0aGUgY29uZmlnLlxuZnVuY3Rpb24gX2luaXRTdG9yYWdlJDIob3B0aW9ucykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGJJbmZvID0ge307XG4gICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgICAgZm9yICh2YXIgaSBpbiBvcHRpb25zKSB7XG4gICAgICAgICAgICBkYkluZm9baV0gPSBvcHRpb25zW2ldO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGJJbmZvLmtleVByZWZpeCA9IGRiSW5mby5uYW1lICsgJy8nO1xuXG4gICAgaWYgKGRiSW5mby5zdG9yZU5hbWUgIT09IHNlbGYuX2RlZmF1bHRDb25maWcuc3RvcmVOYW1lKSB7XG4gICAgICAgIGRiSW5mby5rZXlQcmVmaXggKz0gZGJJbmZvLnN0b3JlTmFtZSArICcvJztcbiAgICB9XG5cbiAgICBzZWxmLl9kYkluZm8gPSBkYkluZm87XG4gICAgZGJJbmZvLnNlcmlhbGl6ZXIgPSBsb2NhbGZvcmFnZVNlcmlhbGl6ZXI7XG5cbiAgICByZXR1cm4gUHJvbWlzZSQxLnJlc29sdmUoKTtcbn1cblxuLy8gUmVtb3ZlIGFsbCBrZXlzIGZyb20gdGhlIGRhdGFzdG9yZSwgZWZmZWN0aXZlbHkgZGVzdHJveWluZyBhbGwgZGF0YSBpblxuLy8gdGhlIGFwcCdzIGtleS92YWx1ZSBzdG9yZSFcbmZ1bmN0aW9uIGNsZWFyJDIoY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIHByb21pc2UgPSBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBrZXlQcmVmaXggPSBzZWxmLl9kYkluZm8ua2V5UHJlZml4O1xuXG4gICAgICAgIGZvciAodmFyIGkgPSBsb2NhbFN0b3JhZ2UubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBsb2NhbFN0b3JhZ2Uua2V5KGkpO1xuXG4gICAgICAgICAgICBpZiAoa2V5LmluZGV4T2Yoa2V5UHJlZml4KSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbi8vIFJldHJpZXZlIGFuIGl0ZW0gZnJvbSB0aGUgc3RvcmUuIFVubGlrZSB0aGUgb3JpZ2luYWwgYXN5bmNfc3RvcmFnZVxuLy8gbGlicmFyeSBpbiBHYWlhLCB3ZSBkb24ndCBtb2RpZnkgcmV0dXJuIHZhbHVlcyBhdCBhbGwuIElmIGEga2V5J3MgdmFsdWVcbi8vIGlzIGB1bmRlZmluZWRgLCB3ZSBwYXNzIHRoYXQgdmFsdWUgdG8gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uLlxuZnVuY3Rpb24gZ2V0SXRlbSQyKGtleSwgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAvLyBDYXN0IHRoZSBrZXkgdG8gYSBzdHJpbmcsIGFzIHRoYXQncyBhbGwgd2UgY2FuIHNldCBhcyBhIGtleS5cbiAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGtleSArICcgdXNlZCBhcyBhIGtleSwgYnV0IGl0IGlzIG5vdCBhIHN0cmluZy4nKTtcbiAgICAgICAga2V5ID0gU3RyaW5nKGtleSk7XG4gICAgfVxuXG4gICAgdmFyIHByb21pc2UgPSBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgIHZhciByZXN1bHQgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShkYkluZm8ua2V5UHJlZml4ICsga2V5KTtcblxuICAgICAgICAvLyBJZiBhIHJlc3VsdCB3YXMgZm91bmQsIHBhcnNlIGl0IGZyb20gdGhlIHNlcmlhbGl6ZWRcbiAgICAgICAgLy8gc3RyaW5nIGludG8gYSBKUyBvYmplY3QuIElmIHJlc3VsdCBpc24ndCB0cnV0aHksIHRoZSBrZXlcbiAgICAgICAgLy8gaXMgbGlrZWx5IHVuZGVmaW5lZCBhbmQgd2UnbGwgcGFzcyBpdCBzdHJhaWdodCB0byB0aGVcbiAgICAgICAgLy8gY2FsbGJhY2suXG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGRiSW5mby5zZXJpYWxpemVyLmRlc2VyaWFsaXplKHJlc3VsdCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gICAgZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuLy8gSXRlcmF0ZSBvdmVyIGFsbCBpdGVtcyBpbiB0aGUgc3RvcmUuXG5mdW5jdGlvbiBpdGVyYXRlJDIoaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHByb21pc2UgPSBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgIHZhciBrZXlQcmVmaXggPSBkYkluZm8ua2V5UHJlZml4O1xuICAgICAgICB2YXIga2V5UHJlZml4TGVuZ3RoID0ga2V5UHJlZml4Lmxlbmd0aDtcbiAgICAgICAgdmFyIGxlbmd0aCA9IGxvY2FsU3RvcmFnZS5sZW5ndGg7XG5cbiAgICAgICAgLy8gV2UgdXNlIGEgZGVkaWNhdGVkIGl0ZXJhdG9yIGluc3RlYWQgb2YgdGhlIGBpYCB2YXJpYWJsZSBiZWxvd1xuICAgICAgICAvLyBzbyBvdGhlciBrZXlzIHdlIGZldGNoIGluIGxvY2FsU3RvcmFnZSBhcmVuJ3QgY291bnRlZCBpblxuICAgICAgICAvLyB0aGUgYGl0ZXJhdGlvbk51bWJlcmAgYXJndW1lbnQgcGFzc2VkIHRvIHRoZSBgaXRlcmF0ZSgpYFxuICAgICAgICAvLyBjYWxsYmFjay5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gU2VlOiBnaXRodWIuY29tL21vemlsbGEvbG9jYWxGb3JhZ2UvcHVsbC80MzUjZGlzY3Vzc2lvbl9yMzgwNjE1MzBcbiAgICAgICAgdmFyIGl0ZXJhdGlvbk51bWJlciA9IDE7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGtleSA9IGxvY2FsU3RvcmFnZS5rZXkoaSk7XG4gICAgICAgICAgICBpZiAoa2V5LmluZGV4T2Yoa2V5UHJlZml4KSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHZhbHVlID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oa2V5KTtcblxuICAgICAgICAgICAgLy8gSWYgYSByZXN1bHQgd2FzIGZvdW5kLCBwYXJzZSBpdCBmcm9tIHRoZSBzZXJpYWxpemVkXG4gICAgICAgICAgICAvLyBzdHJpbmcgaW50byBhIEpTIG9iamVjdC4gSWYgcmVzdWx0IGlzbid0IHRydXRoeSwgdGhlXG4gICAgICAgICAgICAvLyBrZXkgaXMgbGlrZWx5IHVuZGVmaW5lZCBhbmQgd2UnbGwgcGFzcyBpdCBzdHJhaWdodFxuICAgICAgICAgICAgLy8gdG8gdGhlIGl0ZXJhdG9yLlxuICAgICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBkYkluZm8uc2VyaWFsaXplci5kZXNlcmlhbGl6ZSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhbHVlID0gaXRlcmF0b3IodmFsdWUsIGtleS5zdWJzdHJpbmcoa2V5UHJlZml4TGVuZ3RoKSwgaXRlcmF0aW9uTnVtYmVyKyspO1xuXG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IHZvaWQgMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuLy8gU2FtZSBhcyBsb2NhbFN0b3JhZ2UncyBrZXkoKSBtZXRob2QsIGV4Y2VwdCB0YWtlcyBhIGNhbGxiYWNrLlxuZnVuY3Rpb24ga2V5JDIobiwgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIHByb21pc2UgPSBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgIHZhciByZXN1bHQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXN1bHQgPSBsb2NhbFN0b3JhZ2Uua2V5KG4pO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgcmVzdWx0ID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlbW92ZSB0aGUgcHJlZml4IGZyb20gdGhlIGtleSwgaWYgYSBrZXkgaXMgZm91bmQuXG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zdWJzdHJpbmcoZGJJbmZvLmtleVByZWZpeC5sZW5ndGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbmZ1bmN0aW9uIGtleXMkMihjYWxsYmFjaykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgcHJvbWlzZSA9IHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgdmFyIGxlbmd0aCA9IGxvY2FsU3RvcmFnZS5sZW5ndGg7XG4gICAgICAgIHZhciBrZXlzID0gW107XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKGxvY2FsU3RvcmFnZS5rZXkoaSkuaW5kZXhPZihkYkluZm8ua2V5UHJlZml4KSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGtleXMucHVzaChsb2NhbFN0b3JhZ2Uua2V5KGkpLnN1YnN0cmluZyhkYkluZm8ua2V5UHJlZml4Lmxlbmd0aCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGtleXM7XG4gICAgfSk7XG5cbiAgICBleGVjdXRlQ2FsbGJhY2socHJvbWlzZSwgY2FsbGJhY2spO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG4vLyBTdXBwbHkgdGhlIG51bWJlciBvZiBrZXlzIGluIHRoZSBkYXRhc3RvcmUgdG8gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uLlxuZnVuY3Rpb24gbGVuZ3RoJDIoY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIHByb21pc2UgPSBzZWxmLmtleXMoKS50aGVuKGZ1bmN0aW9uIChrZXlzKSB7XG4gICAgICAgIHJldHVybiBrZXlzLmxlbmd0aDtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbi8vIFJlbW92ZSBhbiBpdGVtIGZyb20gdGhlIHN0b3JlLCBuaWNlIGFuZCBzaW1wbGUuXG5mdW5jdGlvbiByZW1vdmVJdGVtJDIoa2V5LCBjYWxsYmFjaykge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIC8vIENhc3QgdGhlIGtleSB0byBhIHN0cmluZywgYXMgdGhhdCdzIGFsbCB3ZSBjYW4gc2V0IGFzIGEga2V5LlxuICAgIGlmICh0eXBlb2Yga2V5ICE9PSAnc3RyaW5nJykge1xuICAgICAgICBjb25zb2xlLndhcm4oa2V5ICsgJyB1c2VkIGFzIGEga2V5LCBidXQgaXQgaXMgbm90IGEgc3RyaW5nLicpO1xuICAgICAgICBrZXkgPSBTdHJpbmcoa2V5KTtcbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZSA9IHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oZGJJbmZvLmtleVByZWZpeCArIGtleSk7XG4gICAgfSk7XG5cbiAgICBleGVjdXRlQ2FsbGJhY2socHJvbWlzZSwgY2FsbGJhY2spO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG4vLyBTZXQgYSBrZXkncyB2YWx1ZSBhbmQgcnVuIGFuIG9wdGlvbmFsIGNhbGxiYWNrIG9uY2UgdGhlIHZhbHVlIGlzIHNldC5cbi8vIFVubGlrZSBHYWlhJ3MgaW1wbGVtZW50YXRpb24sIHRoZSBjYWxsYmFjayBmdW5jdGlvbiBpcyBwYXNzZWQgdGhlIHZhbHVlLFxuLy8gaW4gY2FzZSB5b3Ugd2FudCB0byBvcGVyYXRlIG9uIHRoYXQgdmFsdWUgb25seSBhZnRlciB5b3UncmUgc3VyZSBpdFxuLy8gc2F2ZWQsIG9yIHNvbWV0aGluZyBsaWtlIHRoYXQuXG5mdW5jdGlvbiBzZXRJdGVtJDIoa2V5LCB2YWx1ZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAvLyBDYXN0IHRoZSBrZXkgdG8gYSBzdHJpbmcsIGFzIHRoYXQncyBhbGwgd2UgY2FuIHNldCBhcyBhIGtleS5cbiAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGtleSArICcgdXNlZCBhcyBhIGtleSwgYnV0IGl0IGlzIG5vdCBhIHN0cmluZy4nKTtcbiAgICAgICAga2V5ID0gU3RyaW5nKGtleSk7XG4gICAgfVxuXG4gICAgdmFyIHByb21pc2UgPSBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIENvbnZlcnQgdW5kZWZpbmVkIHZhbHVlcyB0byBudWxsLlxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbW96aWxsYS9sb2NhbEZvcmFnZS9wdWxsLzQyXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTYXZlIHRoZSBvcmlnaW5hbCB2YWx1ZSB0byBwYXNzIHRvIHRoZSBjYWxsYmFjay5cbiAgICAgICAgdmFyIG9yaWdpbmFsVmFsdWUgPSB2YWx1ZTtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICB2YXIgZGJJbmZvID0gc2VsZi5fZGJJbmZvO1xuICAgICAgICAgICAgZGJJbmZvLnNlcmlhbGl6ZXIuc2VyaWFsaXplKHZhbHVlLCBmdW5jdGlvbiAodmFsdWUsIGVycm9yKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKGRiSW5mby5rZXlQcmVmaXggKyBrZXksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUob3JpZ2luYWxWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvY2FsU3RvcmFnZSBjYXBhY2l0eSBleGNlZWRlZC5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IE1ha2UgdGhpcyBhIHNwZWNpZmljIGVycm9yL2V2ZW50LlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUubmFtZSA9PT0gJ1F1b3RhRXhjZWVkZWRFcnJvcicgfHwgZS5uYW1lID09PSAnTlNfRVJST1JfRE9NX1FVT1RBX1JFQUNIRUQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxudmFyIGxvY2FsU3RvcmFnZVdyYXBwZXIgPSB7XG4gICAgX2RyaXZlcjogJ2xvY2FsU3RvcmFnZVdyYXBwZXInLFxuICAgIF9pbml0U3RvcmFnZTogX2luaXRTdG9yYWdlJDIsXG4gICAgLy8gRGVmYXVsdCBBUEksIGZyb20gR2FpYS9sb2NhbFN0b3JhZ2UuXG4gICAgaXRlcmF0ZTogaXRlcmF0ZSQyLFxuICAgIGdldEl0ZW06IGdldEl0ZW0kMixcbiAgICBzZXRJdGVtOiBzZXRJdGVtJDIsXG4gICAgcmVtb3ZlSXRlbTogcmVtb3ZlSXRlbSQyLFxuICAgIGNsZWFyOiBjbGVhciQyLFxuICAgIGxlbmd0aDogbGVuZ3RoJDIsXG4gICAga2V5OiBrZXkkMixcbiAgICBrZXlzOiBrZXlzJDJcbn07XG5cbi8vIEN1c3RvbSBkcml2ZXJzIGFyZSBzdG9yZWQgaGVyZSB3aGVuIGBkZWZpbmVEcml2ZXIoKWAgaXMgY2FsbGVkLlxuLy8gVGhleSBhcmUgc2hhcmVkIGFjcm9zcyBhbGwgaW5zdGFuY2VzIG9mIGxvY2FsRm9yYWdlLlxudmFyIEN1c3RvbURyaXZlcnMgPSB7fTtcblxudmFyIERyaXZlclR5cGUgPSB7XG4gICAgSU5ERVhFRERCOiAnYXN5bmNTdG9yYWdlJyxcbiAgICBMT0NBTFNUT1JBR0U6ICdsb2NhbFN0b3JhZ2VXcmFwcGVyJyxcbiAgICBXRUJTUUw6ICd3ZWJTUUxTdG9yYWdlJ1xufTtcblxudmFyIERlZmF1bHREcml2ZXJPcmRlciA9IFtEcml2ZXJUeXBlLklOREVYRUREQiwgRHJpdmVyVHlwZS5XRUJTUUwsIERyaXZlclR5cGUuTE9DQUxTVE9SQUdFXTtcblxudmFyIExpYnJhcnlNZXRob2RzID0gWydjbGVhcicsICdnZXRJdGVtJywgJ2l0ZXJhdGUnLCAna2V5JywgJ2tleXMnLCAnbGVuZ3RoJywgJ3JlbW92ZUl0ZW0nLCAnc2V0SXRlbSddO1xuXG52YXIgRGVmYXVsdENvbmZpZyA9IHtcbiAgICBkZXNjcmlwdGlvbjogJycsXG4gICAgZHJpdmVyOiBEZWZhdWx0RHJpdmVyT3JkZXIuc2xpY2UoKSxcbiAgICBuYW1lOiAnbG9jYWxmb3JhZ2UnLFxuICAgIC8vIERlZmF1bHQgREIgc2l6ZSBpcyBfSlVTVCBVTkRFUl8gNU1CLCBhcyBpdCdzIHRoZSBoaWdoZXN0IHNpemVcbiAgICAvLyB3ZSBjYW4gdXNlIHdpdGhvdXQgYSBwcm9tcHQuXG4gICAgc2l6ZTogNDk4MDczNixcbiAgICBzdG9yZU5hbWU6ICdrZXl2YWx1ZXBhaXJzJyxcbiAgICB2ZXJzaW9uOiAxLjBcbn07XG5cbnZhciBkcml2ZXJTdXBwb3J0ID0ge307XG4vLyBDaGVjayB0byBzZWUgaWYgSW5kZXhlZERCIGlzIGF2YWlsYWJsZSBhbmQgaWYgaXQgaXMgdGhlIGxhdGVzdFxuLy8gaW1wbGVtZW50YXRpb247IGl0J3Mgb3VyIHByZWZlcnJlZCBiYWNrZW5kIGxpYnJhcnkuIFdlIHVzZSBcIl9zcGVjX3Rlc3RcIlxuLy8gYXMgdGhlIG5hbWUgb2YgdGhlIGRhdGFiYXNlIGJlY2F1c2UgaXQncyBub3QgdGhlIG9uZSB3ZSdsbCBvcGVyYXRlIG9uLFxuLy8gYnV0IGl0J3MgdXNlZnVsIHRvIG1ha2Ugc3VyZSBpdHMgdXNpbmcgdGhlIHJpZ2h0IHNwZWMuXG4vLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9tb3ppbGxhL2xvY2FsRm9yYWdlL2lzc3Vlcy8xMjhcbmRyaXZlclN1cHBvcnRbRHJpdmVyVHlwZS5JTkRFWEVEREJdID0gaXNJbmRleGVkREJWYWxpZCgpO1xuXG5kcml2ZXJTdXBwb3J0W0RyaXZlclR5cGUuV0VCU1FMXSA9IGlzV2ViU1FMVmFsaWQoKTtcblxuZHJpdmVyU3VwcG9ydFtEcml2ZXJUeXBlLkxPQ0FMU1RPUkFHRV0gPSBpc0xvY2FsU3RvcmFnZVZhbGlkKCk7XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJnKSB7XG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxuZnVuY3Rpb24gY2FsbFdoZW5SZWFkeShsb2NhbEZvcmFnZUluc3RhbmNlLCBsaWJyYXJ5TWV0aG9kKSB7XG4gICAgbG9jYWxGb3JhZ2VJbnN0YW5jZVtsaWJyYXJ5TWV0aG9kXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hcmdzID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gbG9jYWxGb3JhZ2VJbnN0YW5jZS5yZWFkeSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGxvY2FsRm9yYWdlSW5zdGFuY2VbbGlicmFyeU1ldGhvZF0uYXBwbHkobG9jYWxGb3JhZ2VJbnN0YW5jZSwgX2FyZ3MpO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBleHRlbmQoKSB7XG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGFyZyA9IGFyZ3VtZW50c1tpXTtcblxuICAgICAgICBpZiAoYXJnKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gYXJnKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFyZy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FycmF5KGFyZ1trZXldKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzWzBdW2tleV0gPSBhcmdba2V5XS5zbGljZSgpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzWzBdW2tleV0gPSBhcmdba2V5XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhcmd1bWVudHNbMF07XG59XG5cbmZ1bmN0aW9uIGlzTGlicmFyeURyaXZlcihkcml2ZXJOYW1lKSB7XG4gICAgZm9yICh2YXIgZHJpdmVyIGluIERyaXZlclR5cGUpIHtcbiAgICAgICAgaWYgKERyaXZlclR5cGUuaGFzT3duUHJvcGVydHkoZHJpdmVyKSAmJiBEcml2ZXJUeXBlW2RyaXZlcl0gPT09IGRyaXZlck5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG52YXIgTG9jYWxGb3JhZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTG9jYWxGb3JhZ2Uob3B0aW9ucykge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTG9jYWxGb3JhZ2UpO1xuXG4gICAgICAgIHRoaXMuSU5ERVhFRERCID0gRHJpdmVyVHlwZS5JTkRFWEVEREI7XG4gICAgICAgIHRoaXMuTE9DQUxTVE9SQUdFID0gRHJpdmVyVHlwZS5MT0NBTFNUT1JBR0U7XG4gICAgICAgIHRoaXMuV0VCU1FMID0gRHJpdmVyVHlwZS5XRUJTUUw7XG5cbiAgICAgICAgdGhpcy5fZGVmYXVsdENvbmZpZyA9IGV4dGVuZCh7fSwgRGVmYXVsdENvbmZpZyk7XG4gICAgICAgIHRoaXMuX2NvbmZpZyA9IGV4dGVuZCh7fSwgdGhpcy5fZGVmYXVsdENvbmZpZywgb3B0aW9ucyk7XG4gICAgICAgIHRoaXMuX2RyaXZlclNldCA9IG51bGw7XG4gICAgICAgIHRoaXMuX2luaXREcml2ZXIgPSBudWxsO1xuICAgICAgICB0aGlzLl9yZWFkeSA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9kYkluZm8gPSBudWxsO1xuXG4gICAgICAgIHRoaXMuX3dyYXBMaWJyYXJ5TWV0aG9kc1dpdGhSZWFkeSgpO1xuICAgICAgICB0aGlzLnNldERyaXZlcih0aGlzLl9jb25maWcuZHJpdmVyKVtcImNhdGNoXCJdKGZ1bmN0aW9uICgpIHt9KTtcbiAgICB9XG5cbiAgICAvLyBTZXQgYW55IGNvbmZpZyB2YWx1ZXMgZm9yIGxvY2FsRm9yYWdlOyBjYW4gYmUgY2FsbGVkIGFueXRpbWUgYmVmb3JlXG4gICAgLy8gdGhlIGZpcnN0IEFQSSBjYWxsIChlLmcuIGBnZXRJdGVtYCwgYHNldEl0ZW1gKS5cbiAgICAvLyBXZSBsb29wIHRocm91Z2ggb3B0aW9ucyBzbyB3ZSBkb24ndCBvdmVyd3JpdGUgZXhpc3RpbmcgY29uZmlnXG4gICAgLy8gdmFsdWVzLlxuXG5cbiAgICBMb2NhbEZvcmFnZS5wcm90b3R5cGUuY29uZmlnID0gZnVuY3Rpb24gY29uZmlnKG9wdGlvbnMpIHtcbiAgICAgICAgLy8gSWYgdGhlIG9wdGlvbnMgYXJndW1lbnQgaXMgYW4gb2JqZWN0LCB3ZSB1c2UgaXQgdG8gc2V0IHZhbHVlcy5cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCB3ZSByZXR1cm4gZWl0aGVyIGEgc3BlY2lmaWVkIGNvbmZpZyB2YWx1ZSBvciBhbGxcbiAgICAgICAgLy8gY29uZmlnIHZhbHVlcy5cbiAgICAgICAgaWYgKCh0eXBlb2Ygb3B0aW9ucyA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2Yob3B0aW9ucykpID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgLy8gSWYgbG9jYWxmb3JhZ2UgaXMgcmVhZHkgYW5kIGZ1bGx5IGluaXRpYWxpemVkLCB3ZSBjYW4ndCBzZXRcbiAgICAgICAgICAgIC8vIGFueSBuZXcgY29uZmlndXJhdGlvbiB2YWx1ZXMuIEluc3RlYWQsIHdlIHJldHVybiBhbiBlcnJvci5cbiAgICAgICAgICAgIGlmICh0aGlzLl9yZWFkeSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRXJyb3IoXCJDYW4ndCBjYWxsIGNvbmZpZygpIGFmdGVyIGxvY2FsZm9yYWdlIFwiICsgJ2hhcyBiZWVuIHVzZWQuJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gb3B0aW9ucykge1xuICAgICAgICAgICAgICAgIGlmIChpID09PSAnc3RvcmVOYW1lJykge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zW2ldID0gb3B0aW9uc1tpXS5yZXBsYWNlKC9cXFcvZywgJ18nKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoaSA9PT0gJ3ZlcnNpb24nICYmIHR5cGVvZiBvcHRpb25zW2ldICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEVycm9yKCdEYXRhYmFzZSB2ZXJzaW9uIG11c3QgYmUgYSBudW1iZXIuJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5fY29uZmlnW2ldID0gb3B0aW9uc1tpXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gYWZ0ZXIgYWxsIGNvbmZpZyBvcHRpb25zIGFyZSBzZXQgYW5kXG4gICAgICAgICAgICAvLyB0aGUgZHJpdmVyIG9wdGlvbiBpcyB1c2VkLCB0cnkgc2V0dGluZyBpdFxuICAgICAgICAgICAgaWYgKCdkcml2ZXInIGluIG9wdGlvbnMgJiYgb3B0aW9ucy5kcml2ZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZXREcml2ZXIodGhpcy5fY29uZmlnLmRyaXZlcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbmZpZ1tvcHRpb25zXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jb25maWc7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gVXNlZCB0byBkZWZpbmUgYSBjdXN0b20gZHJpdmVyLCBzaGFyZWQgYWNyb3NzIGFsbCBpbnN0YW5jZXMgb2ZcbiAgICAvLyBsb2NhbEZvcmFnZS5cblxuXG4gICAgTG9jYWxGb3JhZ2UucHJvdG90eXBlLmRlZmluZURyaXZlciA9IGZ1bmN0aW9uIGRlZmluZURyaXZlcihkcml2ZXJPYmplY3QsIGNhbGxiYWNrLCBlcnJvckNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHZhciBkcml2ZXJOYW1lID0gZHJpdmVyT2JqZWN0Ll9kcml2ZXI7XG4gICAgICAgICAgICAgICAgdmFyIGNvbXBsaWFuY2VFcnJvciA9IG5ldyBFcnJvcignQ3VzdG9tIGRyaXZlciBub3QgY29tcGxpYW50OyBzZWUgJyArICdodHRwczovL21vemlsbGEuZ2l0aHViLmlvL2xvY2FsRm9yYWdlLyNkZWZpbmVkcml2ZXInKTtcbiAgICAgICAgICAgICAgICB2YXIgbmFtaW5nRXJyb3IgPSBuZXcgRXJyb3IoJ0N1c3RvbSBkcml2ZXIgbmFtZSBhbHJlYWR5IGluIHVzZTogJyArIGRyaXZlck9iamVjdC5fZHJpdmVyKTtcblxuICAgICAgICAgICAgICAgIC8vIEEgZHJpdmVyIG5hbWUgc2hvdWxkIGJlIGRlZmluZWQgYW5kIG5vdCBvdmVybGFwIHdpdGggdGhlXG4gICAgICAgICAgICAgICAgLy8gbGlicmFyeS1kZWZpbmVkLCBkZWZhdWx0IGRyaXZlcnMuXG4gICAgICAgICAgICAgICAgaWYgKCFkcml2ZXJPYmplY3QuX2RyaXZlcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoY29tcGxpYW5jZUVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoaXNMaWJyYXJ5RHJpdmVyKGRyaXZlck9iamVjdC5fZHJpdmVyKSkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QobmFtaW5nRXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIGN1c3RvbURyaXZlck1ldGhvZHMgPSBMaWJyYXJ5TWV0aG9kcy5jb25jYXQoJ19pbml0U3RvcmFnZScpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY3VzdG9tRHJpdmVyTWV0aG9kcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgY3VzdG9tRHJpdmVyTWV0aG9kID0gY3VzdG9tRHJpdmVyTWV0aG9kc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjdXN0b21Ecml2ZXJNZXRob2QgfHwgIWRyaXZlck9iamVjdFtjdXN0b21Ecml2ZXJNZXRob2RdIHx8IHR5cGVvZiBkcml2ZXJPYmplY3RbY3VzdG9tRHJpdmVyTWV0aG9kXSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGNvbXBsaWFuY2VFcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB2YXIgc3VwcG9ydFByb21pc2UgPSBQcm9taXNlJDEucmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgICAgICAgICBpZiAoJ19zdXBwb3J0JyBpbiBkcml2ZXJPYmplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRyaXZlck9iamVjdC5fc3VwcG9ydCAmJiB0eXBlb2YgZHJpdmVyT2JqZWN0Ll9zdXBwb3J0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0UHJvbWlzZSA9IGRyaXZlck9iamVjdC5fc3VwcG9ydCgpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3VwcG9ydFByb21pc2UgPSBQcm9taXNlJDEucmVzb2x2ZSghIWRyaXZlck9iamVjdC5fc3VwcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBzdXBwb3J0UHJvbWlzZS50aGVuKGZ1bmN0aW9uIChzdXBwb3J0UmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIGRyaXZlclN1cHBvcnRbZHJpdmVyTmFtZV0gPSBzdXBwb3J0UmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICBDdXN0b21Ecml2ZXJzW2RyaXZlck5hbWVdID0gZHJpdmVyT2JqZWN0O1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGV4ZWN1dGVUd29DYWxsYmFja3MocHJvbWlzZSwgY2FsbGJhY2ssIGVycm9yQ2FsbGJhY2spO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9O1xuXG4gICAgTG9jYWxGb3JhZ2UucHJvdG90eXBlLmRyaXZlciA9IGZ1bmN0aW9uIGRyaXZlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RyaXZlciB8fCBudWxsO1xuICAgIH07XG5cbiAgICBMb2NhbEZvcmFnZS5wcm90b3R5cGUuZ2V0RHJpdmVyID0gZnVuY3Rpb24gZ2V0RHJpdmVyKGRyaXZlck5hbWUsIGNhbGxiYWNrLCBlcnJvckNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdmFyIGdldERyaXZlclByb21pc2UgPSBQcm9taXNlJDEucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKGlzTGlicmFyeURyaXZlcihkcml2ZXJOYW1lKSkge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoZHJpdmVyTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIHNlbGYuSU5ERVhFRERCOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFzeW5jU3RvcmFnZTtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBzZWxmLkxPQ0FMU1RPUkFHRTpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbFN0b3JhZ2VXcmFwcGVyO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIHNlbGYuV0VCU1FMOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdlYlNRTFN0b3JhZ2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChDdXN0b21Ecml2ZXJzW2RyaXZlck5hbWVdKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEN1c3RvbURyaXZlcnNbZHJpdmVyTmFtZV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRHJpdmVyIG5vdCBmb3VuZC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGV4ZWN1dGVUd29DYWxsYmFja3MoZ2V0RHJpdmVyUHJvbWlzZSwgY2FsbGJhY2ssIGVycm9yQ2FsbGJhY2spO1xuICAgICAgICByZXR1cm4gZ2V0RHJpdmVyUHJvbWlzZTtcbiAgICB9O1xuXG4gICAgTG9jYWxGb3JhZ2UucHJvdG90eXBlLmdldFNlcmlhbGl6ZXIgPSBmdW5jdGlvbiBnZXRTZXJpYWxpemVyKGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBzZXJpYWxpemVyUHJvbWlzZSA9IFByb21pc2UkMS5yZXNvbHZlKGxvY2FsZm9yYWdlU2VyaWFsaXplcik7XG4gICAgICAgIGV4ZWN1dGVUd29DYWxsYmFja3Moc2VyaWFsaXplclByb21pc2UsIGNhbGxiYWNrKTtcbiAgICAgICAgcmV0dXJuIHNlcmlhbGl6ZXJQcm9taXNlO1xuICAgIH07XG5cbiAgICBMb2NhbEZvcmFnZS5wcm90b3R5cGUucmVhZHkgPSBmdW5jdGlvbiByZWFkeShjYWxsYmFjaykge1xuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHByb21pc2UgPSBzZWxmLl9kcml2ZXJTZXQudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoc2VsZi5fcmVhZHkgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBzZWxmLl9yZWFkeSA9IHNlbGYuX2luaXREcml2ZXIoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHNlbGYuX3JlYWR5O1xuICAgICAgICB9KTtcblxuICAgICAgICBleGVjdXRlVHdvQ2FsbGJhY2tzKHByb21pc2UsIGNhbGxiYWNrLCBjYWxsYmFjayk7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH07XG5cbiAgICBMb2NhbEZvcmFnZS5wcm90b3R5cGUuc2V0RHJpdmVyID0gZnVuY3Rpb24gc2V0RHJpdmVyKGRyaXZlcnMsIGNhbGxiYWNrLCBlcnJvckNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgICAgICBpZiAoIWlzQXJyYXkoZHJpdmVycykpIHtcbiAgICAgICAgICAgIGRyaXZlcnMgPSBbZHJpdmVyc107XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc3VwcG9ydGVkRHJpdmVycyA9IHRoaXMuX2dldFN1cHBvcnRlZERyaXZlcnMoZHJpdmVycyk7XG5cbiAgICAgICAgZnVuY3Rpb24gc2V0RHJpdmVyVG9Db25maWcoKSB7XG4gICAgICAgICAgICBzZWxmLl9jb25maWcuZHJpdmVyID0gc2VsZi5kcml2ZXIoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGV4dGVuZFNlbGZXaXRoRHJpdmVyKGRyaXZlcikge1xuICAgICAgICAgICAgc2VsZi5fZXh0ZW5kKGRyaXZlcik7XG4gICAgICAgICAgICBzZXREcml2ZXJUb0NvbmZpZygpO1xuXG4gICAgICAgICAgICBzZWxmLl9yZWFkeSA9IHNlbGYuX2luaXRTdG9yYWdlKHNlbGYuX2NvbmZpZyk7XG4gICAgICAgICAgICByZXR1cm4gc2VsZi5fcmVhZHk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBpbml0RHJpdmVyKHN1cHBvcnRlZERyaXZlcnMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnJlbnREcml2ZXJJbmRleCA9IDA7XG5cbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBkcml2ZXJQcm9taXNlTG9vcCgpIHtcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGN1cnJlbnREcml2ZXJJbmRleCA8IHN1cHBvcnRlZERyaXZlcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZHJpdmVyTmFtZSA9IHN1cHBvcnRlZERyaXZlcnNbY3VycmVudERyaXZlckluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnREcml2ZXJJbmRleCsrO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYkluZm8gPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fcmVhZHkgPSBudWxsO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5nZXREcml2ZXIoZHJpdmVyTmFtZSkudGhlbihleHRlbmRTZWxmV2l0aERyaXZlcilbXCJjYXRjaFwiXShkcml2ZXJQcm9taXNlTG9vcCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBzZXREcml2ZXJUb0NvbmZpZygpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ05vIGF2YWlsYWJsZSBzdG9yYWdlIG1ldGhvZCBmb3VuZC4nKTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZHJpdmVyU2V0ID0gUHJvbWlzZSQxLnJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLl9kcml2ZXJTZXQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGRyaXZlclByb21pc2VMb29wKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGhlcmUgbWlnaHQgYmUgYSBkcml2ZXIgaW5pdGlhbGl6YXRpb24gaW4gcHJvZ3Jlc3NcbiAgICAgICAgLy8gc28gd2FpdCBmb3IgaXQgdG8gZmluaXNoIGluIG9yZGVyIHRvIGF2b2lkIGEgcG9zc2libGVcbiAgICAgICAgLy8gcmFjZSBjb25kaXRpb24gdG8gc2V0IF9kYkluZm9cbiAgICAgICAgdmFyIG9sZERyaXZlclNldERvbmUgPSB0aGlzLl9kcml2ZXJTZXQgIT09IG51bGwgPyB0aGlzLl9kcml2ZXJTZXRbXCJjYXRjaFwiXShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZSQxLnJlc29sdmUoKTtcbiAgICAgICAgfSkgOiBQcm9taXNlJDEucmVzb2x2ZSgpO1xuXG4gICAgICAgIHRoaXMuX2RyaXZlclNldCA9IG9sZERyaXZlclNldERvbmUudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgZHJpdmVyTmFtZSA9IHN1cHBvcnRlZERyaXZlcnNbMF07XG4gICAgICAgICAgICBzZWxmLl9kYkluZm8gPSBudWxsO1xuICAgICAgICAgICAgc2VsZi5fcmVhZHkgPSBudWxsO1xuXG4gICAgICAgICAgICByZXR1cm4gc2VsZi5nZXREcml2ZXIoZHJpdmVyTmFtZSkudGhlbihmdW5jdGlvbiAoZHJpdmVyKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5fZHJpdmVyID0gZHJpdmVyLl9kcml2ZXI7XG4gICAgICAgICAgICAgICAgc2V0RHJpdmVyVG9Db25maWcoKTtcbiAgICAgICAgICAgICAgICBzZWxmLl93cmFwTGlicmFyeU1ldGhvZHNXaXRoUmVhZHkoKTtcbiAgICAgICAgICAgICAgICBzZWxmLl9pbml0RHJpdmVyID0gaW5pdERyaXZlcihzdXBwb3J0ZWREcml2ZXJzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVtcImNhdGNoXCJdKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNldERyaXZlclRvQ29uZmlnKCk7XG4gICAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ05vIGF2YWlsYWJsZSBzdG9yYWdlIG1ldGhvZCBmb3VuZC4nKTtcbiAgICAgICAgICAgIHNlbGYuX2RyaXZlclNldCA9IFByb21pc2UkMS5yZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuIHNlbGYuX2RyaXZlclNldDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZXhlY3V0ZVR3b0NhbGxiYWNrcyh0aGlzLl9kcml2ZXJTZXQsIGNhbGxiYWNrLCBlcnJvckNhbGxiYWNrKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RyaXZlclNldDtcbiAgICB9O1xuXG4gICAgTG9jYWxGb3JhZ2UucHJvdG90eXBlLnN1cHBvcnRzID0gZnVuY3Rpb24gc3VwcG9ydHMoZHJpdmVyTmFtZSkge1xuICAgICAgICByZXR1cm4gISFkcml2ZXJTdXBwb3J0W2RyaXZlck5hbWVdO1xuICAgIH07XG5cbiAgICBMb2NhbEZvcmFnZS5wcm90b3R5cGUuX2V4dGVuZCA9IGZ1bmN0aW9uIF9leHRlbmQobGlicmFyeU1ldGhvZHNBbmRQcm9wZXJ0aWVzKSB7XG4gICAgICAgIGV4dGVuZCh0aGlzLCBsaWJyYXJ5TWV0aG9kc0FuZFByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICBMb2NhbEZvcmFnZS5wcm90b3R5cGUuX2dldFN1cHBvcnRlZERyaXZlcnMgPSBmdW5jdGlvbiBfZ2V0U3VwcG9ydGVkRHJpdmVycyhkcml2ZXJzKSB7XG4gICAgICAgIHZhciBzdXBwb3J0ZWREcml2ZXJzID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBkcml2ZXJzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgZHJpdmVyTmFtZSA9IGRyaXZlcnNbaV07XG4gICAgICAgICAgICBpZiAodGhpcy5zdXBwb3J0cyhkcml2ZXJOYW1lKSkge1xuICAgICAgICAgICAgICAgIHN1cHBvcnRlZERyaXZlcnMucHVzaChkcml2ZXJOYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3VwcG9ydGVkRHJpdmVycztcbiAgICB9O1xuXG4gICAgTG9jYWxGb3JhZ2UucHJvdG90eXBlLl93cmFwTGlicmFyeU1ldGhvZHNXaXRoUmVhZHkgPSBmdW5jdGlvbiBfd3JhcExpYnJhcnlNZXRob2RzV2l0aFJlYWR5KCkge1xuICAgICAgICAvLyBBZGQgYSBzdHViIGZvciBlYWNoIGRyaXZlciBBUEkgbWV0aG9kIHRoYXQgZGVsYXlzIHRoZSBjYWxsIHRvIHRoZVxuICAgICAgICAvLyBjb3JyZXNwb25kaW5nIGRyaXZlciBtZXRob2QgdW50aWwgbG9jYWxGb3JhZ2UgaXMgcmVhZHkuIFRoZXNlIHN0dWJzXG4gICAgICAgIC8vIHdpbGwgYmUgcmVwbGFjZWQgYnkgdGhlIGRyaXZlciBtZXRob2RzIGFzIHNvb24gYXMgdGhlIGRyaXZlciBpc1xuICAgICAgICAvLyBsb2FkZWQsIHNvIHRoZXJlIGlzIG5vIHBlcmZvcm1hbmNlIGltcGFjdC5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBMaWJyYXJ5TWV0aG9kcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY2FsbFdoZW5SZWFkeSh0aGlzLCBMaWJyYXJ5TWV0aG9kc1tpXSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgTG9jYWxGb3JhZ2UucHJvdG90eXBlLmNyZWF0ZUluc3RhbmNlID0gZnVuY3Rpb24gY3JlYXRlSW5zdGFuY2Uob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gbmV3IExvY2FsRm9yYWdlKG9wdGlvbnMpO1xuICAgIH07XG5cbiAgICByZXR1cm4gTG9jYWxGb3JhZ2U7XG59KCk7XG5cbi8vIFRoZSBhY3R1YWwgbG9jYWxGb3JhZ2Ugb2JqZWN0IHRoYXQgd2UgZXhwb3NlIGFzIGEgbW9kdWxlIG9yIHZpYSBhXG4vLyBnbG9iYWwuIEl0J3MgZXh0ZW5kZWQgYnkgcHVsbGluZyBpbiBvbmUgb2Ygb3VyIG90aGVyIGxpYnJhcmllcy5cblxuXG52YXIgbG9jYWxmb3JhZ2VfanMgPSBuZXcgTG9jYWxGb3JhZ2UoKTtcblxubW9kdWxlLmV4cG9ydHMgPSBsb2NhbGZvcmFnZV9qcztcblxufSx7XCIzXCI6M31dfSx7fSxbNF0pKDQpXG59KTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL3R5cGUnKTtcbiIsIi8qIVxuICogdHlwZS1kZXRlY3RcbiAqIENvcHlyaWdodChjKSAyMDEzIGpha2UgbHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBQcmltYXJ5IEV4cG9ydHNcbiAqL1xuXG52YXIgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZ2V0VHlwZTtcblxuLyohXG4gKiBEZXRlY3RhYmxlIGphdmFzY3JpcHQgbmF0aXZlc1xuICovXG5cbnZhciBuYXRpdmVzID0ge1xuICAgICdbb2JqZWN0IEFycmF5XSc6ICdhcnJheSdcbiAgLCAnW29iamVjdCBSZWdFeHBdJzogJ3JlZ2V4cCdcbiAgLCAnW29iamVjdCBGdW5jdGlvbl0nOiAnZnVuY3Rpb24nXG4gICwgJ1tvYmplY3QgQXJndW1lbnRzXSc6ICdhcmd1bWVudHMnXG4gICwgJ1tvYmplY3QgRGF0ZV0nOiAnZGF0ZSdcbn07XG5cbi8qKlxuICogIyMjIHR5cGVPZiAob2JqKVxuICpcbiAqIFVzZSBzZXZlcmFsIGRpZmZlcmVudCB0ZWNobmlxdWVzIHRvIGRldGVybWluZVxuICogdGhlIHR5cGUgb2Ygb2JqZWN0IGJlaW5nIHRlc3RlZC5cbiAqXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gKiBAcmV0dXJuIHtTdHJpbmd9IG9iamVjdCB0eXBlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGdldFR5cGUgKG9iaikge1xuICB2YXIgc3RyID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaik7XG4gIGlmIChuYXRpdmVzW3N0cl0pIHJldHVybiBuYXRpdmVzW3N0cl07XG4gIGlmIChvYmogPT09IG51bGwpIHJldHVybiAnbnVsbCc7XG4gIGlmIChvYmogPT09IHVuZGVmaW5lZCkgcmV0dXJuICd1bmRlZmluZWQnO1xuICBpZiAob2JqID09PSBPYmplY3Qob2JqKSkgcmV0dXJuICdvYmplY3QnO1xuICByZXR1cm4gdHlwZW9mIG9iajtcbn1cblxuZXhwb3J0cy5MaWJyYXJ5ID0gTGlicmFyeTtcblxuLyoqXG4gKiAjIyMgTGlicmFyeVxuICpcbiAqIENyZWF0ZSBhIHJlcG9zaXRvcnkgZm9yIGN1c3RvbSB0eXBlIGRldGVjdGlvbi5cbiAqXG4gKiBgYGBqc1xuICogdmFyIGxpYiA9IG5ldyB0eXBlLkxpYnJhcnk7XG4gKiBgYGBcbiAqXG4gKi9cblxuZnVuY3Rpb24gTGlicmFyeSAoKSB7XG4gIHRoaXMudGVzdHMgPSB7fTtcbn1cblxuLyoqXG4gKiAjIyMjIC5vZiAob2JqKVxuICpcbiAqIEV4cG9zZSByZXBsYWNlbWVudCBgdHlwZW9mYCBkZXRlY3Rpb24gdG8gdGhlIGxpYnJhcnkuXG4gKlxuICogYGBganNcbiAqIGlmICgnc3RyaW5nJyA9PT0gbGliLm9mKCdoZWxsbyB3b3JsZCcpKSB7XG4gKiAgIC8vIC4uLlxuICogfVxuICogYGBgXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0IHRvIHRlc3RcbiAqIEByZXR1cm4ge1N0cmluZ30gdHlwZVxuICovXG5cbkxpYnJhcnkucHJvdG90eXBlLm9mID0gZ2V0VHlwZTtcblxuLyoqXG4gKiAjIyMjIC5kZWZpbmUgKHR5cGUsIHRlc3QpXG4gKlxuICogQWRkIGEgdGVzdCB0byBmb3IgdGhlIGAudGVzdCgpYCBhc3NlcnRpb24uXG4gKlxuICogQ2FuIGJlIGRlZmluZWQgYXMgYSByZWd1bGFyIGV4cHJlc3Npb246XG4gKlxuICogYGBganNcbiAqIGxpYi5kZWZpbmUoJ2ludCcsIC9eWzAtOV0rJC8pO1xuICogYGBgXG4gKlxuICogLi4uIG9yIGFzIGEgZnVuY3Rpb246XG4gKlxuICogYGBganNcbiAqIGxpYi5kZWZpbmUoJ2JsbicsIGZ1bmN0aW9uIChvYmopIHtcbiAqICAgaWYgKCdib29sZWFuJyA9PT0gbGliLm9mKG9iaikpIHJldHVybiB0cnVlO1xuICogICB2YXIgYmxucyA9IFsgJ3llcycsICdubycsICd0cnVlJywgJ2ZhbHNlJywgMSwgMCBdO1xuICogICBpZiAoJ3N0cmluZycgPT09IGxpYi5vZihvYmopKSBvYmogPSBvYmoudG9Mb3dlckNhc2UoKTtcbiAqICAgcmV0dXJuICEhIH5ibG5zLmluZGV4T2Yob2JqKTtcbiAqIH0pO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7UmVnRXhwfEZ1bmN0aW9ufSB0ZXN0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkxpYnJhcnkucHJvdG90eXBlLmRlZmluZSA9IGZ1bmN0aW9uICh0eXBlLCB0ZXN0KSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSByZXR1cm4gdGhpcy50ZXN0c1t0eXBlXTtcbiAgdGhpcy50ZXN0c1t0eXBlXSA9IHRlc3Q7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiAjIyMjIC50ZXN0IChvYmosIHRlc3QpXG4gKlxuICogQXNzZXJ0IHRoYXQgYW4gb2JqZWN0IGlzIG9mIHR5cGUuIFdpbGwgZmlyc3RcbiAqIGNoZWNrIG5hdGl2ZXMsIGFuZCBpZiB0aGF0IGRvZXMgbm90IHBhc3MgaXQgd2lsbFxuICogdXNlIHRoZSB1c2VyIGRlZmluZWQgY3VzdG9tIHRlc3RzLlxuICpcbiAqIGBgYGpzXG4gKiBhc3NlcnQobGliLnRlc3QoJzEnLCAnaW50JykpO1xuICogYXNzZXJ0KGxpYi50ZXN0KCd5ZXMnLCAnYmxuJykpO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICogQHJldHVybiB7Qm9vbGVhbn0gcmVzdWx0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkxpYnJhcnkucHJvdG90eXBlLnRlc3QgPSBmdW5jdGlvbiAob2JqLCB0eXBlKSB7XG4gIGlmICh0eXBlID09PSBnZXRUeXBlKG9iaikpIHJldHVybiB0cnVlO1xuICB2YXIgdGVzdCA9IHRoaXMudGVzdHNbdHlwZV07XG5cbiAgaWYgKHRlc3QgJiYgJ3JlZ2V4cCcgPT09IGdldFR5cGUodGVzdCkpIHtcbiAgICByZXR1cm4gdGVzdC50ZXN0KG9iaik7XG4gIH0gZWxzZSBpZiAodGVzdCAmJiAnZnVuY3Rpb24nID09PSBnZXRUeXBlKHRlc3QpKSB7XG4gICAgcmV0dXJuIHRlc3Qob2JqKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoJ1R5cGUgdGVzdCBcIicgKyB0eXBlICsgJ1wiIG5vdCBkZWZpbmVkIG9yIGludmFsaWQuJyk7XG4gIH1cbn07XG4iLCIvKiFcbiAqIHR5cGUtZGV0ZWN0XG4gKiBDb3B5cmlnaHQoYykgMjAxMyBqYWtlIGx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qIVxuICogUHJpbWFyeSBFeHBvcnRzXG4gKi9cblxudmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGdldFR5cGU7XG5cbi8qKlxuICogIyMjIHR5cGVPZiAob2JqKVxuICpcbiAqIFVzZSBzZXZlcmFsIGRpZmZlcmVudCB0ZWNobmlxdWVzIHRvIGRldGVybWluZVxuICogdGhlIHR5cGUgb2Ygb2JqZWN0IGJlaW5nIHRlc3RlZC5cbiAqXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gKiBAcmV0dXJuIHtTdHJpbmd9IG9iamVjdCB0eXBlXG4gKiBAYXBpIHB1YmxpY1xuICovXG52YXIgb2JqZWN0VHlwZVJlZ2V4cCA9IC9eXFxbb2JqZWN0ICguKilcXF0kLztcblxuZnVuY3Rpb24gZ2V0VHlwZShvYmopIHtcbiAgdmFyIHR5cGUgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKS5tYXRjaChvYmplY3RUeXBlUmVnZXhwKVsxXS50b0xvd2VyQ2FzZSgpO1xuICAvLyBMZXQgXCJuZXcgU3RyaW5nKCcnKVwiIHJldHVybiAnb2JqZWN0J1xuICBpZiAodHlwZW9mIFByb21pc2UgPT09ICdmdW5jdGlvbicgJiYgb2JqIGluc3RhbmNlb2YgUHJvbWlzZSkgcmV0dXJuICdwcm9taXNlJztcbiAgLy8gUGhhbnRvbUpTIGhhcyB0eXBlIFwiRE9NV2luZG93XCIgZm9yIG51bGxcbiAgaWYgKG9iaiA9PT0gbnVsbCkgcmV0dXJuICdudWxsJztcbiAgLy8gUGhhbnRvbUpTIGhhcyB0eXBlIFwiRE9NV2luZG93XCIgZm9yIHVuZGVmaW5lZFxuICBpZiAob2JqID09PSB1bmRlZmluZWQpIHJldHVybiAndW5kZWZpbmVkJztcbiAgcmV0dXJuIHR5cGU7XG59XG5cbmV4cG9ydHMuTGlicmFyeSA9IExpYnJhcnk7XG5cbi8qKlxuICogIyMjIExpYnJhcnlcbiAqXG4gKiBDcmVhdGUgYSByZXBvc2l0b3J5IGZvciBjdXN0b20gdHlwZSBkZXRlY3Rpb24uXG4gKlxuICogYGBganNcbiAqIHZhciBsaWIgPSBuZXcgdHlwZS5MaWJyYXJ5O1xuICogYGBgXG4gKlxuICovXG5cbmZ1bmN0aW9uIExpYnJhcnkoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBMaWJyYXJ5KSkgcmV0dXJuIG5ldyBMaWJyYXJ5KCk7XG4gIHRoaXMudGVzdHMgPSB7fTtcbn1cblxuLyoqXG4gKiAjIyMjIC5vZiAob2JqKVxuICpcbiAqIEV4cG9zZSByZXBsYWNlbWVudCBgdHlwZW9mYCBkZXRlY3Rpb24gdG8gdGhlIGxpYnJhcnkuXG4gKlxuICogYGBganNcbiAqIGlmICgnc3RyaW5nJyA9PT0gbGliLm9mKCdoZWxsbyB3b3JsZCcpKSB7XG4gKiAgIC8vIC4uLlxuICogfVxuICogYGBgXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0IHRvIHRlc3RcbiAqIEByZXR1cm4ge1N0cmluZ30gdHlwZVxuICovXG5cbkxpYnJhcnkucHJvdG90eXBlLm9mID0gZ2V0VHlwZTtcblxuLyoqXG4gKiAjIyMjIC5kZWZpbmUgKHR5cGUsIHRlc3QpXG4gKlxuICogQWRkIGEgdGVzdCB0byBmb3IgdGhlIGAudGVzdCgpYCBhc3NlcnRpb24uXG4gKlxuICogQ2FuIGJlIGRlZmluZWQgYXMgYSByZWd1bGFyIGV4cHJlc3Npb246XG4gKlxuICogYGBganNcbiAqIGxpYi5kZWZpbmUoJ2ludCcsIC9eWzAtOV0rJC8pO1xuICogYGBgXG4gKlxuICogLi4uIG9yIGFzIGEgZnVuY3Rpb246XG4gKlxuICogYGBganNcbiAqIGxpYi5kZWZpbmUoJ2JsbicsIGZ1bmN0aW9uIChvYmopIHtcbiAqICAgaWYgKCdib29sZWFuJyA9PT0gbGliLm9mKG9iaikpIHJldHVybiB0cnVlO1xuICogICB2YXIgYmxucyA9IFsgJ3llcycsICdubycsICd0cnVlJywgJ2ZhbHNlJywgMSwgMCBdO1xuICogICBpZiAoJ3N0cmluZycgPT09IGxpYi5vZihvYmopKSBvYmogPSBvYmoudG9Mb3dlckNhc2UoKTtcbiAqICAgcmV0dXJuICEhIH5ibG5zLmluZGV4T2Yob2JqKTtcbiAqIH0pO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7UmVnRXhwfEZ1bmN0aW9ufSB0ZXN0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkxpYnJhcnkucHJvdG90eXBlLmRlZmluZSA9IGZ1bmN0aW9uKHR5cGUsIHRlc3QpIHtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHJldHVybiB0aGlzLnRlc3RzW3R5cGVdO1xuICB0aGlzLnRlc3RzW3R5cGVdID0gdGVzdDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqICMjIyMgLnRlc3QgKG9iaiwgdGVzdClcbiAqXG4gKiBBc3NlcnQgdGhhdCBhbiBvYmplY3QgaXMgb2YgdHlwZS4gV2lsbCBmaXJzdFxuICogY2hlY2sgbmF0aXZlcywgYW5kIGlmIHRoYXQgZG9lcyBub3QgcGFzcyBpdCB3aWxsXG4gKiB1c2UgdGhlIHVzZXIgZGVmaW5lZCBjdXN0b20gdGVzdHMuXG4gKlxuICogYGBganNcbiAqIGFzc2VydChsaWIudGVzdCgnMScsICdpbnQnKSk7XG4gKiBhc3NlcnQobGliLnRlc3QoJ3llcycsICdibG4nKSk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge01peGVkfSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuTGlicmFyeS5wcm90b3R5cGUudGVzdCA9IGZ1bmN0aW9uKG9iaiwgdHlwZSkge1xuICBpZiAodHlwZSA9PT0gZ2V0VHlwZShvYmopKSByZXR1cm4gdHJ1ZTtcbiAgdmFyIHRlc3QgPSB0aGlzLnRlc3RzW3R5cGVdO1xuXG4gIGlmICh0ZXN0ICYmICdyZWdleHAnID09PSBnZXRUeXBlKHRlc3QpKSB7XG4gICAgcmV0dXJuIHRlc3QudGVzdChvYmopO1xuICB9IGVsc2UgaWYgKHRlc3QgJiYgJ2Z1bmN0aW9uJyA9PT0gZ2V0VHlwZSh0ZXN0KSkge1xuICAgIHJldHVybiB0ZXN0KG9iaik7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCdUeXBlIHRlc3QgXCInICsgdHlwZSArICdcIiBub3QgZGVmaW5lZCBvciBpbnZhbGlkLicpO1xuICB9XG59O1xuIiwiKGZ1bmN0aW9uIChkb2N1bWVudCwgd2luZG93KSB7XG4gIC8vIERFUEVOREVOQ0lFU1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBjb25zdCBsb2NhbGZvcmFnZSA9IHJlcXVpcmUoJ2xvY2FsZm9yYWdlJyk7XG4gIGNvbnN0IHByb2JzID0gcmVxdWlyZSgncGpzLXByb2JsZW1zJyk7XG4gIGNvbnN0IGRlZGVudCA9IHJlcXVpcmUoJ2RlZGVudCcpO1xuICBjb25zdCBhc3NlcnQgPSByZXF1aXJlKCdjaGFpJykuYXNzZXJ0O1xuXG4gIC8vIFBST0JMRU0gVEVNUExBVEUgTklDRS1JRklDQVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgZnVuY3Rpb24gZGVkZW50U3RyaW5ncyhwcm9ibGVtcykge1xuICAgIHJldHVybiBwcm9ibGVtcy5tYXAocHJvYiA9PiB7XG4gICAgICBwcm9iLmdpdmVuID0gZGVkZW50KHByb2IuZ2l2ZW4pXG4gICAgICBwcm9iLmFuc3dlciA9IGRlZGVudChwcm9iLmFuc3dlcilcbiAgICAgIHJldHVybiBwcm9iXG4gICAgfSk7XG4gIH1cblxuXG4gIC8vIFBST0JMRU1TXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGxldCBwcm9ibGVtcyA9IFtdO1xuICBPYmplY3Qua2V5cyhwcm9icykuZm9yRWFjaChzdWJqZWN0ID0+IHtcbiAgICBwcm9ibGVtcy5wdXNoKC4uLnByb2JzW3N1YmplY3RdKTtcbiAgfSk7XG4gIHByb2JsZW1zID0gZGVkZW50U3RyaW5ncyhwcm9ibGVtcylcbiAgY29uc29sZS5sb2coJ3Byb2JsZW1zOicsIHByb2JsZW1zKTtcblxuXG5cbiAgLy8gQ09ORklHXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIC8vIEhvaXN0IGN1cnJlbnQgcHJvYmxlbVxuICBsZXQgY3VycmVudFByb2JsZW07XG4gIC8vIEtleXMgdG8gaWdub3JlIHdoaWxlIHVzZXIgaXMgbmF2aWdhdGluZyBhcm91bmQgdGhlIHRleHRhcmVhIGJ1dCBub3QgY2hhbmdpbmcgYW55IGNvZGVcbiAgY29uc3QgaWdub3JlS2V5Q29kZXMgPSBbXG4gICAgOSwgLy8gVGFiXG4gICAgMzcsIC8vIExlZnQgYXJyb3dcbiAgICAzOSwgLy8gUmlnaHQgYXJyb3dcbiAgICAzOCwgLy8gVXAgYXJyb3dcbiAgICA0MCAvLyBEb3duIGFycm93XG4gIF07XG5cbiAgbGV0IGNvbmZpZyA9IHtcbiAgICBzaHVmZmxlOiB0cnVlLFxuICAgIHRpbWVyOiBmYWxzZSxcbiAgICBjdXJyZW50SW5kZXg6IDBcbiAgfTtcblxuICAvLyBQdWxsIGNvbmZpZyBmcm9tIGxvY2FsZm9yYWdlXG4gIGxvY2FsZm9yYWdlXG4gICAgLmdldEl0ZW0oJ2pzX3ByYWN0aWNlX2NvbmZpZycpXG4gICAgLnRoZW4odmFsID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKCdsb2NhbGZvcmFnZSB2YWw6JywgdmFsKTtcbiAgICAgIGlmICh2YWwpIHtcbiAgICAgICAgY29uZmlnID0gdmFsO1xuICAgICAgfVxuICAgICAgbG9hZEFwcChjb25maWcpO1xuICAgIH0pXG4gICAgLmNhdGNoKGVyciA9PiB7XG4gICAgICBjb25zb2xlLmxvZygnbG9jYWxmb3JhZ2UgZXJyOicsIGVycik7XG4gICAgICBsb2FkQXBwKGNvbmZpZyk7XG4gICAgfSk7XG5cbiAgZnVuY3Rpb24gdXBkYXRlTG9jYWxzdG9yZShjb25maWcpIHtcbiAgICByZXR1cm4gbG9jYWxmb3JhZ2VcbiAgICAgIC5zZXRJdGVtKCdqc19wcmFjdGljZV9jb25maWcnLCBjb25maWcpXG4gICAgICAudGhlbih2YWwgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnU2V0dGluZ3MgdXBkYXRlZDonLCB2YWwpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnU2V0dGluZ3MgdXBkYXRlIGVycm9yOicsIGVycik7XG4gICAgICB9KTtcbiAgfVxuXG5cbiAgLy8gVUlcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgLy8gZWxlbWVudHNcbiAgY29uc3QgcHJvYmxlbUVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Byb2JsZW0nKTtcbiAgY29uc3QgY29kZUVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvZGUnKTtcbiAgY29uc3QgdGVzdFN1aXRlRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdC1zdWl0ZScpO1xuICBjb25zdCB0ZXN0VG90YWxFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0LXRvdGFsJyk7XG4gIGNvbnN0IGV2YWxDb25zb2xlRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXZhbC1vdXRwdXQnKTtcbiAgY29uc3QgYXNzZXJ0Q29uc29sZUVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Fzc2VydC1vdXRwdXQnKTtcbiAgY29uc3Qgc2h1ZmZsZVByb2JsZW1zQnV0dG9uRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2h1ZmZsZS1wcm9ibGVtcycpO1xuICBjb25zdCBwcmV2aW91c1Byb2JsZW1CdXR0b25FbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwcmV2LXByb2JsZW0nKTtcbiAgY29uc3QgbmV4dFByb2JsZW1CdXR0b25FbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCduZXh0LXByb2JsZW0nKTtcblxuICAvLyBHZXQgaW5kZXhlc1xuICBmdW5jdGlvbiBnZXRSYW5kb21JbmRleChwcm9ibGVtc0Fycikge1xuICAgIGNvbnN0IGluZCA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHByb2JsZW1zQXJyLmxlbmd0aCk7XG4gICAgY29uZmlnLmN1cnJlbnRJbmRleCA9IGluZDtcbiAgICB1cGRhdGVMb2NhbHN0b3JlKGNvbmZpZyk7XG4gICAgcmV0dXJuIGluZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFByZXZpb3VzSW5kZXgocHJvYmxlbXNBcnIpIHtcbiAgICBsZXQgcHJvYkluZDtcbiAgICBjb25zdCBjdXJyZW50SW5kZXggPSBjb25maWcuY3VycmVudEluZGV4O1xuICAgIC8vIElmIGF0IGJlZ2lubmluZywgZ28gdG8gZW5kXG4gICAgaWYgKGN1cnJlbnRJbmRleCA9PT0gMCkge1xuICAgICAgcHJvYkluZCA9IHByb2JsZW1zQXJyLmxlbmd0aCAtIDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb2JJbmQgPSBjdXJyZW50SW5kZXggLSAxO1xuICAgIH1cbiAgICByZXR1cm4gcHJvYkluZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldE5leHRJbmRleChwcm9ibGVtc0Fycikge1xuICAgIGxldCBwcm9iSW5kO1xuICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IGNvbmZpZy5jdXJyZW50SW5kZXg7XG4gICAgLy8gSWYgYXQgZW5kIG9yIGludmFsaWQsIHJlc3RhcnQgc2VyaWVzXG4gICAgaWYgKGN1cnJlbnRJbmRleCA+PSBwcm9ibGVtc0Fyci5sZW5ndGggLSAxIHx8IGN1cnJlbnRJbmRleCA8IDApIHtcbiAgICAgIHByb2JJbmQgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm9iSW5kID0gY3VycmVudEluZGV4ICsgMTtcbiAgICB9XG4gICAgcmV0dXJuIHByb2JJbmQ7XG4gIH1cblxuICAvLyBHZXQgcHJvYmxlbXNcbiAgZnVuY3Rpb24gZ2V0Q3VycmVudFByb2JsZW0ocHJvYmxlbXNBcnIpIHtcbiAgICByZXR1cm4gcHJvYmxlbXNBcnJbY29uZmlnLmN1cnJlbnRJbmRleF07XG4gIH1cblxuICBmdW5jdGlvbiBwcmV2aW91c1Byb2JsZW0oKSB7XG4gICAgY29uc29sZS5sb2coJ3ByZXZpb3VzUHJvYmxlbSEnKTtcbiAgICBjb25maWcuY3VycmVudEluZGV4ID0gY29uZmlnLnNodWZmbGVcbiAgICAgID8gZ2V0UmFuZG9tSW5kZXgocHJvYmxlbXMpXG4gICAgICA6IGdldFByZXZpb3VzSW5kZXgocHJvYmxlbXMpO1xuICAgIHVwZGF0ZUxvY2Fsc3RvcmUoY29uZmlnKS50aGVuKCgpID0+IHtcbiAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG5leHRQcm9ibGVtKCkge1xuICAgIGNvbnNvbGUubG9nKCduZXh0UHJvYmxlbSEnKTtcbiAgICBjb25maWcuY3VycmVudEluZGV4ID0gY29uZmlnLnNodWZmbGVcbiAgICAgID8gZ2V0UmFuZG9tSW5kZXgocHJvYmxlbXMpXG4gICAgICA6IGdldE5leHRJbmRleChwcm9ibGVtcyk7XG4gICAgdXBkYXRlTG9jYWxzdG9yZShjb25maWcpLnRoZW4oKCkgPT4ge1xuICAgICAgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gdG9nZ2xlU2h1ZmZsZSgpIHtcbiAgICBjb25zb2xlLmxvZygndG9nZ2xlIHNodWZmbGUhJyk7XG4gICAgY29uZmlnLnNodWZmbGUgPSAhY29uZmlnLnNodWZmbGU7IC8vIEZsaXAgaXRcbiAgICBzaHVmZmxlUHJvYmxlbXNCdXR0b25FbC5jbGFzc0xpc3QudG9nZ2xlKCdhY3RpdmUnKTtcbiAgICB1cGRhdGVMb2NhbHN0b3JlKGNvbmZpZyk7XG4gIH1cblxuICBmdW5jdGlvbiBsb2FkUHJvYmxlbShwcm9ibGVtT2JqKSB7XG4gICAgY3VycmVudFByb2JsZW0gPSBwcm9ibGVtT2JqO1xuICAgIC8vIFByb2IgcXVlc3Rpb25cbiAgICBwcm9ibGVtRWwuaW5uZXJUZXh0ID0gcHJvYmxlbU9iai5wcm9tcHQ7XG4gICAgLy8gUHJvYiBnaXZlbiBjb2RlXG4gICAgaWYgKHByb2JsZW1PYmouZ2l2ZW4pIHtcbiAgICAgIGNvZGVFbC52YWx1ZSA9IHByb2JsZW1PYmouZ2l2ZW47XG4gICAgfVxuICAgIC8vIFNlZWQgdGhlIHRlc3RzLCBwYXNzIChpbml0ID0gdHJ1ZSkgYXMgc2Vjb25kIHBhcmFtXG4gICAgdGVzdFN1aXRlKG51bGwsIHRydWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlVGVzdHModGVzdFN0YXR1cywgaW5pdCkge1xuICAgIGlmIChpbml0ID09PSB0cnVlKSB7XG4gICAgICBidWlsZFRlc3RzKGN1cnJlbnRQcm9ibGVtLnRlc3RzKTtcbiAgICB9XG4gICAgdXBkYXRlVGVzdFN0YXR1cyh0ZXN0U3RhdHVzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1aWxkVGVzdHModGVzdHMpIHtcbiAgICBpZiAodGVzdHMpIHtcbiAgICAgIGNvbnN0IHRlc3RzRG9tID0gdGVzdHNcbiAgICAgICAgLm1hcCh0ZXN0ID0+IHtcbiAgICAgICAgICByZXR1cm4gYDxkaXYgY2xhc3M9XCJ0ZXN0IG1vbm9zcGFjZVwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRlc3Qtc3RhdGVcIj5bJiN4MjcxODtdPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGVzdC1uYW1lXCI+JHt0ZXN0Lm5hbWV9PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgfSlcbiAgICAgICAgLmpvaW4oJycpO1xuICAgICAgdGVzdFN1aXRlRWwuaW5uZXJIVE1MID0gdGVzdHNEb207XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlVGVzdFN0YXR1cyh0ZXN0U3RhdHVzZXMpIHtcbiAgICBpZiAoIXRlc3RTdGF0dXNlcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyB0ZXN0U3RhdHVzZXMgcHJvdmlkZWQuJyk7XG4gICAgfVxuICAgIC8vIEZpbmQgb3V0IGlmIGFsbCB0ZXN0cyBoYXZlIHBhc3NlZCBvciBub3RcbiAgICBsZXQgYWxsUGFzc2VkID0gdHJ1ZTtcbiAgICB0ZXN0U3RhdHVzZXMuZm9yRWFjaCh0ZXN0UGFzc2VkID0+IHtcbiAgICAgIGlmICh0ZXN0UGFzc2VkICE9PSB0cnVlKSB7XG4gICAgICAgIGFsbFBhc3NlZCA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbnN0IHRlc3RFbHMgPSBBcnJheS5mcm9tKHRlc3RTdWl0ZUVsLnF1ZXJ5U2VsZWN0b3JBbGwoJy50ZXN0LXN0YXRlJykpO1xuICAgIHRlc3RFbHMuZm9yRWFjaCgodGVzdFN0YXR1c0VsLCBpdGVyKSA9PiB7XG4gICAgICBpZiAodGVzdFN0YXR1c2VzW2l0ZXJdID09PSB0cnVlKSB7XG4gICAgICAgIHRlc3RTdGF0dXNFbC5pbm5lckhUTUwgPSAnWyYjeDI3MTM7XSc7XG4gICAgICAgIHRlc3RTdGF0dXNFbC5jbGFzc0xpc3QucmVtb3ZlKCdmYWlsJyk7XG4gICAgICAgIHRlc3RTdGF0dXNFbC5jbGFzc0xpc3QuYWRkKCdwYXNzJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ZXN0U3RhdHVzRWwuaW5uZXJIVE1MID0gJ1smI3gyNzE4O10nO1xuICAgICAgICB0ZXN0U3RhdHVzRWwuY2xhc3NMaXN0LnJlbW92ZSgncGFzcycpO1xuICAgICAgICB0ZXN0U3RhdHVzRWwuY2xhc3NMaXN0LmFkZCgnZmFpbCcpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKGFsbFBhc3NlZCA9PT0gdHJ1ZSkge1xuICAgICAgdGVzdFRvdGFsRWwuaW5uZXJUZXh0ID0gJ1BBU1MnO1xuICAgICAgdGVzdFRvdGFsRWwuY2xhc3NMaXN0LnJlbW92ZSgnZmFpbCcpO1xuICAgICAgdGVzdFRvdGFsRWwuY2xhc3NMaXN0LmFkZCgncGFzcycpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0ZXN0VG90YWxFbC5pbm5lclRleHQgPSAnRkFJTCc7XG4gICAgICB0ZXN0VG90YWxFbC5jbGFzc0xpc3QucmVtb3ZlKCdwYXNzJyk7XG4gICAgICB0ZXN0VG90YWxFbC5jbGFzc0xpc3QuYWRkKCdmYWlsJyk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcHJpbnRBc3NlcnRFcnJvcihlcnJPYmopIHtcbiAgICAvLyBNYWtlIGVsZW1lbnQgc3RyaW5nXG4gICAgbGV0IGlubmVyID0gJyc7XG4gICAgaWYgKGVyck9iaiAhPT0gbnVsbCkge1xuICAgICAgaW5uZXIgPSBgXG4gICAgICA8ZGl2IGNsYXNzPVwiYXNzZXJ0LWVycm9yXCI+XG4gICAgICAgIEV4cGVjdGVkOiAke0pTT04uc3RyaW5naWZ5KGVyck9iai5leHBlY3RlZCl9XG4gICAgICAgIEFjdHVhbDogJHtKU09OLnN0cmluZ2lmeShlcnJPYmouYWN0dWFsKX1cbiAgICAgIDwvZGl2PmA7XG4gICAgfVxuXG4gICAgLy8gUHJlcGVuZCBlbGVtZW50XG4gICAgYXNzZXJ0Q29uc29sZUVsLmlubmVySFRNTCA9IGlubmVyO1xuICB9XG5cbiAgZnVuY3Rpb24gcHJpbnRFdmFsT3V0cHV0KGVyck9iaiwgb3V0cHV0KSB7XG4gICAgLy8gTWFrZSBlbGVtZW50IHN0cmluZ1xuICAgIGxldCBpbm5lciA9ICcnO1xuICAgIGlmIChlcnJPYmogJiYgZXJyT2JqLm1lc3NhZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaW5uZXIgPSBgXG4gICAgICA8ZGl2IGNsYXNzPVwiYXNzZXJ0LWVycm9yXCI+XG4gICAgICAgIFN5bnRheCBFcnJvcjogJHtKU09OLnN0cmluZ2lmeShlcnJPYmoubWVzc2FnZSl9XG4gICAgICA8L2Rpdj5gO1xuICAgIH0gZWxzZSBpZiAob3V0cHV0KSB7XG4gICAgICBpbm5lciA9IGBcbiAgICAgIDxkaXYgY2xhc3M9XCJhc3NlcnQtZXJyb3JcIj5cbiAgICAgICAgT3V0cHV0OiAke0pTT04uc3RyaW5naWZ5KG91dHB1dCl9XG4gICAgICA8L2Rpdj5gO1xuICAgIH1cbiAgICAvLyBQcmVwZW5kIGVsZW1lbnRcbiAgICBldmFsQ29uc29sZUVsLmlubmVySFRNTCA9IGlubmVyO1xuICB9XG5cblxuICAvLyBWRVJJRklDQVRJT04gTE9HSUNcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgZnVuY3Rpb24gdGVzdFN1aXRlKGluaXQpIHtcbiAgICAvLyBSdW4gc3R1ZmZcbiAgICBjb25zdCBvdXRwdXQgPSBnZXRPdXRwdXQoY29kZUVsLnZhbHVlKTtcbiAgICAvLyBSdW4gdGVzdHMgb24gY29kZSwgcmV0dXJuIG9iamVjdC9hcnJheSBvZiB0ZXN0IHJlc3VsdHNcbiAgICBjb25zdCB0ZXN0ZWQgPSBydW5UZXN0cyhvdXRwdXQpO1xuICAgIC8vIFVwZGF0ZSBVSSB3aXRoIHJlc3VsdHNcbiAgICB1cGRhdGVUZXN0cyh0ZXN0ZWQsIGluaXQpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0T3V0cHV0KGNvZGUpIHtcbiAgICBsZXQgZXZhbGQgPSBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgZXZhbGQgPSBldmFsKGAoZnVuY3Rpb24oKXske2NvZGV9fSkoKWApOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWV2YWxcbiAgICAgIHByaW50RXZhbE91dHB1dChudWxsLCBldmFsZCk7IC8vIFByaW50IGN1cnJlbnQgb3V0cHV0XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBwcmludEV2YWxPdXRwdXQoZXJyKTtcbiAgICB9XG4gICAgcmV0dXJuIGV2YWxkO1xuICB9XG5cbiAgZnVuY3Rpb24gcnVuVGVzdHMob3V0cHV0KSB7XG4gICAgbGV0IHRlc3RlZCA9IGZhbHNlO1xuICAgIHRlc3RlZCA9IGN1cnJlbnRQcm9ibGVtLnRlc3RzLm1hcCh0ZXN0ID0+IHtcbiAgICAgIGxldCB0ZXN0T3V0Y29tZSA9IGZhbHNlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKG91dHB1dCkge1xuICAgICAgICAgIC8vIGNvbnN0IHRlc3RFdmFsID0gZXZhbCh0ZXN0LnRlc3QpO1xuXG4gICAgICAgICAgdGVzdE91dGNvbWUgPSBldmFsKHRlc3QudGVzdCk7XG4gICAgICAgICAgY29uc29sZS5sb2coJ3Rlc3RPdXRjb21lOicsIHRlc3RPdXRjb21lKTtcblxuICAgICAgICB9XG4gICAgICAgIHByaW50QXNzZXJ0RXJyb3IobnVsbCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgcHJpbnRBc3NlcnRFcnJvcihlcnIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRlc3RPdXRjb21lO1xuICAgIH0pO1xuICAgIHJldHVybiB0ZXN0ZWQ7XG4gIH1cblxuICAvLyBXcmFwcGVkIHRvIHByZXZlbnQgcmFjZSB3aXRoIGxvY2FsIGNvbmZpZyByZXRyaWV2YWxcbiAgZnVuY3Rpb24gbG9hZEFwcChjb25maWcpIHtcbiAgICBjb25zb2xlLmxvZygnbG9hZGluZyBhcHAhJyk7XG5cbiAgICAvLyBTaG93IGN1cnJlbnQgdG9nZ2xlIHN0YXRlXG4gICAgaWYgKGNvbmZpZy5zaHVmZmxlID09PSB0cnVlKSB7XG4gICAgICBzaHVmZmxlUHJvYmxlbXNCdXR0b25FbC5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcbiAgICB9XG5cbiAgICAvLyBCaW5kIGl0IHVwXG4gICAgY29kZUVsLmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgZSA9PiB7XG4gICAgICAvLyBJZiBub3QgYXJyb3cga2V5cyBvciBvdGhlciBub24tY2hhcmFjdGVyIGtleXNcbiAgICAgIGlmIChpZ25vcmVLZXlDb2Rlcy5pbmRleE9mKGUua2V5Q29kZSkgPT09IC0xKSB7XG4gICAgICAgIC8vIFJ1biB0ZXN0IHN1aXRlXG4gICAgICAgIHRlc3RTdWl0ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHNodWZmbGVQcm9ibGVtc0J1dHRvbkVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdG9nZ2xlU2h1ZmZsZSk7XG4gICAgcHJldmlvdXNQcm9ibGVtQnV0dG9uRWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBwcmV2aW91c1Byb2JsZW0pO1xuICAgIG5leHRQcm9ibGVtQnV0dG9uRWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBuZXh0UHJvYmxlbSk7XG5cbiAgICAvLyBTdGFydCBpdCB1cCFcbiAgICAvLyBMb2FkIGN1cnJlbnQgcHJvYmxlbVxuICAgIGNvbnN0IGN1cnJQcm9iID0gZ2V0Q3VycmVudFByb2JsZW0ocHJvYmxlbXMpO1xuICAgIGxvYWRQcm9ibGVtKGN1cnJQcm9iKTtcbiAgICAvLyBJbml0YWxpemVkIHRlc3Qgc3VpdGUgd2l0aCBzdGFydGluZyBmYWlsdXJlc1xuICAgIHRlc3RTdWl0ZSh0cnVlKTtcbiAgfVxufSkoZG9jdW1lbnQsIHdpbmRvdyk7XG4iXX0="} +>>>>>>> working import of external problem content diff --git a/public/service-worker.js b/public/service-worker.js index 9c5c5a3..f772c3b 100644 --- a/public/service-worker.js +++ b/public/service-worker.js @@ -1,2 +1,6 @@ +<<<<<<< HEAD "use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}var precacheConfig=[["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","a70702eeea1dbe4a401b7c23189eb7d3"],["/dist/js/bundle.min.js","5a4878a0d8d1655d9f3edbc1aee091b7"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]],cacheName="sw-precache-v3--"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(e){return e.redirected?("body"in e?Promise.resolve(e.body):e.blob()).then(function(t){return new Response(t,{headers:e.headers,status:e.status,statusText:e.statusText})}):Promise.resolve(e)},createCacheKey=function(e,t,n,r){var a=new URL(e);return r&&a.pathname.match(r)||(a.search+=(a.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),a.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,t){var n=new URL(e);return n.hash="",n.search=n.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),n.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],r=new URL(t,self.location),a=createCacheKey(r,hashParamName,n,!1);return[r.toString(),a]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(n){if(!t.has(n)){var r=new Request(n,{credentials:"same-origin"});return fetch(r).then(function(t){if(!t.ok)throw new Error("Request for "+n+" returned a response with status "+t.status);return cleanResponse(t).then(function(t){return e.put(n,t)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(n){return Promise.all(n.map(function(n){if(!t.has(n.url))return e.delete(n)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,n=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);t=urlsToCacheKeys.has(n);t||(n=addDirectoryIndex(n,"index.html"),t=urlsToCacheKeys.has(n));t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}); +======= +"use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}var precacheConfig=[["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","a70702eeea1dbe4a401b7c23189eb7d3"],["/dist/js/bundle.min.js","b811fe18d2d6a402297a71172a324d69"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]],cacheName="sw-precache-v3--"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(e){return e.redirected?("body"in e?Promise.resolve(e.body):e.blob()).then(function(t){return new Response(t,{headers:e.headers,status:e.status,statusText:e.statusText})}):Promise.resolve(e)},createCacheKey=function(e,t,n,r){var a=new URL(e);return r&&a.pathname.match(r)||(a.search+=(a.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),a.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,t){var n=new URL(e);return n.hash="",n.search=n.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),n.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],r=new URL(t,self.location),a=createCacheKey(r,hashParamName,n,!1);return[r.toString(),a]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(n){if(!t.has(n)){var r=new Request(n,{credentials:"same-origin"});return fetch(r).then(function(t){if(!t.ok)throw new Error("Request for "+n+" returned a response with status "+t.status);return cleanResponse(t).then(function(t){return e.put(n,t)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(n){return Promise.all(n.map(function(n){if(!t.has(n.url))return e.delete(n)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,n=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);t=urlsToCacheKeys.has(n);t||(n=addDirectoryIndex(n,"index.html"),t=urlsToCacheKeys.has(n));t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}); +>>>>>>> working import of external problem content //# sourceMappingURL=service-worker.js.map diff --git a/public/service-worker.js.map b/public/service-worker.js.map index 24d6d1d..7f72169 100644 --- a/public/service-worker.js.map +++ b/public/service-worker.js.map @@ -1 +1,5 @@ -{"version":3,"sources":["service-worker.js"],"names":["setOfCachedUrls","cache","keys","then","requests","map","request","url","urls","Set","precacheConfig","cacheName","self","registration","scope","ignoreUrlParametersMatching","addDirectoryIndex","originalUrl","index","URL","pathname","slice","toString","cleanResponse","originalResponse","redirected","Promise","resolve","body","blob","Response","headers","status","statusText","createCacheKey","paramName","paramValue","dontCacheBustUrlsMatching","match","search","encodeURIComponent","isPathWhitelisted","whitelist","absoluteUrlString","length","path","some","whitelistedPathRegex","stripIgnoredUrlParameters","hash","split","kv","filter","every","ignoredRegex","test","join","hashParamName","urlsToCacheKeys","Map","item","relativeUrl","absoluteUrl","location","cacheKey","addEventListener","event","waitUntil","caches","open","cachedUrls","all","Array","from","values","has","Request","credentials","fetch","response","ok","Error","responseToCache","put","skipWaiting","setOfExpectedUrls","existingRequests","existingRequest","delete","clients","claim","method","shouldRespond","respondWith","get","catch","e","console","warn"],"mappings":"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","file":"service-worker.js","sourcesContent":["/**\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n*/\n\n// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY!\n// This file should be overwritten as part of your build process.\n// If you need to extend the behavior of the generated service worker, the best approach is to write\n// additional code and include it using the importScripts option:\n// https://github.com/GoogleChrome/sw-precache#importscripts-arraystring\n//\n// Alternatively, it's possible to make changes to the underlying template file and then use that as the\n// new base for generating output, via the templateFilePath option:\n// https://github.com/GoogleChrome/sw-precache#templatefilepath-string\n//\n// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any\n// changes made to this original template file with your modified copy.\n\n// This generated service worker JavaScript will precache your site's resources.\n// The code needs to be saved in a .js file at the top-level of your site, and registered\n// from your pages in order to be used. See\n// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js\n// for an example of how you can register this script and handle various service worker events.\n\n/* eslint-env worker, serviceworker */\n/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */\n'use strict';\n\nvar precacheConfig = [[\"/dist/css/style.css\",\"ba4d66c91d1ed66848154a34ab4948cf\"],[\"/dist/img/back.svg\",\"898ada2a32ec64bd5b6959c22e8f231d\"],[\"/dist/img/monitor.svg\",\"348592da5567b5a3c46acfb5dcd341bc\"],[\"/dist/img/next.svg\",\"045593410b9f51390e750b9e1e7fff15\"],[\"/dist/img/reload.svg\",\"a0ab1b765280e4d22e6fb747042f6503\"],[\"/dist/img/shuffle.svg\",\"3a5e3c1bf04eb3493d8a2ffa547aa58f\"],[\"/dist/img/social-banner.png\",\"a70702eeea1dbe4a401b7c23189eb7d3\"],[\"/dist/js/bundle.min.js\",\"5a4878a0d8d1655d9f3edbc1aee091b7\"],[\"/dist/js/loadJS.js\",\"72c55936069f60560a386e46f462c73a\"],[\"/dist/js/sw-registration.js\",\"677217d8e642c1ccff69fc01c96b4431\"],[\"/index.html\",\"c7522a5d3255caca0f12c5282ef0644d\"]];\nvar cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');\n\n\nvar ignoreUrlParametersMatching = [/^utm_/];\n\n\n\nvar addDirectoryIndex = function (originalUrl, index) {\n var url = new URL(originalUrl);\n if (url.pathname.slice(-1) === '/') {\n url.pathname += index;\n }\n return url.toString();\n };\n\nvar cleanResponse = function (originalResponse) {\n // If this is not a redirected response, then we don't have to do anything.\n if (!originalResponse.redirected) {\n return Promise.resolve(originalResponse);\n }\n\n // Firefox 50 and below doesn't support the Response.body stream, so we may\n // need to read the entire body to memory as a Blob.\n var bodyPromise = 'body' in originalResponse ?\n Promise.resolve(originalResponse.body) :\n originalResponse.blob();\n\n return bodyPromise.then(function(body) {\n // new Response() is happy when passed either a stream or a Blob.\n return new Response(body, {\n headers: originalResponse.headers,\n status: originalResponse.status,\n statusText: originalResponse.statusText\n });\n });\n };\n\nvar createCacheKey = function (originalUrl, paramName, paramValue,\n dontCacheBustUrlsMatching) {\n // Create a new URL object to avoid modifying originalUrl.\n var url = new URL(originalUrl);\n\n // If dontCacheBustUrlsMatching is not set, or if we don't have a match,\n // then add in the extra cache-busting URL parameter.\n if (!dontCacheBustUrlsMatching ||\n !(url.pathname.match(dontCacheBustUrlsMatching))) {\n url.search += (url.search ? '&' : '') +\n encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);\n }\n\n return url.toString();\n };\n\nvar isPathWhitelisted = function (whitelist, absoluteUrlString) {\n // If the whitelist is empty, then consider all URLs to be whitelisted.\n if (whitelist.length === 0) {\n return true;\n }\n\n // Otherwise compare each path regex to the path of the URL passed in.\n var path = (new URL(absoluteUrlString)).pathname;\n return whitelist.some(function(whitelistedPathRegex) {\n return path.match(whitelistedPathRegex);\n });\n };\n\nvar stripIgnoredUrlParameters = function (originalUrl,\n ignoreUrlParametersMatching) {\n var url = new URL(originalUrl);\n // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290\n url.hash = '';\n\n url.search = url.search.slice(1) // Exclude initial '?'\n .split('&') // Split into an array of 'key=value' strings\n .map(function(kv) {\n return kv.split('='); // Split each 'key=value' string into a [key, value] array\n })\n .filter(function(kv) {\n return ignoreUrlParametersMatching.every(function(ignoredRegex) {\n return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.\n });\n })\n .map(function(kv) {\n return kv.join('='); // Join each [key, value] array into a 'key=value' string\n })\n .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each\n\n return url.toString();\n };\n\n\nvar hashParamName = '_sw-precache';\nvar urlsToCacheKeys = new Map(\n precacheConfig.map(function(item) {\n var relativeUrl = item[0];\n var hash = item[1];\n var absoluteUrl = new URL(relativeUrl, self.location);\n var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);\n return [absoluteUrl.toString(), cacheKey];\n })\n);\n\nfunction setOfCachedUrls(cache) {\n return cache.keys().then(function(requests) {\n return requests.map(function(request) {\n return request.url;\n });\n }).then(function(urls) {\n return new Set(urls);\n });\n}\n\nself.addEventListener('install', function(event) {\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return setOfCachedUrls(cache).then(function(cachedUrls) {\n return Promise.all(\n Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {\n // If we don't have a key matching url in the cache already, add it.\n if (!cachedUrls.has(cacheKey)) {\n var request = new Request(cacheKey, {credentials: 'same-origin'});\n return fetch(request).then(function(response) {\n // Bail out of installation unless we get back a 200 OK for\n // every request.\n if (!response.ok) {\n throw new Error('Request for ' + cacheKey + ' returned a ' +\n 'response with status ' + response.status);\n }\n\n return cleanResponse(response).then(function(responseToCache) {\n return cache.put(cacheKey, responseToCache);\n });\n });\n }\n })\n );\n });\n }).then(function() {\n \n // Force the SW to transition from installing -> active state\n return self.skipWaiting();\n \n })\n );\n});\n\nself.addEventListener('activate', function(event) {\n var setOfExpectedUrls = new Set(urlsToCacheKeys.values());\n\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return cache.keys().then(function(existingRequests) {\n return Promise.all(\n existingRequests.map(function(existingRequest) {\n if (!setOfExpectedUrls.has(existingRequest.url)) {\n return cache.delete(existingRequest);\n }\n })\n );\n });\n }).then(function() {\n \n return self.clients.claim();\n \n })\n );\n});\n\n\nself.addEventListener('fetch', function(event) {\n if (event.request.method === 'GET') {\n // Should we call event.respondWith() inside this fetch event handler?\n // This needs to be determined synchronously, which will give other fetch\n // handlers a chance to handle the request if need be.\n var shouldRespond;\n\n // First, remove all the ignored parameters and hash fragment, and see if we\n // have that URL in our cache. If so, great! shouldRespond will be true.\n var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);\n shouldRespond = urlsToCacheKeys.has(url);\n\n // If shouldRespond is false, check again, this time with 'index.html'\n // (or whatever the directoryIndex option is set to) at the end.\n var directoryIndex = 'index.html';\n if (!shouldRespond && directoryIndex) {\n url = addDirectoryIndex(url, directoryIndex);\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond is still false, check to see if this is a navigation\n // request, and if so, whether the URL matches navigateFallbackWhitelist.\n var navigateFallback = '';\n if (!shouldRespond &&\n navigateFallback &&\n (event.request.mode === 'navigate') &&\n isPathWhitelisted([], event.request.url)) {\n url = new URL(navigateFallback, self.location).toString();\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond was set to true at any point, then call\n // event.respondWith(), using the appropriate cache key.\n if (shouldRespond) {\n event.respondWith(\n caches.open(cacheName).then(function(cache) {\n return cache.match(urlsToCacheKeys.get(url)).then(function(response) {\n if (response) {\n return response;\n }\n throw Error('The cached response that was expected is missing.');\n });\n }).catch(function(e) {\n // Fall back to just fetch()ing the request if some unexpected error\n // prevented the cached response from being valid.\n console.warn('Couldn\\'t serve response for \"%s\" from cache: %O', event.request.url, e);\n return fetch(event.request);\n })\n );\n }\n }\n});\n\n\n\n\n\n\n\n"]} \ No newline at end of file +<<<<<<< HEAD +{"version":3,"sources":["service-worker.js"],"names":["setOfCachedUrls","cache","keys","then","requests","map","request","url","urls","Set","precacheConfig","cacheName","self","registration","scope","ignoreUrlParametersMatching","addDirectoryIndex","originalUrl","index","URL","pathname","slice","toString","cleanResponse","originalResponse","redirected","Promise","resolve","body","blob","Response","headers","status","statusText","createCacheKey","paramName","paramValue","dontCacheBustUrlsMatching","match","search","encodeURIComponent","isPathWhitelisted","whitelist","absoluteUrlString","length","path","some","whitelistedPathRegex","stripIgnoredUrlParameters","hash","split","kv","filter","every","ignoredRegex","test","join","hashParamName","urlsToCacheKeys","Map","item","relativeUrl","absoluteUrl","location","cacheKey","addEventListener","event","waitUntil","caches","open","cachedUrls","all","Array","from","values","has","Request","credentials","fetch","response","ok","Error","responseToCache","put","skipWaiting","setOfExpectedUrls","existingRequests","existingRequest","delete","clients","claim","method","shouldRespond","respondWith","get","catch","e","console","warn"],"mappings":"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","file":"service-worker.js","sourcesContent":["/**\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n*/\n\n// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY!\n// This file should be overwritten as part of your build process.\n// If you need to extend the behavior of the generated service worker, the best approach is to write\n// additional code and include it using the importScripts option:\n// https://github.com/GoogleChrome/sw-precache#importscripts-arraystring\n//\n// Alternatively, it's possible to make changes to the underlying template file and then use that as the\n// new base for generating output, via the templateFilePath option:\n// https://github.com/GoogleChrome/sw-precache#templatefilepath-string\n//\n// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any\n// changes made to this original template file with your modified copy.\n\n// This generated service worker JavaScript will precache your site's resources.\n// The code needs to be saved in a .js file at the top-level of your site, and registered\n// from your pages in order to be used. See\n// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js\n// for an example of how you can register this script and handle various service worker events.\n\n/* eslint-env worker, serviceworker */\n/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */\n'use strict';\n\nvar precacheConfig = [[\"/dist/css/style.css\",\"ba4d66c91d1ed66848154a34ab4948cf\"],[\"/dist/img/back.svg\",\"898ada2a32ec64bd5b6959c22e8f231d\"],[\"/dist/img/monitor.svg\",\"348592da5567b5a3c46acfb5dcd341bc\"],[\"/dist/img/next.svg\",\"045593410b9f51390e750b9e1e7fff15\"],[\"/dist/img/reload.svg\",\"a0ab1b765280e4d22e6fb747042f6503\"],[\"/dist/img/shuffle.svg\",\"3a5e3c1bf04eb3493d8a2ffa547aa58f\"],[\"/dist/img/social-banner.png\",\"a70702eeea1dbe4a401b7c23189eb7d3\"],[\"/dist/js/bundle.min.js\",\"5a4878a0d8d1655d9f3edbc1aee091b7\"],[\"/dist/js/loadJS.js\",\"72c55936069f60560a386e46f462c73a\"],[\"/dist/js/sw-registration.js\",\"677217d8e642c1ccff69fc01c96b4431\"],[\"/index.html\",\"c7522a5d3255caca0f12c5282ef0644d\"]];\nvar cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');\n\n\nvar ignoreUrlParametersMatching = [/^utm_/];\n\n\n\nvar addDirectoryIndex = function (originalUrl, index) {\n var url = new URL(originalUrl);\n if (url.pathname.slice(-1) === '/') {\n url.pathname += index;\n }\n return url.toString();\n };\n\nvar cleanResponse = function (originalResponse) {\n // If this is not a redirected response, then we don't have to do anything.\n if (!originalResponse.redirected) {\n return Promise.resolve(originalResponse);\n }\n\n // Firefox 50 and below doesn't support the Response.body stream, so we may\n // need to read the entire body to memory as a Blob.\n var bodyPromise = 'body' in originalResponse ?\n Promise.resolve(originalResponse.body) :\n originalResponse.blob();\n\n return bodyPromise.then(function(body) {\n // new Response() is happy when passed either a stream or a Blob.\n return new Response(body, {\n headers: originalResponse.headers,\n status: originalResponse.status,\n statusText: originalResponse.statusText\n });\n });\n };\n\nvar createCacheKey = function (originalUrl, paramName, paramValue,\n dontCacheBustUrlsMatching) {\n // Create a new URL object to avoid modifying originalUrl.\n var url = new URL(originalUrl);\n\n // If dontCacheBustUrlsMatching is not set, or if we don't have a match,\n // then add in the extra cache-busting URL parameter.\n if (!dontCacheBustUrlsMatching ||\n !(url.pathname.match(dontCacheBustUrlsMatching))) {\n url.search += (url.search ? '&' : '') +\n encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);\n }\n\n return url.toString();\n };\n\nvar isPathWhitelisted = function (whitelist, absoluteUrlString) {\n // If the whitelist is empty, then consider all URLs to be whitelisted.\n if (whitelist.length === 0) {\n return true;\n }\n\n // Otherwise compare each path regex to the path of the URL passed in.\n var path = (new URL(absoluteUrlString)).pathname;\n return whitelist.some(function(whitelistedPathRegex) {\n return path.match(whitelistedPathRegex);\n });\n };\n\nvar stripIgnoredUrlParameters = function (originalUrl,\n ignoreUrlParametersMatching) {\n var url = new URL(originalUrl);\n // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290\n url.hash = '';\n\n url.search = url.search.slice(1) // Exclude initial '?'\n .split('&') // Split into an array of 'key=value' strings\n .map(function(kv) {\n return kv.split('='); // Split each 'key=value' string into a [key, value] array\n })\n .filter(function(kv) {\n return ignoreUrlParametersMatching.every(function(ignoredRegex) {\n return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.\n });\n })\n .map(function(kv) {\n return kv.join('='); // Join each [key, value] array into a 'key=value' string\n })\n .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each\n\n return url.toString();\n };\n\n\nvar hashParamName = '_sw-precache';\nvar urlsToCacheKeys = new Map(\n precacheConfig.map(function(item) {\n var relativeUrl = item[0];\n var hash = item[1];\n var absoluteUrl = new URL(relativeUrl, self.location);\n var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);\n return [absoluteUrl.toString(), cacheKey];\n })\n);\n\nfunction setOfCachedUrls(cache) {\n return cache.keys().then(function(requests) {\n return requests.map(function(request) {\n return request.url;\n });\n }).then(function(urls) {\n return new Set(urls);\n });\n}\n\nself.addEventListener('install', function(event) {\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return setOfCachedUrls(cache).then(function(cachedUrls) {\n return Promise.all(\n Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {\n // If we don't have a key matching url in the cache already, add it.\n if (!cachedUrls.has(cacheKey)) {\n var request = new Request(cacheKey, {credentials: 'same-origin'});\n return fetch(request).then(function(response) {\n // Bail out of installation unless we get back a 200 OK for\n // every request.\n if (!response.ok) {\n throw new Error('Request for ' + cacheKey + ' returned a ' +\n 'response with status ' + response.status);\n }\n\n return cleanResponse(response).then(function(responseToCache) {\n return cache.put(cacheKey, responseToCache);\n });\n });\n }\n })\n );\n });\n }).then(function() {\n \n // Force the SW to transition from installing -> active state\n return self.skipWaiting();\n \n })\n );\n});\n\nself.addEventListener('activate', function(event) {\n var setOfExpectedUrls = new Set(urlsToCacheKeys.values());\n\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return cache.keys().then(function(existingRequests) {\n return Promise.all(\n existingRequests.map(function(existingRequest) {\n if (!setOfExpectedUrls.has(existingRequest.url)) {\n return cache.delete(existingRequest);\n }\n })\n );\n });\n }).then(function() {\n \n return self.clients.claim();\n \n })\n );\n});\n\n\nself.addEventListener('fetch', function(event) {\n if (event.request.method === 'GET') {\n // Should we call event.respondWith() inside this fetch event handler?\n // This needs to be determined synchronously, which will give other fetch\n // handlers a chance to handle the request if need be.\n var shouldRespond;\n\n // First, remove all the ignored parameters and hash fragment, and see if we\n // have that URL in our cache. If so, great! shouldRespond will be true.\n var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);\n shouldRespond = urlsToCacheKeys.has(url);\n\n // If shouldRespond is false, check again, this time with 'index.html'\n // (or whatever the directoryIndex option is set to) at the end.\n var directoryIndex = 'index.html';\n if (!shouldRespond && directoryIndex) {\n url = addDirectoryIndex(url, directoryIndex);\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond is still false, check to see if this is a navigation\n // request, and if so, whether the URL matches navigateFallbackWhitelist.\n var navigateFallback = '';\n if (!shouldRespond &&\n navigateFallback &&\n (event.request.mode === 'navigate') &&\n isPathWhitelisted([], event.request.url)) {\n url = new URL(navigateFallback, self.location).toString();\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond was set to true at any point, then call\n // event.respondWith(), using the appropriate cache key.\n if (shouldRespond) {\n event.respondWith(\n caches.open(cacheName).then(function(cache) {\n return cache.match(urlsToCacheKeys.get(url)).then(function(response) {\n if (response) {\n return response;\n }\n throw Error('The cached response that was expected is missing.');\n });\n }).catch(function(e) {\n // Fall back to just fetch()ing the request if some unexpected error\n // prevented the cached response from being valid.\n console.warn('Couldn\\'t serve response for \"%s\" from cache: %O', event.request.url, e);\n return fetch(event.request);\n })\n );\n }\n }\n});\n\n\n\n\n\n\n\n"]} +======= +{"version":3,"sources":["service-worker.js"],"names":["setOfCachedUrls","cache","keys","then","requests","map","request","url","urls","Set","precacheConfig","cacheName","self","registration","scope","ignoreUrlParametersMatching","addDirectoryIndex","originalUrl","index","URL","pathname","slice","toString","cleanResponse","originalResponse","redirected","Promise","resolve","body","blob","Response","headers","status","statusText","createCacheKey","paramName","paramValue","dontCacheBustUrlsMatching","match","search","encodeURIComponent","isPathWhitelisted","whitelist","absoluteUrlString","length","path","some","whitelistedPathRegex","stripIgnoredUrlParameters","hash","split","kv","filter","every","ignoredRegex","test","join","hashParamName","urlsToCacheKeys","Map","item","relativeUrl","absoluteUrl","location","cacheKey","addEventListener","event","waitUntil","caches","open","cachedUrls","all","Array","from","values","has","Request","credentials","fetch","response","ok","Error","responseToCache","put","skipWaiting","setOfExpectedUrls","existingRequests","existingRequest","delete","clients","claim","method","shouldRespond","respondWith","get","catch","e","console","warn"],"mappings":"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","file":"service-worker.js","sourcesContent":["/**\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n*/\n\n// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY!\n// This file should be overwritten as part of your build process.\n// If you need to extend the behavior of the generated service worker, the best approach is to write\n// additional code and include it using the importScripts option:\n// https://github.com/GoogleChrome/sw-precache#importscripts-arraystring\n//\n// Alternatively, it's possible to make changes to the underlying template file and then use that as the\n// new base for generating output, via the templateFilePath option:\n// https://github.com/GoogleChrome/sw-precache#templatefilepath-string\n//\n// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any\n// changes made to this original template file with your modified copy.\n\n// This generated service worker JavaScript will precache your site's resources.\n// The code needs to be saved in a .js file at the top-level of your site, and registered\n// from your pages in order to be used. See\n// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js\n// for an example of how you can register this script and handle various service worker events.\n\n/* eslint-env worker, serviceworker */\n/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */\n'use strict';\n\nvar precacheConfig = [[\"/dist/css/style.css\",\"ba4d66c91d1ed66848154a34ab4948cf\"],[\"/dist/img/back.svg\",\"898ada2a32ec64bd5b6959c22e8f231d\"],[\"/dist/img/monitor.svg\",\"348592da5567b5a3c46acfb5dcd341bc\"],[\"/dist/img/next.svg\",\"045593410b9f51390e750b9e1e7fff15\"],[\"/dist/img/reload.svg\",\"a0ab1b765280e4d22e6fb747042f6503\"],[\"/dist/img/shuffle.svg\",\"3a5e3c1bf04eb3493d8a2ffa547aa58f\"],[\"/dist/img/social-banner.png\",\"a70702eeea1dbe4a401b7c23189eb7d3\"],[\"/dist/js/bundle.min.js\",\"b811fe18d2d6a402297a71172a324d69\"],[\"/dist/js/loadJS.js\",\"72c55936069f60560a386e46f462c73a\"],[\"/dist/js/sw-registration.js\",\"677217d8e642c1ccff69fc01c96b4431\"],[\"/index.html\",\"c7522a5d3255caca0f12c5282ef0644d\"]];\nvar cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');\n\n\nvar ignoreUrlParametersMatching = [/^utm_/];\n\n\n\nvar addDirectoryIndex = function (originalUrl, index) {\n var url = new URL(originalUrl);\n if (url.pathname.slice(-1) === '/') {\n url.pathname += index;\n }\n return url.toString();\n };\n\nvar cleanResponse = function (originalResponse) {\n // If this is not a redirected response, then we don't have to do anything.\n if (!originalResponse.redirected) {\n return Promise.resolve(originalResponse);\n }\n\n // Firefox 50 and below doesn't support the Response.body stream, so we may\n // need to read the entire body to memory as a Blob.\n var bodyPromise = 'body' in originalResponse ?\n Promise.resolve(originalResponse.body) :\n originalResponse.blob();\n\n return bodyPromise.then(function(body) {\n // new Response() is happy when passed either a stream or a Blob.\n return new Response(body, {\n headers: originalResponse.headers,\n status: originalResponse.status,\n statusText: originalResponse.statusText\n });\n });\n };\n\nvar createCacheKey = function (originalUrl, paramName, paramValue,\n dontCacheBustUrlsMatching) {\n // Create a new URL object to avoid modifying originalUrl.\n var url = new URL(originalUrl);\n\n // If dontCacheBustUrlsMatching is not set, or if we don't have a match,\n // then add in the extra cache-busting URL parameter.\n if (!dontCacheBustUrlsMatching ||\n !(url.pathname.match(dontCacheBustUrlsMatching))) {\n url.search += (url.search ? '&' : '') +\n encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);\n }\n\n return url.toString();\n };\n\nvar isPathWhitelisted = function (whitelist, absoluteUrlString) {\n // If the whitelist is empty, then consider all URLs to be whitelisted.\n if (whitelist.length === 0) {\n return true;\n }\n\n // Otherwise compare each path regex to the path of the URL passed in.\n var path = (new URL(absoluteUrlString)).pathname;\n return whitelist.some(function(whitelistedPathRegex) {\n return path.match(whitelistedPathRegex);\n });\n };\n\nvar stripIgnoredUrlParameters = function (originalUrl,\n ignoreUrlParametersMatching) {\n var url = new URL(originalUrl);\n // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290\n url.hash = '';\n\n url.search = url.search.slice(1) // Exclude initial '?'\n .split('&') // Split into an array of 'key=value' strings\n .map(function(kv) {\n return kv.split('='); // Split each 'key=value' string into a [key, value] array\n })\n .filter(function(kv) {\n return ignoreUrlParametersMatching.every(function(ignoredRegex) {\n return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.\n });\n })\n .map(function(kv) {\n return kv.join('='); // Join each [key, value] array into a 'key=value' string\n })\n .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each\n\n return url.toString();\n };\n\n\nvar hashParamName = '_sw-precache';\nvar urlsToCacheKeys = new Map(\n precacheConfig.map(function(item) {\n var relativeUrl = item[0];\n var hash = item[1];\n var absoluteUrl = new URL(relativeUrl, self.location);\n var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);\n return [absoluteUrl.toString(), cacheKey];\n })\n);\n\nfunction setOfCachedUrls(cache) {\n return cache.keys().then(function(requests) {\n return requests.map(function(request) {\n return request.url;\n });\n }).then(function(urls) {\n return new Set(urls);\n });\n}\n\nself.addEventListener('install', function(event) {\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return setOfCachedUrls(cache).then(function(cachedUrls) {\n return Promise.all(\n Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {\n // If we don't have a key matching url in the cache already, add it.\n if (!cachedUrls.has(cacheKey)) {\n var request = new Request(cacheKey, {credentials: 'same-origin'});\n return fetch(request).then(function(response) {\n // Bail out of installation unless we get back a 200 OK for\n // every request.\n if (!response.ok) {\n throw new Error('Request for ' + cacheKey + ' returned a ' +\n 'response with status ' + response.status);\n }\n\n return cleanResponse(response).then(function(responseToCache) {\n return cache.put(cacheKey, responseToCache);\n });\n });\n }\n })\n );\n });\n }).then(function() {\n \n // Force the SW to transition from installing -> active state\n return self.skipWaiting();\n \n })\n );\n});\n\nself.addEventListener('activate', function(event) {\n var setOfExpectedUrls = new Set(urlsToCacheKeys.values());\n\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return cache.keys().then(function(existingRequests) {\n return Promise.all(\n existingRequests.map(function(existingRequest) {\n if (!setOfExpectedUrls.has(existingRequest.url)) {\n return cache.delete(existingRequest);\n }\n })\n );\n });\n }).then(function() {\n \n return self.clients.claim();\n \n })\n );\n});\n\n\nself.addEventListener('fetch', function(event) {\n if (event.request.method === 'GET') {\n // Should we call event.respondWith() inside this fetch event handler?\n // This needs to be determined synchronously, which will give other fetch\n // handlers a chance to handle the request if need be.\n var shouldRespond;\n\n // First, remove all the ignored parameters and hash fragment, and see if we\n // have that URL in our cache. If so, great! shouldRespond will be true.\n var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);\n shouldRespond = urlsToCacheKeys.has(url);\n\n // If shouldRespond is false, check again, this time with 'index.html'\n // (or whatever the directoryIndex option is set to) at the end.\n var directoryIndex = 'index.html';\n if (!shouldRespond && directoryIndex) {\n url = addDirectoryIndex(url, directoryIndex);\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond is still false, check to see if this is a navigation\n // request, and if so, whether the URL matches navigateFallbackWhitelist.\n var navigateFallback = '';\n if (!shouldRespond &&\n navigateFallback &&\n (event.request.mode === 'navigate') &&\n isPathWhitelisted([], event.request.url)) {\n url = new URL(navigateFallback, self.location).toString();\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond was set to true at any point, then call\n // event.respondWith(), using the appropriate cache key.\n if (shouldRespond) {\n event.respondWith(\n caches.open(cacheName).then(function(cache) {\n return cache.match(urlsToCacheKeys.get(url)).then(function(response) {\n if (response) {\n return response;\n }\n throw Error('The cached response that was expected is missing.');\n });\n }).catch(function(e) {\n // Fall back to just fetch()ing the request if some unexpected error\n // prevented the cached response from being valid.\n console.warn('Couldn\\'t serve response for \"%s\" from cache: %O', event.request.url, e);\n return fetch(event.request);\n })\n );\n }\n }\n});\n\n\n\n\n\n\n\n"]} +>>>>>>> working import of external problem content diff --git a/shrinkwrap.yaml b/shrinkwrap.yaml new file mode 100644 index 0000000..7be6888 --- /dev/null +++ b/shrinkwrap.yaml @@ -0,0 +1,4148 @@ +createdWith: pnpm@0.68.0 +dependencies: + autoprefixer@^6.7.7: 6.7.7 + ava@^0.18.2: 0.18.2 + babel-core@^6.24.0: 6.24.1 + babel-preset-es2015@^6.24.1: 6.24.1 + babel-preset-es2017@^6.24.1: 6.24.1 + babel-preset-latest@^6.24.1: 6.24.1 + babelify@^7.3.0: 7.3.0 + browserify@^14.1.0: 14.4.0 + chai@^3.5.0: 3.5.0 + cssnano@^3.10.0: 3.10.0 + dedent@^0.7.0: 0.7.0 + gulp-bro@^1.0.2: 1.0.2 + gulp-livereload@^3.8.1: 3.8.1 + gulp-postcss@^6.4.0: 6.4.0 + gulp-sass@^3.1.0: 3.1.0 + gulp-sourcemaps@^2.5.1: 2.6.0 + gulp-svgo@^1.0.3: 1.0.3 + gulp-uglify@2.1.2: 2.1.2 + gulp-util@^3.0.8: 3.0.8 + gulp@^3.9.1: 3.9.1 + husky@^0.13.3: 0.13.4 + lint-staged@^3.4.0: 3.6.0 + localforage@^1.5.0: 1.5.0 + 'pjs-problems@git+https://github.com/practicejavascript/pjs-problems.git': github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916 + rollup-stream@^1.19.0: 1.19.0 + static-eval@^1.1.1: 1.1.1 + uglifyify@^3.0.4: 3.0.4 + vinyl-buffer@^1.0.0: 1.0.0 + vinyl-source-stream@^1.1.0: 1.1.0 + watchify@^3.9.0: 3.9.0 + xo@^0.18.1: 0.18.2 +packages: + /@ava/babel-preset-stage-4/1.0.0: + dependencies: + babel-plugin-check-es2015-constants: 6.22.0 + babel-plugin-syntax-trailing-function-commas: 6.22.0 + babel-plugin-transform-async-to-generator: 6.24.1 + babel-plugin-transform-es2015-destructuring: 6.23.0 + babel-plugin-transform-es2015-function-name: 6.24.1 + babel-plugin-transform-es2015-modules-commonjs: 6.24.1 + babel-plugin-transform-es2015-parameters: 6.24.1 + babel-plugin-transform-es2015-spread: 6.22.0 + babel-plugin-transform-es2015-sticky-regex: 6.24.1 + babel-plugin-transform-es2015-unicode-regex: 6.24.1 + babel-plugin-transform-exponentiation-operator: 6.24.1 + package-hash: 1.2.0 + resolution: a613b5e152f529305422546b072d47facfb26291 + /@ava/babel-preset-transform-test-files/2.0.1: + dependencies: + babel-plugin-ava-throws-helper: 1.0.0 + babel-plugin-espower: 2.3.2 + package-hash: 1.2.0 + resolution: d75232cc6d71dc9c7eae4b76a9004fd81501d0c1 + /@ava/pretty-format/1.1.0: + dependencies: + ansi-styles: 2.2.1 + esutils: 2.0.2 + resolution: d0a57d25eb9aeab9643bdd1a030642b91c123e28 + /@gulp-sourcemaps/identity-map/1.0.1: + dependencies: + acorn: 5.0.3 + css: 2.2.1 + normalize-path: 2.1.1 + source-map: 0.5.6 + through2: 2.0.3 + resolution: cfa23bc5840f9104ce32a65e74db7e7a974bbee1 + /@gulp-sourcemaps/map-sources/1.0.0: + dependencies: + normalize-path: 2.1.1 + through2: 2.0.3 + resolution: 890ae7c5d8c877f6d384860215ace9d7ec945bda + /JSONStream/0.10.0: + dependencies: + jsonparse: 0.0.5 + through: 2.3.8 + resolution: 74349d0d89522b71f30f0a03ff9bd20ca6f12ac0 + /JSONStream/1.3.1: + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + resolution: 707f761e01dae9e16f1bcf93703b78c70966579a + /abbrev/1.1.0: d0554c2256636e2f56e7c2e5ad183f859428d81f + /acorn-jsx/3.0.1: + dependencies: + acorn: 3.3.0 + resolution: afdf9488fb1ecefc8348f6fb22f464e32a58b36b + /acorn/1.2.2: c8ce27de0acc76d896d2b1fad3df588d9e82f014 + /acorn/3.3.0: 45e37fb39e8da3f25baee3ff5369e2bb5f22017a + /acorn/4.0.13: 105495ae5361d697bd195c825192e1ad7f253787 + /acorn/5.0.3: c460df08491463f028ccb82eab3730bf01087b3d + /ajv-keywords/1.5.1: 314dd0a4b3368fad3dfcdc54ede6171b886daf3c + /ajv/4.11.8: + dependencies: + co: 4.6.0 + json-stable-stringify: 1.0.1 + resolution: 82ffb02b29e662ae53bdc20af15947706739c536 + /align-text/0.1.4: + dependencies: + kind-of: 3.2.2 + longest: 1.0.1 + repeat-string: 1.6.1 + resolution: 0cd90a561093f35d0a99256c22b7069433fad117 + /alphanum-sort/1.0.2: 97a1119649b211ad33691d9f9f486a8ec9fbe0a3 + /amdefine/1.0.1: 4a5282ac164729e93619bcfd3ad151f817ce91f5 + /ansi-align/1.1.0: + dependencies: + string-width: 1.0.2 + resolution: 2f0c1658829739add5ebb15e6b0c6e3423f016ba + /ansi-align/2.0.0: + dependencies: + string-width: 2.0.0 + resolution: c36aeccba563b89ceb556f3690f0b1d9e3547f7f + /ansi-escapes/1.4.0: d3a8a83b319aa67793662b13e761c7911422306e + /ansi-regex/0.2.1: 0d8e946967a3d8143f93e24e298525fc1b2235f9 + /ansi-regex/2.1.1: c3b33ab5ee360d86e0e628f0468ae7ef27d654df + /ansi-styles/1.0.0: cb102df1c56f5123eab8b67cd7b98027a0279178 + /ansi-styles/1.1.0: eaecbf66cd706882760b2f4691582b8f55d7a7de + /ansi-styles/2.2.1: b432dd3358b634cf75e1e4664368240533c1ddbe + /anymatch/1.3.0: + dependencies: + arrify: 1.0.1 + micromatch: 2.3.11 + resolution: a3e52fa39168c825ff57b0248126ce5a8ff95507 + /app-root-path/2.0.1: cd62dcf8e4fd5a417efc664d2e5b10653c651b46 + /aproba/1.1.2: 45c6629094de4e96f693ef7eab74ae079c240fc1 + /archy/1.0.0: f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40 + /are-we-there-yet/1.1.4: + dependencies: + delegates: 1.0.0 + readable-stream: 2.2.10 + resolution: bb5dca382bb94f05e15194373d16fd3ba1ca110d + /argparse/1.0.9: + dependencies: + sprintf-js: 1.0.3 + resolution: 73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86 + /arr-diff/2.0.0: + dependencies: + arr-flatten: 1.0.3 + resolution: 8f3b827f955a8bd669697e4a4256ac3ceae356cf + /arr-exclude/1.0.0: dfc7c2e552a270723ccda04cf3128c8cbfe5c631 + /arr-flatten/1.0.3: a274ed85ac08849b6bd7847c4580745dc51adfb1 + /array-differ/1.0.0: eff52e3758249d33be402b8bb8e564bb2b5d4031 + /array-filter/0.0.1: 7da8cf2e26628ed732803581fd21f67cacd2eeec + /array-find-index/1.0.2: df010aa1287e164bbda6f9723b0a96a1ec4187a1 + /array-map/0.0.0: 88a2bab73d1cf7bcd5c1b118a003f66f665fa662 + /array-reduce/0.0.0: 173899d3ffd1c7d9383e4479525dbe278cab5f2b + /array-union/1.0.2: + dependencies: + array-uniq: 1.0.3 + resolution: 9a34410e4f4e3da23dea375be5be70f24778ec39 + /array-uniq/1.0.3: af6ac877a25cc7f74e058894753858dfdb24fdb6 + /array-unique/0.2.1: a1d97ccafcbc2625cc70fadceb36a50c58b01a53 + /arrify/1.0.1: 898508da2226f380df904728456849c1501a4b0d + /asn1.js/4.9.1: + dependencies: + bn.js: 4.11.6 + inherits: 2.0.3 + minimalistic-assert: 1.0.0 + resolution: 48ba240b45a9280e94748990ba597d216617fd40 + /asn1/0.2.3: dac8787713c9966849fc8180777ebe9c1ddf3b86 + /assert-plus/0.2.0: d74e1b87e7affc0db8aadb7021f3fe48101ab234 + /assert-plus/1.0.0: f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525 + /assert/1.4.1: + dependencies: + util: 0.10.3 + resolution: 99912d591836b5a6f5b345c0f07eefc08fc65d91 + /assertion-error/1.0.2: 13ca515d86206da0bac66e834dd397d87581094c + /ast-types/0.8.15: 8eef0827f04dff0ec8857ba925abe3fea6194e52 + /astw/2.2.0: + dependencies: + acorn: 4.0.13 + resolution: 7bd41784d32493987aeb239b6b4e1c57a873b917 + /async-each/1.0.1: 19d386a1d9edc6e7c1c85d388aedbcc56d33602d + /async-foreach/0.1.3: 36121f845c0578172de419a97dbeb1d16ec34542 + /async/1.5.2: ec6a61ae56480c0c3cb241c95618e20892f9672a + /asynckit/0.4.0: c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79 + /atob/1.1.3: 95f13629b12c3a51a5d215abdce2aa9f32f80773 + /auto-bind/1.1.0: 93b864dc7ee01a326281775d5c75ca0a751e5961 + /autoprefixer/6.7.7: + dependencies: + browserslist: 1.7.7 + caniuse-db: 1.0.30000676 + normalize-range: 0.1.2 + num2fraction: 1.2.2 + postcss: 5.2.17 + postcss-value-parser: 3.3.0 + resolution: 1dbd1c835658e35ce3f9984099db00585c782014 + /ava-init/0.2.0: + dependencies: + arr-exclude: 1.0.0 + execa: 0.5.1 + has-yarn: 1.0.0 + read-pkg-up: 2.0.0 + write-pkg: 2.1.0 + resolution: 9304c8b4c357d66e3dfdae1fbff47b1199d5c55d + /ava/0.18.2: + dependencies: + '@ava/babel-preset-stage-4': 1.0.0 + '@ava/babel-preset-transform-test-files': 2.0.1 + '@ava/pretty-format': 1.1.0 + arr-flatten: 1.0.3 + array-union: 1.0.2 + array-uniq: 1.0.3 + arrify: 1.0.1 + auto-bind: 1.1.0 + ava-init: 0.2.0 + babel-code-frame: 6.22.0 + babel-core: 6.24.1 + bluebird: 3.5.0 + caching-transform: 1.0.1 + chalk: 1.1.3 + chokidar: 1.7.0 + clean-stack: 1.3.0 + clean-yaml-object: 0.1.0 + cli-cursor: 2.1.0 + cli-spinners: 1.0.0 + cli-truncate: 0.2.1 + co-with-promise: 4.6.0 + code-excerpt: 2.1.0 + common-path-prefix: 1.0.0 + convert-source-map: 1.5.0 + core-assert: 0.2.1 + currently-unhandled: 0.4.1 + debug: 2.6.8 + diff: 3.2.0 + dot-prop: 4.1.1 + empower-core: 0.6.1 + equal-length: 1.0.1 + figures: 2.0.0 + find-cache-dir: 0.1.1 + fn-name: 2.0.1 + get-port: 2.1.0 + globby: 6.1.0 + has-flag: 2.0.0 + ignore-by-default: 1.0.1 + indent-string: 3.1.0 + is-ci: 1.0.10 + is-generator-fn: 1.0.0 + is-obj: 1.0.1 + is-observable: 0.2.0 + is-promise: 2.1.0 + jest-snapshot: 18.1.0 + last-line-stream: 1.0.0 + lodash.debounce: 4.0.8 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isequal: 4.5.0 + loud-rejection: 1.6.0 + matcher: 0.1.2 + max-timeout: 1.0.0 + md5-hex: 2.0.0 + meow: 3.7.0 + ms: 0.7.3 + multimatch: 2.1.0 + observable-to-promise: 0.4.0 + option-chain: 0.1.1 + package-hash: 1.2.0 + pkg-conf: 2.0.0 + plur: 2.1.2 + pretty-ms: 2.1.0 + require-precompiled: 0.1.0 + resolve-cwd: 1.0.0 + slash: 1.0.0 + source-map-support: 0.4.15 + stack-utils: 1.0.1 + strip-ansi: 3.0.1 + strip-bom-buf: 1.0.0 + time-require: 0.1.2 + unique-temp-dir: 1.0.0 + update-notifier: 1.0.3 + resolution: 79253d1636077034a2780bb55b5c3e6c3d7f312f + /aws-sign2/0.6.0: 14342dd38dbcc94d0e5b87d763cd63612c0e794f + /aws4/1.6.0: 83ef5ca860b2b32e4a0deedee8c771b9db57471e + /babel-code-frame/6.22.0: + dependencies: + chalk: 1.1.3 + esutils: 2.0.2 + js-tokens: 3.0.1 + resolution: 027620bee567a88c32561574e7fd0801d33118e4 + /babel-core/6.24.1: + dependencies: + babel-code-frame: 6.22.0 + babel-generator: 6.24.1 + babel-helpers: 6.24.1 + babel-messages: 6.23.0 + babel-register: 6.24.1 + babel-runtime: 6.23.0 + babel-template: 6.24.1 + babel-traverse: 6.24.1 + babel-types: 6.24.1 + babylon: 6.17.2 + convert-source-map: 1.5.0 + debug: 2.6.8 + json5: 0.5.1 + lodash: 4.17.4 + minimatch: 3.0.4 + path-is-absolute: 1.0.1 + private: 0.1.7 + slash: 1.0.0 + source-map: 0.5.6 + resolution: 8c428564dce1e1f41fb337ec34f4c3b022b5ad83 + /babel-generator/6.24.1: + dependencies: + babel-messages: 6.23.0 + babel-runtime: 6.23.0 + babel-types: 6.24.1 + detect-indent: 4.0.0 + jsesc: 1.3.0 + lodash: 4.17.4 + source-map: 0.5.6 + trim-right: 1.0.1 + resolution: e715f486c58ded25649d888944d52aa07c5d9497 + /babel-helper-builder-binary-assignment-operator-visitor/6.24.1: + dependencies: + babel-helper-explode-assignable-expression: 6.24.1 + babel-runtime: 6.23.0 + babel-types: 6.24.1 + resolution: cce4517ada356f4220bcae8a02c2b346f9a56664 + /babel-helper-call-delegate/6.24.1: + dependencies: + babel-helper-hoist-variables: 6.24.1 + babel-runtime: 6.23.0 + babel-traverse: 6.24.1 + babel-types: 6.24.1 + resolution: ece6aacddc76e41c3461f88bfc575bd0daa2df8d + /babel-helper-define-map/6.24.1: + dependencies: + babel-helper-function-name: 6.24.1 + babel-runtime: 6.23.0 + babel-types: 6.24.1 + lodash: 4.17.4 + resolution: 7a9747f258d8947d32d515f6aa1c7bd02204a080 + /babel-helper-explode-assignable-expression/6.24.1: + dependencies: + babel-runtime: 6.23.0 + babel-traverse: 6.24.1 + babel-types: 6.24.1 + resolution: f25b82cf7dc10433c55f70592d5746400ac22caa + /babel-helper-function-name/6.24.1: + dependencies: + babel-helper-get-function-arity: 6.24.1 + babel-runtime: 6.23.0 + babel-template: 6.24.1 + babel-traverse: 6.24.1 + babel-types: 6.24.1 + resolution: d3475b8c03ed98242a25b48351ab18399d3580a9 + /babel-helper-get-function-arity/6.24.1: + dependencies: + babel-runtime: 6.23.0 + babel-types: 6.24.1 + resolution: 8f7782aa93407c41d3aa50908f89b031b1b6853d + /babel-helper-hoist-variables/6.24.1: + dependencies: + babel-runtime: 6.23.0 + babel-types: 6.24.1 + resolution: 1ecb27689c9d25513eadbc9914a73f5408be7a76 + /babel-helper-optimise-call-expression/6.24.1: + dependencies: + babel-runtime: 6.23.0 + babel-types: 6.24.1 + resolution: f7a13427ba9f73f8f4fa993c54a97882d1244257 + /babel-helper-regex/6.24.1: + dependencies: + babel-runtime: 6.23.0 + babel-types: 6.24.1 + lodash: 4.17.4 + resolution: d36e22fab1008d79d88648e32116868128456ce8 + /babel-helper-remap-async-to-generator/6.24.1: + dependencies: + babel-helper-function-name: 6.24.1 + babel-runtime: 6.23.0 + babel-template: 6.24.1 + babel-traverse: 6.24.1 + babel-types: 6.24.1 + resolution: 5ec581827ad723fecdd381f1c928390676e4551b + /babel-helper-replace-supers/6.24.1: + dependencies: + babel-helper-optimise-call-expression: 6.24.1 + babel-messages: 6.23.0 + babel-runtime: 6.23.0 + babel-template: 6.24.1 + babel-traverse: 6.24.1 + babel-types: 6.24.1 + resolution: bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a + /babel-helpers/6.24.1: + dependencies: + babel-runtime: 6.23.0 + babel-template: 6.24.1 + resolution: 3471de9caec388e5c850e597e58a26ddf37602b2 + /babel-messages/6.23.0: + dependencies: + babel-runtime: 6.23.0 + resolution: f3cdf4703858035b2a2951c6ec5edf6c62f2630e + /babel-plugin-ava-throws-helper/1.0.0: + dependencies: + babel-template: 6.24.1 + babel-types: 6.24.1 + resolution: 8fe6e79d2fd19838b5c3649f89cfb03fd563e241 + /babel-plugin-check-es2015-constants/6.22.0: + dependencies: + babel-runtime: 6.23.0 + resolution: 35157b101426fd2ffd3da3f75c7d1e91835bbf8a + /babel-plugin-espower/2.3.2: + dependencies: + babel-generator: 6.24.1 + babylon: 6.17.2 + call-matcher: 1.0.1 + core-js: 2.4.1 + espower-location-detector: 1.0.0 + espurify: 1.7.0 + estraverse: 4.2.0 + resolution: 5516b8fcdb26c9f0e1d8160749f6e4c65e71271e + /babel-plugin-syntax-async-functions/6.13.0: cad9cad1191b5ad634bf30ae0872391e0647be95 + /babel-plugin-syntax-exponentiation-operator/6.13.0: 9ee7e8337290da95288201a6a57f4170317830de + /babel-plugin-syntax-trailing-function-commas/6.22.0: ba0360937f8d06e40180a43fe0d5616fff532cf3 + /babel-plugin-transform-async-to-generator/6.24.1: + dependencies: + babel-helper-remap-async-to-generator: 6.24.1 + babel-plugin-syntax-async-functions: 6.13.0 + babel-runtime: 6.23.0 + resolution: 6536e378aff6cb1d5517ac0e40eb3e9fc8d08761 + /babel-plugin-transform-es2015-arrow-functions/6.22.0: + dependencies: + babel-runtime: 6.23.0 + resolution: 452692cb711d5f79dc7f85e440ce41b9f244d221 + /babel-plugin-transform-es2015-block-scoped-functions/6.22.0: + dependencies: + babel-runtime: 6.23.0 + resolution: bbc51b49f964d70cb8d8e0b94e820246ce3a6141 + /babel-plugin-transform-es2015-block-scoping/6.24.1: + dependencies: + babel-runtime: 6.23.0 + babel-template: 6.24.1 + babel-traverse: 6.24.1 + babel-types: 6.24.1 + lodash: 4.17.4 + resolution: 76c295dc3a4741b1665adfd3167215dcff32a576 + /babel-plugin-transform-es2015-classes/6.24.1: + dependencies: + babel-helper-define-map: 6.24.1 + babel-helper-function-name: 6.24.1 + babel-helper-optimise-call-expression: 6.24.1 + babel-helper-replace-supers: 6.24.1 + babel-messages: 6.23.0 + babel-runtime: 6.23.0 + babel-template: 6.24.1 + babel-traverse: 6.24.1 + babel-types: 6.24.1 + resolution: 5a4c58a50c9c9461e564b4b2a3bfabc97a2584db + /babel-plugin-transform-es2015-computed-properties/6.24.1: + dependencies: + babel-runtime: 6.23.0 + babel-template: 6.24.1 + resolution: 6fe2a8d16895d5634f4cd999b6d3480a308159b3 + /babel-plugin-transform-es2015-destructuring/6.23.0: + dependencies: + babel-runtime: 6.23.0 + resolution: 997bb1f1ab967f682d2b0876fe358d60e765c56d + /babel-plugin-transform-es2015-duplicate-keys/6.24.1: + dependencies: + babel-runtime: 6.23.0 + babel-types: 6.24.1 + resolution: 73eb3d310ca969e3ef9ec91c53741a6f1576423e + /babel-plugin-transform-es2015-for-of/6.23.0: + dependencies: + babel-runtime: 6.23.0 + resolution: f47c95b2b613df1d3ecc2fdb7573623c75248691 + /babel-plugin-transform-es2015-function-name/6.24.1: + dependencies: + babel-helper-function-name: 6.24.1 + babel-runtime: 6.23.0 + babel-types: 6.24.1 + resolution: 834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b + /babel-plugin-transform-es2015-literals/6.22.0: + dependencies: + babel-runtime: 6.23.0 + resolution: 4f54a02d6cd66cf915280019a31d31925377ca2e + /babel-plugin-transform-es2015-modules-amd/6.24.1: + dependencies: + babel-plugin-transform-es2015-modules-commonjs: 6.24.1 + babel-runtime: 6.23.0 + babel-template: 6.24.1 + resolution: 3b3e54017239842d6d19c3011c4bd2f00a00d154 + /babel-plugin-transform-es2015-modules-commonjs/6.24.1: + dependencies: + babel-plugin-transform-strict-mode: 6.24.1 + babel-runtime: 6.23.0 + babel-template: 6.24.1 + babel-types: 6.24.1 + resolution: d3e310b40ef664a36622200097c6d440298f2bfe + /babel-plugin-transform-es2015-modules-systemjs/6.24.1: + dependencies: + babel-helper-hoist-variables: 6.24.1 + babel-runtime: 6.23.0 + babel-template: 6.24.1 + resolution: ff89a142b9119a906195f5f106ecf305d9407d23 + /babel-plugin-transform-es2015-modules-umd/6.24.1: + dependencies: + babel-plugin-transform-es2015-modules-amd: 6.24.1 + babel-runtime: 6.23.0 + babel-template: 6.24.1 + resolution: ac997e6285cd18ed6176adb607d602344ad38468 + /babel-plugin-transform-es2015-object-super/6.24.1: + dependencies: + babel-helper-replace-supers: 6.24.1 + babel-runtime: 6.23.0 + resolution: 24cef69ae21cb83a7f8603dad021f572eb278f8d + /babel-plugin-transform-es2015-parameters/6.24.1: + dependencies: + babel-helper-call-delegate: 6.24.1 + babel-helper-get-function-arity: 6.24.1 + babel-runtime: 6.23.0 + babel-template: 6.24.1 + babel-traverse: 6.24.1 + babel-types: 6.24.1 + resolution: 57ac351ab49caf14a97cd13b09f66fdf0a625f2b + /babel-plugin-transform-es2015-shorthand-properties/6.24.1: + dependencies: + babel-runtime: 6.23.0 + babel-types: 6.24.1 + resolution: 24f875d6721c87661bbd99a4622e51f14de38aa0 + /babel-plugin-transform-es2015-spread/6.22.0: + dependencies: + babel-runtime: 6.23.0 + resolution: d6d68a99f89aedc4536c81a542e8dd9f1746f8d1 + /babel-plugin-transform-es2015-sticky-regex/6.24.1: + dependencies: + babel-helper-regex: 6.24.1 + babel-runtime: 6.23.0 + babel-types: 6.24.1 + resolution: 00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc + /babel-plugin-transform-es2015-template-literals/6.22.0: + dependencies: + babel-runtime: 6.23.0 + resolution: a84b3450f7e9f8f1f6839d6d687da84bb1236d8d + /babel-plugin-transform-es2015-typeof-symbol/6.23.0: + dependencies: + babel-runtime: 6.23.0 + resolution: dec09f1cddff94b52ac73d505c84df59dcceb372 + /babel-plugin-transform-es2015-unicode-regex/6.24.1: + dependencies: + babel-helper-regex: 6.24.1 + babel-runtime: 6.23.0 + regexpu-core: 2.0.0 + resolution: d38b12f42ea7323f729387f18a7c5ae1faeb35e9 + /babel-plugin-transform-exponentiation-operator/6.24.1: + dependencies: + babel-helper-builder-binary-assignment-operator-visitor: 6.24.1 + babel-plugin-syntax-exponentiation-operator: 6.13.0 + babel-runtime: 6.23.0 + resolution: 2ab0c9c7f3098fa48907772bb813fe41e8de3a0e + /babel-plugin-transform-regenerator/6.24.1: + dependencies: + regenerator-transform: 0.9.11 + resolution: b8da305ad43c3c99b4848e4fe4037b770d23c418 + /babel-plugin-transform-strict-mode/6.24.1: + dependencies: + babel-runtime: 6.23.0 + babel-types: 6.24.1 + resolution: d5faf7aa578a65bbe591cf5edae04a0c67020758 + /babel-preset-es2015/6.24.1: + dependencies: + babel-plugin-check-es2015-constants: 6.22.0 + babel-plugin-transform-es2015-arrow-functions: 6.22.0 + babel-plugin-transform-es2015-block-scoped-functions: 6.22.0 + babel-plugin-transform-es2015-block-scoping: 6.24.1 + babel-plugin-transform-es2015-classes: 6.24.1 + babel-plugin-transform-es2015-computed-properties: 6.24.1 + babel-plugin-transform-es2015-destructuring: 6.23.0 + babel-plugin-transform-es2015-duplicate-keys: 6.24.1 + babel-plugin-transform-es2015-for-of: 6.23.0 + babel-plugin-transform-es2015-function-name: 6.24.1 + babel-plugin-transform-es2015-literals: 6.22.0 + babel-plugin-transform-es2015-modules-amd: 6.24.1 + babel-plugin-transform-es2015-modules-commonjs: 6.24.1 + babel-plugin-transform-es2015-modules-systemjs: 6.24.1 + babel-plugin-transform-es2015-modules-umd: 6.24.1 + babel-plugin-transform-es2015-object-super: 6.24.1 + babel-plugin-transform-es2015-parameters: 6.24.1 + babel-plugin-transform-es2015-shorthand-properties: 6.24.1 + babel-plugin-transform-es2015-spread: 6.22.0 + babel-plugin-transform-es2015-sticky-regex: 6.24.1 + babel-plugin-transform-es2015-template-literals: 6.22.0 + babel-plugin-transform-es2015-typeof-symbol: 6.23.0 + babel-plugin-transform-es2015-unicode-regex: 6.24.1 + babel-plugin-transform-regenerator: 6.24.1 + resolution: d44050d6bc2c9feea702aaf38d727a0210538939 + /babel-preset-es2016/6.24.1: + dependencies: + babel-plugin-transform-exponentiation-operator: 6.24.1 + resolution: f900bf93e2ebc0d276df9b8ab59724ebfd959f8b + /babel-preset-es2017/6.24.1: + dependencies: + babel-plugin-syntax-trailing-function-commas: 6.22.0 + babel-plugin-transform-async-to-generator: 6.24.1 + resolution: 597beadfb9f7f208bcfd8a12e9b2b29b8b2f14d1 + /babel-preset-latest/6.24.1: + dependencies: + babel-preset-es2015: 6.24.1 + babel-preset-es2016: 6.24.1 + babel-preset-es2017: 6.24.1 + resolution: 677de069154a7485c2d25c577c02f624b85b85e8 + /babel-register/6.24.1: + dependencies: + babel-core: 6.24.1 + babel-runtime: 6.23.0 + core-js: 2.4.1 + home-or-tmp: 2.0.0 + lodash: 4.17.4 + mkdirp: 0.5.1 + source-map-support: 0.4.15 + resolution: 7e10e13a2f71065bdfad5a1787ba45bca6ded75f + /babel-runtime/6.23.0: + dependencies: + core-js: 2.4.1 + regenerator-runtime: 0.10.5 + resolution: 0a9489f144de70efb3ce4300accdb329e2fc543b + /babel-template/6.24.1: + dependencies: + babel-runtime: 6.23.0 + babel-traverse: 6.24.1 + babel-types: 6.24.1 + babylon: 6.17.2 + lodash: 4.17.4 + resolution: 04ae514f1f93b3a2537f2a0f60a5a45fb8308333 + /babel-traverse/6.24.1: + dependencies: + babel-code-frame: 6.22.0 + babel-messages: 6.23.0 + babel-runtime: 6.23.0 + babel-types: 6.24.1 + babylon: 6.17.2 + debug: 2.6.8 + globals: 9.17.0 + invariant: 2.2.2 + lodash: 4.17.4 + resolution: ab36673fd356f9a0948659e7b338d5feadb31695 + /babel-types/6.24.1: + dependencies: + babel-runtime: 6.23.0 + esutils: 2.0.2 + lodash: 4.17.4 + to-fast-properties: 1.0.3 + resolution: a136879dc15b3606bda0d90c1fc74304c2ff0975 + /babelify/7.3.0: + dependencies: + babel-core: 6.24.1 + object-assign: 4.1.1 + resolution: aa56aede7067fd7bd549666ee16dc285087e88e5 + /babylon/6.17.2: 201d25ef5f892c41bae49488b08db0dd476e9f5c + /balanced-match/0.4.2: cb3f3e3c732dc0f01ee70b403f302e61d7709838 + /base62/0.1.1: 7b4174c2f94449753b11c2651c083da841a7b084 + /base64-js/1.2.0: a39992d723584811982be5e290bb6a53d86700f1 + /bcrypt-pbkdf/1.0.1: + dependencies: + tweetnacl: 0.14.5 + resolution: 63bc5dcb61331b92bc05fd528953c33462a06f8d + /beeper/1.1.1: e6d5ea8c5dad001304a70b22638447f69cb2f809 + /binary-extensions/1.8.0: 48ec8d16df4377eae5fa5884682480af4d95c774 + /bl/0.9.5: + dependencies: + readable-stream: 1.0.34 + resolution: c06b797af085ea00bc527afc8efcf11de2232054 + /block-stream/0.0.9: + dependencies: + inherits: 2.0.3 + resolution: 13ebfe778a03205cfe03751481ebb4b3300c126a + /bluebird/3.5.0: 791420d7f551eea2897453a8a77653f96606d67c + /bn.js/4.11.6: 53344adb14617a13f6e8dd2ce28905d1c0ba3215 + /body-parser/1.14.2: + dependencies: + bytes: 2.2.0 + content-type: 1.0.2 + debug: 2.2.0 + depd: 1.1.0 + http-errors: 1.3.1 + iconv-lite: 0.4.13 + on-finished: 2.3.0 + qs: 5.2.0 + raw-body: 2.1.7 + type-is: 1.6.15 + resolution: 1015cb1fe2c443858259581db53332f8d0cf50f9 + /boom/2.10.1: + dependencies: + hoek: 2.16.3 + resolution: 39c8918ceff5799f83f9492a848f625add0c766f + /boxen/0.6.0: + dependencies: + ansi-align: 1.1.0 + camelcase: 2.1.1 + chalk: 1.1.3 + cli-boxes: 1.0.0 + filled-array: 1.1.0 + object-assign: 4.1.1 + repeating: 2.0.1 + string-width: 1.0.2 + widest-line: 1.0.0 + resolution: 8364d4248ac34ff0ef1b2f2bf49a6c60ce0d81b6 + /boxen/1.1.0: + dependencies: + ansi-align: 2.0.0 + camelcase: 4.1.0 + chalk: 1.1.3 + cli-boxes: 1.0.0 + string-width: 2.0.0 + term-size: 0.1.1 + widest-line: 1.0.0 + resolution: b1b69dd522305e807a99deee777dbd6e5167b102 + /brace-expansion/1.1.7: + dependencies: + balanced-match: 0.4.2 + concat-map: 0.0.1 + resolution: 3effc3c50e000531fb720eaff80f0ae8ef23cf59 + /braces/1.8.5: + dependencies: + expand-range: 1.8.2 + preserve: 0.2.0 + repeat-element: 1.1.2 + resolution: ba77962e12dff969d6b76711e914b737857bf6a7 + /brorand/1.1.0: 12c25efe40a45e3c323eb8675a0a0ce57b22371f + /browser-pack/6.0.2: + dependencies: + JSONStream: 1.3.1 + combine-source-map: 0.7.2 + defined: 1.0.0 + through2: 2.0.3 + umd: 3.0.1 + resolution: f86cd6cef4f5300c8e63e07a4d512f65fbff4531 + /browser-resolve/1.11.2: + dependencies: + resolve: 1.1.7 + resolution: 8ff09b0a2c421718a1051c260b32e48f442938ce + /browserify-aes/1.0.6: + dependencies: + buffer-xor: 1.0.3 + cipher-base: 1.0.3 + create-hash: 1.1.3 + evp_bytestokey: 1.0.0 + inherits: 2.0.3 + resolution: 5e7725dbdef1fd5930d4ebab48567ce451c48a0a + /browserify-cache-api/3.0.1: + dependencies: + async: 1.5.2 + through2: 2.0.3 + xtend: 4.0.1 + resolution: 96247e853f068fd6e0d45cc73f0bb2cd9778ef02 + /browserify-cipher/1.0.0: + dependencies: + browserify-aes: 1.0.6 + browserify-des: 1.0.0 + evp_bytestokey: 1.0.0 + resolution: 9988244874bf5ed4e28da95666dcd66ac8fc363a + /browserify-des/1.0.0: + dependencies: + cipher-base: 1.0.3 + des.js: 1.0.0 + inherits: 2.0.3 + resolution: daa277717470922ed2fe18594118a175439721dd + /browserify-incremental/3.1.1: + dependencies: + JSONStream: 0.10.0 + browserify-cache-api: 3.0.1 + through2: 2.0.3 + xtend: 4.0.1 + resolution: 0713cb7587247a632a9f08cf1bd169b878b62a8a + /browserify-rsa/4.0.1: + dependencies: + bn.js: 4.11.6 + randombytes: 2.0.4 + resolution: 21e0abfaf6f2029cf2fafb133567a701d4135524 + /browserify-sign/4.0.4: + dependencies: + bn.js: 4.11.6 + browserify-rsa: 4.0.1 + create-hash: 1.1.3 + create-hmac: 1.1.6 + elliptic: 6.4.0 + inherits: 2.0.3 + parse-asn1: 5.1.0 + resolution: aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298 + /browserify-zlib/0.1.4: + dependencies: + pako: 0.2.9 + resolution: bb35f8a519f600e0fa6b8485241c979d0141fb2d + /browserify/14.4.0: + dependencies: + JSONStream: 1.3.1 + assert: 1.4.1 + browser-pack: 6.0.2 + browser-resolve: 1.11.2 + browserify-zlib: 0.1.4 + buffer: 5.0.6 + cached-path-relative: 1.0.1 + concat-stream: 1.5.2 + console-browserify: 1.1.0 + constants-browserify: 1.0.0 + crypto-browserify: 3.11.0 + defined: 1.0.0 + deps-sort: 2.0.0 + domain-browser: 1.1.7 + duplexer2: 0.1.4 + events: 1.1.1 + glob: 7.1.2 + has: 1.0.1 + htmlescape: 1.1.1 + https-browserify: 1.0.0 + inherits: 2.0.3 + insert-module-globals: 7.0.1 + labeled-stream-splicer: 2.0.0 + module-deps: 4.1.1 + os-browserify: 0.1.2 + parents: 1.0.1 + path-browserify: 0.0.0 + process: 0.11.10 + punycode: 1.4.1 + querystring-es3: 0.2.1 + read-only-stream: 2.0.0 + readable-stream: 2.2.10 + resolve: 1.3.3 + shasum: 1.0.2 + shell-quote: 1.6.1 + stream-browserify: 2.0.1 + stream-http: 2.7.1 + string_decoder: 1.0.1 + subarg: 1.0.0 + syntax-error: 1.3.0 + through2: 2.0.3 + timers-browserify: 1.4.2 + tty-browserify: 0.0.0 + url: 0.11.0 + util: 0.10.3 + vm-browserify: 0.0.4 + xtend: 4.0.1 + resolution: 089a3463af58d0e48d8cd4070b3f74654d5abca9 + /browserslist/1.7.7: + dependencies: + caniuse-db: 1.0.30000676 + electron-to-chromium: 1.3.13 + resolution: 0bd76704258be829b2398bb50e4b62d1a166b0b9 + /buf-compare/1.0.1: fef28da8b8113a0a0db4430b0b6467b69730b34a + /buffer-xor/1.0.3: 26e61ed1422fb70dd42e6e36729ed51d855fe8d9 + /buffer/5.0.6: + dependencies: + base64-js: 1.2.0 + ieee754: 1.1.8 + resolution: 2ea669f7eec0b6eda05b08f8b5ff661b28573588 + /builtin-modules/1.1.1: 270f076c5a72c02f5b65a47df94c5fe3a278892f + /builtin-status-codes/3.0.0: 85982878e21b98e1c66425e03d0174788f569ee8 + /bytes/2.2.0: fd35464a403f6f9117c2de3609ecff9cae000588 + /bytes/2.4.0: 7d97196f9d5baf7f6935e25985549edd2a6c2339 + /cached-path-relative/1.0.1: d09c4b52800aa4c078e2dd81a869aac90d2e54e7 + /caching-transform/1.0.1: + dependencies: + md5-hex: 1.3.0 + mkdirp: 0.5.1 + write-file-atomic: 1.3.4 + resolution: 6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1 + /call-matcher/1.0.1: + dependencies: + core-js: 2.4.1 + deep-equal: 1.0.1 + espurify: 1.7.0 + estraverse: 4.2.0 + resolution: 5134d077984f712a54dad3cbf62de28dce416ca8 + /call-signature/0.0.2: a84abc825a55ef4cb2b028bd74e205a65b9a4996 + /caller-path/0.1.0: + dependencies: + callsites: 0.2.0 + resolution: 94085ef63581ecd3daa92444a8fe94e82577751f + /callsites/0.2.0: afab96262910a7f33c19a5775825c69f34e350ca + /camelcase-keys/2.1.0: + dependencies: + camelcase: 2.1.1 + map-obj: 1.0.1 + resolution: 308beeaffdf28119051efa1d932213c91b8f92e7 + /camelcase/1.2.1: 9bb5304d2e0b56698b2c758b08a3eaa9daa58a39 + /camelcase/2.1.1: 7c1d16d679a1bbe59ca02cacecfb011e201f5a1f + /camelcase/3.0.0: 32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a + /camelcase/4.1.0: d545635be1e33c542649c69173e5de6acfae34dd + /caniuse-api/1.6.1: + dependencies: + browserslist: 1.7.7 + caniuse-db: 1.0.30000676 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + resolution: b534e7c734c4f81ec5fbe8aca2ad24354b962c6c + /caniuse-db/1.0.30000676: 82ea578237637c8ff34a28acaade373b624c4ea8 + /capture-stack-trace/1.0.0: 4a6fa07399c26bba47f0b2496b4d0fb408c5550d + /caseless/0.12.0: 1b681c21ff84033c826543090689420d187151dc + /center-align/0.1.3: + dependencies: + align-text: 0.1.4 + lazy-cache: 1.0.4 + resolution: aa0d32629b6ee972200411cbd4461c907bc2b7ad + /chai/3.5.0: + dependencies: + assertion-error: 1.0.2 + deep-eql: 0.1.3 + type-detect: 1.0.0 + resolution: 4d02637b067fe958bdbfdd3a40ec56fef7373247 + /chalk/0.4.0: + dependencies: + ansi-styles: 1.0.0 + has-color: 0.1.7 + strip-ansi: 0.1.1 + resolution: 5199a3ddcd0c1efe23bc08c1b027b06176e0c64f + /chalk/0.5.1: + dependencies: + ansi-styles: 1.1.0 + escape-string-regexp: 1.0.5 + has-ansi: 0.1.0 + strip-ansi: 0.3.0 + supports-color: 0.2.0 + resolution: 663b3a648b68b55d04690d49167aa837858f2174 + /chalk/1.1.3: + dependencies: + ansi-styles: 2.2.1 + escape-string-regexp: 1.0.5 + has-ansi: 2.0.0 + strip-ansi: 3.0.1 + supports-color: 2.0.0 + resolution: a8115c55e4a702fe4d150abd3872822a7e09fc98 + /chokidar/1.7.0: + dependencies: + anymatch: 1.3.0 + async-each: 1.0.1 + fsevents: 1.1.1 + glob-parent: 2.0.0 + inherits: 2.0.3 + is-binary-path: 1.0.1 + is-glob: 2.0.1 + path-is-absolute: 1.0.1 + readdirp: 2.1.0 + resolution: 798e689778151c8076b4b360e5edd28cda2bb468 + /ci-info/1.0.0: dc5285f2b4e251821683681c381c3388f46ec534 + /cipher-base/1.0.3: + dependencies: + inherits: 2.0.3 + resolution: eeabf194419ce900da3018c207d212f2a6df0a07 + /circular-json/0.3.1: be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d + /clap/1.1.3: + dependencies: + chalk: 1.1.3 + resolution: b3bd36e93dd4cbfb395a3c26896352445265c05b + /clean-stack/1.3.0: 9e821501ae979986c46b1d66d2d432db2fd4ae31 + /clean-yaml-object/0.1.0: 63fb110dc2ce1a84dc21f6d9334876d010ae8b68 + /cli-boxes/1.0.0: 4fa917c3e59c94a004cd61f8ee509da651687143 + /cli-cursor/1.0.2: + dependencies: + restore-cursor: 1.0.1 + resolution: 64da3f7d56a54412e59794bd62dc35295e8f2987 + /cli-cursor/2.1.0: + dependencies: + restore-cursor: 2.0.0 + resolution: b35dac376479facc3e94747d41d0d0f5238ffcb5 + /cli-spinners/0.1.2: bb764d88e185fb9e1e6a2a1f19772318f605e31c + /cli-spinners/1.0.0: ef987ed3d48391ac3dab9180b406a742180d6e6a + /cli-truncate/0.2.1: + dependencies: + slice-ansi: 0.0.4 + string-width: 1.0.2 + resolution: 9f15cfbb0705005369216c626ac7d05ab90dd574 + /cli-width/2.1.0: b234ca209b29ef66fc518d9b98d5847b00edf00a + /cliui/2.1.0: + dependencies: + center-align: 0.1.3 + right-align: 0.1.3 + wordwrap: 0.0.2 + resolution: 4b475760ff80264c762c3a1719032e91c7fea0d1 + /cliui/3.2.0: + dependencies: + string-width: 1.0.2 + strip-ansi: 3.0.1 + wrap-ansi: 2.1.0 + resolution: 120601537a916d29940f934da3b48d585a39213d + /clone-stats/0.0.1: b88f94a82cf38b8791d58046ea4029ad88ca99d1 + /clone/0.2.0: c6126a90ad4f72dbf5acdb243cc37724fe93fc1f + /clone/1.0.2: 260b7a99ebb1edfe247538175f783243cb19d149 + /co-with-promise/4.6.0: + dependencies: + pinkie-promise: 1.0.0 + resolution: 413e7db6f5893a60b942cf492c4bec93db415ab7 + /co/4.6.0: 6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184 + /coa/1.0.2: + dependencies: + q: 1.5.0 + resolution: 2ba9fec3b4aa43d7a49d7e6c3561e92061b6bcec + /code-excerpt/2.1.0: + dependencies: + convert-to-spaces: 1.0.2 + resolution: 5dcc081e88f4a7e3b554e9e35d7ef232d47f8147 + /code-point-at/1.1.0: 0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77 + /color-convert/1.9.0: + dependencies: + color-name: 1.1.2 + resolution: 1accf97dd739b983bf994d56fec8f95853641b7a + /color-name/1.1.2: 5c8ab72b64bd2215d617ae9559ebb148475cf98d + /color-string/0.3.0: + dependencies: + color-name: 1.1.2 + resolution: 27d46fb67025c5c2fa25993bfbf579e47841b991 + /color/0.11.4: + dependencies: + clone: 1.0.2 + color-convert: 1.9.0 + color-string: 0.3.0 + resolution: 6d7b5c74fb65e841cd48792ad1ed5e07b904d764 + /colormin/1.1.2: + dependencies: + color: 0.11.4 + css-color-names: 0.0.4 + has: 1.0.1 + resolution: ea2f7420a72b96881a38aae59ec124a6f7298133 + /colors/1.1.2: 168a4701756b6a7f51a12ce0c97bfa28c084ed63 + /combine-source-map/0.7.2: + dependencies: + convert-source-map: 1.1.3 + inline-source-map: 0.6.2 + lodash.memoize: 3.0.4 + source-map: 0.5.6 + resolution: 0870312856b307a87cc4ac486f3a9a62aeccc09e + /combined-stream/1.0.5: + dependencies: + delayed-stream: 1.0.0 + resolution: 938370a57b4a51dea2c77c15d5c5fdf895164009 + /commander/2.9.0: + dependencies: + graceful-readlink: 1.0.1 + resolution: 9c99094176e12240cb22d6c5146098400fe0f7d4 + /common-path-prefix/1.0.0: cd52f6f0712e0baab97d6f9732874f22f47752c0 + /commondir/1.0.1: ddd800da0c66127393cca5950ea968a3aaf1253b + /concat-map/0.0.1: d8a96bd77fd68df7793a73036a3ba0d5405d477b + /concat-stream/1.5.2: + dependencies: + inherits: 2.0.3 + readable-stream: 2.0.6 + typedarray: 0.0.6 + resolution: 708978624d856af41a5a741defdd261da752c266 + /concat-stream/1.6.0: + dependencies: + inherits: 2.0.3 + readable-stream: 2.2.10 + typedarray: 0.0.6 + resolution: 0aac662fd52be78964d5532f694784e70110acf7 + /configstore/2.1.0: + dependencies: + dot-prop: 3.0.0 + graceful-fs: 4.1.11 + mkdirp: 0.5.1 + object-assign: 4.1.1 + os-tmpdir: 1.0.2 + osenv: 0.1.4 + uuid: 2.0.3 + write-file-atomic: 1.3.4 + xdg-basedir: 2.0.0 + resolution: 737a3a7036e9886102aa6099e47bb33ab1aba1a1 + /configstore/3.1.0: + dependencies: + dot-prop: 4.1.1 + graceful-fs: 4.1.11 + make-dir: 1.0.0 + unique-string: 1.0.0 + write-file-atomic: 2.1.0 + xdg-basedir: 3.0.0 + resolution: 45df907073e26dfa1cf4b2d52f5b60545eaa11d1 + /console-browserify/1.1.0: + dependencies: + date-now: 0.1.4 + resolution: f0241c45730a9fc6323b206dbf38edc741d0bb10 + /console-control-strings/1.1.0: 3d7cf4464db6446ea644bf4b39507f9851008e8e + /constants-browserify/1.0.0: c20b96d8c617748aaf1c16021760cd27fcb8cb75 + /contains-path/0.1.0: fe8cf184ff6670b6baef01a9d4861a5cbec4120a + /content-type/1.0.2: b7d113aee7a8dd27bd21133c4dc2529df1721eed + /convert-source-map/1.1.3: 4829c877e9fe49b3161f3bf3673888e204699860 + /convert-source-map/1.5.0: 9acd70851c6d5dfdd93d9282e5edf94a03ff46b5 + /convert-to-spaces/1.0.2: 7e3e48bbe6d997b1417ddca2868204b4d3d85715 + /core-assert/0.2.1: + dependencies: + buf-compare: 1.0.1 + is-error: 2.2.1 + resolution: f85e2cf9bfed28f773cc8b3fa5c5b69bdc02fe3f + /core-js/2.4.1: 4de911e667b0eae9124e34254b53aea6fc618d3e + /core-util-is/1.0.2: b5fd54220aa2bc5ab57aab7140c940754503c1a7 + /cosmiconfig/1.1.0: + dependencies: + graceful-fs: 4.1.11 + js-yaml: 3.8.4 + minimist: 1.2.0 + object-assign: 4.1.1 + os-homedir: 1.0.2 + parse-json: 2.2.0 + pinkie-promise: 2.0.1 + require-from-string: 1.2.1 + resolution: 0dea0f9804efdfb929fbb1b188e25553ea053d37 + /cosmiconfig/2.1.3: + dependencies: + is-directory: 0.3.1 + js-yaml: 3.8.4 + minimist: 1.2.0 + object-assign: 4.1.1 + os-homedir: 1.0.2 + parse-json: 2.2.0 + require-from-string: 1.2.1 + resolution: 952771eb0dddc1cb3fa2f6fbe51a522e93b3ee0a + /create-ecdh/4.0.0: + dependencies: + bn.js: 4.11.6 + elliptic: 6.4.0 + resolution: 888c723596cdf7612f6498233eebd7a35301737d + /create-error-class/3.0.2: + dependencies: + capture-stack-trace: 1.0.0 + resolution: 06be7abef947a3f14a30fd610671d401bca8b7b6 + /create-hash/1.1.3: + dependencies: + cipher-base: 1.0.3 + inherits: 2.0.3 + ripemd160: 2.0.1 + sha.js: 2.4.8 + resolution: 606042ac8b9262750f483caddab0f5819172d8fd + /create-hmac/1.1.6: + dependencies: + cipher-base: 1.0.3 + create-hash: 1.1.3 + inherits: 2.0.3 + ripemd160: 2.0.1 + safe-buffer: 5.1.0 + sha.js: 2.4.8 + resolution: acb9e221a4e17bdb076e90657c42b93e3726cf06 + /cross-spawn-async/2.2.5: + dependencies: + lru-cache: 4.0.2 + which: 1.2.14 + resolution: 845ff0c0834a3ded9d160daca6d390906bb288cc + /cross-spawn/3.0.1: + dependencies: + lru-cache: 4.0.2 + which: 1.2.14 + resolution: 1256037ecb9f0c5f79e3d6ef135e30770184b982 + /cross-spawn/4.0.2: + dependencies: + lru-cache: 4.0.2 + which: 1.2.14 + resolution: 7b9247621c23adfdd3856004a823cbe397424d41 + /cross-spawn/5.1.0: + dependencies: + lru-cache: 4.0.2 + shebang-command: 1.2.0 + which: 1.2.14 + resolution: e8bd0efee58fcff6f8f94510a0a554bbfa235449 + /cryptiles/2.0.5: + dependencies: + boom: 2.10.1 + resolution: 3bdfecdc608147c1c67202fa291e7dca59eaa3b8 + /crypto-browserify/3.11.0: + dependencies: + browserify-cipher: 1.0.0 + browserify-sign: 4.0.4 + create-ecdh: 4.0.0 + create-hash: 1.1.3 + create-hmac: 1.1.6 + diffie-hellman: 5.0.2 + inherits: 2.0.3 + pbkdf2: 3.0.12 + public-encrypt: 4.0.0 + randombytes: 2.0.4 + resolution: 3652a0906ab9b2a7e0c3ce66a408e957a2485522 + /crypto-random-string/1.0.0: a230f64f568310e1498009940790ec99545bca7e + /css-color-names/0.0.4: 808adc2e79cf84738069b646cb20ec27beb629e0 + /css/2.2.1: + dependencies: + inherits: 2.0.3 + source-map: 0.1.43 + source-map-resolve: 0.3.1 + urix: 0.1.0 + resolution: 73a4c81de85db664d4ee674f7d47085e3b2d55dc + /cssnano/3.10.0: + dependencies: + autoprefixer: 6.7.7 + decamelize: 1.2.0 + defined: 1.0.0 + has: 1.0.1 + object-assign: 4.1.1 + postcss: 5.2.17 + postcss-calc: 5.3.1 + postcss-colormin: 2.2.2 + postcss-convert-values: 2.6.1 + postcss-discard-comments: 2.0.4 + postcss-discard-duplicates: 2.1.0 + postcss-discard-empty: 2.1.0 + postcss-discard-overridden: 0.1.1 + postcss-discard-unused: 2.2.3 + postcss-filter-plugins: 2.0.2 + postcss-merge-idents: 2.1.7 + postcss-merge-longhand: 2.0.2 + postcss-merge-rules: 2.1.2 + postcss-minify-font-values: 1.0.5 + postcss-minify-gradients: 1.0.5 + postcss-minify-params: 1.2.2 + postcss-minify-selectors: 2.1.1 + postcss-normalize-charset: 1.1.1 + postcss-normalize-url: 3.0.8 + postcss-ordered-values: 2.2.3 + postcss-reduce-idents: 2.4.0 + postcss-reduce-initial: 1.0.1 + postcss-reduce-transforms: 1.0.4 + postcss-svgo: 2.1.6 + postcss-unique-selectors: 2.0.2 + postcss-value-parser: 3.3.0 + postcss-zindex: 2.2.0 + resolution: 4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38 + /csso/2.0.0: + dependencies: + clap: 1.1.3 + source-map: 0.5.6 + resolution: 178b43a44621221c27756086f531e02f42900ee8 + /csso/2.3.2: + dependencies: + clap: 1.1.3 + source-map: 0.5.6 + resolution: ddd52c587033f49e94b71fc55569f252e8ff5f85 + /currently-unhandled/0.4.1: + dependencies: + array-find-index: 1.0.2 + resolution: 988df33feab191ef799a61369dd76c17adf957ea + /d/1.0.0: + dependencies: + es5-ext: 0.10.22 + resolution: 754bb5bfe55451da69a58b94d45f4c5b0462d58f + /dashdash/1.14.1: + dependencies: + assert-plus: 1.0.0 + resolution: 853cfa0f7cbe2fed5de20326b8dd581035f6e2f0 + /date-fns/1.28.5: 257cfc45d322df45ef5658665967ee841cd73faf + /date-now/0.1.4: eaf439fd4d4848ad74e5cc7dbef200672b9e345b + /date-time/0.1.1: ed2f6d93d9790ce2fd66d5b5ff3edd5bbcbf3b07 + /dateformat/2.0.0: 2743e3abb5c3fc2462e527dca445e04e9f4dee17 + /debug-fabulous/0.1.0: + dependencies: + debug: 2.6.8 + object-assign: 4.1.0 + resolution: ad0ea07a5d519324fb55842a8f34ee59c7f8ff6c + /debug/2.2.0: + dependencies: + ms: 0.7.1 + resolution: f87057e995b1a1f6ae6a4960664137bc56f039da + /debug/2.6.8: + dependencies: + ms: 2.0.0 + resolution: e731531ca2ede27d188222427da17821d68ff4fc + /decamelize/1.2.0: f6534d15148269b20352e7bee26f501f9a191290 + /dedent/0.7.0: 2495ddbaf6eb874abb0e1be9df22d2e5a544326c + /deep-assign/1.0.0: + dependencies: + is-obj: 1.0.1 + resolution: b092743be8427dc621ea0067cdec7e70dd19f37b + /deep-eql/0.1.3: + dependencies: + type-detect: 0.1.1 + resolution: ef558acab8de25206cd713906d74e56930eb69f2 + /deep-equal/1.0.1: f5d260292b660e084eff4cdbc9f08ad3247448b5 + /deep-extend/0.4.2: 48b699c27e334bf89f10892be432f6e4c7d34a7f + /deep-is/0.1.3: b369d6fb5dbc13eecf524f91b070feedc357cf34 + /deep-strict-equal/0.2.0: + dependencies: + core-assert: 0.2.1 + resolution: 4a078147a8ab57f6a0d4f5547243cd22f44eb4e4 + /defaults/1.0.3: + dependencies: + clone: 1.0.2 + resolution: c656051e9817d9ff08ed881477f3fe4019f3ef7d + /defined/1.0.0: c98d9bcef75674188e110969151199e39b1fa693 + /del/2.2.2: + dependencies: + globby: 5.0.0 + is-path-cwd: 1.0.0 + is-path-in-cwd: 1.0.0 + object-assign: 4.1.1 + pify: 2.3.0 + pinkie-promise: 2.0.1 + rimraf: 2.6.1 + resolution: c12c981d067846c84bcaf862cff930d907ffd1a8 + /delayed-stream/1.0.0: df3ae199acadfb7d440aaae0b29e2272b24ec619 + /delegates/1.0.0: 84c6e159b81904fdca59a0ef44cd870d31250f9a + /depd/1.1.0: e1bd82c6aab6ced965b97b88b17ed3e528ca18c3 + /deprecated/0.0.1: f9c9af5464afa1e7a971458a8bdef2aa94d5bb19 + /deps-sort/2.0.0: + dependencies: + JSONStream: 1.3.1 + shasum: 1.0.2 + subarg: 1.0.0 + through2: 2.0.3 + resolution: 091724902e84658260eb910748cccd1af6e21fb5 + /des.js/1.0.0: + dependencies: + inherits: 2.0.3 + minimalistic-assert: 1.0.0 + resolution: c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc + /detect-file/0.1.0: + dependencies: + fs-exists-sync: 0.1.0 + resolution: 4935dedfd9488648e006b0129566e9386711ea63 + /detect-indent/4.0.0: + dependencies: + repeating: 2.0.1 + resolution: f76d064352cdf43a1cb6ce619c4ee3a9475de208 + /detect-indent/5.0.0: 3871cc0a6a002e8c3e5b3cf7f336264675f06b9d + /detect-newline/2.1.0: f41f1c10be4b00e87b5f13da680759f2c5bfd3e2 + /detective/4.5.0: + dependencies: + acorn: 4.0.13 + defined: 1.0.0 + resolution: 6e5a8c6b26e6c7a254b1c6b6d7490d98ec91edd1 + /diff/3.2.0: c9ce393a4b7cbd0b058a725c93df299027868ff9 + /diffie-hellman/5.0.2: + dependencies: + bn.js: 4.11.6 + miller-rabin: 4.0.0 + randombytes: 2.0.4 + resolution: b5835739270cfe26acf632099fded2a07f209e5e + /doctrine/1.5.0: + dependencies: + esutils: 2.0.2 + isarray: 1.0.0 + resolution: 379dce730f6166f76cefa4e6707a159b02c5a6fa + /doctrine/2.0.0: + dependencies: + esutils: 2.0.2 + isarray: 1.0.0 + resolution: c73d8d2909d22291e1a007a395804da8b665fe63 + /domain-browser/1.1.7: 867aa4b093faa05f1de08c06f4d7b21fdf8698bc + /dot-prop/3.0.0: + dependencies: + is-obj: 1.0.1 + resolution: 1b708af094a49c9a0e7dbcad790aba539dac1177 + /dot-prop/4.1.1: + dependencies: + is-obj: 1.0.1 + resolution: a8493f0b7b5eeec82525b5c7587fa7de7ca859c1 + /duplexer/0.1.1: ace6ff808c1ce66b57d1ebf97977acb02334cfc1 + /duplexer2/0.0.2: + dependencies: + readable-stream: 1.1.14 + resolution: c614dcf67e2fb14995a91711e5a617e8a60a31db + /duplexer2/0.1.4: + dependencies: + readable-stream: 2.2.10 + resolution: 8b12dab878c0d69e3e7891051662a32fc6bddcc1 + /duplexer3/0.1.4: ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2 + /ecc-jsbn/0.1.1: + dependencies: + jsbn: 0.1.1 + resolution: 0fc73a9ed5f0d53c38193398523ef7e543777505 + /ee-first/1.1.1: 590c61156b0ae2f4f0255732a158b266bc56b21d + /electron-to-chromium/1.3.13: 1b3a5eace6e087bb5e257a100b0cbfe81b2891fc + /elegant-spinner/1.0.1: db043521c95d7e303fd8f345bedc3349cfb0729e + /elliptic/6.4.0: + dependencies: + bn.js: 4.11.6 + brorand: 1.1.0 + hash.js: 1.0.3 + hmac-drbg: 1.0.1 + inherits: 2.0.3 + minimalistic-assert: 1.0.0 + minimalistic-crypto-utils: 1.0.1 + resolution: cac9af8762c85836187003c8dfe193e5e2eae5df + /empower-core/0.6.1: + dependencies: + call-signature: 0.0.2 + core-js: 2.4.1 + resolution: 6c187f502fcef7554d57933396aac655483772b1 + /end-of-stream/0.1.5: + dependencies: + once: 1.3.3 + resolution: 8e177206c3c80837d85632e8b9359dfe8b2f6eaf + /enhance-visitors/1.0.0: + dependencies: + lodash: 4.17.4 + resolution: aa945d05da465672a1ebd38fee2ed3da8518e95a + /equal-length/1.0.1: 21ca112d48ab24b4e1e7ffc0e5339d31fdfc274c + /error-ex/1.3.1: + dependencies: + is-arrayish: 0.2.1 + resolution: f855a86ce61adc4e8621c3cda21e7a7612c3a8dc + /es3ify/0.1.4: + dependencies: + esprima-fb: 3001.1.0-dev-harmony-fb + jstransform: 3.0.0 + through: 2.3.8 + resolution: ad9fa5df1ae34f3f31e1211b5818b2d51078dfd1 + /es5-ext/0.10.22: + dependencies: + es6-iterator: 2.0.1 + es6-symbol: 3.1.1 + resolution: 1876c51f990769c112c781ea3ebe89f84fd39071 + /es6-iterator/2.0.1: + dependencies: + d: 1.0.0 + es5-ext: 0.10.22 + es6-symbol: 3.1.1 + resolution: 8e319c9f0453bf575d374940a655920e59ca5512 + /es6-map/0.1.5: + dependencies: + d: 1.0.0 + es5-ext: 0.10.22 + es6-iterator: 2.0.1 + es6-set: 0.1.5 + es6-symbol: 3.1.1 + event-emitter: 0.3.5 + resolution: 9136e0503dcc06a301690f0bb14ff4e364e949f0 + /es6-set/0.1.5: + dependencies: + d: 1.0.0 + es5-ext: 0.10.22 + es6-iterator: 2.0.1 + es6-symbol: 3.1.1 + event-emitter: 0.3.5 + resolution: d2b3ec5d4d800ced818db538d28974db0a73ccb1 + /es6-symbol/3.1.1: + dependencies: + d: 1.0.0 + es5-ext: 0.10.22 + resolution: bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77 + /es6-weak-map/2.0.2: + dependencies: + d: 1.0.0 + es5-ext: 0.10.22 + es6-iterator: 2.0.1 + es6-symbol: 3.1.1 + resolution: 5e3ab32251ffd1538a1f8e5ffa1357772f92d96f + /escape-string-regexp/1.0.5: 1b61c0562190a8dff6ae3bb2cf0200ca130b86d4 + /escodegen/1.8.1: + dependencies: + esprima: 2.7.3 + estraverse: 1.9.3 + esutils: 2.0.2 + optionator: 0.8.2 + source-map: 0.2.0 + resolution: 5a5b53af4693110bebb0867aa3430dd3b70a1018 + /escope/3.6.0: + dependencies: + es6-map: 0.1.5 + es6-weak-map: 2.0.2 + esrecurse: 4.1.0 + estraverse: 4.2.0 + resolution: e01975e812781a163a6dadfdd80398dc64c889c3 + /eslint-config-xo/0.18.2: 0a157120875619929e735ffd6b185c41e8a187af + /eslint-formatter-pretty/1.1.0: + dependencies: + ansi-escapes: 1.4.0 + chalk: 1.1.3 + log-symbols: 1.0.2 + plur: 2.1.2 + string-width: 2.0.0 + resolution: ab4d06da02fed8c13ae9f0dc540a433ef7ed6f5e + /eslint-import-resolver-node/0.2.3: + dependencies: + debug: 2.6.8 + object-assign: 4.1.1 + resolve: 1.3.3 + resolution: 5add8106e8c928db2cba232bcd9efa846e3da16c + /eslint-module-utils/2.0.0: + dependencies: + debug: 2.2.0 + pkg-dir: 1.0.0 + resolution: a6f8c21d901358759cdc35dbac1982ae1ee58bce + /eslint-plugin-ava/4.2.0: + dependencies: + arrify: 1.0.1 + deep-strict-equal: 0.2.0 + enhance-visitors: 1.0.0 + espree: 3.4.3 + espurify: 1.7.0 + multimatch: 2.1.0 + pkg-up: 1.0.0 + req-all: 1.0.0 + resolution: 12e4664659c1fae7895fa3f346c313ceb8907c77 + /eslint-plugin-import/2.3.0: + dependencies: + builtin-modules: 1.1.1 + contains-path: 0.1.0 + debug: 2.6.8 + doctrine: 1.5.0 + eslint-import-resolver-node: 0.2.3 + eslint-module-utils: 2.0.0 + has: 1.0.1 + lodash.cond: 4.5.2 + minimatch: 3.0.4 + read-pkg-up: 2.0.0 + resolution: 37c801e0ada0e296cbdf20c3f393acb5b52af36b + /eslint-plugin-no-use-extend-native/0.3.12: + dependencies: + is-get-set-prop: 1.0.0 + is-js-type: 2.0.0 + is-obj-prop: 1.0.0 + is-proto-prop: 1.0.0 + resolution: 3ad9a00c2df23b5d7f7f6be91550985a4ab701ea + /eslint-plugin-promise/3.5.0: 78fbb6ffe047201627569e85a6c5373af2a68fca + /eslint-plugin-unicorn/2.1.1: + dependencies: + lodash.camelcase: 4.3.0 + lodash.kebabcase: 4.1.1 + lodash.snakecase: 4.1.1 + lodash.upperfirst: 4.3.1 + req-all: 1.0.0 + resolution: 3e9294366799b715e16a6df89159495b68930cb3 + /eslint/3.19.0: + dependencies: + babel-code-frame: 6.22.0 + chalk: 1.1.3 + concat-stream: 1.6.0 + debug: 2.6.8 + doctrine: 2.0.0 + escope: 3.6.0 + espree: 3.4.3 + esquery: 1.0.0 + estraverse: 4.2.0 + esutils: 2.0.2 + file-entry-cache: 2.0.0 + glob: 7.1.2 + globals: 9.17.0 + ignore: 3.3.3 + imurmurhash: 0.1.4 + inquirer: 0.12.0 + is-my-json-valid: 2.16.0 + is-resolvable: 1.0.0 + js-yaml: 3.8.4 + json-stable-stringify: 1.0.1 + levn: 0.3.0 + lodash: 4.17.4 + mkdirp: 0.5.1 + natural-compare: 1.4.0 + optionator: 0.8.2 + path-is-inside: 1.0.2 + pluralize: 1.2.1 + progress: 1.1.8 + require-uncached: 1.0.3 + shelljs: 0.7.7 + strip-bom: 3.0.0 + strip-json-comments: 2.0.1 + table: 3.8.3 + text-table: 0.2.0 + user-home: 2.0.0 + resolution: c8fc6201c7f40dd08941b87c085767386a679acc + /esmangle-evaluator/1.0.1: 620d866ef4861b3311f75766d52a8572bb3c6336 + /espower-location-detector/1.0.0: + dependencies: + is-url: 1.2.2 + path-is-absolute: 1.0.1 + source-map: 0.5.6 + xtend: 4.0.1 + resolution: a17b7ecc59d30e179e2bef73fb4137704cb331b5 + /espree/3.4.3: + dependencies: + acorn: 5.0.3 + acorn-jsx: 3.0.1 + resolution: 2910b5ccd49ce893c2ffffaab4fd8b3a31b82374 + /esprima-fb/15001.1001.0-dev-harmony-fb: 43beb57ec26e8cf237d3dd8b33e42533577f2659 + /esprima-fb/3001.1.0-dev-harmony-fb: b77d37abcd38ea0b77426bb8bc2922ce6b426411 + /esprima/2.7.3: 96e3b70d5779f6ad49cd032673d1c312767ba581 + /esprima/3.1.3: fdca51cee6133895e3c88d535ce49dbff62a4633 + /espurify/1.7.0: + dependencies: + core-js: 2.4.1 + resolution: 1c5cf6cbccc32e6f639380bd4f991fab9ba9d226 + /esquery/1.0.0: + dependencies: + estraverse: 4.2.0 + resolution: cfba8b57d7fba93f17298a8a006a04cda13d80fa + /esrecurse/4.1.0: + dependencies: + estraverse: 4.1.1 + object-assign: 4.1.1 + resolution: 4713b6536adf7f2ac4f327d559e7756bff648220 + /estraverse/1.9.3: af67f2dc922582415950926091a4005d29c9bb44 + /estraverse/4.1.1: f6caca728933a850ef90661d0e17982ba47111a2 + /estraverse/4.2.0: 0dee3fed31fcd469618ce7342099fc1afa0bdb13 + /esutils/2.0.2: 0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b + /event-emitter/0.3.5: + dependencies: + d: 1.0.0 + es5-ext: 0.10.22 + resolution: df8c69eef1647923c7157b9ce83840610b02cc39 + /event-stream/3.3.4: + dependencies: + duplexer: 0.1.1 + from: 0.1.7 + map-stream: 0.1.0 + pause-stream: 0.0.11 + split: 0.3.3 + stream-combiner: 0.0.4 + through: 2.3.8 + resolution: 4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571 + /events/1.1.1: 9ebdb7635ad099c70dcc4c2a1f5004288e8bd924 + /evp_bytestokey/1.0.0: + dependencies: + create-hash: 1.1.3 + resolution: 497b66ad9fef65cd7c08a6180824ba1476b66e53 + /execa/0.4.0: + dependencies: + cross-spawn-async: 2.2.5 + is-stream: 1.1.0 + npm-run-path: 1.0.0 + object-assign: 4.1.1 + path-key: 1.0.0 + strip-eof: 1.0.0 + resolution: 4eb6467a36a095fabb2970ff9d5e3fb7bce6ebc3 + /execa/0.5.1: + dependencies: + cross-spawn: 4.0.2 + get-stream: 2.3.1 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.2 + strip-eof: 1.0.0 + resolution: de3fb85cb8d6e91c85bcbceb164581785cb57b36 + /execa/0.6.3: + dependencies: + cross-spawn: 5.1.0 + get-stream: 3.0.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.2 + strip-eof: 1.0.0 + resolution: 57b69a594f081759c69e5370f0d17b9cb11658fe + /exit-hook/1.1.1: f05ca233b48c05d54fff07765df8507e95c02ff8 + /expand-brackets/0.1.5: + dependencies: + is-posix-bracket: 0.1.1 + resolution: df07284e342a807cd733ac5af72411e581d1177b + /expand-range/1.8.2: + dependencies: + fill-range: 2.2.3 + resolution: a299effd335fe2721ebae8e257ec79644fc85337 + /expand-tilde/1.2.2: + dependencies: + os-homedir: 1.0.2 + resolution: 0b81eba897e5a3d31d1c3d102f8f01441e559449 + /extend/1.3.0: d1516fb0ff5624d2ebf9123ea1dac5a1994004f8 + /extend/3.0.1: a755ea7bc1adfcc5a31ce7e762dbaadc5e636444 + /extglob/0.3.2: + dependencies: + is-extglob: 1.0.0 + resolution: 2e18ff3d2f49ab2765cec9023f011daa8d8349a1 + /extsprintf/1.0.2: e1080e0658e300b06294990cc70e1502235fd550 + /falafel/1.2.0: + dependencies: + acorn: 1.2.2 + foreach: 2.0.5 + isarray: 0.0.1 + object-keys: 1.0.11 + resolution: c18d24ef5091174a497f318cd24b026a25cddab4 + /fancy-log/1.3.0: + dependencies: + chalk: 1.1.3 + time-stamp: 1.1.0 + resolution: 45be17d02bb9917d60ccffd4995c999e6c8c9948 + /fast-levenshtein/2.0.6: 3d8a5c66883a16a30ca8643e851f19baa7797917 + /faye-websocket/0.7.3: + dependencies: + websocket-driver: 0.6.5 + resolution: cc4074c7f4a4dfd03af54dd65c354b135132ce11 + /figures/1.7.0: + dependencies: + escape-string-regexp: 1.0.5 + object-assign: 4.1.1 + resolution: cbe1e3affcf1cd44b80cadfed28dc793a9701d2e + /figures/2.0.0: + dependencies: + escape-string-regexp: 1.0.5 + resolution: 3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962 + /file-entry-cache/2.0.0: + dependencies: + flat-cache: 1.2.2 + object-assign: 4.1.1 + resolution: c392990c3e684783d838b8c84a45d8a048458361 + /filename-regex/2.0.1: c1c4b9bee3e09725ddb106b75c1e301fe2f18b26 + /fill-range/2.2.3: + dependencies: + is-number: 2.1.0 + isobject: 2.1.0 + randomatic: 1.1.6 + repeat-element: 1.1.2 + repeat-string: 1.6.1 + resolution: 50b77dfd7e469bc7492470963699fe7a8485a723 + /filled-array/1.1.0: c3c4f6c663b923459a9aa29912d2d031f1507f84 + /find-cache-dir/0.1.1: + dependencies: + commondir: 1.0.1 + mkdirp: 0.5.1 + pkg-dir: 1.0.0 + resolution: c8defae57c8a52a8a784f9e31c57c742e993a0b9 + /find-index/0.1.1: 675d358b2ca3892d795a1ab47232f8b6e2e0dde4 + /find-parent-dir/0.3.0: 33c44b429ab2b2f0646299c5f9f718f376ff8d54 + /find-up/1.1.2: + dependencies: + path-exists: 2.1.0 + pinkie-promise: 2.0.1 + resolution: 6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f + /find-up/2.1.0: + dependencies: + locate-path: 2.0.0 + resolution: 45d1b7e506c717ddd482775a2b77920a3c0c57a7 + /findup-sync/0.4.3: + dependencies: + detect-file: 0.1.0 + is-glob: 2.0.1 + micromatch: 2.3.11 + resolve-dir: 0.1.1 + resolution: 40043929e7bc60adf0b7f4827c4c6e75a0deca12 + /fined/1.0.2: + dependencies: + expand-tilde: 1.2.2 + lodash.assignwith: 4.2.0 + lodash.isempty: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.pick: 4.4.0 + parse-filepath: 1.0.1 + resolution: 5b28424b760d7598960b7ef8480dff8ad3660e97 + /first-chunk-stream/1.0.0: 59bfb50cd905f60d7c394cd3d9acaab4e6ad934e + /flagged-respawn/0.3.2: ff191eddcd7088a675b2610fffc976be9b8074b5 + /flat-cache/1.2.2: + dependencies: + circular-json: 0.3.1 + del: 2.2.2 + graceful-fs: 4.1.11 + write: 0.2.1 + resolution: fa86714e72c21db88601761ecf2f555d1abc6b96 + /flatten/1.0.2: dae46a9d78fbe25292258cc1e780a41d95c03782 + /fn-name/2.0.1: 5214d7537a4d06a4a301c0cc262feb84188002e7 + /for-in/1.0.2: 81068d295a8142ec0ac726c6e2200c30fb6d5e80 + /for-own/0.1.5: + dependencies: + for-in: 1.0.2 + resolution: 5265c681a4f294dabbf17c9509b6763aa84510ce + /foreach/2.0.5: 0bee005018aeb260d0a3af3ae658dd0136ec1b99 + /forever-agent/0.6.1: fbc71f0c41adeb37f96c577ad1ed42d8fdacca91 + /form-data/2.1.4: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.5 + mime-types: 2.1.15 + resolution: 33c183acf193276ecaa98143a69e94bfee1750d1 + /from/0.1.7: 83c60afc58b9c56997007ed1a768b3ab303a44fe + /fs-exists-sync/0.1.0: 982d6893af918e72d08dec9e8673ff2b5a8d6add + /fs.realpath/1.0.0: 1504ad2523158caa40db4a2787cb01411994ea4f + /fsevents/1.1.1: + dependencies: + nan: 2.6.2 + resolution: f19fd28f43eeaf761680e519a203c4d0b3d31aff + /fstream/1.0.11: + dependencies: + graceful-fs: 4.1.11 + inherits: 2.0.3 + mkdirp: 0.5.1 + rimraf: 2.6.1 + resolution: 5c1fb1f117477114f0632a0eb4b71b3cb0fd3171 + /function-bind/1.1.0: 16176714c801798e4e8f2cf7f7529467bb4a5771 + /gauge/2.7.4: + dependencies: + aproba: 1.1.2 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.2 + string-width: 1.0.2 + strip-ansi: 3.0.1 + wide-align: 1.1.2 + resolution: 2c03405c7538c39d7eb37b317022e325fb018bf7 + /gaze/0.5.2: + dependencies: + globule: 0.1.0 + resolution: 40b709537d24d1d45767db5a908689dfe69ac44f + /gaze/1.1.2: + dependencies: + globule: 1.1.0 + resolution: 847224677adb8870d679257ed3388fdb61e40105 + /generate-function/2.0.0: 6858fe7c0969b7d4e9093337647ac79f60dfbe74 + /generate-object-property/1.2.0: + dependencies: + is-property: 1.0.2 + resolution: 9c0e1c40308ce804f4783618b937fa88f99d50d0 + /get-caller-file/1.0.2: f702e63127e7e231c160a80c1554acb70d5047e5 + /get-port/2.1.0: + dependencies: + pinkie-promise: 2.0.1 + resolution: 8783f9dcebd1eea495a334e1a6a251e78887ab1a + /get-set-props/0.1.0: 998475c178445686d0b32246da5df8dbcfbe8ea3 + /get-stdin/4.0.1: b968c6b0a04384324902e8bf1a5df32579a450fe + /get-stdin/5.0.1: 122e161591e21ff4c52530305693f20e6393a398 + /get-stream/2.3.1: + dependencies: + object-assign: 4.1.1 + pinkie-promise: 2.0.1 + resolution: 5f38f93f346009666ee0150a054167f91bdd95de + /get-stream/3.0.0: 8e943d1358dc37555054ecbe2edb05aa174ede14 + /getpass/0.1.7: + dependencies: + assert-plus: 1.0.0 + resolution: 5eff8e3e684d569ae4cb2b1282604e8ba62149fa + /glob-base/0.3.0: + dependencies: + glob-parent: 2.0.0 + is-glob: 2.0.1 + resolution: dbb164f6221b1c0b1ccf82aea328b497df0ea3c4 + /glob-parent/2.0.0: + dependencies: + is-glob: 2.0.1 + resolution: 81383d72db054fcccf5336daa902f182f6edbb28 + /glob-stream/3.1.18: + dependencies: + glob: 4.5.3 + glob2base: 0.0.12 + minimatch: 2.0.10 + ordered-read-streams: 0.1.0 + through2: 0.6.5 + unique-stream: 1.0.0 + resolution: 9170a5f12b790306fdfe598f313f8f7954fd143b + /glob-watcher/0.0.6: + dependencies: + gaze: 0.5.2 + resolution: b95b4a8df74b39c83298b0c05c978b4d9a3b710b + /glob/3.1.21: + dependencies: + graceful-fs: 1.2.3 + inherits: 1.0.2 + minimatch: 0.2.14 + resolution: d29e0a055dea5138f4d07ed40e8982e83c2066cd + /glob/4.5.3: + dependencies: + inflight: 1.0.6 + inherits: 2.0.3 + minimatch: 2.0.10 + once: 1.4.0 + resolution: c6cb73d3226c1efef04de3c56d012f03377ee15f + /glob/7.1.2: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.3 + minimatch: 3.0.4 + once: 1.4.0 + path-is-absolute: 1.0.1 + resolution: c19c9df9a028702d678612384a6552404c636d15 + /glob2base/0.0.12: + dependencies: + find-index: 0.1.1 + resolution: 9d419b3e28f12e83a362164a277055922c9c0d56 + /global-modules/0.2.3: + dependencies: + global-prefix: 0.1.5 + is-windows: 0.2.0 + resolution: ea5a3bed42c6d6ce995a4f8a1269b5dae223828d + /global-prefix/0.1.5: + dependencies: + homedir-polyfill: 1.0.1 + ini: 1.3.4 + is-windows: 0.2.0 + which: 1.2.14 + resolution: 8d3bc6b8da3ca8112a160d8d496ff0462bfef78f + /globals/9.17.0: 0c0ca696d9b9bb694d2e5470bd37777caad50286 + /globby/5.0.0: + dependencies: + array-union: 1.0.2 + arrify: 1.0.1 + glob: 7.1.2 + object-assign: 4.1.1 + pify: 2.3.0 + pinkie-promise: 2.0.1 + resolution: ebd84667ca0dbb330b99bcfc68eac2bc54370e0d + /globby/6.1.0: + dependencies: + array-union: 1.0.2 + glob: 7.1.2 + object-assign: 4.1.1 + pify: 2.3.0 + pinkie-promise: 2.0.1 + resolution: f5a6d70e8395e21c858fb0489d64df02424d506c + /globule/0.1.0: + dependencies: + glob: 3.1.21 + lodash: 1.0.2 + minimatch: 0.2.14 + resolution: d9c8edde1da79d125a151b79533b978676346ae5 + /globule/1.1.0: + dependencies: + glob: 7.1.2 + lodash: 4.16.6 + minimatch: 3.0.4 + resolution: c49352e4dc183d85893ee825385eb994bb6df45f + /glogg/1.0.0: + dependencies: + sparkles: 1.0.0 + resolution: 7fe0f199f57ac906cf512feead8f90ee4a284fc5 + /got/5.7.1: + dependencies: + create-error-class: 3.0.2 + duplexer2: 0.1.4 + is-redirect: 1.0.0 + is-retry-allowed: 1.1.0 + is-stream: 1.1.0 + lowercase-keys: 1.0.0 + node-status-codes: 1.0.0 + object-assign: 4.1.1 + parse-json: 2.2.0 + pinkie-promise: 2.0.1 + read-all-stream: 3.1.0 + readable-stream: 2.2.10 + timed-out: 3.1.3 + unzip-response: 1.0.2 + url-parse-lax: 1.0.0 + resolution: 5f81635a61e4a6589f180569ea4e381680a51f35 + /got/6.7.1: + dependencies: + create-error-class: 3.0.2 + duplexer3: 0.1.4 + get-stream: 3.0.0 + is-redirect: 1.0.0 + is-retry-allowed: 1.1.0 + is-stream: 1.1.0 + lowercase-keys: 1.0.0 + safe-buffer: 5.1.0 + timed-out: 4.0.1 + unzip-response: 2.0.1 + url-parse-lax: 1.0.0 + resolution: 240cd05785a9a18e561dc1b44b41c763ef1e8db0 + /graceful-fs/1.2.3: 15a4806a57547cb2d2dbf27f42e89a8c3451b364 + /graceful-fs/3.0.11: + dependencies: + natives: 1.1.0 + resolution: 7613c778a1afea62f25c630a086d7f3acbbdd818 + /graceful-fs/4.1.11: 0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658 + /graceful-readlink/1.0.1: 4cafad76bc62f02fa039b2f94e9a3dd3a391a725 + /gulp-bro/1.0.2: + dependencies: + browserify: 14.4.0 + browserify-incremental: 3.1.1 + concat-stream: 1.6.0 + gulp-util: 3.0.8 + through2: 2.0.3 + resolution: e56e060f3b9fde1809902ba7b2791df0d9c42b70 + /gulp-livereload/3.8.1: + dependencies: + chalk: 0.5.1 + debug: 2.6.8 + event-stream: 3.3.4 + gulp-util: 3.0.8 + lodash.assign: 3.2.0 + mini-lr: 0.1.9 + resolution: 00f744b2d749d3e9e3746589c8a44acac779b50f + /gulp-postcss/6.4.0: + dependencies: + gulp-util: 3.0.8 + postcss: 5.2.17 + postcss-load-config: 1.2.0 + vinyl-sourcemaps-apply: 0.2.1 + resolution: 78a32e3c87aa6cdcec5ae1c905e196d478e8c5d5 + /gulp-sass/3.1.0: + dependencies: + gulp-util: 3.0.8 + lodash.clonedeep: 4.5.0 + node-sass: 4.5.3 + through2: 2.0.3 + vinyl-sourcemaps-apply: 0.2.1 + resolution: 53dc4b68a1f5ddfe4424ab4c247655269a8b74b7 + /gulp-sourcemaps/2.6.0: + dependencies: + '@gulp-sourcemaps/identity-map': 1.0.1 + '@gulp-sourcemaps/map-sources': 1.0.0 + acorn: 4.0.13 + convert-source-map: 1.5.0 + css: 2.2.1 + debug-fabulous: 0.1.0 + detect-newline: 2.1.0 + graceful-fs: 4.1.11 + source-map: 0.5.6 + strip-bom-string: 1.0.0 + through2: 2.0.3 + vinyl: 1.2.0 + resolution: 7ccce899a8a3bfca1593a3348d0fbf41dd3f51e5 + /gulp-svgo/1.0.3: + dependencies: + svgo: 0.6.6 + resolution: f6ad219f281cdc9ac3e0e6c173d5c77bba8cd692 + /gulp-uglify/2.1.2: + dependencies: + gulplog: 1.0.0 + has-gulplog: 0.1.0 + lodash: 4.17.4 + make-error-cause: 1.2.2 + through2: 2.0.3 + uglify-js: 2.8.27 + uglify-save-license: 0.4.1 + vinyl-sourcemaps-apply: 0.2.1 + resolution: 6db85b1d0ee63d18058592b658649d65c2ec4541 + /gulp-util/3.0.8: + dependencies: + array-differ: 1.0.0 + array-uniq: 1.0.3 + beeper: 1.1.1 + chalk: 1.1.3 + dateformat: 2.0.0 + fancy-log: 1.3.0 + gulplog: 1.0.0 + has-gulplog: 0.1.0 + lodash._reescape: 3.0.0 + lodash._reevaluate: 3.0.0 + lodash._reinterpolate: 3.0.0 + lodash.template: 3.6.2 + minimist: 1.2.0 + multipipe: 0.1.2 + object-assign: 3.0.0 + replace-ext: 0.0.1 + through2: 2.0.3 + vinyl: 0.5.3 + resolution: 0054e1e744502e27c04c187c3ecc505dd54bbb4f + /gulp/3.9.1: + dependencies: + archy: 1.0.0 + chalk: 1.1.3 + deprecated: 0.0.1 + gulp-util: 3.0.8 + interpret: 1.0.3 + liftoff: 2.3.0 + minimist: 1.2.0 + orchestrator: 0.3.8 + pretty-hrtime: 1.0.3 + semver: 4.3.6 + tildify: 1.2.0 + v8flags: 2.1.1 + vinyl-fs: 0.3.14 + resolution: 571ce45928dd40af6514fc4011866016c13845b4 + /gulplog/1.0.0: + dependencies: + glogg: 1.0.0 + resolution: e28c4d45d05ecbbed818363ce8f9c5926229ffe5 + /har-schema/1.0.5: d263135f43307c02c602afc8fe95970c0151369e + /har-validator/4.2.1: + dependencies: + ajv: 4.11.8 + har-schema: 1.0.5 + resolution: 33481d0f1bbff600dd203d75812a6a5fba002e2a + /has-ansi/0.1.0: + dependencies: + ansi-regex: 0.2.1 + resolution: 84f265aae8c0e6a88a12d7022894b7568894c62e + /has-ansi/2.0.0: + dependencies: + ansi-regex: 2.1.1 + resolution: 34f5049ce1ecdf2b0649af3ef24e45ed35416d91 + /has-color/0.1.7: 67144a5260c34fc3cca677d041daf52fe7b78b2f + /has-flag/1.0.0: 9d9e793165ce017a00f00418c43f942a7b1d11fa + /has-flag/2.0.0: e8207af1cc7b30d446cc70b734b5e8be18f88d51 + /has-gulplog/0.1.0: + dependencies: + sparkles: 1.0.0 + resolution: 6414c82913697da51590397dafb12f22967811ce + /has-unicode/2.0.1: e0e6fe6a28cf51138855e086d1691e771de2a8b9 + /has-yarn/1.0.0: 89e25db604b725c8f5976fff0addc921b828a5a7 + /has/1.0.1: + dependencies: + function-bind: 1.1.0 + resolution: 8461733f538b0837c9361e39a9ab9e9704dc2f28 + /hash-base/2.0.2: + dependencies: + inherits: 2.0.3 + resolution: 66ea1d856db4e8a5470cadf6fce23ae5244ef2e1 + /hash.js/1.0.3: + dependencies: + inherits: 2.0.3 + resolution: 1332ff00156c0a0ffdd8236013d07b77a0451573 + /hawk/3.1.3: + dependencies: + boom: 2.10.1 + cryptiles: 2.0.5 + hoek: 2.16.3 + sntp: 1.0.9 + resolution: 078444bd7c1640b0fe540d2c9b73d59678e8e1c4 + /hmac-drbg/1.0.1: + dependencies: + hash.js: 1.0.3 + minimalistic-assert: 1.0.0 + minimalistic-crypto-utils: 1.0.1 + resolution: d2745701025a6c775a6c545793ed502fc0c649a1 + /hoek/2.16.3: 20bb7403d3cea398e91dc4710a8ff1b8274a25ed + /home-or-tmp/2.0.0: + dependencies: + os-homedir: 1.0.2 + os-tmpdir: 1.0.2 + resolution: e36c3f2d2cae7d746a857e38d18d5f32a7882db8 + /homedir-polyfill/1.0.1: + dependencies: + parse-passwd: 1.0.0 + resolution: 4c2bbc8a758998feebf5ed68580f76d46768b4bc + /hosted-git-info/2.4.2: 0076b9f46a270506ddbaaea56496897460612a67 + /html-comment-regex/1.1.1: 668b93776eaae55ebde8f3ad464b307a4963625e + /htmlescape/1.1.1: 3a03edc2214bca3b66424a3e7959349509cb0351 + /http-errors/1.3.1: + dependencies: + inherits: 2.0.3 + statuses: 1.3.1 + resolution: 197e22cdebd4198585e8694ef6786197b91ed942 + /http-signature/1.1.1: + dependencies: + assert-plus: 0.2.0 + jsprim: 1.4.0 + sshpk: 1.13.0 + resolution: df72e267066cd0ac67fb76adf8e134a8fbcf91bf + /https-browserify/1.0.0: ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73 + /husky/0.13.4: + dependencies: + chalk: 1.1.3 + find-parent-dir: 0.3.0 + is-ci: 1.0.10 + normalize-path: 1.0.0 + resolution: 48785c5028de3452a51c48c12c4f94b2124a1407 + /iconv-lite/0.4.13: 1f88aba4ab0b1508e8312acc39345f36e992e2f2 + /ieee754/1.1.8: be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4 + /ignore-by-default/1.0.1: 48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09 + /ignore/3.3.3: 432352e57accd87ab3110e82d3fea0e47812156d + /immediate/3.0.6: 9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b + /imurmurhash/0.1.4: 9218b9b2b928a238b13dc4fb6b6d576f231453ea + /in-publish/2.0.0: e20ff5e3a2afc2690320b6dc552682a9c7fadf51 + /indent-string/2.1.0: + dependencies: + repeating: 2.0.1 + resolution: 8e2d48348742121b4a8218b7a137e9a52049dc80 + /indent-string/3.1.0: 08ff4334603388399b329e6b9538dc7a3cf5de7d + /indexes-of/1.0.1: f30f716c8e2bd346c7b67d3df3915566a7c05607 + /indexof/0.0.1: 82dc336d232b9062179d05ab3293a66059fd435d + /inflight/1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + resolution: 49bd6331d7d02d0c09bc910a1075ba8165b56df9 + /inherits/1.0.2: ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b + /inherits/2.0.1: b17d08d326b4423e568eff719f91b0b1cbdf69f1 + /inherits/2.0.3: 633c2c83e3da42a502f52466022480f4208261de + /ini/1.3.4: 0537cb79daf59b59a1a517dff706c86ec039162e + /inline-process-browser/1.0.0: + dependencies: + falafel: 1.2.0 + through2: 0.6.5 + resolution: 46a61b153dd3c9b1624b1a00626edb4f7f414f22 + /inline-source-map/0.6.2: + dependencies: + source-map: 0.5.6 + resolution: f9393471c18a79d1724f863fa38b586370ade2a5 + /inquirer/0.12.0: + dependencies: + ansi-escapes: 1.4.0 + ansi-regex: 2.1.1 + chalk: 1.1.3 + cli-cursor: 1.0.2 + cli-width: 2.1.0 + figures: 1.7.0 + lodash: 4.17.4 + readline2: 1.0.1 + run-async: 0.1.0 + rx-lite: 3.1.2 + string-width: 1.0.2 + strip-ansi: 3.0.1 + through: 2.3.8 + resolution: 1ef2bfd63504df0bc75785fff8c2c41df12f077e + /insert-module-globals/7.0.1: + dependencies: + JSONStream: 1.3.1 + combine-source-map: 0.7.2 + concat-stream: 1.5.2 + is-buffer: 1.1.5 + lexical-scope: 1.2.0 + process: 0.11.10 + through2: 2.0.3 + xtend: 4.0.1 + resolution: c03bf4e01cb086d5b5e5ace8ad0afe7889d638c3 + /interpret/1.0.3: cbc35c62eeee73f19ab7b10a801511401afc0f90 + /invariant/2.2.2: + dependencies: + loose-envify: 1.3.1 + resolution: 9e1f56ac0acdb6bf303306f338be3b204ae60360 + /invert-kv/1.0.0: 104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6 + /irregular-plurals/1.2.0: 38f299834ba8c00c30be9c554e137269752ff3ac + /is-absolute-url/2.1.0: 50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6 + /is-absolute/0.2.6: + dependencies: + is-relative: 0.2.1 + is-windows: 0.2.0 + resolution: 20de69f3db942ef2d87b9c2da36f172235b1b5eb + /is-arrayish/0.2.1: 77c99840527aa8ecb1a8ba697b80645a7a926a9d + /is-binary-path/1.0.1: + dependencies: + binary-extensions: 1.8.0 + resolution: 75f16642b480f187a711c814161fd3a4a7655898 + /is-buffer/1.1.5: 1f3b26ef613b214b88cbca23cc6c01d87961eecc + /is-builtin-module/1.0.0: + dependencies: + builtin-modules: 1.1.1 + resolution: 540572d34f7ac3119f8f76c30cbc1b1e037affbe + /is-ci/1.0.10: + dependencies: + ci-info: 1.0.0 + resolution: f739336b2632365061a9d48270cd56ae3369318e + /is-directory/0.3.1: 61339b6f2475fc772fd9c9d83f5c8575dc154ae1 + /is-dotfile/1.0.3: a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1 + /is-equal-shallow/0.1.3: + dependencies: + is-primitive: 2.0.0 + resolution: 2238098fc221de0bcfa5d9eac4c45d638aa1c534 + /is-error/2.2.1: 684a96d84076577c98f4cdb40c6d26a5123bf19c + /is-extendable/0.1.1: 62b110e289a471418e3ec36a617d472e301dfc89 + /is-extglob/1.0.0: ac468177c4943405a092fc8f29760c6ffc6206c0 + /is-finite/1.0.2: + dependencies: + number-is-nan: 1.0.1 + resolution: cc6677695602be550ef11e8b4aa6305342b6d0aa + /is-fullwidth-code-point/1.0.0: + dependencies: + number-is-nan: 1.0.1 + resolution: ef9e31386f031a7f0d643af82fde50c457ef00cb + /is-fullwidth-code-point/2.0.0: a3b30a5c4f199183167aaab93beefae3ddfb654f + /is-generator-fn/1.0.0: 969d49e1bb3329f6bb7f09089be26578b2ddd46a + /is-get-set-prop/1.0.0: + dependencies: + get-set-props: 0.1.0 + lowercase-keys: 1.0.0 + resolution: 2731877e4d78a6a69edcce6bb9d68b0779e76312 + /is-glob/2.0.1: + dependencies: + is-extglob: 1.0.0 + resolution: d096f926a3ded5600f3fdfd91198cb0888c2d863 + /is-js-type/2.0.0: + dependencies: + js-types: 1.0.0 + resolution: 73617006d659b4eb4729bba747d28782df0f7e22 + /is-my-json-valid/2.16.0: + dependencies: + generate-function: 2.0.0 + generate-object-property: 1.2.0 + jsonpointer: 4.0.1 + xtend: 4.0.1 + resolution: f079dd9bfdae65ee2038aae8acbc86ab109e3693 + /is-npm/1.0.0: f2fb63a65e4905b406c86072765a1a4dc793b9f4 + /is-number/2.1.0: + dependencies: + kind-of: 3.2.2 + resolution: 01fcbbb393463a548f2f466cce16dece49db908f + /is-obj-prop/1.0.0: + dependencies: + lowercase-keys: 1.0.0 + obj-props: 1.1.0 + resolution: b34de79c450b8d7c73ab2cdf67dc875adb85f80e + /is-obj/1.0.1: 3e4729ac1f5fde025cd7d83a896dab9f4f67db0f + /is-observable/0.2.0: + dependencies: + symbol-observable: 0.2.4 + resolution: b361311d83c6e5d726cabf5e250b0237106f5ae2 + /is-path-cwd/1.0.0: d225ec23132e89edd38fda767472e62e65f1106d + /is-path-in-cwd/1.0.0: + dependencies: + is-path-inside: 1.0.0 + resolution: 6477582b8214d602346094567003be8a9eac04dc + /is-path-inside/1.0.0: + dependencies: + path-is-inside: 1.0.2 + resolution: fc06e5a1683fbda13de667aff717bbc10a48f37f + /is-plain-obj/1.1.0: 71a50c8429dfca773c92a390a4a03b39fcd51d3e + /is-posix-bracket/0.1.1: 3334dc79774368e92f016e6fbc0a88f5cd6e6bc4 + /is-primitive/2.0.0: 207bab91638499c07b2adf240a41a87210034575 + /is-promise/2.1.0: 79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa + /is-property/1.0.2: 57fe1c4e48474edd65b09911f26b1cd4095dda84 + /is-proto-prop/1.0.0: + dependencies: + lowercase-keys: 1.0.0 + proto-props: 0.2.1 + resolution: b3951f95c089924fb5d4fcda6542ab3e83e2b220 + /is-redirect/1.0.0: 1d03dded53bd8db0f30c26e4f95d36fc7c87dc24 + /is-relative/0.2.1: + dependencies: + is-unc-path: 0.1.2 + resolution: d27f4c7d516d175fb610db84bbeef23c3bc97aa5 + /is-resolvable/1.0.0: + dependencies: + tryit: 1.0.3 + resolution: 8df57c61ea2e3c501408d100fb013cf8d6e0cc62 + /is-retry-allowed/1.1.0: 11a060568b67339444033d0125a61a20d564fb34 + /is-stream/1.1.0: 12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44 + /is-svg/2.1.0: + dependencies: + html-comment-regex: 1.1.1 + resolution: cf61090da0d9efbcab8722deba6f032208dbb0e9 + /is-typedarray/1.0.0: e479c80858df0c1b11ddda6940f96011fcda4a9a + /is-unc-path/0.1.2: + dependencies: + unc-path-regex: 0.1.2 + resolution: 6ab053a72573c10250ff416a3814c35178af39b9 + /is-url/1.2.2: 498905a593bf47cc2d9e7f738372bbf7696c7f26 + /is-utf8/0.2.1: 4b0da1442104d1b336340e80797e865cf39f7d72 + /is-windows/0.2.0: de1aa6d63ea29dd248737b69f1ff8b8002d2108c + /isarray/0.0.1: 8a18acfca9a8f4177e09abfc6038939b05d1eedf + /isarray/1.0.0: bb935d48582cba168c06834957a54a3e07124f11 + /isexe/2.0.0: e8fbf374dc556ff8947a10dcb0572d633f2cfa10 + /isobject/2.1.0: + dependencies: + isarray: 1.0.0 + resolution: f065561096a3f1da2ef46272f815c840d87e0c89 + /isstream/0.1.2: 47e63f7af55afa6f92e1500e690eb8b8529c099a + /jest-diff/18.1.0: + dependencies: + chalk: 1.1.3 + diff: 3.2.0 + jest-matcher-utils: 18.1.0 + pretty-format: 18.1.0 + resolution: 4ff79e74dd988c139195b365dc65d87f606f4803 + /jest-file-exists/17.0.0: 7f63eb73a1c43a13f461be261768b45af2cdd169 + /jest-matcher-utils/18.1.0: + dependencies: + chalk: 1.1.3 + pretty-format: 18.1.0 + resolution: 1ac4651955ee2a60cef1e7fcc98cdfd773c0f932 + /jest-mock/18.0.0: 5c248846ea33fa558b526f5312ab4a6765e489b3 + /jest-snapshot/18.1.0: + dependencies: + jest-diff: 18.1.0 + jest-file-exists: 17.0.0 + jest-matcher-utils: 18.1.0 + jest-util: 18.1.0 + natural-compare: 1.4.0 + pretty-format: 18.1.0 + resolution: 55b96d2ee639c9bce76f87f2a3fd40b71c7a5916 + /jest-util/18.1.0: + dependencies: + chalk: 1.1.3 + diff: 3.2.0 + graceful-fs: 4.1.11 + jest-file-exists: 17.0.0 + jest-mock: 18.0.0 + mkdirp: 0.5.1 + resolution: 3a99c32114ab17f84be094382527006e6d4bfc6a + /jodid25519/1.0.2: + dependencies: + jsbn: 0.1.1 + resolution: 06d4912255093419477d425633606e0e90782967 + /js-base64/2.1.9: f0e80ae039a4bd654b5f281fc93f04a914a7fcce + /js-tokens/3.0.1: 08e9f132484a2c45a30907e9dc4d5567b7f114d7 + /js-types/1.0.0: d242e6494ed572ad3c92809fc8bed7f7687cbf03 + /js-yaml/3.6.1: + dependencies: + argparse: 1.0.9 + esprima: 2.7.3 + resolution: 6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30 + /js-yaml/3.7.0: + dependencies: + argparse: 1.0.9 + esprima: 2.7.3 + resolution: 5c967ddd837a9bfdca5f2de84253abe8a1c03b80 + /js-yaml/3.8.4: + dependencies: + argparse: 1.0.9 + esprima: 3.1.3 + resolution: 520b4564f86573ba96662af85a8cafa7b4b5a6f6 + /jsbn/0.1.1: a5e654c2e5a2deb5f201d96cefbca80c0ef2f513 + /jsesc/0.5.0: e7dee66e35d6fc16f710fe91d5cf69f70f08911d + /jsesc/1.3.0: 46c3fec8c1892b12b0833db9bc7622176dbab34b + /json-schema/0.2.3: b480c892e59a2f05954ce727bd3f2a4e882f9e13 + /json-stable-stringify/0.0.1: + dependencies: + jsonify: 0.0.0 + resolution: 611c23e814db375527df851193db59dd2af27f45 + /json-stable-stringify/1.0.1: + dependencies: + jsonify: 0.0.0 + resolution: 9a759d39c5f2ff503fd5300646ed445f88c4f9af + /json-stringify-safe/5.0.1: 1296a2d58fd45f19a0f6ce01d65701e2c735b6eb + /json5/0.5.1: 1eade7acc012034ad84e2396767ead9fa5495821 + /jsonify/0.0.0: 2c74b6ee41d93ca51b7b5aaee8f503631d252a73 + /jsonparse/0.0.5: 330542ad3f0a654665b778f3eb2d9a9fa507ac64 + /jsonparse/1.3.1: 3f4dae4a91fac315f71062f8521cc239f1366280 + /jsonpointer/4.0.1: 4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9 + /jsprim/1.4.0: + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.0.2 + json-schema: 0.2.3 + verror: 1.3.6 + resolution: a3b87e40298d8c380552d8cc7628a0bb95a22918 + /jstransform/3.0.0: + dependencies: + base62: 0.1.1 + esprima-fb: 3001.1.0-dev-harmony-fb + source-map: 0.1.31 + resolution: a2591ab6cee8d97bf3be830dbfa2313b87cd640b + /kind-of/3.2.2: + dependencies: + is-buffer: 1.1.5 + resolution: 31ea21a734bab9bbb0f32466d893aea51e4a3c64 + /labeled-stream-splicer/2.0.0: + dependencies: + inherits: 2.0.3 + isarray: 0.0.1 + stream-splicer: 2.0.0 + resolution: a52e1d138024c00b86b1c0c91f677918b8ae0a59 + /last-line-stream/1.0.0: + dependencies: + through2: 2.0.3 + resolution: d1b64d69f86ff24af2d04883a2ceee14520a5600 + /latest-version/2.0.0: + dependencies: + package-json: 2.4.0 + resolution: 56f8d6139620847b8017f8f1f4d78e211324168b + /latest-version/3.1.0: + dependencies: + package-json: 4.0.1 + resolution: a205383fea322b33b5ae3b18abee0dc2f356ee15 + /lazy-cache/1.0.4: a1d78fc3a50474cb80845d3b3b6e1da49a446e8e + /lazy-req/1.1.0: bdaebead30f8d824039ce0ce149d4daa07ba1fac + /lazy-req/2.0.0: c9450a363ecdda2e6f0c70132ad4f37f8f06f2b4 + /lcid/1.0.0: + dependencies: + invert-kv: 1.0.0 + resolution: 308accafa0bc483a3867b4b6f2b9506251d1b835 + /levn/0.3.0: + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + resolution: 3b09924edf9f083c0490fdd4c0bc4421e04764ee + /lexical-scope/1.2.0: + dependencies: + astw: 2.2.0 + resolution: fcea5edc704a4b3a8796cdca419c3a0afaf22df4 + /lie/3.0.2: + dependencies: + es3ify: 0.1.4 + immediate: 3.0.6 + inline-process-browser: 1.0.0 + unreachable-branch-transform: 0.3.0 + resolution: ffda21d7bba26f377cad865d3649b2fc8ce39fea + /liftoff/2.3.0: + dependencies: + extend: 3.0.1 + findup-sync: 0.4.3 + fined: 1.0.2 + flagged-respawn: 0.3.2 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.mapvalues: 4.6.0 + rechoir: 0.6.2 + resolve: 1.3.3 + resolution: a98f2ff67183d8ba7cfaca10548bd7ff0550b385 + /lint-staged/3.6.0: + dependencies: + app-root-path: 2.0.1 + cosmiconfig: 1.1.0 + execa: 0.6.3 + listr: 0.12.0 + lodash.chunk: 4.2.0 + minimatch: 3.0.4 + npm-which: 3.0.1 + p-map: 1.1.1 + staged-git-files: 0.0.4 + resolution: cda8f0bef16e7928cc14b735186ae12cd662599c + /listr-silent-renderer/1.1.1: 924b5a3757153770bf1a8e3fbf74b8bbf3f9242e + /listr-update-renderer/0.2.0: + dependencies: + chalk: 1.1.3 + cli-truncate: 0.2.1 + elegant-spinner: 1.0.1 + figures: 1.7.0 + indent-string: 3.1.0 + log-symbols: 1.0.2 + log-update: 1.0.2 + strip-ansi: 3.0.1 + resolution: ca80e1779b4e70266807e8eed1ad6abe398550f9 + /listr-verbose-renderer/0.4.0: + dependencies: + chalk: 1.1.3 + cli-cursor: 1.0.2 + date-fns: 1.28.5 + figures: 1.7.0 + resolution: 44dc01bb0c34a03c572154d4d08cde9b1dc5620f + /listr/0.12.0: + dependencies: + chalk: 1.1.3 + cli-truncate: 0.2.1 + figures: 1.7.0 + indent-string: 2.1.0 + is-promise: 2.1.0 + is-stream: 1.1.0 + listr-silent-renderer: 1.1.1 + listr-update-renderer: 0.2.0 + listr-verbose-renderer: 0.4.0 + log-symbols: 1.0.2 + log-update: 1.0.2 + ora: 0.2.3 + p-map: 1.1.1 + rxjs: 5.4.0 + stream-to-observable: 0.1.0 + strip-ansi: 3.0.1 + resolution: 6bce2c0f5603fa49580ea17cd6a00cc0e5fa451a + /livereload-js/2.2.2: 6c87257e648ab475bc24ea257457edcc1f8d0bc2 + /load-json-file/1.1.0: + dependencies: + graceful-fs: 4.1.11 + parse-json: 2.2.0 + pify: 2.3.0 + pinkie-promise: 2.0.1 + strip-bom: 2.0.0 + resolution: 956905708d58b4bab4c2261b04f59f31c99374c0 + /load-json-file/2.0.0: + dependencies: + graceful-fs: 4.1.11 + parse-json: 2.2.0 + pify: 2.3.0 + strip-bom: 3.0.0 + resolution: 7947e42149af80d696cbf797bcaabcfe1fe29ca8 + /localforage/1.5.0: + dependencies: + lie: 3.0.2 + resolution: 6b994e19b56611fa85df3992df397ac4ab66e815 + /locate-path/2.0.0: + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + resolution: 2b568b265eec944c6d9c0de9c3dbbbca0354cd8e + /lodash._baseassign/3.2.0: + dependencies: + lodash._basecopy: 3.0.1 + lodash.keys: 3.1.2 + resolution: 8c38a099500f215ad09e59f1722fd0c52bfe0a4e + /lodash._basecopy/3.0.1: 8da0e6a876cf344c0ad8a54882111dd3c5c7ca36 + /lodash._basetostring/3.0.1: d1861d877f824a52f669832dcaf3ee15566a07d5 + /lodash._basevalues/3.0.0: 5b775762802bde3d3297503e26300820fdf661b7 + /lodash._bindcallback/3.0.1: e531c27644cf8b57a99e17ed95b35c748789392e + /lodash._createassigner/3.1.1: + dependencies: + lodash._bindcallback: 3.0.1 + lodash._isiterateecall: 3.0.9 + lodash.restparam: 3.6.1 + resolution: 838a5bae2fdaca63ac22dee8e19fa4e6d6970b11 + /lodash._getnative/3.9.1: 570bc7dede46d61cdcde687d65d3eecbaa3aaff5 + /lodash._isiterateecall/3.0.9: 5203ad7ba425fae842460e696db9cf3e6aac057c + /lodash._reescape/3.0.0: 2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a + /lodash._reevaluate/3.0.0: 58bc74c40664953ae0b124d806996daca431e2ed + /lodash._reinterpolate/3.0.0: 0ccf2d89166af03b3663c796538b75ac6e114d9d + /lodash._root/3.0.1: fba1c4524c19ee9a5f8136b4609f017cf4ded692 + /lodash.assign/3.2.0: + dependencies: + lodash._baseassign: 3.2.0 + lodash._createassigner: 3.1.1 + lodash.keys: 3.1.2 + resolution: 3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa + /lodash.assign/4.2.0: 0d99f3ccd7a6d261d19bdaeb9245005d285808e7 + /lodash.assignwith/4.2.0: 127a97f02adc41751a954d24b0de17e100e038eb + /lodash.camelcase/4.3.0: b28aa6288a2b9fc651035c7711f65ab6190331a6 + /lodash.chunk/4.2.0: 66e5ce1f76ed27b4303d8c6512e8d1216e8106bc + /lodash.clonedeep/4.5.0: e23f3f9c4f8fbdde872529c1071857a086e5ccef + /lodash.cond/4.5.2: f471a1da486be60f6ab955d17115523dd1d255d5 + /lodash.debounce/4.0.8: 82d79bff30a67c4005ffd5e2515300ad9ca4d7af + /lodash.difference/4.5.0: 9ccb4e505d486b91651345772885a2df27fd017c + /lodash.escape/3.2.0: + dependencies: + lodash._root: 3.0.1 + resolution: 995ee0dc18c1b48cc92effae71a10aab5b487698 + /lodash.flatten/4.4.0: f31c22225a9632d2bbf8e4addbef240aa765a61f + /lodash.isarguments/3.1.0: 2f573d85c6a24289ff00663b491c1d338ff3458a + /lodash.isarray/3.0.4: 79e4eb88c36a8122af86f844aa9bcd851b5fbb55 + /lodash.isempty/4.4.0: 6f86cbedd8be4ec987be9aaf33c9684db1b31e7e + /lodash.isequal/4.5.0: 415c4478f2bcc30120c22ce10ed3226f7d3e18e0 + /lodash.isplainobject/4.0.6: 7c526a52d89b45c45cc690b88163be0497f550cb + /lodash.isstring/4.0.1: d527dfb5456eca7cc9bb95d5daeaf88ba54a5451 + /lodash.kebabcase/4.1.1: 8489b1cb0d29ff88195cceca448ff6d6cc295c36 + /lodash.keys/3.1.2: + dependencies: + lodash._getnative: 3.9.1 + lodash.isarguments: 3.1.0 + lodash.isarray: 3.0.4 + resolution: 4dbc0472b156be50a0b286855d1bd0b0c656098a + /lodash.mapvalues/4.6.0: 1bafa5005de9dd6f4f26668c30ca37230cc9689c + /lodash.memoize/3.0.4: 2dcbd2c287cbc0a55cc42328bd0c736150d53e3f + /lodash.memoize/4.1.2: bcc6c49a42a2840ed997f323eada5ecd182e0bfe + /lodash.mergewith/4.6.0: 150cf0a16791f5903b8891eab154609274bdea55 + /lodash.pick/4.4.0: 52f05610fff9ded422611441ed1fc123a03001b3 + /lodash.restparam/3.6.1: 936a4e309ef330a7645ed4145986c85ae5b20805 + /lodash.snakecase/4.1.1: 39d714a35357147837aefd64b5dcbb16becd8f8d + /lodash.template/3.6.2: + dependencies: + lodash._basecopy: 3.0.1 + lodash._basetostring: 3.0.1 + lodash._basevalues: 3.0.0 + lodash._isiterateecall: 3.0.9 + lodash._reinterpolate: 3.0.0 + lodash.escape: 3.2.0 + lodash.keys: 3.1.2 + lodash.restparam: 3.6.1 + lodash.templatesettings: 3.1.1 + resolution: f8cdecc6169a255be9098ae8b0c53d378931d14f + /lodash.templatesettings/3.1.1: + dependencies: + lodash._reinterpolate: 3.0.0 + lodash.escape: 3.2.0 + resolution: fb307844753b66b9f1afa54e262c745307dba8e5 + /lodash.uniq/4.5.0: d0225373aeb652adc1bc82e4945339a842754773 + /lodash.upperfirst/4.3.1: 1365edf431480481ef0d1c68957a5ed99d49f7ce + /lodash/1.0.2: 8f57560c83b59fc270bd3d561b690043430e2551 + /lodash/4.16.6: d22c9ac660288f3843e16ba7d2b5d06cca27d777 + /lodash/4.17.4: 78203a4d1c328ae1d86dca6460e369b57f4055ae + /log-symbols/1.0.2: + dependencies: + chalk: 1.1.3 + resolution: 376ff7b58ea3086a0f09facc74617eca501e1a18 + /log-update/1.0.2: + dependencies: + ansi-escapes: 1.4.0 + cli-cursor: 1.0.2 + resolution: 19929f64c4093d2d2e7075a1dad8af59c296b8d1 + /longest/1.0.1: 30a0b2da38f73770e8294a0d22e6625ed77d0097 + /loose-envify/1.3.1: + dependencies: + js-tokens: 3.0.1 + resolution: d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848 + /loud-rejection/1.6.0: + dependencies: + currently-unhandled: 0.4.1 + signal-exit: 3.0.2 + resolution: 5b46f80147edee578870f086d04821cf998e551f + /lowercase-keys/1.0.0: 4e3366b39e7f5457e35f1324bdf6f88d0bfc7306 + /lru-cache/2.7.3: 6d4524e8b955f95d4f5b58851ce21dd72fb4e952 + /lru-cache/4.0.2: + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + resolution: 1d17679c069cda5d040991a09dbc2c0db377e55e + /macaddress/0.2.8: 5904dc537c39ec6dbefeae902327135fa8511f12 + /make-dir/1.0.0: + dependencies: + pify: 2.3.0 + resolution: 97a011751e91dd87cfadef58832ebb04936de978 + /make-error-cause/1.2.2: + dependencies: + make-error: 1.3.0 + resolution: df0388fcd0b37816dff0a5fb8108939777dcbc9d + /make-error/1.3.0: 52ad3a339ccf10ce62b4040b708fe707244b8b96 + /map-cache/0.2.2: c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf + /map-obj/1.0.1: d933ceb9205d82bdcf4886f6742bdc2b4dea146d + /map-stream/0.1.0: e56aa94c4c8055a16404a0674b78f215f7c8e194 + /matcher/0.1.2: + dependencies: + escape-string-regexp: 1.0.5 + resolution: ef20cbde64c24c50cc61af5b83ee0b1b8ff00101 + /math-expression-evaluator/1.2.17: de819fdbcd84dccd8fae59c6aeb79615b9d266ac + /max-timeout/1.0.0: b68f69a2f99e0b476fd4cb23e2059ca750715e1f + /md5-hex/1.3.0: + dependencies: + md5-o-matic: 0.1.1 + resolution: d2c4afe983c4370662179b8cad145219135046c4 + /md5-hex/2.0.0: + dependencies: + md5-o-matic: 0.1.1 + resolution: d0588e9f1c74954492ecd24ac0ac6ce997d92e33 + /md5-o-matic/0.1.1: 822bccd65e117c514fab176b25945d54100a03c3 + /media-typer/0.3.0: 8710d7af0aa626f8fffa1ce00168545263255748 + /meow/3.7.0: + dependencies: + camelcase-keys: 2.1.0 + decamelize: 1.2.0 + loud-rejection: 1.6.0 + map-obj: 1.0.1 + minimist: 1.2.0 + normalize-package-data: 2.3.8 + object-assign: 4.1.1 + read-pkg-up: 1.0.1 + redent: 1.0.0 + trim-newlines: 1.0.0 + resolution: 72cb668b425228290abbfa856892587308a801fb + /micromatch/2.3.11: + dependencies: + arr-diff: 2.0.0 + array-unique: 0.2.1 + braces: 1.8.5 + expand-brackets: 0.1.5 + extglob: 0.3.2 + filename-regex: 2.0.1 + is-extglob: 1.0.0 + is-glob: 2.0.1 + kind-of: 3.2.2 + normalize-path: 2.1.1 + object.omit: 2.0.1 + parse-glob: 3.0.4 + regex-cache: 0.4.3 + resolution: 86677c97d1720b363431d04d0d15293bd38c1565 + /miller-rabin/4.0.0: + dependencies: + bn.js: 4.11.6 + brorand: 1.1.0 + resolution: 4a62fb1d42933c05583982f4c716f6fb9e6c6d3d + /mime-db/1.27.0: 820f572296bbd20ec25ed55e5b5de869e5436eb1 + /mime-types/2.1.15: + dependencies: + mime-db: 1.27.0 + resolution: a4ebf5064094569237b8cf70046776d09fc92aed + /mimic-fn/1.1.0: e667783d92e89dbd342818b5230b9d62a672ad18 + /mini-lr/0.1.9: + dependencies: + body-parser: 1.14.2 + debug: 2.6.8 + faye-websocket: 0.7.3 + livereload-js: 2.2.2 + parseurl: 1.3.1 + qs: 2.2.5 + resolution: 02199d27347953d1fd1d6dbded4261f187b2d0f6 + /minimalistic-assert/1.0.0: 702be2dda6b37f4836bcb3f5db56641b64a1d3d3 + /minimalistic-crypto-utils/1.0.1: f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a + /minimatch/0.2.14: + dependencies: + lru-cache: 2.7.3 + sigmund: 1.0.1 + resolution: c74e780574f63c6f9a090e90efbe6ef53a6a756a + /minimatch/2.0.10: + dependencies: + brace-expansion: 1.1.7 + resolution: 8d087c39c6b38c001b97fca7ce6d0e1e80afbac7 + /minimatch/3.0.4: + dependencies: + brace-expansion: 1.1.7 + resolution: 5166e286457f03306064be5497e8dbb0c3d32083 + /minimist/0.0.8: 857fcabfc3397d2625b8228262e86aa7a011b05d + /minimist/1.2.0: a35008b20f41383eec1fb914f4cd5df79a264284 + /mkdirp/0.5.1: + dependencies: + minimist: 0.0.8 + resolution: 30057438eac6cf7f8c4767f38648d6697d75c903 + /module-deps/4.1.1: + dependencies: + JSONStream: 1.3.1 + browser-resolve: 1.11.2 + cached-path-relative: 1.0.1 + concat-stream: 1.5.2 + defined: 1.0.0 + detective: 4.5.0 + duplexer2: 0.1.4 + inherits: 2.0.3 + parents: 1.0.1 + readable-stream: 2.2.10 + resolve: 1.3.3 + stream-combiner2: 1.1.1 + subarg: 1.0.0 + through2: 2.0.3 + xtend: 4.0.1 + resolution: 23215833f1da13fd606ccb8087b44852dcb821fd + /ms/0.7.1: 9cd13c03adbff25b65effde7ce864ee952017098 + /ms/0.7.3: 708155a5e44e33f5fd0fc53e81d0d40a91be1fff + /ms/2.0.0: 5608aeadfc00be6c2901df5f9861788de0d597c8 + /multimatch/2.1.0: + dependencies: + array-differ: 1.0.0 + array-union: 1.0.2 + arrify: 1.0.1 + minimatch: 3.0.4 + resolution: 9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b + /multipipe/0.1.2: + dependencies: + duplexer2: 0.0.2 + resolution: 2a8f2ddf70eed564dff2d57f1e1a137d9f05078b + /mute-stream/0.0.5: 8fbfabb0a98a253d3184331f9e8deb7372fac6c0 + /nan/2.6.2: e4ff34e6c95fdfb5aecc08de6596f43605a7db45 + /natives/1.1.0: e9ff841418a6b2ec7a495e939984f78f163e6e31 + /natural-compare/1.4.0: 4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7 + /node-gyp/3.6.2: + dependencies: + fstream: 1.0.11 + glob: 7.1.2 + graceful-fs: 4.1.11 + minimatch: 3.0.4 + mkdirp: 0.5.1 + nopt: 3.0.6 + npmlog: 4.1.0 + osenv: 0.1.4 + request: 2.81.0 + rimraf: 2.6.1 + semver: 5.3.0 + tar: 2.2.1 + which: 1.2.14 + resolution: 9bfbe54562286284838e750eac05295853fa1c60 + /node-sass/4.5.3: + dependencies: + async-foreach: 0.1.3 + chalk: 1.1.3 + cross-spawn: 3.0.1 + gaze: 1.1.2 + get-stdin: 4.0.1 + glob: 7.1.2 + in-publish: 2.0.0 + lodash.assign: 4.2.0 + lodash.clonedeep: 4.5.0 + lodash.mergewith: 4.6.0 + meow: 3.7.0 + mkdirp: 0.5.1 + nan: 2.6.2 + node-gyp: 3.6.2 + npmlog: 4.1.0 + request: 2.81.0 + sass-graph: 2.2.4 + stdout-stream: 1.4.0 + resolution: d09c9d1179641239d1b97ffc6231fdcec53e1568 + /node-status-codes/1.0.0: 5ae5541d024645d32a58fcddc9ceecea7ae3ac2f + /nopt/3.0.6: + dependencies: + abbrev: 1.1.0 + resolution: c6465dbf08abcd4db359317f79ac68a646b28ff9 + /normalize-package-data/2.3.8: + dependencies: + hosted-git-info: 2.4.2 + is-builtin-module: 1.0.0 + semver: 5.3.0 + validate-npm-package-license: 3.0.1 + resolution: d819eda2a9dedbd1ffa563ea4071d936782295bb + /normalize-path/1.0.0: 32d0e472f91ff345701c15a8311018d3b0a90379 + /normalize-path/2.1.1: + dependencies: + remove-trailing-separator: 1.0.1 + resolution: 1ab28b556e198363a8c1a6f7e6fa20137fe6aed9 + /normalize-range/0.1.2: 2d10c06bdfd312ea9777695a4d28439456b75942 + /normalize-url/1.9.1: + dependencies: + object-assign: 4.1.1 + prepend-http: 1.0.4 + query-string: 4.3.4 + sort-keys: 1.1.2 + resolution: 2cc0d66b31ea23036458436e3620d85954c66c3c + /npm-path/2.0.3: + dependencies: + which: 1.2.14 + resolution: 15cff4e1c89a38da77f56f6055b24f975dfb2bbe + /npm-run-path/1.0.0: + dependencies: + path-key: 1.0.0 + resolution: f5c32bf595fe81ae927daec52e82f8b000ac3c8f + /npm-run-path/2.0.2: + dependencies: + path-key: 2.0.1 + resolution: 35a9232dfa35d7067b4cb2ddf2357b1871536c5f + /npm-which/3.0.1: + dependencies: + commander: 2.9.0 + npm-path: 2.0.3 + which: 1.2.14 + resolution: 9225f26ec3a285c209cae67c3b11a6b4ab7140aa + /npmlog/4.1.0: + dependencies: + are-we-there-yet: 1.1.4 + console-control-strings: 1.1.0 + gauge: 2.7.4 + set-blocking: 2.0.0 + resolution: dc59bee85f64f00ed424efb2af0783df25d1c0b5 + /num2fraction/1.2.2: 6f682b6a027a4e9ddfa4564cd2589d1d4e669ede + /number-is-nan/1.0.1: 097b602b53422a522c1afb8790318336941a011d + /oauth-sign/0.8.2: 46a6ab7f0aead8deae9ec0565780b7d4efeb9d43 + /obj-props/1.1.0: 626313faa442befd4a44e9a02c3cb6bde937b511 + /object-assign/3.0.0: 9bedd5ca0897949bca47e7ff408062d549f587f2 + /object-assign/4.1.0: 7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0 + /object-assign/4.1.1: 2109adc7965887cfc05cbbd442cac8bfbb360863 + /object-keys/1.0.11: c54601778ad560f1142ce0e01bcca8b56d13426d + /object.omit/2.0.1: + dependencies: + for-own: 0.1.5 + is-extendable: 0.1.1 + resolution: 1a9c744829f39dbb858c76ca3579ae2a54ebd1fa + /observable-to-promise/0.4.0: + dependencies: + is-observable: 0.2.0 + symbol-observable: 0.2.4 + resolution: 28afe71645308f2d41d71f47ad3fece1a377e52b + /on-finished/2.3.0: + dependencies: + ee-first: 1.1.1 + resolution: 20f1336481b083cd75337992a16971aa2d906947 + /once/1.3.3: + dependencies: + wrappy: 1.0.2 + resolution: b2e261557ce4c314ec8304f3fa82663e4297ca20 + /once/1.4.0: + dependencies: + wrappy: 1.0.2 + resolution: 583b1aa775961d4b113ac17d9c50baef9dd76bd1 + /onetime/1.1.0: a1f7838f8314c516f05ecefcbc4ccfe04b4ed789 + /onetime/2.0.1: + dependencies: + mimic-fn: 1.1.0 + resolution: 067428230fd67443b2794b22bba528b6867962d4 + /option-chain/0.1.1: + dependencies: + object-assign: 4.1.1 + resolution: e9b811e006f1c0f54802f28295bfc8970f8dcfbd + /optionator/0.8.2: + dependencies: + deep-is: 0.1.3 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + wordwrap: 1.0.0 + resolution: 364c5e409d3f4d6301d6c0b4c05bba50180aeb64 + /ora/0.2.3: + dependencies: + chalk: 1.1.3 + cli-cursor: 1.0.2 + cli-spinners: 0.1.2 + object-assign: 4.1.1 + resolution: 37527d220adcd53c39b73571d754156d5db657a4 + /orchestrator/0.3.8: + dependencies: + end-of-stream: 0.1.5 + sequencify: 0.0.7 + stream-consume: 0.1.0 + resolution: 14e7e9e2764f7315fbac184e506c7aa6df94ad7e + /ordered-read-streams/0.1.0: fd565a9af8eb4473ba69b6ed8a34352cb552f126 + /os-browserify/0.1.2: 49ca0293e0b19590a5f5de10c7f265a617d8fe54 + /os-homedir/1.0.2: ffbc4988336e0e833de0c168c7ef152121aa7fb3 + /os-locale/1.4.0: + dependencies: + lcid: 1.0.0 + resolution: 20f9f17ae29ed345e8bde583b13d2009803c14d9 + /os-tmpdir/1.0.2: bbe67406c79aa85c5cfec766fe5734555dfa1274 + /osenv/0.1.4: + dependencies: + os-homedir: 1.0.2 + os-tmpdir: 1.0.2 + resolution: 42fe6d5953df06c8064be6f176c3d05aaaa34644 + /outpipe/1.1.1: + dependencies: + shell-quote: 1.6.1 + resolution: 50cf8616365e87e031e29a5ec9339a3da4725fa2 + /p-finally/1.0.0: 3fbcfb15b899a44123b34b6dcc18b724336a2cae + /p-limit/1.1.0: b07ff2d9a5d88bec806035895a2bab66a27988bc + /p-locate/2.0.0: + dependencies: + p-limit: 1.1.0 + resolution: 20a0103b222a70c8fd39cc2e580680f3dde5ec43 + /p-map/1.1.1: 05f5e4ae97a068371bc2a5cc86bfbdbc19c4ae7a + /package-hash/1.2.0: + dependencies: + md5-hex: 1.3.0 + resolution: 003e56cd57b736a6ed6114cc2b81542672770e44 + /package-json/2.4.0: + dependencies: + got: 5.7.1 + registry-auth-token: 3.3.1 + registry-url: 3.1.0 + semver: 5.3.0 + resolution: 0d15bd67d1cbbddbb2ca222ff2edb86bcb31a8bb + /package-json/4.0.1: + dependencies: + got: 6.7.1 + registry-auth-token: 3.3.1 + registry-url: 3.1.0 + semver: 5.3.0 + resolution: 8869a0401253661c4c4ca3da6c2121ed555f5eed + /pako/0.2.9: f3f7522f4ef782348da8161bad9ecfd51bf83a75 + /parents/1.0.1: + dependencies: + path-platform: 0.11.15 + resolution: fedd4d2bf193a77745fe71e371d73c3307d9c751 + /parse-asn1/5.1.0: + dependencies: + asn1.js: 4.9.1 + browserify-aes: 1.0.6 + create-hash: 1.1.3 + evp_bytestokey: 1.0.0 + pbkdf2: 3.0.12 + resolution: 37c4f9b7ed3ab65c74817b5f2480937fbf97c712 + /parse-filepath/1.0.1: + dependencies: + is-absolute: 0.2.6 + map-cache: 0.2.2 + path-root: 0.1.1 + resolution: 159d6155d43904d16c10ef698911da1e91969b73 + /parse-glob/3.0.4: + dependencies: + glob-base: 0.3.0 + is-dotfile: 1.0.3 + is-extglob: 1.0.0 + is-glob: 2.0.1 + resolution: b2c376cfb11f35513badd173ef0bb6e3a388391c + /parse-json/2.2.0: + dependencies: + error-ex: 1.3.1 + resolution: f480f40434ef80741f8469099f8dea18f55a4dc9 + /parse-ms/0.1.2: dd3fa25ed6c2efc7bdde12ad9b46c163aa29224e + /parse-ms/1.0.1: 56346d4749d78f23430ca0c713850aef91aa361d + /parse-passwd/1.0.0: 6d5b934a456993b23d37f40a382d6f1666a8e5c6 + /parseurl/1.3.1: c8ab8c9223ba34888aa64a297b28853bec18da56 + /path-browserify/0.0.0: a0b870729aae214005b7d5032ec2cbbb0fb4451a + /path-exists/2.1.0: + dependencies: + pinkie-promise: 2.0.1 + resolution: 0feb6c64f0fc518d9a754dd5efb62c7022761f4b + /path-exists/3.0.0: ce0ebeaa5f78cb18925ea7d810d7b59b010fd515 + /path-is-absolute/1.0.1: 174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f + /path-is-inside/1.0.2: 365417dede44430d1c11af61027facf074bdfc53 + /path-key/1.0.0: 5d53d578019646c0d68800db4e146e6bdc2ac7af + /path-key/2.0.1: 411cadb574c5a140d3a4b1910d40d80cc9f40b40 + /path-parse/1.0.5: 3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1 + /path-platform/0.11.15: e864217f74c36850f0852b78dc7bf7d4a5721bf2 + /path-root-regex/0.1.2: bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d + /path-root/0.1.1: + dependencies: + path-root-regex: 0.1.2 + resolution: 9a4a6814cac1c0cd73360a95f32083c8ea4745b7 + /path-type/1.1.0: + dependencies: + graceful-fs: 4.1.11 + pify: 2.3.0 + pinkie-promise: 2.0.1 + resolution: 59c44f7ee491da704da415da5a4070ba4f8fe441 + /path-type/2.0.0: + dependencies: + pify: 2.3.0 + resolution: f012ccb8415b7096fc2daa1054c3d72389594c73 + /pause-stream/0.0.11: + dependencies: + through: 2.3.8 + resolution: fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445 + /pbkdf2/3.0.12: + dependencies: + create-hash: 1.1.3 + create-hmac: 1.1.6 + ripemd160: 2.0.1 + safe-buffer: 5.1.0 + sha.js: 2.4.8 + resolution: be36785c5067ea48d806ff923288c5f750b6b8a2 + /performance-now/0.2.0: 33ef30c5c77d4ea21c5a53869d91b56d8f2555e5 + /pify/2.3.0: ed141a6ac043a849ea588498e7dca8b15330e90c + /pinkie-promise/1.0.0: + dependencies: + pinkie: 1.0.0 + resolution: d1da67f5482563bb7cf57f286ae2822ecfbf3670 + /pinkie-promise/2.0.1: + dependencies: + pinkie: 2.0.4 + resolution: 2135d6dfa7a358c069ac9b178776288228450ffa + /pinkie/1.0.0: 5a47f28ba1015d0201bda7bf0f358e47bec8c7e4 + /pinkie/2.0.4: 72556b80cfa0d48a974e80e77248e80ed4f7f870 + /pkg-conf/2.0.0: + dependencies: + find-up: 2.1.0 + load-json-file: 2.0.0 + resolution: 071c87650403bccfb9c627f58751bfe47c067279 + /pkg-dir/1.0.0: + dependencies: + find-up: 1.1.2 + resolution: 7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4 + /pkg-up/1.0.0: + dependencies: + find-up: 1.1.2 + resolution: 3e08fb461525c4421624a33b9f7e6d0af5b05a26 + /plur/1.0.0: db85c6814f5e5e5a3b49efc28d604fec62975156 + /plur/2.1.2: + dependencies: + irregular-plurals: 1.2.0 + resolution: 7482452c1a0f508e3e344eaec312c91c29dc655a + /pluralize/1.2.1: d1a21483fd22bb41e58a12fa3421823140897c45 + /postcss-calc/5.3.1: + dependencies: + postcss: 5.2.17 + postcss-message-helpers: 2.0.0 + reduce-css-calc: 1.3.0 + resolution: 77bae7ca928ad85716e2fda42f261bf7c1d65b5e + /postcss-colormin/2.2.2: + dependencies: + colormin: 1.1.2 + postcss: 5.2.17 + postcss-value-parser: 3.3.0 + resolution: 6631417d5f0e909a3d7ec26b24c8a8d1e4f96e4b + /postcss-convert-values/2.6.1: + dependencies: + postcss: 5.2.17 + postcss-value-parser: 3.3.0 + resolution: bbd8593c5c1fd2e3d1c322bb925dcae8dae4d62d + /postcss-discard-comments/2.0.4: + dependencies: + postcss: 5.2.17 + resolution: befe89fafd5b3dace5ccce51b76b81514be00e3d + /postcss-discard-duplicates/2.1.0: + dependencies: + postcss: 5.2.17 + resolution: b9abf27b88ac188158a5eb12abcae20263b91932 + /postcss-discard-empty/2.1.0: + dependencies: + postcss: 5.2.17 + resolution: d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5 + /postcss-discard-overridden/0.1.1: + dependencies: + postcss: 5.2.17 + resolution: 8b1eaf554f686fb288cd874c55667b0aa3668d58 + /postcss-discard-unused/2.2.3: + dependencies: + postcss: 5.2.17 + uniqs: 2.0.0 + resolution: bce30b2cc591ffc634322b5fb3464b6d934f4433 + /postcss-filter-plugins/2.0.2: + dependencies: + postcss: 5.2.17 + uniqid: 4.1.1 + resolution: 6d85862534d735ac420e4a85806e1f5d4286d84c + /postcss-load-config/1.2.0: + dependencies: + cosmiconfig: 2.1.3 + object-assign: 4.1.1 + postcss-load-options: 1.2.0 + postcss-load-plugins: 2.3.0 + resolution: 539e9afc9ddc8620121ebf9d8c3673e0ce50d28a + /postcss-load-options/1.2.0: + dependencies: + cosmiconfig: 2.1.3 + object-assign: 4.1.1 + resolution: b098b1559ddac2df04bc0bb375f99a5cfe2b6d8c + /postcss-load-plugins/2.3.0: + dependencies: + cosmiconfig: 2.1.3 + object-assign: 4.1.1 + resolution: 745768116599aca2f009fad426b00175049d8d92 + /postcss-merge-idents/2.1.7: + dependencies: + has: 1.0.1 + postcss: 5.2.17 + postcss-value-parser: 3.3.0 + resolution: 4c5530313c08e1d5b3bbf3d2bbc747e278eea270 + /postcss-merge-longhand/2.0.2: + dependencies: + postcss: 5.2.17 + resolution: 23d90cd127b0a77994915332739034a1a4f3d658 + /postcss-merge-rules/2.1.2: + dependencies: + browserslist: 1.7.7 + caniuse-api: 1.6.1 + postcss: 5.2.17 + postcss-selector-parser: 2.2.3 + vendors: 1.0.1 + resolution: d1df5dfaa7b1acc3be553f0e9e10e87c61b5f721 + /postcss-message-helpers/2.0.0: a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e + /postcss-minify-font-values/1.0.5: + dependencies: + object-assign: 4.1.1 + postcss: 5.2.17 + postcss-value-parser: 3.3.0 + resolution: 4b58edb56641eba7c8474ab3526cafd7bbdecb69 + /postcss-minify-gradients/1.0.5: + dependencies: + postcss: 5.2.17 + postcss-value-parser: 3.3.0 + resolution: 5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1 + /postcss-minify-params/1.2.2: + dependencies: + alphanum-sort: 1.0.2 + postcss: 5.2.17 + postcss-value-parser: 3.3.0 + uniqs: 2.0.0 + resolution: ad2ce071373b943b3d930a3fa59a358c28d6f1f3 + /postcss-minify-selectors/2.1.1: + dependencies: + alphanum-sort: 1.0.2 + has: 1.0.1 + postcss: 5.2.17 + postcss-selector-parser: 2.2.3 + resolution: b2c6a98c0072cf91b932d1a496508114311735bf + /postcss-normalize-charset/1.1.1: + dependencies: + postcss: 5.2.17 + resolution: ef9ee71212d7fe759c78ed162f61ed62b5cb93f1 + /postcss-normalize-url/3.0.8: + dependencies: + is-absolute-url: 2.1.0 + normalize-url: 1.9.1 + postcss: 5.2.17 + postcss-value-parser: 3.3.0 + resolution: 108f74b3f2fcdaf891a2ffa3ea4592279fc78222 + /postcss-ordered-values/2.2.3: + dependencies: + postcss: 5.2.17 + postcss-value-parser: 3.3.0 + resolution: eec6c2a67b6c412a8db2042e77fe8da43f95c11d + /postcss-reduce-idents/2.4.0: + dependencies: + postcss: 5.2.17 + postcss-value-parser: 3.3.0 + resolution: c2c6d20cc958284f6abfbe63f7609bf409059ad3 + /postcss-reduce-initial/1.0.1: + dependencies: + postcss: 5.2.17 + resolution: 68f80695f045d08263a879ad240df8dd64f644ea + /postcss-reduce-transforms/1.0.4: + dependencies: + has: 1.0.1 + postcss: 5.2.17 + postcss-value-parser: 3.3.0 + resolution: ff76f4d8212437b31c298a42d2e1444025771ae1 + /postcss-selector-parser/2.2.3: + dependencies: + flatten: 1.0.2 + indexes-of: 1.0.1 + uniq: 1.0.1 + resolution: f9437788606c3c9acee16ffe8d8b16297f27bb90 + /postcss-svgo/2.1.6: + dependencies: + is-svg: 2.1.0 + postcss: 5.2.17 + postcss-value-parser: 3.3.0 + svgo: 0.7.2 + resolution: b6df18aa613b666e133f08adb5219c2684ac108d + /postcss-unique-selectors/2.0.2: + dependencies: + alphanum-sort: 1.0.2 + postcss: 5.2.17 + uniqs: 2.0.0 + resolution: 981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d + /postcss-value-parser/3.3.0: 87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15 + /postcss-zindex/2.2.0: + dependencies: + has: 1.0.1 + postcss: 5.2.17 + uniqs: 2.0.0 + resolution: d2109ddc055b91af67fc4cb3b025946639d2af22 + /postcss/5.2.17: + dependencies: + chalk: 1.1.3 + js-base64: 2.1.9 + source-map: 0.5.6 + supports-color: 3.2.3 + resolution: cf4f597b864d65c8a492b2eabe9d706c879c388b + /prelude-ls/1.1.2: 21932a549f5e52ffd9a827f570e04be62a97da54 + /prepend-http/1.0.4: d4f4562b0ce3696e41ac52d0e002e57a635dc6dc + /preserve/0.2.0: 815ed1f6ebc65926f865b310c0713bcb3315ce4b + /pretty-format/18.1.0: + dependencies: + ansi-styles: 2.2.1 + resolution: fb65a86f7a7f9194963eee91865c1bcf1039e284 + /pretty-hrtime/1.0.3: b7e3ea42435a4c9b2759d99e0f201eb195802ee1 + /pretty-ms/0.2.2: + dependencies: + parse-ms: 0.1.2 + resolution: da879a682ff33a37011046f13d627f67c73b84f6 + /pretty-ms/2.1.0: + dependencies: + is-finite: 1.0.2 + parse-ms: 1.0.1 + plur: 1.0.0 + resolution: 4257c256df3fb0b451d6affaab021884126981dc + /private/0.1.7: 68ce5e8a1ef0a23bb570cc28537b5332aba63ef1 + /process-nextick-args/1.0.7: 150e20b756590ad3f91093f25a4f2ad8bff30ba3 + /process/0.11.10: 7332300e840161bda3e69a1d1d91a7d4bc16f182 + /progress/1.1.8: e260c78f6161cdd9b0e56cc3e0a85de17c7a57be + /proto-props/0.2.1: 5e01dc2675a0de9abfa76e799dfa334d6f483f4b + /pseudomap/1.0.2: f052a28da70e618917ef0a8ac34c1ae5a68286b3 + /public-encrypt/4.0.0: + dependencies: + bn.js: 4.11.6 + browserify-rsa: 4.0.1 + create-hash: 1.1.3 + parse-asn1: 5.1.0 + randombytes: 2.0.4 + resolution: 39f699f3a46560dd5ebacbca693caf7c65c18cc6 + /punycode/1.3.2: 9653a036fb7c1ee42342f2325cceefea3926c48d + /punycode/1.4.1: c0d5a63b2718800ad8e1eb0fa5269c84dd41845e + /q/1.5.0: dd01bac9d06d30e6f219aecb8253ee9ebdc308f1 + /qs/2.2.5: 1088abaf9dcc0ae5ae45b709e6c6b5888b23923c + /qs/5.2.0: a9f31142af468cb72b25b30136ba2456834916be + /qs/6.4.0: 13e26d28ad6b0ffaa91312cd3bf708ed351e7233 + /query-string/4.3.4: + dependencies: + object-assign: 4.1.1 + strict-uri-encode: 1.1.0 + resolution: bbb693b9ca915c232515b228b1a02b609043dbeb + /querystring-es3/0.2.1: 9ec61f79049875707d69414596fd907a4d711e73 + /querystring/0.2.0: b209849203bb25df820da756e747005878521620 + /randomatic/1.1.6: + dependencies: + is-number: 2.1.0 + kind-of: 3.2.2 + resolution: 110dcabff397e9dcff7c0789ccc0a49adf1ec5bb + /randombytes/2.0.4: + dependencies: + safe-buffer: 5.1.0 + resolution: 9551df208422c8f80eb58e2326dd0b840ff22efd + /raw-body/2.1.7: + dependencies: + bytes: 2.4.0 + iconv-lite: 0.4.13 + unpipe: 1.0.0 + resolution: adfeace2e4fb3098058014d08c072dcc59758774 + /rc/1.2.1: + dependencies: + deep-extend: 0.4.2 + ini: 1.3.4 + minimist: 1.2.0 + strip-json-comments: 2.0.1 + resolution: 2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95 + /read-all-stream/3.1.0: + dependencies: + pinkie-promise: 2.0.1 + readable-stream: 2.2.10 + resolution: 35c3e177f2078ef789ee4bfafa4373074eaef4fa + /read-only-stream/2.0.0: + dependencies: + readable-stream: 2.2.10 + resolution: 2724fd6a8113d73764ac288d4386270c1dbf17f0 + /read-pkg-up/1.0.1: + dependencies: + find-up: 1.1.2 + read-pkg: 1.1.0 + resolution: 9d63c13276c065918d57f002a57f40a1b643fb02 + /read-pkg-up/2.0.0: + dependencies: + find-up: 2.1.0 + read-pkg: 2.0.0 + resolution: 6b72a8048984e0c41e79510fd5e9fa99b3b549be + /read-pkg/1.1.0: + dependencies: + load-json-file: 1.1.0 + normalize-package-data: 2.3.8 + path-type: 1.1.0 + resolution: f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28 + /read-pkg/2.0.0: + dependencies: + load-json-file: 2.0.0 + normalize-package-data: 2.3.8 + path-type: 2.0.0 + resolution: 8ef1c0623c6a6db0dc6713c4bfac46332b2368f8 + /readable-stream/1.0.34: + dependencies: + core-util-is: 1.0.2 + inherits: 2.0.3 + isarray: 0.0.1 + string_decoder: 0.10.31 + resolution: 125820e34bc842d2f2aaafafe4c2916ee32c157c + /readable-stream/1.1.14: + dependencies: + core-util-is: 1.0.2 + inherits: 2.0.3 + isarray: 0.0.1 + string_decoder: 0.10.31 + resolution: 7cf4c54ef648e3813084c636dd2079e166c081d9 + /readable-stream/2.0.6: + dependencies: + core-util-is: 1.0.2 + inherits: 2.0.3 + isarray: 1.0.0 + process-nextick-args: 1.0.7 + string_decoder: 0.10.31 + util-deprecate: 1.0.2 + resolution: 8f90341e68a53ccc928788dacfcd11b36eb9b78e + /readable-stream/2.2.10: + dependencies: + core-util-is: 1.0.2 + inherits: 2.0.3 + isarray: 1.0.0 + process-nextick-args: 1.0.7 + safe-buffer: 5.1.0 + string_decoder: 1.0.1 + util-deprecate: 1.0.2 + resolution: effe72bb7c884c0dd335e2379d526196d9d011ee + /readdirp/2.1.0: + dependencies: + graceful-fs: 4.1.11 + minimatch: 3.0.4 + readable-stream: 2.2.10 + set-immediate-shim: 1.0.1 + resolution: 4ed0ad060df3073300c48440373f72d1cc642d78 + /readline2/1.0.1: + dependencies: + code-point-at: 1.1.0 + is-fullwidth-code-point: 1.0.0 + mute-stream: 0.0.5 + resolution: 41059608ffc154757b715d9989d199ffbf372e35 + /recast/0.10.43: + dependencies: + ast-types: 0.8.15 + esprima-fb: 15001.1001.0-dev-harmony-fb + private: 0.1.7 + source-map: 0.5.6 + resolution: b95d50f6d60761a5f6252e15d80678168491ce7f + /rechoir/0.6.2: + dependencies: + resolve: 1.3.3 + resolution: 85204b54dba82d5742e28c96756ef43af50e3384 + /redent/1.0.0: + dependencies: + indent-string: 2.1.0 + strip-indent: 1.0.1 + resolution: cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde + /reduce-css-calc/1.3.0: + dependencies: + balanced-match: 0.4.2 + math-expression-evaluator: 1.2.17 + reduce-function-call: 1.0.2 + resolution: 747c914e049614a4c9cfbba629871ad1d2927716 + /reduce-function-call/1.0.2: + dependencies: + balanced-match: 0.4.2 + resolution: 5a200bf92e0e37751752fe45b0ab330fd4b6be99 + /regenerate/1.3.2: d1941c67bad437e1be76433add5b385f95b19260 + /regenerator-runtime/0.10.5: 336c3efc1220adcedda2c9fab67b5a7955a33658 + /regenerator-transform/0.9.11: + dependencies: + babel-runtime: 6.23.0 + babel-types: 6.24.1 + private: 0.1.7 + resolution: 3a7d067520cb7b7176769eb5ff868691befe1283 + /regex-cache/0.4.3: + dependencies: + is-equal-shallow: 0.1.3 + is-primitive: 2.0.0 + resolution: 9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145 + /regexpu-core/2.0.0: + dependencies: + regenerate: 1.3.2 + regjsgen: 0.2.0 + regjsparser: 0.1.5 + resolution: 49d038837b8dcf8bfa5b9a42139938e6ea2ae240 + /registry-auth-token/3.3.1: + dependencies: + rc: 1.2.1 + safe-buffer: 5.1.0 + resolution: fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006 + /registry-url/3.1.0: + dependencies: + rc: 1.2.1 + resolution: 3d4ef870f73dde1d77f0cf9a381432444e174942 + /regjsgen/0.2.0: 6c016adeac554f75823fe37ac05b92d5a4edb1f7 + /regjsparser/0.1.5: + dependencies: + jsesc: 0.5.0 + resolution: 7ee8f84dc6fa792d3fd0ae228d24bd949ead205c + /remove-trailing-separator/1.0.1: 615ebb96af559552d4bf4057c8436d486ab63cc4 + /repeat-element/1.1.2: ef089a178d1483baae4d93eb98b4f9e4e11d990a + /repeat-string/1.6.1: 8dcae470e1c88abc2d600fff4a776286da75e637 + /repeating/2.0.1: + dependencies: + is-finite: 1.0.2 + resolution: 5214c53a926d3552707527fbab415dbc08d06dda + /replace-ext/0.0.1: 29bbd92078a739f0bcce2b4ee41e837953522924 + /req-all/1.0.0: d128569451c340b432409c656cf166260cd2628d + /request/2.81.0: + dependencies: + aws-sign2: 0.6.0 + aws4: 1.6.0 + caseless: 0.12.0 + combined-stream: 1.0.5 + extend: 3.0.1 + forever-agent: 0.6.1 + form-data: 2.1.4 + har-validator: 4.2.1 + hawk: 3.1.3 + http-signature: 1.1.1 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.15 + oauth-sign: 0.8.2 + performance-now: 0.2.0 + qs: 6.4.0 + safe-buffer: 5.1.0 + stringstream: 0.0.5 + tough-cookie: 2.3.2 + tunnel-agent: 0.6.0 + uuid: 3.0.1 + resolution: c6928946a0e06c5f8d6f8a9333469ffda46298a0 + /require-directory/2.1.1: 8c64ad5fd30dab1c976e2344ffe7f792a6a6df42 + /require-from-string/1.2.1: 529c9ccef27380adfec9a2f965b649bbee636418 + /require-main-filename/1.0.1: 97f717b69d48784f5f526a6c5aa8ffdda055a4d1 + /require-precompiled/0.1.0: 5a1b52eb70ebed43eb982e974c85ab59571e56fa + /require-uncached/1.0.3: + dependencies: + caller-path: 0.1.0 + resolve-from: 1.0.1 + resolution: 4e0d56d6c9662fd31e43011c4b95aa49955421d3 + /resolve-cwd/1.0.0: + dependencies: + resolve-from: 2.0.0 + resolution: 4eaeea41ed040d1702457df64a42b2b07d246f9f + /resolve-dir/0.1.1: + dependencies: + expand-tilde: 1.2.2 + global-modules: 0.2.3 + resolution: b219259a5602fac5c5c496ad894a6e8cc430261e + /resolve-from/1.0.1: 26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226 + /resolve-from/2.0.0: 9480ab20e94ffa1d9e80a804c7ea147611966b57 + /resolve-url/0.2.1: 2c637fe77c893afd2a663fe21aa9080068e2052a + /resolve/1.1.7: 203114d82ad2c5ed9e8e0411b3932875e889e97b + /resolve/1.3.3: + dependencies: + path-parse: 1.0.5 + resolution: 655907c3469a8680dc2de3a275a8fdd69691f0e5 + /restore-cursor/1.0.1: + dependencies: + exit-hook: 1.1.1 + onetime: 1.1.0 + resolution: 34661f46886327fed2991479152252df92daa541 + /restore-cursor/2.0.0: + dependencies: + onetime: 2.0.1 + signal-exit: 3.0.2 + resolution: 9f7ee287f82fd326d4fd162923d62129eee0dfaf + /right-align/0.1.3: + dependencies: + align-text: 0.1.4 + resolution: 61339b722fe6a3515689210d24e14c96148613ef + /rimraf/2.6.1: + dependencies: + glob: 7.1.2 + resolution: c2338ec643df7a1b7fe5c54fa86f57428a55f33d + /ripemd160/2.0.1: + dependencies: + hash-base: 2.0.2 + inherits: 2.0.3 + resolution: 0f4584295c53a3628af7e6d79aca21ce57d1c6e7 + /rollup-stream/1.19.0: + dependencies: + rollup: 0.41.6 + resolution: 8ab70d3970d8ec8529f1c1d7a688d8d65f90599a + /rollup/0.41.6: + dependencies: + source-map-support: 0.4.15 + resolution: e0d05497877a398c104d816d2733a718a7a94e2a + /run-async/0.1.0: + dependencies: + once: 1.4.0 + resolution: c8ad4a5e110661e402a7d21b530e009f25f8e389 + /rx-lite/3.1.2: 19ce502ca572665f3b647b10939f97fd1615f102 + /rxjs/5.4.0: + dependencies: + symbol-observable: 1.0.4 + resolution: a7db14ab157f9d7aac6a56e655e7a3860d39bf26 + /safe-buffer/5.1.0: fe4c8460397f9eaaaa58e73be46273408a45e223 + /sass-graph/2.2.4: + dependencies: + glob: 7.1.2 + lodash: 4.17.4 + scss-tokenizer: 0.2.3 + yargs: 7.1.0 + resolution: 13fbd63cd1caf0908b9fd93476ad43a51d1e0b49 + /sax/1.2.2: fd8631a23bc7826bef5d871bdb87378c95647828 + /scss-tokenizer/0.2.3: + dependencies: + js-base64: 2.1.9 + source-map: 0.4.4 + resolution: 8eb06db9a9723333824d3f5530641149847ce5d1 + /semver-diff/2.1.0: + dependencies: + semver: 5.3.0 + resolution: 4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36 + /semver/4.3.6: 300bc6e0e86374f7ba61068b5b1ecd57fc6532da + /semver/5.3.0: 9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f + /sequencify/0.0.7: 90cff19d02e07027fd767f5ead3e7b95d1e7380c + /set-blocking/2.0.0: 045f9782d011ae9a6803ddd382b24392b3d890f7 + /set-immediate-shim/1.0.1: 4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61 + /sha.js/2.4.8: + dependencies: + inherits: 2.0.3 + resolution: 37068c2c476b6baf402d14a49c67f597921f634f + /shasum/1.0.2: + dependencies: + json-stable-stringify: 0.0.1 + sha.js: 2.4.8 + resolution: e7012310d8f417f4deb5712150e5678b87ae565f + /shebang-command/1.2.0: + dependencies: + shebang-regex: 1.0.0 + resolution: 44aac65b695b03398968c39f363fee5deafdf1ea + /shebang-regex/1.0.0: da42f49740c0b42db2ca9728571cb190c98efea3 + /shell-quote/1.6.1: + dependencies: + array-filter: 0.0.1 + array-map: 0.0.0 + array-reduce: 0.0.0 + jsonify: 0.0.0 + resolution: f4781949cce402697127430ea3b3c5476f481767 + /shelljs/0.7.7: + dependencies: + glob: 7.1.2 + interpret: 1.0.3 + rechoir: 0.6.2 + resolution: b2f5c77ef97148f4b4f6e22682e10bba8667cff1 + /sigmund/1.0.1: 3ff21f198cad2175f9f3b781853fd94d0d19b590 + /signal-exit/3.0.2: b5fdc08f1287ea1178628e415e25132b73646c6d + /slash/1.0.0: c41f2f6c39fc16d1cd17ad4b5d896114ae470d55 + /slice-ansi/0.0.4: edbf8903f66f7ce2f8eafd6ceed65e264c831b35 + /slide/1.1.6: 56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707 + /sntp/1.0.9: + dependencies: + hoek: 2.16.3 + resolution: 6541184cc90aeea6c6e7b35e2659082443c66198 + /sort-keys/1.1.2: + dependencies: + is-plain-obj: 1.1.0 + resolution: 441b6d4d346798f1b4e49e8920adfba0e543f9ad + /source-map-resolve/0.3.1: + dependencies: + atob: 1.1.3 + resolve-url: 0.2.1 + source-map-url: 0.3.0 + urix: 0.1.0 + resolution: 610f6122a445b8dd51535a2a71b783dfc1248761 + /source-map-support/0.4.15: + dependencies: + source-map: 0.5.6 + resolution: 03202df65c06d2bd8c7ec2362a193056fef8d3b1 + /source-map-url/0.3.0: 7ecaf13b57bcd09da8a40c5d269db33799d4aaf9 + /source-map/0.1.31: + dependencies: + amdefine: 1.0.1 + resolution: 9f704d0d69d9e138a81badf6ebb4fde33d151c61 + /source-map/0.1.43: + dependencies: + amdefine: 1.0.1 + resolution: c24bc146ca517c1471f5dacbe2571b2b7f9e3346 + /source-map/0.2.0: + dependencies: + amdefine: 1.0.1 + resolution: dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d + /source-map/0.4.4: + dependencies: + amdefine: 1.0.1 + resolution: eba4f5da9c0dc999de68032d8b4f76173652036b + /source-map/0.5.6: 75ce38f52bf0733c5a7f0c118d81334a2bb5f412 + /sparkles/1.0.0: 1acbbfb592436d10bbe8f785b7cc6f82815012c3 + /spdx-correct/1.0.2: + dependencies: + spdx-license-ids: 1.2.2 + resolution: 4b3073d933ff51f3912f03ac5519498a4150db40 + /spdx-expression-parse/1.0.4: 9bdf2f20e1f40ed447fbe273266191fced51626c + /spdx-license-ids/1.2.2: c9df7a3424594ade6bd11900d596696dc06bac57 + /split/0.3.3: + dependencies: + through: 2.3.8 + resolution: cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f + /sprintf-js/1.0.3: 04e6926f662895354f3dd015203633b857297e2c + /sshpk/1.13.0: + dependencies: + asn1: 0.2.3 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.1 + dashdash: 1.14.1 + ecc-jsbn: 0.1.1 + getpass: 0.1.7 + jodid25519: 1.0.2 + jsbn: 0.1.1 + tweetnacl: 0.14.5 + resolution: ff2a3e4fd04497555fed97b39a0fd82fafb3a33c + /stack-utils/1.0.1: d4f33ab54e8e38778b0ca5cfd3b3afb12db68620 + /staged-git-files/0.0.4: d797e1b551ca7a639dec0237dc6eb4bb9be17d35 + /static-eval/1.1.1: + dependencies: + escodegen: 1.8.1 + resolution: ca8130210354cf13d9a722bc7e923778457bb192 + /statuses/1.3.1: faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e + /stdout-stream/1.4.0: + dependencies: + readable-stream: 2.2.10 + resolution: a2c7c8587e54d9427ea9edb3ac3f2cd522df378b + /stream-browserify/2.0.1: + dependencies: + inherits: 2.0.3 + readable-stream: 2.2.10 + resolution: 66266ee5f9bdb9940a4e4514cafb43bb71e5c9db + /stream-combiner/0.0.4: + dependencies: + duplexer: 0.1.1 + resolution: 4d5e433c185261dde623ca3f44c586bcf5c4ad14 + /stream-combiner2/1.1.1: + dependencies: + duplexer2: 0.1.4 + readable-stream: 2.2.10 + resolution: fb4d8a1420ea362764e21ad4780397bebcb41cbe + /stream-consume/0.1.0: a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f + /stream-http/2.7.1: + dependencies: + builtin-status-codes: 3.0.0 + inherits: 2.0.3 + readable-stream: 2.2.10 + to-arraybuffer: 1.0.1 + xtend: 4.0.1 + resolution: 546a51741ad5a6b07e9e31b0b10441a917df528a + /stream-splicer/2.0.0: + dependencies: + inherits: 2.0.3 + readable-stream: 2.2.10 + resolution: 1b63be438a133e4b671cc1935197600175910d83 + /stream-to-observable/0.1.0: 45bf1d9f2d7dc09bed81f1c307c430e68b84cffe + /strict-uri-encode/1.1.0: 279b225df1d582b1f54e65addd4352e18faa0713 + /string-width/1.0.2: + dependencies: + code-point-at: 1.1.0 + is-fullwidth-code-point: 1.0.0 + strip-ansi: 3.0.1 + resolution: 118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3 + /string-width/2.0.0: + dependencies: + is-fullwidth-code-point: 2.0.0 + strip-ansi: 3.0.1 + resolution: 635c5436cc72a6e0c387ceca278d4e2eec52687e + /string_decoder/0.10.31: 62e203bc41766c6c28c9fc84301dab1c5310fa94 + /string_decoder/1.0.1: + dependencies: + safe-buffer: 5.1.0 + resolution: 62e200f039955a6810d8df0a33ffc0f013662d98 + /stringstream/0.0.5: 4e484cd4de5a0bbbee18e46307710a8a81621878 + /strip-ansi/0.1.1: 39e8a98d044d150660abe4a6808acf70bb7bc991 + /strip-ansi/0.3.0: + dependencies: + ansi-regex: 0.2.1 + resolution: 25f48ea22ca79187f3174a4db8759347bb126220 + /strip-ansi/3.0.1: + dependencies: + ansi-regex: 2.1.1 + resolution: 6a385fb8853d952d5ff05d0e8aaf94278dc63dcf + /strip-bom-buf/1.0.0: + dependencies: + is-utf8: 0.2.1 + resolution: 1cb45aaf57530f4caf86c7f75179d2c9a51dd572 + /strip-bom-string/1.0.0: e5211e9224369fbb81d633a2f00044dc8cedad92 + /strip-bom/1.0.0: + dependencies: + first-chunk-stream: 1.0.0 + is-utf8: 0.2.1 + resolution: 85b8862f3844b5a6d5ec8467a93598173a36f794 + /strip-bom/2.0.0: + dependencies: + is-utf8: 0.2.1 + resolution: 6219a85616520491f35788bdbf1447a99c7e6b0e + /strip-bom/3.0.0: 2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3 + /strip-eof/1.0.0: bb43ff5598a6eb05d89b59fcd129c983313606bf + /strip-indent/1.0.1: + dependencies: + get-stdin: 4.0.1 + resolution: 0c7962a6adefa7bbd4ac366460a638552ae1a0a2 + /strip-json-comments/2.0.1: 3c531942e908c2697c0ec344858c286c7ca0a60a + /subarg/1.0.0: + dependencies: + minimist: 1.2.0 + resolution: f62cf17581e996b48fc965699f54c06ae268b8d2 + /supports-color/0.2.0: d92de2694eb3f67323973d7ae3d8b55b4c22190a + /supports-color/2.0.0: 535d045ce6b6363fa40117084629995e9df324c7 + /supports-color/3.2.3: + dependencies: + has-flag: 1.0.0 + resolution: 65ac0504b3954171d8a64946b2ae3cbb8a5f54f6 + /svgo/0.6.6: + dependencies: + coa: 1.0.2 + colors: 1.1.2 + csso: 2.0.0 + js-yaml: 3.6.1 + mkdirp: 0.5.1 + sax: 1.2.2 + whet.extend: 0.9.9 + resolution: b340889036f20f9b447543077d0f5573ed044c08 + /svgo/0.7.2: + dependencies: + coa: 1.0.2 + colors: 1.1.2 + csso: 2.3.2 + js-yaml: 3.7.0 + mkdirp: 0.5.1 + sax: 1.2.2 + whet.extend: 0.9.9 + resolution: 9f5772413952135c6fefbf40afe6a4faa88b4bb5 + /symbol-observable/0.2.4: 95a83db26186d6af7e7a18dbd9760a2f86d08f40 + /symbol-observable/1.0.4: 29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d + /syntax-error/1.3.0: + dependencies: + acorn: 4.0.13 + resolution: 1ed9266c4d40be75dc55bf9bb1cb77062bb96ca1 + /table/3.8.3: + dependencies: + ajv: 4.11.8 + ajv-keywords: 1.5.1 + chalk: 1.1.3 + lodash: 4.17.4 + slice-ansi: 0.0.4 + string-width: 2.0.0 + resolution: 2bbc542f0fda9861a755d3947fefd8b3f513855f + /tar/2.2.1: + dependencies: + block-stream: 0.0.9 + fstream: 1.0.11 + inherits: 2.0.3 + resolution: 8e4d2a256c0e2185c6b18ad694aec968b83cb1d1 + /term-size/0.1.1: + dependencies: + execa: 0.4.0 + resolution: 87360b96396cab5760963714cda0d0cbeecad9ca + /text-table/0.2.0: 7f5ee823ae805207c00af2df4a84ec3fcfa570b4 + /the-argv/1.0.0: 0084705005730dd84db755253c931ae398db9522 + /through/2.3.8: 0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5 + /through2/0.6.5: + dependencies: + readable-stream: 1.0.34 + xtend: 4.0.1 + resolution: 41ab9c67b29d57209071410e1d7a7a968cd3ad48 + /through2/2.0.3: + dependencies: + readable-stream: 2.2.10 + xtend: 4.0.1 + resolution: 0004569b37c7c74ba39c43f3ced78d1ad94140be + /tildify/1.2.0: + dependencies: + os-homedir: 1.0.2 + resolution: dcec03f55dca9b7aa3e5b04f21817eb56e63588a + /time-require/0.1.2: + dependencies: + chalk: 0.4.0 + date-time: 0.1.1 + pretty-ms: 0.2.2 + text-table: 0.2.0 + resolution: f9e12cb370fc2605e11404582ba54ef5ca2b2d98 + /time-stamp/1.1.0: 764a5a11af50561921b133f3b44e618687e0f5c3 + /timed-out/3.1.3: 95860bfcc5c76c277f8f8326fd0f5b2e20eba217 + /timed-out/4.0.1: f32eacac5a175bea25d7fab565ab3ed8741ef56f + /timers-browserify/1.4.2: + dependencies: + process: 0.11.10 + resolution: c9c58b575be8407375cb5e2462dacee74359f41d + /to-arraybuffer/1.0.1: 7d229b1fcc637e466ca081180836a7aabff83f43 + /to-fast-properties/1.0.3: b83571fa4d8c25b82e231b06e3a3055de4ca1a47 + /tough-cookie/2.3.2: + dependencies: + punycode: 1.4.1 + resolution: f081f76e4c85720e6c37a5faced737150d84072a + /trim-newlines/1.0.0: 5887966bb582a4503a41eb524f7d35011815a613 + /trim-right/1.0.1: cb2e1203067e0c8de1f614094b9fe45704ea6003 + /tryit/1.0.3: 393be730a9446fd1ead6da59a014308f36c289cb + /tty-browserify/0.0.0: a157ba402da24e9bf957f9aa69d524eed42901a6 + /tunnel-agent/0.6.0: + dependencies: + safe-buffer: 5.1.0 + resolution: 27a5dea06b36b04a0a9966774b290868f0fc40fd + /tweetnacl/0.14.5: 5ae68177f192d4456269d108afa93ff8743f4f64 + /type-check/0.3.2: + dependencies: + prelude-ls: 1.1.2 + resolution: 5884cab512cf1d355e3fb784f30804b2b520db72 + /type-detect/0.1.1: 0ba5ec2a885640e470ea4e8505971900dac58822 + /type-detect/1.0.0: 762217cc06db258ec48908a1298e8b95121e8ea2 + /type-is/1.6.15: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.15 + resolution: cab10fb4909e441c82842eafe1ad646c81804410 + /typedarray/0.0.6: 867ac74e3864187b1d3d47d996a78ec5c8830777 + /uglify-js/2.8.27: + dependencies: + source-map: 0.5.6 + uglify-to-browserify: 1.0.2 + yargs: 3.10.0 + resolution: 47787f912b0f242e5b984343be8e35e95f694c9c + /uglify-save-license/0.4.1: 95726c17cc6fd171c3617e3bf4d8d82aa8c4cce1 + /uglify-to-browserify/1.0.2: 6e0924d6bda6b5afe349e39a6d632850a0f882b7 + /uglifyify/3.0.4: + dependencies: + convert-source-map: 1.1.3 + extend: 1.3.0 + minimatch: 3.0.4 + through: 2.3.8 + uglify-js: 2.8.27 + resolution: 487e080a5a7798880e68e90def9b06681fb13bd2 + /uid2/0.0.3: 483126e11774df2f71b8b639dcd799c376162b82 + /umd/3.0.1: 8ae556e11011f63c2596708a8837259f01b3d60e + /unc-path-regex/0.1.2: e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa + /uniq/1.0.1: b31c5ae8254844a3a8281541ce2b04b865a734ff + /uniqid/4.1.1: + dependencies: + macaddress: 0.2.8 + resolution: 89220ddf6b751ae52b5f72484863528596bb84c1 + /uniqs/2.0.0: ffede4b36b25290696e6e165d4a59edb998e6b02 + /unique-stream/1.0.0: d59a4a75427447d9aa6c91e70263f8d26a4b104b + /unique-string/1.0.0: + dependencies: + crypto-random-string: 1.0.0 + resolution: 9e1057cca851abb93398f8b33ae187b99caec11a + /unique-temp-dir/1.0.0: + dependencies: + mkdirp: 0.5.1 + os-tmpdir: 1.0.2 + uid2: 0.0.3 + resolution: 6dce95b2681ca003eebfb304a415f9cbabcc5385 + /unpipe/1.0.0: b2bf4ee8514aae6165b4817829d21b2ef49904ec + /unreachable-branch-transform/0.3.0: + dependencies: + esmangle-evaluator: 1.0.1 + recast: 0.10.43 + through2: 0.6.5 + resolution: d99cc4c6e746d264928845b611db54b0f3474caa + /unzip-response/1.0.2: b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe + /unzip-response/2.0.1: d2f0f737d16b0615e72a6935ed04214572d56f97 + /update-notifier/1.0.3: + dependencies: + boxen: 0.6.0 + chalk: 1.1.3 + configstore: 2.1.0 + is-npm: 1.0.0 + latest-version: 2.0.0 + lazy-req: 1.1.0 + semver-diff: 2.1.0 + xdg-basedir: 2.0.0 + resolution: 8f92c515482bd6831b7c93013e70f87552c7cf5a + /update-notifier/2.1.0: + dependencies: + boxen: 1.1.0 + chalk: 1.1.3 + configstore: 3.1.0 + is-npm: 1.0.0 + latest-version: 3.1.0 + lazy-req: 2.0.0 + semver-diff: 2.1.0 + xdg-basedir: 3.0.0 + resolution: ec0c1e53536b76647a24b77cb83966d9315123d9 + /urix/0.1.0: da937f7a62e21fec1fd18d49b35c2935067a6c72 + /url-parse-lax/1.0.0: + dependencies: + prepend-http: 1.0.4 + resolution: 7af8f303645e9bd79a272e7a14ac68bc0609da73 + /url/0.11.0: + dependencies: + punycode: 1.3.2 + querystring: 0.2.0 + resolution: 3838e97cfc60521eb73c525a8e55bfdd9e2e28f1 + /user-home/1.1.1: 2b5be23a32b63a7c9deb8d0f28d485724a3df190 + /user-home/2.0.0: + dependencies: + os-homedir: 1.0.2 + resolution: 9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f + /util-deprecate/1.0.2: 450d4dc9fa70de732762fbd2d4a28981419a0ccf + /util/0.10.3: + dependencies: + inherits: 2.0.1 + resolution: 7afb1afe50805246489e3db7fe0ed379336ac0f9 + /uuid/2.0.3: 67e2e863797215530dff318e5bf9dcebfd47b21a + /uuid/3.0.1: 6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1 + /v8flags/2.1.1: + dependencies: + user-home: 1.1.1 + resolution: aab1a1fa30d45f88dd321148875ac02c0b55e5b4 + /validate-npm-package-license/3.0.1: + dependencies: + spdx-correct: 1.0.2 + spdx-expression-parse: 1.0.4 + resolution: 2804babe712ad3379459acfbe24746ab2c303fbc + /vendors/1.0.1: 37ad73c8ee417fb3d580e785312307d274847f22 + /verror/1.3.6: + dependencies: + extsprintf: 1.0.2 + resolution: cff5df12946d297d2baaefaa2689e25be01c005c + /vinyl-buffer/1.0.0: + dependencies: + bl: 0.9.5 + through2: 0.6.5 + resolution: ca067ea08431d507722b1de5083f602616ebc234 + /vinyl-fs/0.3.14: + dependencies: + defaults: 1.0.3 + glob-stream: 3.1.18 + glob-watcher: 0.0.6 + graceful-fs: 3.0.11 + mkdirp: 0.5.1 + strip-bom: 1.0.0 + through2: 0.6.5 + vinyl: 0.4.6 + resolution: 9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6 + /vinyl-source-stream/1.1.0: + dependencies: + through2: 0.6.5 + vinyl: 0.4.6 + resolution: 44cbe5108205279deb0c5653c094a2887938b1ab + /vinyl-sourcemaps-apply/0.2.1: + dependencies: + source-map: 0.5.6 + resolution: ab6549d61d172c2b1b87be5c508d239c8ef87705 + /vinyl/0.4.6: + dependencies: + clone: 0.2.0 + clone-stats: 0.0.1 + resolution: 2f356c87a550a255461f36bbeb2a5ba8bf784847 + /vinyl/0.5.3: + dependencies: + clone: 1.0.2 + clone-stats: 0.0.1 + replace-ext: 0.0.1 + resolution: b0455b38fc5e0cf30d4325132e461970c2091cde + /vinyl/1.2.0: + dependencies: + clone: 1.0.2 + clone-stats: 0.0.1 + replace-ext: 0.0.1 + resolution: 5c88036cf565e5df05558bfc911f8656df218884 + /vm-browserify/0.0.4: + dependencies: + indexof: 0.0.1 + resolution: 5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73 + /watchify/3.9.0: + dependencies: + anymatch: 1.3.0 + browserify: 14.4.0 + chokidar: 1.7.0 + defined: 1.0.0 + outpipe: 1.1.1 + through2: 2.0.3 + xtend: 4.0.1 + resolution: f075fd2e8a86acde84cedba6e5c2a0bedd523d9e + /websocket-driver/0.6.5: + dependencies: + websocket-extensions: 0.1.1 + resolution: 5cb2556ceb85f4373c6d8238aa691c8454e13a36 + /websocket-extensions/0.1.1: 76899499c184b6ef754377c2dbb0cd6cb55d29e7 + /whet.extend/0.9.9: f877d5bf648c97e5aa542fadc16d6a259b9c11a1 + /which-module/1.0.0: bba63ca861948994ff307736089e3b96026c2a4f + /which/1.2.14: + dependencies: + isexe: 2.0.0 + resolution: 9a87c4378f03e827cecaf1acdf56c736c01c14e5 + /wide-align/1.1.2: + dependencies: + string-width: 1.0.2 + resolution: 571e0f1b0604636ebc0dfc21b0339bbe31341710 + /widest-line/1.0.0: + dependencies: + string-width: 1.0.2 + resolution: 0c09c85c2a94683d0d7eaf8ee097d564bf0e105c + /window-size/0.1.0: 5438cd2ea93b202efa3a19fe8887aee7c94f9c9d + /wordwrap/0.0.2: b79669bb42ecb409f83d583cad52ca17eaa1643f + /wordwrap/1.0.0: 27584810891456a4171c8d0226441ade90cbcaeb + /wrap-ansi/2.1.0: + dependencies: + string-width: 1.0.2 + strip-ansi: 3.0.1 + resolution: d8fc3d284dd05794fe84973caecdd1cf824fdd85 + /wrappy/1.0.2: b5243d8f3ec1aa35f1364605bc0d1036e30ab69f + /write-file-atomic/1.3.4: + dependencies: + graceful-fs: 4.1.11 + imurmurhash: 0.1.4 + slide: 1.1.6 + resolution: f807a4f0b1d9e913ae7a48112e6cc3af1991b45f + /write-file-atomic/2.1.0: + dependencies: + graceful-fs: 4.1.11 + imurmurhash: 0.1.4 + slide: 1.1.6 + resolution: 1769f4b551eedce419f0505deae2e26763542d37 + /write-json-file/2.2.0: + dependencies: + detect-indent: 5.0.0 + graceful-fs: 4.1.11 + make-dir: 1.0.0 + pify: 2.3.0 + sort-keys: 1.1.2 + write-file-atomic: 2.1.0 + resolution: 51862506bbb3b619eefab7859f1fd6c6d0530876 + /write-pkg/2.1.0: + dependencies: + sort-keys: 1.1.2 + write-json-file: 2.2.0 + resolution: 353aa44c39c48c21440f5c08ce6abd46141c9c08 + /write/0.2.1: + dependencies: + mkdirp: 0.5.1 + resolution: 5fc03828e264cea3fe91455476f7a3c566cb0757 + /xdg-basedir/2.0.0: + dependencies: + os-homedir: 1.0.2 + resolution: edbc903cc385fc04523d966a335504b5504d1bd2 + /xdg-basedir/3.0.0: 496b2cc109eca8dbacfe2dc72b603c17c5870ad4 + /xo-init/0.5.0: + dependencies: + arrify: 1.0.1 + execa: 0.5.1 + minimist: 1.2.0 + path-exists: 3.0.0 + read-pkg-up: 2.0.0 + the-argv: 1.0.0 + write-pkg: 2.1.0 + resolution: 8e28dec79676cc5e042fde5fd8f710e2646b0e36 + /xo/0.18.2: + dependencies: + arrify: 1.0.1 + debug: 2.6.8 + deep-assign: 1.0.0 + eslint: 3.19.0 + eslint-config-xo: 0.18.2 + eslint-formatter-pretty: 1.1.0 + eslint-plugin-ava: 4.2.0 + eslint-plugin-import: 2.3.0 + eslint-plugin-no-use-extend-native: 0.3.12 + eslint-plugin-promise: 3.5.0 + eslint-plugin-unicorn: 2.1.1 + get-stdin: 5.0.1 + globby: 6.1.0 + has-flag: 2.0.0 + ignore: 3.3.3 + lodash.isequal: 4.5.0 + meow: 3.7.0 + multimatch: 2.1.0 + path-exists: 3.0.0 + pkg-conf: 2.0.0 + resolve-cwd: 1.0.0 + resolve-from: 2.0.0 + slash: 1.0.0 + update-notifier: 2.1.0 + xo-init: 0.5.0 + resolution: 92a42eb02a4fb149dfea5518021914f5aac84ff0 + /xtend/4.0.1: a5c6d532be656e23db820efb943a1f04998d63af + /y18n/3.2.1: 6d15fba884c08679c0d77e88e7759e811e07fa41 + /yallist/2.1.2: 1c11f9218f076089a47dd512f93c6699a6a81d52 + /yargs-parser/5.0.0: + dependencies: + camelcase: 3.0.0 + resolution: 275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a + /yargs/3.10.0: + dependencies: + camelcase: 1.2.1 + cliui: 2.1.0 + decamelize: 1.2.0 + window-size: 0.1.0 + resolution: f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1 + /yargs/7.1.0: + dependencies: + camelcase: 3.0.0 + cliui: 3.2.0 + decamelize: 1.2.0 + get-caller-file: 1.0.2 + os-locale: 1.4.0 + read-pkg-up: 1.0.1 + require-directory: 2.1.1 + require-main-filename: 1.0.1 + set-blocking: 2.0.0 + string-width: 1.0.2 + which-module: 1.0.0 + y18n: 3.2.1 + yargs-parser: 5.0.0 + resolution: 6ba318eb16961727f5d284f8ea003e8d6154d0c8 + github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916: + resolution: + tarball: 'https://codeload.github.com/practicejavascript/pjs-problems/tar.gz/0823cc1cffb999352e3f0caed295df8633f13916' +registry: 'https://registry.npmjs.org/' +version: 2 diff --git a/src/js/index.js b/src/js/index.js index c4e5c8e..0e202d6 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -2,10 +2,32 @@ // DEPENDENCIES // ============================================================ const localforage = require('localforage'); + const probs = require('pjs-problems'); + const dedent = require('dedent'); + const assert = require('chai').assert; + + // PROBLEM TEMPLATE NICE-IFICATION + // ============================================================ + + function dedentStrings(problems) { + return problems.map(prob => { + prob.given = dedent(prob.given) + prob.answer = dedent(prob.answer) + return prob + }); + } + // PROBLEMS // ============================================================ - const problems = require('../problems/arrays.js'); + + let problems = []; + Object.keys(probs).forEach(subject => { + problems.push(...probs[subject]); + }); + problems = dedentStrings(problems) + console.log('problems:', problems); + // CONFIG // ============================================================ @@ -259,6 +281,7 @@ evalConsoleEl.innerHTML = inner; } + // VERIFICATION LOGIC // ============================================================ @@ -292,7 +315,11 @@ let testOutcome = false; try { if (output) { - testOutcome = test.test(output); + // const testEval = eval(test.test); + + testOutcome = eval(test.test); + console.log('testOutcome:', testOutcome); + } printAssertError(null); } catch (err) { diff --git a/src/service-worker.js b/src/service-worker.js index 01b3385..6981f7b 100644 --- a/src/service-worker.js +++ b/src/service-worker.js @@ -37,7 +37,11 @@ /* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */ 'use strict'; +<<<<<<< HEAD var precacheConfig = [["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","a70702eeea1dbe4a401b7c23189eb7d3"],["/dist/js/bundle.min.js","5a4878a0d8d1655d9f3edbc1aee091b7"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]]; +======= +var precacheConfig = [["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","a70702eeea1dbe4a401b7c23189eb7d3"],["/dist/js/bundle.min.js","b811fe18d2d6a402297a71172a324d69"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]]; +>>>>>>> working import of external problem content var cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : ''); From 2d17b7911ef725ff112fc6b30d3d744252243d18 Mon Sep 17 00:00:00 2001 From: Jakob Anderson Date: Fri, 2 Jun 2017 23:34:05 -0600 Subject: [PATCH 2/8] using external content now. booyah --- gulpfile.js | 9 +- package.json | 6 +- public/dist/css/style.css | 2 +- public/dist/img/social-banner.png | Bin 28916 -> 28860 bytes public/dist/js/bundle.min.js | 9386 +------------------------ public/dist/js/bundle.min.js.map | 6 +- public/dist/js/loadJS.js | 23 +- public/dist/js/loadJS.js.map | 2 +- public/dist/js/sw-registration.js | 64 +- public/dist/js/sw-registration.js.map | 2 +- public/service-worker.js | 6 +- public/service-worker.js.map | 6 +- shrinkwrap.yaml | 655 +- src/js/index.js | 3 +- src/service-worker.js | 6 +- 15 files changed, 732 insertions(+), 9444 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 0a3bb92..9d173cc 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -6,7 +6,9 @@ const sourcemaps = require('gulp-sourcemaps'); const browserify = require('browserify'); const source = require('vinyl-source-stream'); const buffer = require('vinyl-buffer'); -const uglify = require('gulp-uglify'); +const uglifyES = require('uglify-es'); +const composer = require('gulp-uglify/composer'); +const uglify = composer(uglifyES, console); const watchify = require('watchify'); const babel = require('babelify'); const postcss = require('gulp-postcss'); @@ -18,6 +20,7 @@ const livereload = require('gulp-livereload'); const htmlmin = require('gulp-htmlmin'); const swPrecache = require('sw-precache'); const image = require('gulp-image'); +const pump = require('pump'); // CONFIG // ============================================================ @@ -71,7 +74,7 @@ function compile(watch) { .pipe(sourcemaps.init({ loadMaps: true })) - // .pipe(uglify()) + .pipe(uglify()) .pipe(sourcemaps.write('./')) .pipe(gulp.dest('./public/dist/js')); } @@ -118,7 +121,7 @@ gulp.task('js', () => { .pipe(sourcemaps.init({ loadMaps: true })) - .pipe(uglify(uglifyConf)) + // .pipe(uglify(uglifyConf)) .pipe(sourcemaps.write('./')) .pipe(gulp.dest('./public/dist/js')); }); diff --git a/package.json b/package.json index 345896b..0e4cc5d 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "chai": "^3.5.0", "cssnano": "^3.10.0", "dedent": "^0.7.0", + "gulp": "^3.9.1", "gulp-bro": "^1.0.2", "gulp-htmlmin": "^3.0.0", "gulp-image": "^2.8.0", @@ -65,14 +66,15 @@ "gulp-sass": "^3.1.0", "gulp-sourcemaps": "^2.6.0", "gulp-svgo": "^1.0.3", - "gulp-uglify": "^2.1.2", + "gulp-uglify": "^3.0.0", "gulp-util": "^3.0.8", - "gulp": "^3.9.1", "husky": "^0.13.3", "lint-staged": "^3.4.0", "localforage": "^1.5.0", + "pump": "^1.0.2", "rollup-stream": "^1.19.0", "sw-precache": "^5.1.1", + "uglify-es": "^3.0.15", "uglifyify": "^3.0.4", "vinyl-buffer": "^1.0.0", "vinyl-source-stream": "^1.1.0", diff --git a/public/dist/css/style.css b/public/dist/css/style.css index 1fa747c..1db0a90 100644 --- a/public/dist/css/style.css +++ b/public/dist/css/style.css @@ -1 +1 @@ -html{background-color:#0c141f;min-height:100%}body{margin:0}body,input,select,textarea{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,Arial,sans-serif;font-size:16pt;box-sizing:border-box;color:#e6ffff;-webkit-font-smoothing:antialiased}a{color:#6fc3df}.monospace{font-family:Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.hidden,.hide-until-load{visibility:hidden}.visually-hidden{position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);padding:0!important;border:0!important;height:1px!important;width:1px!important;overflow:hidden}body{opacity:1;transition:opacity .2s ease-in-out}.container{display:block}.site-heading{padding:.5em;text-align:center;margin:0;display:flex;flex-direction:column}.site-heading span{display:flex;align-items:center;justify-content:center;text-shadow:0 0 10px #fff,0 0 40px #6fc3df}.site-heading h1{font-size:200%;margin:.3em 0 .5em .5em;letter-spacing:0;font-weight:200}.site-heading img.logo{display:none}.controls{cursor:pointer;display:flex;justify-content:space-around;font-size:60%;text-transform:uppercase}.controls img{padding:1em;border-radius:1em;background-color:transparent;height:30px}.controls>div>.active,.controls>div>:active{background-color:#6fc3df;transition:color .1s ease-in-out}.problem-group{display:block;margin:.7em 0;align-items:center}.problem{display:block;margin:1em}.code-and-tests{vertical-align:top;display:block}.code{font-size:80%;color:#f8f8f2;color:#fff;overflow-x:auto;padding:.5em;background:#23241f;background:#1a1a1a;border-radius:3px;padding:.25em .65em}.code,.test-area{display:inline-block;width:100%}.test-area{vertical-align:top}.test-suite{font-size:60%}.test{display:block;margin:.7em 0}.test-state{display:inline-block;transition:all .2s ease-in-out}.test-state.pass{color:#6fc3df}.test-state.fail{color:#df740c}.test-name{display:inline-block}.test-total{background-color:gray;color:#fff;text-align:center;padding:.5em;transition:all .2s ease-in-out}.test-total.working{background:url(/dist/img/reload.svg)}.test-total.pass{background-color:#6fc3df}.test-total.fail{background-color:#df740c}.console{font-size:70%;margin:.5em 0;vertical-align:top}.console>h4{text-align:center}.ads-bottom{display:flex;flex-direction:row;align-items:center;justify-content:center;margin:5em 0 1em}footer{margin:0 auto;text-align:center;left:0;bottom:0;height:70px;width:100%;font-size:60%}footer>div{margin:.4em auto}@media (min-width:760px){.container{width:92%;margin:0 auto;display:flex}.left-spacer{flex:0.5}main{flex:30}.site-heading .container{justify-content:space-between;flex-direction:row;align-items:center}.site-heading>.container>h1{font-size:200%}.site-heading img.logo{height:60px;display:flex}.problem-name{display:block}.problem-group{display:flex;justify-content:space-between}.problem{display:block;margin-right:.6em}.code-and-tests{display:flex}.test-area{width:30%}.code-and-eval-console{width:70%}} \ No newline at end of file +html{background-color:#0c141f;min-height:100%}body{margin:0}body,input,select,textarea{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,Arial,sans-serif;font-size:16pt;box-sizing:border-box;color:#e6ffff;-webkit-font-smoothing:antialiased}a{color:#6fc3df}.monospace{font-family:Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.hidden,.hide-until-load{visibility:hidden}.visually-hidden{position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);padding:0!important;border:0!important;height:1px!important;width:1px!important;overflow:hidden}body{opacity:1;transition:opacity .2s ease-in-out}.container{display:block}.site-heading{padding:.5em;text-align:center;margin:0;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.site-heading,.site-heading span{display:-webkit-box;display:-ms-flexbox;display:flex}.site-heading span{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;text-shadow:0 0 10px #fff,0 0 40px #6fc3df}.site-heading h1{font-size:200%;margin:.3em 0 .5em .5em;letter-spacing:0;font-weight:200}.site-heading img.logo{display:none}.controls{cursor:pointer;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-pack:distribute;justify-content:space-around;font-size:60%;text-transform:uppercase}.controls img{padding:1em;border-radius:1em;background-color:transparent;height:30px}.controls>div>.active,.controls>div>:active{background-color:#6fc3df;transition:color .1s ease-in-out}.problem-group{display:block;margin:.7em 0;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.problem{display:block;margin:1em}.code-and-tests{vertical-align:top;display:block}.code{font-size:80%;color:#f8f8f2;color:#fff;overflow-x:auto;padding:.5em;background:#23241f;background:#1a1a1a;border-radius:3px;padding:.25em .65em}.code,.test-area{display:inline-block;width:100%}.test-area{vertical-align:top}.test-suite{font-size:60%}.test{display:block;margin:.7em 0}.test-state{display:inline-block;transition:all .2s ease-in-out}.test-state.pass{color:#6fc3df}.test-state.fail{color:#df740c}.test-name{display:inline-block}.test-total{background-color:gray;color:#fff;text-align:center;padding:.5em;transition:all .2s ease-in-out}.test-total.working{background:url(/dist/img/reload.svg)}.test-total.pass{background-color:#6fc3df}.test-total.fail{background-color:#df740c}.console{font-size:70%;margin:.5em 0;vertical-align:top}.console>h4{text-align:center}.ads-bottom{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin:5em 0 1em}footer{margin:0 auto;text-align:center;left:0;bottom:0;height:70px;width:100%;font-size:60%}footer>div{margin:.4em auto}@media (min-width:760px){.container{width:92%;margin:0 auto;display:-webkit-box;display:-ms-flexbox;display:flex}.left-spacer{-webkit-box-flex:0.5;-ms-flex:0.5;flex:0.5}main{-webkit-box-flex:30;-ms-flex:30;flex:30}.site-heading .container{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.site-heading>.container>h1{font-size:200%}.site-heading img.logo{height:60px;display:-webkit-box;display:-ms-flexbox;display:flex}.problem-name{display:block}.problem-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.problem{display:block;margin-right:.6em}.code-and-tests{display:-webkit-box;display:-ms-flexbox;display:flex}.test-area{width:30%}.code-and-eval-console{width:70%}} \ No newline at end of file diff --git a/public/dist/img/social-banner.png b/public/dist/img/social-banner.png index a665cc0642ea7b9720794f509041507c865ee559..e6c0d5d5ff2803eb318e633a00c8ce5ec8f13483 100644 GIT binary patch delta 28240 zcmV(;K-<6c;Q_qi0kACte|kwoK~#7F?9{~pLop0MvBdii-D~+{SQ_CO5~BeC00000 z@|)Bp$Xn7C2wOg1; z+1I%59Y`8mX6jmaQ6AKpiI(CZ6hzM%Ks4I>^8cSY@kt>Rlq9nze|Po`J2y8E#@4ZJ zW*qG8F%de~N4q&~8z@%fx=!rhyYys#pENtupIs z)B%b*&qgD~HdDTPRiuKm8)7^nHI=gfB(d0sn#iSO^{!j1u|Lv zO9&F8#Q@k@w2yi{2u=nyJ57VAWR*f@YZr_M$bx2dt(xKKn|`ksY`k+i9a>_Bn-!*d zn%tNp*iW%KSnBm$ak-p8p?12$QR$}So`j{0U>q4*e;`|Bxw=>Jk|NMyu#l){0VRvb z#7Jd9oHeG*{ z=PiRZ&SkE^as@@Rudm*SQ)WrA^(IB4<4m2afoNIbrjqRj+s*YIP_?JGnN+L+TSZhn zwKz=Ne^M67q+0>qiQf~|T* zqhDX&AV>T4_4WKQQzrX56FX+9gX|PN!lW(pQiEb&WwRl$>zLuseDZj_Rn56FlOdx0 z$((s8H;w~Q@N)Dii-zPVYS%eu`~N@e<_#Lq6ty|`2GS@NOg=P*qf#)289TxnR9J*1 ze?2i0n~qWqGFN30Dk%F8Kd)1-gg)S=txjeF8icnx%d08y0}1tzRjcIbR#k7&S>6vbh%B9}&P397N{GHVQB5e6kv z$}IrCN?0*MSf{?fkQrsyUSEH9-|N**f8rOo+6gkxmL`R~Zje&SOUNuMWsM)s*iMD5 zzD@yJHf9(8tvbzQqz6eZ|-$NL6rue=q=Y zMA?qBKa8+{h&5lgwx$5vGp7NR?G&HO*&jOPQ3kl_Q}$q-0vk0&e?ZxfH+E-tZ~qIhx4XlH>pelIz-C<~>>{u&ByHO^ zqHQf{on~eAUx{~EiN+}_sL`(S63Jkt!gzEj+T&0Ug?|>0{NbQ1RfE^J=o@eH6}Ty9 zXs|_ugmv&W<9nwlo(tJnESJj}zAg;;Di%#aIU=*$Twh@*8^Kq8ia~VieVR;3dRxH7Ru>V z*^e;xgt1U`^E{gl?@AERC^2T=*(D#Iwyz3|h#09rAH0B&_Ih%;RHG zV#HXZ+seMbz#e>YUUf_Cy0FUg>gwt`b0cnV{QTU)J-fIl${uB7?VlT~7+k90oUt+P z35_w(V?Yp>nBUC{fBDK*dtzb8*j_J`-)t&M^&ET)#!}y9tU($4ErYMw*y8IHUyWs6 zXja@;w#=trfG#4cDF$W)jct#N;U@4`}6RSV88A08ebA9s}MKAcgd!w!IFGB|ji}600fw5DL7-q;=BYycgKv&~$I-;qw^`EoUGdT#`gqqb$kP9lp z8l@`#&#D>yf2M6kVZ5sLxb&@+qLNBw(gs;zij8G#8=66a8z8tY2_8ukNJ*BJr0d$I z|Np-4oO>BUlbQ#965ys_?9ab@?zv9%6UG08#aSS$0*Rn2Wp%e=q}m8TjA&tPWoM_( zTnnW#u*&L*Sr2VN<#%y|5BiEr5^9-7bhfe6 zPB?$UO<5GFSc@9GgBYW&8=Gi7PDZP5#` z{M%0|e~ahE`Vdw>k;c6aqIwoQFuLgJ^ zWuYXL74cR_6qnm-teuq}8y;fpYh5nAc(f*7f5;;4@b&*0yCQ5rSG&Ds`rU53-8zD^ zgEYaF?NC`hBLr-SvtpdqNsexysqw0_W)xQ_*DPKcnbJ~F3b_%5N%96HX(fy3Y>kMj zx_^1L^#MbIEbev!H5SlVan`OYbV;wqQUdr2Spk~$s1C}MMTa4akt(}Xb#?4fOr0&X zf7q+9L^QWb;Ea$`Bsn!pzcR(I& z?6wHIxAkakZ2duF54Yi~vRqVjSBt=^^)C2vw2Ukfg1RXr0D9I5fUt#OO_Z{>iP&S9iHDZLVEvkse zRW=Hv-aN9#S~i3q35*5$>j7QQtFe&%xs*NvXS0sZ8-kQCoQnvkC9TNGmDmOcf6qo@ zb%~OTvDGU4vBDAvi~5SmtJ^(38NEZQ=iu}mvOT7=fx8Q3Gn}kZ){Yum41N-0i~2PR zLrcs)QGw=-^`ye*2sDTY(9M= z&aT`r_@1$QH1^`rTDdp`e}BT*l@hxmEPS0bFK=#c{!(tp<+M3DACHcQXN{vP$A_|S z=+`*;H2le22>FN*EjFR)e&jn833N8}~Mm6=s@Qe`D)aB~%M!n#Zv7 z0EAthE!gwWCH9Dm4@o`CGZ;&LtH4*(*W=OXbOKqK?tDIHzL(AG^V3nU+iu0~ZYm$? z2zGdbP+awLPcSYbxYQZI*FcC}T$r7zMcZ4HS%6DobOj ztQrd*WUQ=|w%2Rye>RQ%b)}27J;8GrYlNLNVe9;s+}-i{$a^KtK=&u3pm zS$3H-g<}=DsItsT<+6>b&@r%QYRfaM1{bP zRX)$8auUTii zEjC>U6Ut^u#J&_+X^!#@L|#H6&t?M$6Hy>heSxy9vQ>-78`+|eCkd*87K0<`9bdT+ z7hsj$-R}Ynf7vZ6i?D1fOCD(K&t%{{Gvy zf0;Gw=Ekusihqh_#^Izksrf9V3Vzzk|Zi@Zn}g;?r2sO_U< z6Sjd&KwRZ8j`9gWM`eL6bt#!mo(Dd?Okm?KVLh*U~_F^rBm@-)Z>>mW_z!z(*>XL5uZgk zNwp))e@Y?1^5$=^jK=DKZ zb&8yR8q5M&l(GoZx>ELsLu^zOY_!;PpH->Nf6Tu5)?06j-g)P(cV=gx7bka&zWd%l z6<*-$9+=Iw^#-Vwyhxfm)`;Z-c}pu?uSE&OJ#G?k29kFyUop_VK-W`PH|wU}%m;Z> z_kI8U5B}I_G!nLx&1&?B_Qs>x4oJzOMvxUnmyg5KFbkUnvWbimi*@2R3>NiTM{81V3$g5_G>E`@;FXcW z==Nx`a9RA82S7+g@+++qz$)<|fiOcUe||sX1^KP1bfK@WGC65s#EQ%Q@@E{`8;FIz zYhuCcMq&XhvJdM=_?n8i(qmGV|DXt75n)o#bjvA_H(!OFcBhWo5i zpOMPbWOG1`%A#MP$y_4itv$|wOdDy6^S=;F(HC>MPW(m{C1WwfBiUsKx=Ud94~JnA8}-mc!~kBXtBu!b%pz zasivv)(hdnQ4rW>ieaV*ZN91dTxeTgh2hasACSfR3yUw#ML!&3W&i(M#r_g2W?Jk( zefU`TfAp^}-<&=!Hj9eOZ+aPo#}=VPpb1hrh|4FHH}t_6*A}m&iD|?ie>i782|EUU z62Kyzh4P$bS^fR<^993j7tjFuBlfyzG@5~e?;}wFA(l*Pf)a%!v?gEt<=E|vsg!hT z(2wtc)-Er!8n<#C1IY3viRHY4jMc+%sbVdcVX`nP9$tHaf;%~roa{!pjUeI;Q*$wiVzlGcD2g?8f?Qi42hJhn?W2#LeN#mQ5^_h;xmjpTnkPraZgVd z=I2V)s>KFH+Hliup-?XM^nln47LeTrlil)aL@e|}BevZrSZA?)e?7I~$z$Qk#l?$@ z&?V}trPF6FGsHV*CU%UzH(s5aH{51`ImPpW081lVak?~05*0_S1mOWjtkR@jj%G>3 zEbBP7bOBJQI&tKa2}L$_V}5yX{L0m<15?%Ia=BcD%5$%u`=E$DArER6sl(a~8|5t{ z*?@n6Ss;HtWqJxWTq%C@@Qj+9|~H`d9DVxN#G@bzvW4`^ByiMAn)sqymf>e?{e~W+23h=wmiRAO%;I z+jn@PsQ1kVfGrw~RKfKdCc}#F<8x$%_g;XFc%IE|(qUl?gHx5?T)i|tRV|g#2`
@PtqkZm*Dx{UCB5xd&k+E~S|76tX;7mtOv?|eNwduP|J8#fO_ zH*egyweu`yf1YpdqB5wB4=%%IQEoO_@i&`6# z&$IBt4+F>+_%cn`DBqi^)%S(x>ic((-?#ejt&~?DJa}MXKOi;`LT&umOL$m|nL&Ug zfGjlzVav!TdJL^559Uce;A%a9hS9QzAQu=`uf0j1e;;o=_qVJ9i!Gvb9|5uT4|}XK zki}R`;2`s61CsOb2(3^XivgM>T#m%Dv-bwQKO2+x>21UbCu!=035&-(6qrqv1P}Vh z_XF5V55w@(SGUM3g8K;fyU6URJtJea!R2{F4?HDfXK-aKZzfELt5JvIo|8$(cH(v* zL2mk(e~XI62j%j-Ra{sw{KjL648|FL7qs&b@F`Le0NDAtL3ApfglEvS9Jl&QCCqGt zSZePK!%G~oX;iYWY(awy`T-HUu^B7CN;7tAs?Vwojm&%!-u`+P#NN7b`03rdGk3x4 ztzCBx+z!JNcc*uZ);|QYWlY_!Yw(`akq2Q&e+Nvn@ACuK$Dn6*AICJ8#Gm3I4=9}Y zGgsuB`2cDz%+KAQs*MdVh37^_->rZ6tXjP{ckkZ473RWdG|09GB}{BNQVJ+^(@#`P zpJ?$Y?D1@EG*Vo>rBditZQ7(LWEQJ2biL$%`Ph-7a4%i{=l-TDo3<57J+=Bo7#wwiYL@u7{W*~Vkp79^ z`s4q|@A>Ea=A13>lUC~}ZuIx08BZ?OnCw!i zKewKIYPGS77Bt0tL0Em-vYzS2oH!Aaz(qU(b-md1Fn!f2yWs zZ%Bxp*AQ91EMTieMD`dGd$YuT2x6ruSV$Hj)&~}+nwexKV>UNHcJ;RpT0eWPn_>O6 z*$b=Ha=Fs!C{lL9Y@S%o=fA$Vln4;>9R=&mkaU)aZ!#5g`ssT<^KFO=1mq)3Q392z zsf1Xi+D<#MqzSRzt-gUPd+C8Xe`vMJWu=0{^IV-tlBHQiM)NBWkaj#>W4b+(BtIdO z#94@$v5j}CWP=iY_csvaDBu6l=O6F>OF!$qG&tFeoV+)9Vt&Dd*vLF8BNflml8;-h zR#RxE)&P(HTFN8#q-hMfB^tg=p+dLgTT-luv73ylf!E?RMR;wtR-2tIf6JpzuLYD! zc@VeV?XB)Z)|1aQ$X@kk*UX5SKDFm8>z5E4DiflUi79BSR4U>qB$Ou-YQ>NDAe2`< zF$1fea=E2q;;LGU2VFx3a2QX|xEZ`$t95FfN+96VA3#q%$4Ht#uzuJyQ&i4#>CaLU zu$d{u60z#NcTGSnTe4Sof4Gi6v0*Lp{-Uq3jYhp_W>SU`VR75+*4G=2fB)S2&rWd{ zriO)hy4_a81A!Jw*!LgB$6D6^eNYj_$(2&#j2dw{j7 zO{WvPV;GFk*>9EQdI+Y4Ckw`2i0@D>HD5!?oe`3{Yr7}G=IdM|N z2lf5>;uQDxTlLJ~EH-oZ)LmahXDJ)5B8$`tu^)lh@gCWyJ}O0lqH6PzCd5WTHm%MQ zXV6d!21B7xI)q7$q9B)v$-GdD3Ahxyl-9^QnL}z;0+#%N@C9JK6%6%yX)H|U1^ilT z5VrMEsr!^={d8ree{tdQqPf+N8d0Ov?`KRh*?+B{{oA$UYKuUg2?PS2YE@7ih=I*M&?hb3cCfe^nzII_z-(j`v72R&;zpjLH25kK@K?h$IX0XKP5ZR(+YVd zQm5jP-MhjG&Zg9A1V%cZvvb2Cj~b7YQUoYu+3^XkV?!*!UL*EXw-dWw zM_{u*p)Ia#A*Zq#=gryjJP*;#+QX(pplBQ_Fl9lEz|Wr5nJT>HVQJ5{-J`wkm6cQHtiQkT;=`-OmtG!mWj+!y zWwL4=6opyva*jTqm7(*DO{Y~Ll5)+@!od&)f7!TOugh786T&QQ9MtfmY;^%F$X;#8 z-%M;^mZBgf#F|ldMGGO41M_XWuHaj8X ze{ykNiWm-)ssSEHWn;RCLphMBqbnC!f03~u+uhqsMMZ6GQg}!LTa+bx5Hk)BOQn|& zOMIqlUR!di)MTL`%_qgroqiq59?2oM{zjOBV%KFAj{gDpP1*nt) z!pC(k$Jl))x0EUwqfu<$L4DX&oRNZ#Zy-qy-TJYC9z|(*R=Io1KVR}u|FrbAe@^Sw zM(TU$(6aENjE(HA`>V>Rly_+2LN?D`=XYJuq-1UNnqsf0h76X;qafz|$O8e0X?h?4ufRN&GslJ48rNh`r*}jW}76sun^7o#HNJUX|}hH zAF)2L*N7Eh?<97eIwu+%l5B!OBxjh7W;W_8%RiwtBw20s%9VP(+wJadex z^VZo@m*0JTOXdQYz0FOphk*ggz2EP%4s1RwL*>$AW`p25<~0(P(-7ve$w>%-R(7jq zIL5~^iG5p${l@qlpR|vqfA#;>k9~S#GN4{1_FU0S(jw8coFmAU_Dpt3E;LQv1Mon@ zbu{GC>mhg4l`P0Hzt$;N+imhRL>Fw$Jvtz)k~Fq2)OUCPN8On~HJPRhde*bezOQ|l zh1u8YKIit{XU^O)ssr>c6&(Xj+?6|uWO0@zq_L*PR+et|F3=%9LyLz(TY8F*K1X4UEbX)j}2<4<~$yM)xf~MeeJ4t z-@bhV1CpR;q9}425c}&td3D3akGH&Eq!a5ZLi3kz=IMf5^^vyy zJwvsf``gYWi#bq6ZG}_$fxNtn^)P#deCh{;Fo-Ig-tfCPKf_1z_Ha&f5Z`AHJY6k& zPh77ZYTvi#2FypjUf$z`TMHdfYB3V2_JtDO8Hjx}e~4g=ZaRuBHC!(*=*Jio1t4Ek z+}m=ZvqKHF51f4Lls85!0eGEpR#x_E4o$mQd5a(4x;Tn1ZOJ<`Gc|)Y@I0<;amQkA z%^mByn^)JWhB{B2N%}or-kYsnZ&W)Y8+~0J)c3ja_V)Wyl~Y_S#1=hAEXcm(#C}7F z{lPl1e|=7T_K|H6tGk_J_wo&HXTQB4MqW{HgpI z@4UzLnYA!0#&G>6{S4n~D8AjJ)}`n6cGN6+e;kT>|Lu3a{>pEY@y`;AP^}_KV~BkX zVmTK3A=WAO`Aoi?=mzJpgX)=d-1QNd_D6Z{b!tDlcJL~`<|jY<*#|%Soy(r zw5mN@SbD#3)Z+=a4XrQk+^uP>jk?^8A>VDK4%;K~U??^}H$5_(MHWtn!4|7yc(`8F zfBTHVP@MZjtxM=_Aw5yu3(kE)Df3EGu#oH}=%3%ftYv?{F`%`n{V)N~my|8=v zj8<%znaZD<#`1!>CV39GYIa{F^?T@&WGB1)ez!JZ&OK0ba?d3-wC7|^&4Ig*HUA{c zLhRh=)aWP*YCh`fT3>tQroOhx17KSU3by2Lg;&!hKKsets_w4ts=McE$%NWbf3qJ` z67?F$e)SbfL?Bi#VF6w#!THVq{^1YaSSPlx0c0_-`Dl4JF7LhjxFYv)O(pCeCrPDg zSnp?4?ZQ+6$X>bj>8GE3LID5D;5OdI-9(4BZ{;YTjK*p@cwgF%-R{14WY0eSz5hbW zp}AJH32U$yNFotSFe7Hc^vL))e^$ZZ@EGKd>A()lIb`z`oA>hfU*Gk(>O#ehlLP#Y zx(fDV&Nj(rl|ih%`MPR7v1fPH<3l%i8xkkfzJ%Ky3t4?_>QdZpx0CLvy>#YqcXQQ^ zN|v`C(X^FVqh|HpW}{CYS3M_Bvd=9QlcUdwy->7u^E+=rEH$zu2-k>3e_m!{-&iNs zAv$(At79Jwj*S!=+~#V#u~xO2l8cLr?doK5pX$sFq});4RDO9ufmnWBmO{9Sl}b4Pz?lnU2Xox+iBKS3veeX7qlUV=OksPl z&*`6xdL~74M5CVhXd=Pde@+-=t%LlgrfK@xUIWKCj<&&*aQC8M_gygS=}+Xsc{p1H zSqy_WaDeqTebs@k!^u}2c1n3<18<0tqXhpkpeDy8wFB>4ksZ+rZ_ z+zp|CNvSHn?1?1X)Zq3P`xEXI#D-ECYdUD(r7nfT;Tq1ju7GT`HI#|SD|FWy;tvSK zSB<5MU6<5}uEhnre-F!jRO0Q$u3tG~zwwmVch-nCqj0v)jt_$Dg9ld!c_Jnm)sJa}xFXV^Va-?u{F4(RvcU#Rmu{`P>J9>FsXRHofw1lg{;b_(~lx8-P z$Kci)w1%q7>Udb2NCzP{sT12|Vkak@Je{bU=b*7Rrm^$gfBM>ttZitJERnu8;_~w# z$;oM?>pLC?&1=L?@PBR$sq3YpWq-Qi`yUW6_&S9uPiv(C7J*pmQ$G4Q|0%H`i^b|{ z?of4QfdItvE#j!Gi#@92BL52d()(09tc~m>{&`k{S%ZT+3kq#ZwdzbF;pdNaVc+Zx zn9Vw|)hu4+fA8p73Yr6%OggxHmvDy8A7-h2vv0V^b*S=U1_r=`andy8{v7^!RYUpCf zYPM!F0ogu#i5;bT+2k`@ts!fl*?x-*rOy{i#a3d8l|+I}kE^0XJ@Ewsf$9==5@MSc zOCxrlf3p!z{f#__30aEr(AVrhaB!u zmk3xL-S*axP_p0ox|Hl?iG^LgZson7|Ll!ZA8pFtt`i$@Of&$1f2mV-Can+~0I_Ah zM#OlyRy~Q7MC^78$A3j)ZaRPG*qsMNi8rEQe<^QiQA1&;8?+iO4ypYdr#E`oC^1z%Qc#^)1ajm9JLv@CH; zkQ0*Q@<@Ncigw|s_i);KqAnLK+_ahle{p+wDJk(-Q+U;9MgzOG#tC^2L7s9tyB6&% zYdv0U3@>XNWUUnJk&UZ?ICz3ssfa?K_nEUPx*|%VbS3-V*RsS?ST4o3LhM&RLu}s! zD&6m@Q60?_yeCK+=vE`fva&o}rm)c%DG47`yEKlKk$SYO1oKCxY(=hiwGUebe`2*K zsy!0Y7YnjL6fQHhtJXz}&*uw(ER`_oQm%y!$)p-r5i16VhuuU zs~uz;iaGB`5NPzc9lYLr?3C#e31Z6@BFh0Mf8Y=b%0Miz zqmeAKmLp$VNq8l?IZY_X3+`>|U;s3$cU%}!?F*3-h;`^jgHwpzvEw|4g&}`4O7_)% z`^~RPfhoWWvBIkm`;#?dU0Gs7S_8z^smh6olr_N z<1x=n`3PAi;=~x99v2nWf4BQW6Pid zw?l)VAqdH4{AxFaFotv2wAr0V}=a+Pcc(aWVtM-BE-9M1ic*zN5bKSey1@@`(0#tgrto0UMV6Cq@zFKmKe=HbF?EQh1 zrkC(J`uZU@7xS`sJ4*J=*FO00J*x8o_Oryk`O&8L4LY&rzL2~trM2p|*4UUrteNz( z5Nk3e&#B|4Qd4P}v4TC&^aKFmQ-V==N)5a@K^8lm+GAC_f7FP`VqRN|-M9oswQ6r< zIhcXa#!T9BU`P*obi=F;Es7RRD~Uo|)a5Ym<^z1FSikN5w5~7sveQ#@(d%kYC>>lC zVnxMPhj34c7kUy}CTjp4Ez`={gn_ySR7;^|NR)EtPh)s!EH`8uQPI zi+pr=m{U-P_MFOdrL4=#t6}O2BCGL$hTg&d&4}jUe-v8?hm-nRfSsEfp{|SECW~ha zy@qqD(ie|J77waQQ|W@y9$X_<3yJ2n@7S-7(?hlCqc^|*!OuVZDwT(@`fI=T1;kbh zv1W+XD6eWwH$F$~YPgJVT&aeVNt3D67^zd|L;9;j5E{dCKDuH)s160pA&td(>QZBj zO_1fHe`7g0l8Z?^d)~x!3YFRz%A~vZ*DB=ruE$NHXj7V42T>0vxaP2?PpD3N7FhO) zG#5Jswo`L8s#7O6N8!nZEvQ%zX7HRRs)c+)EE+c1)Vo);sut72YC08VquJqEV2@>d zVt^kBM;6%6C30SuBGr8fa^YkyP_l+Bu@aA6e<${(_q>P|y!xZJ-`(<0ojV|wkgL%i zCt{!_*hg(b2ew09&J7zmRwTOBQ5K1ZR=fliC69`>nO{o!W3d#(@~8u82rR{bILtfQp+?F#wlruj+oD`ZY0bDbe3k4nM-$8PYA2i`mU>49(0P zg;?oarw`|=AJSg-9I*kN*htq>On^l)8T^?rC`jZ@U0CEZ79z)BH z)tbUvTrqV;8f6nOj#$hdESd0A_hTAGe+a@t=E_QA%Ia%6M!*=Uz14O&5@fB0Hwy9M zBvFqT41gmzjSW%@G^lUX>{Pg=C5#IiM#r8gi&Tf)Bo)MBh{h V^Pb3u0Ak4l35V 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 TsVb=600000NkvXXu0mjf6B{fm delta 28298 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,"expected #{this} to have a length above #{exp} but got #{act}","expected #{this} to not have a length above #{exp}",e,r)}else this.assert(n>e,"expected #{this} to be above "+e,"expected #{this} to be at most "+e)}function c(e,t){t&&P(this,"message",t);var n=P(this,"object");if(P(this,"doLength")){new N(n,t).to.have.property("length");var r=n.length;this.assert(r>=e,"expected #{this} to have a length at least #{exp} but got #{act}","expected #{this} to have a length below #{exp}",e,r)}else this.assert(n>=e,"expected #{this} to be at least "+e,"expected #{this} to be below "+e)}function f(e,t){t&&P(this,"message",t);var n=P(this,"object");if(P(this,"doLength")){new N(n,t).to.have.property("length");var r=n.length;this.assert(r1)throw new Error(i);break;case"object":if(arguments.length>1)throw new Error(i);e=Object.keys(e);break;default:e=Array.prototype.slice.call(arguments)}if(!e.length)throw new Error("keys required");var a=Object.keys(r),s=e,u=e.length,c=P(this,"any"),f=P(this,"all");if(c||f||(f=!0),c){o=s.filter(function(e){return~a.indexOf(e)}).length>0}if(f&&(o=e.every(function(e){return~a.indexOf(e)}),P(this,"negate")||P(this,"contains")||(o=o&&e.length==a.length)),u>1){e=e.map(function(e){return t.inspect(e)});var l=e.pop();f&&(n=e.join(", ")+", and "+l),c&&(n=e.join(", ")+", or "+l)}else n=t.inspect(e[0]);n=(u>1?"keys ":"key ")+n,n=(P(this,"contains")?"contain ":"have ")+n,this.assert(o,"expected #{this} to "+n,"expected #{this} to not "+n,s.slice(0).sort(),a.sort(),!0)}function m(e,n,r){r&&P(this,"message",r);var o=P(this,"object");new N(o,r).is.a("function");var i=!1,a=null,s=null,u=null;0===arguments.length?(n=null,e=null):e&&(e instanceof RegExp||"string"==typeof e)?(n=e,e=null):e&&e instanceof Error?(a=e,e=null,n=null):"function"==typeof e?(!(s=e.prototype.name)||"Error"===s&&e!==Error)&&(s=e.name||(new e).name):e=null;try{o()}catch(r){if(a)return this.assert(r===a,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp}",a instanceof Error?a.toString():a,r instanceof Error?r.toString():r),P(this,"object",r),this;if(e&&(this.assert(r instanceof e,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp} but #{act} was thrown",s,r instanceof Error?r.toString():r),!n))return P(this,"object",r),this;var c="error"===t.type(r)&&"message"in r?r.message:""+r;if(null!=c&&n&&n instanceof RegExp)return this.assert(n.exec(c),"expected #{this} to throw error matching #{exp} but got #{act}","expected #{this} to throw error not matching #{exp}",n,c),P(this,"object",r),this;if(null!=c&&n&&"string"==typeof n)return this.assert(~c.indexOf(n),"expected #{this} to throw error including #{exp} but got #{act}","expected #{this} to throw error not including #{act}",n,c),P(this,"object",r),this;i=!0,u=r}var f="",l=null!==s?s:a?"#{exp}":"an error";i&&(f=" but #{act} was thrown"),this.assert(!0===i,"expected #{this} to throw "+l+f,"expected #{this} to not throw "+l+f,a instanceof Error?a.toString():a,u instanceof Error?u.toString():u),P(this,"object",u)}function w(e,n){n&&P(this,"message",n);var r=P(this,"object"),o=P(this,"itself"),i="function"!==t.type(r)||o?r[e]:r.prototype[e];this.assert("function"==typeof i,"expected #{this} to respond to "+t.inspect(e),"expected #{this} to not respond to "+t.inspect(e))}function x(e,n){n&&P(this,"message",n);var r=P(this,"object"),o=e(r);this.assert(o,"expected #{this} to satisfy "+t.objDisplay(e),"expected #{this} to not satisfy"+t.objDisplay(e),!this.negate,o)}function E(e,n,r){r&&P(this,"message",r);var o=P(this,"object");if(new N(o,r).is.a("number"),"number"!==t.type(e)||"number"!==t.type(n))throw new Error("the arguments to closeTo or approximately must be numbers");this.assert(Math.abs(o-e)<=n,"expected #{this} to be close to "+e+" +/- "+n,"expected #{this} not to be close to "+e+" +/- "+n)}function j(e,t,n){return e.every(function(e){return n?t.some(function(t){return n(e,t)}):-1!==t.indexOf(e)})}function O(e,t){t&&P(this,"message",t);var n=P(this,"object");new N(e).to.be.an("array"),this.assert(e.indexOf(n)>-1,"expected #{this} to be one of #{exp}","expected #{this} to not be one of #{exp}",e,n)}function S(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(o!==e[t],"expected ."+t+" to change","expected ."+t+" to not change")}function A(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(e[t]-o>0,"expected ."+t+" to increase","expected ."+t+" to not increase")}function _(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(e[t]-o<0,"expected ."+t+" to decrease","expected ."+t+" to not decrease")}var N=e.Assertion,P=(Object.prototype.toString,t.flag);["to","be","been","is","and","has","have","with","that","which","at","of","same"].forEach(function(e){N.addProperty(e,function(){return this})}),N.addProperty("not",function(){P(this,"negate",!0)}),N.addProperty("deep",function(){P(this,"deep",!0)}),N.addProperty("any",function(){P(this,"any",!0),P(this,"all",!1)}),N.addProperty("all",function(){P(this,"all",!0),P(this,"any",!1)}),N.addChainableMethod("an",n),N.addChainableMethod("a",n),N.addChainableMethod("include",o,r),N.addChainableMethod("contain",o,r),N.addChainableMethod("contains",o,r),N.addChainableMethod("includes",o,r),N.addProperty("ok",function(){this.assert(P(this,"object"),"expected #{this} to be truthy","expected #{this} to be falsy")}),N.addProperty("true",function(){this.assert(!0===P(this,"object"),"expected #{this} to be true","expected #{this} to be false",!this.negate)}),N.addProperty("false",function(){this.assert(!1===P(this,"object"),"expected #{this} to be false","expected #{this} to be true",!!this.negate)}),N.addProperty("null",function(){this.assert(null===P(this,"object"),"expected #{this} to be null","expected #{this} not to be null")}),N.addProperty("undefined",function(){this.assert(void 0===P(this,"object"),"expected #{this} to be undefined","expected #{this} not to be undefined")}),N.addProperty("NaN",function(){this.assert(isNaN(P(this,"object")),"expected #{this} to be NaN","expected #{this} not to be NaN")}),N.addProperty("exist",function(){this.assert(null!=P(this,"object"),"expected #{this} to exist","expected #{this} to not exist")}),N.addProperty("empty",function(){var e=P(this,"object"),t=e;Array.isArray(e)||"string"==typeof object?t=e.length:"object"==typeof e&&(t=Object.keys(e).length),this.assert(!t,"expected #{this} to be empty","expected #{this} not to be empty")}),N.addProperty("arguments",i),N.addProperty("Arguments",i),N.addMethod("equal",a),N.addMethod("equals",a),N.addMethod("eq",a),N.addMethod("eql",s),N.addMethod("eqls",s),N.addMethod("above",u),N.addMethod("gt",u),N.addMethod("greaterThan",u),N.addMethod("least",c),N.addMethod("gte",c),N.addMethod("below",f),N.addMethod("lt",f),N.addMethod("lessThan",f),N.addMethod("most",l),N.addMethod("lte",l),N.addMethod("within",function(e,t,n){n&&P(this,"message",n);var r=P(this,"object"),o=e+".."+t;if(P(this,"doLength")){new N(r,n).to.have.property("length");var i=r.length;this.assert(i>=e&&i<=t,"expected #{this} to have a length within "+o,"expected #{this} to not have a length within "+o)}else this.assert(r>=e&&r<=t,"expected #{this} to be within "+o,"expected #{this} to not be within "+o)}),N.addMethod("instanceof",d),N.addMethod("instanceOf",d),N.addMethod("property",function(e,n,r){r&&P(this,"message",r);var o=!!P(this,"deep"),i=o?"deep property ":"property ",a=P(this,"negate"),s=P(this,"object"),u=o?t.getPathInfo(e,s):null,c=o?u.exists:t.hasProperty(e,s),f=o?u.value:s[e];if(a&&arguments.length>1){if(void 0===f)throw r=null!=r?r+": ":"",new Error(r+t.inspect(s)+" has no "+i+t.inspect(e))}else this.assert(c,"expected #{this} to have a "+i+t.inspect(e),"expected #{this} to not have "+i+t.inspect(e));arguments.length>1&&this.assert(n===f,"expected #{this} to have a "+i+t.inspect(e)+" of #{exp}, but got #{act}","expected #{this} to not have a "+i+t.inspect(e)+" of #{act}",n,f),P(this,"object",f)}),N.addMethod("ownProperty",h),N.addMethod("haveOwnProperty",h),N.addMethod("ownPropertyDescriptor",p),N.addMethod("haveOwnPropertyDescriptor",p),N.addChainableMethod("length",b,v),N.addMethod("lengthOf",b),N.addMethod("match",y),N.addMethod("matches",y),N.addMethod("string",function(e,n){n&&P(this,"message",n);var r=P(this,"object");new N(r,n).is.a("string"),this.assert(~r.indexOf(e),"expected #{this} to contain "+t.inspect(e),"expected #{this} to not contain "+t.inspect(e))}),N.addMethod("keys",g),N.addMethod("key",g),N.addMethod("throw",m),N.addMethod("throws",m),N.addMethod("Throw",m),N.addMethod("respondTo",w),N.addMethod("respondsTo",w),N.addProperty("itself",function(){P(this,"itself",!0)}),N.addMethod("satisfy",x),N.addMethod("satisfies",x),N.addMethod("closeTo",E),N.addMethod("approximately",E),N.addMethod("members",function(e,n){n&&P(this,"message",n);var r=P(this,"object");new N(r).to.be.an("array"),new N(e).to.be.an("array");var o=P(this,"deep")?t.eql:void 0;if(P(this,"contains"))return this.assert(j(e,r,o),"expected #{this} to be a superset of #{act}","expected #{this} to not be a superset of #{act}",r,e);this.assert(j(r,e,o)&&j(e,r,o),"expected #{this} to have the same members as #{act}","expected #{this} to not have the same members as #{act}",r,e)}),N.addMethod("oneOf",O),N.addChainableMethod("change",S),N.addChainableMethod("changes",S),N.addChainableMethod("increase",A),N.addChainableMethod("increases",A),N.addChainableMethod("decrease",_),N.addChainableMethod("decreases",_),N.addProperty("extensible",function(){var e,t=P(this,"object");try{e=Object.isExtensible(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!1}this.assert(e,"expected #{this} to be extensible","expected #{this} to not be extensible")}),N.addProperty("sealed",function(){var e,t=P(this,"object");try{e=Object.isSealed(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!0}this.assert(e,"expected #{this} to be sealed","expected #{this} to not be sealed")}),N.addProperty("frozen",function(){var e,t=P(this,"object");try{e=Object.isFrozen(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!0}this.assert(e,"expected #{this} to be frozen","expected #{this} to not be frozen")})}},{}],7:[function(e,t,n){t.exports=function(e,t){var n=e.Assertion,r=t.flag,o=e.assert=function(t,r){new n(null,null,e.assert).assert(t,r,"[ negation message unavailable ]")};o.fail=function(t,n,r,i){throw r=r||"assert.fail()",new e.AssertionError(r,{actual:t,expected:n,operator:i},o.fail)},o.isOk=function(e,t){new n(e,t).is.ok},o.isNotOk=function(e,t){new n(e,t).is.not.ok},o.equal=function(e,t,i){var a=new n(e,i,o.equal);a.assert(t==r(a,"object"),"expected #{this} to equal #{exp}","expected #{this} to not equal #{act}",t,e)},o.notEqual=function(e,t,i){var a=new n(e,i,o.notEqual);a.assert(t!=r(a,"object"),"expected #{this} to not equal #{exp}","expected #{this} to equal #{act}",t,e)},o.strictEqual=function(e,t,r){new n(e,r).to.equal(t)},o.notStrictEqual=function(e,t,r){new n(e,r).to.not.equal(t)},o.deepEqual=function(e,t,r){new n(e,r).to.eql(t)},o.notDeepEqual=function(e,t,r){new n(e,r).to.not.eql(t)},o.isAbove=function(e,t,r){new n(e,r).to.be.above(t)},o.isAtLeast=function(e,t,r){new n(e,r).to.be.least(t)},o.isBelow=function(e,t,r){new n(e,r).to.be.below(t)},o.isAtMost=function(e,t,r){new n(e,r).to.be.most(t)},o.isTrue=function(e,t){new n(e,t).is.true},o.isNotTrue=function(e,t){new n(e,t).to.not.equal(!0)},o.isFalse=function(e,t){new n(e,t).is.false},o.isNotFalse=function(e,t){new n(e,t).to.not.equal(!1)},o.isNull=function(e,t){new n(e,t).to.equal(null)},o.isNotNull=function(e,t){new n(e,t).to.not.equal(null)},o.isNaN=function(e,t){new n(e,t).to.be.NaN},o.isNotNaN=function(e,t){new n(e,t).not.to.be.NaN},o.isUndefined=function(e,t){new n(e,t).to.equal(void 0)},o.isDefined=function(e,t){new n(e,t).to.not.equal(void 0)},o.isFunction=function(e,t){new n(e,t).to.be.a("function")},o.isNotFunction=function(e,t){new n(e,t).to.not.be.a("function")},o.isObject=function(e,t){new n(e,t).to.be.a("object")},o.isNotObject=function(e,t){new n(e,t).to.not.be.a("object")},o.isArray=function(e,t){new n(e,t).to.be.an("array")},o.isNotArray=function(e,t){new n(e,t).to.not.be.an("array")},o.isString=function(e,t){new n(e,t).to.be.a("string")},o.isNotString=function(e,t){new n(e,t).to.not.be.a("string")},o.isNumber=function(e,t){new n(e,t).to.be.a("number")},o.isNotNumber=function(e,t){new n(e,t).to.not.be.a("number")},o.isBoolean=function(e,t){new n(e,t).to.be.a("boolean")},o.isNotBoolean=function(e,t){new n(e,t).to.not.be.a("boolean")},o.typeOf=function(e,t,r){new n(e,r).to.be.a(t)},o.notTypeOf=function(e,t,r){new n(e,r).to.not.be.a(t)},o.instanceOf=function(e,t,r){new n(e,r).to.be.instanceOf(t)},o.notInstanceOf=function(e,t,r){new n(e,r).to.not.be.instanceOf(t)},o.include=function(e,t,r){new n(e,r,o.include).include(t)},o.notInclude=function(e,t,r){new n(e,r,o.notInclude).not.include(t)},o.match=function(e,t,r){new n(e,r).to.match(t)},o.notMatch=function(e,t,r){new n(e,r).to.not.match(t)},o.property=function(e,t,r){new n(e,r).to.have.property(t)},o.notProperty=function(e,t,r){new n(e,r).to.not.have.property(t)},o.deepProperty=function(e,t,r){new n(e,r).to.have.deep.property(t)},o.notDeepProperty=function(e,t,r){new n(e,r).to.not.have.deep.property(t)},o.propertyVal=function(e,t,r,o){new n(e,o).to.have.property(t,r)},o.propertyNotVal=function(e,t,r,o){new n(e,o).to.not.have.property(t,r)},o.deepPropertyVal=function(e,t,r,o){new n(e,o).to.have.deep.property(t,r)},o.deepPropertyNotVal=function(e,t,r,o){new n(e,o).to.not.have.deep.property(t,r)},o.lengthOf=function(e,t,r){new n(e,r).to.have.length(t)},o.throws=function(e,t,o,i){("string"==typeof t||t instanceof RegExp)&&(o=t,t=null);var a=new n(e,i).to.throw(t,o);return r(a,"object")},o.doesNotThrow=function(e,t,r){"string"==typeof t&&(r=t,t=null),new n(e,r).to.not.Throw(t)},o.operator=function(e,o,i,a){var s;switch(o){case"==":s=e==i;break;case"===":s=e===i;break;case">":s=e>i;break;case">=":s=e>=i;break;case"<":s=e1&&n===t.length-1?"or ":"")+r+" "+e}).join(", ");if(!t.some(function(t){return i(e)===t}))throw new r("object tested must be "+n+", but "+i(e)+" given")}},{"./flag":14,"assertion-error":1,"type-detect":36}],14:[function(e,t,n){t.exports=function(e,t,n){var r=e.__flags||(e.__flags=Object.create(null));if(3!==arguments.length)return r[t];r[t]=n}},{}],15:[function(e,t,n){t.exports=function(e,t){return t.length>4?t[4]:e._obj}},{}],16:[function(e,t,n){t.exports=function(e){var t=[];for(var n in e)t.push(n);return t}},{}],17:[function(e,t,n){var r=e("./flag"),o=e("./getActual"),i=(e("./inspect"),e("./objDisplay"));t.exports=function(e,t){var n=r(e,"negate"),a=r(e,"object"),s=t[3],u=o(e,t),c=n?t[2]:t[1],f=r(e,"message");return"function"==typeof c&&(c=c()),c=c||"",c=c.replace(/#\{this\}/g,function(){return i(a)}).replace(/#\{act\}/g,function(){return i(u)}).replace(/#\{exp\}/g,function(){return i(s)}),f?f+": "+c:c}},{"./flag":14,"./getActual":15,"./inspect":24,"./objDisplay":25}],18:[function(e,t,n){t.exports=function(e){if(e.name)return e.name;var t=/^\s?function ([^(]*)\(/.exec(e);return t&&t[1]?t[1]:""}},{}],19:[function(e,t,n){function r(e){return e.replace(/([^\\])\[/g,"$1.[").match(/(\\\.|[^.]+?)+/g).map(function(e){var t=/^\[(\d+)\]$/,n=t.exec(e);return n?{i:parseFloat(n[1])}:{p:e.replace(/\\([.\[\]])/g,"$1")}})}function o(e,t,n){var r,o=t;n=void 0===n?e.length:n;for(var i=0,a=n;i1?o(n,t,n.length-1):t,name:a.p||a.i,value:o(n,t)};return s.exists=i(s.name,s.parent),s}},{"./hasProperty":22}],20:[function(e,t,n){var r=e("./getPathInfo");t.exports=function(e,t){return r(e,t).value}},{"./getPathInfo":19}],21:[function(e,t,n){t.exports=function(e){function t(e){-1===n.indexOf(e)&&n.push(e)}for(var n=Object.getOwnPropertyNames(e),r=Object.getPrototypeOf(e);null!==r;)Object.getOwnPropertyNames(r).forEach(t),r=Object.getPrototypeOf(r);return n}},{}],22:[function(e,t,n){var r=e("type-detect"),o={number:Number,string:String};t.exports=function(e,t){var n=r(t);return"null"!==n&&"undefined"!==n&&(o[n]&&"object"!=typeof t&&(t=new o[n](t)),e in t)}},{"type-detect":36}],23:[function(e,t,n){var n=t.exports={};n.test=e("./test"),n.type=e("type-detect"),n.expectTypes=e("./expectTypes"),n.getMessage=e("./getMessage"),n.getActual=e("./getActual"),n.inspect=e("./inspect"),n.objDisplay=e("./objDisplay"),n.flag=e("./flag"),n.transferFlags=e("./transferFlags"),n.eql=e("deep-eql"),n.getPathValue=e("./getPathValue"),n.getPathInfo=e("./getPathInfo"),n.hasProperty=e("./hasProperty"),n.getName=e("./getName"),n.addProperty=e("./addProperty"),n.addMethod=e("./addMethod"),n.overwriteProperty=e("./overwriteProperty"),n.overwriteMethod=e("./overwriteMethod"),n.addChainableMethod=e("./addChainableMethod"),n.overwriteChainableMethod=e("./overwriteChainableMethod")},{"./addChainableMethod":10,"./addMethod":11,"./addProperty":12,"./expectTypes":13,"./flag":14,"./getActual":15,"./getMessage":17,"./getName":18,"./getPathInfo":19,"./getPathValue":20,"./hasProperty":22,"./inspect":24,"./objDisplay":25,"./overwriteChainableMethod":26,"./overwriteMethod":27,"./overwriteProperty":28,"./test":29,"./transferFlags":30,"deep-eql":31,"type-detect":36}],24:[function(e,t,n){function r(e,t,n,r){return o({showHidden:t,seen:[],stylize:function(e){return e}},e,void 0===n?2:n)}function o(e,t,r){if(t&&"function"==typeof t.inspect&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var p=t.inspect(r);return"string"!=typeof p&&(p=o(e,p,r)),p}var m=i(e,t);if(m)return m;if(g(t)){if("outerHTML"in t)return t.outerHTML;try{if(document.xmlVersion){return(new XMLSerializer).serializeToString(t)}var w=document.createElementNS("http://www.w3.org/1999/xhtml","_");return w.appendChild(t.cloneNode(!1)),html=w.innerHTML.replace("><",">"+t.innerHTML+"<"),w.innerHTML="",html}catch(e){}}var x=y(t),E=e.showHidden?b(t):x;if(0===E.length||h(t)&&(1===E.length&&"stack"===E[0]||2===E.length&&"description"===E[0]&&"stack"===E[1])){if("function"==typeof t){var j=v(t),O=j?": "+j:"";return e.stylize("[Function"+O+"]","special")}if(l(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(d(t))return e.stylize(Date.prototype.toUTCString.call(t),"date");if(h(t))return a(t)}var S="",A=!1,_=["{","}"];if(f(t)&&(A=!0,_=["[","]"]),"function"==typeof t){var j=v(t),O=j?": "+j:"";S=" [Function"+O+"]"}if(l(t)&&(S=" "+RegExp.prototype.toString.call(t)),d(t)&&(S=" "+Date.prototype.toUTCString.call(t)),h(t))return a(t);if(0===E.length&&(!A||0==t.length))return _[0]+S+_[1];if(r<0)return l(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var N;return N=A?s(e,t,r,x,E):E.map(function(n){return u(e,t,r,x,n,A)}),e.seen.pop(),c(N,S,_)}function i(e,t){switch(typeof t){case"undefined":return e.stylize("undefined","undefined");case"string":var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string");case"number":return 0===t&&1/t==-1/0?e.stylize("-0","number"):e.stylize(""+t,"number");case"boolean":return e.stylize(""+t,"boolean")}if(null===t)return e.stylize("null","null")}function a(e){return"["+Error.prototype.toString.call(e)+"]"}function s(e,t,n,r,o){for(var i=[],a=0,s=t.length;a-1&&(u=a?u.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+u.split("\n").map(function(e){return" "+e}).join("\n"))):u=e.stylize("[Circular]","special")),void 0===s){if(a&&i.match(/^\d+$/))return u;s=JSON.stringify(""+i),s.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(s=s.substr(1,s.length-2),s=e.stylize(s,"name")):(s=s.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),s=e.stylize(s,"string"))}return s+": "+u}function c(e,t,n){var r=0;return e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.length+1},0)>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function f(e){return Array.isArray(e)||"object"==typeof e&&"[object Array]"===p(e)}function l(e){return"object"==typeof e&&"[object RegExp]"===p(e)}function d(e){return"object"==typeof e&&"[object Date]"===p(e)}function h(e){return"object"==typeof e&&"[object Error]"===p(e)}function p(e){return Object.prototype.toString.call(e)}var v=e("./getName"),b=e("./getProperties"),y=e("./getEnumerableProperties");t.exports=r;var g=function(e){return"object"==typeof HTMLElement?e instanceof HTMLElement:e&&"object"==typeof e&&1===e.nodeType&&"string"==typeof e.nodeName}},{"./getEnumerableProperties":16,"./getName":18,"./getProperties":21}],25:[function(e,t,n){var r=e("./inspect"),o=e("../config");t.exports=function(e){var t=r(e),n=Object.prototype.toString.call(e);if(o.truncateThreshold&&t.length>=o.truncateThreshold){if("[object Function]"===n)return e.name&&""!==e.name?"[Function: "+e.name+"]":"[Function]";if("[object Array]"===n)return"[ Array("+e.length+") ]";if("[object Object]"===n){var i=Object.keys(e);return"{ Object ("+(i.length>2?i.splice(0,2).join(", ")+", ...":i.join(", "))+") }"}return t}return t}},{"../config":5,"./inspect":24}],26:[function(e,t,n){t.exports=function(e,t,n,r){var o=e.__methods[t],i=o.chainingBehavior;o.chainingBehavior=function(){var e=r(i).call(this);return void 0===e?this:e};var a=o.method;o.method=function(){var e=n(a).apply(this,arguments);return void 0===e?this:e}}},{}],27:[function(e,t,n){t.exports=function(e,t,n){var r=e[t],o=function(){return this};r&&"function"==typeof r&&(o=r),e[t]=function(){var e=n(o).apply(this,arguments);return void 0===e?this:e}}},{}],28:[function(e,t,n){t.exports=function(e,t,n){var r=Object.getOwnPropertyDescriptor(e,t),o=function(){};r&&"function"==typeof r.get&&(o=r.get),Object.defineProperty(e,t,{get:function(){var e=n(o).call(this);return void 0===e?this:e},configurable:!0})}},{}],29:[function(e,t,n){var r=e("./flag");t.exports=function(e,t){var n=r(e,"negate"),o=t[0];return n?!o:o}},{"./flag":14}],30:[function(e,t,n){t.exports=function(e,t,n){var r=e.__flags||(e.__flags=Object.create(null));t.__flags||(t.__flags=Object.create(null)),n=3!==arguments.length||n;for(var o in r)(n||"object"!==o&&"ssfi"!==o&&"message"!=o)&&(t.__flags[o]=r[o])}},{}],31:[function(e,t,n){t.exports=e("./lib/eql")},{"./lib/eql":32}],32:[function(e,t,n){function r(e,t,n){return!!o(e,t)||("date"===v(e)?a(e,t):"regexp"===v(e)?s(e,t):p.isBuffer(e)?l(e,t):"arguments"===v(e)?u(e,t,n):!!i(e,t)&&("object"!==v(e)&&"object"!==v(t)&&"array"!==v(e)&&"array"!==v(t)?o(e,t):h(e,t,n)))}function o(e,t){return e===t?0!==e||1/e==1/t:e!==e&&t!==t}function i(e,t){return v(e)===v(t)}function a(e,t){return"date"===v(t)&&o(e.getTime(),t.getTime())}function s(e,t){return"regexp"===v(t)&&o(e.toString(),t.toString())}function u(e,t,n){return"arguments"===v(t)&&(e=[].slice.call(e),t=[].slice.call(t),r(e,t,n))}function c(e){var t=[];for(var n in e)t.push(n);return t}function f(e,t){if(e.length!==t.length)return!1;for(var n=0,r=!0;n=0;o--)if(s=i[o],!r(e[s],t[s],n))return!1;return!0}var p,v=e("type-detect");try{p=e("buffer").Buffer}catch(e){p={},p.isBuffer=function(){return!1}}t.exports=r},{buffer:void 0,"type-detect":33}],33:[function(e,t,n){t.exports=e("./lib/type")},{"./lib/type":34}],34:[function(e,t,n){function r(e){var t=Object.prototype.toString.call(e);return i[t]?i[t]:null===e?"null":void 0===e?"undefined":e===Object(e)?"object":typeof e}function o(){this.tests={}}var n=t.exports=r,i={"[object Array]":"array","[object RegExp]":"regexp","[object Function]":"function","[object Arguments]":"arguments","[object Date]":"date"};n.Library=o,o.prototype.of=r,o.prototype.define=function(e,t){return 1===arguments.length?this.tests[e]:(this.tests[e]=t,this)},o.prototype.test=function(e,t){if(t===r(e))return!0;var n=this.tests[t];if(n&&"regexp"===r(n))return n.test(e);if(n&&"function"===r(n))return n(e);throw new ReferenceError('Type test "'+t+'" not defined or invalid.')}},{}],35:[function(e,t,n){(function(r){!function(e){if("object"==typeof n&&void 0!==t)t.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var o;o="undefined"!=typeof window?window:void 0!==r?r:"undefined"!=typeof self?self:this,o.localforage=e()}}(function(){return function t(n,r,o){function i(s,u){if(!r[s]){if(!n[s]){var c="function"==typeof e&&e;if(!u&&c)return c(s,!0);if(a)return a(s,!0);var f=new Error("Cannot find module '"+s+"'");throw f.code="MODULE_NOT_FOUND",f}var l=r[s]={exports:{}};n[s][0].call(l.exports,function(e){var t=n[s][1][e];return i(t||e)},l,l.exports,t,n,r,o)}return r[s].exports}for(var a="function"==typeof e&&e,s=0;s=43)}}).catch(function(){return!1})}function c(e){return"boolean"==typeof re?ie.resolve(re):u(e).then(function(e){return re=e})}function f(e){var t=oe[e.name],n={};n.promise=new ie(function(e){n.resolve=e}),t.deferredOperations.push(n),t.dbReady?t.dbReady=t.dbReady.then(function(){return n.promise}):t.dbReady=n.promise}function l(e){var t=oe[e.name],n=t.deferredOperations.pop();n&&n.resolve()}function d(e,t){return new ie(function(n,r){if(e.db){if(!t)return n(e.db);f(e),e.db.close()}var o=[e.name];t&&o.push(e.version);var i=ne.open.apply(ne,o);t&&(i.onupgradeneeded=function(t){var n=i.result;try{n.createObjectStore(e.storeName),t.oldVersion<=1&&n.createObjectStore(ae)}catch(n){if("ConstraintError"!==n.name)throw n;console.warn('The database "'+e.name+'" has been upgraded from version '+t.oldVersion+" to version "+t.newVersion+', but the storage "'+e.storeName+'" already exists.')}}),i.onerror=function(e){e.preventDefault(),r(i.error)},i.onsuccess=function(){n(i.result),l(e)}})}function h(e){return d(e,!1)}function p(e){return d(e,!0)}function v(e,t){if(!e.db)return!0;var n=!e.db.objectStoreNames.contains(e.storeName),r=e.versione.db.version;if(r&&(e.version!==t&&console.warn('The database "'+e.name+"\" can't be downgraded from version "+e.db.version+" to version "+e.version+"."),e.version=e.db.version),o||n){if(n){var i=e.db.version+1;i>e.version&&(e.version=i)}return!0}return!1}function b(e){return new ie(function(t,n){var r=new FileReader;r.onerror=n,r.onloadend=function(n){var r=btoa(n.target.result||"");t({__local_forage_encoded_blob:!0,data:r,type:e.type})},r.readAsBinaryString(e)})}function y(e){return o([s(atob(e.data))],{type:e.type})}function g(e){return e&&e.__local_forage_encoded_blob}function m(e){var t=this,n=t._initReady().then(function(){var e=oe[t._dbInfo.name];if(e&&e.dbReady)return e.dbReady});return a(n,e,e),n}function w(e){function t(){return ie.resolve()}var n=this,r={db:null};if(e)for(var o in e)r[o]=e[o];oe||(oe={});var i=oe[r.name];i||(i={forages:[],db:null,dbReady:null,deferredOperations:[]},oe[r.name]=i),i.forages.push(n),n._initReady||(n._initReady=n.ready,n.ready=m);for(var a=[],s=0;s>4,f[u++]=(15&r)<<4|o>>2,f[u++]=(3&o)<<6|63&i;return c}function M(e){var t,n=new Uint8Array(e),r="";for(t=0;t>2],r+=ce[(3&n[t])<<4|n[t+1]>>4],r+=ce[(15&n[t+1])<<2|n[t+2]>>6],r+=ce[63&n[t+2]];return n.length%3==2?r=r.substring(0,r.length-1)+"=":n.length%3==1&&(r=r.substring(0,r.length-2)+"=="),r}function I(e,t){var n="";if(e&&(n=Ae.call(e)),e&&("[object ArrayBuffer]"===n||e.buffer&&"[object ArrayBuffer]"===Ae.call(e.buffer))){var r,o=de;e instanceof ArrayBuffer?(r=e,o+=pe):(r=e.buffer,"[object Int8Array]"===n?o+=be:"[object Uint8Array]"===n?o+=ye:"[object Uint8ClampedArray]"===n?o+=ge:"[object Int16Array]"===n?o+=me:"[object Uint16Array]"===n?o+=xe:"[object Int32Array]"===n?o+=we:"[object Uint32Array]"===n?o+=Ee:"[object Float32Array]"===n?o+=je:"[object Float64Array]"===n?o+=Oe:t(new Error("Failed to get type for BinaryArray"))),t(o+M(r))}else if("[object Blob]"===n){var i=new FileReader;i.onload=function(){var n=fe+e.type+"~"+M(this.result);t(de+ve+n)},i.readAsArrayBuffer(e)}else try{t(JSON.stringify(e))}catch(n){console.error("Couldn't convert value into a JSON string: ",e),t(null,n)}}function k(e){if(e.substring(0,he)!==de)return JSON.parse(e);var t,n=e.substring(Se),r=e.substring(he,Se);if(r===ve&&le.test(n)){var i=n.match(le);t=i[1],n=n.substring(i[0].length)}var a=P(n);switch(r){case pe:return a;case ve:return o([a],{type:t});case be:return new Int8Array(a);case ye:return new Uint8Array(a);case ge:return new Uint8ClampedArray(a);case me:return new Int16Array(a);case xe:return new Uint16Array(a);case we:return new Int32Array(a);case Ee:return new Uint32Array(a);case je:return new Float32Array(a);case Oe:return new Float64Array(a);default:throw new Error("Unkown type: "+r)}}function T(e){var t=this,n={db:null};if(e)for(var r in e)n[r]="string"!=typeof e[r]?e[r].toString():e[r];var o=new ie(function(e,r){try{n.db=openDatabase(n.name,String(n.version),n.description,n.size)}catch(e){return r(e)}n.db.transaction(function(o){o.executeSql("CREATE TABLE IF NOT EXISTS "+n.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){t._dbInfo=n,e()},function(e,t){r(t)})})});return n.serializer=_e,o}function C(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT * FROM "+o.storeName+" WHERE key = ? LIMIT 1",[e],function(e,n){var r=n.rows.length?n.rows.item(0).value:null;r&&(r=o.serializer.deserialize(r)),t(r)},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function R(e,t){var n=this,r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT * FROM "+o.storeName,[],function(n,r){for(var i=r.rows,a=i.length,s=0;s0)return void i(q.apply(o,[e,s,n,r-1]));a(t)}})})}).catch(a)});return i(a,n),a}function L(e,t,n){return q.apply(this,[e,t,n,1])}function D(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("DELETE FROM "+o.storeName+" WHERE key = ?",[e],function(){t()},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function B(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("DELETE FROM "+r.storeName,[],function(){e()},function(e,t){n(t)})})}).catch(n)});return i(n,e),n}function F(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("SELECT COUNT(key) as c FROM "+r.storeName,[],function(t,n){var r=n.rows.item(0).c;e(r)},function(e,t){n(t)})})}).catch(n)});return i(n,e),n}function z(e,t){var n=this,r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT key FROM "+o.storeName+" WHERE id = ? LIMIT 1",[e+1],function(e,n){var r=n.rows.length?n.rows.item(0).key:null;t(r)},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function U(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("SELECT key FROM "+r.storeName,[],function(t,n){for(var r=[],o=0;o=0;n--){var r=localStorage.key(n);0===r.indexOf(e)&&localStorage.removeItem(r)}});return i(n,e),n}function J(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=n.ready().then(function(){var t=n._dbInfo,r=localStorage.getItem(t.keyPrefix+e);return r&&(r=t.serializer.deserialize(r)),r});return i(r,t),r}function G(e,t){var n=this,r=n.ready().then(function(){for(var t=n._dbInfo,r=t.keyPrefix,o=r.length,i=localStorage.length,a=1,s=0;s=e.length-1||t<0?0:t+1}function getCurrentProblem(e){return e[config.currentIndex]}function previousProblem(){console.log("previousProblem!"),previousProblemButtonEl.classList.add("active"),config.currentIndex=config.shuffle?getRandomIndex(problems):getPreviousIndex(problems),updateLocalstore(config).then(function(){window.location.reload()})}function nextProblem(){console.log("nextProblem!"), -nextProblemButtonEl.classList.add("active"),config.currentIndex=config.shuffle?getRandomIndex(problems):getNextIndex(problems),updateLocalstore(config).then(function(){window.location.reload()})}function toggleShuffle(){console.log("toggle shuffle!"),config.shuffle=!config.shuffle,shuffleProblemsButtonEl.classList.toggle("active"),previousProblemButtonEl.parentNode.classList.toggle("hidden"),updateLocalstore(config)}function loadProblem(e){currentProblem=e,problemEl.innerText=e.prompt,e.given&&(codeEl.value=e.given),testSuite(null,!0)}function updateTests(e,t){!0===t&&buildTests(currentProblem.tests),updateTestStatus(e)}function buildTests(e){if(e){var t=e.map(function(e){return'
\n
[✘]
\n
'+e.name+"
\n
"}).join("");testSuiteEl.innerHTML=t}}function updateTestStatus(e){if(!e)throw new Error("No testStatuses provided.");var t=!0;e.forEach(function(e){!0!==e&&(t=!1)}),[].slice.call(testSuiteEl.querySelectorAll(".test-state")).forEach(function(t,n){!0===e[n]?(t.innerHTML="[✓]",t.classList.remove("fail"),t.classList.add("pass")):(t.innerHTML="[✘]",t.classList.remove("pass"),t.classList.add("fail"))}),!0===t?(testTotalEl.innerText="PASS",testTotalEl.classList.remove("fail"),testTotalEl.classList.add("pass")):(testTotalEl.innerText="FAIL",testTotalEl.classList.remove("pass"),testTotalEl.classList.add("fail"))}function printAssertError(e){var t="";null!==e&&(t='\n
\n Expected: '+JSON.stringify(e.expected)+"\n Actual: "+JSON.stringify(e.actual)+"\n
"),assertConsoleEl.innerHTML=t}function printEvalOutput(e,t){var n="";e&&void 0!==e.message?n='\n
\n Syntax Error: '+JSON.stringify(e.message)+"\n
":t&&(n='\n
\n Output: '+JSON.stringify(t)+"\n
"),evalConsoleEl.innerHTML=n}function testSuite(e){testTotalEl.classList.toggle("working");var t=getOutput(codeEl.value),n=runTests(t);testTotalEl.classList.toggle("working"),updateTests(n,e)}function getOutput(code){var evald=!1;try{evald=eval("(function(){"+code+"})()"),printEvalOutput(null,evald)}catch(e){printEvalOutput(e)}return evald}function runTests(e){return currentProblem.tests.map(function(t){var n=!1;try{e&&(n=t.test(e)),printAssertError(null)}catch(e){printAssertError(e)}return n})}function loadApp(e){function t(t){!1===e.shuffle&&13===t.keyCode&&t.shiftKey&&(t.metaKey||t.ctrlKey)?previousProblem():13!==t.keyCode||t.shiftKey||!t.metaKey&&!t.ctrlKey||nextProblem()}console.log("loading app!"),!0===e.shuffle&&(shuffleProblemsButtonEl.classList.add("active"),previousProblemButtonEl.parentNode.classList.add("hidden"));var n=debounce(function(e){-1===ignoreKeyCodes.indexOf(e.keyCode)&&testSuite()},200);codeEl.addEventListener("keydown",n),document.addEventListener("keydown",t),shuffleProblemsButtonEl.addEventListener("click",toggleShuffle),previousProblemButtonEl.addEventListener("click",previousProblem),nextProblemButtonEl.addEventListener("click",nextProblem),loadProblem(getCurrentProblem(problems)),testSuite(!0)}var localforage=require("localforage"),problems=require("../problems/arrays.js"),currentProblem=void 0,ignoreKeyCodes=[9,37,39,38,40],config={shuffle:!0,timer:!1,currentIndex:0};localforage.getItem("js_practice_config").then(function(e){e&&(config=e),loadApp(config)}).catch(function(e){console.log("localforage err:",e),loadApp(config)});var problemEl=document.getElementById("problem"),codeEl=document.getElementById("code"),testSuiteEl=document.getElementById("test-suite"),testTotalEl=document.getElementById("test-total"),evalConsoleEl=document.getElementById("eval-output"),assertConsoleEl=document.getElementById("assert-output"),shuffleProblemsButtonEl=document.getElementById("shuffle-problems"),previousProblemButtonEl=document.getElementById("prev-problem"),nextProblemButtonEl=document.getElementById("next-problem")}(document,window)},{"../problems/arrays.js":39,localforage:35}],39:[function(e,t,n){"use strict";var r=e("chai").assert;t.exports=[{name:"Create Array",time:10,prompt:"Create and return an array that contains 'apple' and 'banana'",given:"const fruits = [];\rreturn fruits;",answer:"const fruits = ['apple', 'banana'];\n return fruits;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["apple","banana"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 2 items",test:function(e){return void 0===r.lengthOf(e,2)}}]},{name:"Access Array by index (first)",time:10,prompt:"Return the first value of the Array",given:"const fruits = ['apple', 'banana'];\r",answer:"const fruits = ['apple', 'banana'];\n return fruits[0];",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,"apple")}},{name:"Returns a String",test:function(e){return void 0===r.isString(e)}}]},{name:"Access Array by index (last)",time:10,prompt:"Return the last value of the Array",given:"const fruits = ['apple', 'banana', 'orange'];\r",answer:"const fruits = ['apple', 'banana', 'orange'];\n return fruits[fruits.length - 1];",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,"orange")}},{name:"Returns a String",test:function(e){return void 0===r.isString(e)}}]},{name:"Access Array by index (second)",time:10,prompt:"Return the second value of the Array",given:"const fruits = ['apple', 'banana'];\r",answer:"const fruits = ['apple', 'banana'];\n return fruits[1];",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,"banana")}},{name:"Returns a String",test:function(e){return void 0===r.isString(e)}}]},{name:"Array.forEach()",time:20,prompt:"Loop over the array, add an 'x' to the end of each name, push each fruit into a new array, then return the new array.",given:"const fruits = ['apple', 'banana'];\r",answer:"const fruits = ['apple', 'banana'];\n const newFruits = [];\n fruits.forEach(function(item) {\n newFruits.push(item+'x');\n });\n return newFruits;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["applex","bananax"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 2 items",test:function(e){return void 0===r.lengthOf(e,2)}}]},{name:"Array.push()",time:10,prompt:"Add 'orange' to the end of the 'fruits' array and return 'fruits'.",given:"const fruits = ['apple', 'banana'];\r",answer:"const fruits = ['apple', 'banana'];\n fruits.push('orange');\n return fruits;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["apple","banana","orange"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 3 items",test:function(e){return void 0===r.lengthOf(e,3)}}]},{name:"Array.pop()",time:10,prompt:"Remove 'orange' from the end of the 'fruits' array and return 'fruits'.",given:"const fruits = ['apple', 'banana', 'orange'];\r",answer:"const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["apple","banana"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 2 items",test:function(e){return void 0===r.lengthOf(e,2)}}]},{name:"Array.shift()",time:10,prompt:"Remove 'apple' from the front of the 'fruits' array and return 'fruits'.",given:"const fruits = ['apple', 'banana', 'orange'];\r",answer:"const fruits = ['apple', 'banana', 'orange'];\n fruits.shift();\n return fruits;",tests:[{name:"Output must be correct",test:function(e){return void 0===r.deepEqual(e,["banana","orange"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 2 items",test:function(e){return void 0===r.lengthOf(e,2)}}]},{name:"Array.unshift()",time:10,prompt:"Add 'strawberry' to the front of the 'fruits' array and return 'fruits'.",given:"const fruits = ['apple', 'banana', 'orange'];\r",answer:"const fruits = ['apple', 'banana', 'orange'];\n fruits.unshift('strawberry');\n return fruits;",tests:[{name:"Output must be correct",test:function(e){return void 0===r.deepEqual(e,["strawberry","apple","banana","orange"])}},{name:"Must return an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 4 items",test:function(e){return void 0===r.lengthOf(e,4)}}]},{name:"Array.indexOf()",time:10,prompt:"Return the index of 'banana' in the Array.",given:"const fruits = ['strawberry', 'banana', 'mango'];\r",answer:"const fruits = ['strawberry', 'banana', 'mango'];\n const ind = fruits.indexOf('banana');\n return ind;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,1)}},{name:"Returns a Number",test:function(e){return void 0===r.isNumber(e)}}]},{name:"Array.concat()",time:10,prompt:"Merge the two arrays using Array's 'concat()' method. Return the resulting array.",given:"const fruits = ['strawberry', 'banana'];\rconst otherFruits = ['pear','peach'];\r",answer:"const fruits = ['strawberry', 'banana'];\n const otherFruits = ['pear','peach'];\n const allTheFruits = fruits.concat(otherFruits);\n return allTheFruits;\r",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["strawberry","banana","pear","peach"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 4 items",test:function(e){return void 0===r.lengthOf(e,4)}}]},{name:"Array.join()",time:10,prompt:"Mix the two flavors with a '-' using Array's 'join' method. Return the resulting hybrid flavor.",given:"const fruits = ['strawberry', 'banana'];\r",answer:"const fruits = ['strawberry', 'banana'];\n const hybrid = fruits.join('-');\n return hybrid;\r",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,"strawberry-banana")}},{name:"Returns a String",test:function(e){return void 0===r.isString(e)}}]},{name:"Array.slice()",time:20,prompt:"Return just the citrus fruits from the 'fruits' array using 'Array.slice()'",given:"const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\r",answer:"const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const citrus = fruits.slice(1, 3);\n return citrus;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["orange","lemon"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 2 items",test:function(e){return void 0===r.lengthOf(e,2)}}]},{name:"Array.reverse()",time:10,prompt:"Reverse the order of the 'fruit' array using 'Array.reverse()'",given:"const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\r",answer:"const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const stiurf = fruits.reverse();\n return stiurf;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["banana","lemon","orange","strawberry"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 4 items",test:function(e){return void 0===r.lengthOf(e,4)}},{name:"First item is 'banana'",test:function(e){return void 0===r.deepEqual(e[0],"banana")}}]},{name:"Array.sort()",time:10,prompt:"Sort the order of the 'fruit' array using 'Array.sort()'",given:"const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\r",answer:"const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const orderlyFruit = fruits.sort();\n return orderlyFruit;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,["banana","lemon","orange","strawberry"])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 4 items",test:function(e){return void 0===r.lengthOf(e,4)}},{name:"First item is 'banana'",test:function(e){return void 0===r.deepEqual(e[0],"banana")}}]},{name:"Array.lastIndexOf()",time:10,prompt:"Return the index of the last 'peach' instance in the 'fruit' array using 'Array.lastIndexOf()'",given:"const fruits = ['peach', 'orange', 'lemon', 'peach'];\r",answer:"const fruits = ['peach', 'orange', 'lemon', 'peach'];\n const wheresTheLastPeach = fruits.lastIndexOf('peach');\n return wheresTheLastPeach;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,3)}},{name:"Returns a Number",test:function(e){return void 0===r.isNumber(e)}}]},{name:"Array.filter()",time:10,prompt:"Return an array of the numbers greater than 5 in 'numbers' using 'Array.filter()'",given:"const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\r",answer:"const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\n const overFive = numbers.filter(num => num > 5);\n return overFive;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,[8,13,21])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 3 items",test:function(e){return void 0===r.lengthOf(e,3)}},{name:"First item is 8",test:function(e){return void 0===r.deepEqual(e[0],8)}}]},{name:"Array.map()",time:10,prompt:"Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'",given:"const numbers = [25, 121, 169];\r",answer:"const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,[5,11,13])}},{name:"Returns an Array",test:function(e){return void 0===r.isArray(e)}},{name:"Array has 3 items",test:function(e){return void 0===r.lengthOf(e,3)}},{name:"First item is 5",test:function(e){return void 0===r.deepEqual(e[0],5)}},{name:"Last item is 13",test:function(e){return void 0===r.deepEqual(e[e.length-1],13)}}]},{name:"Array.every()",time:10,prompt:"Return object that returns whether each array contains all even numbers using Array.every().",given:"\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 5, 6, 8];\nfunction isEven(element) {\n\n}\nreturn {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n};",answer:"\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 5, 6, 8];\nfunction isEven(element) {\n return element % 2 === 0\n}\nreturn {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n};",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,{evenNumbers:!0,someOddNumbers:!1})}},{name:"Returns an Object",test:function(e){return void 0===r.isObject(e)}},{name:"Object has 2 items",test:function(e){return void 0===r.lengthOf(Object.keys(e),2)}},{name:"First value is true",test:function(e){return void 0===r.isTrue(e.evenNumbers)}},{name:"Second value is false",test:function(e){return void 0===r.isFalse(e.someOddNumbers)}}]},{name:"Array.some()",time:10,prompt:"Return object that returns whether each array contains some odd numbers using Array.some().",given:"\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 4, 7, 8];\nfunction isOdd(element) {\n\n}\nreturn {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n};",answer:"\nconst evenNumbers = [1, 3, 5, 7];\nconst someOddNumbers = [1, 3, 6, 7];\nfunction isOdd(element) {\n return element % 2 !== 0;\n}\nreturn {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n};",tests:[{name:"Correct output",test:function(e){return void 0===r.deepEqual(e,{evenNumbers:!1,someOddNumbers:!0})}},{name:"Returns an Object",test:function(e){return void 0===r.isObject(e)}},{name:"Object has 2 items",test:function(e){return void 0===r.lengthOf(Object.keys(e),2)}},{name:"First value is false",test:function(e){return void 0===r.isFalse(e.evenNumbers)}},{name:"Second value is true",test:function(e){return void 0===r.isTrue(e.someOddNumbers)}}]}]},{chai:2}]},{},[38]); -======= -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o num > 5); - return overFive;`, - tests: [ - { - name: 'Correct output', - test: `assert.deepEqual(output, [8, 13, 21]) === undefined;` - }, - { - name: 'Returns an Array', - test: `assert.isArray(output) === undefined;` - }, - { - name: 'Array has 3 items', - test: `assert.lengthOf(output, 3) === undefined;` - }, - { - name: `First item is 8`, - test: `assert.deepEqual(output[0], 8) === undefined;` - } - ] - }, - { - name: 'Array.map()', - time: 10, - prompt: `Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`, - given: `const numbers = [25, 121, 169];\r`, - answer: `const numbers = [25, 121, 169]; - const roots = numbers.map(num => Math.sqrt(num)); - return roots;`, - tests: [ - { - name: 'Correct output', - test: `assert.deepEqual(output, [5, 11, 13]) === undefined;` - }, - { - name: 'Returns an Array', - test: `assert.isArray(output) === undefined;` - }, - { - name: 'Array has 3 items', - test: `assert.lengthOf(output, 3) === undefined;` - }, - { - name: `First item is 5`, - test: `assert.deepEqual(output[0], 5) === undefined;` - }, - { - name: `Last item is 13`, - test: `assert.deepEqual(output[output.length - 1], 13) === undefined;` - } - ] - }, - { - name: 'Array.every()', - time: 10, - prompt: `Return object that returns whether each array contains all even numbers using Array.every().`, - given: `const evenNumbers = [2, 4, 6, 8]; - const someOddNumbers = [2, 5, 6, 8]; - function isEven(element) { - - } - return { - evenNumbers: evenNumbers., - someOddNumbers: someOddNumbers. - };`, - answer: `const evenNumbers = [2, 4, 6, 8]; - const someOddNumbers = [2, 5, 6, 8]; - function isEven(element) { - return element % 2 === 0 - } - return { - evenNumbers: evenNumbers.every(isEven), - someOddNumbers: someOddNumbers.every(isEven) - };`, - tests: [ - { - name: 'Correct output', - test: `assert.deepEqual(output, { - evenNumbers: true, - someOddNumbers: false - }) === undefined;` - }, - { - name: 'Returns an Object', - test: `assert.isObject(output) === undefined;` - }, - { - name: 'Object has 2 items', - test: `assert.lengthOf(Object.keys(output), 2) === undefined;` - }, - { - name: `First value is true`, - test: `assert.isTrue(output.evenNumbers) === undefined;` - }, - { - name: `Second value is false`, - test: `assert.isFalse(output.someOddNumbers) === undefined;` - } - ] - }, - { - name: 'Array.some()', - time: 10, - prompt: `Return 'Object' that returns whether each array contains some odd numbers using 'Array.some()'.`, - given: `const evenNumbers = [2, 4, 6, 8]; - const someOddNumbers = [2, 4, 7, 8]; - function isOdd(element) { - - } - return { - evenNumbers: evenNumbers., - someOddNumbers: someOddNumbers. - };`, - answer: `const evenNumbers = [1, 3, 5, 7]; - const someOddNumbers = [1, 3, 6, 7]; - function isOdd(element) { - return element % 2 !== 0; - } - return { - evenNumbers: evenNumbers.some(isOdd), - someOddNumbers: someOddNumbers.some(isOdd) - };`, - tests: [ - { - name: 'Correct output', - test: `assert.deepEqual(output, { - evenNumbers: false, - someOddNumbers: true - }) === undefined;` - }, - { - name: 'Returns an Object', - test: `assert.isObject(output) === undefined;` - }, - { - name: 'Object has 2 items', - test: `assert.lengthOf(Object.keys(output), 2) === undefined;` - }, - { - name: `First value is false`, - test: `assert.isFalse(output.evenNumbers) === undefined;` - }, - { - name: `Second value is true`, - test: `assert.isTrue(output.someOddNumbers) === undefined;` - } - ] - } - // Next problems to create: - // forEach? fix one above that tried, but can't verify forEach was used - // some - // reduce - // reduceRight - // Array.from and other ways to turn array-like into array -]; - -},{}],3:[function(require,module,exports){ -module.exports = [ - { - name: 'Create Array', - time: 10, - prompt: 'Create and return an array that contains \'apple\' and \'banana\'', - given: `const fruits = [];\rreturn fruits;`, - answer: `const fruits = ['apple', 'banana']; - return fruits;`, - tests: [ - { - name: 'Correct output', - test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;` - }, - { - name: 'Returns an Array', - test: `assert.isArray(output) === undefined;` - }, - { - name: 'Array has 2 items', - test: `assert.lengthOf(output, 2) === undefined;` - } - ] - }, - { - name: 'Array.pop()', - time: 10, - prompt: `Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`, - given: `const fruits = ['apple', 'banana', 'orange'];\r`, - answer: `const fruits = ['apple', 'banana', 'orange']; - fruits.pop(); - return fruits;`, - tests: [ - { - name: 'Correct output', - test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;` - }, - { - name: 'Returns an Array', - test: `assert.isArray(output) === undefined;` - }, - { - name: 'Array has 2 items', - test: `assert.lengthOf(output, 2) === undefined;` - } - ] - }, -] - -},{}],4:[function(require,module,exports){ -/*! - * assertion-error - * Copyright(c) 2013 Jake Luer - * MIT Licensed - */ - -/*! - * Return a function that will copy properties from - * one object to another excluding any originally - * listed. Returned function will create a new `{}`. - * - * @param {String} excluded properties ... - * @return {Function} - */ - -function exclude () { - var excludes = [].slice.call(arguments); - - function excludeProps (res, obj) { - Object.keys(obj).forEach(function (key) { - if (!~excludes.indexOf(key)) res[key] = obj[key]; - }); - } - - return function extendExclude () { - var args = [].slice.call(arguments) - , i = 0 - , res = {}; - - for (; i < args.length; i++) { - excludeProps(res, args[i]); - } - - return res; - }; -}; - -/*! - * Primary Exports - */ - -module.exports = AssertionError; - -/** - * ### AssertionError - * - * An extension of the JavaScript `Error` constructor for - * assertion and validation scenarios. - * - * @param {String} message - * @param {Object} properties to include (optional) - * @param {callee} start stack function (optional) - */ - -function AssertionError (message, _props, ssf) { - var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON') - , props = extend(_props || {}); - - // default values - this.message = message || 'Unspecified AssertionError'; - this.showDiff = false; - - // copy from properties - for (var key in props) { - this[key] = props[key]; - } - - // capture stack trace - ssf = ssf || arguments.callee; - if (ssf && Error.captureStackTrace) { - Error.captureStackTrace(this, ssf); - } else { - try { - throw new Error(); - } catch(e) { - this.stack = e.stack; - } - } -} - -/*! - * Inherit from Error.prototype - */ - -AssertionError.prototype = Object.create(Error.prototype); - -/*! - * Statically set name - */ - -AssertionError.prototype.name = 'AssertionError'; - -/*! - * Ensure correct constructor - */ - -AssertionError.prototype.constructor = AssertionError; - -/** - * Allow errors to be converted to JSON for static transfer. - * - * @param {Boolean} include stack (default: `true`) - * @return {Object} object that can be `JSON.stringify` - */ - -AssertionError.prototype.toJSON = function (stack) { - var extend = exclude('constructor', 'toJSON', 'stack') - , props = extend({ name: this.name }, this); - - // include stack if exists and not turned off - if (false !== stack && this.stack) { - props.stack = this.stack; - } - - return props; -}; - -},{}],5:[function(require,module,exports){ -module.exports = require('./lib/chai'); - -},{"./lib/chai":6}],6:[function(require,module,exports){ -/*! - * chai - * Copyright(c) 2011-2014 Jake Luer - * MIT Licensed - */ - -var used = [] - , exports = module.exports = {}; - -/*! - * Chai version - */ - -exports.version = '3.5.0'; - -/*! - * Assertion Error - */ - -exports.AssertionError = require('assertion-error'); - -/*! - * Utils for plugins (not exported) - */ - -var util = require('./chai/utils'); - -/** - * # .use(function) - * - * Provides a way to extend the internals of Chai - * - * @param {Function} - * @returns {this} for chaining - * @api public - */ - -exports.use = function (fn) { - if (!~used.indexOf(fn)) { - fn(this, util); - used.push(fn); - } - - return this; -}; - -/*! - * Utility Functions - */ - -exports.util = util; - -/*! - * Configuration - */ - -var config = require('./chai/config'); -exports.config = config; - -/*! - * Primary `Assertion` prototype - */ - -var assertion = require('./chai/assertion'); -exports.use(assertion); - -/*! - * Core Assertions - */ - -var core = require('./chai/core/assertions'); -exports.use(core); - -/*! - * Expect interface - */ - -var expect = require('./chai/interface/expect'); -exports.use(expect); - -/*! - * Should interface - */ - -var should = require('./chai/interface/should'); -exports.use(should); - -/*! - * Assert interface - */ - -var assert = require('./chai/interface/assert'); -exports.use(assert); - -},{"./chai/assertion":7,"./chai/config":8,"./chai/core/assertions":9,"./chai/interface/assert":10,"./chai/interface/expect":11,"./chai/interface/should":12,"./chai/utils":26,"assertion-error":4}],7:[function(require,module,exports){ -/*! - * chai - * http://chaijs.com - * Copyright(c) 2011-2014 Jake Luer - * MIT Licensed - */ - -var config = require('./config'); - -module.exports = function (_chai, util) { - /*! - * Module dependencies. - */ - - var AssertionError = _chai.AssertionError - , flag = util.flag; - - /*! - * Module export. - */ - - _chai.Assertion = Assertion; - - /*! - * Assertion Constructor - * - * Creates object for chaining. - * - * @api private - */ - - function Assertion (obj, msg, stack) { - flag(this, 'ssfi', stack || arguments.callee); - flag(this, 'object', obj); - flag(this, 'message', msg); - } - - Object.defineProperty(Assertion, 'includeStack', { - get: function() { - console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); - return config.includeStack; - }, - set: function(value) { - console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); - config.includeStack = value; - } - }); - - Object.defineProperty(Assertion, 'showDiff', { - get: function() { - console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); - return config.showDiff; - }, - set: function(value) { - console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); - config.showDiff = value; - } - }); - - Assertion.addProperty = function (name, fn) { - util.addProperty(this.prototype, name, fn); - }; - - Assertion.addMethod = function (name, fn) { - util.addMethod(this.prototype, name, fn); - }; - - Assertion.addChainableMethod = function (name, fn, chainingBehavior) { - util.addChainableMethod(this.prototype, name, fn, chainingBehavior); - }; - - Assertion.overwriteProperty = function (name, fn) { - util.overwriteProperty(this.prototype, name, fn); - }; - - Assertion.overwriteMethod = function (name, fn) { - util.overwriteMethod(this.prototype, name, fn); - }; - - Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) { - util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); - }; - - /** - * ### .assert(expression, message, negateMessage, expected, actual, showDiff) - * - * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. - * - * @name assert - * @param {Philosophical} expression to be tested - * @param {String|Function} message or function that returns message to display if expression fails - * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails - * @param {Mixed} expected value (remember to check for negation) - * @param {Mixed} actual (optional) will default to `this.obj` - * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails - * @api private - */ - - Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) { - var ok = util.test(this, arguments); - if (true !== showDiff) showDiff = false; - if (true !== config.showDiff) showDiff = false; - - if (!ok) { - var msg = util.getMessage(this, arguments) - , actual = util.getActual(this, arguments); - throw new AssertionError(msg, { - actual: actual - , expected: expected - , showDiff: showDiff - }, (config.includeStack) ? this.assert : flag(this, 'ssfi')); - } - }; - - /*! - * ### ._obj - * - * Quick reference to stored `actual` value for plugin developers. - * - * @api private - */ - - Object.defineProperty(Assertion.prototype, '_obj', - { get: function () { - return flag(this, 'object'); - } - , set: function (val) { - flag(this, 'object', val); - } - }); -}; - -},{"./config":8}],8:[function(require,module,exports){ -module.exports = { - - /** - * ### config.includeStack - * - * User configurable property, influences whether stack trace - * is included in Assertion error message. Default of false - * suppresses stack trace in the error message. - * - * chai.config.includeStack = true; // enable stack on error - * - * @param {Boolean} - * @api public - */ - - includeStack: false, - - /** - * ### config.showDiff - * - * User configurable property, influences whether or not - * the `showDiff` flag should be included in the thrown - * AssertionErrors. `false` will always be `false`; `true` - * will be true when the assertion has requested a diff - * be shown. - * - * @param {Boolean} - * @api public - */ - - showDiff: true, - - /** - * ### config.truncateThreshold - * - * User configurable property, sets length threshold for actual and - * expected values in assertion errors. If this threshold is exceeded, for - * example for large data structures, the value is replaced with something - * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. - * - * Set it to zero if you want to disable truncating altogether. - * - * This is especially userful when doing assertions on arrays: having this - * set to a reasonable large value makes the failure messages readily - * inspectable. - * - * chai.config.truncateThreshold = 0; // disable truncating - * - * @param {Number} - * @api public - */ - - truncateThreshold: 40 - -}; - -},{}],9:[function(require,module,exports){ -/*! - * chai - * http://chaijs.com - * Copyright(c) 2011-2014 Jake Luer - * MIT Licensed - */ - -module.exports = function (chai, _) { - var Assertion = chai.Assertion - , toString = Object.prototype.toString - , flag = _.flag; - - /** - * ### Language Chains - * - * The following are provided as chainable getters to - * improve the readability of your assertions. They - * do not provide testing capabilities unless they - * have been overwritten by a plugin. - * - * **Chains** - * - * - to - * - be - * - been - * - is - * - that - * - which - * - and - * - has - * - have - * - with - * - at - * - of - * - same - * - * @name language chains - * @namespace BDD - * @api public - */ - - [ 'to', 'be', 'been' - , 'is', 'and', 'has', 'have' - , 'with', 'that', 'which', 'at' - , 'of', 'same' ].forEach(function (chain) { - Assertion.addProperty(chain, function () { - return this; - }); - }); - - /** - * ### .not - * - * Negates any of assertions following in the chain. - * - * expect(foo).to.not.equal('bar'); - * expect(goodFn).to.not.throw(Error); - * expect({ foo: 'baz' }).to.have.property('foo') - * .and.not.equal('bar'); - * - * @name not - * @namespace BDD - * @api public - */ - - Assertion.addProperty('not', function () { - flag(this, 'negate', true); - }); - - /** - * ### .deep - * - * Sets the `deep` flag, later used by the `equal` and - * `property` assertions. - * - * expect(foo).to.deep.equal({ bar: 'baz' }); - * expect({ foo: { bar: { baz: 'quux' } } }) - * .to.have.deep.property('foo.bar.baz', 'quux'); - * - * `.deep.property` special characters can be escaped - * by adding two slashes before the `.` or `[]`. - * - * var deepCss = { '.link': { '[target]': 42 }}; - * expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42); - * - * @name deep - * @namespace BDD - * @api public - */ - - Assertion.addProperty('deep', function () { - flag(this, 'deep', true); - }); - - /** - * ### .any - * - * Sets the `any` flag, (opposite of the `all` flag) - * later used in the `keys` assertion. - * - * expect(foo).to.have.any.keys('bar', 'baz'); - * - * @name any - * @namespace BDD - * @api public - */ - - Assertion.addProperty('any', function () { - flag(this, 'any', true); - flag(this, 'all', false) - }); - - - /** - * ### .all - * - * Sets the `all` flag (opposite of the `any` flag) - * later used by the `keys` assertion. - * - * expect(foo).to.have.all.keys('bar', 'baz'); - * - * @name all - * @namespace BDD - * @api public - */ - - Assertion.addProperty('all', function () { - flag(this, 'all', true); - flag(this, 'any', false); - }); - - /** - * ### .a(type) - * - * The `a` and `an` assertions are aliases that can be - * used either as language chains or to assert a value's - * type. - * - * // typeof - * expect('test').to.be.a('string'); - * expect({ foo: 'bar' }).to.be.an('object'); - * expect(null).to.be.a('null'); - * expect(undefined).to.be.an('undefined'); - * expect(new Error).to.be.an('error'); - * expect(new Promise).to.be.a('promise'); - * expect(new Float32Array()).to.be.a('float32array'); - * expect(Symbol()).to.be.a('symbol'); - * - * // es6 overrides - * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo'); - * - * // language chain - * expect(foo).to.be.an.instanceof(Foo); - * - * @name a - * @alias an - * @param {String} type - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function an (type, msg) { - if (msg) flag(this, 'message', msg); - type = type.toLowerCase(); - var obj = flag(this, 'object') - , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a '; - - this.assert( - type === _.type(obj) - , 'expected #{this} to be ' + article + type - , 'expected #{this} not to be ' + article + type - ); - } - - Assertion.addChainableMethod('an', an); - Assertion.addChainableMethod('a', an); - - /** - * ### .include(value) - * - * The `include` and `contain` assertions can be used as either property - * based language chains or as methods to assert the inclusion of an object - * in an array or a substring in a string. When used as language chains, - * they toggle the `contains` flag for the `keys` assertion. - * - * expect([1,2,3]).to.include(2); - * expect('foobar').to.contain('foo'); - * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo'); - * - * @name include - * @alias contain - * @alias includes - * @alias contains - * @param {Object|String|Number} obj - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function includeChainingBehavior () { - flag(this, 'contains', true); - } - - function include (val, msg) { - _.expectTypes(this, ['array', 'object', 'string']); - - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - var expected = false; - - if (_.type(obj) === 'array' && _.type(val) === 'object') { - for (var i in obj) { - if (_.eql(obj[i], val)) { - expected = true; - break; - } - } - } else if (_.type(val) === 'object') { - if (!flag(this, 'negate')) { - for (var k in val) new Assertion(obj).property(k, val[k]); - return; - } - var subset = {}; - for (var k in val) subset[k] = obj[k]; - expected = _.eql(subset, val); - } else { - expected = (obj != undefined) && ~obj.indexOf(val); - } - this.assert( - expected - , 'expected #{this} to include ' + _.inspect(val) - , 'expected #{this} to not include ' + _.inspect(val)); - } - - Assertion.addChainableMethod('include', include, includeChainingBehavior); - Assertion.addChainableMethod('contain', include, includeChainingBehavior); - Assertion.addChainableMethod('contains', include, includeChainingBehavior); - Assertion.addChainableMethod('includes', include, includeChainingBehavior); - - /** - * ### .ok - * - * Asserts that the target is truthy. - * - * expect('everything').to.be.ok; - * expect(1).to.be.ok; - * expect(false).to.not.be.ok; - * expect(undefined).to.not.be.ok; - * expect(null).to.not.be.ok; - * - * @name ok - * @namespace BDD - * @api public - */ - - Assertion.addProperty('ok', function () { - this.assert( - flag(this, 'object') - , 'expected #{this} to be truthy' - , 'expected #{this} to be falsy'); - }); - - /** - * ### .true - * - * Asserts that the target is `true`. - * - * expect(true).to.be.true; - * expect(1).to.not.be.true; - * - * @name true - * @namespace BDD - * @api public - */ - - Assertion.addProperty('true', function () { - this.assert( - true === flag(this, 'object') - , 'expected #{this} to be true' - , 'expected #{this} to be false' - , this.negate ? false : true - ); - }); - - /** - * ### .false - * - * Asserts that the target is `false`. - * - * expect(false).to.be.false; - * expect(0).to.not.be.false; - * - * @name false - * @namespace BDD - * @api public - */ - - Assertion.addProperty('false', function () { - this.assert( - false === flag(this, 'object') - , 'expected #{this} to be false' - , 'expected #{this} to be true' - , this.negate ? true : false - ); - }); - - /** - * ### .null - * - * Asserts that the target is `null`. - * - * expect(null).to.be.null; - * expect(undefined).to.not.be.null; - * - * @name null - * @namespace BDD - * @api public - */ - - Assertion.addProperty('null', function () { - this.assert( - null === flag(this, 'object') - , 'expected #{this} to be null' - , 'expected #{this} not to be null' - ); - }); - - /** - * ### .undefined - * - * Asserts that the target is `undefined`. - * - * expect(undefined).to.be.undefined; - * expect(null).to.not.be.undefined; - * - * @name undefined - * @namespace BDD - * @api public - */ - - Assertion.addProperty('undefined', function () { - this.assert( - undefined === flag(this, 'object') - , 'expected #{this} to be undefined' - , 'expected #{this} not to be undefined' - ); - }); - - /** - * ### .NaN - * Asserts that the target is `NaN`. - * - * expect('foo').to.be.NaN; - * expect(4).not.to.be.NaN; - * - * @name NaN - * @namespace BDD - * @api public - */ - - Assertion.addProperty('NaN', function () { - this.assert( - isNaN(flag(this, 'object')) - , 'expected #{this} to be NaN' - , 'expected #{this} not to be NaN' - ); - }); - - /** - * ### .exist - * - * Asserts that the target is neither `null` nor `undefined`. - * - * var foo = 'hi' - * , bar = null - * , baz; - * - * expect(foo).to.exist; - * expect(bar).to.not.exist; - * expect(baz).to.not.exist; - * - * @name exist - * @namespace BDD - * @api public - */ - - Assertion.addProperty('exist', function () { - this.assert( - null != flag(this, 'object') - , 'expected #{this} to exist' - , 'expected #{this} to not exist' - ); - }); - - - /** - * ### .empty - * - * Asserts that the target's length is `0`. For arrays and strings, it checks - * the `length` property. For objects, it gets the count of - * enumerable keys. - * - * expect([]).to.be.empty; - * expect('').to.be.empty; - * expect({}).to.be.empty; - * - * @name empty - * @namespace BDD - * @api public - */ - - Assertion.addProperty('empty', function () { - var obj = flag(this, 'object') - , expected = obj; - - if (Array.isArray(obj) || 'string' === typeof object) { - expected = obj.length; - } else if (typeof obj === 'object') { - expected = Object.keys(obj).length; - } - - this.assert( - !expected - , 'expected #{this} to be empty' - , 'expected #{this} not to be empty' - ); - }); - - /** - * ### .arguments - * - * Asserts that the target is an arguments object. - * - * function test () { - * expect(arguments).to.be.arguments; - * } - * - * @name arguments - * @alias Arguments - * @namespace BDD - * @api public - */ - - function checkArguments () { - var obj = flag(this, 'object') - , type = Object.prototype.toString.call(obj); - this.assert( - '[object Arguments]' === type - , 'expected #{this} to be arguments but got ' + type - , 'expected #{this} to not be arguments' - ); - } - - Assertion.addProperty('arguments', checkArguments); - Assertion.addProperty('Arguments', checkArguments); - - /** - * ### .equal(value) - * - * Asserts that the target is strictly equal (`===`) to `value`. - * Alternately, if the `deep` flag is set, asserts that - * the target is deeply equal to `value`. - * - * expect('hello').to.equal('hello'); - * expect(42).to.equal(42); - * expect(1).to.not.equal(true); - * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' }); - * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' }); - * - * @name equal - * @alias equals - * @alias eq - * @alias deep.equal - * @param {Mixed} value - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function assertEqual (val, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - if (flag(this, 'deep')) { - return this.eql(val); - } else { - this.assert( - val === obj - , 'expected #{this} to equal #{exp}' - , 'expected #{this} to not equal #{exp}' - , val - , this._obj - , true - ); - } - } - - Assertion.addMethod('equal', assertEqual); - Assertion.addMethod('equals', assertEqual); - Assertion.addMethod('eq', assertEqual); - - /** - * ### .eql(value) - * - * Asserts that the target is deeply equal to `value`. - * - * expect({ foo: 'bar' }).to.eql({ foo: 'bar' }); - * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]); - * - * @name eql - * @alias eqls - * @param {Mixed} value - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function assertEql(obj, msg) { - if (msg) flag(this, 'message', msg); - this.assert( - _.eql(obj, flag(this, 'object')) - , 'expected #{this} to deeply equal #{exp}' - , 'expected #{this} to not deeply equal #{exp}' - , obj - , this._obj - , true - ); - } - - Assertion.addMethod('eql', assertEql); - Assertion.addMethod('eqls', assertEql); - - /** - * ### .above(value) - * - * Asserts that the target is greater than `value`. - * - * expect(10).to.be.above(5); - * - * Can also be used in conjunction with `length` to - * assert a minimum length. The benefit being a - * more informative error message than if the length - * was supplied directly. - * - * expect('foo').to.have.length.above(2); - * expect([ 1, 2, 3 ]).to.have.length.above(2); - * - * @name above - * @alias gt - * @alias greaterThan - * @param {Number} value - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function assertAbove (n, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - if (flag(this, 'doLength')) { - new Assertion(obj, msg).to.have.property('length'); - var len = obj.length; - this.assert( - len > n - , 'expected #{this} to have a length above #{exp} but got #{act}' - , 'expected #{this} to not have a length above #{exp}' - , n - , len - ); - } else { - this.assert( - obj > n - , 'expected #{this} to be above ' + n - , 'expected #{this} to be at most ' + n - ); - } - } - - Assertion.addMethod('above', assertAbove); - Assertion.addMethod('gt', assertAbove); - Assertion.addMethod('greaterThan', assertAbove); - - /** - * ### .least(value) - * - * Asserts that the target is greater than or equal to `value`. - * - * expect(10).to.be.at.least(10); - * - * Can also be used in conjunction with `length` to - * assert a minimum length. The benefit being a - * more informative error message than if the length - * was supplied directly. - * - * expect('foo').to.have.length.of.at.least(2); - * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3); - * - * @name least - * @alias gte - * @param {Number} value - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function assertLeast (n, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - if (flag(this, 'doLength')) { - new Assertion(obj, msg).to.have.property('length'); - var len = obj.length; - this.assert( - len >= n - , 'expected #{this} to have a length at least #{exp} but got #{act}' - , 'expected #{this} to have a length below #{exp}' - , n - , len - ); - } else { - this.assert( - obj >= n - , 'expected #{this} to be at least ' + n - , 'expected #{this} to be below ' + n - ); - } - } - - Assertion.addMethod('least', assertLeast); - Assertion.addMethod('gte', assertLeast); - - /** - * ### .below(value) - * - * Asserts that the target is less than `value`. - * - * expect(5).to.be.below(10); - * - * Can also be used in conjunction with `length` to - * assert a maximum length. The benefit being a - * more informative error message than if the length - * was supplied directly. - * - * expect('foo').to.have.length.below(4); - * expect([ 1, 2, 3 ]).to.have.length.below(4); - * - * @name below - * @alias lt - * @alias lessThan - * @param {Number} value - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function assertBelow (n, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - if (flag(this, 'doLength')) { - new Assertion(obj, msg).to.have.property('length'); - var len = obj.length; - this.assert( - len < n - , 'expected #{this} to have a length below #{exp} but got #{act}' - , 'expected #{this} to not have a length below #{exp}' - , n - , len - ); - } else { - this.assert( - obj < n - , 'expected #{this} to be below ' + n - , 'expected #{this} to be at least ' + n - ); - } - } - - Assertion.addMethod('below', assertBelow); - Assertion.addMethod('lt', assertBelow); - Assertion.addMethod('lessThan', assertBelow); - - /** - * ### .most(value) - * - * Asserts that the target is less than or equal to `value`. - * - * expect(5).to.be.at.most(5); - * - * Can also be used in conjunction with `length` to - * assert a maximum length. The benefit being a - * more informative error message than if the length - * was supplied directly. - * - * expect('foo').to.have.length.of.at.most(4); - * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3); - * - * @name most - * @alias lte - * @param {Number} value - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function assertMost (n, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - if (flag(this, 'doLength')) { - new Assertion(obj, msg).to.have.property('length'); - var len = obj.length; - this.assert( - len <= n - , 'expected #{this} to have a length at most #{exp} but got #{act}' - , 'expected #{this} to have a length above #{exp}' - , n - , len - ); - } else { - this.assert( - obj <= n - , 'expected #{this} to be at most ' + n - , 'expected #{this} to be above ' + n - ); - } - } - - Assertion.addMethod('most', assertMost); - Assertion.addMethod('lte', assertMost); - - /** - * ### .within(start, finish) - * - * Asserts that the target is within a range. - * - * expect(7).to.be.within(5,10); - * - * Can also be used in conjunction with `length` to - * assert a length range. The benefit being a - * more informative error message than if the length - * was supplied directly. - * - * expect('foo').to.have.length.within(2,4); - * expect([ 1, 2, 3 ]).to.have.length.within(2,4); - * - * @name within - * @param {Number} start lowerbound inclusive - * @param {Number} finish upperbound inclusive - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - Assertion.addMethod('within', function (start, finish, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object') - , range = start + '..' + finish; - if (flag(this, 'doLength')) { - new Assertion(obj, msg).to.have.property('length'); - var len = obj.length; - this.assert( - len >= start && len <= finish - , 'expected #{this} to have a length within ' + range - , 'expected #{this} to not have a length within ' + range - ); - } else { - this.assert( - obj >= start && obj <= finish - , 'expected #{this} to be within ' + range - , 'expected #{this} to not be within ' + range - ); - } - }); - - /** - * ### .instanceof(constructor) - * - * Asserts that the target is an instance of `constructor`. - * - * var Tea = function (name) { this.name = name; } - * , Chai = new Tea('chai'); - * - * expect(Chai).to.be.an.instanceof(Tea); - * expect([ 1, 2, 3 ]).to.be.instanceof(Array); - * - * @name instanceof - * @param {Constructor} constructor - * @param {String} message _optional_ - * @alias instanceOf - * @namespace BDD - * @api public - */ - - function assertInstanceOf (constructor, msg) { - if (msg) flag(this, 'message', msg); - var name = _.getName(constructor); - this.assert( - flag(this, 'object') instanceof constructor - , 'expected #{this} to be an instance of ' + name - , 'expected #{this} to not be an instance of ' + name - ); - }; - - Assertion.addMethod('instanceof', assertInstanceOf); - Assertion.addMethod('instanceOf', assertInstanceOf); - - /** - * ### .property(name, [value]) - * - * Asserts that the target has a property `name`, optionally asserting that - * the value of that property is strictly equal to `value`. - * If the `deep` flag is set, you can use dot- and bracket-notation for deep - * references into objects and arrays. - * - * // simple referencing - * var obj = { foo: 'bar' }; - * expect(obj).to.have.property('foo'); - * expect(obj).to.have.property('foo', 'bar'); - * - * // deep referencing - * var deepObj = { - * green: { tea: 'matcha' } - * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ] - * }; - * - * expect(deepObj).to.have.deep.property('green.tea', 'matcha'); - * expect(deepObj).to.have.deep.property('teas[1]', 'matcha'); - * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha'); - * - * You can also use an array as the starting point of a `deep.property` - * assertion, or traverse nested arrays. - * - * var arr = [ - * [ 'chai', 'matcha', 'konacha' ] - * , [ { tea: 'chai' } - * , { tea: 'matcha' } - * , { tea: 'konacha' } ] - * ]; - * - * expect(arr).to.have.deep.property('[0][1]', 'matcha'); - * expect(arr).to.have.deep.property('[1][2].tea', 'konacha'); - * - * Furthermore, `property` changes the subject of the assertion - * to be the value of that property from the original object. This - * permits for further chainable assertions on that property. - * - * expect(obj).to.have.property('foo') - * .that.is.a('string'); - * expect(deepObj).to.have.property('green') - * .that.is.an('object') - * .that.deep.equals({ tea: 'matcha' }); - * expect(deepObj).to.have.property('teas') - * .that.is.an('array') - * .with.deep.property('[2]') - * .that.deep.equals({ tea: 'konacha' }); - * - * Note that dots and bracket in `name` must be backslash-escaped when - * the `deep` flag is set, while they must NOT be escaped when the `deep` - * flag is not set. - * - * // simple referencing - * var css = { '.link[target]': 42 }; - * expect(css).to.have.property('.link[target]', 42); - * - * // deep referencing - * var deepCss = { '.link': { '[target]': 42 }}; - * expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42); - * - * @name property - * @alias deep.property - * @param {String} name - * @param {Mixed} value (optional) - * @param {String} message _optional_ - * @returns value of property for chaining - * @namespace BDD - * @api public - */ - - Assertion.addMethod('property', function (name, val, msg) { - if (msg) flag(this, 'message', msg); - - var isDeep = !!flag(this, 'deep') - , descriptor = isDeep ? 'deep property ' : 'property ' - , negate = flag(this, 'negate') - , obj = flag(this, 'object') - , pathInfo = isDeep ? _.getPathInfo(name, obj) : null - , hasProperty = isDeep - ? pathInfo.exists - : _.hasProperty(name, obj) - , value = isDeep - ? pathInfo.value - : obj[name]; - - if (negate && arguments.length > 1) { - if (undefined === value) { - msg = (msg != null) ? msg + ': ' : ''; - throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name)); - } - } else { - this.assert( - hasProperty - , 'expected #{this} to have a ' + descriptor + _.inspect(name) - , 'expected #{this} to not have ' + descriptor + _.inspect(name)); - } - - if (arguments.length > 1) { - this.assert( - val === value - , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}' - , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}' - , val - , value - ); - } - - flag(this, 'object', value); - }); - - - /** - * ### .ownProperty(name) - * - * Asserts that the target has an own property `name`. - * - * expect('test').to.have.ownProperty('length'); - * - * @name ownProperty - * @alias haveOwnProperty - * @param {String} name - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function assertOwnProperty (name, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - this.assert( - obj.hasOwnProperty(name) - , 'expected #{this} to have own property ' + _.inspect(name) - , 'expected #{this} to not have own property ' + _.inspect(name) - ); - } - - Assertion.addMethod('ownProperty', assertOwnProperty); - Assertion.addMethod('haveOwnProperty', assertOwnProperty); - - /** - * ### .ownPropertyDescriptor(name[, descriptor[, message]]) - * - * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`. - * - * expect('test').to.have.ownPropertyDescriptor('length'); - * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 }); - * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 }); - * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false); - * expect('test').ownPropertyDescriptor('length').to.have.keys('value'); - * - * @name ownPropertyDescriptor - * @alias haveOwnPropertyDescriptor - * @param {String} name - * @param {Object} descriptor _optional_ - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function assertOwnPropertyDescriptor (name, descriptor, msg) { - if (typeof descriptor === 'string') { - msg = descriptor; - descriptor = null; - } - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); - if (actualDescriptor && descriptor) { - this.assert( - _.eql(descriptor, actualDescriptor) - , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor) - , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor) - , descriptor - , actualDescriptor - , true - ); - } else { - this.assert( - actualDescriptor - , 'expected #{this} to have an own property descriptor for ' + _.inspect(name) - , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name) - ); - } - flag(this, 'object', actualDescriptor); - } - - Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor); - Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor); - - /** - * ### .length - * - * Sets the `doLength` flag later used as a chain precursor to a value - * comparison for the `length` property. - * - * expect('foo').to.have.length.above(2); - * expect([ 1, 2, 3 ]).to.have.length.above(2); - * expect('foo').to.have.length.below(4); - * expect([ 1, 2, 3 ]).to.have.length.below(4); - * expect('foo').to.have.length.within(2,4); - * expect([ 1, 2, 3 ]).to.have.length.within(2,4); - * - * *Deprecation notice:* Using `length` as an assertion will be deprecated - * in version 2.4.0 and removed in 3.0.0. Code using the old style of - * asserting for `length` property value using `length(value)` should be - * switched to use `lengthOf(value)` instead. - * - * @name length - * @namespace BDD - * @api public - */ - - /** - * ### .lengthOf(value[, message]) - * - * Asserts that the target's `length` property has - * the expected value. - * - * expect([ 1, 2, 3]).to.have.lengthOf(3); - * expect('foobar').to.have.lengthOf(6); - * - * @name lengthOf - * @param {Number} length - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function assertLengthChain () { - flag(this, 'doLength', true); - } - - function assertLength (n, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - new Assertion(obj, msg).to.have.property('length'); - var len = obj.length; - - this.assert( - len == n - , 'expected #{this} to have a length of #{exp} but got #{act}' - , 'expected #{this} to not have a length of #{act}' - , n - , len - ); - } - - Assertion.addChainableMethod('length', assertLength, assertLengthChain); - Assertion.addMethod('lengthOf', assertLength); - - /** - * ### .match(regexp) - * - * Asserts that the target matches a regular expression. - * - * expect('foobar').to.match(/^foo/); - * - * @name match - * @alias matches - * @param {RegExp} RegularExpression - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - function assertMatch(re, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - this.assert( - re.exec(obj) - , 'expected #{this} to match ' + re - , 'expected #{this} not to match ' + re - ); - } - - Assertion.addMethod('match', assertMatch); - Assertion.addMethod('matches', assertMatch); - - /** - * ### .string(string) - * - * Asserts that the string target contains another string. - * - * expect('foobar').to.have.string('bar'); - * - * @name string - * @param {String} string - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - Assertion.addMethod('string', function (str, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - new Assertion(obj, msg).is.a('string'); - - this.assert( - ~obj.indexOf(str) - , 'expected #{this} to contain ' + _.inspect(str) - , 'expected #{this} to not contain ' + _.inspect(str) - ); - }); - - - /** - * ### .keys(key1, [key2], [...]) - * - * Asserts that the target contains any or all of the passed-in keys. - * Use in combination with `any`, `all`, `contains`, or `have` will affect - * what will pass. - * - * When used in conjunction with `any`, at least one key that is passed - * in must exist in the target object. This is regardless whether or not - * the `have` or `contain` qualifiers are used. Note, either `any` or `all` - * should be used in the assertion. If neither are used, the assertion is - * defaulted to `all`. - * - * When both `all` and `contain` are used, the target object must have at - * least all of the passed-in keys but may have more keys not listed. - * - * When both `all` and `have` are used, the target object must both contain - * all of the passed-in keys AND the number of keys in the target object must - * match the number of keys passed in (in other words, a target object must - * have all and only all of the passed-in keys). - * - * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz'); - * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo'); - * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz'); - * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']); - * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6}); - * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']); - * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7}); - * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']); - * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6}); - * - * - * @name keys - * @alias key - * @param {...String|Array|Object} keys - * @namespace BDD - * @api public - */ - - function assertKeys (keys) { - var obj = flag(this, 'object') - , str - , ok = true - , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments'; - - switch (_.type(keys)) { - case "array": - if (arguments.length > 1) throw (new Error(mixedArgsMsg)); - break; - case "object": - if (arguments.length > 1) throw (new Error(mixedArgsMsg)); - keys = Object.keys(keys); - break; - default: - keys = Array.prototype.slice.call(arguments); - } - - if (!keys.length) throw new Error('keys required'); - - var actual = Object.keys(obj) - , expected = keys - , len = keys.length - , any = flag(this, 'any') - , all = flag(this, 'all'); - - if (!any && !all) { - all = true; - } - - // Has any - if (any) { - var intersection = expected.filter(function(key) { - return ~actual.indexOf(key); - }); - ok = intersection.length > 0; - } - - // Has all - if (all) { - ok = keys.every(function(key){ - return ~actual.indexOf(key); - }); - if (!flag(this, 'negate') && !flag(this, 'contains')) { - ok = ok && keys.length == actual.length; - } - } - - // Key string - if (len > 1) { - keys = keys.map(function(key){ - return _.inspect(key); - }); - var last = keys.pop(); - if (all) { - str = keys.join(', ') + ', and ' + last; - } - if (any) { - str = keys.join(', ') + ', or ' + last; - } - } else { - str = _.inspect(keys[0]); - } - - // Form - str = (len > 1 ? 'keys ' : 'key ') + str; - - // Have / include - str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; - - // Assertion - this.assert( - ok - , 'expected #{this} to ' + str - , 'expected #{this} to not ' + str - , expected.slice(0).sort() - , actual.sort() - , true - ); - } - - Assertion.addMethod('keys', assertKeys); - Assertion.addMethod('key', assertKeys); - - /** - * ### .throw(constructor) - * - * Asserts that the function target will throw a specific error, or specific type of error - * (as determined using `instanceof`), optionally with a RegExp or string inclusion test - * for the error's message. - * - * var err = new ReferenceError('This is a bad function.'); - * var fn = function () { throw err; } - * expect(fn).to.throw(ReferenceError); - * expect(fn).to.throw(Error); - * expect(fn).to.throw(/bad function/); - * expect(fn).to.not.throw('good function'); - * expect(fn).to.throw(ReferenceError, /bad function/); - * expect(fn).to.throw(err); - * - * Please note that when a throw expectation is negated, it will check each - * parameter independently, starting with error constructor type. The appropriate way - * to check for the existence of a type of error but for a message that does not match - * is to use `and`. - * - * expect(fn).to.throw(ReferenceError) - * .and.not.throw(/good function/); - * - * @name throw - * @alias throws - * @alias Throw - * @param {ErrorConstructor} constructor - * @param {String|RegExp} expected error message - * @param {String} message _optional_ - * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types - * @returns error for chaining (null if no error) - * @namespace BDD - * @api public - */ - - function assertThrows (constructor, errMsg, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - new Assertion(obj, msg).is.a('function'); - - var thrown = false - , desiredError = null - , name = null - , thrownError = null; - - if (arguments.length === 0) { - errMsg = null; - constructor = null; - } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) { - errMsg = constructor; - constructor = null; - } else if (constructor && constructor instanceof Error) { - desiredError = constructor; - constructor = null; - errMsg = null; - } else if (typeof constructor === 'function') { - name = constructor.prototype.name; - if (!name || (name === 'Error' && constructor !== Error)) { - name = constructor.name || (new constructor()).name; - } - } else { - constructor = null; - } - - try { - obj(); - } catch (err) { - // first, check desired error - if (desiredError) { - this.assert( - err === desiredError - , 'expected #{this} to throw #{exp} but #{act} was thrown' - , 'expected #{this} to not throw #{exp}' - , (desiredError instanceof Error ? desiredError.toString() : desiredError) - , (err instanceof Error ? err.toString() : err) - ); - - flag(this, 'object', err); - return this; - } - - // next, check constructor - if (constructor) { - this.assert( - err instanceof constructor - , 'expected #{this} to throw #{exp} but #{act} was thrown' - , 'expected #{this} to not throw #{exp} but #{act} was thrown' - , name - , (err instanceof Error ? err.toString() : err) - ); - - if (!errMsg) { - flag(this, 'object', err); - return this; - } - } - - // next, check message - var message = 'error' === _.type(err) && "message" in err - ? err.message - : '' + err; - - if ((message != null) && errMsg && errMsg instanceof RegExp) { - this.assert( - errMsg.exec(message) - , 'expected #{this} to throw error matching #{exp} but got #{act}' - , 'expected #{this} to throw error not matching #{exp}' - , errMsg - , message - ); - - flag(this, 'object', err); - return this; - } else if ((message != null) && errMsg && 'string' === typeof errMsg) { - this.assert( - ~message.indexOf(errMsg) - , 'expected #{this} to throw error including #{exp} but got #{act}' - , 'expected #{this} to throw error not including #{act}' - , errMsg - , message - ); - - flag(this, 'object', err); - return this; - } else { - thrown = true; - thrownError = err; - } - } - - var actuallyGot = '' - , expectedThrown = name !== null - ? name - : desiredError - ? '#{exp}' //_.inspect(desiredError) - : 'an error'; - - if (thrown) { - actuallyGot = ' but #{act} was thrown' - } - - this.assert( - thrown === true - , 'expected #{this} to throw ' + expectedThrown + actuallyGot - , 'expected #{this} to not throw ' + expectedThrown + actuallyGot - , (desiredError instanceof Error ? desiredError.toString() : desiredError) - , (thrownError instanceof Error ? thrownError.toString() : thrownError) - ); - - flag(this, 'object', thrownError); - }; - - Assertion.addMethod('throw', assertThrows); - Assertion.addMethod('throws', assertThrows); - Assertion.addMethod('Throw', assertThrows); - - /** - * ### .respondTo(method) - * - * Asserts that the object or class target will respond to a method. - * - * Klass.prototype.bar = function(){}; - * expect(Klass).to.respondTo('bar'); - * expect(obj).to.respondTo('bar'); - * - * To check if a constructor will respond to a static function, - * set the `itself` flag. - * - * Klass.baz = function(){}; - * expect(Klass).itself.to.respondTo('baz'); - * - * @name respondTo - * @alias respondsTo - * @param {String} method - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function respondTo (method, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object') - , itself = flag(this, 'itself') - , context = ('function' === _.type(obj) && !itself) - ? obj.prototype[method] - : obj[method]; - - this.assert( - 'function' === typeof context - , 'expected #{this} to respond to ' + _.inspect(method) - , 'expected #{this} to not respond to ' + _.inspect(method) - ); - } - - Assertion.addMethod('respondTo', respondTo); - Assertion.addMethod('respondsTo', respondTo); - - /** - * ### .itself - * - * Sets the `itself` flag, later used by the `respondTo` assertion. - * - * function Foo() {} - * Foo.bar = function() {} - * Foo.prototype.baz = function() {} - * - * expect(Foo).itself.to.respondTo('bar'); - * expect(Foo).itself.not.to.respondTo('baz'); - * - * @name itself - * @namespace BDD - * @api public - */ - - Assertion.addProperty('itself', function () { - flag(this, 'itself', true); - }); - - /** - * ### .satisfy(method) - * - * Asserts that the target passes a given truth test. - * - * expect(1).to.satisfy(function(num) { return num > 0; }); - * - * @name satisfy - * @alias satisfies - * @param {Function} matcher - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function satisfy (matcher, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - var result = matcher(obj); - this.assert( - result - , 'expected #{this} to satisfy ' + _.objDisplay(matcher) - , 'expected #{this} to not satisfy' + _.objDisplay(matcher) - , this.negate ? false : true - , result - ); - } - - Assertion.addMethod('satisfy', satisfy); - Assertion.addMethod('satisfies', satisfy); - - /** - * ### .closeTo(expected, delta) - * - * Asserts that the target is equal `expected`, to within a +/- `delta` range. - * - * expect(1.5).to.be.closeTo(1, 0.5); - * - * @name closeTo - * @alias approximately - * @param {Number} expected - * @param {Number} delta - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function closeTo(expected, delta, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - - new Assertion(obj, msg).is.a('number'); - if (_.type(expected) !== 'number' || _.type(delta) !== 'number') { - throw new Error('the arguments to closeTo or approximately must be numbers'); - } - - this.assert( - Math.abs(obj - expected) <= delta - , 'expected #{this} to be close to ' + expected + ' +/- ' + delta - , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta - ); - } - - Assertion.addMethod('closeTo', closeTo); - Assertion.addMethod('approximately', closeTo); - - function isSubsetOf(subset, superset, cmp) { - return subset.every(function(elem) { - if (!cmp) return superset.indexOf(elem) !== -1; - - return superset.some(function(elem2) { - return cmp(elem, elem2); - }); - }) - } - - /** - * ### .members(set) - * - * Asserts that the target is a superset of `set`, - * or that the target and `set` have the same strictly-equal (===) members. - * Alternately, if the `deep` flag is set, set members are compared for deep - * equality. - * - * expect([1, 2, 3]).to.include.members([3, 2]); - * expect([1, 2, 3]).to.not.include.members([3, 2, 8]); - * - * expect([4, 2]).to.have.members([2, 4]); - * expect([5, 2]).to.not.have.members([5, 2, 1]); - * - * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]); - * - * @name members - * @param {Array} set - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - Assertion.addMethod('members', function (subset, msg) { - if (msg) flag(this, 'message', msg); - var obj = flag(this, 'object'); - - new Assertion(obj).to.be.an('array'); - new Assertion(subset).to.be.an('array'); - - var cmp = flag(this, 'deep') ? _.eql : undefined; - - if (flag(this, 'contains')) { - return this.assert( - isSubsetOf(subset, obj, cmp) - , 'expected #{this} to be a superset of #{act}' - , 'expected #{this} to not be a superset of #{act}' - , obj - , subset - ); - } - - this.assert( - isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp) - , 'expected #{this} to have the same members as #{act}' - , 'expected #{this} to not have the same members as #{act}' - , obj - , subset - ); - }); - - /** - * ### .oneOf(list) - * - * Assert that a value appears somewhere in the top level of array `list`. - * - * expect('a').to.be.oneOf(['a', 'b', 'c']); - * expect(9).to.not.be.oneOf(['z']); - * expect([3]).to.not.be.oneOf([1, 2, [3]]); - * - * var three = [3]; - * // for object-types, contents are not compared - * expect(three).to.not.be.oneOf([1, 2, [3]]); - * // comparing references works - * expect(three).to.be.oneOf([1, 2, three]); - * - * @name oneOf - * @param {Array<*>} list - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function oneOf (list, msg) { - if (msg) flag(this, 'message', msg); - var expected = flag(this, 'object'); - new Assertion(list).to.be.an('array'); - - this.assert( - list.indexOf(expected) > -1 - , 'expected #{this} to be one of #{exp}' - , 'expected #{this} to not be one of #{exp}' - , list - , expected - ); - } - - Assertion.addMethod('oneOf', oneOf); - - - /** - * ### .change(function) - * - * Asserts that a function changes an object property - * - * var obj = { val: 10 }; - * var fn = function() { obj.val += 3 }; - * var noChangeFn = function() { return 'foo' + 'bar'; } - * expect(fn).to.change(obj, 'val'); - * expect(noChangeFn).to.not.change(obj, 'val') - * - * @name change - * @alias changes - * @alias Change - * @param {String} object - * @param {String} property name - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function assertChanges (object, prop, msg) { - if (msg) flag(this, 'message', msg); - var fn = flag(this, 'object'); - new Assertion(object, msg).to.have.property(prop); - new Assertion(fn).is.a('function'); - - var initial = object[prop]; - fn(); - - this.assert( - initial !== object[prop] - , 'expected .' + prop + ' to change' - , 'expected .' + prop + ' to not change' - ); - } - - Assertion.addChainableMethod('change', assertChanges); - Assertion.addChainableMethod('changes', assertChanges); - - /** - * ### .increase(function) - * - * Asserts that a function increases an object property - * - * var obj = { val: 10 }; - * var fn = function() { obj.val = 15 }; - * expect(fn).to.increase(obj, 'val'); - * - * @name increase - * @alias increases - * @alias Increase - * @param {String} object - * @param {String} property name - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function assertIncreases (object, prop, msg) { - if (msg) flag(this, 'message', msg); - var fn = flag(this, 'object'); - new Assertion(object, msg).to.have.property(prop); - new Assertion(fn).is.a('function'); - - var initial = object[prop]; - fn(); - - this.assert( - object[prop] - initial > 0 - , 'expected .' + prop + ' to increase' - , 'expected .' + prop + ' to not increase' - ); - } - - Assertion.addChainableMethod('increase', assertIncreases); - Assertion.addChainableMethod('increases', assertIncreases); - - /** - * ### .decrease(function) - * - * Asserts that a function decreases an object property - * - * var obj = { val: 10 }; - * var fn = function() { obj.val = 5 }; - * expect(fn).to.decrease(obj, 'val'); - * - * @name decrease - * @alias decreases - * @alias Decrease - * @param {String} object - * @param {String} property name - * @param {String} message _optional_ - * @namespace BDD - * @api public - */ - - function assertDecreases (object, prop, msg) { - if (msg) flag(this, 'message', msg); - var fn = flag(this, 'object'); - new Assertion(object, msg).to.have.property(prop); - new Assertion(fn).is.a('function'); - - var initial = object[prop]; - fn(); - - this.assert( - object[prop] - initial < 0 - , 'expected .' + prop + ' to decrease' - , 'expected .' + prop + ' to not decrease' - ); - } - - Assertion.addChainableMethod('decrease', assertDecreases); - Assertion.addChainableMethod('decreases', assertDecreases); - - /** - * ### .extensible - * - * Asserts that the target is extensible (can have new properties added to - * it). - * - * var nonExtensibleObject = Object.preventExtensions({}); - * var sealedObject = Object.seal({}); - * var frozenObject = Object.freeze({}); - * - * expect({}).to.be.extensible; - * expect(nonExtensibleObject).to.not.be.extensible; - * expect(sealedObject).to.not.be.extensible; - * expect(frozenObject).to.not.be.extensible; - * - * @name extensible - * @namespace BDD - * @api public - */ - - Assertion.addProperty('extensible', function() { - var obj = flag(this, 'object'); - - // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError. - // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false. - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible - // The following provides ES6 behavior when a TypeError is thrown under ES5. - - var isExtensible; - - try { - isExtensible = Object.isExtensible(obj); - } catch (err) { - if (err instanceof TypeError) isExtensible = false; - else throw err; - } - - this.assert( - isExtensible - , 'expected #{this} to be extensible' - , 'expected #{this} to not be extensible' - ); - }); - - /** - * ### .sealed - * - * Asserts that the target is sealed (cannot have new properties added to it - * and its existing properties cannot be removed). - * - * var sealedObject = Object.seal({}); - * var frozenObject = Object.freeze({}); - * - * expect(sealedObject).to.be.sealed; - * expect(frozenObject).to.be.sealed; - * expect({}).to.not.be.sealed; - * - * @name sealed - * @namespace BDD - * @api public - */ - - Assertion.addProperty('sealed', function() { - var obj = flag(this, 'object'); - - // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError. - // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true. - // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed - // The following provides ES6 behavior when a TypeError is thrown under ES5. - - var isSealed; - - try { - isSealed = Object.isSealed(obj); - } catch (err) { - if (err instanceof TypeError) isSealed = true; - else throw err; - } - - this.assert( - isSealed - , 'expected #{this} to be sealed' - , 'expected #{this} to not be sealed' - ); - }); - - /** - * ### .frozen - * - * Asserts that the target is frozen (cannot have new properties added to it - * and its existing properties cannot be modified). - * - * var frozenObject = Object.freeze({}); - * - * expect(frozenObject).to.be.frozen; - * expect({}).to.not.be.frozen; - * - * @name frozen - * @namespace BDD - * @api public - */ - - Assertion.addProperty('frozen', function() { - var obj = flag(this, 'object'); - - // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError. - // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true. - // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen - // The following provides ES6 behavior when a TypeError is thrown under ES5. - - var isFrozen; - - try { - isFrozen = Object.isFrozen(obj); - } catch (err) { - if (err instanceof TypeError) isFrozen = true; - else throw err; - } - - this.assert( - isFrozen - , 'expected #{this} to be frozen' - , 'expected #{this} to not be frozen' - ); - }); -}; - -},{}],10:[function(require,module,exports){ -/*! - * chai - * Copyright(c) 2011-2014 Jake Luer - * MIT Licensed - */ - - -module.exports = function (chai, util) { - - /*! - * Chai dependencies. - */ - - var Assertion = chai.Assertion - , flag = util.flag; - - /*! - * Module export. - */ - - /** - * ### assert(expression, message) - * - * Write your own test expressions. - * - * assert('foo' !== 'bar', 'foo is not bar'); - * assert(Array.isArray([]), 'empty arrays are arrays'); - * - * @param {Mixed} expression to test for truthiness - * @param {String} message to display on error - * @name assert - * @namespace Assert - * @api public - */ - - var assert = chai.assert = function (express, errmsg) { - var test = new Assertion(null, null, chai.assert); - test.assert( - express - , errmsg - , '[ negation message unavailable ]' - ); - }; - - /** - * ### .fail(actual, expected, [message], [operator]) - * - * Throw a failure. Node.js `assert` module-compatible. - * - * @name fail - * @param {Mixed} actual - * @param {Mixed} expected - * @param {String} message - * @param {String} operator - * @namespace Assert - * @api public - */ - - assert.fail = function (actual, expected, message, operator) { - message = message || 'assert.fail()'; - throw new chai.AssertionError(message, { - actual: actual - , expected: expected - , operator: operator - }, assert.fail); - }; - - /** - * ### .isOk(object, [message]) - * - * Asserts that `object` is truthy. - * - * assert.isOk('everything', 'everything is ok'); - * assert.isOk(false, 'this will fail'); - * - * @name isOk - * @alias ok - * @param {Mixed} object to test - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isOk = function (val, msg) { - new Assertion(val, msg).is.ok; - }; - - /** - * ### .isNotOk(object, [message]) - * - * Asserts that `object` is falsy. - * - * assert.isNotOk('everything', 'this will fail'); - * assert.isNotOk(false, 'this will pass'); - * - * @name isNotOk - * @alias notOk - * @param {Mixed} object to test - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isNotOk = function (val, msg) { - new Assertion(val, msg).is.not.ok; - }; - - /** - * ### .equal(actual, expected, [message]) - * - * Asserts non-strict equality (`==`) of `actual` and `expected`. - * - * assert.equal(3, '3', '== coerces values to strings'); - * - * @name equal - * @param {Mixed} actual - * @param {Mixed} expected - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.equal = function (act, exp, msg) { - var test = new Assertion(act, msg, assert.equal); - - test.assert( - exp == flag(test, 'object') - , 'expected #{this} to equal #{exp}' - , 'expected #{this} to not equal #{act}' - , exp - , act - ); - }; - - /** - * ### .notEqual(actual, expected, [message]) - * - * Asserts non-strict inequality (`!=`) of `actual` and `expected`. - * - * assert.notEqual(3, 4, 'these numbers are not equal'); - * - * @name notEqual - * @param {Mixed} actual - * @param {Mixed} expected - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.notEqual = function (act, exp, msg) { - var test = new Assertion(act, msg, assert.notEqual); - - test.assert( - exp != flag(test, 'object') - , 'expected #{this} to not equal #{exp}' - , 'expected #{this} to equal #{act}' - , exp - , act - ); - }; - - /** - * ### .strictEqual(actual, expected, [message]) - * - * Asserts strict equality (`===`) of `actual` and `expected`. - * - * assert.strictEqual(true, true, 'these booleans are strictly equal'); - * - * @name strictEqual - * @param {Mixed} actual - * @param {Mixed} expected - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.strictEqual = function (act, exp, msg) { - new Assertion(act, msg).to.equal(exp); - }; - - /** - * ### .notStrictEqual(actual, expected, [message]) - * - * Asserts strict inequality (`!==`) of `actual` and `expected`. - * - * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); - * - * @name notStrictEqual - * @param {Mixed} actual - * @param {Mixed} expected - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.notStrictEqual = function (act, exp, msg) { - new Assertion(act, msg).to.not.equal(exp); - }; - - /** - * ### .deepEqual(actual, expected, [message]) - * - * Asserts that `actual` is deeply equal to `expected`. - * - * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); - * - * @name deepEqual - * @param {Mixed} actual - * @param {Mixed} expected - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.deepEqual = function (act, exp, msg) { - new Assertion(act, msg).to.eql(exp); - }; - - /** - * ### .notDeepEqual(actual, expected, [message]) - * - * Assert that `actual` is not deeply equal to `expected`. - * - * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); - * - * @name notDeepEqual - * @param {Mixed} actual - * @param {Mixed} expected - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.notDeepEqual = function (act, exp, msg) { - new Assertion(act, msg).to.not.eql(exp); - }; - - /** - * ### .isAbove(valueToCheck, valueToBeAbove, [message]) - * - * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove` - * - * assert.isAbove(5, 2, '5 is strictly greater than 2'); - * - * @name isAbove - * @param {Mixed} valueToCheck - * @param {Mixed} valueToBeAbove - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isAbove = function (val, abv, msg) { - new Assertion(val, msg).to.be.above(abv); - }; - - /** - * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message]) - * - * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast` - * - * assert.isAtLeast(5, 2, '5 is greater or equal to 2'); - * assert.isAtLeast(3, 3, '3 is greater or equal to 3'); - * - * @name isAtLeast - * @param {Mixed} valueToCheck - * @param {Mixed} valueToBeAtLeast - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isAtLeast = function (val, atlst, msg) { - new Assertion(val, msg).to.be.least(atlst); - }; - - /** - * ### .isBelow(valueToCheck, valueToBeBelow, [message]) - * - * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow` - * - * assert.isBelow(3, 6, '3 is strictly less than 6'); - * - * @name isBelow - * @param {Mixed} valueToCheck - * @param {Mixed} valueToBeBelow - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isBelow = function (val, blw, msg) { - new Assertion(val, msg).to.be.below(blw); - }; - - /** - * ### .isAtMost(valueToCheck, valueToBeAtMost, [message]) - * - * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost` - * - * assert.isAtMost(3, 6, '3 is less than or equal to 6'); - * assert.isAtMost(4, 4, '4 is less than or equal to 4'); - * - * @name isAtMost - * @param {Mixed} valueToCheck - * @param {Mixed} valueToBeAtMost - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isAtMost = function (val, atmst, msg) { - new Assertion(val, msg).to.be.most(atmst); - }; - - /** - * ### .isTrue(value, [message]) - * - * Asserts that `value` is true. - * - * var teaServed = true; - * assert.isTrue(teaServed, 'the tea has been served'); - * - * @name isTrue - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isTrue = function (val, msg) { - new Assertion(val, msg).is['true']; - }; - - /** - * ### .isNotTrue(value, [message]) - * - * Asserts that `value` is not true. - * - * var tea = 'tasty chai'; - * assert.isNotTrue(tea, 'great, time for tea!'); - * - * @name isNotTrue - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isNotTrue = function (val, msg) { - new Assertion(val, msg).to.not.equal(true); - }; - - /** - * ### .isFalse(value, [message]) - * - * Asserts that `value` is false. - * - * var teaServed = false; - * assert.isFalse(teaServed, 'no tea yet? hmm...'); - * - * @name isFalse - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isFalse = function (val, msg) { - new Assertion(val, msg).is['false']; - }; - - /** - * ### .isNotFalse(value, [message]) - * - * Asserts that `value` is not false. - * - * var tea = 'tasty chai'; - * assert.isNotFalse(tea, 'great, time for tea!'); - * - * @name isNotFalse - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isNotFalse = function (val, msg) { - new Assertion(val, msg).to.not.equal(false); - }; - - /** - * ### .isNull(value, [message]) - * - * Asserts that `value` is null. - * - * assert.isNull(err, 'there was no error'); - * - * @name isNull - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isNull = function (val, msg) { - new Assertion(val, msg).to.equal(null); - }; - - /** - * ### .isNotNull(value, [message]) - * - * Asserts that `value` is not null. - * - * var tea = 'tasty chai'; - * assert.isNotNull(tea, 'great, time for tea!'); - * - * @name isNotNull - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isNotNull = function (val, msg) { - new Assertion(val, msg).to.not.equal(null); - }; - - /** - * ### .isNaN - * Asserts that value is NaN - * - * assert.isNaN('foo', 'foo is NaN'); - * - * @name isNaN - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isNaN = function (val, msg) { - new Assertion(val, msg).to.be.NaN; - }; - - /** - * ### .isNotNaN - * Asserts that value is not NaN - * - * assert.isNotNaN(4, '4 is not NaN'); - * - * @name isNotNaN - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - assert.isNotNaN = function (val, msg) { - new Assertion(val, msg).not.to.be.NaN; - }; - - /** - * ### .isUndefined(value, [message]) - * - * Asserts that `value` is `undefined`. - * - * var tea; - * assert.isUndefined(tea, 'no tea defined'); - * - * @name isUndefined - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isUndefined = function (val, msg) { - new Assertion(val, msg).to.equal(undefined); - }; - - /** - * ### .isDefined(value, [message]) - * - * Asserts that `value` is not `undefined`. - * - * var tea = 'cup of chai'; - * assert.isDefined(tea, 'tea has been defined'); - * - * @name isDefined - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isDefined = function (val, msg) { - new Assertion(val, msg).to.not.equal(undefined); - }; - - /** - * ### .isFunction(value, [message]) - * - * Asserts that `value` is a function. - * - * function serveTea() { return 'cup of tea'; }; - * assert.isFunction(serveTea, 'great, we can have tea now'); - * - * @name isFunction - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isFunction = function (val, msg) { - new Assertion(val, msg).to.be.a('function'); - }; - - /** - * ### .isNotFunction(value, [message]) - * - * Asserts that `value` is _not_ a function. - * - * var serveTea = [ 'heat', 'pour', 'sip' ]; - * assert.isNotFunction(serveTea, 'great, we have listed the steps'); - * - * @name isNotFunction - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isNotFunction = function (val, msg) { - new Assertion(val, msg).to.not.be.a('function'); - }; - - /** - * ### .isObject(value, [message]) - * - * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`). - * _The assertion does not match subclassed objects._ - * - * var selection = { name: 'Chai', serve: 'with spices' }; - * assert.isObject(selection, 'tea selection is an object'); - * - * @name isObject - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isObject = function (val, msg) { - new Assertion(val, msg).to.be.a('object'); - }; - - /** - * ### .isNotObject(value, [message]) - * - * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`). - * - * var selection = 'chai' - * assert.isNotObject(selection, 'tea selection is not an object'); - * assert.isNotObject(null, 'null is not an object'); - * - * @name isNotObject - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isNotObject = function (val, msg) { - new Assertion(val, msg).to.not.be.a('object'); - }; - - /** - * ### .isArray(value, [message]) - * - * Asserts that `value` is an array. - * - * var menu = [ 'green', 'chai', 'oolong' ]; - * assert.isArray(menu, 'what kind of tea do we want?'); - * - * @name isArray - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isArray = function (val, msg) { - new Assertion(val, msg).to.be.an('array'); - }; - - /** - * ### .isNotArray(value, [message]) - * - * Asserts that `value` is _not_ an array. - * - * var menu = 'green|chai|oolong'; - * assert.isNotArray(menu, 'what kind of tea do we want?'); - * - * @name isNotArray - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isNotArray = function (val, msg) { - new Assertion(val, msg).to.not.be.an('array'); - }; - - /** - * ### .isString(value, [message]) - * - * Asserts that `value` is a string. - * - * var teaOrder = 'chai'; - * assert.isString(teaOrder, 'order placed'); - * - * @name isString - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isString = function (val, msg) { - new Assertion(val, msg).to.be.a('string'); - }; - - /** - * ### .isNotString(value, [message]) - * - * Asserts that `value` is _not_ a string. - * - * var teaOrder = 4; - * assert.isNotString(teaOrder, 'order placed'); - * - * @name isNotString - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isNotString = function (val, msg) { - new Assertion(val, msg).to.not.be.a('string'); - }; - - /** - * ### .isNumber(value, [message]) - * - * Asserts that `value` is a number. - * - * var cups = 2; - * assert.isNumber(cups, 'how many cups'); - * - * @name isNumber - * @param {Number} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isNumber = function (val, msg) { - new Assertion(val, msg).to.be.a('number'); - }; - - /** - * ### .isNotNumber(value, [message]) - * - * Asserts that `value` is _not_ a number. - * - * var cups = '2 cups please'; - * assert.isNotNumber(cups, 'how many cups'); - * - * @name isNotNumber - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isNotNumber = function (val, msg) { - new Assertion(val, msg).to.not.be.a('number'); - }; - - /** - * ### .isBoolean(value, [message]) - * - * Asserts that `value` is a boolean. - * - * var teaReady = true - * , teaServed = false; - * - * assert.isBoolean(teaReady, 'is the tea ready'); - * assert.isBoolean(teaServed, 'has tea been served'); - * - * @name isBoolean - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isBoolean = function (val, msg) { - new Assertion(val, msg).to.be.a('boolean'); - }; - - /** - * ### .isNotBoolean(value, [message]) - * - * Asserts that `value` is _not_ a boolean. - * - * var teaReady = 'yep' - * , teaServed = 'nope'; - * - * assert.isNotBoolean(teaReady, 'is the tea ready'); - * assert.isNotBoolean(teaServed, 'has tea been served'); - * - * @name isNotBoolean - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.isNotBoolean = function (val, msg) { - new Assertion(val, msg).to.not.be.a('boolean'); - }; - - /** - * ### .typeOf(value, name, [message]) - * - * Asserts that `value`'s type is `name`, as determined by - * `Object.prototype.toString`. - * - * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); - * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); - * assert.typeOf('tea', 'string', 'we have a string'); - * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); - * assert.typeOf(null, 'null', 'we have a null'); - * assert.typeOf(undefined, 'undefined', 'we have an undefined'); - * - * @name typeOf - * @param {Mixed} value - * @param {String} name - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.typeOf = function (val, type, msg) { - new Assertion(val, msg).to.be.a(type); - }; - - /** - * ### .notTypeOf(value, name, [message]) - * - * Asserts that `value`'s type is _not_ `name`, as determined by - * `Object.prototype.toString`. - * - * assert.notTypeOf('tea', 'number', 'strings are not numbers'); - * - * @name notTypeOf - * @param {Mixed} value - * @param {String} typeof name - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.notTypeOf = function (val, type, msg) { - new Assertion(val, msg).to.not.be.a(type); - }; - - /** - * ### .instanceOf(object, constructor, [message]) - * - * Asserts that `value` is an instance of `constructor`. - * - * var Tea = function (name) { this.name = name; } - * , chai = new Tea('chai'); - * - * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); - * - * @name instanceOf - * @param {Object} object - * @param {Constructor} constructor - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.instanceOf = function (val, type, msg) { - new Assertion(val, msg).to.be.instanceOf(type); - }; - - /** - * ### .notInstanceOf(object, constructor, [message]) - * - * Asserts `value` is not an instance of `constructor`. - * - * var Tea = function (name) { this.name = name; } - * , chai = new String('chai'); - * - * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); - * - * @name notInstanceOf - * @param {Object} object - * @param {Constructor} constructor - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.notInstanceOf = function (val, type, msg) { - new Assertion(val, msg).to.not.be.instanceOf(type); - }; - - /** - * ### .include(haystack, needle, [message]) - * - * Asserts that `haystack` includes `needle`. Works - * for strings and arrays. - * - * assert.include('foobar', 'bar', 'foobar contains string "bar"'); - * assert.include([ 1, 2, 3 ], 3, 'array contains value'); - * - * @name include - * @param {Array|String} haystack - * @param {Mixed} needle - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.include = function (exp, inc, msg) { - new Assertion(exp, msg, assert.include).include(inc); - }; - - /** - * ### .notInclude(haystack, needle, [message]) - * - * Asserts that `haystack` does not include `needle`. Works - * for strings and arrays. - * - * assert.notInclude('foobar', 'baz', 'string not include substring'); - * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value'); - * - * @name notInclude - * @param {Array|String} haystack - * @param {Mixed} needle - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.notInclude = function (exp, inc, msg) { - new Assertion(exp, msg, assert.notInclude).not.include(inc); - }; - - /** - * ### .match(value, regexp, [message]) - * - * Asserts that `value` matches the regular expression `regexp`. - * - * assert.match('foobar', /^foo/, 'regexp matches'); - * - * @name match - * @param {Mixed} value - * @param {RegExp} regexp - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.match = function (exp, re, msg) { - new Assertion(exp, msg).to.match(re); - }; - - /** - * ### .notMatch(value, regexp, [message]) - * - * Asserts that `value` does not match the regular expression `regexp`. - * - * assert.notMatch('foobar', /^foo/, 'regexp does not match'); - * - * @name notMatch - * @param {Mixed} value - * @param {RegExp} regexp - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.notMatch = function (exp, re, msg) { - new Assertion(exp, msg).to.not.match(re); - }; - - /** - * ### .property(object, property, [message]) - * - * Asserts that `object` has a property named by `property`. - * - * assert.property({ tea: { green: 'matcha' }}, 'tea'); - * - * @name property - * @param {Object} object - * @param {String} property - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.property = function (obj, prop, msg) { - new Assertion(obj, msg).to.have.property(prop); - }; - - /** - * ### .notProperty(object, property, [message]) - * - * Asserts that `object` does _not_ have a property named by `property`. - * - * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); - * - * @name notProperty - * @param {Object} object - * @param {String} property - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.notProperty = function (obj, prop, msg) { - new Assertion(obj, msg).to.not.have.property(prop); - }; - - /** - * ### .deepProperty(object, property, [message]) - * - * Asserts that `object` has a property named by `property`, which can be a - * string using dot- and bracket-notation for deep reference. - * - * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green'); - * - * @name deepProperty - * @param {Object} object - * @param {String} property - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.deepProperty = function (obj, prop, msg) { - new Assertion(obj, msg).to.have.deep.property(prop); - }; - - /** - * ### .notDeepProperty(object, property, [message]) - * - * Asserts that `object` does _not_ have a property named by `property`, which - * can be a string using dot- and bracket-notation for deep reference. - * - * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); - * - * @name notDeepProperty - * @param {Object} object - * @param {String} property - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.notDeepProperty = function (obj, prop, msg) { - new Assertion(obj, msg).to.not.have.deep.property(prop); - }; - - /** - * ### .propertyVal(object, property, value, [message]) - * - * Asserts that `object` has a property named by `property` with value given - * by `value`. - * - * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); - * - * @name propertyVal - * @param {Object} object - * @param {String} property - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.propertyVal = function (obj, prop, val, msg) { - new Assertion(obj, msg).to.have.property(prop, val); - }; - - /** - * ### .propertyNotVal(object, property, value, [message]) - * - * Asserts that `object` has a property named by `property`, but with a value - * different from that given by `value`. - * - * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad'); - * - * @name propertyNotVal - * @param {Object} object - * @param {String} property - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.propertyNotVal = function (obj, prop, val, msg) { - new Assertion(obj, msg).to.not.have.property(prop, val); - }; - - /** - * ### .deepPropertyVal(object, property, value, [message]) - * - * Asserts that `object` has a property named by `property` with value given - * by `value`. `property` can use dot- and bracket-notation for deep - * reference. - * - * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha'); - * - * @name deepPropertyVal - * @param {Object} object - * @param {String} property - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.deepPropertyVal = function (obj, prop, val, msg) { - new Assertion(obj, msg).to.have.deep.property(prop, val); - }; - - /** - * ### .deepPropertyNotVal(object, property, value, [message]) - * - * Asserts that `object` has a property named by `property`, but with a value - * different from that given by `value`. `property` can use dot- and - * bracket-notation for deep reference. - * - * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha'); - * - * @name deepPropertyNotVal - * @param {Object} object - * @param {String} property - * @param {Mixed} value - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.deepPropertyNotVal = function (obj, prop, val, msg) { - new Assertion(obj, msg).to.not.have.deep.property(prop, val); - }; - - /** - * ### .lengthOf(object, length, [message]) - * - * Asserts that `object` has a `length` property with the expected value. - * - * assert.lengthOf([1,2,3], 3, 'array has length of 3'); - * assert.lengthOf('foobar', 6, 'string has length of 6'); - * - * @name lengthOf - * @param {Mixed} object - * @param {Number} length - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.lengthOf = function (exp, len, msg) { - new Assertion(exp, msg).to.have.length(len); - }; - - /** - * ### .throws(function, [constructor/string/regexp], [string/regexp], [message]) - * - * Asserts that `function` will throw an error that is an instance of - * `constructor`, or alternately that it will throw an error with message - * matching `regexp`. - * - * assert.throws(fn, 'function throws a reference error'); - * assert.throws(fn, /function throws a reference error/); - * assert.throws(fn, ReferenceError); - * assert.throws(fn, ReferenceError, 'function throws a reference error'); - * assert.throws(fn, ReferenceError, /function throws a reference error/); - * - * @name throws - * @alias throw - * @alias Throw - * @param {Function} function - * @param {ErrorConstructor} constructor - * @param {RegExp} regexp - * @param {String} message - * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types - * @namespace Assert - * @api public - */ - - assert.throws = function (fn, errt, errs, msg) { - if ('string' === typeof errt || errt instanceof RegExp) { - errs = errt; - errt = null; - } - - var assertErr = new Assertion(fn, msg).to.throw(errt, errs); - return flag(assertErr, 'object'); - }; - - /** - * ### .doesNotThrow(function, [constructor/regexp], [message]) - * - * Asserts that `function` will _not_ throw an error that is an instance of - * `constructor`, or alternately that it will not throw an error with message - * matching `regexp`. - * - * assert.doesNotThrow(fn, Error, 'function does not throw'); - * - * @name doesNotThrow - * @param {Function} function - * @param {ErrorConstructor} constructor - * @param {RegExp} regexp - * @param {String} message - * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types - * @namespace Assert - * @api public - */ - - assert.doesNotThrow = function (fn, type, msg) { - if ('string' === typeof type) { - msg = type; - type = null; - } - - new Assertion(fn, msg).to.not.Throw(type); - }; - - /** - * ### .operator(val1, operator, val2, [message]) - * - * Compares two values using `operator`. - * - * assert.operator(1, '<', 2, 'everything is ok'); - * assert.operator(1, '>', 2, 'this will fail'); - * - * @name operator - * @param {Mixed} val1 - * @param {String} operator - * @param {Mixed} val2 - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.operator = function (val, operator, val2, msg) { - var ok; - switch(operator) { - case '==': - ok = val == val2; - break; - case '===': - ok = val === val2; - break; - case '>': - ok = val > val2; - break; - case '>=': - ok = val >= val2; - break; - case '<': - ok = val < val2; - break; - case '<=': - ok = val <= val2; - break; - case '!=': - ok = val != val2; - break; - case '!==': - ok = val !== val2; - break; - default: - throw new Error('Invalid operator "' + operator + '"'); - } - var test = new Assertion(ok, msg); - test.assert( - true === flag(test, 'object') - , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2) - , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) ); - }; - - /** - * ### .closeTo(actual, expected, delta, [message]) - * - * Asserts that the target is equal `expected`, to within a +/- `delta` range. - * - * assert.closeTo(1.5, 1, 0.5, 'numbers are close'); - * - * @name closeTo - * @param {Number} actual - * @param {Number} expected - * @param {Number} delta - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.closeTo = function (act, exp, delta, msg) { - new Assertion(act, msg).to.be.closeTo(exp, delta); - }; - - /** - * ### .approximately(actual, expected, delta, [message]) - * - * Asserts that the target is equal `expected`, to within a +/- `delta` range. - * - * assert.approximately(1.5, 1, 0.5, 'numbers are close'); - * - * @name approximately - * @param {Number} actual - * @param {Number} expected - * @param {Number} delta - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.approximately = function (act, exp, delta, msg) { - new Assertion(act, msg).to.be.approximately(exp, delta); - }; - - /** - * ### .sameMembers(set1, set2, [message]) - * - * Asserts that `set1` and `set2` have the same members. - * Order is not taken into account. - * - * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); - * - * @name sameMembers - * @param {Array} set1 - * @param {Array} set2 - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.sameMembers = function (set1, set2, msg) { - new Assertion(set1, msg).to.have.same.members(set2); - } - - /** - * ### .sameDeepMembers(set1, set2, [message]) - * - * Asserts that `set1` and `set2` have the same members - using a deep equality checking. - * Order is not taken into account. - * - * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members'); - * - * @name sameDeepMembers - * @param {Array} set1 - * @param {Array} set2 - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.sameDeepMembers = function (set1, set2, msg) { - new Assertion(set1, msg).to.have.same.deep.members(set2); - } - - /** - * ### .includeMembers(superset, subset, [message]) - * - * Asserts that `subset` is included in `superset`. - * Order is not taken into account. - * - * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members'); - * - * @name includeMembers - * @param {Array} superset - * @param {Array} subset - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.includeMembers = function (superset, subset, msg) { - new Assertion(superset, msg).to.include.members(subset); - } - - /** - * ### .includeDeepMembers(superset, subset, [message]) - * - * Asserts that `subset` is included in `superset` - using deep equality checking. - * Order is not taken into account. - * Duplicates are ignored. - * - * assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members'); - * - * @name includeDeepMembers - * @param {Array} superset - * @param {Array} subset - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.includeDeepMembers = function (superset, subset, msg) { - new Assertion(superset, msg).to.include.deep.members(subset); - } - - /** - * ### .oneOf(inList, list, [message]) - * - * Asserts that non-object, non-array value `inList` appears in the flat array `list`. - * - * assert.oneOf(1, [ 2, 1 ], 'Not found in list'); - * - * @name oneOf - * @param {*} inList - * @param {Array<*>} list - * @param {String} message - * @namespace Assert - * @api public - */ - - assert.oneOf = function (inList, list, msg) { - new Assertion(inList, msg).to.be.oneOf(list); - } - - /** - * ### .changes(function, object, property) - * - * Asserts that a function changes the value of a property - * - * var obj = { val: 10 }; - * var fn = function() { obj.val = 22 }; - * assert.changes(fn, obj, 'val'); - * - * @name changes - * @param {Function} modifier function - * @param {Object} object - * @param {String} property name - * @param {String} message _optional_ - * @namespace Assert - * @api public - */ - - assert.changes = function (fn, obj, prop) { - new Assertion(fn).to.change(obj, prop); - } - - /** - * ### .doesNotChange(function, object, property) - * - * Asserts that a function does not changes the value of a property - * - * var obj = { val: 10 }; - * var fn = function() { console.log('foo'); }; - * assert.doesNotChange(fn, obj, 'val'); - * - * @name doesNotChange - * @param {Function} modifier function - * @param {Object} object - * @param {String} property name - * @param {String} message _optional_ - * @namespace Assert - * @api public - */ - - assert.doesNotChange = function (fn, obj, prop) { - new Assertion(fn).to.not.change(obj, prop); - } - - /** - * ### .increases(function, object, property) - * - * Asserts that a function increases an object property - * - * var obj = { val: 10 }; - * var fn = function() { obj.val = 13 }; - * assert.increases(fn, obj, 'val'); - * - * @name increases - * @param {Function} modifier function - * @param {Object} object - * @param {String} property name - * @param {String} message _optional_ - * @namespace Assert - * @api public - */ - - assert.increases = function (fn, obj, prop) { - new Assertion(fn).to.increase(obj, prop); - } - - /** - * ### .doesNotIncrease(function, object, property) - * - * Asserts that a function does not increase object property - * - * var obj = { val: 10 }; - * var fn = function() { obj.val = 8 }; - * assert.doesNotIncrease(fn, obj, 'val'); - * - * @name doesNotIncrease - * @param {Function} modifier function - * @param {Object} object - * @param {String} property name - * @param {String} message _optional_ - * @namespace Assert - * @api public - */ - - assert.doesNotIncrease = function (fn, obj, prop) { - new Assertion(fn).to.not.increase(obj, prop); - } - - /** - * ### .decreases(function, object, property) - * - * Asserts that a function decreases an object property - * - * var obj = { val: 10 }; - * var fn = function() { obj.val = 5 }; - * assert.decreases(fn, obj, 'val'); - * - * @name decreases - * @param {Function} modifier function - * @param {Object} object - * @param {String} property name - * @param {String} message _optional_ - * @namespace Assert - * @api public - */ - - assert.decreases = function (fn, obj, prop) { - new Assertion(fn).to.decrease(obj, prop); - } - - /** - * ### .doesNotDecrease(function, object, property) - * - * Asserts that a function does not decreases an object property - * - * var obj = { val: 10 }; - * var fn = function() { obj.val = 15 }; - * assert.doesNotDecrease(fn, obj, 'val'); - * - * @name doesNotDecrease - * @param {Function} modifier function - * @param {Object} object - * @param {String} property name - * @param {String} message _optional_ - * @namespace Assert - * @api public - */ - - assert.doesNotDecrease = function (fn, obj, prop) { - new Assertion(fn).to.not.decrease(obj, prop); - } - - /*! - * ### .ifError(object) - * - * Asserts if value is not a false value, and throws if it is a true value. - * This is added to allow for chai to be a drop-in replacement for Node's - * assert class. - * - * var err = new Error('I am a custom error'); - * assert.ifError(err); // Rethrows err! - * - * @name ifError - * @param {Object} object - * @namespace Assert - * @api public - */ - - assert.ifError = function (val) { - if (val) { - throw(val); - } - }; - - /** - * ### .isExtensible(object) - * - * Asserts that `object` is extensible (can have new properties added to it). - * - * assert.isExtensible({}); - * - * @name isExtensible - * @alias extensible - * @param {Object} object - * @param {String} message _optional_ - * @namespace Assert - * @api public - */ - - assert.isExtensible = function (obj, msg) { - new Assertion(obj, msg).to.be.extensible; - }; - - /** - * ### .isNotExtensible(object) - * - * Asserts that `object` is _not_ extensible. - * - * var nonExtensibleObject = Object.preventExtensions({}); - * var sealedObject = Object.seal({}); - * var frozenObject = Object.freese({}); - * - * assert.isNotExtensible(nonExtensibleObject); - * assert.isNotExtensible(sealedObject); - * assert.isNotExtensible(frozenObject); - * - * @name isNotExtensible - * @alias notExtensible - * @param {Object} object - * @param {String} message _optional_ - * @namespace Assert - * @api public - */ - - assert.isNotExtensible = function (obj, msg) { - new Assertion(obj, msg).to.not.be.extensible; - }; - - /** - * ### .isSealed(object) - * - * Asserts that `object` is sealed (cannot have new properties added to it - * and its existing properties cannot be removed). - * - * var sealedObject = Object.seal({}); - * var frozenObject = Object.seal({}); - * - * assert.isSealed(sealedObject); - * assert.isSealed(frozenObject); - * - * @name isSealed - * @alias sealed - * @param {Object} object - * @param {String} message _optional_ - * @namespace Assert - * @api public - */ - - assert.isSealed = function (obj, msg) { - new Assertion(obj, msg).to.be.sealed; - }; - - /** - * ### .isNotSealed(object) - * - * Asserts that `object` is _not_ sealed. - * - * assert.isNotSealed({}); - * - * @name isNotSealed - * @alias notSealed - * @param {Object} object - * @param {String} message _optional_ - * @namespace Assert - * @api public - */ - - assert.isNotSealed = function (obj, msg) { - new Assertion(obj, msg).to.not.be.sealed; - }; - - /** - * ### .isFrozen(object) - * - * Asserts that `object` is frozen (cannot have new properties added to it - * and its existing properties cannot be modified). - * - * var frozenObject = Object.freeze({}); - * assert.frozen(frozenObject); - * - * @name isFrozen - * @alias frozen - * @param {Object} object - * @param {String} message _optional_ - * @namespace Assert - * @api public - */ - - assert.isFrozen = function (obj, msg) { - new Assertion(obj, msg).to.be.frozen; - }; - - /** - * ### .isNotFrozen(object) - * - * Asserts that `object` is _not_ frozen. - * - * assert.isNotFrozen({}); - * - * @name isNotFrozen - * @alias notFrozen - * @param {Object} object - * @param {String} message _optional_ - * @namespace Assert - * @api public - */ - - assert.isNotFrozen = function (obj, msg) { - new Assertion(obj, msg).to.not.be.frozen; - }; - - /*! - * Aliases. - */ - - (function alias(name, as){ - assert[as] = assert[name]; - return alias; - }) - ('isOk', 'ok') - ('isNotOk', 'notOk') - ('throws', 'throw') - ('throws', 'Throw') - ('isExtensible', 'extensible') - ('isNotExtensible', 'notExtensible') - ('isSealed', 'sealed') - ('isNotSealed', 'notSealed') - ('isFrozen', 'frozen') - ('isNotFrozen', 'notFrozen'); -}; - -},{}],11:[function(require,module,exports){ -/*! - * chai - * Copyright(c) 2011-2014 Jake Luer - * MIT Licensed - */ - -module.exports = function (chai, util) { - chai.expect = function (val, message) { - return new chai.Assertion(val, message); - }; - - /** - * ### .fail(actual, expected, [message], [operator]) - * - * Throw a failure. - * - * @name fail - * @param {Mixed} actual - * @param {Mixed} expected - * @param {String} message - * @param {String} operator - * @namespace Expect - * @api public - */ - - chai.expect.fail = function (actual, expected, message, operator) { - message = message || 'expect.fail()'; - throw new chai.AssertionError(message, { - actual: actual - , expected: expected - , operator: operator - }, chai.expect.fail); - }; -}; - -},{}],12:[function(require,module,exports){ -/*! - * chai - * Copyright(c) 2011-2014 Jake Luer - * MIT Licensed - */ - -module.exports = function (chai, util) { - var Assertion = chai.Assertion; - - function loadShould () { - // explicitly define this method as function as to have it's name to include as `ssfi` - function shouldGetter() { - if (this instanceof String || this instanceof Number || this instanceof Boolean ) { - return new Assertion(this.valueOf(), null, shouldGetter); - } - return new Assertion(this, null, shouldGetter); - } - function shouldSetter(value) { - // See https://github.com/chaijs/chai/issues/86: this makes - // `whatever.should = someValue` actually set `someValue`, which is - // especially useful for `global.should = require('chai').should()`. - // - // Note that we have to use [[DefineProperty]] instead of [[Put]] - // since otherwise we would trigger this very setter! - Object.defineProperty(this, 'should', { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } - // modify Object.prototype to have `should` - Object.defineProperty(Object.prototype, 'should', { - set: shouldSetter - , get: shouldGetter - , configurable: true - }); - - var should = {}; - - /** - * ### .fail(actual, expected, [message], [operator]) - * - * Throw a failure. - * - * @name fail - * @param {Mixed} actual - * @param {Mixed} expected - * @param {String} message - * @param {String} operator - * @namespace Should - * @api public - */ - - should.fail = function (actual, expected, message, operator) { - message = message || 'should.fail()'; - throw new chai.AssertionError(message, { - actual: actual - , expected: expected - , operator: operator - }, should.fail); - }; - - /** - * ### .equal(actual, expected, [message]) - * - * Asserts non-strict equality (`==`) of `actual` and `expected`. - * - * should.equal(3, '3', '== coerces values to strings'); - * - * @name equal - * @param {Mixed} actual - * @param {Mixed} expected - * @param {String} message - * @namespace Should - * @api public - */ - - should.equal = function (val1, val2, msg) { - new Assertion(val1, msg).to.equal(val2); - }; - - /** - * ### .throw(function, [constructor/string/regexp], [string/regexp], [message]) - * - * Asserts that `function` will throw an error that is an instance of - * `constructor`, or alternately that it will throw an error with message - * matching `regexp`. - * - * should.throw(fn, 'function throws a reference error'); - * should.throw(fn, /function throws a reference error/); - * should.throw(fn, ReferenceError); - * should.throw(fn, ReferenceError, 'function throws a reference error'); - * should.throw(fn, ReferenceError, /function throws a reference error/); - * - * @name throw - * @alias Throw - * @param {Function} function - * @param {ErrorConstructor} constructor - * @param {RegExp} regexp - * @param {String} message - * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types - * @namespace Should - * @api public - */ - - should.Throw = function (fn, errt, errs, msg) { - new Assertion(fn, msg).to.Throw(errt, errs); - }; - - /** - * ### .exist - * - * Asserts that the target is neither `null` nor `undefined`. - * - * var foo = 'hi'; - * - * should.exist(foo, 'foo exists'); - * - * @name exist - * @namespace Should - * @api public - */ - - should.exist = function (val, msg) { - new Assertion(val, msg).to.exist; - } - - // negation - should.not = {} - - /** - * ### .not.equal(actual, expected, [message]) - * - * Asserts non-strict inequality (`!=`) of `actual` and `expected`. - * - * should.not.equal(3, 4, 'these numbers are not equal'); - * - * @name not.equal - * @param {Mixed} actual - * @param {Mixed} expected - * @param {String} message - * @namespace Should - * @api public - */ - - should.not.equal = function (val1, val2, msg) { - new Assertion(val1, msg).to.not.equal(val2); - }; - - /** - * ### .throw(function, [constructor/regexp], [message]) - * - * Asserts that `function` will _not_ throw an error that is an instance of - * `constructor`, or alternately that it will not throw an error with message - * matching `regexp`. - * - * should.not.throw(fn, Error, 'function does not throw'); - * - * @name not.throw - * @alias not.Throw - * @param {Function} function - * @param {ErrorConstructor} constructor - * @param {RegExp} regexp - * @param {String} message - * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types - * @namespace Should - * @api public - */ - - should.not.Throw = function (fn, errt, errs, msg) { - new Assertion(fn, msg).to.not.Throw(errt, errs); - }; - - /** - * ### .not.exist - * - * Asserts that the target is neither `null` nor `undefined`. - * - * var bar = null; - * - * should.not.exist(bar, 'bar does not exist'); - * - * @name not.exist - * @namespace Should - * @api public - */ - - should.not.exist = function (val, msg) { - new Assertion(val, msg).to.not.exist; - } - - should['throw'] = should['Throw']; - should.not['throw'] = should.not['Throw']; - - return should; - }; - - chai.should = loadShould; - chai.Should = loadShould; -}; - -},{}],13:[function(require,module,exports){ -/*! - * Chai - addChainingMethod utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -/*! - * Module dependencies - */ - -var transferFlags = require('./transferFlags'); -var flag = require('./flag'); -var config = require('../config'); - -/*! - * Module variables - */ - -// Check whether `__proto__` is supported -var hasProtoSupport = '__proto__' in Object; - -// Without `__proto__` support, this module will need to add properties to a function. -// However, some Function.prototype methods cannot be overwritten, -// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69). -var excludeNames = /^(?:length|name|arguments|caller)$/; - -// Cache `Function` properties -var call = Function.prototype.call, - apply = Function.prototype.apply; - -/** - * ### addChainableMethod (ctx, name, method, chainingBehavior) - * - * Adds a method to an object, such that the method can also be chained. - * - * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) { - * var obj = utils.flag(this, 'object'); - * new chai.Assertion(obj).to.be.equal(str); - * }); - * - * Can also be accessed directly from `chai.Assertion`. - * - * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior); - * - * The result can then be used as both a method assertion, executing both `method` and - * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`. - * - * expect(fooStr).to.be.foo('bar'); - * expect(fooStr).to.be.foo.equal('foo'); - * - * @param {Object} ctx object to which the method is added - * @param {String} name of method to add - * @param {Function} method function to be used for `name`, when called - * @param {Function} chainingBehavior function to be called every time the property is accessed - * @namespace Utils - * @name addChainableMethod - * @api public - */ - -module.exports = function (ctx, name, method, chainingBehavior) { - if (typeof chainingBehavior !== 'function') { - chainingBehavior = function () { }; - } - - var chainableBehavior = { - method: method - , chainingBehavior: chainingBehavior - }; - - // save the methods so we can overwrite them later, if we need to. - if (!ctx.__methods) { - ctx.__methods = {}; - } - ctx.__methods[name] = chainableBehavior; - - Object.defineProperty(ctx, name, - { get: function () { - chainableBehavior.chainingBehavior.call(this); - - var assert = function assert() { - var old_ssfi = flag(this, 'ssfi'); - if (old_ssfi && config.includeStack === false) - flag(this, 'ssfi', assert); - var result = chainableBehavior.method.apply(this, arguments); - return result === undefined ? this : result; - }; - - // Use `__proto__` if available - if (hasProtoSupport) { - // Inherit all properties from the object by replacing the `Function` prototype - var prototype = assert.__proto__ = Object.create(this); - // Restore the `call` and `apply` methods from `Function` - prototype.call = call; - prototype.apply = apply; - } - // Otherwise, redefine all properties (slow!) - else { - var asserterNames = Object.getOwnPropertyNames(ctx); - asserterNames.forEach(function (asserterName) { - if (!excludeNames.test(asserterName)) { - var pd = Object.getOwnPropertyDescriptor(ctx, asserterName); - Object.defineProperty(assert, asserterName, pd); - } - }); - } - - transferFlags(this, assert); - return assert; - } - , configurable: true - }); -}; - -},{"../config":8,"./flag":17,"./transferFlags":33}],14:[function(require,module,exports){ -/*! - * Chai - addMethod utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -var config = require('../config'); - -/** - * ### .addMethod (ctx, name, method) - * - * Adds a method to the prototype of an object. - * - * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) { - * var obj = utils.flag(this, 'object'); - * new chai.Assertion(obj).to.be.equal(str); - * }); - * - * Can also be accessed directly from `chai.Assertion`. - * - * chai.Assertion.addMethod('foo', fn); - * - * Then can be used as any other assertion. - * - * expect(fooStr).to.be.foo('bar'); - * - * @param {Object} ctx object to which the method is added - * @param {String} name of method to add - * @param {Function} method function to be used for name - * @namespace Utils - * @name addMethod - * @api public - */ -var flag = require('./flag'); - -module.exports = function (ctx, name, method) { - ctx[name] = function () { - var old_ssfi = flag(this, 'ssfi'); - if (old_ssfi && config.includeStack === false) - flag(this, 'ssfi', ctx[name]); - var result = method.apply(this, arguments); - return result === undefined ? this : result; - }; -}; - -},{"../config":8,"./flag":17}],15:[function(require,module,exports){ -/*! - * Chai - addProperty utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -var config = require('../config'); -var flag = require('./flag'); - -/** - * ### addProperty (ctx, name, getter) - * - * Adds a property to the prototype of an object. - * - * utils.addProperty(chai.Assertion.prototype, 'foo', function () { - * var obj = utils.flag(this, 'object'); - * new chai.Assertion(obj).to.be.instanceof(Foo); - * }); - * - * Can also be accessed directly from `chai.Assertion`. - * - * chai.Assertion.addProperty('foo', fn); - * - * Then can be used as any other assertion. - * - * expect(myFoo).to.be.foo; - * - * @param {Object} ctx object to which the property is added - * @param {String} name of property to add - * @param {Function} getter function to be used for name - * @namespace Utils - * @name addProperty - * @api public - */ - -module.exports = function (ctx, name, getter) { - Object.defineProperty(ctx, name, - { get: function addProperty() { - var old_ssfi = flag(this, 'ssfi'); - if (old_ssfi && config.includeStack === false) - flag(this, 'ssfi', addProperty); - - var result = getter.call(this); - return result === undefined ? this : result; - } - , configurable: true - }); -}; - -},{"../config":8,"./flag":17}],16:[function(require,module,exports){ -/*! - * Chai - expectTypes utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -/** - * ### expectTypes(obj, types) - * - * Ensures that the object being tested against is of a valid type. - * - * utils.expectTypes(this, ['array', 'object', 'string']); - * - * @param {Mixed} obj constructed Assertion - * @param {Array} type A list of allowed types for this assertion - * @namespace Utils - * @name expectTypes - * @api public - */ - -var AssertionError = require('assertion-error'); -var flag = require('./flag'); -var type = require('type-detect'); - -module.exports = function (obj, types) { - var obj = flag(obj, 'object'); - types = types.map(function (t) { return t.toLowerCase(); }); - types.sort(); - - // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum' - var str = types.map(function (t, index) { - var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a'; - var or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; - return or + art + ' ' + t; - }).join(', '); - - if (!types.some(function (expected) { return type(obj) === expected; })) { - throw new AssertionError( - 'object tested must be ' + str + ', but ' + type(obj) + ' given' - ); - } -}; - -},{"./flag":17,"assertion-error":4,"type-detect":40}],17:[function(require,module,exports){ -/*! - * Chai - flag utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -/** - * ### flag(object, key, [value]) - * - * Get or set a flag value on an object. If a - * value is provided it will be set, else it will - * return the currently set value or `undefined` if - * the value is not set. - * - * utils.flag(this, 'foo', 'bar'); // setter - * utils.flag(this, 'foo'); // getter, returns `bar` - * - * @param {Object} object constructed Assertion - * @param {String} key - * @param {Mixed} value (optional) - * @namespace Utils - * @name flag - * @api private - */ - -module.exports = function (obj, key, value) { - var flags = obj.__flags || (obj.__flags = Object.create(null)); - if (arguments.length === 3) { - flags[key] = value; - } else { - return flags[key]; - } -}; - -},{}],18:[function(require,module,exports){ -/*! - * Chai - getActual utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -/** - * # getActual(object, [actual]) - * - * Returns the `actual` value for an Assertion - * - * @param {Object} object (constructed Assertion) - * @param {Arguments} chai.Assertion.prototype.assert arguments - * @namespace Utils - * @name getActual - */ - -module.exports = function (obj, args) { - return args.length > 4 ? args[4] : obj._obj; -}; - -},{}],19:[function(require,module,exports){ -/*! - * Chai - getEnumerableProperties utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -/** - * ### .getEnumerableProperties(object) - * - * This allows the retrieval of enumerable property names of an object, - * inherited or not. - * - * @param {Object} object - * @returns {Array} - * @namespace Utils - * @name getEnumerableProperties - * @api public - */ - -module.exports = function getEnumerableProperties(object) { - var result = []; - for (var name in object) { - result.push(name); - } - return result; -}; - -},{}],20:[function(require,module,exports){ -/*! - * Chai - message composition utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -/*! - * Module dependancies - */ - -var flag = require('./flag') - , getActual = require('./getActual') - , inspect = require('./inspect') - , objDisplay = require('./objDisplay'); - -/** - * ### .getMessage(object, message, negateMessage) - * - * Construct the error message based on flags - * and template tags. Template tags will return - * a stringified inspection of the object referenced. - * - * Message template tags: - * - `#{this}` current asserted object - * - `#{act}` actual value - * - `#{exp}` expected value - * - * @param {Object} object (constructed Assertion) - * @param {Arguments} chai.Assertion.prototype.assert arguments - * @namespace Utils - * @name getMessage - * @api public - */ - -module.exports = function (obj, args) { - var negate = flag(obj, 'negate') - , val = flag(obj, 'object') - , expected = args[3] - , actual = getActual(obj, args) - , msg = negate ? args[2] : args[1] - , flagMsg = flag(obj, 'message'); - - if(typeof msg === "function") msg = msg(); - msg = msg || ''; - msg = msg - .replace(/#\{this\}/g, function () { return objDisplay(val); }) - .replace(/#\{act\}/g, function () { return objDisplay(actual); }) - .replace(/#\{exp\}/g, function () { return objDisplay(expected); }); - - return flagMsg ? flagMsg + ': ' + msg : msg; -}; - -},{"./flag":17,"./getActual":18,"./inspect":27,"./objDisplay":28}],21:[function(require,module,exports){ -/*! - * Chai - getName utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -/** - * # getName(func) - * - * Gets the name of a function, in a cross-browser way. - * - * @param {Function} a function (usually a constructor) - * @namespace Utils - * @name getName - */ - -module.exports = function (func) { - if (func.name) return func.name; - - var match = /^\s?function ([^(]*)\(/.exec(func); - return match && match[1] ? match[1] : ""; -}; - -},{}],22:[function(require,module,exports){ -/*! - * Chai - getPathInfo utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -var hasProperty = require('./hasProperty'); - -/** - * ### .getPathInfo(path, object) - * - * This allows the retrieval of property info in an - * object given a string path. - * - * The path info consists of an object with the - * following properties: - * - * * parent - The parent object of the property referenced by `path` - * * name - The name of the final property, a number if it was an array indexer - * * value - The value of the property, if it exists, otherwise `undefined` - * * exists - Whether the property exists or not - * - * @param {String} path - * @param {Object} object - * @returns {Object} info - * @namespace Utils - * @name getPathInfo - * @api public - */ - -module.exports = function getPathInfo(path, obj) { - var parsed = parsePath(path), - last = parsed[parsed.length - 1]; - - var info = { - parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj, - name: last.p || last.i, - value: _getPathValue(parsed, obj) - }; - info.exists = hasProperty(info.name, info.parent); - - return info; -}; - - -/*! - * ## parsePath(path) - * - * Helper function used to parse string object - * paths. Use in conjunction with `_getPathValue`. - * - * var parsed = parsePath('myobject.property.subprop'); - * - * ### Paths: - * - * * Can be as near infinitely deep and nested - * * Arrays are also valid using the formal `myobject.document[3].property`. - * * Literal dots and brackets (not delimiter) must be backslash-escaped. - * - * @param {String} path - * @returns {Object} parsed - * @api private - */ - -function parsePath (path) { - var str = path.replace(/([^\\])\[/g, '$1.[') - , parts = str.match(/(\\\.|[^.]+?)+/g); - return parts.map(function (value) { - var re = /^\[(\d+)\]$/ - , mArr = re.exec(value); - if (mArr) return { i: parseFloat(mArr[1]) }; - else return { p: value.replace(/\\([.\[\]])/g, '$1') }; - }); -} - - -/*! - * ## _getPathValue(parsed, obj) - * - * Helper companion function for `.parsePath` that returns - * the value located at the parsed address. - * - * var value = getPathValue(parsed, obj); - * - * @param {Object} parsed definition from `parsePath`. - * @param {Object} object to search against - * @param {Number} object to search against - * @returns {Object|Undefined} value - * @api private - */ - -function _getPathValue (parsed, obj, index) { - var tmp = obj - , res; - - index = (index === undefined ? parsed.length : index); - - for (var i = 0, l = index; i < l; i++) { - var part = parsed[i]; - if (tmp) { - if ('undefined' !== typeof part.p) - tmp = tmp[part.p]; - else if ('undefined' !== typeof part.i) - tmp = tmp[part.i]; - if (i == (l - 1)) res = tmp; - } else { - res = undefined; - } - } - return res; -} - -},{"./hasProperty":25}],23:[function(require,module,exports){ -/*! - * Chai - getPathValue utility - * Copyright(c) 2012-2014 Jake Luer - * @see https://github.com/logicalparadox/filtr - * MIT Licensed - */ - -var getPathInfo = require('./getPathInfo'); - -/** - * ### .getPathValue(path, object) - * - * This allows the retrieval of values in an - * object given a string path. - * - * var obj = { - * prop1: { - * arr: ['a', 'b', 'c'] - * , str: 'Hello' - * } - * , prop2: { - * arr: [ { nested: 'Universe' } ] - * , str: 'Hello again!' - * } - * } - * - * The following would be the results. - * - * getPathValue('prop1.str', obj); // Hello - * getPathValue('prop1.att[2]', obj); // b - * getPathValue('prop2.arr[0].nested', obj); // Universe - * - * @param {String} path - * @param {Object} object - * @returns {Object} value or `undefined` - * @namespace Utils - * @name getPathValue - * @api public - */ -module.exports = function(path, obj) { - var info = getPathInfo(path, obj); - return info.value; -}; - -},{"./getPathInfo":22}],24:[function(require,module,exports){ -/*! - * Chai - getProperties utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -/** - * ### .getProperties(object) - * - * This allows the retrieval of property names of an object, enumerable or not, - * inherited or not. - * - * @param {Object} object - * @returns {Array} - * @namespace Utils - * @name getProperties - * @api public - */ - -module.exports = function getProperties(object) { - var result = Object.getOwnPropertyNames(object); - - function addProperty(property) { - if (result.indexOf(property) === -1) { - result.push(property); - } - } - - var proto = Object.getPrototypeOf(object); - while (proto !== null) { - Object.getOwnPropertyNames(proto).forEach(addProperty); - proto = Object.getPrototypeOf(proto); - } - - return result; -}; - -},{}],25:[function(require,module,exports){ -/*! - * Chai - hasProperty utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -var type = require('type-detect'); - -/** - * ### .hasProperty(object, name) - * - * This allows checking whether an object has - * named property or numeric array index. - * - * Basically does the same thing as the `in` - * operator but works properly with natives - * and null/undefined values. - * - * var obj = { - * arr: ['a', 'b', 'c'] - * , str: 'Hello' - * } - * - * The following would be the results. - * - * hasProperty('str', obj); // true - * hasProperty('constructor', obj); // true - * hasProperty('bar', obj); // false - * - * hasProperty('length', obj.str); // true - * hasProperty(1, obj.str); // true - * hasProperty(5, obj.str); // false - * - * hasProperty('length', obj.arr); // true - * hasProperty(2, obj.arr); // true - * hasProperty(3, obj.arr); // false - * - * @param {Objuect} object - * @param {String|Number} name - * @returns {Boolean} whether it exists - * @namespace Utils - * @name getPathInfo - * @api public - */ - -var literals = { - 'number': Number - , 'string': String -}; - -module.exports = function hasProperty(name, obj) { - var ot = type(obj); - - // Bad Object, obviously no props at all - if(ot === 'null' || ot === 'undefined') - return false; - - // The `in` operator does not work with certain literals - // box these before the check - if(literals[ot] && typeof obj !== 'object') - obj = new literals[ot](obj); - - return name in obj; -}; - -},{"type-detect":40}],26:[function(require,module,exports){ -/*! - * chai - * Copyright(c) 2011 Jake Luer - * MIT Licensed - */ - -/*! - * Main exports - */ - -var exports = module.exports = {}; - -/*! - * test utility - */ - -exports.test = require('./test'); - -/*! - * type utility - */ - -exports.type = require('type-detect'); - -/*! - * expectTypes utility - */ -exports.expectTypes = require('./expectTypes'); - -/*! - * message utility - */ - -exports.getMessage = require('./getMessage'); - -/*! - * actual utility - */ - -exports.getActual = require('./getActual'); - -/*! - * Inspect util - */ - -exports.inspect = require('./inspect'); - -/*! - * Object Display util - */ - -exports.objDisplay = require('./objDisplay'); - -/*! - * Flag utility - */ - -exports.flag = require('./flag'); - -/*! - * Flag transferring utility - */ - -exports.transferFlags = require('./transferFlags'); - -/*! - * Deep equal utility - */ - -exports.eql = require('deep-eql'); - -/*! - * Deep path value - */ - -exports.getPathValue = require('./getPathValue'); - -/*! - * Deep path info - */ - -exports.getPathInfo = require('./getPathInfo'); - -/*! - * Check if a property exists - */ - -exports.hasProperty = require('./hasProperty'); - -/*! - * Function name - */ - -exports.getName = require('./getName'); - -/*! - * add Property - */ - -exports.addProperty = require('./addProperty'); - -/*! - * add Method - */ - -exports.addMethod = require('./addMethod'); - -/*! - * overwrite Property - */ - -exports.overwriteProperty = require('./overwriteProperty'); - -/*! - * overwrite Method - */ - -exports.overwriteMethod = require('./overwriteMethod'); - -/*! - * Add a chainable method - */ - -exports.addChainableMethod = require('./addChainableMethod'); - -/*! - * Overwrite chainable method - */ - -exports.overwriteChainableMethod = require('./overwriteChainableMethod'); - -},{"./addChainableMethod":13,"./addMethod":14,"./addProperty":15,"./expectTypes":16,"./flag":17,"./getActual":18,"./getMessage":20,"./getName":21,"./getPathInfo":22,"./getPathValue":23,"./hasProperty":25,"./inspect":27,"./objDisplay":28,"./overwriteChainableMethod":29,"./overwriteMethod":30,"./overwriteProperty":31,"./test":32,"./transferFlags":33,"deep-eql":35,"type-detect":40}],27:[function(require,module,exports){ -// This is (almost) directly from Node.js utils -// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js - -var getName = require('./getName'); -var getProperties = require('./getProperties'); -var getEnumerableProperties = require('./getEnumerableProperties'); - -module.exports = inspect; - -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Boolean} showHidden Flag that shows hidden (not enumerable) - * properties of objects. - * @param {Number} depth Depth in which to descend in object. Default is 2. - * @param {Boolean} colors Flag to turn on ANSI escape codes to color the - * output. Default is false (no coloring). - * @namespace Utils - * @name inspect - */ -function inspect(obj, showHidden, depth, colors) { - var ctx = { - showHidden: showHidden, - seen: [], - stylize: function (str) { return str; } - }; - return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth)); -} - -// Returns true if object is a DOM element. -var isDOMElement = function (object) { - if (typeof HTMLElement === 'object') { - return object instanceof HTMLElement; - } else { - return object && - typeof object === 'object' && - object.nodeType === 1 && - typeof object.nodeName === 'string'; - } -}; - -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (value && typeof value.inspect === 'function' && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes); - if (typeof ret !== 'string') { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; - } - - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } - - // If this is a DOM element, try to get the outer HTML. - if (isDOMElement(value)) { - if ('outerHTML' in value) { - return value.outerHTML; - // This value does not have an outerHTML attribute, - // it could still be an XML element - } else { - // Attempt to serialize it - try { - if (document.xmlVersion) { - var xmlSerializer = new XMLSerializer(); - return xmlSerializer.serializeToString(value); - } else { - // Firefox 11- do not support outerHTML - // It does, however, support innerHTML - // Use the following to render the element - var ns = "http://www.w3.org/1999/xhtml"; - var container = document.createElementNS(ns, '_'); - - container.appendChild(value.cloneNode(false)); - html = container.innerHTML - .replace('><', '>' + value.innerHTML + '<'); - container.innerHTML = ''; - return html; - } - } catch (err) { - // This could be a non-native DOM implementation, - // continue with the normal flow: - // printing the element as if it is an object. - } - } - } - - // Look up the keys of the object. - var visibleKeys = getEnumerableProperties(value); - var keys = ctx.showHidden ? getProperties(value) : visibleKeys; - - // Some type of object without properties can be shortcutted. - // In IE, errors have a single `stack` property, or if they are vanilla `Error`, - // a `stack` plus `description` property; ignore those for consistency. - if (keys.length === 0 || (isError(value) && ( - (keys.length === 1 && keys[0] === 'stack') || - (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack') - ))) { - if (typeof value === 'function') { - var name = getName(value); - var nameSuffix = name ? ': ' + name : ''; - return ctx.stylize('[Function' + nameSuffix + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toUTCString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } - - var base = '', array = false, braces = ['{', '}']; - - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } - - // Make functions say that they are functions - if (typeof value === 'function') { - var name = getName(value); - var nameSuffix = name ? ': ' + name : ''; - base = ' [Function' + nameSuffix + ']'; - } - - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } - - // Make error with message first say the error - if (isError(value)) { - return formatError(value); - } - - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } - } - - ctx.seen.push(value); - - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); - } - - ctx.seen.pop(); - - return reduceToSingleString(output, base, braces); -} - - -function formatPrimitive(ctx, value) { - switch (typeof value) { - case 'undefined': - return ctx.stylize('undefined', 'undefined'); - - case 'string': - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - - case 'number': - if (value === 0 && (1/value) === -Infinity) { - return ctx.stylize('-0', 'number'); - } - return ctx.stylize('' + value, 'number'); - - case 'boolean': - return ctx.stylize('' + value, 'boolean'); - } - // For some reason typeof null is "object", so special case here. - if (value === null) { - return ctx.stylize('null', 'null'); - } -} - - -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; -} - - -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (Object.prototype.hasOwnProperty.call(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} - - -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str; - if (value.__lookupGetter__) { - if (value.__lookupGetter__(key)) { - if (value.__lookupSetter__(key)) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (value.__lookupSetter__(key)) { - str = ctx.stylize('[Setter]', 'special'); - } - } - } - if (visibleKeys.indexOf(key) < 0) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(value[key]) < 0) { - if (recurseTimes === null) { - str = formatValue(ctx, value[key], null); - } else { - str = formatValue(ctx, value[key], recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (typeof name === 'undefined') { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } - } - - return name + ': ' + str; -} - - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.length + 1; - }, 0); - - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; - } - - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} - -function isArray(ar) { - return Array.isArray(ar) || - (typeof ar === 'object' && objectToString(ar) === '[object Array]'); -} - -function isRegExp(re) { - return typeof re === 'object' && objectToString(re) === '[object RegExp]'; -} - -function isDate(d) { - return typeof d === 'object' && objectToString(d) === '[object Date]'; -} - -function isError(e) { - return typeof e === 'object' && objectToString(e) === '[object Error]'; -} - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - -},{"./getEnumerableProperties":19,"./getName":21,"./getProperties":24}],28:[function(require,module,exports){ -/*! - * Chai - flag utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -/*! - * Module dependancies - */ - -var inspect = require('./inspect'); -var config = require('../config'); - -/** - * ### .objDisplay (object) - * - * Determines if an object or an array matches - * criteria to be inspected in-line for error - * messages or should be truncated. - * - * @param {Mixed} javascript object to inspect - * @name objDisplay - * @namespace Utils - * @api public - */ - -module.exports = function (obj) { - var str = inspect(obj) - , type = Object.prototype.toString.call(obj); - - if (config.truncateThreshold && str.length >= config.truncateThreshold) { - if (type === '[object Function]') { - return !obj.name || obj.name === '' - ? '[Function]' - : '[Function: ' + obj.name + ']'; - } else if (type === '[object Array]') { - return '[ Array(' + obj.length + ') ]'; - } else if (type === '[object Object]') { - var keys = Object.keys(obj) - , kstr = keys.length > 2 - ? keys.splice(0, 2).join(', ') + ', ...' - : keys.join(', '); - return '{ Object (' + kstr + ') }'; - } else { - return str; - } - } else { - return str; - } -}; - -},{"../config":8,"./inspect":27}],29:[function(require,module,exports){ -/*! - * Chai - overwriteChainableMethod utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -/** - * ### overwriteChainableMethod (ctx, name, method, chainingBehavior) - * - * Overwites an already existing chainable method - * and provides access to the previous function or - * property. Must return functions to be used for - * name. - * - * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length', - * function (_super) { - * } - * , function (_super) { - * } - * ); - * - * Can also be accessed directly from `chai.Assertion`. - * - * chai.Assertion.overwriteChainableMethod('foo', fn, fn); - * - * Then can be used as any other assertion. - * - * expect(myFoo).to.have.length(3); - * expect(myFoo).to.have.length.above(3); - * - * @param {Object} ctx object whose method / property is to be overwritten - * @param {String} name of method / property to overwrite - * @param {Function} method function that returns a function to be used for name - * @param {Function} chainingBehavior function that returns a function to be used for property - * @namespace Utils - * @name overwriteChainableMethod - * @api public - */ - -module.exports = function (ctx, name, method, chainingBehavior) { - var chainableBehavior = ctx.__methods[name]; - - var _chainingBehavior = chainableBehavior.chainingBehavior; - chainableBehavior.chainingBehavior = function () { - var result = chainingBehavior(_chainingBehavior).call(this); - return result === undefined ? this : result; - }; - - var _method = chainableBehavior.method; - chainableBehavior.method = function () { - var result = method(_method).apply(this, arguments); - return result === undefined ? this : result; - }; -}; - -},{}],30:[function(require,module,exports){ -/*! - * Chai - overwriteMethod utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -/** - * ### overwriteMethod (ctx, name, fn) - * - * Overwites an already existing method and provides - * access to previous function. Must return function - * to be used for name. - * - * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) { - * return function (str) { - * var obj = utils.flag(this, 'object'); - * if (obj instanceof Foo) { - * new chai.Assertion(obj.value).to.equal(str); - * } else { - * _super.apply(this, arguments); - * } - * } - * }); - * - * Can also be accessed directly from `chai.Assertion`. - * - * chai.Assertion.overwriteMethod('foo', fn); - * - * Then can be used as any other assertion. - * - * expect(myFoo).to.equal('bar'); - * - * @param {Object} ctx object whose method is to be overwritten - * @param {String} name of method to overwrite - * @param {Function} method function that returns a function to be used for name - * @namespace Utils - * @name overwriteMethod - * @api public - */ - -module.exports = function (ctx, name, method) { - var _method = ctx[name] - , _super = function () { return this; }; - - if (_method && 'function' === typeof _method) - _super = _method; - - ctx[name] = function () { - var result = method(_super).apply(this, arguments); - return result === undefined ? this : result; - } -}; - -},{}],31:[function(require,module,exports){ -/*! - * Chai - overwriteProperty utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -/** - * ### overwriteProperty (ctx, name, fn) - * - * Overwites an already existing property getter and provides - * access to previous value. Must return function to use as getter. - * - * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) { - * return function () { - * var obj = utils.flag(this, 'object'); - * if (obj instanceof Foo) { - * new chai.Assertion(obj.name).to.equal('bar'); - * } else { - * _super.call(this); - * } - * } - * }); - * - * - * Can also be accessed directly from `chai.Assertion`. - * - * chai.Assertion.overwriteProperty('foo', fn); - * - * Then can be used as any other assertion. - * - * expect(myFoo).to.be.ok; - * - * @param {Object} ctx object whose property is to be overwritten - * @param {String} name of property to overwrite - * @param {Function} getter function that returns a getter function to be used for name - * @namespace Utils - * @name overwriteProperty - * @api public - */ - -module.exports = function (ctx, name, getter) { - var _get = Object.getOwnPropertyDescriptor(ctx, name) - , _super = function () {}; - - if (_get && 'function' === typeof _get.get) - _super = _get.get - - Object.defineProperty(ctx, name, - { get: function () { - var result = getter(_super).call(this); - return result === undefined ? this : result; - } - , configurable: true - }); -}; - -},{}],32:[function(require,module,exports){ -/*! - * Chai - test utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -/*! - * Module dependancies - */ - -var flag = require('./flag'); - -/** - * # test(object, expression) - * - * Test and object for expression. - * - * @param {Object} object (constructed Assertion) - * @param {Arguments} chai.Assertion.prototype.assert arguments - * @namespace Utils - * @name test - */ - -module.exports = function (obj, args) { - var negate = flag(obj, 'negate') - , expr = args[0]; - return negate ? !expr : expr; -}; - -},{"./flag":17}],33:[function(require,module,exports){ -/*! - * Chai - transferFlags utility - * Copyright(c) 2012-2014 Jake Luer - * MIT Licensed - */ - -/** - * ### transferFlags(assertion, object, includeAll = true) - * - * Transfer all the flags for `assertion` to `object`. If - * `includeAll` is set to `false`, then the base Chai - * assertion flags (namely `object`, `ssfi`, and `message`) - * will not be transferred. - * - * - * var newAssertion = new Assertion(); - * utils.transferFlags(assertion, newAssertion); - * - * var anotherAsseriton = new Assertion(myObj); - * utils.transferFlags(assertion, anotherAssertion, false); - * - * @param {Assertion} assertion the assertion to transfer the flags from - * @param {Object} object the object to transfer the flags to; usually a new assertion - * @param {Boolean} includeAll - * @namespace Utils - * @name transferFlags - * @api private - */ - -module.exports = function (assertion, object, includeAll) { - var flags = assertion.__flags || (assertion.__flags = Object.create(null)); - - if (!object.__flags) { - object.__flags = Object.create(null); - } - - includeAll = arguments.length === 3 ? includeAll : true; - - for (var flag in flags) { - if (includeAll || - (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) { - object.__flags[flag] = flags[flag]; - } - } -}; - -},{}],34:[function(require,module,exports){ -"use strict"; - -function dedent(strings) { - - var raw = void 0; - if (typeof strings === "string") { - // dedent can be used as a plain function - raw = [strings]; - } else { - raw = strings.raw; - } - - // first, perform interpolation - var result = ""; - for (var i = 0; i < raw.length; i++) { - result += raw[i]. - // join lines when there is a suppressed newline - replace(/\\\n[ \t]*/g, ""). - - // handle escaped backticks - replace(/\\`/g, "`"); - - if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) { - result += arguments.length <= i + 1 ? undefined : arguments[i + 1]; - } - } - - // now strip indentation - var lines = result.split("\n"); - var mindent = null; - lines.forEach(function (l) { - var m = l.match(/^(\s+)\S+/); - if (m) { - var indent = m[1].length; - if (!mindent) { - // this is the first indented line - mindent = indent; - } else { - mindent = Math.min(mindent, indent); - } - } - }); - - if (mindent !== null) { - result = lines.map(function (l) { - return l[0] === " " ? l.slice(mindent) : l; - }).join("\n"); - } - - // dedent eats leading and trailing whitespace too - result = result.trim(); - - // handle escaped newlines at the end to ensure they don't get stripped too - return result.replace(/\\n/g, "\n"); -} - -if (typeof module !== "undefined") { - module.exports = dedent; -} - -},{}],35:[function(require,module,exports){ -module.exports = require('./lib/eql'); - -},{"./lib/eql":36}],36:[function(require,module,exports){ -/*! - * deep-eql - * Copyright(c) 2013 Jake Luer - * MIT Licensed - */ - -/*! - * Module dependencies - */ - -var type = require('type-detect'); - -/*! - * Buffer.isBuffer browser shim - */ - -var Buffer; -try { Buffer = require('buffer').Buffer; } -catch(ex) { - Buffer = {}; - Buffer.isBuffer = function() { return false; } -} - -/*! - * Primary Export - */ - -module.exports = deepEqual; - -/** - * Assert super-strict (egal) equality between - * two objects of any type. - * - * @param {Mixed} a - * @param {Mixed} b - * @param {Array} memoised (optional) - * @return {Boolean} equal match - */ - -function deepEqual(a, b, m) { - if (sameValue(a, b)) { - return true; - } else if ('date' === type(a)) { - return dateEqual(a, b); - } else if ('regexp' === type(a)) { - return regexpEqual(a, b); - } else if (Buffer.isBuffer(a)) { - return bufferEqual(a, b); - } else if ('arguments' === type(a)) { - return argumentsEqual(a, b, m); - } else if (!typeEqual(a, b)) { - return false; - } else if (('object' !== type(a) && 'object' !== type(b)) - && ('array' !== type(a) && 'array' !== type(b))) { - return sameValue(a, b); - } else { - return objectEqual(a, b, m); - } -} - -/*! - * Strict (egal) equality test. Ensures that NaN always - * equals NaN and `-0` does not equal `+0`. - * - * @param {Mixed} a - * @param {Mixed} b - * @return {Boolean} equal match - */ - -function sameValue(a, b) { - if (a === b) return a !== 0 || 1 / a === 1 / b; - return a !== a && b !== b; -} - -/*! - * Compare the types of two given objects and - * return if they are equal. Note that an Array - * has a type of `array` (not `object`) and arguments - * have a type of `arguments` (not `array`/`object`). - * - * @param {Mixed} a - * @param {Mixed} b - * @return {Boolean} result - */ - -function typeEqual(a, b) { - return type(a) === type(b); -} - -/*! - * Compare two Date objects by asserting that - * the time values are equal using `saveValue`. - * - * @param {Date} a - * @param {Date} b - * @return {Boolean} result - */ - -function dateEqual(a, b) { - if ('date' !== type(b)) return false; - return sameValue(a.getTime(), b.getTime()); -} - -/*! - * Compare two regular expressions by converting them - * to string and checking for `sameValue`. - * - * @param {RegExp} a - * @param {RegExp} b - * @return {Boolean} result - */ - -function regexpEqual(a, b) { - if ('regexp' !== type(b)) return false; - return sameValue(a.toString(), b.toString()); -} - -/*! - * Assert deep equality of two `arguments` objects. - * Unfortunately, these must be sliced to arrays - * prior to test to ensure no bad behavior. - * - * @param {Arguments} a - * @param {Arguments} b - * @param {Array} memoize (optional) - * @return {Boolean} result - */ - -function argumentsEqual(a, b, m) { - if ('arguments' !== type(b)) return false; - a = [].slice.call(a); - b = [].slice.call(b); - return deepEqual(a, b, m); -} - -/*! - * Get enumerable properties of a given object. - * - * @param {Object} a - * @return {Array} property names - */ - -function enumerable(a) { - var res = []; - for (var key in a) res.push(key); - return res; -} - -/*! - * Simple equality for flat iterable objects - * such as Arrays or Node.js buffers. - * - * @param {Iterable} a - * @param {Iterable} b - * @return {Boolean} result - */ - -function iterableEqual(a, b) { - if (a.length !== b.length) return false; - - var i = 0; - var match = true; - - for (; i < a.length; i++) { - if (a[i] !== b[i]) { - match = false; - break; - } - } - - return match; -} - -/*! - * Extension to `iterableEqual` specifically - * for Node.js Buffers. - * - * @param {Buffer} a - * @param {Mixed} b - * @return {Boolean} result - */ - -function bufferEqual(a, b) { - if (!Buffer.isBuffer(b)) return false; - return iterableEqual(a, b); -} - -/*! - * Block for `objectEqual` ensuring non-existing - * values don't get in. - * - * @param {Mixed} object - * @return {Boolean} result - */ - -function isValue(a) { - return a !== null && a !== undefined; -} - -/*! - * Recursively check the equality of two objects. - * Once basic sameness has been established it will - * defer to `deepEqual` for each enumerable key - * in the object. - * - * @param {Mixed} a - * @param {Mixed} b - * @return {Boolean} result - */ - -function objectEqual(a, b, m) { - if (!isValue(a) || !isValue(b)) { - return false; - } - - if (a.prototype !== b.prototype) { - return false; - } - - var i; - if (m) { - for (i = 0; i < m.length; i++) { - if ((m[i][0] === a && m[i][1] === b) - || (m[i][0] === b && m[i][1] === a)) { - return true; - } - } - } else { - m = []; - } - - try { - var ka = enumerable(a); - var kb = enumerable(b); - } catch (ex) { - return false; - } - - ka.sort(); - kb.sort(); - - if (!iterableEqual(ka, kb)) { - return false; - } - - m.push([ a, b ]); - - var key; - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!deepEqual(a[key], b[key], m)) { - return false; - } - } - - return true; -} - -},{"buffer":undefined,"type-detect":38}],37:[function(require,module,exports){ -(function (global){ -/*! - localForage -- Offline Storage, Improved - Version 1.5.0 - https://localforage.github.io/localForage - (c) 2013-2017 Mozilla, Apache License 2.0 -*/ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.localforage = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw (f.code="MODULE_NOT_FOUND", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o element; its readystatechange event will be fired asynchronously once it is inserted - // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called. - var scriptEl = global.document.createElement('script'); - scriptEl.onreadystatechange = function () { - nextTick(); - - scriptEl.onreadystatechange = null; - scriptEl.parentNode.removeChild(scriptEl); - scriptEl = null; - }; - global.document.documentElement.appendChild(scriptEl); - }; - } else { - scheduleDrain = function () { - setTimeout(nextTick, 0); - }; - } -} - -var draining; -var queue = []; -//named nextTick for less confusing stack traces -function nextTick() { - draining = true; - var i, oldQueue; - var len = queue.length; - while (len) { - oldQueue = queue; - queue = []; - i = -1; - while (++i < len) { - oldQueue[i](); - } - len = queue.length; - } - draining = false; -} - -module.exports = immediate; -function immediate(task) { - if (queue.push(task) === 1 && !draining) { - scheduleDrain(); - } -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],2:[function(_dereq_,module,exports){ -'use strict'; -var immediate = _dereq_(1); - -/* istanbul ignore next */ -function INTERNAL() {} - -var handlers = {}; - -var REJECTED = ['REJECTED']; -var FULFILLED = ['FULFILLED']; -var PENDING = ['PENDING']; - -module.exports = exports = Promise; - -function Promise(resolver) { - if (typeof resolver !== 'function') { - throw new TypeError('resolver must be a function'); - } - this.state = PENDING; - this.queue = []; - this.outcome = void 0; - if (resolver !== INTERNAL) { - safelyResolveThenable(this, resolver); - } -} - -Promise.prototype["catch"] = function (onRejected) { - return this.then(null, onRejected); -}; -Promise.prototype.then = function (onFulfilled, onRejected) { - if (typeof onFulfilled !== 'function' && this.state === FULFILLED || - typeof onRejected !== 'function' && this.state === REJECTED) { - return this; - } - var promise = new this.constructor(INTERNAL); - if (this.state !== PENDING) { - var resolver = this.state === FULFILLED ? onFulfilled : onRejected; - unwrap(promise, resolver, this.outcome); - } else { - this.queue.push(new QueueItem(promise, onFulfilled, onRejected)); - } - - return promise; -}; -function QueueItem(promise, onFulfilled, onRejected) { - this.promise = promise; - if (typeof onFulfilled === 'function') { - this.onFulfilled = onFulfilled; - this.callFulfilled = this.otherCallFulfilled; - } - if (typeof onRejected === 'function') { - this.onRejected = onRejected; - this.callRejected = this.otherCallRejected; - } -} -QueueItem.prototype.callFulfilled = function (value) { - handlers.resolve(this.promise, value); -}; -QueueItem.prototype.otherCallFulfilled = function (value) { - unwrap(this.promise, this.onFulfilled, value); -}; -QueueItem.prototype.callRejected = function (value) { - handlers.reject(this.promise, value); -}; -QueueItem.prototype.otherCallRejected = function (value) { - unwrap(this.promise, this.onRejected, value); -}; - -function unwrap(promise, func, value) { - immediate(function () { - var returnValue; - try { - returnValue = func(value); - } catch (e) { - return handlers.reject(promise, e); - } - if (returnValue === promise) { - handlers.reject(promise, new TypeError('Cannot resolve promise with itself')); - } else { - handlers.resolve(promise, returnValue); - } - }); -} - -handlers.resolve = function (self, value) { - var result = tryCatch(getThen, value); - if (result.status === 'error') { - return handlers.reject(self, result.value); - } - var thenable = result.value; - - if (thenable) { - safelyResolveThenable(self, thenable); - } else { - self.state = FULFILLED; - self.outcome = value; - var i = -1; - var len = self.queue.length; - while (++i < len) { - self.queue[i].callFulfilled(value); - } - } - return self; -}; -handlers.reject = function (self, error) { - self.state = REJECTED; - self.outcome = error; - var i = -1; - var len = self.queue.length; - while (++i < len) { - self.queue[i].callRejected(error); - } - return self; -}; - -function getThen(obj) { - // Make sure we only access the accessor once as required by the spec - var then = obj && obj.then; - if (obj && typeof obj === 'object' && typeof then === 'function') { - return function appyThen() { - then.apply(obj, arguments); - }; - } -} - -function safelyResolveThenable(self, thenable) { - // Either fulfill, reject or reject with error - var called = false; - function onError(value) { - if (called) { - return; - } - called = true; - handlers.reject(self, value); - } - - function onSuccess(value) { - if (called) { - return; - } - called = true; - handlers.resolve(self, value); - } - - function tryToUnwrap() { - thenable(onSuccess, onError); - } - - var result = tryCatch(tryToUnwrap); - if (result.status === 'error') { - onError(result.value); - } -} - -function tryCatch(func, value) { - var out = {}; - try { - out.value = func(value); - out.status = 'success'; - } catch (e) { - out.status = 'error'; - out.value = e; - } - return out; -} - -exports.resolve = resolve; -function resolve(value) { - if (value instanceof this) { - return value; - } - return handlers.resolve(new this(INTERNAL), value); -} - -exports.reject = reject; -function reject(reason) { - var promise = new this(INTERNAL); - return handlers.reject(promise, reason); -} - -exports.all = all; -function all(iterable) { - var self = this; - if (Object.prototype.toString.call(iterable) !== '[object Array]') { - return this.reject(new TypeError('must be an array')); - } - - var len = iterable.length; - var called = false; - if (!len) { - return this.resolve([]); - } - - var values = new Array(len); - var resolved = 0; - var i = -1; - var promise = new this(INTERNAL); - - while (++i < len) { - allResolver(iterable[i], i); - } - return promise; - function allResolver(value, i) { - self.resolve(value).then(resolveFromAll, function (error) { - if (!called) { - called = true; - handlers.reject(promise, error); - } - }); - function resolveFromAll(outValue) { - values[i] = outValue; - if (++resolved === len && !called) { - called = true; - handlers.resolve(promise, values); - } - } - } -} - -exports.race = race; -function race(iterable) { - var self = this; - if (Object.prototype.toString.call(iterable) !== '[object Array]') { - return this.reject(new TypeError('must be an array')); - } - - var len = iterable.length; - var called = false; - if (!len) { - return this.resolve([]); - } - - var i = -1; - var promise = new this(INTERNAL); - - while (++i < len) { - resolver(iterable[i]); - } - return promise; - function resolver(value) { - self.resolve(value).then(function (response) { - if (!called) { - called = true; - handlers.resolve(promise, response); - } - }, function (error) { - if (!called) { - called = true; - handlers.reject(promise, error); - } - }); - } -} - -},{"1":1}],3:[function(_dereq_,module,exports){ -(function (global){ -'use strict'; -if (typeof global.Promise !== 'function') { - global.Promise = _dereq_(2); -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"2":2}],4:[function(_dereq_,module,exports){ -'use strict'; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -function getIDB() { - /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */ - try { - if (typeof indexedDB !== 'undefined') { - return indexedDB; - } - if (typeof webkitIndexedDB !== 'undefined') { - return webkitIndexedDB; - } - if (typeof mozIndexedDB !== 'undefined') { - return mozIndexedDB; - } - if (typeof OIndexedDB !== 'undefined') { - return OIndexedDB; - } - if (typeof msIndexedDB !== 'undefined') { - return msIndexedDB; - } - } catch (e) {} -} - -var idb = getIDB(); - -function isIndexedDBValid() { - try { - // Initialize IndexedDB; fall back to vendor-prefixed versions - // if needed. - if (!idb) { - return false; - } - // We mimic PouchDB here; - // - // We test for openDatabase because IE Mobile identifies itself - // as Safari. Oh the lulz... - var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform); - - var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1; - - // Safari <10.1 does not meet our requirements for IDB support (#5572) - // since Safari 10.1 shipped with fetch, we can use that to detect it - return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' && - // some outdated implementations of IDB that appear on Samsung - // and HTC Android devices <4.4 are missing IDBKeyRange - typeof IDBKeyRange !== 'undefined'; - } catch (e) { - return false; - } -} - -function isWebSQLValid() { - return typeof openDatabase === 'function'; -} - -function isLocalStorageValid() { - try { - return typeof localStorage !== 'undefined' && 'setItem' in localStorage && localStorage.setItem; - } catch (e) { - return false; - } -} - -// Abstracts constructing a Blob object, so it also works in older -// browsers that don't support the native Blob constructor. (i.e. -// old QtWebKit versions, at least). -// Abstracts constructing a Blob object, so it also works in older -// browsers that don't support the native Blob constructor. (i.e. -// old QtWebKit versions, at least). -function createBlob(parts, properties) { - /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */ - parts = parts || []; - properties = properties || {}; - try { - return new Blob(parts, properties); - } catch (e) { - if (e.name !== 'TypeError') { - throw e; - } - var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder; - var builder = new Builder(); - for (var i = 0; i < parts.length; i += 1) { - builder.append(parts[i]); - } - return builder.getBlob(properties.type); - } -} - -// This is CommonJS because lie is an external dependency, so Rollup -// can just ignore it. -if (typeof Promise === 'undefined') { - // In the "nopromises" build this will just throw if you don't have - // a global promise object, but it would throw anyway later. - _dereq_(3); -} -var Promise$1 = Promise; - -function executeCallback(promise, callback) { - if (callback) { - promise.then(function (result) { - callback(null, result); - }, function (error) { - callback(error); - }); - } -} - -function executeTwoCallbacks(promise, callback, errorCallback) { - if (typeof callback === 'function') { - promise.then(callback); - } - - if (typeof errorCallback === 'function') { - promise["catch"](errorCallback); - } -} - -// Some code originally from async_storage.js in -// [Gaia](https://github.com/mozilla-b2g/gaia). - -var DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support'; -var supportsBlobs; -var dbContexts; -var toString = Object.prototype.toString; - -// Transform a binary string to an array buffer, because otherwise -// weird stuff happens when you try to work with the binary string directly. -// It is known. -// From http://stackoverflow.com/questions/14967647/ (continues on next line) -// encode-decode-image-with-base64-breaks-image (2013-04-21) -function _binStringToArrayBuffer(bin) { - var length = bin.length; - var buf = new ArrayBuffer(length); - var arr = new Uint8Array(buf); - for (var i = 0; i < length; i++) { - arr[i] = bin.charCodeAt(i); - } - return buf; -} - -// -// Blobs are not supported in all versions of IndexedDB, notably -// Chrome <37 and Android <5. In those versions, storing a blob will throw. -// -// Various other blob bugs exist in Chrome v37-42 (inclusive). -// Detecting them is expensive and confusing to users, and Chrome 37-42 -// is at very low usage worldwide, so we do a hacky userAgent check instead. -// -// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120 -// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916 -// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836 -// -// Code borrowed from PouchDB. See: -// https://github.com/pouchdb/pouchdb/blob/master/packages/node_modules/pouchdb-adapter-idb/src/blobSupport.js -// -function _checkBlobSupportWithoutCaching(idb) { - return new Promise$1(function (resolve) { - var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, 'readwrite'); - var blob = createBlob(['']); - txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key'); - - txn.onabort = function (e) { - // If the transaction aborts now its due to not being able to - // write to the database, likely due to the disk being full - e.preventDefault(); - e.stopPropagation(); - resolve(false); - }; - - txn.oncomplete = function () { - var matchedChrome = navigator.userAgent.match(/Chrome\/(\d+)/); - var matchedEdge = navigator.userAgent.match(/Edge\//); - // MS Edge pretends to be Chrome 42: - // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx - resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43); - }; - })["catch"](function () { - return false; // error, so assume unsupported - }); -} - -function _checkBlobSupport(idb) { - if (typeof supportsBlobs === 'boolean') { - return Promise$1.resolve(supportsBlobs); - } - return _checkBlobSupportWithoutCaching(idb).then(function (value) { - supportsBlobs = value; - return supportsBlobs; - }); -} - -function _deferReadiness(dbInfo) { - var dbContext = dbContexts[dbInfo.name]; - - // Create a deferred object representing the current database operation. - var deferredOperation = {}; - - deferredOperation.promise = new Promise$1(function (resolve) { - deferredOperation.resolve = resolve; - }); - - // Enqueue the deferred operation. - dbContext.deferredOperations.push(deferredOperation); - - // Chain its promise to the database readiness. - if (!dbContext.dbReady) { - dbContext.dbReady = deferredOperation.promise; - } else { - dbContext.dbReady = dbContext.dbReady.then(function () { - return deferredOperation.promise; - }); - } -} - -function _advanceReadiness(dbInfo) { - var dbContext = dbContexts[dbInfo.name]; - - // Dequeue a deferred operation. - var deferredOperation = dbContext.deferredOperations.pop(); - - // Resolve its promise (which is part of the database readiness - // chain of promises). - if (deferredOperation) { - deferredOperation.resolve(); - } -} - -function _getConnection(dbInfo, upgradeNeeded) { - return new Promise$1(function (resolve, reject) { - - if (dbInfo.db) { - if (upgradeNeeded) { - _deferReadiness(dbInfo); - dbInfo.db.close(); - } else { - return resolve(dbInfo.db); - } - } - - var dbArgs = [dbInfo.name]; - - if (upgradeNeeded) { - dbArgs.push(dbInfo.version); - } - - var openreq = idb.open.apply(idb, dbArgs); - - if (upgradeNeeded) { - openreq.onupgradeneeded = function (e) { - var db = openreq.result; - try { - db.createObjectStore(dbInfo.storeName); - if (e.oldVersion <= 1) { - // Added when support for blob shims was added - db.createObjectStore(DETECT_BLOB_SUPPORT_STORE); - } - } catch (ex) { - if (ex.name === 'ConstraintError') { - console.warn('The database "' + dbInfo.name + '"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage "' + dbInfo.storeName + '" already exists.'); - } else { - throw ex; - } - } - }; - } - - openreq.onerror = function (e) { - e.preventDefault(); - reject(openreq.error); - }; - - openreq.onsuccess = function () { - resolve(openreq.result); - _advanceReadiness(dbInfo); - }; - }); -} - -function _getOriginalConnection(dbInfo) { - return _getConnection(dbInfo, false); -} - -function _getUpgradedConnection(dbInfo) { - return _getConnection(dbInfo, true); -} - -function _isUpgradeNeeded(dbInfo, defaultVersion) { - if (!dbInfo.db) { - return true; - } - - var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName); - var isDowngrade = dbInfo.version < dbInfo.db.version; - var isUpgrade = dbInfo.version > dbInfo.db.version; - - if (isDowngrade) { - // If the version is not the default one - // then warn for impossible downgrade. - if (dbInfo.version !== defaultVersion) { - console.warn('The database "' + dbInfo.name + '"' + ' can\'t be downgraded from version ' + dbInfo.db.version + ' to version ' + dbInfo.version + '.'); - } - // Align the versions to prevent errors. - dbInfo.version = dbInfo.db.version; - } - - if (isUpgrade || isNewStore) { - // If the store is new then increment the version (if needed). - // This will trigger an "upgradeneeded" event which is required - // for creating a store. - if (isNewStore) { - var incVersion = dbInfo.db.version + 1; - if (incVersion > dbInfo.version) { - dbInfo.version = incVersion; - } - } - - return true; - } - - return false; -} - -// encode a blob for indexeddb engines that don't support blobs -function _encodeBlob(blob) { - return new Promise$1(function (resolve, reject) { - var reader = new FileReader(); - reader.onerror = reject; - reader.onloadend = function (e) { - var base64 = btoa(e.target.result || ''); - resolve({ - __local_forage_encoded_blob: true, - data: base64, - type: blob.type - }); - }; - reader.readAsBinaryString(blob); - }); -} - -// decode an encoded blob -function _decodeBlob(encodedBlob) { - var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data)); - return createBlob([arrayBuff], { type: encodedBlob.type }); -} - -// is this one of our fancy encoded blobs? -function _isEncodedBlob(value) { - return value && value.__local_forage_encoded_blob; -} - -// Specialize the default `ready()` function by making it dependent -// on the current database operations. Thus, the driver will be actually -// ready when it's been initialized (default) *and* there are no pending -// operations on the database (initiated by some other instances). -function _fullyReady(callback) { - var self = this; - - var promise = self._initReady().then(function () { - var dbContext = dbContexts[self._dbInfo.name]; - - if (dbContext && dbContext.dbReady) { - return dbContext.dbReady; - } - }); - - executeTwoCallbacks(promise, callback, callback); - return promise; -} - -// Open the IndexedDB database (automatically creates one if one didn't -// previously exist), using any options set in the config. -function _initStorage(options) { - var self = this; - var dbInfo = { - db: null - }; - - if (options) { - for (var i in options) { - dbInfo[i] = options[i]; - } - } - - // Initialize a singleton container for all running localForages. - if (!dbContexts) { - dbContexts = {}; - } - - // Get the current context of the database; - var dbContext = dbContexts[dbInfo.name]; - - // ...or create a new context. - if (!dbContext) { - dbContext = { - // Running localForages sharing a database. - forages: [], - // Shared database. - db: null, - // Database readiness (promise). - dbReady: null, - // Deferred operations on the database. - deferredOperations: [] - }; - // Register the new context in the global container. - dbContexts[dbInfo.name] = dbContext; - } - - // Register itself as a running localForage in the current context. - dbContext.forages.push(self); - - // Replace the default `ready()` function with the specialized one. - if (!self._initReady) { - self._initReady = self.ready; - self.ready = _fullyReady; - } - - // Create an array of initialization states of the related localForages. - var initPromises = []; - - function ignoreErrors() { - // Don't handle errors here, - // just makes sure related localForages aren't pending. - return Promise$1.resolve(); - } - - for (var j = 0; j < dbContext.forages.length; j++) { - var forage = dbContext.forages[j]; - if (forage !== self) { - // Don't wait for itself... - initPromises.push(forage._initReady()["catch"](ignoreErrors)); - } - } - - // Take a snapshot of the related localForages. - var forages = dbContext.forages.slice(0); - - // Initialize the connection process only when - // all the related localForages aren't pending. - return Promise$1.all(initPromises).then(function () { - dbInfo.db = dbContext.db; - // Get the connection or open a new one without upgrade. - return _getOriginalConnection(dbInfo); - }).then(function (db) { - dbInfo.db = db; - if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) { - // Reopen the database for upgrading. - return _getUpgradedConnection(dbInfo); - } - return db; - }).then(function (db) { - dbInfo.db = dbContext.db = db; - self._dbInfo = dbInfo; - // Share the final connection amongst related localForages. - for (var k = 0; k < forages.length; k++) { - var forage = forages[k]; - if (forage !== self) { - // Self is already up-to-date. - forage._dbInfo.db = dbInfo.db; - forage._dbInfo.version = dbInfo.version; - } - } - }); -} - -function getItem(key, callback) { - var self = this; - - // Cast the key to a string, as that's all we can set as a key. - if (typeof key !== 'string') { - console.warn(key + ' used as a key, but it is not a string.'); - key = String(key); - } - - var promise = new Promise$1(function (resolve, reject) { - self.ready().then(function () { - var dbInfo = self._dbInfo; - var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName); - var req = store.get(key); - - req.onsuccess = function () { - var value = req.result; - if (value === undefined) { - value = null; - } - if (_isEncodedBlob(value)) { - value = _decodeBlob(value); - } - resolve(value); - }; - - req.onerror = function () { - reject(req.error); - }; - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -// Iterate over all items stored in database. -function iterate(iterator, callback) { - var self = this; - - var promise = new Promise$1(function (resolve, reject) { - self.ready().then(function () { - var dbInfo = self._dbInfo; - var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName); - - var req = store.openCursor(); - var iterationNumber = 1; - - req.onsuccess = function () { - var cursor = req.result; - - if (cursor) { - var value = cursor.value; - if (_isEncodedBlob(value)) { - value = _decodeBlob(value); - } - var result = iterator(value, cursor.key, iterationNumber++); - - if (result !== void 0) { - resolve(result); - } else { - cursor["continue"](); - } - } else { - resolve(); - } - }; - - req.onerror = function () { - reject(req.error); - }; - })["catch"](reject); - }); - - executeCallback(promise, callback); - - return promise; -} - -function setItem(key, value, callback) { - var self = this; - - // Cast the key to a string, as that's all we can set as a key. - if (typeof key !== 'string') { - console.warn(key + ' used as a key, but it is not a string.'); - key = String(key); - } - - var promise = new Promise$1(function (resolve, reject) { - var dbInfo; - self.ready().then(function () { - dbInfo = self._dbInfo; - if (toString.call(value) === '[object Blob]') { - return _checkBlobSupport(dbInfo.db).then(function (blobSupport) { - if (blobSupport) { - return value; - } - return _encodeBlob(value); - }); - } - return value; - }).then(function (value) { - var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite'); - var store = transaction.objectStore(dbInfo.storeName); - var req = store.put(value, key); - - // The reason we don't _save_ null is because IE 10 does - // not support saving the `null` type in IndexedDB. How - // ironic, given the bug below! - // See: https://github.com/mozilla/localForage/issues/161 - if (value === null) { - value = undefined; - } - - transaction.oncomplete = function () { - // Cast to undefined so the value passed to - // callback/promise is the same as what one would get out - // of `getItem()` later. This leads to some weirdness - // (setItem('foo', undefined) will return `null`), but - // it's not my fault localStorage is our baseline and that - // it's weird. - if (value === undefined) { - value = null; - } - - resolve(value); - }; - transaction.onabort = transaction.onerror = function () { - var err = req.error ? req.error : req.transaction.error; - reject(err); - }; - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -function removeItem(key, callback) { - var self = this; - - // Cast the key to a string, as that's all we can set as a key. - if (typeof key !== 'string') { - console.warn(key + ' used as a key, but it is not a string.'); - key = String(key); - } - - var promise = new Promise$1(function (resolve, reject) { - self.ready().then(function () { - var dbInfo = self._dbInfo; - var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite'); - var store = transaction.objectStore(dbInfo.storeName); - - // We use a Grunt task to make this safe for IE and some - // versions of Android (including those used by Cordova). - // Normally IE won't like `.delete()` and will insist on - // using `['delete']()`, but we have a build step that - // fixes this for us now. - var req = store["delete"](key); - transaction.oncomplete = function () { - resolve(); - }; - - transaction.onerror = function () { - reject(req.error); - }; - - // The request will be also be aborted if we've exceeded our storage - // space. - transaction.onabort = function () { - var err = req.error ? req.error : req.transaction.error; - reject(err); - }; - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -function clear(callback) { - var self = this; - - var promise = new Promise$1(function (resolve, reject) { - self.ready().then(function () { - var dbInfo = self._dbInfo; - var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite'); - var store = transaction.objectStore(dbInfo.storeName); - var req = store.clear(); - - transaction.oncomplete = function () { - resolve(); - }; - - transaction.onabort = transaction.onerror = function () { - var err = req.error ? req.error : req.transaction.error; - reject(err); - }; - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -function length(callback) { - var self = this; - - var promise = new Promise$1(function (resolve, reject) { - self.ready().then(function () { - var dbInfo = self._dbInfo; - var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName); - var req = store.count(); - - req.onsuccess = function () { - resolve(req.result); - }; - - req.onerror = function () { - reject(req.error); - }; - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -function key(n, callback) { - var self = this; - - var promise = new Promise$1(function (resolve, reject) { - if (n < 0) { - resolve(null); - - return; - } - - self.ready().then(function () { - var dbInfo = self._dbInfo; - var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName); - - var advanced = false; - var req = store.openCursor(); - req.onsuccess = function () { - var cursor = req.result; - if (!cursor) { - // this means there weren't enough keys - resolve(null); - - return; - } - - if (n === 0) { - // We have the first key, return it if that's what they - // wanted. - resolve(cursor.key); - } else { - if (!advanced) { - // Otherwise, ask the cursor to skip ahead n - // records. - advanced = true; - cursor.advance(n); - } else { - // When we get here, we've got the nth key. - resolve(cursor.key); - } - } - }; - - req.onerror = function () { - reject(req.error); - }; - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -function keys(callback) { - var self = this; - - var promise = new Promise$1(function (resolve, reject) { - self.ready().then(function () { - var dbInfo = self._dbInfo; - var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName); - - var req = store.openCursor(); - var keys = []; - - req.onsuccess = function () { - var cursor = req.result; - - if (!cursor) { - resolve(keys); - return; - } - - keys.push(cursor.key); - cursor["continue"](); - }; - - req.onerror = function () { - reject(req.error); - }; - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -var asyncStorage = { - _driver: 'asyncStorage', - _initStorage: _initStorage, - iterate: iterate, - getItem: getItem, - setItem: setItem, - removeItem: removeItem, - clear: clear, - length: length, - key: key, - keys: keys -}; - -// Sadly, the best way to save binary data in WebSQL/localStorage is serializing -// it to Base64, so this is how we store it to prevent very strange errors with less -// verbose ways of binary <-> string data storage. -var BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - -var BLOB_TYPE_PREFIX = '~~local_forage_type~'; -var BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/; - -var SERIALIZED_MARKER = '__lfsc__:'; -var SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length; - -// OMG the serializations! -var TYPE_ARRAYBUFFER = 'arbf'; -var TYPE_BLOB = 'blob'; -var TYPE_INT8ARRAY = 'si08'; -var TYPE_UINT8ARRAY = 'ui08'; -var TYPE_UINT8CLAMPEDARRAY = 'uic8'; -var TYPE_INT16ARRAY = 'si16'; -var TYPE_INT32ARRAY = 'si32'; -var TYPE_UINT16ARRAY = 'ur16'; -var TYPE_UINT32ARRAY = 'ui32'; -var TYPE_FLOAT32ARRAY = 'fl32'; -var TYPE_FLOAT64ARRAY = 'fl64'; -var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length; - -var toString$1 = Object.prototype.toString; - -function stringToBuffer(serializedString) { - // Fill the string into a ArrayBuffer. - var bufferLength = serializedString.length * 0.75; - var len = serializedString.length; - var i; - var p = 0; - var encoded1, encoded2, encoded3, encoded4; - - if (serializedString[serializedString.length - 1] === '=') { - bufferLength--; - if (serializedString[serializedString.length - 2] === '=') { - bufferLength--; - } - } - - var buffer = new ArrayBuffer(bufferLength); - var bytes = new Uint8Array(buffer); - - for (i = 0; i < len; i += 4) { - encoded1 = BASE_CHARS.indexOf(serializedString[i]); - encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]); - encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]); - encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]); - - /*jslint bitwise: true */ - bytes[p++] = encoded1 << 2 | encoded2 >> 4; - bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2; - bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63; - } - return buffer; -} - -// Converts a buffer to a string to store, serialized, in the backend -// storage library. -function bufferToString(buffer) { - // base64-arraybuffer - var bytes = new Uint8Array(buffer); - var base64String = ''; - var i; - - for (i = 0; i < bytes.length; i += 3) { - /*jslint bitwise: true */ - base64String += BASE_CHARS[bytes[i] >> 2]; - base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4]; - base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6]; - base64String += BASE_CHARS[bytes[i + 2] & 63]; - } - - if (bytes.length % 3 === 2) { - base64String = base64String.substring(0, base64String.length - 1) + '='; - } else if (bytes.length % 3 === 1) { - base64String = base64String.substring(0, base64String.length - 2) + '=='; - } - - return base64String; -} - -// Serialize a value, afterwards executing a callback (which usually -// instructs the `setItem()` callback/promise to be executed). This is how -// we store binary data with localStorage. -function serialize(value, callback) { - var valueType = ''; - if (value) { - valueType = toString$1.call(value); - } - - // Cannot use `value instanceof ArrayBuffer` or such here, as these - // checks fail when running the tests using casper.js... - // - // TODO: See why those tests fail and use a better solution. - if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) { - // Convert binary arrays to a string and prefix the string with - // a special marker. - var buffer; - var marker = SERIALIZED_MARKER; - - if (value instanceof ArrayBuffer) { - buffer = value; - marker += TYPE_ARRAYBUFFER; - } else { - buffer = value.buffer; - - if (valueType === '[object Int8Array]') { - marker += TYPE_INT8ARRAY; - } else if (valueType === '[object Uint8Array]') { - marker += TYPE_UINT8ARRAY; - } else if (valueType === '[object Uint8ClampedArray]') { - marker += TYPE_UINT8CLAMPEDARRAY; - } else if (valueType === '[object Int16Array]') { - marker += TYPE_INT16ARRAY; - } else if (valueType === '[object Uint16Array]') { - marker += TYPE_UINT16ARRAY; - } else if (valueType === '[object Int32Array]') { - marker += TYPE_INT32ARRAY; - } else if (valueType === '[object Uint32Array]') { - marker += TYPE_UINT32ARRAY; - } else if (valueType === '[object Float32Array]') { - marker += TYPE_FLOAT32ARRAY; - } else if (valueType === '[object Float64Array]') { - marker += TYPE_FLOAT64ARRAY; - } else { - callback(new Error('Failed to get type for BinaryArray')); - } - } - - callback(marker + bufferToString(buffer)); - } else if (valueType === '[object Blob]') { - // Conver the blob to a binaryArray and then to a string. - var fileReader = new FileReader(); - - fileReader.onload = function () { - // Backwards-compatible prefix for the blob type. - var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result); - - callback(SERIALIZED_MARKER + TYPE_BLOB + str); - }; - - fileReader.readAsArrayBuffer(value); - } else { - try { - callback(JSON.stringify(value)); - } catch (e) { - console.error("Couldn't convert value into a JSON string: ", value); - - callback(null, e); - } - } -} - -// Deserialize data we've inserted into a value column/field. We place -// special markers into our strings to mark them as encoded; this isn't -// as nice as a meta field, but it's the only sane thing we can do whilst -// keeping localStorage support intact. -// -// Oftentimes this will just deserialize JSON content, but if we have a -// special marker (SERIALIZED_MARKER, defined above), we will extract -// some kind of arraybuffer/binary data/typed array out of the string. -function deserialize(value) { - // If we haven't marked this string as being specially serialized (i.e. - // something other than serialized JSON), we can just return it and be - // done with it. - if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) { - return JSON.parse(value); - } - - // The following code deals with deserializing some kind of Blob or - // TypedArray. First we separate out the type of data we're dealing - // with from the data itself. - var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH); - var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH); - - var blobType; - // Backwards-compatible blob type serialization strategy. - // DBs created with older versions of localForage will simply not have the blob type. - if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) { - var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX); - blobType = matcher[1]; - serializedString = serializedString.substring(matcher[0].length); - } - var buffer = stringToBuffer(serializedString); - - // Return the right type based on the code/type set during - // serialization. - switch (type) { - case TYPE_ARRAYBUFFER: - return buffer; - case TYPE_BLOB: - return createBlob([buffer], { type: blobType }); - case TYPE_INT8ARRAY: - return new Int8Array(buffer); - case TYPE_UINT8ARRAY: - return new Uint8Array(buffer); - case TYPE_UINT8CLAMPEDARRAY: - return new Uint8ClampedArray(buffer); - case TYPE_INT16ARRAY: - return new Int16Array(buffer); - case TYPE_UINT16ARRAY: - return new Uint16Array(buffer); - case TYPE_INT32ARRAY: - return new Int32Array(buffer); - case TYPE_UINT32ARRAY: - return new Uint32Array(buffer); - case TYPE_FLOAT32ARRAY: - return new Float32Array(buffer); - case TYPE_FLOAT64ARRAY: - return new Float64Array(buffer); - default: - throw new Error('Unkown type: ' + type); - } -} - -var localforageSerializer = { - serialize: serialize, - deserialize: deserialize, - stringToBuffer: stringToBuffer, - bufferToString: bufferToString -}; - -/* - * Includes code from: - * - * base64-arraybuffer - * https://github.com/niklasvh/base64-arraybuffer - * - * Copyright (c) 2012 Niklas von Hertzen - * Licensed under the MIT license. - */ -// Open the WebSQL database (automatically creates one if one didn't -// previously exist), using any options set in the config. -function _initStorage$1(options) { - var self = this; - var dbInfo = { - db: null - }; - - if (options) { - for (var i in options) { - dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i]; - } - } - - var dbInfoPromise = new Promise$1(function (resolve, reject) { - // Open the database; the openDatabase API will automatically - // create it for us if it doesn't exist. - try { - dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size); - } catch (e) { - return reject(e); - } - - // Create our key/value table if it doesn't exist. - dbInfo.db.transaction(function (t) { - t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' (id INTEGER PRIMARY KEY, key unique, value)', [], function () { - self._dbInfo = dbInfo; - resolve(); - }, function (t, error) { - reject(error); - }); - }); - }); - - dbInfo.serializer = localforageSerializer; - return dbInfoPromise; -} - -function getItem$1(key, callback) { - var self = this; - - // Cast the key to a string, as that's all we can set as a key. - if (typeof key !== 'string') { - console.warn(key + ' used as a key, but it is not a string.'); - key = String(key); - } - - var promise = new Promise$1(function (resolve, reject) { - self.ready().then(function () { - var dbInfo = self._dbInfo; - dbInfo.db.transaction(function (t) { - t.executeSql('SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) { - var result = results.rows.length ? results.rows.item(0).value : null; - - // Check to see if this is serialized content we need to - // unpack. - if (result) { - result = dbInfo.serializer.deserialize(result); - } - - resolve(result); - }, function (t, error) { - - reject(error); - }); - }); - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -function iterate$1(iterator, callback) { - var self = this; - - var promise = new Promise$1(function (resolve, reject) { - self.ready().then(function () { - var dbInfo = self._dbInfo; - - dbInfo.db.transaction(function (t) { - t.executeSql('SELECT * FROM ' + dbInfo.storeName, [], function (t, results) { - var rows = results.rows; - var length = rows.length; - - for (var i = 0; i < length; i++) { - var item = rows.item(i); - var result = item.value; - - // Check to see if this is serialized content - // we need to unpack. - if (result) { - result = dbInfo.serializer.deserialize(result); - } - - result = iterator(result, item.key, i + 1); - - // void(0) prevents problems with redefinition - // of `undefined`. - if (result !== void 0) { - resolve(result); - return; - } - } - - resolve(); - }, function (t, error) { - reject(error); - }); - }); - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -function _setItem(key, value, callback, retriesLeft) { - var self = this; - - // Cast the key to a string, as that's all we can set as a key. - if (typeof key !== 'string') { - console.warn(key + ' used as a key, but it is not a string.'); - key = String(key); - } - - var promise = new Promise$1(function (resolve, reject) { - self.ready().then(function () { - // The localStorage API doesn't return undefined values in an - // "expected" way, so undefined is always cast to null in all - // drivers. See: https://github.com/mozilla/localForage/pull/42 - if (value === undefined) { - value = null; - } - - // Save the original value to pass to the callback. - var originalValue = value; - - var dbInfo = self._dbInfo; - dbInfo.serializer.serialize(value, function (value, error) { - if (error) { - reject(error); - } else { - dbInfo.db.transaction(function (t) { - t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + ' (key, value) VALUES (?, ?)', [key, value], function () { - resolve(originalValue); - }, function (t, error) { - reject(error); - }); - }, function (sqlError) { - // The transaction failed; check - // to see if it's a quota error. - if (sqlError.code === sqlError.QUOTA_ERR) { - // We reject the callback outright for now, but - // it's worth trying to re-run the transaction. - // Even if the user accepts the prompt to use - // more storage on Safari, this error will - // be called. - // - // Try to re-run the transaction. - if (retriesLeft > 0) { - resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1])); - return; - } - reject(sqlError); - } - }); - } - }); - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -function setItem$1(key, value, callback) { - return _setItem.apply(this, [key, value, callback, 1]); -} - -function removeItem$1(key, callback) { - var self = this; - - // Cast the key to a string, as that's all we can set as a key. - if (typeof key !== 'string') { - console.warn(key + ' used as a key, but it is not a string.'); - key = String(key); - } - - var promise = new Promise$1(function (resolve, reject) { - self.ready().then(function () { - var dbInfo = self._dbInfo; - dbInfo.db.transaction(function (t) { - t.executeSql('DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () { - resolve(); - }, function (t, error) { - - reject(error); - }); - }); - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -// Deletes every item in the table. -// TODO: Find out if this resets the AUTO_INCREMENT number. -function clear$1(callback) { - var self = this; - - var promise = new Promise$1(function (resolve, reject) { - self.ready().then(function () { - var dbInfo = self._dbInfo; - dbInfo.db.transaction(function (t) { - t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function () { - resolve(); - }, function (t, error) { - reject(error); - }); - }); - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -// Does a simple `COUNT(key)` to get the number of items stored in -// localForage. -function length$1(callback) { - var self = this; - - var promise = new Promise$1(function (resolve, reject) { - self.ready().then(function () { - var dbInfo = self._dbInfo; - dbInfo.db.transaction(function (t) { - // Ahhh, SQL makes this one soooooo easy. - t.executeSql('SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) { - var result = results.rows.item(0).c; - - resolve(result); - }, function (t, error) { - - reject(error); - }); - }); - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -// Return the key located at key index X; essentially gets the key from a -// `WHERE id = ?`. This is the most efficient way I can think to implement -// this rarely-used (in my experience) part of the API, but it can seem -// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so -// the ID of each key will change every time it's updated. Perhaps a stored -// procedure for the `setItem()` SQL would solve this problem? -// TODO: Don't change ID on `setItem()`. -function key$1(n, callback) { - var self = this; - - var promise = new Promise$1(function (resolve, reject) { - self.ready().then(function () { - var dbInfo = self._dbInfo; - dbInfo.db.transaction(function (t) { - t.executeSql('SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) { - var result = results.rows.length ? results.rows.item(0).key : null; - resolve(result); - }, function (t, error) { - reject(error); - }); - }); - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -function keys$1(callback) { - var self = this; - - var promise = new Promise$1(function (resolve, reject) { - self.ready().then(function () { - var dbInfo = self._dbInfo; - dbInfo.db.transaction(function (t) { - t.executeSql('SELECT key FROM ' + dbInfo.storeName, [], function (t, results) { - var keys = []; - - for (var i = 0; i < results.rows.length; i++) { - keys.push(results.rows.item(i).key); - } - - resolve(keys); - }, function (t, error) { - - reject(error); - }); - }); - })["catch"](reject); - }); - - executeCallback(promise, callback); - return promise; -} - -var webSQLStorage = { - _driver: 'webSQLStorage', - _initStorage: _initStorage$1, - iterate: iterate$1, - getItem: getItem$1, - setItem: setItem$1, - removeItem: removeItem$1, - clear: clear$1, - length: length$1, - key: key$1, - keys: keys$1 -}; - -// Config the localStorage backend, using options set in the config. -function _initStorage$2(options) { - var self = this; - var dbInfo = {}; - if (options) { - for (var i in options) { - dbInfo[i] = options[i]; - } - } - - dbInfo.keyPrefix = dbInfo.name + '/'; - - if (dbInfo.storeName !== self._defaultConfig.storeName) { - dbInfo.keyPrefix += dbInfo.storeName + '/'; - } - - self._dbInfo = dbInfo; - dbInfo.serializer = localforageSerializer; - - return Promise$1.resolve(); -} - -// Remove all keys from the datastore, effectively destroying all data in -// the app's key/value store! -function clear$2(callback) { - var self = this; - var promise = self.ready().then(function () { - var keyPrefix = self._dbInfo.keyPrefix; - - for (var i = localStorage.length - 1; i >= 0; i--) { - var key = localStorage.key(i); - - if (key.indexOf(keyPrefix) === 0) { - localStorage.removeItem(key); - } - } - }); - - executeCallback(promise, callback); - return promise; -} - -// Retrieve an item from the store. Unlike the original async_storage -// library in Gaia, we don't modify return values at all. If a key's value -// is `undefined`, we pass that value to the callback function. -function getItem$2(key, callback) { - var self = this; - - // Cast the key to a string, as that's all we can set as a key. - if (typeof key !== 'string') { - console.warn(key + ' used as a key, but it is not a string.'); - key = String(key); - } - - var promise = self.ready().then(function () { - var dbInfo = self._dbInfo; - var result = localStorage.getItem(dbInfo.keyPrefix + key); - - // If a result was found, parse it from the serialized - // string into a JS object. If result isn't truthy, the key - // is likely undefined and we'll pass it straight to the - // callback. - if (result) { - result = dbInfo.serializer.deserialize(result); - } - - return result; - }); - - executeCallback(promise, callback); - return promise; -} - -// Iterate over all items in the store. -function iterate$2(iterator, callback) { - var self = this; - - var promise = self.ready().then(function () { - var dbInfo = self._dbInfo; - var keyPrefix = dbInfo.keyPrefix; - var keyPrefixLength = keyPrefix.length; - var length = localStorage.length; - - // We use a dedicated iterator instead of the `i` variable below - // so other keys we fetch in localStorage aren't counted in - // the `iterationNumber` argument passed to the `iterate()` - // callback. - // - // See: github.com/mozilla/localForage/pull/435#discussion_r38061530 - var iterationNumber = 1; - - for (var i = 0; i < length; i++) { - var key = localStorage.key(i); - if (key.indexOf(keyPrefix) !== 0) { - continue; - } - var value = localStorage.getItem(key); - - // If a result was found, parse it from the serialized - // string into a JS object. If result isn't truthy, the - // key is likely undefined and we'll pass it straight - // to the iterator. - if (value) { - value = dbInfo.serializer.deserialize(value); - } - - value = iterator(value, key.substring(keyPrefixLength), iterationNumber++); - - if (value !== void 0) { - return value; - } - } - }); - - executeCallback(promise, callback); - return promise; -} - -// Same as localStorage's key() method, except takes a callback. -function key$2(n, callback) { - var self = this; - var promise = self.ready().then(function () { - var dbInfo = self._dbInfo; - var result; - try { - result = localStorage.key(n); - } catch (error) { - result = null; - } - - // Remove the prefix from the key, if a key is found. - if (result) { - result = result.substring(dbInfo.keyPrefix.length); - } - - return result; - }); - - executeCallback(promise, callback); - return promise; -} - -function keys$2(callback) { - var self = this; - var promise = self.ready().then(function () { - var dbInfo = self._dbInfo; - var length = localStorage.length; - var keys = []; - - for (var i = 0; i < length; i++) { - if (localStorage.key(i).indexOf(dbInfo.keyPrefix) === 0) { - keys.push(localStorage.key(i).substring(dbInfo.keyPrefix.length)); - } - } - - return keys; - }); - - executeCallback(promise, callback); - return promise; -} - -// Supply the number of keys in the datastore to the callback function. -function length$2(callback) { - var self = this; - var promise = self.keys().then(function (keys) { - return keys.length; - }); - - executeCallback(promise, callback); - return promise; -} - -// Remove an item from the store, nice and simple. -function removeItem$2(key, callback) { - var self = this; - - // Cast the key to a string, as that's all we can set as a key. - if (typeof key !== 'string') { - console.warn(key + ' used as a key, but it is not a string.'); - key = String(key); - } - - var promise = self.ready().then(function () { - var dbInfo = self._dbInfo; - localStorage.removeItem(dbInfo.keyPrefix + key); - }); - - executeCallback(promise, callback); - return promise; -} - -// Set a key's value and run an optional callback once the value is set. -// Unlike Gaia's implementation, the callback function is passed the value, -// in case you want to operate on that value only after you're sure it -// saved, or something like that. -function setItem$2(key, value, callback) { - var self = this; - - // Cast the key to a string, as that's all we can set as a key. - if (typeof key !== 'string') { - console.warn(key + ' used as a key, but it is not a string.'); - key = String(key); - } - - var promise = self.ready().then(function () { - // Convert undefined values to null. - // https://github.com/mozilla/localForage/pull/42 - if (value === undefined) { - value = null; - } - - // Save the original value to pass to the callback. - var originalValue = value; - - return new Promise$1(function (resolve, reject) { - var dbInfo = self._dbInfo; - dbInfo.serializer.serialize(value, function (value, error) { - if (error) { - reject(error); - } else { - try { - localStorage.setItem(dbInfo.keyPrefix + key, value); - resolve(originalValue); - } catch (e) { - // localStorage capacity exceeded. - // TODO: Make this a specific error/event. - if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') { - reject(e); - } - reject(e); - } - } - }); - }); - }); - - executeCallback(promise, callback); - return promise; -} - -var localStorageWrapper = { - _driver: 'localStorageWrapper', - _initStorage: _initStorage$2, - // Default API, from Gaia/localStorage. - iterate: iterate$2, - getItem: getItem$2, - setItem: setItem$2, - removeItem: removeItem$2, - clear: clear$2, - length: length$2, - key: key$2, - keys: keys$2 -}; - -// Custom drivers are stored here when `defineDriver()` is called. -// They are shared across all instances of localForage. -var CustomDrivers = {}; - -var DriverType = { - INDEXEDDB: 'asyncStorage', - LOCALSTORAGE: 'localStorageWrapper', - WEBSQL: 'webSQLStorage' -}; - -var DefaultDriverOrder = [DriverType.INDEXEDDB, DriverType.WEBSQL, DriverType.LOCALSTORAGE]; - -var LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem']; - -var DefaultConfig = { - description: '', - driver: DefaultDriverOrder.slice(), - name: 'localforage', - // Default DB size is _JUST UNDER_ 5MB, as it's the highest size - // we can use without a prompt. - size: 4980736, - storeName: 'keyvaluepairs', - version: 1.0 -}; - -var driverSupport = {}; -// Check to see if IndexedDB is available and if it is the latest -// implementation; it's our preferred backend library. We use "_spec_test" -// as the name of the database because it's not the one we'll operate on, -// but it's useful to make sure its using the right spec. -// See: https://github.com/mozilla/localForage/issues/128 -driverSupport[DriverType.INDEXEDDB] = isIndexedDBValid(); - -driverSupport[DriverType.WEBSQL] = isWebSQLValid(); - -driverSupport[DriverType.LOCALSTORAGE] = isLocalStorageValid(); - -var isArray = Array.isArray || function (arg) { - return Object.prototype.toString.call(arg) === '[object Array]'; -}; - -function callWhenReady(localForageInstance, libraryMethod) { - localForageInstance[libraryMethod] = function () { - var _args = arguments; - return localForageInstance.ready().then(function () { - return localForageInstance[libraryMethod].apply(localForageInstance, _args); - }); - }; -} - -function extend() { - for (var i = 1; i < arguments.length; i++) { - var arg = arguments[i]; - - if (arg) { - for (var key in arg) { - if (arg.hasOwnProperty(key)) { - if (isArray(arg[key])) { - arguments[0][key] = arg[key].slice(); - } else { - arguments[0][key] = arg[key]; - } - } - } - } - } - - return arguments[0]; -} - -function isLibraryDriver(driverName) { - for (var driver in DriverType) { - if (DriverType.hasOwnProperty(driver) && DriverType[driver] === driverName) { - return true; - } - } - - return false; -} - -var LocalForage = function () { - function LocalForage(options) { - _classCallCheck(this, LocalForage); - - this.INDEXEDDB = DriverType.INDEXEDDB; - this.LOCALSTORAGE = DriverType.LOCALSTORAGE; - this.WEBSQL = DriverType.WEBSQL; - - this._defaultConfig = extend({}, DefaultConfig); - this._config = extend({}, this._defaultConfig, options); - this._driverSet = null; - this._initDriver = null; - this._ready = false; - this._dbInfo = null; - - this._wrapLibraryMethodsWithReady(); - this.setDriver(this._config.driver)["catch"](function () {}); - } - - // Set any config values for localForage; can be called anytime before - // the first API call (e.g. `getItem`, `setItem`). - // We loop through options so we don't overwrite existing config - // values. - - - LocalForage.prototype.config = function config(options) { - // If the options argument is an object, we use it to set values. - // Otherwise, we return either a specified config value or all - // config values. - if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') { - // If localforage is ready and fully initialized, we can't set - // any new configuration values. Instead, we return an error. - if (this._ready) { - return new Error("Can't call config() after localforage " + 'has been used.'); - } - - for (var i in options) { - if (i === 'storeName') { - options[i] = options[i].replace(/\W/g, '_'); - } - - if (i === 'version' && typeof options[i] !== 'number') { - return new Error('Database version must be a number.'); - } - - this._config[i] = options[i]; - } - - // after all config options are set and - // the driver option is used, try setting it - if ('driver' in options && options.driver) { - return this.setDriver(this._config.driver); - } - - return true; - } else if (typeof options === 'string') { - return this._config[options]; - } else { - return this._config; - } - }; - - // Used to define a custom driver, shared across all instances of - // localForage. - - - LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) { - var promise = new Promise$1(function (resolve, reject) { - try { - var driverName = driverObject._driver; - var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver'); - var namingError = new Error('Custom driver name already in use: ' + driverObject._driver); - - // A driver name should be defined and not overlap with the - // library-defined, default drivers. - if (!driverObject._driver) { - reject(complianceError); - return; - } - if (isLibraryDriver(driverObject._driver)) { - reject(namingError); - return; - } - - var customDriverMethods = LibraryMethods.concat('_initStorage'); - for (var i = 0; i < customDriverMethods.length; i++) { - var customDriverMethod = customDriverMethods[i]; - if (!customDriverMethod || !driverObject[customDriverMethod] || typeof driverObject[customDriverMethod] !== 'function') { - reject(complianceError); - return; - } - } - - var supportPromise = Promise$1.resolve(true); - if ('_support' in driverObject) { - if (driverObject._support && typeof driverObject._support === 'function') { - supportPromise = driverObject._support(); - } else { - supportPromise = Promise$1.resolve(!!driverObject._support); - } - } - - supportPromise.then(function (supportResult) { - driverSupport[driverName] = supportResult; - CustomDrivers[driverName] = driverObject; - resolve(); - }, reject); - } catch (e) { - reject(e); - } - }); - - executeTwoCallbacks(promise, callback, errorCallback); - return promise; - }; - - LocalForage.prototype.driver = function driver() { - return this._driver || null; - }; - - LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) { - var self = this; - var getDriverPromise = Promise$1.resolve().then(function () { - if (isLibraryDriver(driverName)) { - switch (driverName) { - case self.INDEXEDDB: - return asyncStorage; - case self.LOCALSTORAGE: - return localStorageWrapper; - case self.WEBSQL: - return webSQLStorage; - } - } else if (CustomDrivers[driverName]) { - return CustomDrivers[driverName]; - } else { - throw new Error('Driver not found.'); - } - }); - executeTwoCallbacks(getDriverPromise, callback, errorCallback); - return getDriverPromise; - }; - - LocalForage.prototype.getSerializer = function getSerializer(callback) { - var serializerPromise = Promise$1.resolve(localforageSerializer); - executeTwoCallbacks(serializerPromise, callback); - return serializerPromise; - }; - - LocalForage.prototype.ready = function ready(callback) { - var self = this; - - var promise = self._driverSet.then(function () { - if (self._ready === null) { - self._ready = self._initDriver(); - } - - return self._ready; - }); - - executeTwoCallbacks(promise, callback, callback); - return promise; - }; - - LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) { - var self = this; - - if (!isArray(drivers)) { - drivers = [drivers]; - } - - var supportedDrivers = this._getSupportedDrivers(drivers); - - function setDriverToConfig() { - self._config.driver = self.driver(); - } - - function extendSelfWithDriver(driver) { - self._extend(driver); - setDriverToConfig(); - - self._ready = self._initStorage(self._config); - return self._ready; - } - - function initDriver(supportedDrivers) { - return function () { - var currentDriverIndex = 0; - - function driverPromiseLoop() { - while (currentDriverIndex < supportedDrivers.length) { - var driverName = supportedDrivers[currentDriverIndex]; - currentDriverIndex++; - - self._dbInfo = null; - self._ready = null; - - return self.getDriver(driverName).then(extendSelfWithDriver)["catch"](driverPromiseLoop); - } - - setDriverToConfig(); - var error = new Error('No available storage method found.'); - self._driverSet = Promise$1.reject(error); - return self._driverSet; - } - - return driverPromiseLoop(); - }; - } - - // There might be a driver initialization in progress - // so wait for it to finish in order to avoid a possible - // race condition to set _dbInfo - var oldDriverSetDone = this._driverSet !== null ? this._driverSet["catch"](function () { - return Promise$1.resolve(); - }) : Promise$1.resolve(); - - this._driverSet = oldDriverSetDone.then(function () { - var driverName = supportedDrivers[0]; - self._dbInfo = null; - self._ready = null; - - return self.getDriver(driverName).then(function (driver) { - self._driver = driver._driver; - setDriverToConfig(); - self._wrapLibraryMethodsWithReady(); - self._initDriver = initDriver(supportedDrivers); - }); - })["catch"](function () { - setDriverToConfig(); - var error = new Error('No available storage method found.'); - self._driverSet = Promise$1.reject(error); - return self._driverSet; - }); - - executeTwoCallbacks(this._driverSet, callback, errorCallback); - return this._driverSet; - }; - - LocalForage.prototype.supports = function supports(driverName) { - return !!driverSupport[driverName]; - }; - - LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) { - extend(this, libraryMethodsAndProperties); - }; - - LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) { - var supportedDrivers = []; - for (var i = 0, len = drivers.length; i < len; i++) { - var driverName = drivers[i]; - if (this.supports(driverName)) { - supportedDrivers.push(driverName); - } - } - return supportedDrivers; - }; - - LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() { - // Add a stub for each driver API method that delays the call to the - // corresponding driver method until localForage is ready. These stubs - // will be replaced by the driver methods as soon as the driver is - // loaded, so there is no performance impact. - for (var i = 0; i < LibraryMethods.length; i++) { - callWhenReady(this, LibraryMethods[i]); - } - }; - - LocalForage.prototype.createInstance = function createInstance(options) { - return new LocalForage(options); - }; - - return LocalForage; -}(); - -// The actual localForage object that we expose as a module or via a -// global. It's extended by pulling in one of our other libraries. - - -var localforage_js = new LocalForage(); - -module.exports = localforage_js; - -},{"3":3}]},{},[4])(4) -}); -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],38:[function(require,module,exports){ -module.exports = require('./lib/type'); - -},{"./lib/type":39}],39:[function(require,module,exports){ -/*! - * type-detect - * Copyright(c) 2013 jake luer - * MIT Licensed - */ - -/*! - * Primary Exports - */ - -var exports = module.exports = getType; - -/*! - * Detectable javascript natives - */ - -var natives = { - '[object Array]': 'array' - , '[object RegExp]': 'regexp' - , '[object Function]': 'function' - , '[object Arguments]': 'arguments' - , '[object Date]': 'date' -}; - -/** - * ### typeOf (obj) - * - * Use several different techniques to determine - * the type of object being tested. - * - * - * @param {Mixed} object - * @return {String} object type - * @api public - */ - -function getType (obj) { - var str = Object.prototype.toString.call(obj); - if (natives[str]) return natives[str]; - if (obj === null) return 'null'; - if (obj === undefined) return 'undefined'; - if (obj === Object(obj)) return 'object'; - return typeof obj; -} - -exports.Library = Library; - -/** - * ### Library - * - * Create a repository for custom type detection. - * - * ```js - * var lib = new type.Library; - * ``` - * - */ - -function Library () { - this.tests = {}; -} - -/** - * #### .of (obj) - * - * Expose replacement `typeof` detection to the library. - * - * ```js - * if ('string' === lib.of('hello world')) { - * // ... - * } - * ``` - * - * @param {Mixed} object to test - * @return {String} type - */ - -Library.prototype.of = getType; - -/** - * #### .define (type, test) - * - * Add a test to for the `.test()` assertion. - * - * Can be defined as a regular expression: - * - * ```js - * lib.define('int', /^[0-9]+$/); - * ``` - * - * ... or as a function: - * - * ```js - * lib.define('bln', function (obj) { - * if ('boolean' === lib.of(obj)) return true; - * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ]; - * if ('string' === lib.of(obj)) obj = obj.toLowerCase(); - * return !! ~blns.indexOf(obj); - * }); - * ``` - * - * @param {String} type - * @param {RegExp|Function} test - * @api public - */ - -Library.prototype.define = function (type, test) { - if (arguments.length === 1) return this.tests[type]; - this.tests[type] = test; - return this; -}; - -/** - * #### .test (obj, test) - * - * Assert that an object is of type. Will first - * check natives, and if that does not pass it will - * use the user defined custom tests. - * - * ```js - * assert(lib.test('1', 'int')); - * assert(lib.test('yes', 'bln')); - * ``` - * - * @param {Mixed} object - * @param {String} type - * @return {Boolean} result - * @api public - */ - -Library.prototype.test = function (obj, type) { - if (type === getType(obj)) return true; - var test = this.tests[type]; - - if (test && 'regexp' === getType(test)) { - return test.test(obj); - } else if (test && 'function' === getType(test)) { - return test(obj); - } else { - throw new ReferenceError('Type test "' + type + '" not defined or invalid.'); - } -}; - -},{}],40:[function(require,module,exports){ -arguments[4][38][0].apply(exports,arguments) -},{"./lib/type":41,"dup":38}],41:[function(require,module,exports){ -/*! - * type-detect - * Copyright(c) 2013 jake luer - * MIT Licensed - */ - -/*! - * Primary Exports - */ - -var exports = module.exports = getType; - -/** - * ### typeOf (obj) - * - * Use several different techniques to determine - * the type of object being tested. - * - * - * @param {Mixed} object - * @return {String} object type - * @api public - */ -var objectTypeRegexp = /^\[object (.*)\]$/; - -function getType(obj) { - var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase(); - // Let "new String('')" return 'object' - if (typeof Promise === 'function' && obj instanceof Promise) return 'promise'; - // PhantomJS has type "DOMWindow" for null - if (obj === null) return 'null'; - // PhantomJS has type "DOMWindow" for undefined - if (obj === undefined) return 'undefined'; - return type; -} - -exports.Library = Library; - -/** - * ### Library - * - * Create a repository for custom type detection. - * - * ```js - * var lib = new type.Library; - * ``` - * - */ - -function Library() { - if (!(this instanceof Library)) return new Library(); - this.tests = {}; -} - -/** - * #### .of (obj) - * - * Expose replacement `typeof` detection to the library. - * - * ```js - * if ('string' === lib.of('hello world')) { - * // ... - * } - * ``` - * - * @param {Mixed} object to test - * @return {String} type - */ - -Library.prototype.of = getType; - -/** - * #### .define (type, test) - * - * Add a test to for the `.test()` assertion. - * - * Can be defined as a regular expression: - * - * ```js - * lib.define('int', /^[0-9]+$/); - * ``` - * - * ... or as a function: - * - * ```js - * lib.define('bln', function (obj) { - * if ('boolean' === lib.of(obj)) return true; - * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ]; - * if ('string' === lib.of(obj)) obj = obj.toLowerCase(); - * return !! ~blns.indexOf(obj); - * }); - * ``` - * - * @param {String} type - * @param {RegExp|Function} test - * @api public - */ - -Library.prototype.define = function(type, test) { - if (arguments.length === 1) return this.tests[type]; - this.tests[type] = test; - return this; -}; - -/** - * #### .test (obj, test) - * - * Assert that an object is of type. Will first - * check natives, and if that does not pass it will - * use the user defined custom tests. - * - * ```js - * assert(lib.test('1', 'int')); - * assert(lib.test('yes', 'bln')); - * ``` - * - * @param {Mixed} object - * @param {String} type - * @return {Boolean} result - * @api public - */ - -Library.prototype.test = function(obj, type) { - if (type === getType(obj)) return true; - var test = this.tests[type]; - - if (test && 'regexp' === getType(test)) { - return test.test(obj); - } else if (test && 'function' === getType(test)) { - return test(obj); - } else { - throw new ReferenceError('Type test "' + type + '" not defined or invalid.'); - } -}; - -},{}],42:[function(require,module,exports){ -'use strict'; - -function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } - -(function (document, window) { - // DEPENDENCIES - // ============================================================ - - var localforage = require('localforage'); - var probs = require('pjs-problems'); - var dedent = require('dedent'); - var assert = require('chai').assert; - - // PROBLEM TEMPLATE NICE-IFICATION - // ============================================================ - - function dedentStrings(problems) { - return problems.map(function (prob) { - prob.given = dedent(prob.given); - prob.answer = dedent(prob.answer); - return prob; - }); - } - - // PROBLEMS - // ============================================================ - - var problems = []; - Object.keys(probs).forEach(function (subject) { - var _problems; - - (_problems = problems).push.apply(_problems, _toConsumableArray(probs[subject])); - }); - problems = dedentStrings(problems); - console.log('problems:', problems); - - // CONFIG - // ============================================================ - - // Hoist current problem - var currentProblem = void 0; - // Keys to ignore while user is navigating around the textarea but not changing any code - var ignoreKeyCodes = [9, // Tab - 37, // Left arrow - 39, // Right arrow - 38, // Up arrow - 40 // Down arrow - ]; - - var config = { - shuffle: true, - timer: false, - currentIndex: 0 - }; - - // Pull config from localforage - localforage.getItem('js_practice_config').then(function (val) { - console.log('localforage val:', val); - if (val) { - config = val; - } - loadApp(config); - }).catch(function (err) { - console.log('localforage err:', err); - loadApp(config); - }); - - function updateLocalstore(config) { - return localforage.setItem('js_practice_config', config).then(function (val) { - console.log('Settings updated:', val); - }).catch(function (err) { - console.log('Settings update error:', err); - }); - } - - // UI - // ============================================================ - - // elements - var problemEl = document.getElementById('problem'); - var codeEl = document.getElementById('code'); - var testSuiteEl = document.getElementById('test-suite'); - var testTotalEl = document.getElementById('test-total'); - var evalConsoleEl = document.getElementById('eval-output'); - var assertConsoleEl = document.getElementById('assert-output'); - var shuffleProblemsButtonEl = document.getElementById('shuffle-problems'); - var previousProblemButtonEl = document.getElementById('prev-problem'); - var nextProblemButtonEl = document.getElementById('next-problem'); - - // Get indexes - function getRandomIndex(problemsArr) { - var ind = Math.floor(Math.random() * problemsArr.length); - config.currentIndex = ind; - updateLocalstore(config); - return ind; - } - - function getPreviousIndex(problemsArr) { - var probInd = void 0; - var currentIndex = config.currentIndex; - // If at beginning, go to end - if (currentIndex === 0) { - probInd = problemsArr.length - 1; - } else { - probInd = currentIndex - 1; - } - return probInd; - } - - function getNextIndex(problemsArr) { - var probInd = void 0; - var currentIndex = config.currentIndex; - // If at end or invalid, restart series - if (currentIndex >= problemsArr.length - 1 || currentIndex < 0) { - probInd = 0; - } else { - probInd = currentIndex + 1; - } - return probInd; - } - - // Get problems - function getCurrentProblem(problemsArr) { - return problemsArr[config.currentIndex]; - } - - function previousProblem() { - console.log('previousProblem!'); - config.currentIndex = config.shuffle ? getRandomIndex(problems) : getPreviousIndex(problems); - updateLocalstore(config).then(function () { - window.location.reload(); - }); - } - - function nextProblem() { - console.log('nextProblem!'); - config.currentIndex = config.shuffle ? getRandomIndex(problems) : getNextIndex(problems); - updateLocalstore(config).then(function () { - window.location.reload(); - }); - } - - function toggleShuffle() { - console.log('toggle shuffle!'); - config.shuffle = !config.shuffle; // Flip it - shuffleProblemsButtonEl.classList.toggle('active'); - updateLocalstore(config); - } - - function loadProblem(problemObj) { - currentProblem = problemObj; - // Prob question - problemEl.innerText = problemObj.prompt; - // Prob given code - if (problemObj.given) { - codeEl.value = problemObj.given; - } - // Seed the tests, pass (init = true) as second param - testSuite(null, true); - } - - function updateTests(testStatus, init) { - if (init === true) { - buildTests(currentProblem.tests); - } - updateTestStatus(testStatus); - } - - function buildTests(tests) { - if (tests) { - var testsDom = tests.map(function (test) { - return '
\n
[✘]
\n
' + test.name + '
\n
'; - }).join(''); - testSuiteEl.innerHTML = testsDom; - } - } - - function updateTestStatus(testStatuses) { - if (!testStatuses) { - throw new Error('No testStatuses provided.'); - } - // Find out if all tests have passed or not - var allPassed = true; - testStatuses.forEach(function (testPassed) { - if (testPassed !== true) { - allPassed = false; - } - }); - var testEls = Array.from(testSuiteEl.querySelectorAll('.test-state')); - testEls.forEach(function (testStatusEl, iter) { - if (testStatuses[iter] === true) { - testStatusEl.innerHTML = '[✓]'; - testStatusEl.classList.remove('fail'); - testStatusEl.classList.add('pass'); - } else { - testStatusEl.innerHTML = '[✘]'; - testStatusEl.classList.remove('pass'); - testStatusEl.classList.add('fail'); - } - }); - - if (allPassed === true) { - testTotalEl.innerText = 'PASS'; - testTotalEl.classList.remove('fail'); - testTotalEl.classList.add('pass'); - } else { - testTotalEl.innerText = 'FAIL'; - testTotalEl.classList.remove('pass'); - testTotalEl.classList.add('fail'); - } - } - - function printAssertError(errObj) { - // Make element string - var inner = ''; - if (errObj !== null) { - inner = '\n
\n Expected: ' + JSON.stringify(errObj.expected) + '\n Actual: ' + JSON.stringify(errObj.actual) + '\n
'; - } - - // Prepend element - assertConsoleEl.innerHTML = inner; - } - - function printEvalOutput(errObj, output) { - // Make element string - var inner = ''; - if (errObj && errObj.message !== undefined) { - inner = '\n
\n Syntax Error: ' + JSON.stringify(errObj.message) + '\n
'; - } else if (output) { - inner = '\n
\n Output: ' + JSON.stringify(output) + '\n
'; - } - // Prepend element - evalConsoleEl.innerHTML = inner; - } - - // VERIFICATION LOGIC - // ============================================================ - - function testSuite(init) { - // Run stuff - var output = getOutput(codeEl.value); - // Run tests on code, return object/array of test results - var tested = runTests(output); - // Update UI with results - updateTests(tested, init); - } - - function getOutput(code) { - var evald = false; - try { - evald = eval('(function(){' + code + '})()'); // eslint-disable-line no-eval - printEvalOutput(null, evald); // Print current output - } catch (err) { - printEvalOutput(err); - } - return evald; - } - - function runTests(output) { - var tested = false; - tested = currentProblem.tests.map(function (test) { - var testOutcome = false; - try { - if (output) { - // const testEval = eval(test.test); - - testOutcome = eval(test.test); - console.log('testOutcome:', testOutcome); - } - printAssertError(null); - } catch (err) { - printAssertError(err); - } - return testOutcome; - }); - return tested; - } - - // Wrapped to prevent race with local config retrieval - function loadApp(config) { - console.log('loading app!'); - - // Show current toggle state - if (config.shuffle === true) { - shuffleProblemsButtonEl.classList.add('active'); - } - - // Bind it up - codeEl.addEventListener('keyup', function (e) { - // If not arrow keys or other non-character keys - if (ignoreKeyCodes.indexOf(e.keyCode) === -1) { - // Run test suite - testSuite(); - } - }); - shuffleProblemsButtonEl.addEventListener('click', toggleShuffle); - previousProblemButtonEl.addEventListener('click', previousProblem); - nextProblemButtonEl.addEventListener('click', nextProblem); - - // Start it up! - // Load current problem - var currProb = getCurrentProblem(problems); - loadProblem(currProb); - // Initalized test suite with starting failures - testSuite(true); - } -})(document, window); - -},{"chai":5,"dedent":34,"localforage":37,"pjs-problems":1}]},{},[42]) - ->>>>>>> working import of external problem content +!function e(t,n,r){function o(a,s){if(!n[a]){if(!t[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(i)return i(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var f=n[a]={exports:{}};t[a][0].call(f.exports,function(e){var n=t[a][1][e];return o(n||e)},f,f.exports,e,t,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;a num > 5);\n return overFive;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, [8, 13, 21]) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 3 items",test:`assert.lengthOf(output, 3) === undefined;`},{name:`First item is 8`,test:`assert.deepEqual(output[0], 8) === undefined;`}]},{name:"Array.map()",time:10,prompt:`Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,given:`const numbers = [25, 121, 169];\r`,answer:`const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, [5, 11, 13]) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 3 items",test:`assert.lengthOf(output, 3) === undefined;`},{name:`First item is 5`,test:`assert.deepEqual(output[0], 5) === undefined;`},{name:`Last item is 13`,test:`assert.deepEqual(output[output.length - 1], 13) === undefined;`}]},{name:"Array.every()",time:10,prompt:`Return object that returns whether each array contains all even numbers using Array.every().`,given:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,answer:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n return element % 2 === 0\n }\n return {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n };`,tests:[{name:"Correct output",test:`assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;`},{name:"Returns an Object",test:`assert.isObject(output) === undefined;`},{name:"Object has 2 items",test:`assert.lengthOf(Object.keys(output), 2) === undefined;`},{name:`First value is true`,test:`assert.isTrue(output.evenNumbers) === undefined;`},{name:`Second value is false`,test:`assert.isFalse(output.someOddNumbers) === undefined;`}]},{name:"Array.some()",time:10,prompt:`Return 'Object' that returns whether each array contains some odd numbers using 'Array.some()'.`,given:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 4, 7, 8];\n function isOdd(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,answer:`const evenNumbers = [1, 3, 5, 7];\n const someOddNumbers = [1, 3, 6, 7];\n function isOdd(element) {\n return element % 2 !== 0;\n }\n return {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n };`,tests:[{name:"Correct output",test:`assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;`},{name:"Returns an Object",test:`assert.isObject(output) === undefined;`},{name:"Object has 2 items",test:`assert.lengthOf(Object.keys(output), 2) === undefined;`},{name:`First value is false`,test:`assert.isFalse(output.evenNumbers) === undefined;`},{name:`Second value is true`,test:`assert.isTrue(output.someOddNumbers) === undefined;`}]}]},{}],3:[function(e,t,n){t.exports=[{name:"Create Array",time:10,prompt:"Create and return an array that contains 'apple' and 'banana'",given:`const fruits = [];\rreturn fruits;`,answer:`const fruits = ['apple', 'banana'];\n return fruits;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, ['apple', 'banana']) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 2 items",test:`assert.lengthOf(output, 2) === undefined;`}]},{name:"Array.pop()",time:10,prompt:`Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,given:`const fruits = ['apple', 'banana', 'orange'];\r`,answer:`const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, ['apple', 'banana']) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 2 items",test:`assert.lengthOf(output, 2) === undefined;`}]}]},{}],4:[function(e,t,n){function r(){function e(e,n){Object.keys(n).forEach(function(r){~t.indexOf(r)||(e[r]=n[r])})}var t=[].slice.call(arguments);return function(){for(var t=[].slice.call(arguments),n=0,r={};ne,"expected #{this} to have a length above #{exp} but got #{act}","expected #{this} to not have a length above #{exp}",e,r)}else this.assert(n>e,"expected #{this} to be above "+e,"expected #{this} to be at most "+e)}function u(e,t){t&&P(this,"message",t);var n=P(this,"object");if(P(this,"doLength")){new N(n,t).to.have.property("length");var r=n.length;this.assert(r>=e,"expected #{this} to have a length at least #{exp} but got #{act}","expected #{this} to have a length below #{exp}",e,r)}else this.assert(n>=e,"expected #{this} to be at least "+e,"expected #{this} to be below "+e)}function f(e,t){t&&P(this,"message",t);var n=P(this,"object");if(P(this,"doLength")){new N(n,t).to.have.property("length");var r=n.length;this.assert(r1)throw new Error(i);break;case"object":if(arguments.length>1)throw new Error(i);e=Object.keys(e);break;default:e=Array.prototype.slice.call(arguments)}if(!e.length)throw new Error("keys required");var a=Object.keys(r),s=e,c=e.length,u=P(this,"any"),f=P(this,"all");if(u||f||(f=!0),u&&(o=s.filter(function(e){return~a.indexOf(e)}).length>0),f&&(o=e.every(function(e){return~a.indexOf(e)}),P(this,"negate")||P(this,"contains")||(o=o&&e.length==a.length)),c>1){var l=(e=e.map(function(e){return t.inspect(e)})).pop();f&&(n=e.join(", ")+", and "+l),u&&(n=e.join(", ")+", or "+l)}else n=t.inspect(e[0]);n=(c>1?"keys ":"key ")+n,n=(P(this,"contains")?"contain ":"have ")+n,this.assert(o,"expected #{this} to "+n,"expected #{this} to not "+n,s.slice(0).sort(),a.sort(),!0)}function m(e,n,r){r&&P(this,"message",r);var o=P(this,"object");new N(o,r).is.a("function");var i=!1,a=null,s=null,c=null;0===arguments.length?(n=null,e=null):e&&(e instanceof RegExp||"string"==typeof e)?(n=e,e=null):e&&e instanceof Error?(a=e,e=null,n=null):"function"==typeof e?(!(s=e.prototype.name)||"Error"===s&&e!==Error)&&(s=e.name||(new e).name):e=null;try{o()}catch(r){if(a)return this.assert(r===a,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp}",a instanceof Error?a.toString():a,r instanceof Error?r.toString():r),P(this,"object",r),this;if(e&&(this.assert(r instanceof e,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp} but #{act} was thrown",s,r instanceof Error?r.toString():r),!n))return P(this,"object",r),this;var u="error"===t.type(r)&&"message"in r?r.message:""+r;if(null!=u&&n&&n instanceof RegExp)return this.assert(n.exec(u),"expected #{this} to throw error matching #{exp} but got #{act}","expected #{this} to throw error not matching #{exp}",n,u),P(this,"object",r),this;if(null!=u&&n&&"string"==typeof n)return this.assert(~u.indexOf(n),"expected #{this} to throw error including #{exp} but got #{act}","expected #{this} to throw error not including #{act}",n,u),P(this,"object",r),this;i=!0,c=r}var f="",l=null!==s?s:a?"#{exp}":"an error";i&&(f=" but #{act} was thrown"),this.assert(!0===i,"expected #{this} to throw "+l+f,"expected #{this} to not throw "+l+f,a instanceof Error?a.toString():a,c instanceof Error?c.toString():c),P(this,"object",c)}function w(e,n){n&&P(this,"message",n);var r=P(this,"object"),o=P(this,"itself"),i="function"!==t.type(r)||o?r[e]:r.prototype[e];this.assert("function"==typeof i,"expected #{this} to respond to "+t.inspect(e),"expected #{this} to not respond to "+t.inspect(e))}function x(e,n){n&&P(this,"message",n);var r=e(P(this,"object"));this.assert(r,"expected #{this} to satisfy "+t.objDisplay(e),"expected #{this} to not satisfy"+t.objDisplay(e),!this.negate,r)}function j(e,n,r){r&&P(this,"message",r);var o=P(this,"object");if(new N(o,r).is.a("number"),"number"!==t.type(e)||"number"!==t.type(n))throw new Error("the arguments to closeTo or approximately must be numbers");this.assert(Math.abs(o-e)<=n,"expected #{this} to be close to "+e+" +/- "+n,"expected #{this} not to be close to "+e+" +/- "+n)}function E(e,t,n){return e.every(function(e){return n?t.some(function(t){return n(e,t)}):-1!==t.indexOf(e)})}function S(e,t){t&&P(this,"message",t);var n=P(this,"object");new N(e).to.be.an("array"),this.assert(e.indexOf(n)>-1,"expected #{this} to be one of #{exp}","expected #{this} to not be one of #{exp}",e,n)}function _(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(o!==e[t],"expected ."+t+" to change","expected ."+t+" to not change")}function O(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(e[t]-o>0,"expected ."+t+" to increase","expected ."+t+" to not increase")}function A(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(e[t]-o<0,"expected ."+t+" to decrease","expected ."+t+" to not decrease")}var N=e.Assertion,P=(Object.prototype.toString,t.flag);["to","be","been","is","and","has","have","with","that","which","at","of","same"].forEach(function(e){N.addProperty(e,function(){return this})}),N.addProperty("not",function(){P(this,"negate",!0)}),N.addProperty("deep",function(){P(this,"deep",!0)}),N.addProperty("any",function(){P(this,"any",!0),P(this,"all",!1)}),N.addProperty("all",function(){P(this,"all",!0),P(this,"any",!1)}),N.addChainableMethod("an",n),N.addChainableMethod("a",n),N.addChainableMethod("include",o,r),N.addChainableMethod("contain",o,r),N.addChainableMethod("contains",o,r),N.addChainableMethod("includes",o,r),N.addProperty("ok",function(){this.assert(P(this,"object"),"expected #{this} to be truthy","expected #{this} to be falsy")}),N.addProperty("true",function(){this.assert(!0===P(this,"object"),"expected #{this} to be true","expected #{this} to be false",!this.negate)}),N.addProperty("false",function(){this.assert(!1===P(this,"object"),"expected #{this} to be false","expected #{this} to be true",!!this.negate)}),N.addProperty("null",function(){this.assert(null===P(this,"object"),"expected #{this} to be null","expected #{this} not to be null")}),N.addProperty("undefined",function(){this.assert(void 0===P(this,"object"),"expected #{this} to be undefined","expected #{this} not to be undefined")}),N.addProperty("NaN",function(){this.assert(isNaN(P(this,"object")),"expected #{this} to be NaN","expected #{this} not to be NaN")}),N.addProperty("exist",function(){this.assert(null!=P(this,"object"),"expected #{this} to exist","expected #{this} to not exist")}),N.addProperty("empty",function(){var e=P(this,"object"),t=e;Array.isArray(e)||"string"==typeof object?t=e.length:"object"==typeof e&&(t=Object.keys(e).length),this.assert(!t,"expected #{this} to be empty","expected #{this} not to be empty")}),N.addProperty("arguments",i),N.addProperty("Arguments",i),N.addMethod("equal",a),N.addMethod("equals",a),N.addMethod("eq",a),N.addMethod("eql",s),N.addMethod("eqls",s),N.addMethod("above",c),N.addMethod("gt",c),N.addMethod("greaterThan",c),N.addMethod("least",u),N.addMethod("gte",u),N.addMethod("below",f),N.addMethod("lt",f),N.addMethod("lessThan",f),N.addMethod("most",l),N.addMethod("lte",l),N.addMethod("within",function(e,t,n){n&&P(this,"message",n);var r=P(this,"object"),o=e+".."+t;if(P(this,"doLength")){new N(r,n).to.have.property("length");var i=r.length;this.assert(i>=e&&i<=t,"expected #{this} to have a length within "+o,"expected #{this} to not have a length within "+o)}else this.assert(r>=e&&r<=t,"expected #{this} to be within "+o,"expected #{this} to not be within "+o)}),N.addMethod("instanceof",d),N.addMethod("instanceOf",d),N.addMethod("property",function(e,n,r){r&&P(this,"message",r);var o=!!P(this,"deep"),i=o?"deep property ":"property ",a=P(this,"negate"),s=P(this,"object"),c=o?t.getPathInfo(e,s):null,u=o?c.exists:t.hasProperty(e,s),f=o?c.value:s[e];if(a&&arguments.length>1){if(void 0===f)throw r=null!=r?r+": ":"",new Error(r+t.inspect(s)+" has no "+i+t.inspect(e))}else this.assert(u,"expected #{this} to have a "+i+t.inspect(e),"expected #{this} to not have "+i+t.inspect(e));arguments.length>1&&this.assert(n===f,"expected #{this} to have a "+i+t.inspect(e)+" of #{exp}, but got #{act}","expected #{this} to not have a "+i+t.inspect(e)+" of #{act}",n,f),P(this,"object",f)}),N.addMethod("ownProperty",h),N.addMethod("haveOwnProperty",h),N.addMethod("ownPropertyDescriptor",p),N.addMethod("haveOwnPropertyDescriptor",p),N.addChainableMethod("length",y,v),N.addMethod("lengthOf",y),N.addMethod("match",g),N.addMethod("matches",g),N.addMethod("string",function(e,n){n&&P(this,"message",n);var r=P(this,"object");new N(r,n).is.a("string"),this.assert(~r.indexOf(e),"expected #{this} to contain "+t.inspect(e),"expected #{this} to not contain "+t.inspect(e))}),N.addMethod("keys",b),N.addMethod("key",b),N.addMethod("throw",m),N.addMethod("throws",m),N.addMethod("Throw",m),N.addMethod("respondTo",w),N.addMethod("respondsTo",w),N.addProperty("itself",function(){P(this,"itself",!0)}),N.addMethod("satisfy",x),N.addMethod("satisfies",x),N.addMethod("closeTo",j),N.addMethod("approximately",j),N.addMethod("members",function(e,n){n&&P(this,"message",n);var r=P(this,"object");new N(r).to.be.an("array"),new N(e).to.be.an("array");var o=P(this,"deep")?t.eql:void 0;if(P(this,"contains"))return this.assert(E(e,r,o),"expected #{this} to be a superset of #{act}","expected #{this} to not be a superset of #{act}",r,e);this.assert(E(r,e,o)&&E(e,r,o),"expected #{this} to have the same members as #{act}","expected #{this} to not have the same members as #{act}",r,e)}),N.addMethod("oneOf",S),N.addChainableMethod("change",_),N.addChainableMethod("changes",_),N.addChainableMethod("increase",O),N.addChainableMethod("increases",O),N.addChainableMethod("decrease",A),N.addChainableMethod("decreases",A),N.addProperty("extensible",function(){var e,t=P(this,"object");try{e=Object.isExtensible(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!1}this.assert(e,"expected #{this} to be extensible","expected #{this} to not be extensible")}),N.addProperty("sealed",function(){var e,t=P(this,"object");try{e=Object.isSealed(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!0}this.assert(e,"expected #{this} to be sealed","expected #{this} to not be sealed")}),N.addProperty("frozen",function(){var e,t=P(this,"object");try{e=Object.isFrozen(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!0}this.assert(e,"expected #{this} to be frozen","expected #{this} to not be frozen")})}},{}],10:[function(e,t,n){t.exports=function(e,t){var n=e.Assertion,r=t.flag,o=e.assert=function(t,r){new n(null,null,e.assert).assert(t,r,"[ negation message unavailable ]")};o.fail=function(t,n,r,i){throw r=r||"assert.fail()",new e.AssertionError(r,{actual:t,expected:n,operator:i},o.fail)},o.isOk=function(e,t){new n(e,t).is.ok},o.isNotOk=function(e,t){new n(e,t).is.not.ok},o.equal=function(e,t,i){var a=new n(e,i,o.equal);a.assert(t==r(a,"object"),"expected #{this} to equal #{exp}","expected #{this} to not equal #{act}",t,e)},o.notEqual=function(e,t,i){var a=new n(e,i,o.notEqual);a.assert(t!=r(a,"object"),"expected #{this} to not equal #{exp}","expected #{this} to equal #{act}",t,e)},o.strictEqual=function(e,t,r){new n(e,r).to.equal(t)},o.notStrictEqual=function(e,t,r){new n(e,r).to.not.equal(t)},o.deepEqual=function(e,t,r){new n(e,r).to.eql(t)},o.notDeepEqual=function(e,t,r){new n(e,r).to.not.eql(t)},o.isAbove=function(e,t,r){new n(e,r).to.be.above(t)},o.isAtLeast=function(e,t,r){new n(e,r).to.be.least(t)},o.isBelow=function(e,t,r){new n(e,r).to.be.below(t)},o.isAtMost=function(e,t,r){new n(e,r).to.be.most(t)},o.isTrue=function(e,t){new n(e,t).is.true},o.isNotTrue=function(e,t){new n(e,t).to.not.equal(!0)},o.isFalse=function(e,t){new n(e,t).is.false},o.isNotFalse=function(e,t){new n(e,t).to.not.equal(!1)},o.isNull=function(e,t){new n(e,t).to.equal(null)},o.isNotNull=function(e,t){new n(e,t).to.not.equal(null)},o.isNaN=function(e,t){new n(e,t).to.be.NaN},o.isNotNaN=function(e,t){new n(e,t).not.to.be.NaN},o.isUndefined=function(e,t){new n(e,t).to.equal(void 0)},o.isDefined=function(e,t){new n(e,t).to.not.equal(void 0)},o.isFunction=function(e,t){new n(e,t).to.be.a("function")},o.isNotFunction=function(e,t){new n(e,t).to.not.be.a("function")},o.isObject=function(e,t){new n(e,t).to.be.a("object")},o.isNotObject=function(e,t){new n(e,t).to.not.be.a("object")},o.isArray=function(e,t){new n(e,t).to.be.an("array")},o.isNotArray=function(e,t){new n(e,t).to.not.be.an("array")},o.isString=function(e,t){new n(e,t).to.be.a("string")},o.isNotString=function(e,t){new n(e,t).to.not.be.a("string")},o.isNumber=function(e,t){new n(e,t).to.be.a("number")},o.isNotNumber=function(e,t){new n(e,t).to.not.be.a("number")},o.isBoolean=function(e,t){new n(e,t).to.be.a("boolean")},o.isNotBoolean=function(e,t){new n(e,t).to.not.be.a("boolean")},o.typeOf=function(e,t,r){new n(e,r).to.be.a(t)},o.notTypeOf=function(e,t,r){new n(e,r).to.not.be.a(t)},o.instanceOf=function(e,t,r){new n(e,r).to.be.instanceOf(t)},o.notInstanceOf=function(e,t,r){new n(e,r).to.not.be.instanceOf(t)},o.include=function(e,t,r){new n(e,r,o.include).include(t)},o.notInclude=function(e,t,r){new n(e,r,o.notInclude).not.include(t)},o.match=function(e,t,r){new n(e,r).to.match(t)},o.notMatch=function(e,t,r){new n(e,r).to.not.match(t)},o.property=function(e,t,r){new n(e,r).to.have.property(t)},o.notProperty=function(e,t,r){new n(e,r).to.not.have.property(t)},o.deepProperty=function(e,t,r){new n(e,r).to.have.deep.property(t)},o.notDeepProperty=function(e,t,r){new n(e,r).to.not.have.deep.property(t)},o.propertyVal=function(e,t,r,o){new n(e,o).to.have.property(t,r)},o.propertyNotVal=function(e,t,r,o){new n(e,o).to.not.have.property(t,r)},o.deepPropertyVal=function(e,t,r,o){new n(e,o).to.have.deep.property(t,r)},o.deepPropertyNotVal=function(e,t,r,o){new n(e,o).to.not.have.deep.property(t,r)},o.lengthOf=function(e,t,r){new n(e,r).to.have.length(t)},o.throws=function(e,t,o,i){("string"==typeof t||t instanceof RegExp)&&(o=t,t=null);var a=new n(e,i).to.throw(t,o);return r(a,"object")},o.doesNotThrow=function(e,t,r){"string"==typeof t&&(r=t,t=null),new n(e,r).to.not.Throw(t)},o.operator=function(e,o,i,a){var s;switch(o){case"==":s=e==i;break;case"===":s=e===i;break;case">":s=e>i;break;case">=":s=e>=i;break;case"<":s=e1&&n===t.length-1?"or ":"")+r+" "+e}).join(", ");if(!t.some(function(t){return i(e)===t}))throw new r("object tested must be "+n+", but "+i(e)+" given")}},{"./flag":17,"assertion-error":4,"type-detect":40}],17:[function(e,t,n){t.exports=function(e,t,n){var r=e.__flags||(e.__flags=Object.create(null));if(3!==arguments.length)return r[t];r[t]=n}},{}],18:[function(e,t,n){t.exports=function(e,t){return t.length>4?t[4]:e._obj}},{}],19:[function(e,t,n){t.exports=function(e){var t=[];for(var n in e)t.push(n);return t}},{}],20:[function(e,t,n){var r=e("./flag"),o=e("./getActual"),i=(e("./inspect"),e("./objDisplay"));t.exports=function(e,t){var n=r(e,"negate"),a=r(e,"object"),s=t[3],c=o(e,t),u=n?t[2]:t[1],f=r(e,"message");return"function"==typeof u&&(u=u()),u=u||"",u=u.replace(/#\{this\}/g,function(){return i(a)}).replace(/#\{act\}/g,function(){return i(c)}).replace(/#\{exp\}/g,function(){return i(s)}),f?f+": "+u:u}},{"./flag":17,"./getActual":18,"./inspect":27,"./objDisplay":28}],21:[function(e,t,n){t.exports=function(e){if(e.name)return e.name;var t=/^\s?function ([^(]*)\(/.exec(e);return t&&t[1]?t[1]:""}},{}],22:[function(e,t,n){function r(e){return e.replace(/([^\\])\[/g,"$1.[").match(/(\\\.|[^.]+?)+/g).map(function(e){var t=/^\[(\d+)\]$/.exec(e);return t?{i:parseFloat(t[1])}:{p:e.replace(/\\([.\[\]])/g,"$1")}})}function o(e,t,n){for(var r,o=t,i=0,a=n=void 0===n?e.length:n;i1?o(n,t,n.length-1):t,name:a.p||a.i,value:o(n,t)};return s.exists=i(s.name,s.parent),s}},{"./hasProperty":25}],23:[function(e,t,n){var r=e("./getPathInfo");t.exports=function(e,t){return r(e,t).value}},{"./getPathInfo":22}],24:[function(e,t,n){t.exports=function(e){function t(e){-1===n.indexOf(e)&&n.push(e)}for(var n=Object.getOwnPropertyNames(e),r=Object.getPrototypeOf(e);null!==r;)Object.getOwnPropertyNames(r).forEach(t),r=Object.getPrototypeOf(r);return n}},{}],25:[function(e,t,n){var r=e("type-detect"),o={number:Number,string:String};t.exports=function(e,t){var n=r(t);return"null"!==n&&"undefined"!==n&&(o[n]&&"object"!=typeof t&&(t=new o[n](t)),e in t)}},{"type-detect":40}],26:[function(e,t,n){(n=t.exports={}).test=e("./test"),n.type=e("type-detect"),n.expectTypes=e("./expectTypes"),n.getMessage=e("./getMessage"),n.getActual=e("./getActual"),n.inspect=e("./inspect"),n.objDisplay=e("./objDisplay"),n.flag=e("./flag"),n.transferFlags=e("./transferFlags"),n.eql=e("deep-eql"),n.getPathValue=e("./getPathValue"),n.getPathInfo=e("./getPathInfo"),n.hasProperty=e("./hasProperty"),n.getName=e("./getName"),n.addProperty=e("./addProperty"),n.addMethod=e("./addMethod"),n.overwriteProperty=e("./overwriteProperty"),n.overwriteMethod=e("./overwriteMethod"),n.addChainableMethod=e("./addChainableMethod"),n.overwriteChainableMethod=e("./overwriteChainableMethod")},{"./addChainableMethod":13,"./addMethod":14,"./addProperty":15,"./expectTypes":16,"./flag":17,"./getActual":18,"./getMessage":20,"./getName":21,"./getPathInfo":22,"./getPathValue":23,"./hasProperty":25,"./inspect":27,"./objDisplay":28,"./overwriteChainableMethod":29,"./overwriteMethod":30,"./overwriteProperty":31,"./test":32,"./transferFlags":33,"deep-eql":35,"type-detect":40}],27:[function(e,t,n){function r(e,t,n,r){return o({showHidden:t,seen:[],stylize:function(e){return e}},e,void 0===n?2:n)}function o(e,t,r){if(t&&"function"==typeof t.inspect&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var p=t.inspect(r);return"string"!=typeof p&&(p=o(e,p,r)),p}var m=i(e,t);if(m)return m;if(b(t)){if("outerHTML"in t)return t.outerHTML;try{if(document.xmlVersion)return(new XMLSerializer).serializeToString(t);var w=document.createElementNS("http://www.w3.org/1999/xhtml","_");return w.appendChild(t.cloneNode(!1)),html=w.innerHTML.replace("><",">"+t.innerHTML+"<"),w.innerHTML="",html}catch(e){}}var x=g(t),j=e.showHidden?y(t):x;if(0===j.length||h(t)&&(1===j.length&&"stack"===j[0]||2===j.length&&"description"===j[0]&&"stack"===j[1])){if("function"==typeof t){var E=(A=v(t))?": "+A:"";return e.stylize("[Function"+E+"]","special")}if(l(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(d(t))return e.stylize(Date.prototype.toUTCString.call(t),"date");if(h(t))return a(t)}var S="",_=!1,O=["{","}"];if(f(t)&&(_=!0,O=["[","]"]),"function"==typeof t){var A=v(t);S=" [Function"+(E=A?": "+A:"")+"]"}if(l(t)&&(S=" "+RegExp.prototype.toString.call(t)),d(t)&&(S=" "+Date.prototype.toUTCString.call(t)),h(t))return a(t);if(0===j.length&&(!_||0==t.length))return O[0]+S+O[1];if(r<0)return l(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var N;return N=_?s(e,t,r,x,j):j.map(function(n){return c(e,t,r,x,n,_)}),e.seen.pop(),u(N,S,O)}function i(e,t){switch(typeof t){case"undefined":return e.stylize("undefined","undefined");case"string":var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string");case"number":return 0===t&&1/t==-1/0?e.stylize("-0","number"):e.stylize(""+t,"number");case"boolean":return e.stylize(""+t,"boolean")}if(null===t)return e.stylize("null","null")}function a(e){return"["+Error.prototype.toString.call(e)+"]"}function s(e,t,n,r,o){for(var i=[],a=0,s=t.length;a-1&&(c=a?c.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+c.split("\n").map(function(e){return" "+e}).join("\n")):c=e.stylize("[Circular]","special")),void 0===s){if(a&&i.match(/^\d+$/))return c;(s=JSON.stringify(""+i)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(s=s.substr(1,s.length-2),s=e.stylize(s,"name")):(s=s.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),s=e.stylize(s,"string"))}return s+": "+c}function u(e,t,n){var r=0;return e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.length+1},0)>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function f(e){return Array.isArray(e)||"object"==typeof e&&"[object Array]"===p(e)}function l(e){return"object"==typeof e&&"[object RegExp]"===p(e)}function d(e){return"object"==typeof e&&"[object Date]"===p(e)}function h(e){return"object"==typeof e&&"[object Error]"===p(e)}function p(e){return Object.prototype.toString.call(e)}var v=e("./getName"),y=e("./getProperties"),g=e("./getEnumerableProperties");t.exports=r;var b=function(e){return"object"==typeof HTMLElement?e instanceof HTMLElement:e&&"object"==typeof e&&1===e.nodeType&&"string"==typeof e.nodeName}},{"./getEnumerableProperties":19,"./getName":21,"./getProperties":24}],28:[function(e,t,n){var r=e("./inspect"),o=e("../config");t.exports=function(e){var t=r(e),n=Object.prototype.toString.call(e);if(o.truncateThreshold&&t.length>=o.truncateThreshold){if("[object Function]"===n)return e.name&&""!==e.name?"[Function: "+e.name+"]":"[Function]";if("[object Array]"===n)return"[ Array("+e.length+") ]";if("[object Object]"===n){var i=Object.keys(e);return"{ Object ("+(i.length>2?i.splice(0,2).join(", ")+", ...":i.join(", "))+") }"}return t}return t}},{"../config":8,"./inspect":27}],29:[function(e,t,n){t.exports=function(e,t,n,r){var o=e.__methods[t],i=o.chainingBehavior;o.chainingBehavior=function(){var e=r(i).call(this);return void 0===e?this:e};var a=o.method;o.method=function(){var e=n(a).apply(this,arguments);return void 0===e?this:e}}},{}],30:[function(e,t,n){t.exports=function(e,t,n){var r=e[t],o=function(){return this};r&&"function"==typeof r&&(o=r),e[t]=function(){var e=n(o).apply(this,arguments);return void 0===e?this:e}}},{}],31:[function(e,t,n){t.exports=function(e,t,n){var r=Object.getOwnPropertyDescriptor(e,t),o=function(){};r&&"function"==typeof r.get&&(o=r.get),Object.defineProperty(e,t,{get:function(){var e=n(o).call(this);return void 0===e?this:e},configurable:!0})}},{}],32:[function(e,t,n){var r=e("./flag");t.exports=function(e,t){var n=r(e,"negate"),o=t[0];return n?!o:o}},{"./flag":17}],33:[function(e,t,n){t.exports=function(e,t,n){var r=e.__flags||(e.__flags=Object.create(null));t.__flags||(t.__flags=Object.create(null)),n=3!==arguments.length||n;for(var o in r)(n||"object"!==o&&"ssfi"!==o&&"message"!=o)&&(t.__flags[o]=r[o])}},{}],34:[function(e,t,n){"use strict";function r(e){var t=void 0;t="string"==typeof e?[e]:e.raw;for(var n="",r=0;r=0;o--)if(s=i[o],!r(e[s],t[s],n))return!1;return!0}var p,v=e("type-detect");try{p=e("buffer").Buffer}catch(e){(p={}).isBuffer=function(){return!1}}t.exports=r},{buffer:void 0,"type-detect":38}],37:[function(e,t,n){(function(r){!function(e){if("object"==typeof n&&void 0!==t)t.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:void 0!==r?r:"undefined"!=typeof self?self:this).localforage=e()}}(function(){return function t(n,r,o){function i(s,c){if(!r[s]){if(!n[s]){var u="function"==typeof e&&e;if(!c&&u)return u(s,!0);if(a)return a(s,!0);var f=new Error("Cannot find module '"+s+"'");throw f.code="MODULE_NOT_FOUND",f}var l=r[s]={exports:{}};n[s][0].call(l.exports,function(e){var t=n[s][1][e];return i(t||e)},l,l.exports,t,n,r,o)}return r[s].exports}for(var a="function"==typeof e&&e,s=0;s=43)}}).catch(function(){return!1})}function u(e){return"boolean"==typeof re?ie.resolve(re):c(e).then(function(e){return re=e})}function f(e){var t=oe[e.name],n={};n.promise=new ie(function(e){n.resolve=e}),t.deferredOperations.push(n),t.dbReady?t.dbReady=t.dbReady.then(function(){return n.promise}):t.dbReady=n.promise}function l(e){var t=oe[e.name].deferredOperations.pop();t&&t.resolve()}function d(e,t){return new ie(function(n,r){if(e.db){if(!t)return n(e.db);f(e),e.db.close()}var o=[e.name];t&&o.push(e.version);var i=ne.open.apply(ne,o);t&&(i.onupgradeneeded=function(t){var n=i.result;try{n.createObjectStore(e.storeName),t.oldVersion<=1&&n.createObjectStore(ae)}catch(n){if("ConstraintError"!==n.name)throw n;console.warn('The database "'+e.name+'" has been upgraded from version '+t.oldVersion+" to version "+t.newVersion+', but the storage "'+e.storeName+'" already exists.')}}),i.onerror=function(e){e.preventDefault(),r(i.error)},i.onsuccess=function(){n(i.result),l(e)}})}function h(e){return d(e,!1)}function p(e){return d(e,!0)}function v(e,t){if(!e.db)return!0;var n=!e.db.objectStoreNames.contains(e.storeName),r=e.versione.db.version;if(r&&(e.version!==t&&console.warn('The database "'+e.name+"\" can't be downgraded from version "+e.db.version+" to version "+e.version+"."),e.version=e.db.version),o||n){if(n){var i=e.db.version+1;i>e.version&&(e.version=i)}return!0}return!1}function y(e){return new ie(function(t,n){var r=new FileReader;r.onerror=n,r.onloadend=function(n){var r=btoa(n.target.result||"");t({__local_forage_encoded_blob:!0,data:r,type:e.type})},r.readAsBinaryString(e)})}function g(e){return o([s(atob(e.data))],{type:e.type})}function b(e){return e&&e.__local_forage_encoded_blob}function m(e){var t=this,n=t._initReady().then(function(){var e=oe[t._dbInfo.name];if(e&&e.dbReady)return e.dbReady});return a(n,e,e),n}function w(e){function t(){return ie.resolve()}var n=this,r={db:null};if(e)for(var o in e)r[o]=e[o];oe||(oe={});var i=oe[r.name];i||(i={forages:[],db:null,dbReady:null,deferredOperations:[]},oe[r.name]=i),i.forages.push(n),n._initReady||(n._initReady=n.ready,n.ready=m);for(var a=[],s=0;s>4,f[c++]=(15&r)<<4|o>>2,f[c++]=(3&o)<<6|63&i;return u}function M(e){var t,n=new Uint8Array(e),r="";for(t=0;t>2],r+=ue[(3&n[t])<<4|n[t+1]>>4],r+=ue[(15&n[t+1])<<2|n[t+2]>>6],r+=ue[63&n[t+2]];return n.length%3==2?r=r.substring(0,r.length-1)+"=":n.length%3==1&&(r=r.substring(0,r.length-2)+"=="),r}function I(e,t){var n="";if(e&&(n=Oe.call(e)),e&&("[object ArrayBuffer]"===n||e.buffer&&"[object ArrayBuffer]"===Oe.call(e.buffer))){var r,o=de;e instanceof ArrayBuffer?(r=e,o+=pe):(r=e.buffer,"[object Int8Array]"===n?o+=ye:"[object Uint8Array]"===n?o+=ge:"[object Uint8ClampedArray]"===n?o+=be:"[object Int16Array]"===n?o+=me:"[object Uint16Array]"===n?o+=xe:"[object Int32Array]"===n?o+=we:"[object Uint32Array]"===n?o+=je:"[object Float32Array]"===n?o+=Ee:"[object Float64Array]"===n?o+=Se:t(new Error("Failed to get type for BinaryArray"))),t(o+M(r))}else if("[object Blob]"===n){var i=new FileReader;i.onload=function(){var n=fe+e.type+"~"+M(this.result);t(de+ve+n)},i.readAsArrayBuffer(e)}else try{t(JSON.stringify(e))}catch(n){console.error("Couldn't convert value into a JSON string: ",e),t(null,n)}}function k(e){if(e.substring(0,he)!==de)return JSON.parse(e);var t,n=e.substring(_e),r=e.substring(he,_e);if(r===ve&&le.test(n)){var i=n.match(le);t=i[1],n=n.substring(i[0].length)}var a=P(n);switch(r){case pe:return a;case ve:return o([a],{type:t});case ye:return new Int8Array(a);case ge:return new Uint8Array(a);case be:return new Uint8ClampedArray(a);case me:return new Int16Array(a);case xe:return new Uint16Array(a);case we:return new Int32Array(a);case je:return new Uint32Array(a);case Ee:return new Float32Array(a);case Se:return new Float64Array(a);default:throw new Error("Unkown type: "+r)}}function T(e){var t=this,n={db:null};if(e)for(var r in e)n[r]="string"!=typeof e[r]?e[r].toString():e[r];var o=new ie(function(e,r){try{n.db=openDatabase(n.name,String(n.version),n.description,n.size)}catch(e){return r(e)}n.db.transaction(function(o){o.executeSql("CREATE TABLE IF NOT EXISTS "+n.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){t._dbInfo=n,e()},function(e,t){r(t)})})});return n.serializer=Ae,o}function C(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT * FROM "+o.storeName+" WHERE key = ? LIMIT 1",[e],function(e,n){var r=n.rows.length?n.rows.item(0).value:null;r&&(r=o.serializer.deserialize(r)),t(r)},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function D(e,t){var n=this,r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT * FROM "+o.storeName,[],function(n,r){for(var i=r.rows,a=i.length,s=0;s0)return void i(L.apply(o,[e,s,n,r-1]));a(t)}})})}).catch(a)});return i(a,n),a}function R(e,t,n){return L.apply(this,[e,t,n,1])}function B(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("DELETE FROM "+o.storeName+" WHERE key = ?",[e],function(){t()},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function q(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("DELETE FROM "+r.storeName,[],function(){e()},function(e,t){n(t)})})}).catch(n)});return i(n,e),n}function z(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("SELECT COUNT(key) as c FROM "+r.storeName,[],function(t,n){var r=n.rows.item(0).c;e(r)},function(e,t){n(t)})})}).catch(n)});return i(n,e),n}function F(e,t){var n=this,r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT key FROM "+o.storeName+" WHERE id = ? LIMIT 1",[e+1],function(e,n){var r=n.rows.length?n.rows.item(0).key:null;t(r)},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function U(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("SELECT key FROM "+r.storeName,[],function(t,n){for(var r=[],o=0;o=0;n--){var r=localStorage.key(n);0===r.indexOf(e)&&localStorage.removeItem(r)}});return i(n,e),n}function J(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=n.ready().then(function(){var t=n._dbInfo,r=localStorage.getItem(t.keyPrefix+e);return r&&(r=t.serializer.deserialize(r)),r});return i(r,t),r}function G(e,t){var n=this,r=n.ready().then(function(){for(var t=n._dbInfo,r=t.keyPrefix,o=r.length,i=localStorage.length,a=1,s=0;s=e.length-1||t<0?0:t+1}function getCurrentProblem(e){return e[config.currentIndex]}function previousProblem(){console.log("previousProblem!"),previousProblemButtonEl.classList.add("active"),config.currentIndex=config.shuffle?getRandomIndex(problems):getPreviousIndex(problems),updateLocalstore(config).then(function(){window.location.reload()})}function nextProblem(){console.log("nextProblem!"),nextProblemButtonEl.classList.add("active"),config.currentIndex=config.shuffle?getRandomIndex(problems):getNextIndex(problems),updateLocalstore(config).then(function(){window.location.reload()})}function toggleShuffle(){console.log("toggle shuffle!"),config.shuffle=!config.shuffle,shuffleProblemsButtonEl.classList.toggle("active"),previousProblemButtonEl.parentNode.classList.toggle("hidden"),updateLocalstore(config)}function loadProblem(e){currentProblem=e,problemEl.innerText=e.prompt,e.given&&(codeEl.value=e.given),testSuite(null,!0)}function updateTests(e,t){!0===t&&buildTests(currentProblem.tests),updateTestStatus(e)}function buildTests(e){if(e){var t=e.map(function(e){return'
\n
[✘]
\n
'+e.name+"
\n
"}).join("");testSuiteEl.innerHTML=t}}function updateTestStatus(e){if(!e)throw new Error("No testStatuses provided.");var t=!0;e.forEach(function(e){!0!==e&&(t=!1)}),[].slice.call(testSuiteEl.querySelectorAll(".test-state")).forEach(function(t,n){!0===e[n]?(t.innerHTML="[✓]",t.classList.remove("fail"),t.classList.add("pass")):(t.innerHTML="[✘]",t.classList.remove("pass"),t.classList.add("fail"))}),!0===t?(testTotalEl.innerText="PASS",testTotalEl.classList.remove("fail"),testTotalEl.classList.add("pass")):(testTotalEl.innerText="FAIL",testTotalEl.classList.remove("pass"),testTotalEl.classList.add("fail"))}function printAssertError(e){var t="";null!==e&&(t='\n
\n Expected: '+JSON.stringify(e.expected)+"\n Actual: "+JSON.stringify(e.actual)+"\n
"),assertConsoleEl.innerHTML=t}function printEvalOutput(e,t){var n="";e&&void 0!==e.message?n='\n
\n Syntax Error: '+JSON.stringify(e.message)+"\n
":t&&(n='\n
\n Output: '+JSON.stringify(t)+"\n
"),evalConsoleEl.innerHTML=n}function testSuite(e){testTotalEl.classList.toggle("working");var t=runTests(getOutput(codeEl.value));testTotalEl.classList.toggle("working"),updateTests(t,e)}function getOutput(code){var evald=!1;try{evald=eval("(function(){"+code+"})()"),printEvalOutput(null,evald)}catch(e){printEvalOutput(e)}return evald}function runTests(output){var tested=!1;return tested=currentProblem.tests.map(function(test){var testOutcome=!1;try{output&&(testOutcome=eval(test.test),console.log("testOutcome:",testOutcome)),printAssertError(null)}catch(e){printAssertError(e)}return testOutcome})}function loadApp(e){function t(t){!1===e.shuffle&&13===t.keyCode&&t.shiftKey&&(t.metaKey||t.ctrlKey)?previousProblem():13!==t.keyCode||t.shiftKey||!t.metaKey&&!t.ctrlKey||nextProblem()}console.log("loading app!"),!0===e.shuffle&&(shuffleProblemsButtonEl.classList.add("active"),previousProblemButtonEl.parentNode.classList.add("hidden"));var n=debounce(function(e){-1===ignoreKeyCodes.indexOf(e.keyCode)&&testSuite()},200);codeEl.addEventListener("keydown",n),document.addEventListener("keydown",t),shuffleProblemsButtonEl.addEventListener("click",toggleShuffle),previousProblemButtonEl.addEventListener("click",previousProblem),nextProblemButtonEl.addEventListener("click",nextProblem),loadProblem(getCurrentProblem(problems)),testSuite(!0)}var localforage=require("localforage"),probs=require("pjs-problems"),dedent=require("dedent"),assert=require("chai").assert,problems=[];Object.keys(probs).forEach(function(e){var t;(t=problems).push.apply(t,_toConsumableArray(probs[e]))}),problems=dedentStrings(problems);var currentProblem=void 0,ignoreKeyCodes=[9,37,39,38,40],config={shuffle:!0,timer:!1,currentIndex:0};localforage.getItem("js_practice_config").then(function(e){e&&(config=e),loadApp(config)}).catch(function(e){console.log("localforage err:",e),loadApp(config)});var problemEl=document.getElementById("problem"),codeEl=document.getElementById("code"),testSuiteEl=document.getElementById("test-suite"),testTotalEl=document.getElementById("test-total"),evalConsoleEl=document.getElementById("eval-output"),assertConsoleEl=document.getElementById("assert-output"),shuffleProblemsButtonEl=document.getElementById("shuffle-problems"),previousProblemButtonEl=document.getElementById("prev-problem"),nextProblemButtonEl=document.getElementById("next-problem")}(document,window)},{chai:5,dedent:34,localforage:37,"pjs-problems":1}]},{},[42]); //# sourceMappingURL=bundle.min.js.map diff --git a/public/dist/js/bundle.min.js.map b/public/dist/js/bundle.min.js.map index 05d2de1..51fd579 100644 --- a/public/dist/js/bundle.min.js.map +++ b/public/dist/js/bundle.min.js.map @@ -1,5 +1 @@ -<<<<<<< HEAD -{"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/assertion-error/index.js","node_modules/chai/index.js","node_modules/chai/lib/chai.js","node_modules/chai/lib/chai/assertion.js","node_modules/chai/lib/chai/config.js","node_modules/chai/lib/chai/core/assertions.js","node_modules/chai/lib/chai/interface/assert.js","node_modules/chai/lib/chai/interface/expect.js","node_modules/chai/lib/chai/interface/should.js","node_modules/chai/lib/chai/utils/addChainableMethod.js","node_modules/chai/lib/chai/utils/addMethod.js","node_modules/chai/lib/chai/utils/addProperty.js","node_modules/chai/lib/chai/utils/expectTypes.js","node_modules/chai/lib/chai/utils/flag.js","node_modules/chai/lib/chai/utils/getActual.js","node_modules/chai/lib/chai/utils/getEnumerableProperties.js","node_modules/chai/lib/chai/utils/getMessage.js","node_modules/chai/lib/chai/utils/getName.js","node_modules/chai/lib/chai/utils/getPathInfo.js","node_modules/chai/lib/chai/utils/getPathValue.js","node_modules/chai/lib/chai/utils/getProperties.js","node_modules/chai/lib/chai/utils/hasProperty.js","node_modules/chai/lib/chai/utils/index.js","node_modules/chai/lib/chai/utils/inspect.js","node_modules/chai/lib/chai/utils/objDisplay.js","node_modules/chai/lib/chai/utils/overwriteChainableMethod.js","node_modules/chai/lib/chai/utils/overwriteMethod.js","node_modules/chai/lib/chai/utils/overwriteProperty.js","node_modules/chai/lib/chai/utils/test.js","node_modules/chai/lib/chai/utils/transferFlags.js","node_modules/deep-eql/index.js","node_modules/deep-eql/lib/eql.js","node_modules/deep-eql/node_modules/type-detect/index.js","node_modules/deep-eql/node_modules/type-detect/lib/type.js","node_modules/localforage/dist/localforage.js","node_modules/type-detect/lib/type.js","src/js/index.js","src/problems/arrays.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length","1","module","exclude","excludeProps","res","obj","Object","keys","forEach","key","excludes","indexOf","slice","arguments","args","AssertionError","message","_props","ssf","extend","props","this","showDiff","callee","captureStackTrace","stack","prototype","create","name","constructor","toJSON","used","version","util","use","fn","push","config","assertion","core","expect","should","assert","_chai","Assertion","msg","flag","defineProperty","get","console","warn","includeStack","set","value","addProperty","addMethod","addChainableMethod","chainingBehavior","overwriteProperty","overwriteMethod","overwriteChainableMethod","expr","negateMsg","expected","_actual","ok","test","getMessage","actual","getActual","val","truncateThreshold","chai","_","an","type","toLowerCase","article","charAt","includeChainingBehavior","include","expectTypes","eql","k","property","subset","undefined","inspect","checkArguments","toString","assertEqual","_obj","assertEql","assertAbove","to","have","len","assertLeast","assertBelow","assertMost","assertInstanceOf","getName","assertOwnProperty","hasOwnProperty","assertOwnPropertyDescriptor","descriptor","actualDescriptor","getOwnPropertyDescriptor","assertLengthChain","assertLength","assertMatch","re","exec","assertKeys","str","mixedArgsMsg","Array","any","all","filter","every","map","last","pop","join","sort","assertThrows","errMsg","is","thrown","desiredError","thrownError","RegExp","err","actuallyGot","expectedThrown","respondTo","method","itself","context","satisfy","matcher","result","objDisplay","negate","closeTo","delta","Math","abs","isSubsetOf","superset","cmp","elem","some","elem2","oneOf","list","be","assertChanges","object","prop","initial","assertIncreases","assertDecreases","chain","isNaN","isArray","start","finish","range","isDeep","pathInfo","getPathInfo","hasProperty","exists","isExtensible","TypeError","isSealed","isFrozen","express","errmsg","fail","operator","isOk","isNotOk","not","equal","act","exp","notEqual","strictEqual","notStrictEqual","deepEqual","notDeepEqual","isAbove","abv","above","isAtLeast","atlst","least","isBelow","blw","below","isAtMost","atmst","most","isTrue","isNotTrue","isFalse","isNotFalse","isNull","isNotNull","NaN","isNotNaN","isUndefined","isDefined","isFunction","isNotFunction","isObject","isNotObject","isNotArray","isString","isNotString","isNumber","isNotNumber","isBoolean","isNotBoolean","typeOf","notTypeOf","instanceOf","notInstanceOf","inc","notInclude","match","notMatch","notProperty","deepProperty","deep","notDeepProperty","propertyVal","propertyNotVal","deepPropertyVal","deepPropertyNotVal","lengthOf","throws","errt","errs","assertErr","throw","doesNotThrow","Throw","val2","approximately","sameMembers","set1","set2","same","members","sameDeepMembers","includeMembers","includeDeepMembers","inList","changes","change","doesNotChange","increases","increase","doesNotIncrease","decreases","decrease","doesNotDecrease","ifError","extensible","isNotExtensible","sealed","isNotSealed","frozen","isNotFrozen","alias","as","loadShould","shouldGetter","String","Number","Boolean","valueOf","shouldSetter","enumerable","configurable","writable","val1","exist","Should","transferFlags","hasProtoSupport","excludeNames","Function","apply","ctx","chainableBehavior","__methods","__proto__","getOwnPropertyNames","asserterName","pd","getter","types","index","art","flags","__flags","flagMsg","replace","func","parsePath","path","mArr","parseFloat","p","_getPathValue","parsed","tmp","part","info","parent","proto","getPrototypeOf","literals","number","string","ot","getPathValue","showHidden","depth","colors","formatValue","seen","stylize","recurseTimes","ret","primitive","formatPrimitive","isDOMElement","outerHTML","document","xmlVersion","XMLSerializer","serializeToString","container","createElementNS","appendChild","cloneNode","html","innerHTML","visibleKeys","getEnumerableProperties","getProperties","isError","nameSuffix","isRegExp","isDate","Date","toUTCString","formatError","base","array","braces","output","formatArray","formatProperty","reduceToSingleString","simple","JSON","stringify","Infinity","__lookupGetter__","__lookupSetter__","split","line","substr","numLinesEst","reduce","prev","cur","ar","objectToString","d","HTMLElement","nodeType","nodeName","splice","_chainingBehavior","_method","_super","_get","includeAll","b","m","sameValue","dateEqual","regexpEqual","Buffer","isBuffer","bufferEqual","argumentsEqual","typeEqual","objectEqual","getTime","iterableEqual","isValue","ka","kb","ex","getType","natives","Library","tests","[object Array]","[object RegExp]","[object Function]","[object Arguments]","[object Date]","of","define","ReferenceError","amd","g","window","global","self","localforage","_dereq_","nextTick","draining","oldQueue","queue","immediate","task","scheduleDrain","Mutation","MutationObserver","WebKitMutationObserver","called","observer","element","createTextNode","observe","characterData","data","setImmediate","MessageChannel","createElement","scriptEl","onreadystatechange","parentNode","removeChild","documentElement","setTimeout","channel","port1","onmessage","port2","postMessage","2","INTERNAL","Promise","resolver","state","PENDING","outcome","safelyResolveThenable","QueueItem","promise","onFulfilled","onRejected","callFulfilled","otherCallFulfilled","callRejected","otherCallRejected","unwrap","returnValue","handlers","reject","resolve","getThen","then","thenable","onError","onSuccess","tryToUnwrap","tryCatch","status","out","reason","iterable","values","resolved","resolveFromAll","outValue","error","race","response","REJECTED","FULFILLED","3","4","_classCallCheck","instance","Constructor","createBlob","parts","properties","Blob","Builder","BlobBuilder","MSBlobBuilder","MozBlobBuilder","WebKitBlobBuilder","builder","append","getBlob","executeCallback","callback","executeTwoCallbacks","errorCallback","_binStringToArrayBuffer","bin","buf","ArrayBuffer","arr","Uint8Array","charCodeAt","_checkBlobSupportWithoutCaching","idb","Promise$1","txn","transaction","DETECT_BLOB_SUPPORT_STORE","blob","objectStore","put","onabort","preventDefault","stopPropagation","oncomplete","matchedChrome","navigator","userAgent","matchedEdge","parseInt","_checkBlobSupport","supportsBlobs","_deferReadiness","dbInfo","dbContext","dbContexts","deferredOperation","deferredOperations","dbReady","_advanceReadiness","_getConnection","upgradeNeeded","db","close","dbArgs","openreq","open","onupgradeneeded","createObjectStore","storeName","oldVersion","newVersion","onerror","onsuccess","_getOriginalConnection","_getUpgradedConnection","_isUpgradeNeeded","defaultVersion","isNewStore","objectStoreNames","contains","isDowngrade","isUpgrade","incVersion","_encodeBlob","reader","FileReader","onloadend","base64","btoa","target","__local_forage_encoded_blob","readAsBinaryString","_decodeBlob","encodedBlob","atob","_isEncodedBlob","_fullyReady","_initReady","_dbInfo","_initStorage","options","ignoreErrors","forages","ready","initPromises","j","forage","_defaultConfig","getItem","store","req","iterate","iterator","openCursor","iterationNumber","cursor","setItem","blobSupport","removeItem","clear","count","advanced","advance","stringToBuffer","serializedString","encoded1","encoded2","encoded3","encoded4","bufferLength","buffer","bytes","BASE_CHARS","bufferToString","base64String","substring","serialize","valueType","toString$1","marker","SERIALIZED_MARKER","TYPE_ARRAYBUFFER","TYPE_INT8ARRAY","TYPE_UINT8ARRAY","TYPE_UINT8CLAMPEDARRAY","TYPE_INT16ARRAY","TYPE_UINT16ARRAY","TYPE_INT32ARRAY","TYPE_UINT32ARRAY","TYPE_FLOAT32ARRAY","TYPE_FLOAT64ARRAY","fileReader","onload","BLOB_TYPE_PREFIX","TYPE_BLOB","readAsArrayBuffer","deserialize","SERIALIZED_MARKER_LENGTH","parse","blobType","TYPE_SERIALIZED_MARKER_LENGTH","BLOB_TYPE_PREFIX_REGEX","Int8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","_initStorage$1","dbInfoPromise","openDatabase","description","size","executeSql","serializer","localforageSerializer","getItem$1","results","rows","item","iterate$1","_setItem","retriesLeft","originalValue","sqlError","QUOTA_ERR","setItem$1","removeItem$1","clear$1","length$1","c","key$1","keys$1","_initStorage$2","keyPrefix","clear$2","localStorage","getItem$2","iterate$2","keyPrefixLength","key$2","keys$2","length$2","removeItem$2","setItem$2","callWhenReady","localForageInstance","libraryMethod","_args","arg","isLibraryDriver","driverName","driver","DriverType","_typeof","Symbol","indexedDB","webkitIndexedDB","mozIndexedDB","OIndexedDB","msIndexedDB","asyncStorage","_driver","webSQLStorage","localStorageWrapper","CustomDrivers","INDEXEDDB","LOCALSTORAGE","WEBSQL","DefaultDriverOrder","LibraryMethods","DefaultConfig","driverSupport","isSafari","platform","hasFetch","fetch","IDBKeyRange","LocalForage","_config","_driverSet","_initDriver","_ready","_wrapLibraryMethodsWithReady","setDriver","defineDriver","driverObject","complianceError","namingError","customDriverMethods","concat","customDriverMethod","supportPromise","_support","supportResult","getDriver","getDriverPromise","getSerializer","serializerPromise","drivers","setDriverToConfig","extendSelfWithDriver","_extend","initDriver","supportedDrivers","driverPromiseLoop","currentDriverIndex","_getSupportedDrivers","oldDriverSetDone","supports","libraryMethodsAndProperties","createInstance","localforage_js","objectTypeRegexp","updateLocalstore","catch","log","debounce","wait","timeout","later","callNow","clearTimeout","getRandomIndex","problemsArr","ind","floor","random","currentIndex","getPreviousIndex","getNextIndex","getCurrentProblem","previousProblem","previousProblemButtonEl","classList","add","shuffle","problems","location","reload","nextProblem","nextProblemButtonEl","toggleShuffle","shuffleProblemsButtonEl","toggle","loadProblem","problemObj","currentProblem","problemEl","innerText","prompt","given","codeEl","testSuite","updateTests","testStatus","init","buildTests","updateTestStatus","testsDom","testSuiteEl","testStatuses","allPassed","testPassed","querySelectorAll","testStatusEl","iter","remove","testTotalEl","printAssertError","errObj","inner","assertConsoleEl","printEvalOutput","evalConsoleEl","getOutput","tested","runTests","evald","eval","testOutcome","loadApp","problemNav","keyCode","shiftKey","metaKey","ctrlKey","debouncedInputValidation","ignoreKeyCodes","addEventListener","timer","getElementById","time","answer","evenNumbers","someOddNumbers"],"mappings":"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","file":"bundle.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o\n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n var excludes = [].slice.call(arguments);\n\n function excludeProps (res, obj) {\n Object.keys(obj).forEach(function (key) {\n if (!~excludes.indexOf(key)) res[key] = obj[key];\n });\n }\n\n return function extendExclude () {\n var args = [].slice.call(arguments)\n , i = 0\n , res = {};\n\n for (; i < args.length; i++) {\n excludeProps(res, args[i]);\n }\n\n return res;\n };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n , props = extend(_props || {});\n\n // default values\n this.message = message || 'Unspecified AssertionError';\n this.showDiff = false;\n\n // copy from properties\n for (var key in props) {\n this[key] = props[key];\n }\n\n // capture stack trace\n ssf = ssf || arguments.callee;\n if (ssf && Error.captureStackTrace) {\n Error.captureStackTrace(this, ssf);\n } else {\n try {\n throw new Error();\n } catch(e) {\n this.stack = e.stack;\n }\n }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n var extend = exclude('constructor', 'toJSON', 'stack')\n , props = extend({ name: this.name }, this);\n\n // include stack if exists and not turned off\n if (false !== stack && this.stack) {\n props.stack = this.stack;\n }\n\n return props;\n};\n","module.exports = require('./lib/chai');\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar used = []\n , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n if (!~used.indexOf(fn)) {\n fn(this, util);\n used.push(fn);\n }\n\n return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n /*!\n * Module dependencies.\n */\n\n var AssertionError = _chai.AssertionError\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n _chai.Assertion = Assertion;\n\n /*!\n * Assertion Constructor\n *\n * Creates object for chaining.\n *\n * @api private\n */\n\n function Assertion (obj, msg, stack) {\n flag(this, 'ssfi', stack || arguments.callee);\n flag(this, 'object', obj);\n flag(this, 'message', msg);\n }\n\n Object.defineProperty(Assertion, 'includeStack', {\n get: function() {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n return config.includeStack;\n },\n set: function(value) {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n config.includeStack = value;\n }\n });\n\n Object.defineProperty(Assertion, 'showDiff', {\n get: function() {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n return config.showDiff;\n },\n set: function(value) {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n config.showDiff = value;\n }\n });\n\n Assertion.addProperty = function (name, fn) {\n util.addProperty(this.prototype, name, fn);\n };\n\n Assertion.addMethod = function (name, fn) {\n util.addMethod(this.prototype, name, fn);\n };\n\n Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n Assertion.overwriteProperty = function (name, fn) {\n util.overwriteProperty(this.prototype, name, fn);\n };\n\n Assertion.overwriteMethod = function (name, fn) {\n util.overwriteMethod(this.prototype, name, fn);\n };\n\n Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n /**\n * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n *\n * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n *\n * @name assert\n * @param {Philosophical} expression to be tested\n * @param {String|Function} message or function that returns message to display if expression fails\n * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n * @param {Mixed} expected value (remember to check for negation)\n * @param {Mixed} actual (optional) will default to `this.obj`\n * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n * @api private\n */\n\n Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n var ok = util.test(this, arguments);\n if (true !== showDiff) showDiff = false;\n if (true !== config.showDiff) showDiff = false;\n\n if (!ok) {\n var msg = util.getMessage(this, arguments)\n , actual = util.getActual(this, arguments);\n throw new AssertionError(msg, {\n actual: actual\n , expected: expected\n , showDiff: showDiff\n }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n }\n };\n\n /*!\n * ### ._obj\n *\n * Quick reference to stored `actual` value for plugin developers.\n *\n * @api private\n */\n\n Object.defineProperty(Assertion.prototype, '_obj',\n { get: function () {\n return flag(this, 'object');\n }\n , set: function (val) {\n flag(this, 'object', val);\n }\n });\n};\n","module.exports = {\n\n /**\n * ### config.includeStack\n *\n * User configurable property, influences whether stack trace\n * is included in Assertion error message. Default of false\n * suppresses stack trace in the error message.\n *\n * chai.config.includeStack = true; // enable stack on error\n *\n * @param {Boolean}\n * @api public\n */\n\n includeStack: false,\n\n /**\n * ### config.showDiff\n *\n * User configurable property, influences whether or not\n * the `showDiff` flag should be included in the thrown\n * AssertionErrors. `false` will always be `false`; `true`\n * will be true when the assertion has requested a diff\n * be shown.\n *\n * @param {Boolean}\n * @api public\n */\n\n showDiff: true,\n\n /**\n * ### config.truncateThreshold\n *\n * User configurable property, sets length threshold for actual and\n * expected values in assertion errors. If this threshold is exceeded, for\n * example for large data structures, the value is replaced with something\n * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n *\n * Set it to zero if you want to disable truncating altogether.\n *\n * This is especially userful when doing assertions on arrays: having this\n * set to a reasonable large value makes the failure messages readily\n * inspectable.\n *\n * chai.config.truncateThreshold = 0; // disable truncating\n *\n * @param {Number}\n * @api public\n */\n\n truncateThreshold: 40\n\n};\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n var Assertion = chai.Assertion\n , toString = Object.prototype.toString\n , flag = _.flag;\n\n /**\n * ### Language Chains\n *\n * The following are provided as chainable getters to\n * improve the readability of your assertions. They\n * do not provide testing capabilities unless they\n * have been overwritten by a plugin.\n *\n * **Chains**\n *\n * - to\n * - be\n * - been\n * - is\n * - that\n * - which\n * - and\n * - has\n * - have\n * - with\n * - at\n * - of\n * - same\n *\n * @name language chains\n * @namespace BDD\n * @api public\n */\n\n [ 'to', 'be', 'been'\n , 'is', 'and', 'has', 'have'\n , 'with', 'that', 'which', 'at'\n , 'of', 'same' ].forEach(function (chain) {\n Assertion.addProperty(chain, function () {\n return this;\n });\n });\n\n /**\n * ### .not\n *\n * Negates any of assertions following in the chain.\n *\n * expect(foo).to.not.equal('bar');\n * expect(goodFn).to.not.throw(Error);\n * expect({ foo: 'baz' }).to.have.property('foo')\n * .and.not.equal('bar');\n *\n * @name not\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('not', function () {\n flag(this, 'negate', true);\n });\n\n /**\n * ### .deep\n *\n * Sets the `deep` flag, later used by the `equal` and\n * `property` assertions.\n *\n * expect(foo).to.deep.equal({ bar: 'baz' });\n * expect({ foo: { bar: { baz: 'quux' } } })\n * .to.have.deep.property('foo.bar.baz', 'quux');\n *\n * `.deep.property` special characters can be escaped\n * by adding two slashes before the `.` or `[]`.\n *\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name deep\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('deep', function () {\n flag(this, 'deep', true);\n });\n\n /**\n * ### .any\n *\n * Sets the `any` flag, (opposite of the `all` flag)\n * later used in the `keys` assertion.\n *\n * expect(foo).to.have.any.keys('bar', 'baz');\n *\n * @name any\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('any', function () {\n flag(this, 'any', true);\n flag(this, 'all', false)\n });\n\n\n /**\n * ### .all\n *\n * Sets the `all` flag (opposite of the `any` flag)\n * later used by the `keys` assertion.\n *\n * expect(foo).to.have.all.keys('bar', 'baz');\n *\n * @name all\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('all', function () {\n flag(this, 'all', true);\n flag(this, 'any', false);\n });\n\n /**\n * ### .a(type)\n *\n * The `a` and `an` assertions are aliases that can be\n * used either as language chains or to assert a value's\n * type.\n *\n * // typeof\n * expect('test').to.be.a('string');\n * expect({ foo: 'bar' }).to.be.an('object');\n * expect(null).to.be.a('null');\n * expect(undefined).to.be.an('undefined');\n * expect(new Error).to.be.an('error');\n * expect(new Promise).to.be.a('promise');\n * expect(new Float32Array()).to.be.a('float32array');\n * expect(Symbol()).to.be.a('symbol');\n *\n * // es6 overrides\n * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n *\n * // language chain\n * expect(foo).to.be.an.instanceof(Foo);\n *\n * @name a\n * @alias an\n * @param {String} type\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function an (type, msg) {\n if (msg) flag(this, 'message', msg);\n type = type.toLowerCase();\n var obj = flag(this, 'object')\n , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n this.assert(\n type === _.type(obj)\n , 'expected #{this} to be ' + article + type\n , 'expected #{this} not to be ' + article + type\n );\n }\n\n Assertion.addChainableMethod('an', an);\n Assertion.addChainableMethod('a', an);\n\n /**\n * ### .include(value)\n *\n * The `include` and `contain` assertions can be used as either property\n * based language chains or as methods to assert the inclusion of an object\n * in an array or a substring in a string. When used as language chains,\n * they toggle the `contains` flag for the `keys` assertion.\n *\n * expect([1,2,3]).to.include(2);\n * expect('foobar').to.contain('foo');\n * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n *\n * @name include\n * @alias contain\n * @alias includes\n * @alias contains\n * @param {Object|String|Number} obj\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function includeChainingBehavior () {\n flag(this, 'contains', true);\n }\n\n function include (val, msg) {\n _.expectTypes(this, ['array', 'object', 'string']);\n\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var expected = false;\n\n if (_.type(obj) === 'array' && _.type(val) === 'object') {\n for (var i in obj) {\n if (_.eql(obj[i], val)) {\n expected = true;\n break;\n }\n }\n } else if (_.type(val) === 'object') {\n if (!flag(this, 'negate')) {\n for (var k in val) new Assertion(obj).property(k, val[k]);\n return;\n }\n var subset = {};\n for (var k in val) subset[k] = obj[k];\n expected = _.eql(subset, val);\n } else {\n expected = (obj != undefined) && ~obj.indexOf(val);\n }\n this.assert(\n expected\n , 'expected #{this} to include ' + _.inspect(val)\n , 'expected #{this} to not include ' + _.inspect(val));\n }\n\n Assertion.addChainableMethod('include', include, includeChainingBehavior);\n Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n /**\n * ### .ok\n *\n * Asserts that the target is truthy.\n *\n * expect('everything').to.be.ok;\n * expect(1).to.be.ok;\n * expect(false).to.not.be.ok;\n * expect(undefined).to.not.be.ok;\n * expect(null).to.not.be.ok;\n *\n * @name ok\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('ok', function () {\n this.assert(\n flag(this, 'object')\n , 'expected #{this} to be truthy'\n , 'expected #{this} to be falsy');\n });\n\n /**\n * ### .true\n *\n * Asserts that the target is `true`.\n *\n * expect(true).to.be.true;\n * expect(1).to.not.be.true;\n *\n * @name true\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('true', function () {\n this.assert(\n true === flag(this, 'object')\n , 'expected #{this} to be true'\n , 'expected #{this} to be false'\n , this.negate ? false : true\n );\n });\n\n /**\n * ### .false\n *\n * Asserts that the target is `false`.\n *\n * expect(false).to.be.false;\n * expect(0).to.not.be.false;\n *\n * @name false\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('false', function () {\n this.assert(\n false === flag(this, 'object')\n , 'expected #{this} to be false'\n , 'expected #{this} to be true'\n , this.negate ? true : false\n );\n });\n\n /**\n * ### .null\n *\n * Asserts that the target is `null`.\n *\n * expect(null).to.be.null;\n * expect(undefined).to.not.be.null;\n *\n * @name null\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('null', function () {\n this.assert(\n null === flag(this, 'object')\n , 'expected #{this} to be null'\n , 'expected #{this} not to be null'\n );\n });\n\n /**\n * ### .undefined\n *\n * Asserts that the target is `undefined`.\n *\n * expect(undefined).to.be.undefined;\n * expect(null).to.not.be.undefined;\n *\n * @name undefined\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('undefined', function () {\n this.assert(\n undefined === flag(this, 'object')\n , 'expected #{this} to be undefined'\n , 'expected #{this} not to be undefined'\n );\n });\n\n /**\n * ### .NaN\n * Asserts that the target is `NaN`.\n *\n * expect('foo').to.be.NaN;\n * expect(4).not.to.be.NaN;\n *\n * @name NaN\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('NaN', function () {\n this.assert(\n isNaN(flag(this, 'object'))\n , 'expected #{this} to be NaN'\n , 'expected #{this} not to be NaN'\n );\n });\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi'\n * , bar = null\n * , baz;\n *\n * expect(foo).to.exist;\n * expect(bar).to.not.exist;\n * expect(baz).to.not.exist;\n *\n * @name exist\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('exist', function () {\n this.assert(\n null != flag(this, 'object')\n , 'expected #{this} to exist'\n , 'expected #{this} to not exist'\n );\n });\n\n\n /**\n * ### .empty\n *\n * Asserts that the target's length is `0`. For arrays and strings, it checks\n * the `length` property. For objects, it gets the count of\n * enumerable keys.\n *\n * expect([]).to.be.empty;\n * expect('').to.be.empty;\n * expect({}).to.be.empty;\n *\n * @name empty\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('empty', function () {\n var obj = flag(this, 'object')\n , expected = obj;\n\n if (Array.isArray(obj) || 'string' === typeof object) {\n expected = obj.length;\n } else if (typeof obj === 'object') {\n expected = Object.keys(obj).length;\n }\n\n this.assert(\n !expected\n , 'expected #{this} to be empty'\n , 'expected #{this} not to be empty'\n );\n });\n\n /**\n * ### .arguments\n *\n * Asserts that the target is an arguments object.\n *\n * function test () {\n * expect(arguments).to.be.arguments;\n * }\n *\n * @name arguments\n * @alias Arguments\n * @namespace BDD\n * @api public\n */\n\n function checkArguments () {\n var obj = flag(this, 'object')\n , type = Object.prototype.toString.call(obj);\n this.assert(\n '[object Arguments]' === type\n , 'expected #{this} to be arguments but got ' + type\n , 'expected #{this} to not be arguments'\n );\n }\n\n Assertion.addProperty('arguments', checkArguments);\n Assertion.addProperty('Arguments', checkArguments);\n\n /**\n * ### .equal(value)\n *\n * Asserts that the target is strictly equal (`===`) to `value`.\n * Alternately, if the `deep` flag is set, asserts that\n * the target is deeply equal to `value`.\n *\n * expect('hello').to.equal('hello');\n * expect(42).to.equal(42);\n * expect(1).to.not.equal(true);\n * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n *\n * @name equal\n * @alias equals\n * @alias eq\n * @alias deep.equal\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEqual (val, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'deep')) {\n return this.eql(val);\n } else {\n this.assert(\n val === obj\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{exp}'\n , val\n , this._obj\n , true\n );\n }\n }\n\n Assertion.addMethod('equal', assertEqual);\n Assertion.addMethod('equals', assertEqual);\n Assertion.addMethod('eq', assertEqual);\n\n /**\n * ### .eql(value)\n *\n * Asserts that the target is deeply equal to `value`.\n *\n * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n *\n * @name eql\n * @alias eqls\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEql(obj, msg) {\n if (msg) flag(this, 'message', msg);\n this.assert(\n _.eql(obj, flag(this, 'object'))\n , 'expected #{this} to deeply equal #{exp}'\n , 'expected #{this} to not deeply equal #{exp}'\n , obj\n , this._obj\n , true\n );\n }\n\n Assertion.addMethod('eql', assertEql);\n Assertion.addMethod('eqls', assertEql);\n\n /**\n * ### .above(value)\n *\n * Asserts that the target is greater than `value`.\n *\n * expect(10).to.be.above(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n *\n * @name above\n * @alias gt\n * @alias greaterThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertAbove (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len > n\n , 'expected #{this} to have a length above #{exp} but got #{act}'\n , 'expected #{this} to not have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj > n\n , 'expected #{this} to be above ' + n\n , 'expected #{this} to be at most ' + n\n );\n }\n }\n\n Assertion.addMethod('above', assertAbove);\n Assertion.addMethod('gt', assertAbove);\n Assertion.addMethod('greaterThan', assertAbove);\n\n /**\n * ### .least(value)\n *\n * Asserts that the target is greater than or equal to `value`.\n *\n * expect(10).to.be.at.least(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.least(2);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n *\n * @name least\n * @alias gte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLeast (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= n\n , 'expected #{this} to have a length at least #{exp} but got #{act}'\n , 'expected #{this} to have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj >= n\n , 'expected #{this} to be at least ' + n\n , 'expected #{this} to be below ' + n\n );\n }\n }\n\n Assertion.addMethod('least', assertLeast);\n Assertion.addMethod('gte', assertLeast);\n\n /**\n * ### .below(value)\n *\n * Asserts that the target is less than `value`.\n *\n * expect(5).to.be.below(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n *\n * @name below\n * @alias lt\n * @alias lessThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertBelow (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len < n\n , 'expected #{this} to have a length below #{exp} but got #{act}'\n , 'expected #{this} to not have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj < n\n , 'expected #{this} to be below ' + n\n , 'expected #{this} to be at least ' + n\n );\n }\n }\n\n Assertion.addMethod('below', assertBelow);\n Assertion.addMethod('lt', assertBelow);\n Assertion.addMethod('lessThan', assertBelow);\n\n /**\n * ### .most(value)\n *\n * Asserts that the target is less than or equal to `value`.\n *\n * expect(5).to.be.at.most(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.most(4);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n *\n * @name most\n * @alias lte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertMost (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len <= n\n , 'expected #{this} to have a length at most #{exp} but got #{act}'\n , 'expected #{this} to have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj <= n\n , 'expected #{this} to be at most ' + n\n , 'expected #{this} to be above ' + n\n );\n }\n }\n\n Assertion.addMethod('most', assertMost);\n Assertion.addMethod('lte', assertMost);\n\n /**\n * ### .within(start, finish)\n *\n * Asserts that the target is within a range.\n *\n * expect(7).to.be.within(5,10);\n *\n * Can also be used in conjunction with `length` to\n * assert a length range. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * @name within\n * @param {Number} start lowerbound inclusive\n * @param {Number} finish upperbound inclusive\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('within', function (start, finish, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , range = start + '..' + finish;\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= start && len <= finish\n , 'expected #{this} to have a length within ' + range\n , 'expected #{this} to not have a length within ' + range\n );\n } else {\n this.assert(\n obj >= start && obj <= finish\n , 'expected #{this} to be within ' + range\n , 'expected #{this} to not be within ' + range\n );\n }\n });\n\n /**\n * ### .instanceof(constructor)\n *\n * Asserts that the target is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , Chai = new Tea('chai');\n *\n * expect(Chai).to.be.an.instanceof(Tea);\n * expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n *\n * @name instanceof\n * @param {Constructor} constructor\n * @param {String} message _optional_\n * @alias instanceOf\n * @namespace BDD\n * @api public\n */\n\n function assertInstanceOf (constructor, msg) {\n if (msg) flag(this, 'message', msg);\n var name = _.getName(constructor);\n this.assert(\n flag(this, 'object') instanceof constructor\n , 'expected #{this} to be an instance of ' + name\n , 'expected #{this} to not be an instance of ' + name\n );\n };\n\n Assertion.addMethod('instanceof', assertInstanceOf);\n Assertion.addMethod('instanceOf', assertInstanceOf);\n\n /**\n * ### .property(name, [value])\n *\n * Asserts that the target has a property `name`, optionally asserting that\n * the value of that property is strictly equal to `value`.\n * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n * references into objects and arrays.\n *\n * // simple referencing\n * var obj = { foo: 'bar' };\n * expect(obj).to.have.property('foo');\n * expect(obj).to.have.property('foo', 'bar');\n *\n * // deep referencing\n * var deepObj = {\n * green: { tea: 'matcha' }\n * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n * };\n *\n * expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n *\n * You can also use an array as the starting point of a `deep.property`\n * assertion, or traverse nested arrays.\n *\n * var arr = [\n * [ 'chai', 'matcha', 'konacha' ]\n * , [ { tea: 'chai' }\n * , { tea: 'matcha' }\n * , { tea: 'konacha' } ]\n * ];\n *\n * expect(arr).to.have.deep.property('[0][1]', 'matcha');\n * expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n *\n * Furthermore, `property` changes the subject of the assertion\n * to be the value of that property from the original object. This\n * permits for further chainable assertions on that property.\n *\n * expect(obj).to.have.property('foo')\n * .that.is.a('string');\n * expect(deepObj).to.have.property('green')\n * .that.is.an('object')\n * .that.deep.equals({ tea: 'matcha' });\n * expect(deepObj).to.have.property('teas')\n * .that.is.an('array')\n * .with.deep.property('[2]')\n * .that.deep.equals({ tea: 'konacha' });\n *\n * Note that dots and bracket in `name` must be backslash-escaped when\n * the `deep` flag is set, while they must NOT be escaped when the `deep`\n * flag is not set.\n *\n * // simple referencing\n * var css = { '.link[target]': 42 };\n * expect(css).to.have.property('.link[target]', 42);\n *\n * // deep referencing\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name property\n * @alias deep.property\n * @param {String} name\n * @param {Mixed} value (optional)\n * @param {String} message _optional_\n * @returns value of property for chaining\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('property', function (name, val, msg) {\n if (msg) flag(this, 'message', msg);\n\n var isDeep = !!flag(this, 'deep')\n , descriptor = isDeep ? 'deep property ' : 'property '\n , negate = flag(this, 'negate')\n , obj = flag(this, 'object')\n , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n , hasProperty = isDeep\n ? pathInfo.exists\n : _.hasProperty(name, obj)\n , value = isDeep\n ? pathInfo.value\n : obj[name];\n\n if (negate && arguments.length > 1) {\n if (undefined === value) {\n msg = (msg != null) ? msg + ': ' : '';\n throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n }\n } else {\n this.assert(\n hasProperty\n , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n }\n\n if (arguments.length > 1) {\n this.assert(\n val === value\n , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n , val\n , value\n );\n }\n\n flag(this, 'object', value);\n });\n\n\n /**\n * ### .ownProperty(name)\n *\n * Asserts that the target has an own property `name`.\n *\n * expect('test').to.have.ownProperty('length');\n *\n * @name ownProperty\n * @alias haveOwnProperty\n * @param {String} name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnProperty (name, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n obj.hasOwnProperty(name)\n , 'expected #{this} to have own property ' + _.inspect(name)\n , 'expected #{this} to not have own property ' + _.inspect(name)\n );\n }\n\n Assertion.addMethod('ownProperty', assertOwnProperty);\n Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n /**\n * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n *\n * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n *\n * expect('test').to.have.ownPropertyDescriptor('length');\n * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n * expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n *\n * @name ownPropertyDescriptor\n * @alias haveOwnPropertyDescriptor\n * @param {String} name\n * @param {Object} descriptor _optional_\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnPropertyDescriptor (name, descriptor, msg) {\n if (typeof descriptor === 'string') {\n msg = descriptor;\n descriptor = null;\n }\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n if (actualDescriptor && descriptor) {\n this.assert(\n _.eql(descriptor, actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n , descriptor\n , actualDescriptor\n , true\n );\n } else {\n this.assert(\n actualDescriptor\n , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n );\n }\n flag(this, 'object', actualDescriptor);\n }\n\n Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n /**\n * ### .length\n *\n * Sets the `doLength` flag later used as a chain precursor to a value\n * comparison for the `length` property.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * *Deprecation notice:* Using `length` as an assertion will be deprecated\n * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n * asserting for `length` property value using `length(value)` should be\n * switched to use `lengthOf(value)` instead.\n *\n * @name length\n * @namespace BDD\n * @api public\n */\n\n /**\n * ### .lengthOf(value[, message])\n *\n * Asserts that the target's `length` property has\n * the expected value.\n *\n * expect([ 1, 2, 3]).to.have.lengthOf(3);\n * expect('foobar').to.have.lengthOf(6);\n *\n * @name lengthOf\n * @param {Number} length\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLengthChain () {\n flag(this, 'doLength', true);\n }\n\n function assertLength (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n\n this.assert(\n len == n\n , 'expected #{this} to have a length of #{exp} but got #{act}'\n , 'expected #{this} to not have a length of #{act}'\n , n\n , len\n );\n }\n\n Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n Assertion.addMethod('lengthOf', assertLength);\n\n /**\n * ### .match(regexp)\n *\n * Asserts that the target matches a regular expression.\n *\n * expect('foobar').to.match(/^foo/);\n *\n * @name match\n * @alias matches\n * @param {RegExp} RegularExpression\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n function assertMatch(re, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n re.exec(obj)\n , 'expected #{this} to match ' + re\n , 'expected #{this} not to match ' + re\n );\n }\n\n Assertion.addMethod('match', assertMatch);\n Assertion.addMethod('matches', assertMatch);\n\n /**\n * ### .string(string)\n *\n * Asserts that the string target contains another string.\n *\n * expect('foobar').to.have.string('bar');\n *\n * @name string\n * @param {String} string\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('string', function (str, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('string');\n\n this.assert(\n ~obj.indexOf(str)\n , 'expected #{this} to contain ' + _.inspect(str)\n , 'expected #{this} to not contain ' + _.inspect(str)\n );\n });\n\n\n /**\n * ### .keys(key1, [key2], [...])\n *\n * Asserts that the target contains any or all of the passed-in keys.\n * Use in combination with `any`, `all`, `contains`, or `have` will affect\n * what will pass.\n *\n * When used in conjunction with `any`, at least one key that is passed\n * in must exist in the target object. This is regardless whether or not\n * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n * should be used in the assertion. If neither are used, the assertion is\n * defaulted to `all`.\n *\n * When both `all` and `contain` are used, the target object must have at\n * least all of the passed-in keys but may have more keys not listed.\n *\n * When both `all` and `have` are used, the target object must both contain\n * all of the passed-in keys AND the number of keys in the target object must\n * match the number of keys passed in (in other words, a target object must\n * have all and only all of the passed-in keys).\n *\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n *\n *\n * @name keys\n * @alias key\n * @param {...String|Array|Object} keys\n * @namespace BDD\n * @api public\n */\n\n function assertKeys (keys) {\n var obj = flag(this, 'object')\n , str\n , ok = true\n , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n switch (_.type(keys)) {\n case \"array\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n break;\n case \"object\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n keys = Object.keys(keys);\n break;\n default:\n keys = Array.prototype.slice.call(arguments);\n }\n\n if (!keys.length) throw new Error('keys required');\n\n var actual = Object.keys(obj)\n , expected = keys\n , len = keys.length\n , any = flag(this, 'any')\n , all = flag(this, 'all');\n\n if (!any && !all) {\n all = true;\n }\n\n // Has any\n if (any) {\n var intersection = expected.filter(function(key) {\n return ~actual.indexOf(key);\n });\n ok = intersection.length > 0;\n }\n\n // Has all\n if (all) {\n ok = keys.every(function(key){\n return ~actual.indexOf(key);\n });\n if (!flag(this, 'negate') && !flag(this, 'contains')) {\n ok = ok && keys.length == actual.length;\n }\n }\n\n // Key string\n if (len > 1) {\n keys = keys.map(function(key){\n return _.inspect(key);\n });\n var last = keys.pop();\n if (all) {\n str = keys.join(', ') + ', and ' + last;\n }\n if (any) {\n str = keys.join(', ') + ', or ' + last;\n }\n } else {\n str = _.inspect(keys[0]);\n }\n\n // Form\n str = (len > 1 ? 'keys ' : 'key ') + str;\n\n // Have / include\n str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n // Assertion\n this.assert(\n ok\n , 'expected #{this} to ' + str\n , 'expected #{this} to not ' + str\n , expected.slice(0).sort()\n , actual.sort()\n , true\n );\n }\n\n Assertion.addMethod('keys', assertKeys);\n Assertion.addMethod('key', assertKeys);\n\n /**\n * ### .throw(constructor)\n *\n * Asserts that the function target will throw a specific error, or specific type of error\n * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n * for the error's message.\n *\n * var err = new ReferenceError('This is a bad function.');\n * var fn = function () { throw err; }\n * expect(fn).to.throw(ReferenceError);\n * expect(fn).to.throw(Error);\n * expect(fn).to.throw(/bad function/);\n * expect(fn).to.not.throw('good function');\n * expect(fn).to.throw(ReferenceError, /bad function/);\n * expect(fn).to.throw(err);\n *\n * Please note that when a throw expectation is negated, it will check each\n * parameter independently, starting with error constructor type. The appropriate way\n * to check for the existence of a type of error but for a message that does not match\n * is to use `and`.\n *\n * expect(fn).to.throw(ReferenceError)\n * .and.not.throw(/good function/);\n *\n * @name throw\n * @alias throws\n * @alias Throw\n * @param {ErrorConstructor} constructor\n * @param {String|RegExp} expected error message\n * @param {String} message _optional_\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @returns error for chaining (null if no error)\n * @namespace BDD\n * @api public\n */\n\n function assertThrows (constructor, errMsg, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('function');\n\n var thrown = false\n , desiredError = null\n , name = null\n , thrownError = null;\n\n if (arguments.length === 0) {\n errMsg = null;\n constructor = null;\n } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n errMsg = constructor;\n constructor = null;\n } else if (constructor && constructor instanceof Error) {\n desiredError = constructor;\n constructor = null;\n errMsg = null;\n } else if (typeof constructor === 'function') {\n name = constructor.prototype.name;\n if (!name || (name === 'Error' && constructor !== Error)) {\n name = constructor.name || (new constructor()).name;\n }\n } else {\n constructor = null;\n }\n\n try {\n obj();\n } catch (err) {\n // first, check desired error\n if (desiredError) {\n this.assert(\n err === desiredError\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp}'\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (err instanceof Error ? err.toString() : err)\n );\n\n flag(this, 'object', err);\n return this;\n }\n\n // next, check constructor\n if (constructor) {\n this.assert(\n err instanceof constructor\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n , name\n , (err instanceof Error ? err.toString() : err)\n );\n\n if (!errMsg) {\n flag(this, 'object', err);\n return this;\n }\n }\n\n // next, check message\n var message = 'error' === _.type(err) && \"message\" in err\n ? err.message\n : '' + err;\n\n if ((message != null) && errMsg && errMsg instanceof RegExp) {\n this.assert(\n errMsg.exec(message)\n , 'expected #{this} to throw error matching #{exp} but got #{act}'\n , 'expected #{this} to throw error not matching #{exp}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n this.assert(\n ~message.indexOf(errMsg)\n , 'expected #{this} to throw error including #{exp} but got #{act}'\n , 'expected #{this} to throw error not including #{act}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else {\n thrown = true;\n thrownError = err;\n }\n }\n\n var actuallyGot = ''\n , expectedThrown = name !== null\n ? name\n : desiredError\n ? '#{exp}' //_.inspect(desiredError)\n : 'an error';\n\n if (thrown) {\n actuallyGot = ' but #{act} was thrown'\n }\n\n this.assert(\n thrown === true\n , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n );\n\n flag(this, 'object', thrownError);\n };\n\n Assertion.addMethod('throw', assertThrows);\n Assertion.addMethod('throws', assertThrows);\n Assertion.addMethod('Throw', assertThrows);\n\n /**\n * ### .respondTo(method)\n *\n * Asserts that the object or class target will respond to a method.\n *\n * Klass.prototype.bar = function(){};\n * expect(Klass).to.respondTo('bar');\n * expect(obj).to.respondTo('bar');\n *\n * To check if a constructor will respond to a static function,\n * set the `itself` flag.\n *\n * Klass.baz = function(){};\n * expect(Klass).itself.to.respondTo('baz');\n *\n * @name respondTo\n * @alias respondsTo\n * @param {String} method\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function respondTo (method, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , itself = flag(this, 'itself')\n , context = ('function' === _.type(obj) && !itself)\n ? obj.prototype[method]\n : obj[method];\n\n this.assert(\n 'function' === typeof context\n , 'expected #{this} to respond to ' + _.inspect(method)\n , 'expected #{this} to not respond to ' + _.inspect(method)\n );\n }\n\n Assertion.addMethod('respondTo', respondTo);\n Assertion.addMethod('respondsTo', respondTo);\n\n /**\n * ### .itself\n *\n * Sets the `itself` flag, later used by the `respondTo` assertion.\n *\n * function Foo() {}\n * Foo.bar = function() {}\n * Foo.prototype.baz = function() {}\n *\n * expect(Foo).itself.to.respondTo('bar');\n * expect(Foo).itself.not.to.respondTo('baz');\n *\n * @name itself\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('itself', function () {\n flag(this, 'itself', true);\n });\n\n /**\n * ### .satisfy(method)\n *\n * Asserts that the target passes a given truth test.\n *\n * expect(1).to.satisfy(function(num) { return num > 0; });\n *\n * @name satisfy\n * @alias satisfies\n * @param {Function} matcher\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function satisfy (matcher, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var result = matcher(obj);\n this.assert(\n result\n , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n , this.negate ? false : true\n , result\n );\n }\n\n Assertion.addMethod('satisfy', satisfy);\n Assertion.addMethod('satisfies', satisfy);\n\n /**\n * ### .closeTo(expected, delta)\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * expect(1.5).to.be.closeTo(1, 0.5);\n *\n * @name closeTo\n * @alias approximately\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function closeTo(expected, delta, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj, msg).is.a('number');\n if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n throw new Error('the arguments to closeTo or approximately must be numbers');\n }\n\n this.assert(\n Math.abs(obj - expected) <= delta\n , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n );\n }\n\n Assertion.addMethod('closeTo', closeTo);\n Assertion.addMethod('approximately', closeTo);\n\n function isSubsetOf(subset, superset, cmp) {\n return subset.every(function(elem) {\n if (!cmp) return superset.indexOf(elem) !== -1;\n\n return superset.some(function(elem2) {\n return cmp(elem, elem2);\n });\n })\n }\n\n /**\n * ### .members(set)\n *\n * Asserts that the target is a superset of `set`,\n * or that the target and `set` have the same strictly-equal (===) members.\n * Alternately, if the `deep` flag is set, set members are compared for deep\n * equality.\n *\n * expect([1, 2, 3]).to.include.members([3, 2]);\n * expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n *\n * expect([4, 2]).to.have.members([2, 4]);\n * expect([5, 2]).to.not.have.members([5, 2, 1]);\n *\n * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n *\n * @name members\n * @param {Array} set\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('members', function (subset, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj).to.be.an('array');\n new Assertion(subset).to.be.an('array');\n\n var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n if (flag(this, 'contains')) {\n return this.assert(\n isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to be a superset of #{act}'\n , 'expected #{this} to not be a superset of #{act}'\n , obj\n , subset\n );\n }\n\n this.assert(\n isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to have the same members as #{act}'\n , 'expected #{this} to not have the same members as #{act}'\n , obj\n , subset\n );\n });\n\n /**\n * ### .oneOf(list)\n *\n * Assert that a value appears somewhere in the top level of array `list`.\n *\n * expect('a').to.be.oneOf(['a', 'b', 'c']);\n * expect(9).to.not.be.oneOf(['z']);\n * expect([3]).to.not.be.oneOf([1, 2, [3]]);\n *\n * var three = [3];\n * // for object-types, contents are not compared\n * expect(three).to.not.be.oneOf([1, 2, [3]]);\n * // comparing references works\n * expect(three).to.be.oneOf([1, 2, three]);\n *\n * @name oneOf\n * @param {Array<*>} list\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function oneOf (list, msg) {\n if (msg) flag(this, 'message', msg);\n var expected = flag(this, 'object');\n new Assertion(list).to.be.an('array');\n\n this.assert(\n list.indexOf(expected) > -1\n , 'expected #{this} to be one of #{exp}'\n , 'expected #{this} to not be one of #{exp}'\n , list\n , expected\n );\n }\n\n Assertion.addMethod('oneOf', oneOf);\n\n\n /**\n * ### .change(function)\n *\n * Asserts that a function changes an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val += 3 };\n * var noChangeFn = function() { return 'foo' + 'bar'; }\n * expect(fn).to.change(obj, 'val');\n * expect(noChangeFn).to.not.change(obj, 'val')\n *\n * @name change\n * @alias changes\n * @alias Change\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertChanges (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n initial !== object[prop]\n , 'expected .' + prop + ' to change'\n , 'expected .' + prop + ' to not change'\n );\n }\n\n Assertion.addChainableMethod('change', assertChanges);\n Assertion.addChainableMethod('changes', assertChanges);\n\n /**\n * ### .increase(function)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * expect(fn).to.increase(obj, 'val');\n *\n * @name increase\n * @alias increases\n * @alias Increase\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertIncreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial > 0\n , 'expected .' + prop + ' to increase'\n , 'expected .' + prop + ' to not increase'\n );\n }\n\n Assertion.addChainableMethod('increase', assertIncreases);\n Assertion.addChainableMethod('increases', assertIncreases);\n\n /**\n * ### .decrease(function)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * expect(fn).to.decrease(obj, 'val');\n *\n * @name decrease\n * @alias decreases\n * @alias Decrease\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertDecreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial < 0\n , 'expected .' + prop + ' to decrease'\n , 'expected .' + prop + ' to not decrease'\n );\n }\n\n Assertion.addChainableMethod('decrease', assertDecreases);\n Assertion.addChainableMethod('decreases', assertDecreases);\n\n /**\n * ### .extensible\n *\n * Asserts that the target is extensible (can have new properties added to\n * it).\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect({}).to.be.extensible;\n * expect(nonExtensibleObject).to.not.be.extensible;\n * expect(sealedObject).to.not.be.extensible;\n * expect(frozenObject).to.not.be.extensible;\n *\n * @name extensible\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('extensible', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isExtensible;\n\n try {\n isExtensible = Object.isExtensible(obj);\n } catch (err) {\n if (err instanceof TypeError) isExtensible = false;\n else throw err;\n }\n\n this.assert(\n isExtensible\n , 'expected #{this} to be extensible'\n , 'expected #{this} to not be extensible'\n );\n });\n\n /**\n * ### .sealed\n *\n * Asserts that the target is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect(sealedObject).to.be.sealed;\n * expect(frozenObject).to.be.sealed;\n * expect({}).to.not.be.sealed;\n *\n * @name sealed\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('sealed', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isSealed;\n\n try {\n isSealed = Object.isSealed(obj);\n } catch (err) {\n if (err instanceof TypeError) isSealed = true;\n else throw err;\n }\n\n this.assert(\n isSealed\n , 'expected #{this} to be sealed'\n , 'expected #{this} to not be sealed'\n );\n });\n\n /**\n * ### .frozen\n *\n * Asserts that the target is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n *\n * expect(frozenObject).to.be.frozen;\n * expect({}).to.not.be.frozen;\n *\n * @name frozen\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('frozen', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isFrozen;\n\n try {\n isFrozen = Object.isFrozen(obj);\n } catch (err) {\n if (err instanceof TypeError) isFrozen = true;\n else throw err;\n }\n\n this.assert(\n isFrozen\n , 'expected #{this} to be frozen'\n , 'expected #{this} to not be frozen'\n );\n });\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n /*!\n * Chai dependencies.\n */\n\n var Assertion = chai.Assertion\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n /**\n * ### assert(expression, message)\n *\n * Write your own test expressions.\n *\n * assert('foo' !== 'bar', 'foo is not bar');\n * assert(Array.isArray([]), 'empty arrays are arrays');\n *\n * @param {Mixed} expression to test for truthiness\n * @param {String} message to display on error\n * @name assert\n * @namespace Assert\n * @api public\n */\n\n var assert = chai.assert = function (express, errmsg) {\n var test = new Assertion(null, null, chai.assert);\n test.assert(\n express\n , errmsg\n , '[ negation message unavailable ]'\n );\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure. Node.js `assert` module-compatible.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Assert\n * @api public\n */\n\n assert.fail = function (actual, expected, message, operator) {\n message = message || 'assert.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, assert.fail);\n };\n\n /**\n * ### .isOk(object, [message])\n *\n * Asserts that `object` is truthy.\n *\n * assert.isOk('everything', 'everything is ok');\n * assert.isOk(false, 'this will fail');\n *\n * @name isOk\n * @alias ok\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isOk = function (val, msg) {\n new Assertion(val, msg).is.ok;\n };\n\n /**\n * ### .isNotOk(object, [message])\n *\n * Asserts that `object` is falsy.\n *\n * assert.isNotOk('everything', 'this will fail');\n * assert.isNotOk(false, 'this will pass');\n *\n * @name isNotOk\n * @alias notOk\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotOk = function (val, msg) {\n new Assertion(val, msg).is.not.ok;\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * assert.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.equal = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.equal);\n\n test.assert(\n exp == flag(test, 'object')\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .notEqual(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * assert.notEqual(3, 4, 'these numbers are not equal');\n *\n * @name notEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notEqual = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.notEqual);\n\n test.assert(\n exp != flag(test, 'object')\n , 'expected #{this} to not equal #{exp}'\n , 'expected #{this} to equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .strictEqual(actual, expected, [message])\n *\n * Asserts strict equality (`===`) of `actual` and `expected`.\n *\n * assert.strictEqual(true, true, 'these booleans are strictly equal');\n *\n * @name strictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.strictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.equal(exp);\n };\n\n /**\n * ### .notStrictEqual(actual, expected, [message])\n *\n * Asserts strict inequality (`!==`) of `actual` and `expected`.\n *\n * assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n *\n * @name notStrictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notStrictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.equal(exp);\n };\n\n /**\n * ### .deepEqual(actual, expected, [message])\n *\n * Asserts that `actual` is deeply equal to `expected`.\n *\n * assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n *\n * @name deepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.eql(exp);\n };\n\n /**\n * ### .notDeepEqual(actual, expected, [message])\n *\n * Assert that `actual` is not deeply equal to `expected`.\n *\n * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n *\n * @name notDeepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.eql(exp);\n };\n\n /**\n * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n *\n * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n *\n * assert.isAbove(5, 2, '5 is strictly greater than 2');\n *\n * @name isAbove\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAbove\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAbove = function (val, abv, msg) {\n new Assertion(val, msg).to.be.above(abv);\n };\n\n /**\n * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n *\n * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n *\n * assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n * assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n *\n * @name isAtLeast\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtLeast\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtLeast = function (val, atlst, msg) {\n new Assertion(val, msg).to.be.least(atlst);\n };\n\n /**\n * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n *\n * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n *\n * assert.isBelow(3, 6, '3 is strictly less than 6');\n *\n * @name isBelow\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeBelow\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBelow = function (val, blw, msg) {\n new Assertion(val, msg).to.be.below(blw);\n };\n\n /**\n * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n *\n * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n *\n * assert.isAtMost(3, 6, '3 is less than or equal to 6');\n * assert.isAtMost(4, 4, '4 is less than or equal to 4');\n *\n * @name isAtMost\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtMost\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtMost = function (val, atmst, msg) {\n new Assertion(val, msg).to.be.most(atmst);\n };\n\n /**\n * ### .isTrue(value, [message])\n *\n * Asserts that `value` is true.\n *\n * var teaServed = true;\n * assert.isTrue(teaServed, 'the tea has been served');\n *\n * @name isTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isTrue = function (val, msg) {\n new Assertion(val, msg).is['true'];\n };\n\n /**\n * ### .isNotTrue(value, [message])\n *\n * Asserts that `value` is not true.\n *\n * var tea = 'tasty chai';\n * assert.isNotTrue(tea, 'great, time for tea!');\n *\n * @name isNotTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotTrue = function (val, msg) {\n new Assertion(val, msg).to.not.equal(true);\n };\n\n /**\n * ### .isFalse(value, [message])\n *\n * Asserts that `value` is false.\n *\n * var teaServed = false;\n * assert.isFalse(teaServed, 'no tea yet? hmm...');\n *\n * @name isFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFalse = function (val, msg) {\n new Assertion(val, msg).is['false'];\n };\n\n /**\n * ### .isNotFalse(value, [message])\n *\n * Asserts that `value` is not false.\n *\n * var tea = 'tasty chai';\n * assert.isNotFalse(tea, 'great, time for tea!');\n *\n * @name isNotFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFalse = function (val, msg) {\n new Assertion(val, msg).to.not.equal(false);\n };\n\n /**\n * ### .isNull(value, [message])\n *\n * Asserts that `value` is null.\n *\n * assert.isNull(err, 'there was no error');\n *\n * @name isNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNull = function (val, msg) {\n new Assertion(val, msg).to.equal(null);\n };\n\n /**\n * ### .isNotNull(value, [message])\n *\n * Asserts that `value` is not null.\n *\n * var tea = 'tasty chai';\n * assert.isNotNull(tea, 'great, time for tea!');\n *\n * @name isNotNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNull = function (val, msg) {\n new Assertion(val, msg).to.not.equal(null);\n };\n\n /**\n * ### .isNaN\n * Asserts that value is NaN\n *\n * assert.isNaN('foo', 'foo is NaN');\n *\n * @name isNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNaN = function (val, msg) {\n new Assertion(val, msg).to.be.NaN;\n };\n\n /**\n * ### .isNotNaN\n * Asserts that value is not NaN\n *\n * assert.isNotNaN(4, '4 is not NaN');\n *\n * @name isNotNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n assert.isNotNaN = function (val, msg) {\n new Assertion(val, msg).not.to.be.NaN;\n };\n\n /**\n * ### .isUndefined(value, [message])\n *\n * Asserts that `value` is `undefined`.\n *\n * var tea;\n * assert.isUndefined(tea, 'no tea defined');\n *\n * @name isUndefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isUndefined = function (val, msg) {\n new Assertion(val, msg).to.equal(undefined);\n };\n\n /**\n * ### .isDefined(value, [message])\n *\n * Asserts that `value` is not `undefined`.\n *\n * var tea = 'cup of chai';\n * assert.isDefined(tea, 'tea has been defined');\n *\n * @name isDefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isDefined = function (val, msg) {\n new Assertion(val, msg).to.not.equal(undefined);\n };\n\n /**\n * ### .isFunction(value, [message])\n *\n * Asserts that `value` is a function.\n *\n * function serveTea() { return 'cup of tea'; };\n * assert.isFunction(serveTea, 'great, we can have tea now');\n *\n * @name isFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFunction = function (val, msg) {\n new Assertion(val, msg).to.be.a('function');\n };\n\n /**\n * ### .isNotFunction(value, [message])\n *\n * Asserts that `value` is _not_ a function.\n *\n * var serveTea = [ 'heat', 'pour', 'sip' ];\n * assert.isNotFunction(serveTea, 'great, we have listed the steps');\n *\n * @name isNotFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFunction = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('function');\n };\n\n /**\n * ### .isObject(value, [message])\n *\n * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n * _The assertion does not match subclassed objects._\n *\n * var selection = { name: 'Chai', serve: 'with spices' };\n * assert.isObject(selection, 'tea selection is an object');\n *\n * @name isObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isObject = function (val, msg) {\n new Assertion(val, msg).to.be.a('object');\n };\n\n /**\n * ### .isNotObject(value, [message])\n *\n * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n *\n * var selection = 'chai'\n * assert.isNotObject(selection, 'tea selection is not an object');\n * assert.isNotObject(null, 'null is not an object');\n *\n * @name isNotObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotObject = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('object');\n };\n\n /**\n * ### .isArray(value, [message])\n *\n * Asserts that `value` is an array.\n *\n * var menu = [ 'green', 'chai', 'oolong' ];\n * assert.isArray(menu, 'what kind of tea do we want?');\n *\n * @name isArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isArray = function (val, msg) {\n new Assertion(val, msg).to.be.an('array');\n };\n\n /**\n * ### .isNotArray(value, [message])\n *\n * Asserts that `value` is _not_ an array.\n *\n * var menu = 'green|chai|oolong';\n * assert.isNotArray(menu, 'what kind of tea do we want?');\n *\n * @name isNotArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotArray = function (val, msg) {\n new Assertion(val, msg).to.not.be.an('array');\n };\n\n /**\n * ### .isString(value, [message])\n *\n * Asserts that `value` is a string.\n *\n * var teaOrder = 'chai';\n * assert.isString(teaOrder, 'order placed');\n *\n * @name isString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isString = function (val, msg) {\n new Assertion(val, msg).to.be.a('string');\n };\n\n /**\n * ### .isNotString(value, [message])\n *\n * Asserts that `value` is _not_ a string.\n *\n * var teaOrder = 4;\n * assert.isNotString(teaOrder, 'order placed');\n *\n * @name isNotString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotString = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('string');\n };\n\n /**\n * ### .isNumber(value, [message])\n *\n * Asserts that `value` is a number.\n *\n * var cups = 2;\n * assert.isNumber(cups, 'how many cups');\n *\n * @name isNumber\n * @param {Number} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNumber = function (val, msg) {\n new Assertion(val, msg).to.be.a('number');\n };\n\n /**\n * ### .isNotNumber(value, [message])\n *\n * Asserts that `value` is _not_ a number.\n *\n * var cups = '2 cups please';\n * assert.isNotNumber(cups, 'how many cups');\n *\n * @name isNotNumber\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNumber = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('number');\n };\n\n /**\n * ### .isBoolean(value, [message])\n *\n * Asserts that `value` is a boolean.\n *\n * var teaReady = true\n * , teaServed = false;\n *\n * assert.isBoolean(teaReady, 'is the tea ready');\n * assert.isBoolean(teaServed, 'has tea been served');\n *\n * @name isBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBoolean = function (val, msg) {\n new Assertion(val, msg).to.be.a('boolean');\n };\n\n /**\n * ### .isNotBoolean(value, [message])\n *\n * Asserts that `value` is _not_ a boolean.\n *\n * var teaReady = 'yep'\n * , teaServed = 'nope';\n *\n * assert.isNotBoolean(teaReady, 'is the tea ready');\n * assert.isNotBoolean(teaServed, 'has tea been served');\n *\n * @name isNotBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotBoolean = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('boolean');\n };\n\n /**\n * ### .typeOf(value, name, [message])\n *\n * Asserts that `value`'s type is `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n * assert.typeOf('tea', 'string', 'we have a string');\n * assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n * assert.typeOf(null, 'null', 'we have a null');\n * assert.typeOf(undefined, 'undefined', 'we have an undefined');\n *\n * @name typeOf\n * @param {Mixed} value\n * @param {String} name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.typeOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.a(type);\n };\n\n /**\n * ### .notTypeOf(value, name, [message])\n *\n * Asserts that `value`'s type is _not_ `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.notTypeOf('tea', 'number', 'strings are not numbers');\n *\n * @name notTypeOf\n * @param {Mixed} value\n * @param {String} typeof name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notTypeOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.a(type);\n };\n\n /**\n * ### .instanceOf(object, constructor, [message])\n *\n * Asserts that `value` is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new Tea('chai');\n *\n * assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n *\n * @name instanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.instanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.instanceOf(type);\n };\n\n /**\n * ### .notInstanceOf(object, constructor, [message])\n *\n * Asserts `value` is not an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new String('chai');\n *\n * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n *\n * @name notInstanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInstanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.instanceOf(type);\n };\n\n /**\n * ### .include(haystack, needle, [message])\n *\n * Asserts that `haystack` includes `needle`. Works\n * for strings and arrays.\n *\n * assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n * assert.include([ 1, 2, 3 ], 3, 'array contains value');\n *\n * @name include\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.include = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.include).include(inc);\n };\n\n /**\n * ### .notInclude(haystack, needle, [message])\n *\n * Asserts that `haystack` does not include `needle`. Works\n * for strings and arrays.\n *\n * assert.notInclude('foobar', 'baz', 'string not include substring');\n * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n *\n * @name notInclude\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInclude = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.notInclude).not.include(inc);\n };\n\n /**\n * ### .match(value, regexp, [message])\n *\n * Asserts that `value` matches the regular expression `regexp`.\n *\n * assert.match('foobar', /^foo/, 'regexp matches');\n *\n * @name match\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.match = function (exp, re, msg) {\n new Assertion(exp, msg).to.match(re);\n };\n\n /**\n * ### .notMatch(value, regexp, [message])\n *\n * Asserts that `value` does not match the regular expression `regexp`.\n *\n * assert.notMatch('foobar', /^foo/, 'regexp does not match');\n *\n * @name notMatch\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notMatch = function (exp, re, msg) {\n new Assertion(exp, msg).to.not.match(re);\n };\n\n /**\n * ### .property(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`.\n *\n * assert.property({ tea: { green: 'matcha' }}, 'tea');\n *\n * @name property\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.property = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.property(prop);\n };\n\n /**\n * ### .notProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`.\n *\n * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n *\n * @name notProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.property(prop);\n };\n\n /**\n * ### .deepProperty(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`, which can be a\n * string using dot- and bracket-notation for deep reference.\n *\n * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n *\n * @name deepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop);\n };\n\n /**\n * ### .notDeepProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`, which\n * can be a string using dot- and bracket-notation for deep reference.\n *\n * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n *\n * @name notDeepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop);\n };\n\n /**\n * ### .propertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`.\n *\n * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n *\n * @name propertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.property(prop, val);\n };\n\n /**\n * ### .propertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`.\n *\n * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n *\n * @name propertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.property(prop, val);\n };\n\n /**\n * ### .deepPropertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`. `property` can use dot- and bracket-notation for deep\n * reference.\n *\n * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n *\n * @name deepPropertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop, val);\n };\n\n /**\n * ### .deepPropertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`. `property` can use dot- and\n * bracket-notation for deep reference.\n *\n * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n *\n * @name deepPropertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n };\n\n /**\n * ### .lengthOf(object, length, [message])\n *\n * Asserts that `object` has a `length` property with the expected value.\n *\n * assert.lengthOf([1,2,3], 3, 'array has length of 3');\n * assert.lengthOf('foobar', 6, 'string has length of 6');\n *\n * @name lengthOf\n * @param {Mixed} object\n * @param {Number} length\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.lengthOf = function (exp, len, msg) {\n new Assertion(exp, msg).to.have.length(len);\n };\n\n /**\n * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * assert.throws(fn, 'function throws a reference error');\n * assert.throws(fn, /function throws a reference error/);\n * assert.throws(fn, ReferenceError);\n * assert.throws(fn, ReferenceError, 'function throws a reference error');\n * assert.throws(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throws\n * @alias throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.throws = function (fn, errt, errs, msg) {\n if ('string' === typeof errt || errt instanceof RegExp) {\n errs = errt;\n errt = null;\n }\n\n var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n return flag(assertErr, 'object');\n };\n\n /**\n * ### .doesNotThrow(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * assert.doesNotThrow(fn, Error, 'function does not throw');\n *\n * @name doesNotThrow\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotThrow = function (fn, type, msg) {\n if ('string' === typeof type) {\n msg = type;\n type = null;\n }\n\n new Assertion(fn, msg).to.not.Throw(type);\n };\n\n /**\n * ### .operator(val1, operator, val2, [message])\n *\n * Compares two values using `operator`.\n *\n * assert.operator(1, '<', 2, 'everything is ok');\n * assert.operator(1, '>', 2, 'this will fail');\n *\n * @name operator\n * @param {Mixed} val1\n * @param {String} operator\n * @param {Mixed} val2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.operator = function (val, operator, val2, msg) {\n var ok;\n switch(operator) {\n case '==':\n ok = val == val2;\n break;\n case '===':\n ok = val === val2;\n break;\n case '>':\n ok = val > val2;\n break;\n case '>=':\n ok = val >= val2;\n break;\n case '<':\n ok = val < val2;\n break;\n case '<=':\n ok = val <= val2;\n break;\n case '!=':\n ok = val != val2;\n break;\n case '!==':\n ok = val !== val2;\n break;\n default:\n throw new Error('Invalid operator \"' + operator + '\"');\n }\n var test = new Assertion(ok, msg);\n test.assert(\n true === flag(test, 'object')\n , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n };\n\n /**\n * ### .closeTo(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n *\n * @name closeTo\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.closeTo = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.closeTo(exp, delta);\n };\n\n /**\n * ### .approximately(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.approximately(1.5, 1, 0.5, 'numbers are close');\n *\n * @name approximately\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.approximately = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.approximately(exp, delta);\n };\n\n /**\n * ### .sameMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members.\n * Order is not taken into account.\n *\n * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n *\n * @name sameMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.members(set2);\n }\n\n /**\n * ### .sameDeepMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n * Order is not taken into account.\n *\n * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n *\n * @name sameDeepMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameDeepMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.deep.members(set2);\n }\n\n /**\n * ### .includeMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset`.\n * Order is not taken into account.\n *\n * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n *\n * @name includeMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.members(subset);\n }\n\n /**\n * ### .includeDeepMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset` - using deep equality checking.\n * Order is not taken into account.\n * Duplicates are ignored.\n *\n * assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n *\n * @name includeDeepMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeDeepMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.deep.members(subset);\n }\n\n /**\n * ### .oneOf(inList, list, [message])\n *\n * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n *\n * assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n *\n * @name oneOf\n * @param {*} inList\n * @param {Array<*>} list\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.oneOf = function (inList, list, msg) {\n new Assertion(inList, msg).to.be.oneOf(list);\n }\n\n /**\n * ### .changes(function, object, property)\n *\n * Asserts that a function changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 22 };\n * assert.changes(fn, obj, 'val');\n *\n * @name changes\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.changes = function (fn, obj, prop) {\n new Assertion(fn).to.change(obj, prop);\n }\n\n /**\n * ### .doesNotChange(function, object, property)\n *\n * Asserts that a function does not changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { console.log('foo'); };\n * assert.doesNotChange(fn, obj, 'val');\n *\n * @name doesNotChange\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotChange = function (fn, obj, prop) {\n new Assertion(fn).to.not.change(obj, prop);\n }\n\n /**\n * ### .increases(function, object, property)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 13 };\n * assert.increases(fn, obj, 'val');\n *\n * @name increases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.increases = function (fn, obj, prop) {\n new Assertion(fn).to.increase(obj, prop);\n }\n\n /**\n * ### .doesNotIncrease(function, object, property)\n *\n * Asserts that a function does not increase object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 8 };\n * assert.doesNotIncrease(fn, obj, 'val');\n *\n * @name doesNotIncrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotIncrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.increase(obj, prop);\n }\n\n /**\n * ### .decreases(function, object, property)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * assert.decreases(fn, obj, 'val');\n *\n * @name decreases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.decreases = function (fn, obj, prop) {\n new Assertion(fn).to.decrease(obj, prop);\n }\n\n /**\n * ### .doesNotDecrease(function, object, property)\n *\n * Asserts that a function does not decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * assert.doesNotDecrease(fn, obj, 'val');\n *\n * @name doesNotDecrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotDecrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.decrease(obj, prop);\n }\n\n /*!\n * ### .ifError(object)\n *\n * Asserts if value is not a false value, and throws if it is a true value.\n * This is added to allow for chai to be a drop-in replacement for Node's\n * assert class.\n *\n * var err = new Error('I am a custom error');\n * assert.ifError(err); // Rethrows err!\n *\n * @name ifError\n * @param {Object} object\n * @namespace Assert\n * @api public\n */\n\n assert.ifError = function (val) {\n if (val) {\n throw(val);\n }\n };\n\n /**\n * ### .isExtensible(object)\n *\n * Asserts that `object` is extensible (can have new properties added to it).\n *\n * assert.isExtensible({});\n *\n * @name isExtensible\n * @alias extensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.be.extensible;\n };\n\n /**\n * ### .isNotExtensible(object)\n *\n * Asserts that `object` is _not_ extensible.\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freese({});\n *\n * assert.isNotExtensible(nonExtensibleObject);\n * assert.isNotExtensible(sealedObject);\n * assert.isNotExtensible(frozenObject);\n *\n * @name isNotExtensible\n * @alias notExtensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.extensible;\n };\n\n /**\n * ### .isSealed(object)\n *\n * Asserts that `object` is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.seal({});\n *\n * assert.isSealed(sealedObject);\n * assert.isSealed(frozenObject);\n *\n * @name isSealed\n * @alias sealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isSealed = function (obj, msg) {\n new Assertion(obj, msg).to.be.sealed;\n };\n\n /**\n * ### .isNotSealed(object)\n *\n * Asserts that `object` is _not_ sealed.\n *\n * assert.isNotSealed({});\n *\n * @name isNotSealed\n * @alias notSealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotSealed = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.sealed;\n };\n\n /**\n * ### .isFrozen(object)\n *\n * Asserts that `object` is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n * assert.frozen(frozenObject);\n *\n * @name isFrozen\n * @alias frozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.be.frozen;\n };\n\n /**\n * ### .isNotFrozen(object)\n *\n * Asserts that `object` is _not_ frozen.\n *\n * assert.isNotFrozen({});\n *\n * @name isNotFrozen\n * @alias notFrozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.frozen;\n };\n\n /*!\n * Aliases.\n */\n\n (function alias(name, as){\n assert[as] = assert[name];\n return alias;\n })\n ('isOk', 'ok')\n ('isNotOk', 'notOk')\n ('throws', 'throw')\n ('throws', 'Throw')\n ('isExtensible', 'extensible')\n ('isNotExtensible', 'notExtensible')\n ('isSealed', 'sealed')\n ('isNotSealed', 'notSealed')\n ('isFrozen', 'frozen')\n ('isNotFrozen', 'notFrozen');\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n chai.expect = function (val, message) {\n return new chai.Assertion(val, message);\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Expect\n * @api public\n */\n\n chai.expect.fail = function (actual, expected, message, operator) {\n message = message || 'expect.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, chai.expect.fail);\n };\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n var Assertion = chai.Assertion;\n\n function loadShould () {\n // explicitly define this method as function as to have it's name to include as `ssfi`\n function shouldGetter() {\n if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n return new Assertion(this.valueOf(), null, shouldGetter);\n }\n return new Assertion(this, null, shouldGetter);\n }\n function shouldSetter(value) {\n // See https://github.com/chaijs/chai/issues/86: this makes\n // `whatever.should = someValue` actually set `someValue`, which is\n // especially useful for `global.should = require('chai').should()`.\n //\n // Note that we have to use [[DefineProperty]] instead of [[Put]]\n // since otherwise we would trigger this very setter!\n Object.defineProperty(this, 'should', {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n }\n // modify Object.prototype to have `should`\n Object.defineProperty(Object.prototype, 'should', {\n set: shouldSetter\n , get: shouldGetter\n , configurable: true\n });\n\n var should = {};\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Should\n * @api public\n */\n\n should.fail = function (actual, expected, message, operator) {\n message = message || 'should.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, should.fail);\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * should.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * should.throw(fn, 'function throws a reference error');\n * should.throw(fn, /function throws a reference error/);\n * should.throw(fn, ReferenceError);\n * should.throw(fn, ReferenceError, 'function throws a reference error');\n * should.throw(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.Throw(errt, errs);\n };\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi';\n *\n * should.exist(foo, 'foo exists');\n *\n * @name exist\n * @namespace Should\n * @api public\n */\n\n should.exist = function (val, msg) {\n new Assertion(val, msg).to.exist;\n }\n\n // negation\n should.not = {}\n\n /**\n * ### .not.equal(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * should.not.equal(3, 4, 'these numbers are not equal');\n *\n * @name not.equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.not.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.not.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * should.not.throw(fn, Error, 'function does not throw');\n *\n * @name not.throw\n * @alias not.Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.not.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.not.Throw(errt, errs);\n };\n\n /**\n * ### .not.exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var bar = null;\n *\n * should.not.exist(bar, 'bar does not exist');\n *\n * @name not.exist\n * @namespace Should\n * @api public\n */\n\n should.not.exist = function (val, msg) {\n new Assertion(val, msg).to.not.exist;\n }\n\n should['throw'] = should['Throw'];\n should.not['throw'] = should.not['Throw'];\n\n return should;\n };\n\n chai.should = loadShould;\n chai.Should = loadShould;\n};\n","/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call = Function.prototype.call,\n apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n * expect(fooStr).to.be.foo('bar');\n * expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n if (typeof chainingBehavior !== 'function') {\n chainingBehavior = function () { };\n }\n\n var chainableBehavior = {\n method: method\n , chainingBehavior: chainingBehavior\n };\n\n // save the methods so we can overwrite them later, if we need to.\n if (!ctx.__methods) {\n ctx.__methods = {};\n }\n ctx.__methods[name] = chainableBehavior;\n\n Object.defineProperty(ctx, name,\n { get: function () {\n chainableBehavior.chainingBehavior.call(this);\n\n var assert = function assert() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', assert);\n var result = chainableBehavior.method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n\n // Use `__proto__` if available\n if (hasProtoSupport) {\n // Inherit all properties from the object by replacing the `Function` prototype\n var prototype = assert.__proto__ = Object.create(this);\n // Restore the `call` and `apply` methods from `Function`\n prototype.call = call;\n prototype.apply = apply;\n }\n // Otherwise, redefine all properties (slow!)\n else {\n var asserterNames = Object.getOwnPropertyNames(ctx);\n asserterNames.forEach(function (asserterName) {\n if (!excludeNames.test(asserterName)) {\n var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n Object.defineProperty(assert, asserterName, pd);\n }\n });\n }\n\n transferFlags(this, assert);\n return assert;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n ctx[name] = function () {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', ctx[name]);\n var result = method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n * utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.instanceof(Foo);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n Object.defineProperty(ctx, name,\n { get: function addProperty() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', addProperty);\n\n var result = getter.call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n * utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n var obj = flag(obj, 'object');\n types = types.map(function (t) { return t.toLowerCase(); });\n types.sort();\n\n // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n var str = types.map(function (t, index) {\n var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n return or + art + ' ' + t;\n }).join(', ');\n\n if (!types.some(function (expected) { return type(obj) === expected; })) {\n throw new AssertionError(\n 'object tested must be ' + str + ', but ' + type(obj) + ' given'\n );\n }\n};\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n * utils.flag(this, 'foo', 'bar'); // setter\n * utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n var flags = obj.__flags || (obj.__flags = Object.create(null));\n if (arguments.length === 3) {\n flags[key] = value;\n } else {\n return flags[key];\n }\n};\n","/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n return args.length > 4 ? args[4] : obj._obj;\n};\n","/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n var result = [];\n for (var name in object) {\n result.push(name);\n }\n return result;\n};\n","/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n , getActual = require('./getActual')\n , inspect = require('./inspect')\n , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , val = flag(obj, 'object')\n , expected = args[3]\n , actual = getActual(obj, args)\n , msg = negate ? args[2] : args[1]\n , flagMsg = flag(obj, 'message');\n\n if(typeof msg === \"function\") msg = msg();\n msg = msg || '';\n msg = msg\n .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n","/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n if (func.name) return func.name;\n\n var match = /^\\s?function ([^(]*)\\(/.exec(func);\n return match && match[1] ? match[1] : \"\";\n};\n","/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n var parsed = parsePath(path),\n last = parsed[parsed.length - 1];\n\n var info = {\n parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n name: last.p || last.i,\n value: _getPathValue(parsed, obj)\n };\n info.exists = hasProperty(info.name, info.parent);\n\n return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n * var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n return parts.map(function (value) {\n var re = /^\\[(\\d+)\\]$/\n , mArr = re.exec(value);\n if (mArr) return { i: parseFloat(mArr[1]) };\n else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n * var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n var tmp = obj\n , res;\n\n index = (index === undefined ? parsed.length : index);\n\n for (var i = 0, l = index; i < l; i++) {\n var part = parsed[i];\n if (tmp) {\n if ('undefined' !== typeof part.p)\n tmp = tmp[part.p];\n else if ('undefined' !== typeof part.i)\n tmp = tmp[part.i];\n if (i == (l - 1)) res = tmp;\n } else {\n res = undefined;\n }\n }\n return res;\n}\n","/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer \n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n * var obj = {\n * prop1: {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n * , prop2: {\n * arr: [ { nested: 'Universe' } ]\n * , str: 'Hello again!'\n * }\n * }\n *\n * The following would be the results.\n *\n * getPathValue('prop1.str', obj); // Hello\n * getPathValue('prop1.att[2]', obj); // b\n * getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n var info = getPathInfo(path, obj);\n return info.value;\n};\n","/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n var result = Object.getOwnPropertyNames(object);\n\n function addProperty(property) {\n if (result.indexOf(property) === -1) {\n result.push(property);\n }\n }\n\n var proto = Object.getPrototypeOf(object);\n while (proto !== null) {\n Object.getOwnPropertyNames(proto).forEach(addProperty);\n proto = Object.getPrototypeOf(proto);\n }\n\n return result;\n};\n","/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n * var obj = {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n *\n * The following would be the results.\n *\n * hasProperty('str', obj); // true\n * hasProperty('constructor', obj); // true\n * hasProperty('bar', obj); // false\n *\n * hasProperty('length', obj.str); // true\n * hasProperty(1, obj.str); // true\n * hasProperty(5, obj.str); // false\n *\n * hasProperty('length', obj.arr); // true\n * hasProperty(2, obj.arr); // true\n * hasProperty(3, obj.arr); // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n 'number': Number\n , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n var ot = type(obj);\n\n // Bad Object, obviously no props at all\n if(ot === 'null' || ot === 'undefined')\n return false;\n\n // The `in` operator does not work with certain literals\n // box these before the check\n if(literals[ot] && typeof obj !== 'object')\n obj = new literals[ot](obj);\n\n return name in obj;\n};\n","/*!\n * chai\n * Copyright(c) 2011 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n","// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n * properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n * output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n var ctx = {\n showHidden: showHidden,\n seen: [],\n stylize: function (str) { return str; }\n };\n return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n if (typeof HTMLElement === 'object') {\n return object instanceof HTMLElement;\n } else {\n return object &&\n typeof object === 'object' &&\n object.nodeType === 1 &&\n typeof object.nodeName === 'string';\n }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (value && typeof value.inspect === 'function' &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes);\n if (typeof ret !== 'string') {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // If this is a DOM element, try to get the outer HTML.\n if (isDOMElement(value)) {\n if ('outerHTML' in value) {\n return value.outerHTML;\n // This value does not have an outerHTML attribute,\n // it could still be an XML element\n } else {\n // Attempt to serialize it\n try {\n if (document.xmlVersion) {\n var xmlSerializer = new XMLSerializer();\n return xmlSerializer.serializeToString(value);\n } else {\n // Firefox 11- do not support outerHTML\n // It does, however, support innerHTML\n // Use the following to render the element\n var ns = \"http://www.w3.org/1999/xhtml\";\n var container = document.createElementNS(ns, '_');\n\n container.appendChild(value.cloneNode(false));\n html = container.innerHTML\n .replace('><', '>' + value.innerHTML + '<');\n container.innerHTML = '';\n return html;\n }\n } catch (err) {\n // This could be a non-native DOM implementation,\n // continue with the normal flow:\n // printing the element as if it is an object.\n }\n }\n }\n\n // Look up the keys of the object.\n var visibleKeys = getEnumerableProperties(value);\n var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n // Some type of object without properties can be shortcutted.\n // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n // a `stack` plus `description` property; ignore those for consistency.\n if (keys.length === 0 || (isError(value) && (\n (keys.length === 1 && keys[0] === 'stack') ||\n (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n ))) {\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n base = ' [Function' + nameSuffix + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n return formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n switch (typeof value) {\n case 'undefined':\n return ctx.stylize('undefined', 'undefined');\n\n case 'string':\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n\n case 'number':\n if (value === 0 && (1/value) === -Infinity) {\n return ctx.stylize('-0', 'number');\n }\n return ctx.stylize('' + value, 'number');\n\n case 'boolean':\n return ctx.stylize('' + value, 'boolean');\n }\n // For some reason typeof null is \"object\", so special case here.\n if (value === null) {\n return ctx.stylize('null', 'null');\n }\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str;\n if (value.__lookupGetter__) {\n if (value.__lookupGetter__(key)) {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n }\n if (visibleKeys.indexOf(key) < 0) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(value[key]) < 0) {\n if (recurseTimes === null) {\n str = formatValue(ctx, value[key], null);\n } else {\n str = formatValue(ctx, value[key], recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (typeof name === 'undefined') {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n return Array.isArray(ar) ||\n (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n var str = inspect(obj)\n , type = Object.prototype.toString.call(obj);\n\n if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n if (type === '[object Function]') {\n return !obj.name || obj.name === ''\n ? '[Function]'\n : '[Function: ' + obj.name + ']';\n } else if (type === '[object Array]') {\n return '[ Array(' + obj.length + ') ]';\n } else if (type === '[object Object]') {\n var keys = Object.keys(obj)\n , kstr = keys.length > 2\n ? keys.splice(0, 2).join(', ') + ', ...'\n : keys.join(', ');\n return '{ Object (' + kstr + ') }';\n } else {\n return str;\n }\n } else {\n return str;\n }\n};\n","/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property. Must return functions to be used for\n * name.\n *\n * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n * function (_super) {\n * }\n * , function (_super) {\n * }\n * );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.have.length(3);\n * expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n var chainableBehavior = ctx.__methods[name];\n\n var _chainingBehavior = chainableBehavior.chainingBehavior;\n chainableBehavior.chainingBehavior = function () {\n var result = chainingBehavior(_chainingBehavior).call(this);\n return result === undefined ? this : result;\n };\n\n var _method = chainableBehavior.method;\n chainableBehavior.method = function () {\n var result = method(_method).apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n * return function (str) {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.value).to.equal(str);\n * } else {\n * _super.apply(this, arguments);\n * }\n * }\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n var _method = ctx[name]\n , _super = function () { return this; };\n\n if (_method && 'function' === typeof _method)\n _super = _method;\n\n ctx[name] = function () {\n var result = method(_super).apply(this, arguments);\n return result === undefined ? this : result;\n }\n};\n","/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n * return function () {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.name).to.equal('bar');\n * } else {\n * _super.call(this);\n * }\n * }\n * });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n var _get = Object.getOwnPropertyDescriptor(ctx, name)\n , _super = function () {};\n\n if (_get && 'function' === typeof _get.get)\n _super = _get.get\n\n Object.defineProperty(ctx, name,\n { get: function () {\n var result = getter(_super).call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , expr = args[0];\n return negate ? !expr : expr;\n};\n","/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n * var newAssertion = new Assertion();\n * utils.transferFlags(assertion, newAssertion);\n *\n * var anotherAsseriton = new Assertion(myObj);\n * utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n if (!object.__flags) {\n object.__flags = Object.create(null);\n }\n\n includeAll = arguments.length === 3 ? includeAll : true;\n\n for (var flag in flags) {\n if (includeAll ||\n (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n object.__flags[flag] = flags[flag];\n }\n }\n};\n","module.exports = require('./lib/eql');\n","/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n Buffer = {};\n Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n if (sameValue(a, b)) {\n return true;\n } else if ('date' === type(a)) {\n return dateEqual(a, b);\n } else if ('regexp' === type(a)) {\n return regexpEqual(a, b);\n } else if (Buffer.isBuffer(a)) {\n return bufferEqual(a, b);\n } else if ('arguments' === type(a)) {\n return argumentsEqual(a, b, m);\n } else if (!typeEqual(a, b)) {\n return false;\n } else if (('object' !== type(a) && 'object' !== type(b))\n && ('array' !== type(a) && 'array' !== type(b))) {\n return sameValue(a, b);\n } else {\n return objectEqual(a, b, m);\n }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n if (a === b) return a !== 0 || 1 / a === 1 / b;\n return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n if ('date' !== type(b)) return false;\n return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n if ('regexp' !== type(b)) return false;\n return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n if ('arguments' !== type(b)) return false;\n a = [].slice.call(a);\n b = [].slice.call(b);\n return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n var res = [];\n for (var key in a) res.push(key);\n return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n if (a.length !== b.length) return false;\n\n var i = 0;\n var match = true;\n\n for (; i < a.length; i++) {\n if (a[i] !== b[i]) {\n match = false;\n break;\n }\n }\n\n return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n if (!Buffer.isBuffer(b)) return false;\n return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n if (!isValue(a) || !isValue(b)) {\n return false;\n }\n\n if (a.prototype !== b.prototype) {\n return false;\n }\n\n var i;\n if (m) {\n for (i = 0; i < m.length; i++) {\n if ((m[i][0] === a && m[i][1] === b)\n || (m[i][0] === b && m[i][1] === a)) {\n return true;\n }\n }\n } else {\n m = [];\n }\n\n try {\n var ka = enumerable(a);\n var kb = enumerable(b);\n } catch (ex) {\n return false;\n }\n\n ka.sort();\n kb.sort();\n\n if (!iterableEqual(ka, kb)) {\n return false;\n }\n\n m.push([ a, b ]);\n\n var key;\n for (i = ka.length - 1; i >= 0; i--) {\n key = ka[i];\n if (!deepEqual(a[key], b[key], m)) {\n return false;\n }\n }\n\n return true;\n}\n","module.exports = require('./lib/type');\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n '[object Array]': 'array'\n , '[object RegExp]': 'regexp'\n , '[object Function]': 'function'\n , '[object Arguments]': 'arguments'\n , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n var str = Object.prototype.toString.call(obj);\n if (natives[str]) return natives[str];\n if (obj === null) return 'null';\n if (obj === undefined) return 'undefined';\n if (obj === Object(obj)) return 'object';\n return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","/*!\n localForage -- Offline Storage, Improved\n Version 1.5.0\n https://localforage.github.io/localForage\n (c) 2013-2017 Mozilla, Apache License 2.0\n*/\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.localforage = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw (f.code=\"MODULE_NOT_FOUND\", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o element; its readystatechange event will be fired asynchronously once it is inserted\n // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.\n var scriptEl = global.document.createElement('script');\n scriptEl.onreadystatechange = function () {\n nextTick();\n\n scriptEl.onreadystatechange = null;\n scriptEl.parentNode.removeChild(scriptEl);\n scriptEl = null;\n };\n global.document.documentElement.appendChild(scriptEl);\n };\n } else {\n scheduleDrain = function () {\n setTimeout(nextTick, 0);\n };\n }\n}\n\nvar draining;\nvar queue = [];\n//named nextTick for less confusing stack traces\nfunction nextTick() {\n draining = true;\n var i, oldQueue;\n var len = queue.length;\n while (len) {\n oldQueue = queue;\n queue = [];\n i = -1;\n while (++i < len) {\n oldQueue[i]();\n }\n len = queue.length;\n }\n draining = false;\n}\n\nmodule.exports = immediate;\nfunction immediate(task) {\n if (queue.push(task) === 1 && !draining) {\n scheduleDrain();\n }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],2:[function(_dereq_,module,exports){\n'use strict';\nvar immediate = _dereq_(1);\n\n/* istanbul ignore next */\nfunction INTERNAL() {}\n\nvar handlers = {};\n\nvar REJECTED = ['REJECTED'];\nvar FULFILLED = ['FULFILLED'];\nvar PENDING = ['PENDING'];\n\nmodule.exports = exports = Promise;\n\nfunction Promise(resolver) {\n if (typeof resolver !== 'function') {\n throw new TypeError('resolver must be a function');\n }\n this.state = PENDING;\n this.queue = [];\n this.outcome = void 0;\n if (resolver !== INTERNAL) {\n safelyResolveThenable(this, resolver);\n }\n}\n\nPromise.prototype[\"catch\"] = function (onRejected) {\n return this.then(null, onRejected);\n};\nPromise.prototype.then = function (onFulfilled, onRejected) {\n if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||\n typeof onRejected !== 'function' && this.state === REJECTED) {\n return this;\n }\n var promise = new this.constructor(INTERNAL);\n if (this.state !== PENDING) {\n var resolver = this.state === FULFILLED ? onFulfilled : onRejected;\n unwrap(promise, resolver, this.outcome);\n } else {\n this.queue.push(new QueueItem(promise, onFulfilled, onRejected));\n }\n\n return promise;\n};\nfunction QueueItem(promise, onFulfilled, onRejected) {\n this.promise = promise;\n if (typeof onFulfilled === 'function') {\n this.onFulfilled = onFulfilled;\n this.callFulfilled = this.otherCallFulfilled;\n }\n if (typeof onRejected === 'function') {\n this.onRejected = onRejected;\n this.callRejected = this.otherCallRejected;\n }\n}\nQueueItem.prototype.callFulfilled = function (value) {\n handlers.resolve(this.promise, value);\n};\nQueueItem.prototype.otherCallFulfilled = function (value) {\n unwrap(this.promise, this.onFulfilled, value);\n};\nQueueItem.prototype.callRejected = function (value) {\n handlers.reject(this.promise, value);\n};\nQueueItem.prototype.otherCallRejected = function (value) {\n unwrap(this.promise, this.onRejected, value);\n};\n\nfunction unwrap(promise, func, value) {\n immediate(function () {\n var returnValue;\n try {\n returnValue = func(value);\n } catch (e) {\n return handlers.reject(promise, e);\n }\n if (returnValue === promise) {\n handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));\n } else {\n handlers.resolve(promise, returnValue);\n }\n });\n}\n\nhandlers.resolve = function (self, value) {\n var result = tryCatch(getThen, value);\n if (result.status === 'error') {\n return handlers.reject(self, result.value);\n }\n var thenable = result.value;\n\n if (thenable) {\n safelyResolveThenable(self, thenable);\n } else {\n self.state = FULFILLED;\n self.outcome = value;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callFulfilled(value);\n }\n }\n return self;\n};\nhandlers.reject = function (self, error) {\n self.state = REJECTED;\n self.outcome = error;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callRejected(error);\n }\n return self;\n};\n\nfunction getThen(obj) {\n // Make sure we only access the accessor once as required by the spec\n var then = obj && obj.then;\n if (obj && typeof obj === 'object' && typeof then === 'function') {\n return function appyThen() {\n then.apply(obj, arguments);\n };\n }\n}\n\nfunction safelyResolveThenable(self, thenable) {\n // Either fulfill, reject or reject with error\n var called = false;\n function onError(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.reject(self, value);\n }\n\n function onSuccess(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.resolve(self, value);\n }\n\n function tryToUnwrap() {\n thenable(onSuccess, onError);\n }\n\n var result = tryCatch(tryToUnwrap);\n if (result.status === 'error') {\n onError(result.value);\n }\n}\n\nfunction tryCatch(func, value) {\n var out = {};\n try {\n out.value = func(value);\n out.status = 'success';\n } catch (e) {\n out.status = 'error';\n out.value = e;\n }\n return out;\n}\n\nexports.resolve = resolve;\nfunction resolve(value) {\n if (value instanceof this) {\n return value;\n }\n return handlers.resolve(new this(INTERNAL), value);\n}\n\nexports.reject = reject;\nfunction reject(reason) {\n var promise = new this(INTERNAL);\n return handlers.reject(promise, reason);\n}\n\nexports.all = all;\nfunction all(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var values = new Array(len);\n var resolved = 0;\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n allResolver(iterable[i], i);\n }\n return promise;\n function allResolver(value, i) {\n self.resolve(value).then(resolveFromAll, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n function resolveFromAll(outValue) {\n values[i] = outValue;\n if (++resolved === len && !called) {\n called = true;\n handlers.resolve(promise, values);\n }\n }\n }\n}\n\nexports.race = race;\nfunction race(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n resolver(iterable[i]);\n }\n return promise;\n function resolver(value) {\n self.resolve(value).then(function (response) {\n if (!called) {\n called = true;\n handlers.resolve(promise, response);\n }\n }, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n }\n}\n\n},{\"1\":1}],3:[function(_dereq_,module,exports){\n(function (global){\n'use strict';\nif (typeof global.Promise !== 'function') {\n global.Promise = _dereq_(2);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"2\":2}],4:[function(_dereq_,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction getIDB() {\n /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */\n try {\n if (typeof indexedDB !== 'undefined') {\n return indexedDB;\n }\n if (typeof webkitIndexedDB !== 'undefined') {\n return webkitIndexedDB;\n }\n if (typeof mozIndexedDB !== 'undefined') {\n return mozIndexedDB;\n }\n if (typeof OIndexedDB !== 'undefined') {\n return OIndexedDB;\n }\n if (typeof msIndexedDB !== 'undefined') {\n return msIndexedDB;\n }\n } catch (e) {}\n}\n\nvar idb = getIDB();\n\nfunction isIndexedDBValid() {\n try {\n // Initialize IndexedDB; fall back to vendor-prefixed versions\n // if needed.\n if (!idb) {\n return false;\n }\n // We mimic PouchDB here;\n //\n // We test for openDatabase because IE Mobile identifies itself\n // as Safari. Oh the lulz...\n var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform);\n\n var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1;\n\n // Safari <10.1 does not meet our requirements for IDB support (#5572)\n // since Safari 10.1 shipped with fetch, we can use that to detect it\n return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' &&\n // some outdated implementations of IDB that appear on Samsung\n // and HTC Android devices <4.4 are missing IDBKeyRange\n typeof IDBKeyRange !== 'undefined';\n } catch (e) {\n return false;\n }\n}\n\nfunction isWebSQLValid() {\n return typeof openDatabase === 'function';\n}\n\nfunction isLocalStorageValid() {\n try {\n return typeof localStorage !== 'undefined' && 'setItem' in localStorage && localStorage.setItem;\n } catch (e) {\n return false;\n }\n}\n\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\nfunction createBlob(parts, properties) {\n /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */\n parts = parts || [];\n properties = properties || {};\n try {\n return new Blob(parts, properties);\n } catch (e) {\n if (e.name !== 'TypeError') {\n throw e;\n }\n var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder;\n var builder = new Builder();\n for (var i = 0; i < parts.length; i += 1) {\n builder.append(parts[i]);\n }\n return builder.getBlob(properties.type);\n }\n}\n\n// This is CommonJS because lie is an external dependency, so Rollup\n// can just ignore it.\nif (typeof Promise === 'undefined') {\n // In the \"nopromises\" build this will just throw if you don't have\n // a global promise object, but it would throw anyway later.\n _dereq_(3);\n}\nvar Promise$1 = Promise;\n\nfunction executeCallback(promise, callback) {\n if (callback) {\n promise.then(function (result) {\n callback(null, result);\n }, function (error) {\n callback(error);\n });\n }\n}\n\nfunction executeTwoCallbacks(promise, callback, errorCallback) {\n if (typeof callback === 'function') {\n promise.then(callback);\n }\n\n if (typeof errorCallback === 'function') {\n promise[\"catch\"](errorCallback);\n }\n}\n\n// Some code originally from async_storage.js in\n// [Gaia](https://github.com/mozilla-b2g/gaia).\n\nvar DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support';\nvar supportsBlobs;\nvar dbContexts;\nvar toString = Object.prototype.toString;\n\n// Transform a binary string to an array buffer, because otherwise\n// weird stuff happens when you try to work with the binary string directly.\n// It is known.\n// From http://stackoverflow.com/questions/14967647/ (continues on next line)\n// encode-decode-image-with-base64-breaks-image (2013-04-21)\nfunction _binStringToArrayBuffer(bin) {\n var length = bin.length;\n var buf = new ArrayBuffer(length);\n var arr = new Uint8Array(buf);\n for (var i = 0; i < length; i++) {\n arr[i] = bin.charCodeAt(i);\n }\n return buf;\n}\n\n//\n// Blobs are not supported in all versions of IndexedDB, notably\n// Chrome <37 and Android <5. In those versions, storing a blob will throw.\n//\n// Various other blob bugs exist in Chrome v37-42 (inclusive).\n// Detecting them is expensive and confusing to users, and Chrome 37-42\n// is at very low usage worldwide, so we do a hacky userAgent check instead.\n//\n// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120\n// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916\n// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836\n//\n// Code borrowed from PouchDB. See:\n// https://github.com/pouchdb/pouchdb/blob/master/packages/node_modules/pouchdb-adapter-idb/src/blobSupport.js\n//\nfunction _checkBlobSupportWithoutCaching(idb) {\n return new Promise$1(function (resolve) {\n var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, 'readwrite');\n var blob = createBlob(['']);\n txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');\n\n txn.onabort = function (e) {\n // If the transaction aborts now its due to not being able to\n // write to the database, likely due to the disk being full\n e.preventDefault();\n e.stopPropagation();\n resolve(false);\n };\n\n txn.oncomplete = function () {\n var matchedChrome = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n var matchedEdge = navigator.userAgent.match(/Edge\\//);\n // MS Edge pretends to be Chrome 42:\n // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx\n resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43);\n };\n })[\"catch\"](function () {\n return false; // error, so assume unsupported\n });\n}\n\nfunction _checkBlobSupport(idb) {\n if (typeof supportsBlobs === 'boolean') {\n return Promise$1.resolve(supportsBlobs);\n }\n return _checkBlobSupportWithoutCaching(idb).then(function (value) {\n supportsBlobs = value;\n return supportsBlobs;\n });\n}\n\nfunction _deferReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Create a deferred object representing the current database operation.\n var deferredOperation = {};\n\n deferredOperation.promise = new Promise$1(function (resolve) {\n deferredOperation.resolve = resolve;\n });\n\n // Enqueue the deferred operation.\n dbContext.deferredOperations.push(deferredOperation);\n\n // Chain its promise to the database readiness.\n if (!dbContext.dbReady) {\n dbContext.dbReady = deferredOperation.promise;\n } else {\n dbContext.dbReady = dbContext.dbReady.then(function () {\n return deferredOperation.promise;\n });\n }\n}\n\nfunction _advanceReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Dequeue a deferred operation.\n var deferredOperation = dbContext.deferredOperations.pop();\n\n // Resolve its promise (which is part of the database readiness\n // chain of promises).\n if (deferredOperation) {\n deferredOperation.resolve();\n }\n}\n\nfunction _getConnection(dbInfo, upgradeNeeded) {\n return new Promise$1(function (resolve, reject) {\n\n if (dbInfo.db) {\n if (upgradeNeeded) {\n _deferReadiness(dbInfo);\n dbInfo.db.close();\n } else {\n return resolve(dbInfo.db);\n }\n }\n\n var dbArgs = [dbInfo.name];\n\n if (upgradeNeeded) {\n dbArgs.push(dbInfo.version);\n }\n\n var openreq = idb.open.apply(idb, dbArgs);\n\n if (upgradeNeeded) {\n openreq.onupgradeneeded = function (e) {\n var db = openreq.result;\n try {\n db.createObjectStore(dbInfo.storeName);\n if (e.oldVersion <= 1) {\n // Added when support for blob shims was added\n db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);\n }\n } catch (ex) {\n if (ex.name === 'ConstraintError') {\n console.warn('The database \"' + dbInfo.name + '\"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage \"' + dbInfo.storeName + '\" already exists.');\n } else {\n throw ex;\n }\n }\n };\n }\n\n openreq.onerror = function (e) {\n e.preventDefault();\n reject(openreq.error);\n };\n\n openreq.onsuccess = function () {\n resolve(openreq.result);\n _advanceReadiness(dbInfo);\n };\n });\n}\n\nfunction _getOriginalConnection(dbInfo) {\n return _getConnection(dbInfo, false);\n}\n\nfunction _getUpgradedConnection(dbInfo) {\n return _getConnection(dbInfo, true);\n}\n\nfunction _isUpgradeNeeded(dbInfo, defaultVersion) {\n if (!dbInfo.db) {\n return true;\n }\n\n var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName);\n var isDowngrade = dbInfo.version < dbInfo.db.version;\n var isUpgrade = dbInfo.version > dbInfo.db.version;\n\n if (isDowngrade) {\n // If the version is not the default one\n // then warn for impossible downgrade.\n if (dbInfo.version !== defaultVersion) {\n console.warn('The database \"' + dbInfo.name + '\"' + ' can\\'t be downgraded from version ' + dbInfo.db.version + ' to version ' + dbInfo.version + '.');\n }\n // Align the versions to prevent errors.\n dbInfo.version = dbInfo.db.version;\n }\n\n if (isUpgrade || isNewStore) {\n // If the store is new then increment the version (if needed).\n // This will trigger an \"upgradeneeded\" event which is required\n // for creating a store.\n if (isNewStore) {\n var incVersion = dbInfo.db.version + 1;\n if (incVersion > dbInfo.version) {\n dbInfo.version = incVersion;\n }\n }\n\n return true;\n }\n\n return false;\n}\n\n// encode a blob for indexeddb engines that don't support blobs\nfunction _encodeBlob(blob) {\n return new Promise$1(function (resolve, reject) {\n var reader = new FileReader();\n reader.onerror = reject;\n reader.onloadend = function (e) {\n var base64 = btoa(e.target.result || '');\n resolve({\n __local_forage_encoded_blob: true,\n data: base64,\n type: blob.type\n });\n };\n reader.readAsBinaryString(blob);\n });\n}\n\n// decode an encoded blob\nfunction _decodeBlob(encodedBlob) {\n var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data));\n return createBlob([arrayBuff], { type: encodedBlob.type });\n}\n\n// is this one of our fancy encoded blobs?\nfunction _isEncodedBlob(value) {\n return value && value.__local_forage_encoded_blob;\n}\n\n// Specialize the default `ready()` function by making it dependent\n// on the current database operations. Thus, the driver will be actually\n// ready when it's been initialized (default) *and* there are no pending\n// operations on the database (initiated by some other instances).\nfunction _fullyReady(callback) {\n var self = this;\n\n var promise = self._initReady().then(function () {\n var dbContext = dbContexts[self._dbInfo.name];\n\n if (dbContext && dbContext.dbReady) {\n return dbContext.dbReady;\n }\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n}\n\n// Open the IndexedDB database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n // Initialize a singleton container for all running localForages.\n if (!dbContexts) {\n dbContexts = {};\n }\n\n // Get the current context of the database;\n var dbContext = dbContexts[dbInfo.name];\n\n // ...or create a new context.\n if (!dbContext) {\n dbContext = {\n // Running localForages sharing a database.\n forages: [],\n // Shared database.\n db: null,\n // Database readiness (promise).\n dbReady: null,\n // Deferred operations on the database.\n deferredOperations: []\n };\n // Register the new context in the global container.\n dbContexts[dbInfo.name] = dbContext;\n }\n\n // Register itself as a running localForage in the current context.\n dbContext.forages.push(self);\n\n // Replace the default `ready()` function with the specialized one.\n if (!self._initReady) {\n self._initReady = self.ready;\n self.ready = _fullyReady;\n }\n\n // Create an array of initialization states of the related localForages.\n var initPromises = [];\n\n function ignoreErrors() {\n // Don't handle errors here,\n // just makes sure related localForages aren't pending.\n return Promise$1.resolve();\n }\n\n for (var j = 0; j < dbContext.forages.length; j++) {\n var forage = dbContext.forages[j];\n if (forage !== self) {\n // Don't wait for itself...\n initPromises.push(forage._initReady()[\"catch\"](ignoreErrors));\n }\n }\n\n // Take a snapshot of the related localForages.\n var forages = dbContext.forages.slice(0);\n\n // Initialize the connection process only when\n // all the related localForages aren't pending.\n return Promise$1.all(initPromises).then(function () {\n dbInfo.db = dbContext.db;\n // Get the connection or open a new one without upgrade.\n return _getOriginalConnection(dbInfo);\n }).then(function (db) {\n dbInfo.db = db;\n if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) {\n // Reopen the database for upgrading.\n return _getUpgradedConnection(dbInfo);\n }\n return db;\n }).then(function (db) {\n dbInfo.db = dbContext.db = db;\n self._dbInfo = dbInfo;\n // Share the final connection amongst related localForages.\n for (var k = 0; k < forages.length; k++) {\n var forage = forages[k];\n if (forage !== self) {\n // Self is already up-to-date.\n forage._dbInfo.db = dbInfo.db;\n forage._dbInfo.version = dbInfo.version;\n }\n }\n });\n}\n\nfunction getItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.get(key);\n\n req.onsuccess = function () {\n var value = req.result;\n if (value === undefined) {\n value = null;\n }\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n resolve(value);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items stored in database.\nfunction iterate(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var iterationNumber = 1;\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (cursor) {\n var value = cursor.value;\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n var result = iterator(value, cursor.key, iterationNumber++);\n\n if (result !== void 0) {\n resolve(result);\n } else {\n cursor[\"continue\"]();\n }\n } else {\n resolve();\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n\n return promise;\n}\n\nfunction setItem(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n var dbInfo;\n self.ready().then(function () {\n dbInfo = self._dbInfo;\n if (toString.call(value) === '[object Blob]') {\n return _checkBlobSupport(dbInfo.db).then(function (blobSupport) {\n if (blobSupport) {\n return value;\n }\n return _encodeBlob(value);\n });\n }\n return value;\n }).then(function (value) {\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.put(value, key);\n\n // The reason we don't _save_ null is because IE 10 does\n // not support saving the `null` type in IndexedDB. How\n // ironic, given the bug below!\n // See: https://github.com/mozilla/localForage/issues/161\n if (value === null) {\n value = undefined;\n }\n\n transaction.oncomplete = function () {\n // Cast to undefined so the value passed to\n // callback/promise is the same as what one would get out\n // of `getItem()` later. This leads to some weirdness\n // (setItem('foo', undefined) will return `null`), but\n // it's not my fault localStorage is our baseline and that\n // it's weird.\n if (value === undefined) {\n value = null;\n }\n\n resolve(value);\n };\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction removeItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n\n // We use a Grunt task to make this safe for IE and some\n // versions of Android (including those used by Cordova).\n // Normally IE won't like `.delete()` and will insist on\n // using `['delete']()`, but we have a build step that\n // fixes this for us now.\n var req = store[\"delete\"](key);\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onerror = function () {\n reject(req.error);\n };\n\n // The request will be also be aborted if we've exceeded our storage\n // space.\n transaction.onabort = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction clear(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.clear();\n\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction length(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.count();\n\n req.onsuccess = function () {\n resolve(req.result);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction key(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n if (n < 0) {\n resolve(null);\n\n return;\n }\n\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var advanced = false;\n var req = store.openCursor();\n req.onsuccess = function () {\n var cursor = req.result;\n if (!cursor) {\n // this means there weren't enough keys\n resolve(null);\n\n return;\n }\n\n if (n === 0) {\n // We have the first key, return it if that's what they\n // wanted.\n resolve(cursor.key);\n } else {\n if (!advanced) {\n // Otherwise, ask the cursor to skip ahead n\n // records.\n advanced = true;\n cursor.advance(n);\n } else {\n // When we get here, we've got the nth key.\n resolve(cursor.key);\n }\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var keys = [];\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (!cursor) {\n resolve(keys);\n return;\n }\n\n keys.push(cursor.key);\n cursor[\"continue\"]();\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar asyncStorage = {\n _driver: 'asyncStorage',\n _initStorage: _initStorage,\n iterate: iterate,\n getItem: getItem,\n setItem: setItem,\n removeItem: removeItem,\n clear: clear,\n length: length,\n key: key,\n keys: keys\n};\n\n// Sadly, the best way to save binary data in WebSQL/localStorage is serializing\n// it to Base64, so this is how we store it to prevent very strange errors with less\n// verbose ways of binary <-> string data storage.\nvar BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\nvar BLOB_TYPE_PREFIX = '~~local_forage_type~';\nvar BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;\n\nvar SERIALIZED_MARKER = '__lfsc__:';\nvar SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;\n\n// OMG the serializations!\nvar TYPE_ARRAYBUFFER = 'arbf';\nvar TYPE_BLOB = 'blob';\nvar TYPE_INT8ARRAY = 'si08';\nvar TYPE_UINT8ARRAY = 'ui08';\nvar TYPE_UINT8CLAMPEDARRAY = 'uic8';\nvar TYPE_INT16ARRAY = 'si16';\nvar TYPE_INT32ARRAY = 'si32';\nvar TYPE_UINT16ARRAY = 'ur16';\nvar TYPE_UINT32ARRAY = 'ui32';\nvar TYPE_FLOAT32ARRAY = 'fl32';\nvar TYPE_FLOAT64ARRAY = 'fl64';\nvar TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;\n\nvar toString$1 = Object.prototype.toString;\n\nfunction stringToBuffer(serializedString) {\n // Fill the string into a ArrayBuffer.\n var bufferLength = serializedString.length * 0.75;\n var len = serializedString.length;\n var i;\n var p = 0;\n var encoded1, encoded2, encoded3, encoded4;\n\n if (serializedString[serializedString.length - 1] === '=') {\n bufferLength--;\n if (serializedString[serializedString.length - 2] === '=') {\n bufferLength--;\n }\n }\n\n var buffer = new ArrayBuffer(bufferLength);\n var bytes = new Uint8Array(buffer);\n\n for (i = 0; i < len; i += 4) {\n encoded1 = BASE_CHARS.indexOf(serializedString[i]);\n encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);\n encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);\n encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);\n\n /*jslint bitwise: true */\n bytes[p++] = encoded1 << 2 | encoded2 >> 4;\n bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;\n bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;\n }\n return buffer;\n}\n\n// Converts a buffer to a string to store, serialized, in the backend\n// storage library.\nfunction bufferToString(buffer) {\n // base64-arraybuffer\n var bytes = new Uint8Array(buffer);\n var base64String = '';\n var i;\n\n for (i = 0; i < bytes.length; i += 3) {\n /*jslint bitwise: true */\n base64String += BASE_CHARS[bytes[i] >> 2];\n base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];\n base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];\n base64String += BASE_CHARS[bytes[i + 2] & 63];\n }\n\n if (bytes.length % 3 === 2) {\n base64String = base64String.substring(0, base64String.length - 1) + '=';\n } else if (bytes.length % 3 === 1) {\n base64String = base64String.substring(0, base64String.length - 2) + '==';\n }\n\n return base64String;\n}\n\n// Serialize a value, afterwards executing a callback (which usually\n// instructs the `setItem()` callback/promise to be executed). This is how\n// we store binary data with localStorage.\nfunction serialize(value, callback) {\n var valueType = '';\n if (value) {\n valueType = toString$1.call(value);\n }\n\n // Cannot use `value instanceof ArrayBuffer` or such here, as these\n // checks fail when running the tests using casper.js...\n //\n // TODO: See why those tests fail and use a better solution.\n if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) {\n // Convert binary arrays to a string and prefix the string with\n // a special marker.\n var buffer;\n var marker = SERIALIZED_MARKER;\n\n if (value instanceof ArrayBuffer) {\n buffer = value;\n marker += TYPE_ARRAYBUFFER;\n } else {\n buffer = value.buffer;\n\n if (valueType === '[object Int8Array]') {\n marker += TYPE_INT8ARRAY;\n } else if (valueType === '[object Uint8Array]') {\n marker += TYPE_UINT8ARRAY;\n } else if (valueType === '[object Uint8ClampedArray]') {\n marker += TYPE_UINT8CLAMPEDARRAY;\n } else if (valueType === '[object Int16Array]') {\n marker += TYPE_INT16ARRAY;\n } else if (valueType === '[object Uint16Array]') {\n marker += TYPE_UINT16ARRAY;\n } else if (valueType === '[object Int32Array]') {\n marker += TYPE_INT32ARRAY;\n } else if (valueType === '[object Uint32Array]') {\n marker += TYPE_UINT32ARRAY;\n } else if (valueType === '[object Float32Array]') {\n marker += TYPE_FLOAT32ARRAY;\n } else if (valueType === '[object Float64Array]') {\n marker += TYPE_FLOAT64ARRAY;\n } else {\n callback(new Error('Failed to get type for BinaryArray'));\n }\n }\n\n callback(marker + bufferToString(buffer));\n } else if (valueType === '[object Blob]') {\n // Conver the blob to a binaryArray and then to a string.\n var fileReader = new FileReader();\n\n fileReader.onload = function () {\n // Backwards-compatible prefix for the blob type.\n var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result);\n\n callback(SERIALIZED_MARKER + TYPE_BLOB + str);\n };\n\n fileReader.readAsArrayBuffer(value);\n } else {\n try {\n callback(JSON.stringify(value));\n } catch (e) {\n console.error(\"Couldn't convert value into a JSON string: \", value);\n\n callback(null, e);\n }\n }\n}\n\n// Deserialize data we've inserted into a value column/field. We place\n// special markers into our strings to mark them as encoded; this isn't\n// as nice as a meta field, but it's the only sane thing we can do whilst\n// keeping localStorage support intact.\n//\n// Oftentimes this will just deserialize JSON content, but if we have a\n// special marker (SERIALIZED_MARKER, defined above), we will extract\n// some kind of arraybuffer/binary data/typed array out of the string.\nfunction deserialize(value) {\n // If we haven't marked this string as being specially serialized (i.e.\n // something other than serialized JSON), we can just return it and be\n // done with it.\n if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {\n return JSON.parse(value);\n }\n\n // The following code deals with deserializing some kind of Blob or\n // TypedArray. First we separate out the type of data we're dealing\n // with from the data itself.\n var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);\n var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH);\n\n var blobType;\n // Backwards-compatible blob type serialization strategy.\n // DBs created with older versions of localForage will simply not have the blob type.\n if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {\n var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);\n blobType = matcher[1];\n serializedString = serializedString.substring(matcher[0].length);\n }\n var buffer = stringToBuffer(serializedString);\n\n // Return the right type based on the code/type set during\n // serialization.\n switch (type) {\n case TYPE_ARRAYBUFFER:\n return buffer;\n case TYPE_BLOB:\n return createBlob([buffer], { type: blobType });\n case TYPE_INT8ARRAY:\n return new Int8Array(buffer);\n case TYPE_UINT8ARRAY:\n return new Uint8Array(buffer);\n case TYPE_UINT8CLAMPEDARRAY:\n return new Uint8ClampedArray(buffer);\n case TYPE_INT16ARRAY:\n return new Int16Array(buffer);\n case TYPE_UINT16ARRAY:\n return new Uint16Array(buffer);\n case TYPE_INT32ARRAY:\n return new Int32Array(buffer);\n case TYPE_UINT32ARRAY:\n return new Uint32Array(buffer);\n case TYPE_FLOAT32ARRAY:\n return new Float32Array(buffer);\n case TYPE_FLOAT64ARRAY:\n return new Float64Array(buffer);\n default:\n throw new Error('Unkown type: ' + type);\n }\n}\n\nvar localforageSerializer = {\n serialize: serialize,\n deserialize: deserialize,\n stringToBuffer: stringToBuffer,\n bufferToString: bufferToString\n};\n\n/*\n * Includes code from:\n *\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n// Open the WebSQL database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage$1(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i];\n }\n }\n\n var dbInfoPromise = new Promise$1(function (resolve, reject) {\n // Open the database; the openDatabase API will automatically\n // create it for us if it doesn't exist.\n try {\n dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size);\n } catch (e) {\n return reject(e);\n }\n\n // Create our key/value table if it doesn't exist.\n dbInfo.db.transaction(function (t) {\n t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' (id INTEGER PRIMARY KEY, key unique, value)', [], function () {\n self._dbInfo = dbInfo;\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n });\n\n dbInfo.serializer = localforageSerializer;\n return dbInfoPromise;\n}\n\nfunction getItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).value : null;\n\n // Check to see if this is serialized content we need to\n // unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction iterate$1(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName, [], function (t, results) {\n var rows = results.rows;\n var length = rows.length;\n\n for (var i = 0; i < length; i++) {\n var item = rows.item(i);\n var result = item.value;\n\n // Check to see if this is serialized content\n // we need to unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n result = iterator(result, item.key, i + 1);\n\n // void(0) prevents problems with redefinition\n // of `undefined`.\n if (result !== void 0) {\n resolve(result);\n return;\n }\n }\n\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction _setItem(key, value, callback, retriesLeft) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n // The localStorage API doesn't return undefined values in an\n // \"expected\" way, so undefined is always cast to null in all\n // drivers. See: https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n dbInfo.db.transaction(function (t) {\n t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + ' (key, value) VALUES (?, ?)', [key, value], function () {\n resolve(originalValue);\n }, function (t, error) {\n reject(error);\n });\n }, function (sqlError) {\n // The transaction failed; check\n // to see if it's a quota error.\n if (sqlError.code === sqlError.QUOTA_ERR) {\n // We reject the callback outright for now, but\n // it's worth trying to re-run the transaction.\n // Even if the user accepts the prompt to use\n // more storage on Safari, this error will\n // be called.\n //\n // Try to re-run the transaction.\n if (retriesLeft > 0) {\n resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1]));\n return;\n }\n reject(sqlError);\n }\n });\n }\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction setItem$1(key, value, callback) {\n return _setItem.apply(this, [key, value, callback, 1]);\n}\n\nfunction removeItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () {\n resolve();\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Deletes every item in the table.\n// TODO: Find out if this resets the AUTO_INCREMENT number.\nfunction clear$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function () {\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Does a simple `COUNT(key)` to get the number of items stored in\n// localForage.\nfunction length$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n // Ahhh, SQL makes this one soooooo easy.\n t.executeSql('SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) {\n var result = results.rows.item(0).c;\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Return the key located at key index X; essentially gets the key from a\n// `WHERE id = ?`. This is the most efficient way I can think to implement\n// this rarely-used (in my experience) part of the API, but it can seem\n// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so\n// the ID of each key will change every time it's updated. Perhaps a stored\n// procedure for the `setItem()` SQL would solve this problem?\n// TODO: Don't change ID on `setItem()`.\nfunction key$1(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).key : null;\n resolve(result);\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName, [], function (t, results) {\n var keys = [];\n\n for (var i = 0; i < results.rows.length; i++) {\n keys.push(results.rows.item(i).key);\n }\n\n resolve(keys);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar webSQLStorage = {\n _driver: 'webSQLStorage',\n _initStorage: _initStorage$1,\n iterate: iterate$1,\n getItem: getItem$1,\n setItem: setItem$1,\n removeItem: removeItem$1,\n clear: clear$1,\n length: length$1,\n key: key$1,\n keys: keys$1\n};\n\n// Config the localStorage backend, using options set in the config.\nfunction _initStorage$2(options) {\n var self = this;\n var dbInfo = {};\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n dbInfo.keyPrefix = dbInfo.name + '/';\n\n if (dbInfo.storeName !== self._defaultConfig.storeName) {\n dbInfo.keyPrefix += dbInfo.storeName + '/';\n }\n\n self._dbInfo = dbInfo;\n dbInfo.serializer = localforageSerializer;\n\n return Promise$1.resolve();\n}\n\n// Remove all keys from the datastore, effectively destroying all data in\n// the app's key/value store!\nfunction clear$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var keyPrefix = self._dbInfo.keyPrefix;\n\n for (var i = localStorage.length - 1; i >= 0; i--) {\n var key = localStorage.key(i);\n\n if (key.indexOf(keyPrefix) === 0) {\n localStorage.removeItem(key);\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Retrieve an item from the store. Unlike the original async_storage\n// library in Gaia, we don't modify return values at all. If a key's value\n// is `undefined`, we pass that value to the callback function.\nfunction getItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result = localStorage.getItem(dbInfo.keyPrefix + key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the key\n // is likely undefined and we'll pass it straight to the\n // callback.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items in the store.\nfunction iterate$2(iterator, callback) {\n var self = this;\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var keyPrefix = dbInfo.keyPrefix;\n var keyPrefixLength = keyPrefix.length;\n var length = localStorage.length;\n\n // We use a dedicated iterator instead of the `i` variable below\n // so other keys we fetch in localStorage aren't counted in\n // the `iterationNumber` argument passed to the `iterate()`\n // callback.\n //\n // See: github.com/mozilla/localForage/pull/435#discussion_r38061530\n var iterationNumber = 1;\n\n for (var i = 0; i < length; i++) {\n var key = localStorage.key(i);\n if (key.indexOf(keyPrefix) !== 0) {\n continue;\n }\n var value = localStorage.getItem(key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the\n // key is likely undefined and we'll pass it straight\n // to the iterator.\n if (value) {\n value = dbInfo.serializer.deserialize(value);\n }\n\n value = iterator(value, key.substring(keyPrefixLength), iterationNumber++);\n\n if (value !== void 0) {\n return value;\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Same as localStorage's key() method, except takes a callback.\nfunction key$2(n, callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result;\n try {\n result = localStorage.key(n);\n } catch (error) {\n result = null;\n }\n\n // Remove the prefix from the key, if a key is found.\n if (result) {\n result = result.substring(dbInfo.keyPrefix.length);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var length = localStorage.length;\n var keys = [];\n\n for (var i = 0; i < length; i++) {\n if (localStorage.key(i).indexOf(dbInfo.keyPrefix) === 0) {\n keys.push(localStorage.key(i).substring(dbInfo.keyPrefix.length));\n }\n }\n\n return keys;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Supply the number of keys in the datastore to the callback function.\nfunction length$2(callback) {\n var self = this;\n var promise = self.keys().then(function (keys) {\n return keys.length;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Remove an item from the store, nice and simple.\nfunction removeItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n localStorage.removeItem(dbInfo.keyPrefix + key);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Set a key's value and run an optional callback once the value is set.\n// Unlike Gaia's implementation, the callback function is passed the value,\n// in case you want to operate on that value only after you're sure it\n// saved, or something like that.\nfunction setItem$2(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n // Convert undefined values to null.\n // https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n return new Promise$1(function (resolve, reject) {\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n try {\n localStorage.setItem(dbInfo.keyPrefix + key, value);\n resolve(originalValue);\n } catch (e) {\n // localStorage capacity exceeded.\n // TODO: Make this a specific error/event.\n if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {\n reject(e);\n }\n reject(e);\n }\n }\n });\n });\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar localStorageWrapper = {\n _driver: 'localStorageWrapper',\n _initStorage: _initStorage$2,\n // Default API, from Gaia/localStorage.\n iterate: iterate$2,\n getItem: getItem$2,\n setItem: setItem$2,\n removeItem: removeItem$2,\n clear: clear$2,\n length: length$2,\n key: key$2,\n keys: keys$2\n};\n\n// Custom drivers are stored here when `defineDriver()` is called.\n// They are shared across all instances of localForage.\nvar CustomDrivers = {};\n\nvar DriverType = {\n INDEXEDDB: 'asyncStorage',\n LOCALSTORAGE: 'localStorageWrapper',\n WEBSQL: 'webSQLStorage'\n};\n\nvar DefaultDriverOrder = [DriverType.INDEXEDDB, DriverType.WEBSQL, DriverType.LOCALSTORAGE];\n\nvar LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem'];\n\nvar DefaultConfig = {\n description: '',\n driver: DefaultDriverOrder.slice(),\n name: 'localforage',\n // Default DB size is _JUST UNDER_ 5MB, as it's the highest size\n // we can use without a prompt.\n size: 4980736,\n storeName: 'keyvaluepairs',\n version: 1.0\n};\n\nvar driverSupport = {};\n// Check to see if IndexedDB is available and if it is the latest\n// implementation; it's our preferred backend library. We use \"_spec_test\"\n// as the name of the database because it's not the one we'll operate on,\n// but it's useful to make sure its using the right spec.\n// See: https://github.com/mozilla/localForage/issues/128\ndriverSupport[DriverType.INDEXEDDB] = isIndexedDBValid();\n\ndriverSupport[DriverType.WEBSQL] = isWebSQLValid();\n\ndriverSupport[DriverType.LOCALSTORAGE] = isLocalStorageValid();\n\nvar isArray = Array.isArray || function (arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n};\n\nfunction callWhenReady(localForageInstance, libraryMethod) {\n localForageInstance[libraryMethod] = function () {\n var _args = arguments;\n return localForageInstance.ready().then(function () {\n return localForageInstance[libraryMethod].apply(localForageInstance, _args);\n });\n };\n}\n\nfunction extend() {\n for (var i = 1; i < arguments.length; i++) {\n var arg = arguments[i];\n\n if (arg) {\n for (var key in arg) {\n if (arg.hasOwnProperty(key)) {\n if (isArray(arg[key])) {\n arguments[0][key] = arg[key].slice();\n } else {\n arguments[0][key] = arg[key];\n }\n }\n }\n }\n }\n\n return arguments[0];\n}\n\nfunction isLibraryDriver(driverName) {\n for (var driver in DriverType) {\n if (DriverType.hasOwnProperty(driver) && DriverType[driver] === driverName) {\n return true;\n }\n }\n\n return false;\n}\n\nvar LocalForage = function () {\n function LocalForage(options) {\n _classCallCheck(this, LocalForage);\n\n this.INDEXEDDB = DriverType.INDEXEDDB;\n this.LOCALSTORAGE = DriverType.LOCALSTORAGE;\n this.WEBSQL = DriverType.WEBSQL;\n\n this._defaultConfig = extend({}, DefaultConfig);\n this._config = extend({}, this._defaultConfig, options);\n this._driverSet = null;\n this._initDriver = null;\n this._ready = false;\n this._dbInfo = null;\n\n this._wrapLibraryMethodsWithReady();\n this.setDriver(this._config.driver)[\"catch\"](function () {});\n }\n\n // Set any config values for localForage; can be called anytime before\n // the first API call (e.g. `getItem`, `setItem`).\n // We loop through options so we don't overwrite existing config\n // values.\n\n\n LocalForage.prototype.config = function config(options) {\n // If the options argument is an object, we use it to set values.\n // Otherwise, we return either a specified config value or all\n // config values.\n if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {\n // If localforage is ready and fully initialized, we can't set\n // any new configuration values. Instead, we return an error.\n if (this._ready) {\n return new Error(\"Can't call config() after localforage \" + 'has been used.');\n }\n\n for (var i in options) {\n if (i === 'storeName') {\n options[i] = options[i].replace(/\\W/g, '_');\n }\n\n if (i === 'version' && typeof options[i] !== 'number') {\n return new Error('Database version must be a number.');\n }\n\n this._config[i] = options[i];\n }\n\n // after all config options are set and\n // the driver option is used, try setting it\n if ('driver' in options && options.driver) {\n return this.setDriver(this._config.driver);\n }\n\n return true;\n } else if (typeof options === 'string') {\n return this._config[options];\n } else {\n return this._config;\n }\n };\n\n // Used to define a custom driver, shared across all instances of\n // localForage.\n\n\n LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) {\n var promise = new Promise$1(function (resolve, reject) {\n try {\n var driverName = driverObject._driver;\n var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver');\n var namingError = new Error('Custom driver name already in use: ' + driverObject._driver);\n\n // A driver name should be defined and not overlap with the\n // library-defined, default drivers.\n if (!driverObject._driver) {\n reject(complianceError);\n return;\n }\n if (isLibraryDriver(driverObject._driver)) {\n reject(namingError);\n return;\n }\n\n var customDriverMethods = LibraryMethods.concat('_initStorage');\n for (var i = 0; i < customDriverMethods.length; i++) {\n var customDriverMethod = customDriverMethods[i];\n if (!customDriverMethod || !driverObject[customDriverMethod] || typeof driverObject[customDriverMethod] !== 'function') {\n reject(complianceError);\n return;\n }\n }\n\n var supportPromise = Promise$1.resolve(true);\n if ('_support' in driverObject) {\n if (driverObject._support && typeof driverObject._support === 'function') {\n supportPromise = driverObject._support();\n } else {\n supportPromise = Promise$1.resolve(!!driverObject._support);\n }\n }\n\n supportPromise.then(function (supportResult) {\n driverSupport[driverName] = supportResult;\n CustomDrivers[driverName] = driverObject;\n resolve();\n }, reject);\n } catch (e) {\n reject(e);\n }\n });\n\n executeTwoCallbacks(promise, callback, errorCallback);\n return promise;\n };\n\n LocalForage.prototype.driver = function driver() {\n return this._driver || null;\n };\n\n LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) {\n var self = this;\n var getDriverPromise = Promise$1.resolve().then(function () {\n if (isLibraryDriver(driverName)) {\n switch (driverName) {\n case self.INDEXEDDB:\n return asyncStorage;\n case self.LOCALSTORAGE:\n return localStorageWrapper;\n case self.WEBSQL:\n return webSQLStorage;\n }\n } else if (CustomDrivers[driverName]) {\n return CustomDrivers[driverName];\n } else {\n throw new Error('Driver not found.');\n }\n });\n executeTwoCallbacks(getDriverPromise, callback, errorCallback);\n return getDriverPromise;\n };\n\n LocalForage.prototype.getSerializer = function getSerializer(callback) {\n var serializerPromise = Promise$1.resolve(localforageSerializer);\n executeTwoCallbacks(serializerPromise, callback);\n return serializerPromise;\n };\n\n LocalForage.prototype.ready = function ready(callback) {\n var self = this;\n\n var promise = self._driverSet.then(function () {\n if (self._ready === null) {\n self._ready = self._initDriver();\n }\n\n return self._ready;\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n };\n\n LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) {\n var self = this;\n\n if (!isArray(drivers)) {\n drivers = [drivers];\n }\n\n var supportedDrivers = this._getSupportedDrivers(drivers);\n\n function setDriverToConfig() {\n self._config.driver = self.driver();\n }\n\n function extendSelfWithDriver(driver) {\n self._extend(driver);\n setDriverToConfig();\n\n self._ready = self._initStorage(self._config);\n return self._ready;\n }\n\n function initDriver(supportedDrivers) {\n return function () {\n var currentDriverIndex = 0;\n\n function driverPromiseLoop() {\n while (currentDriverIndex < supportedDrivers.length) {\n var driverName = supportedDrivers[currentDriverIndex];\n currentDriverIndex++;\n\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(extendSelfWithDriver)[\"catch\"](driverPromiseLoop);\n }\n\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n }\n\n return driverPromiseLoop();\n };\n }\n\n // There might be a driver initialization in progress\n // so wait for it to finish in order to avoid a possible\n // race condition to set _dbInfo\n var oldDriverSetDone = this._driverSet !== null ? this._driverSet[\"catch\"](function () {\n return Promise$1.resolve();\n }) : Promise$1.resolve();\n\n this._driverSet = oldDriverSetDone.then(function () {\n var driverName = supportedDrivers[0];\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(function (driver) {\n self._driver = driver._driver;\n setDriverToConfig();\n self._wrapLibraryMethodsWithReady();\n self._initDriver = initDriver(supportedDrivers);\n });\n })[\"catch\"](function () {\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n });\n\n executeTwoCallbacks(this._driverSet, callback, errorCallback);\n return this._driverSet;\n };\n\n LocalForage.prototype.supports = function supports(driverName) {\n return !!driverSupport[driverName];\n };\n\n LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) {\n extend(this, libraryMethodsAndProperties);\n };\n\n LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) {\n var supportedDrivers = [];\n for (var i = 0, len = drivers.length; i < len; i++) {\n var driverName = drivers[i];\n if (this.supports(driverName)) {\n supportedDrivers.push(driverName);\n }\n }\n return supportedDrivers;\n };\n\n LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() {\n // Add a stub for each driver API method that delays the call to the\n // corresponding driver method until localForage is ready. These stubs\n // will be replaced by the driver methods as soon as the driver is\n // loaded, so there is no performance impact.\n for (var i = 0; i < LibraryMethods.length; i++) {\n callWhenReady(this, LibraryMethods[i]);\n }\n };\n\n LocalForage.prototype.createInstance = function createInstance(options) {\n return new LocalForage(options);\n };\n\n return LocalForage;\n}();\n\n// The actual localForage object that we expose as a module or via a\n// global. It's extended by pulling in one of our other libraries.\n\n\nvar localforage_js = new LocalForage();\n\nmodule.exports = localforage_js;\n\n},{\"3\":3}]},{},[4])(4)\n});","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n // Let \"new String('')\" return 'object'\n if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n // PhantomJS has type \"DOMWindow\" for null\n if (obj === null) return 'null';\n // PhantomJS has type \"DOMWindow\" for undefined\n if (obj === undefined) return 'undefined';\n return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n if (!(this instanceof Library)) return new Library();\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","(function (document, window) {\n // DEPENDENCIES\n // ============================================================\n const localforage = require('localforage');\n\n // PROBLEMS\n // ============================================================\n const problems = require('../problems/arrays.js');\n\n // CONFIG\n // ============================================================\n\n // Hoist current problem\n let currentProblem;\n\n // Keys to ignore while user is navigating around the textarea but not changing any code\n const ignoreKeyCodes = [\n 9, // Tab\n 37, // Left arrow\n 39, // Right arrow\n 38, // Up arrow\n 40 // Down arrow\n ];\n\n let config = {\n shuffle: true,\n timer: false,\n currentIndex: 0\n };\n\n // Pull config from localforage\n localforage\n .getItem('js_practice_config')\n .then(val => {\n // console.log('localforage val:', val);\n if (val) {\n config = val;\n }\n loadApp(config);\n })\n .catch(err => {\n console.log('localforage err:', err);\n loadApp(config);\n });\n\n function updateLocalstore(config) {\n return localforage\n .setItem('js_practice_config', config)\n .then(val => {\n // console.log('Settings updated:', val);\n })\n .catch(err => {\n console.log('Settings update error:', err);\n });\n }\n\n // HELPERS\n // ============================================================\n\n function debounce(func, wait, immediate) {\n let timeout;\n return function () {\n const context = this;\n const args = arguments;\n const later = function () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n };\n const callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) {\n func.apply(context, args);\n }\n };\n }\n\n // UI\n // ============================================================\n\n // elements\n const problemEl = document.getElementById('problem');\n const codeEl = document.getElementById('code');\n const testSuiteEl = document.getElementById('test-suite');\n const testTotalEl = document.getElementById('test-total');\n const evalConsoleEl = document.getElementById('eval-output');\n const assertConsoleEl = document.getElementById('assert-output');\n const shuffleProblemsButtonEl = document.getElementById('shuffle-problems');\n const previousProblemButtonEl = document.getElementById('prev-problem');\n const nextProblemButtonEl = document.getElementById('next-problem');\n\n // Get indexes\n function getRandomIndex(problemsArr) {\n const ind = Math.floor(Math.random() * problemsArr.length);\n config.currentIndex = ind;\n updateLocalstore(config);\n return ind;\n }\n\n function getPreviousIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at beginning, go to end\n if (currentIndex === 0) {\n probInd = problemsArr.length - 1;\n } else {\n probInd = currentIndex - 1;\n }\n return probInd;\n }\n\n function getNextIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at end or invalid, restart series\n if (currentIndex >= problemsArr.length - 1 || currentIndex < 0) {\n probInd = 0;\n } else {\n probInd = currentIndex + 1;\n }\n return probInd;\n }\n\n // Get problems\n function getCurrentProblem(problemsArr) {\n return problemsArr[config.currentIndex];\n }\n\n function previousProblem() {\n console.log('previousProblem!');\n // Activate back button, for visual queue of nav feedback\n previousProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getPreviousIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function nextProblem() {\n console.log('nextProblem!');\n // Activate next button, for visual queue of nav feedback\n nextProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getNextIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function toggleShuffle() {\n console.log('toggle shuffle!');\n config.shuffle = !config.shuffle; // Flip it\n shuffleProblemsButtonEl.classList.toggle('active');\n previousProblemButtonEl.parentNode.classList.toggle('hidden');\n updateLocalstore(config);\n }\n\n function loadProblem(problemObj) {\n currentProblem = problemObj;\n // Prob question\n problemEl.innerText = problemObj.prompt;\n // Prob given code\n if (problemObj.given) {\n codeEl.value = problemObj.given;\n }\n // Seed the tests, pass (init = true) as second param\n testSuite(null, true);\n }\n\n // TODO: Build the assert errors into the test dom on each update.\n function updateTests(testStatus, init) {\n if (init === true) {\n buildTests(currentProblem.tests);\n }\n updateTestStatus(testStatus);\n }\n\n function buildTests(tests) {\n if (tests) {\n const testsDom = tests\n .map(test => {\n return `
\n
[✘]
\n
${test.name}
\n
`;\n })\n .join('');\n testSuiteEl.innerHTML = testsDom;\n }\n }\n\n function updateTestStatus(testStatuses) {\n if (!testStatuses) {\n throw new Error('No testStatuses provided.');\n }\n // Find out if all tests have passed or not\n let allPassed = true;\n testStatuses.forEach(testPassed => {\n if (testPassed !== true) {\n allPassed = false;\n }\n });\n const testEls = [].slice.call(testSuiteEl.querySelectorAll('.test-state'));\n testEls.forEach((testStatusEl, iter) => {\n if (testStatuses[iter] === true) {\n testStatusEl.innerHTML = '[✓]';\n testStatusEl.classList.remove('fail');\n testStatusEl.classList.add('pass');\n } else {\n testStatusEl.innerHTML = '[✘]';\n testStatusEl.classList.remove('pass');\n testStatusEl.classList.add('fail');\n }\n });\n\n if (allPassed === true) {\n testTotalEl.innerText = 'PASS';\n testTotalEl.classList.remove('fail');\n testTotalEl.classList.add('pass');\n } else {\n testTotalEl.innerText = 'FAIL';\n testTotalEl.classList.remove('pass');\n testTotalEl.classList.add('fail');\n }\n }\n\n function printAssertError(errObj) {\n // Make element string\n let inner = '';\n if (errObj !== null) {\n inner = `\n
\n Expected: ${JSON.stringify(errObj.expected)}\n Actual: ${JSON.stringify(errObj.actual)}\n
`;\n }\n\n // Prepend element\n assertConsoleEl.innerHTML = inner;\n }\n\n function printEvalOutput(errObj, output) {\n // Make element string\n let inner = '';\n if (errObj && errObj.message !== undefined) {\n inner = `\n
\n Syntax Error: ${JSON.stringify(errObj.message)}\n
`;\n } else if (output) {\n inner = `\n
\n Output: ${JSON.stringify(output)}\n
`;\n }\n // Prepend element\n evalConsoleEl.innerHTML = inner;\n }\n\n // VERIFICATION LOGIC\n // ============================================================\n\n function testSuite(init) {\n // Show 'working' indicator\n testTotalEl.classList.toggle('working');\n // Run stuff\n const output = getOutput(codeEl.value);\n // Run tests on code, return object/array of test results\n const tested = runTests(output);\n // Hide 'working' indicator\n testTotalEl.classList.toggle('working');\n // Update UI with results\n updateTests(tested, init);\n }\n\n function getOutput(code) {\n let evald = false;\n try {\n evald = eval(`(function(){${code}})()`); // eslint-disable-line no-eval\n printEvalOutput(null, evald); // Print current output\n } catch (err) {\n printEvalOutput(err);\n }\n return evald;\n }\n\n function runTests(output) {\n let tested = false;\n tested = currentProblem.tests.map(test => {\n let testOutcome = false;\n try {\n if (output) {\n testOutcome = test.test(output);\n }\n printAssertError(null);\n } catch (err) {\n printAssertError(err);\n }\n return testOutcome;\n });\n return tested;\n }\n\n // Wrapped to prevent race with local config retrieval\n function loadApp(config) {\n console.log('loading app!');\n\n // Show current toggle state\n if (config.shuffle === true) {\n shuffleProblemsButtonEl.classList.add('active');\n previousProblemButtonEl.parentNode.classList.add('hidden');\n }\n\n // Keybinding stuff\n // ============================================================\n\n // Debounced code validation\n const debouncedInputValidation = debounce(e => {\n // If not arrow keys or other non-character keys\n if (ignoreKeyCodes.indexOf(e.keyCode) === -1) {\n // Run test suite\n testSuite();\n }\n }, 200);\n\n function problemNav(e) {\n // Go to previous problem keybinding\n // If CMD/CTRL + SHIFT + RETURN/ENTER\n if (config.shuffle === false && e.keyCode === 13 && e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem\n previousProblem();\n } else if (e.keyCode === 13 && !e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem keybinding\n // If CMD/CTRL + RETURN/ENTER\n // Go to next problem\n nextProblem();\n }\n }\n\n // Event Bindings\n // ============================================================\n\n // Bind it up\n codeEl.addEventListener('keydown', debouncedInputValidation);\n document.addEventListener('keydown', problemNav);\n shuffleProblemsButtonEl.addEventListener('click', toggleShuffle);\n previousProblemButtonEl.addEventListener('click', previousProblem);\n nextProblemButtonEl.addEventListener('click', nextProblem);\n\n // Start it up!\n // Load current problem\n const currProb = getCurrentProblem(problems);\n loadProblem(currProb);\n // Initalized test suite with starting failures\n testSuite(true);\n }\n})(document, window);\n","const assert = require('chai').assert;\n\nmodule.exports = [\n {\n name: 'Create Array',\n time: 10,\n prompt: 'Create and return an array that contains \\'apple\\' and \\'banana\\'',\n given: `const fruits = [];\\rreturn fruits;`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, ['apple', 'banana']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Access Array by index (first)',\n time: 10,\n prompt: 'Return the first value of the Array',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits[0];`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 'apple') === undefined;\n }\n },\n {\n name: 'Returns a String',\n test(output) {\n return assert.isString(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Access Array by index (last)',\n time: 10,\n prompt: 'Return the last value of the Array',\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n return fruits[fruits.length - 1];`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 'orange') === undefined;\n }\n },\n {\n name: 'Returns a String',\n test(output) {\n return assert.isString(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Access Array by index (second)',\n time: 10,\n prompt: 'Return the second value of the Array',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits[1];`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 'banana') === undefined;\n }\n },\n {\n name: 'Returns a String',\n test(output) {\n return assert.isString(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.forEach()',\n time: 20,\n prompt: 'Loop over the array, add an \\'x\\' to the end of each name, push each fruit into a new array, then return the new array.',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n const newFruits = [];\n fruits.forEach(function(item) {\n newFruits.push(item+'x');\n });\n return newFruits;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, ['applex', 'bananax']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.push()',\n time: 10,\n prompt: `Add 'orange' to the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n fruits.push('orange');\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return (assert.deepEqual(output, ['apple', 'banana', 'orange']) === undefined);\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 3 items',\n test(output) {\n return assert.lengthOf(output, 3) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.pop()',\n time: 10,\n prompt: `Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, ['apple', 'banana']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.shift()',\n time: 10,\n prompt: `Remove 'apple' from the front of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.shift();\n return fruits;`,\n tests: [\n {\n name: 'Output must be correct',\n test(output) {\n return assert.deepEqual(output, ['banana', 'orange']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.unshift()',\n time: 10,\n prompt: `Add 'strawberry' to the front of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.unshift('strawberry');\n return fruits;`,\n tests: [\n {\n name: 'Output must be correct',\n test(output) {\n return (\n assert.deepEqual(output, [\n 'strawberry',\n 'apple',\n 'banana',\n 'orange'\n ]) === undefined\n );\n }\n },\n {\n name: 'Must return an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 4 items',\n test(output) {\n return assert.lengthOf(output, 4) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.indexOf()',\n time: 10,\n prompt: `Return the index of 'banana' in the Array.`,\n given: `const fruits = ['strawberry', 'banana', 'mango'];\\r`,\n answer: `const fruits = ['strawberry', 'banana', 'mango'];\n const ind = fruits.indexOf('banana');\n return ind;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 1) === undefined;\n }\n },\n {\n name: 'Returns a Number',\n test(output) {\n return assert.isNumber(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.concat()',\n time: 10,\n prompt: `Merge the two arrays using Array's 'concat()' method. Return the resulting array.`,\n given: `const fruits = ['strawberry', 'banana'];\\rconst otherFruits = ['pear','peach'];\\r`,\n answer: `const fruits = ['strawberry', 'banana'];\n const otherFruits = ['pear','peach'];\n const allTheFruits = fruits.concat(otherFruits);\n return allTheFruits;\\r`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return (\n assert.deepEqual(output, [\n 'strawberry',\n 'banana',\n 'pear',\n 'peach'\n ]) === undefined\n );\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 4 items',\n test(output) {\n return assert.lengthOf(output, 4) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.join()',\n time: 10,\n prompt: `Mix the two flavors with a '-' using Array's 'join' method. Return the resulting hybrid flavor.`,\n given: `const fruits = ['strawberry', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'banana'];\n const hybrid = fruits.join('-');\n return hybrid;\\r`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 'strawberry-banana') === undefined;\n }\n },\n {\n name: 'Returns a String',\n test(output) {\n return assert.isString(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.slice()',\n time: 20,\n prompt: `Return just the citrus fruits from the 'fruits' array using 'Array.slice()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const citrus = fruits.slice(1, 3);\n return citrus;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, ['orange', 'lemon']) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 2 items',\n test(output) {\n return assert.lengthOf(output, 2) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.reverse()',\n time: 10,\n prompt: `Reverse the order of the 'fruit' array using 'Array.reverse()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const stiurf = fruits.reverse();\n return stiurf;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return (\n assert.deepEqual(output, [\n 'banana',\n 'lemon',\n 'orange',\n 'strawberry'\n ]) === undefined\n );\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 4 items',\n test(output) {\n return assert.lengthOf(output, 4) === undefined;\n }\n },\n {\n name: `First item is 'banana'`,\n test(output) {\n return assert.deepEqual(output[0], 'banana') === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.sort()',\n time: 10,\n prompt: `Sort the order of the 'fruit' array using 'Array.sort()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const orderlyFruit = fruits.sort();\n return orderlyFruit;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return (\n assert.deepEqual(output, [\n 'banana',\n 'lemon',\n 'orange',\n 'strawberry'\n ]) === undefined\n );\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 4 items',\n test(output) {\n return assert.lengthOf(output, 4) === undefined;\n }\n },\n {\n name: `First item is 'banana'`,\n test(output) {\n return assert.deepEqual(output[0], 'banana') === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.lastIndexOf()',\n time: 10,\n prompt: `Return the index of the last 'peach' instance in the 'fruit' array using 'Array.lastIndexOf()'`,\n given: `const fruits = ['peach', 'orange', 'lemon', 'peach'];\\r`,\n answer: `const fruits = ['peach', 'orange', 'lemon', 'peach'];\n const wheresTheLastPeach = fruits.lastIndexOf('peach');\n return wheresTheLastPeach;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, 3) === undefined;\n }\n },\n {\n name: 'Returns a Number',\n test(output) {\n return assert.isNumber(output) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.filter()',\n time: 10,\n prompt: `Return an array of the numbers greater than 5 in 'numbers' using 'Array.filter()'`,\n given: `const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\\r`,\n answer: `const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\n const overFive = numbers.filter(num => num > 5);\n return overFive;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, [8, 13, 21]) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 3 items',\n test(output) {\n return assert.lengthOf(output, 3) === undefined;\n }\n },\n {\n name: `First item is 8`,\n test(output) {\n return assert.deepEqual(output[0], 8) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.map()',\n time: 10,\n prompt: `Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,\n given: `const numbers = [25, 121, 169];\\r`,\n answer: `const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, [5, 11, 13]) === undefined;\n }\n },\n {\n name: 'Returns an Array',\n test(output) {\n return assert.isArray(output) === undefined;\n }\n },\n {\n name: 'Array has 3 items',\n test(output) {\n return assert.lengthOf(output, 3) === undefined;\n }\n },\n {\n name: `First item is 5`,\n test(output) {\n return assert.deepEqual(output[0], 5) === undefined;\n }\n },\n {\n name: `Last item is 13`,\n test(output) {\n return assert.deepEqual(output[output.length - 1], 13) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.every()',\n time: 10,\n prompt: `Return object that returns whether each array contains all even numbers using Array.every().`,\n given: `\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 5, 6, 8];\nfunction isEven(element) {\n\n}\nreturn {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n};`,\n answer: `\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 5, 6, 8];\nfunction isEven(element) {\n return element % 2 === 0\n}\nreturn {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n};`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;\n }\n },\n {\n name: 'Returns an Object',\n test(output) {\n return assert.isObject(output) === undefined;\n }\n },\n {\n name: 'Object has 2 items',\n test(output) {\n return assert.lengthOf(Object.keys(output), 2) === undefined;\n }\n },\n {\n name: `First value is true`,\n test(output) {\n return assert.isTrue(output.evenNumbers) === undefined;\n }\n },\n {\n name: `Second value is false`,\n test(output) {\n return assert.isFalse(output.someOddNumbers) === undefined;\n }\n }\n ]\n },\n {\n name: 'Array.some()',\n time: 10,\n prompt: `Return object that returns whether each array contains some odd numbers using Array.some().`,\n given: `\nconst evenNumbers = [2, 4, 6, 8];\nconst someOddNumbers = [2, 4, 7, 8];\nfunction isOdd(element) {\n\n}\nreturn {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n};`,\n answer: `\nconst evenNumbers = [1, 3, 5, 7];\nconst someOddNumbers = [1, 3, 6, 7];\nfunction isOdd(element) {\n return element % 2 !== 0;\n}\nreturn {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n};`,\n tests: [\n {\n name: 'Correct output',\n test(output) {\n return assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;\n }\n },\n {\n name: 'Returns an Object',\n test(output) {\n return assert.isObject(output) === undefined;\n }\n },\n {\n name: 'Object has 2 items',\n test(output) {\n return assert.lengthOf(Object.keys(output), 2) === undefined;\n }\n },\n {\n name: `First value is false`,\n test(output) {\n return assert.isFalse(output.evenNumbers) === undefined;\n }\n },\n {\n name: `Second value is true`,\n test(output) {\n return assert.isTrue(output.someOddNumbers) === undefined;\n }\n }\n ]\n }\n // Next problems to create:\n // forEach? fix one above that tried, but can't verify forEach was used\n // some\n // reduce\n // reduceRight\n // Array.from and other ways to turn array-like into array\n];\n"]} -======= -{"version":3,"sources":["node_modules/.registry.npmjs.org/browser-pack/6.0.2/node_modules/browser-pack/_prelude.js","node_modules/.github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916/node_modules/pjs-problems/index.js","node_modules/.github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916/node_modules/pjs-problems/problems/arrays.js","node_modules/.github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916/node_modules/pjs-problems/problems/initial.js","node_modules/.registry.npmjs.org/assertion-error/1.0.2/node_modules/assertion-error/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/assertion.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/config.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/core/assertions.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/assert.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/expect.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/should.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addChainableMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/expectTypes.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/flag.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getActual.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getEnumerableProperties.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getMessage.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getName.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getPathInfo.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getPathValue.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getProperties.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/hasProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/inspect.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/objDisplay.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/test.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/transferFlags.js","node_modules/.registry.npmjs.org/dedent/0.7.0/node_modules/dedent/dist/dedent.js","node_modules/.registry.npmjs.org/deep-eql/0.1.3/node_modules/deep-eql/index.js","node_modules/.registry.npmjs.org/deep-eql/0.1.3/node_modules/deep-eql/lib/eql.js","node_modules/.registry.npmjs.org/localforage/1.5.0/node_modules/localforage/dist/node_modules/localforage/dist/localforage.js","node_modules/.registry.npmjs.org/type-detect/0.1.1/node_modules/type-detect/index.js","node_modules/.registry.npmjs.org/type-detect/0.1.1/node_modules/type-detect/lib/type.js","node_modules/.registry.npmjs.org/type-detect/1.0.0/node_modules/type-detect/lib/type.js","src/js/index.js"],"names":[],"mappings":"AAAA;ACAA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1eA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpHA;AACA;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACp0DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7mDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/UA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3DA;AACA;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACjQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;ACxwEA;AACA;;ACDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACtIA,CAAC,UAAU,QAAV,EAAoB,MAApB,EAA4B;AAC3B;AACA;;AAEA,MAAM,cAAc,QAAQ,aAAR,CAApB;AACA,MAAM,QAAQ,QAAQ,cAAR,CAAd;AACA,MAAM,SAAS,QAAQ,QAAR,CAAf;AACA,MAAM,SAAS,QAAQ,MAAR,EAAgB,MAA/B;;AAEA;AACA;;AAEA,WAAS,aAAT,CAAuB,QAAvB,EAAiC;AAC/B,WAAO,SAAS,GAAT,CAAa,gBAAQ;AAC1B,WAAK,KAAL,GAAa,OAAO,KAAK,KAAZ,CAAb;AACA,WAAK,MAAL,GAAc,OAAO,KAAK,MAAZ,CAAd;AACA,aAAO,IAAP;AACD,KAJM,CAAP;AAKD;;AAGD;AACA;;AAEA,MAAI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","file":"bundle.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o num > 5);\n return overFive;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, [8, 13, 21]) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n },\n {\n name: `First item is 8`,\n test: `assert.deepEqual(output[0], 8) === undefined;`\n }\n ]\n },\n {\n name: 'Array.map()',\n time: 10,\n prompt: `Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,\n given: `const numbers = [25, 121, 169];\\r`,\n answer: `const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, [5, 11, 13]) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n },\n {\n name: `First item is 5`,\n test: `assert.deepEqual(output[0], 5) === undefined;`\n },\n {\n name: `Last item is 13`,\n test: `assert.deepEqual(output[output.length - 1], 13) === undefined;`\n }\n ]\n },\n {\n name: 'Array.every()',\n time: 10,\n prompt: `Return object that returns whether each array contains all even numbers using Array.every().`,\n given: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,\n answer: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n return element % 2 === 0\n }\n return {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n };`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;`\n },\n {\n name: 'Returns an Object',\n test: `assert.isObject(output) === undefined;`\n },\n {\n name: 'Object has 2 items',\n test: `assert.lengthOf(Object.keys(output), 2) === undefined;`\n },\n {\n name: `First value is true`,\n test: `assert.isTrue(output.evenNumbers) === undefined;`\n },\n {\n name: `Second value is false`,\n test: `assert.isFalse(output.someOddNumbers) === undefined;`\n }\n ]\n },\n {\n name: 'Array.some()',\n time: 10,\n prompt: `Return 'Object' that returns whether each array contains some odd numbers using 'Array.some()'.`,\n given: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 4, 7, 8];\n function isOdd(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,\n answer: `const evenNumbers = [1, 3, 5, 7];\n const someOddNumbers = [1, 3, 6, 7];\n function isOdd(element) {\n return element % 2 !== 0;\n }\n return {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n };`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;`\n },\n {\n name: 'Returns an Object',\n test: `assert.isObject(output) === undefined;`\n },\n {\n name: 'Object has 2 items',\n test: `assert.lengthOf(Object.keys(output), 2) === undefined;`\n },\n {\n name: `First value is false`,\n test: `assert.isFalse(output.evenNumbers) === undefined;`\n },\n {\n name: `Second value is true`,\n test: `assert.isTrue(output.someOddNumbers) === undefined;`\n }\n ]\n }\n // Next problems to create:\n // forEach? fix one above that tried, but can't verify forEach was used\n // some\n // reduce\n // reduceRight\n // Array.from and other ways to turn array-like into array\n];\n","module.exports = [\n {\n name: 'Create Array',\n time: 10,\n prompt: 'Create and return an array that contains \\'apple\\' and \\'banana\\'',\n given: `const fruits = [];\\rreturn fruits;`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.pop()',\n time: 10,\n prompt: `Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n]\n","/*!\n * assertion-error\n * Copyright(c) 2013 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n var excludes = [].slice.call(arguments);\n\n function excludeProps (res, obj) {\n Object.keys(obj).forEach(function (key) {\n if (!~excludes.indexOf(key)) res[key] = obj[key];\n });\n }\n\n return function extendExclude () {\n var args = [].slice.call(arguments)\n , i = 0\n , res = {};\n\n for (; i < args.length; i++) {\n excludeProps(res, args[i]);\n }\n\n return res;\n };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n , props = extend(_props || {});\n\n // default values\n this.message = message || 'Unspecified AssertionError';\n this.showDiff = false;\n\n // copy from properties\n for (var key in props) {\n this[key] = props[key];\n }\n\n // capture stack trace\n ssf = ssf || arguments.callee;\n if (ssf && Error.captureStackTrace) {\n Error.captureStackTrace(this, ssf);\n } else {\n try {\n throw new Error();\n } catch(e) {\n this.stack = e.stack;\n }\n }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n var extend = exclude('constructor', 'toJSON', 'stack')\n , props = extend({ name: this.name }, this);\n\n // include stack if exists and not turned off\n if (false !== stack && this.stack) {\n props.stack = this.stack;\n }\n\n return props;\n};\n","module.exports = require('./lib/chai');\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar used = []\n , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n if (!~used.indexOf(fn)) {\n fn(this, util);\n used.push(fn);\n }\n\n return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n /*!\n * Module dependencies.\n */\n\n var AssertionError = _chai.AssertionError\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n _chai.Assertion = Assertion;\n\n /*!\n * Assertion Constructor\n *\n * Creates object for chaining.\n *\n * @api private\n */\n\n function Assertion (obj, msg, stack) {\n flag(this, 'ssfi', stack || arguments.callee);\n flag(this, 'object', obj);\n flag(this, 'message', msg);\n }\n\n Object.defineProperty(Assertion, 'includeStack', {\n get: function() {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n return config.includeStack;\n },\n set: function(value) {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n config.includeStack = value;\n }\n });\n\n Object.defineProperty(Assertion, 'showDiff', {\n get: function() {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n return config.showDiff;\n },\n set: function(value) {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n config.showDiff = value;\n }\n });\n\n Assertion.addProperty = function (name, fn) {\n util.addProperty(this.prototype, name, fn);\n };\n\n Assertion.addMethod = function (name, fn) {\n util.addMethod(this.prototype, name, fn);\n };\n\n Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n Assertion.overwriteProperty = function (name, fn) {\n util.overwriteProperty(this.prototype, name, fn);\n };\n\n Assertion.overwriteMethod = function (name, fn) {\n util.overwriteMethod(this.prototype, name, fn);\n };\n\n Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n /**\n * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n *\n * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n *\n * @name assert\n * @param {Philosophical} expression to be tested\n * @param {String|Function} message or function that returns message to display if expression fails\n * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n * @param {Mixed} expected value (remember to check for negation)\n * @param {Mixed} actual (optional) will default to `this.obj`\n * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n * @api private\n */\n\n Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n var ok = util.test(this, arguments);\n if (true !== showDiff) showDiff = false;\n if (true !== config.showDiff) showDiff = false;\n\n if (!ok) {\n var msg = util.getMessage(this, arguments)\n , actual = util.getActual(this, arguments);\n throw new AssertionError(msg, {\n actual: actual\n , expected: expected\n , showDiff: showDiff\n }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n }\n };\n\n /*!\n * ### ._obj\n *\n * Quick reference to stored `actual` value for plugin developers.\n *\n * @api private\n */\n\n Object.defineProperty(Assertion.prototype, '_obj',\n { get: function () {\n return flag(this, 'object');\n }\n , set: function (val) {\n flag(this, 'object', val);\n }\n });\n};\n","module.exports = {\n\n /**\n * ### config.includeStack\n *\n * User configurable property, influences whether stack trace\n * is included in Assertion error message. Default of false\n * suppresses stack trace in the error message.\n *\n * chai.config.includeStack = true; // enable stack on error\n *\n * @param {Boolean}\n * @api public\n */\n\n includeStack: false,\n\n /**\n * ### config.showDiff\n *\n * User configurable property, influences whether or not\n * the `showDiff` flag should be included in the thrown\n * AssertionErrors. `false` will always be `false`; `true`\n * will be true when the assertion has requested a diff\n * be shown.\n *\n * @param {Boolean}\n * @api public\n */\n\n showDiff: true,\n\n /**\n * ### config.truncateThreshold\n *\n * User configurable property, sets length threshold for actual and\n * expected values in assertion errors. If this threshold is exceeded, for\n * example for large data structures, the value is replaced with something\n * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n *\n * Set it to zero if you want to disable truncating altogether.\n *\n * This is especially userful when doing assertions on arrays: having this\n * set to a reasonable large value makes the failure messages readily\n * inspectable.\n *\n * chai.config.truncateThreshold = 0; // disable truncating\n *\n * @param {Number}\n * @api public\n */\n\n truncateThreshold: 40\n\n};\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n var Assertion = chai.Assertion\n , toString = Object.prototype.toString\n , flag = _.flag;\n\n /**\n * ### Language Chains\n *\n * The following are provided as chainable getters to\n * improve the readability of your assertions. They\n * do not provide testing capabilities unless they\n * have been overwritten by a plugin.\n *\n * **Chains**\n *\n * - to\n * - be\n * - been\n * - is\n * - that\n * - which\n * - and\n * - has\n * - have\n * - with\n * - at\n * - of\n * - same\n *\n * @name language chains\n * @namespace BDD\n * @api public\n */\n\n [ 'to', 'be', 'been'\n , 'is', 'and', 'has', 'have'\n , 'with', 'that', 'which', 'at'\n , 'of', 'same' ].forEach(function (chain) {\n Assertion.addProperty(chain, function () {\n return this;\n });\n });\n\n /**\n * ### .not\n *\n * Negates any of assertions following in the chain.\n *\n * expect(foo).to.not.equal('bar');\n * expect(goodFn).to.not.throw(Error);\n * expect({ foo: 'baz' }).to.have.property('foo')\n * .and.not.equal('bar');\n *\n * @name not\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('not', function () {\n flag(this, 'negate', true);\n });\n\n /**\n * ### .deep\n *\n * Sets the `deep` flag, later used by the `equal` and\n * `property` assertions.\n *\n * expect(foo).to.deep.equal({ bar: 'baz' });\n * expect({ foo: { bar: { baz: 'quux' } } })\n * .to.have.deep.property('foo.bar.baz', 'quux');\n *\n * `.deep.property` special characters can be escaped\n * by adding two slashes before the `.` or `[]`.\n *\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name deep\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('deep', function () {\n flag(this, 'deep', true);\n });\n\n /**\n * ### .any\n *\n * Sets the `any` flag, (opposite of the `all` flag)\n * later used in the `keys` assertion.\n *\n * expect(foo).to.have.any.keys('bar', 'baz');\n *\n * @name any\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('any', function () {\n flag(this, 'any', true);\n flag(this, 'all', false)\n });\n\n\n /**\n * ### .all\n *\n * Sets the `all` flag (opposite of the `any` flag)\n * later used by the `keys` assertion.\n *\n * expect(foo).to.have.all.keys('bar', 'baz');\n *\n * @name all\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('all', function () {\n flag(this, 'all', true);\n flag(this, 'any', false);\n });\n\n /**\n * ### .a(type)\n *\n * The `a` and `an` assertions are aliases that can be\n * used either as language chains or to assert a value's\n * type.\n *\n * // typeof\n * expect('test').to.be.a('string');\n * expect({ foo: 'bar' }).to.be.an('object');\n * expect(null).to.be.a('null');\n * expect(undefined).to.be.an('undefined');\n * expect(new Error).to.be.an('error');\n * expect(new Promise).to.be.a('promise');\n * expect(new Float32Array()).to.be.a('float32array');\n * expect(Symbol()).to.be.a('symbol');\n *\n * // es6 overrides\n * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n *\n * // language chain\n * expect(foo).to.be.an.instanceof(Foo);\n *\n * @name a\n * @alias an\n * @param {String} type\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function an (type, msg) {\n if (msg) flag(this, 'message', msg);\n type = type.toLowerCase();\n var obj = flag(this, 'object')\n , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n this.assert(\n type === _.type(obj)\n , 'expected #{this} to be ' + article + type\n , 'expected #{this} not to be ' + article + type\n );\n }\n\n Assertion.addChainableMethod('an', an);\n Assertion.addChainableMethod('a', an);\n\n /**\n * ### .include(value)\n *\n * The `include` and `contain` assertions can be used as either property\n * based language chains or as methods to assert the inclusion of an object\n * in an array or a substring in a string. When used as language chains,\n * they toggle the `contains` flag for the `keys` assertion.\n *\n * expect([1,2,3]).to.include(2);\n * expect('foobar').to.contain('foo');\n * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n *\n * @name include\n * @alias contain\n * @alias includes\n * @alias contains\n * @param {Object|String|Number} obj\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function includeChainingBehavior () {\n flag(this, 'contains', true);\n }\n\n function include (val, msg) {\n _.expectTypes(this, ['array', 'object', 'string']);\n\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var expected = false;\n\n if (_.type(obj) === 'array' && _.type(val) === 'object') {\n for (var i in obj) {\n if (_.eql(obj[i], val)) {\n expected = true;\n break;\n }\n }\n } else if (_.type(val) === 'object') {\n if (!flag(this, 'negate')) {\n for (var k in val) new Assertion(obj).property(k, val[k]);\n return;\n }\n var subset = {};\n for (var k in val) subset[k] = obj[k];\n expected = _.eql(subset, val);\n } else {\n expected = (obj != undefined) && ~obj.indexOf(val);\n }\n this.assert(\n expected\n , 'expected #{this} to include ' + _.inspect(val)\n , 'expected #{this} to not include ' + _.inspect(val));\n }\n\n Assertion.addChainableMethod('include', include, includeChainingBehavior);\n Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n /**\n * ### .ok\n *\n * Asserts that the target is truthy.\n *\n * expect('everything').to.be.ok;\n * expect(1).to.be.ok;\n * expect(false).to.not.be.ok;\n * expect(undefined).to.not.be.ok;\n * expect(null).to.not.be.ok;\n *\n * @name ok\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('ok', function () {\n this.assert(\n flag(this, 'object')\n , 'expected #{this} to be truthy'\n , 'expected #{this} to be falsy');\n });\n\n /**\n * ### .true\n *\n * Asserts that the target is `true`.\n *\n * expect(true).to.be.true;\n * expect(1).to.not.be.true;\n *\n * @name true\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('true', function () {\n this.assert(\n true === flag(this, 'object')\n , 'expected #{this} to be true'\n , 'expected #{this} to be false'\n , this.negate ? false : true\n );\n });\n\n /**\n * ### .false\n *\n * Asserts that the target is `false`.\n *\n * expect(false).to.be.false;\n * expect(0).to.not.be.false;\n *\n * @name false\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('false', function () {\n this.assert(\n false === flag(this, 'object')\n , 'expected #{this} to be false'\n , 'expected #{this} to be true'\n , this.negate ? true : false\n );\n });\n\n /**\n * ### .null\n *\n * Asserts that the target is `null`.\n *\n * expect(null).to.be.null;\n * expect(undefined).to.not.be.null;\n *\n * @name null\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('null', function () {\n this.assert(\n null === flag(this, 'object')\n , 'expected #{this} to be null'\n , 'expected #{this} not to be null'\n );\n });\n\n /**\n * ### .undefined\n *\n * Asserts that the target is `undefined`.\n *\n * expect(undefined).to.be.undefined;\n * expect(null).to.not.be.undefined;\n *\n * @name undefined\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('undefined', function () {\n this.assert(\n undefined === flag(this, 'object')\n , 'expected #{this} to be undefined'\n , 'expected #{this} not to be undefined'\n );\n });\n\n /**\n * ### .NaN\n * Asserts that the target is `NaN`.\n *\n * expect('foo').to.be.NaN;\n * expect(4).not.to.be.NaN;\n *\n * @name NaN\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('NaN', function () {\n this.assert(\n isNaN(flag(this, 'object'))\n , 'expected #{this} to be NaN'\n , 'expected #{this} not to be NaN'\n );\n });\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi'\n * , bar = null\n * , baz;\n *\n * expect(foo).to.exist;\n * expect(bar).to.not.exist;\n * expect(baz).to.not.exist;\n *\n * @name exist\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('exist', function () {\n this.assert(\n null != flag(this, 'object')\n , 'expected #{this} to exist'\n , 'expected #{this} to not exist'\n );\n });\n\n\n /**\n * ### .empty\n *\n * Asserts that the target's length is `0`. For arrays and strings, it checks\n * the `length` property. For objects, it gets the count of\n * enumerable keys.\n *\n * expect([]).to.be.empty;\n * expect('').to.be.empty;\n * expect({}).to.be.empty;\n *\n * @name empty\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('empty', function () {\n var obj = flag(this, 'object')\n , expected = obj;\n\n if (Array.isArray(obj) || 'string' === typeof object) {\n expected = obj.length;\n } else if (typeof obj === 'object') {\n expected = Object.keys(obj).length;\n }\n\n this.assert(\n !expected\n , 'expected #{this} to be empty'\n , 'expected #{this} not to be empty'\n );\n });\n\n /**\n * ### .arguments\n *\n * Asserts that the target is an arguments object.\n *\n * function test () {\n * expect(arguments).to.be.arguments;\n * }\n *\n * @name arguments\n * @alias Arguments\n * @namespace BDD\n * @api public\n */\n\n function checkArguments () {\n var obj = flag(this, 'object')\n , type = Object.prototype.toString.call(obj);\n this.assert(\n '[object Arguments]' === type\n , 'expected #{this} to be arguments but got ' + type\n , 'expected #{this} to not be arguments'\n );\n }\n\n Assertion.addProperty('arguments', checkArguments);\n Assertion.addProperty('Arguments', checkArguments);\n\n /**\n * ### .equal(value)\n *\n * Asserts that the target is strictly equal (`===`) to `value`.\n * Alternately, if the `deep` flag is set, asserts that\n * the target is deeply equal to `value`.\n *\n * expect('hello').to.equal('hello');\n * expect(42).to.equal(42);\n * expect(1).to.not.equal(true);\n * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n *\n * @name equal\n * @alias equals\n * @alias eq\n * @alias deep.equal\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEqual (val, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'deep')) {\n return this.eql(val);\n } else {\n this.assert(\n val === obj\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{exp}'\n , val\n , this._obj\n , true\n );\n }\n }\n\n Assertion.addMethod('equal', assertEqual);\n Assertion.addMethod('equals', assertEqual);\n Assertion.addMethod('eq', assertEqual);\n\n /**\n * ### .eql(value)\n *\n * Asserts that the target is deeply equal to `value`.\n *\n * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n *\n * @name eql\n * @alias eqls\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEql(obj, msg) {\n if (msg) flag(this, 'message', msg);\n this.assert(\n _.eql(obj, flag(this, 'object'))\n , 'expected #{this} to deeply equal #{exp}'\n , 'expected #{this} to not deeply equal #{exp}'\n , obj\n , this._obj\n , true\n );\n }\n\n Assertion.addMethod('eql', assertEql);\n Assertion.addMethod('eqls', assertEql);\n\n /**\n * ### .above(value)\n *\n * Asserts that the target is greater than `value`.\n *\n * expect(10).to.be.above(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n *\n * @name above\n * @alias gt\n * @alias greaterThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertAbove (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len > n\n , 'expected #{this} to have a length above #{exp} but got #{act}'\n , 'expected #{this} to not have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj > n\n , 'expected #{this} to be above ' + n\n , 'expected #{this} to be at most ' + n\n );\n }\n }\n\n Assertion.addMethod('above', assertAbove);\n Assertion.addMethod('gt', assertAbove);\n Assertion.addMethod('greaterThan', assertAbove);\n\n /**\n * ### .least(value)\n *\n * Asserts that the target is greater than or equal to `value`.\n *\n * expect(10).to.be.at.least(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.least(2);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n *\n * @name least\n * @alias gte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLeast (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= n\n , 'expected #{this} to have a length at least #{exp} but got #{act}'\n , 'expected #{this} to have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj >= n\n , 'expected #{this} to be at least ' + n\n , 'expected #{this} to be below ' + n\n );\n }\n }\n\n Assertion.addMethod('least', assertLeast);\n Assertion.addMethod('gte', assertLeast);\n\n /**\n * ### .below(value)\n *\n * Asserts that the target is less than `value`.\n *\n * expect(5).to.be.below(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n *\n * @name below\n * @alias lt\n * @alias lessThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertBelow (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len < n\n , 'expected #{this} to have a length below #{exp} but got #{act}'\n , 'expected #{this} to not have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj < n\n , 'expected #{this} to be below ' + n\n , 'expected #{this} to be at least ' + n\n );\n }\n }\n\n Assertion.addMethod('below', assertBelow);\n Assertion.addMethod('lt', assertBelow);\n Assertion.addMethod('lessThan', assertBelow);\n\n /**\n * ### .most(value)\n *\n * Asserts that the target is less than or equal to `value`.\n *\n * expect(5).to.be.at.most(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.most(4);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n *\n * @name most\n * @alias lte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertMost (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len <= n\n , 'expected #{this} to have a length at most #{exp} but got #{act}'\n , 'expected #{this} to have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj <= n\n , 'expected #{this} to be at most ' + n\n , 'expected #{this} to be above ' + n\n );\n }\n }\n\n Assertion.addMethod('most', assertMost);\n Assertion.addMethod('lte', assertMost);\n\n /**\n * ### .within(start, finish)\n *\n * Asserts that the target is within a range.\n *\n * expect(7).to.be.within(5,10);\n *\n * Can also be used in conjunction with `length` to\n * assert a length range. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * @name within\n * @param {Number} start lowerbound inclusive\n * @param {Number} finish upperbound inclusive\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('within', function (start, finish, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , range = start + '..' + finish;\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= start && len <= finish\n , 'expected #{this} to have a length within ' + range\n , 'expected #{this} to not have a length within ' + range\n );\n } else {\n this.assert(\n obj >= start && obj <= finish\n , 'expected #{this} to be within ' + range\n , 'expected #{this} to not be within ' + range\n );\n }\n });\n\n /**\n * ### .instanceof(constructor)\n *\n * Asserts that the target is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , Chai = new Tea('chai');\n *\n * expect(Chai).to.be.an.instanceof(Tea);\n * expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n *\n * @name instanceof\n * @param {Constructor} constructor\n * @param {String} message _optional_\n * @alias instanceOf\n * @namespace BDD\n * @api public\n */\n\n function assertInstanceOf (constructor, msg) {\n if (msg) flag(this, 'message', msg);\n var name = _.getName(constructor);\n this.assert(\n flag(this, 'object') instanceof constructor\n , 'expected #{this} to be an instance of ' + name\n , 'expected #{this} to not be an instance of ' + name\n );\n };\n\n Assertion.addMethod('instanceof', assertInstanceOf);\n Assertion.addMethod('instanceOf', assertInstanceOf);\n\n /**\n * ### .property(name, [value])\n *\n * Asserts that the target has a property `name`, optionally asserting that\n * the value of that property is strictly equal to `value`.\n * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n * references into objects and arrays.\n *\n * // simple referencing\n * var obj = { foo: 'bar' };\n * expect(obj).to.have.property('foo');\n * expect(obj).to.have.property('foo', 'bar');\n *\n * // deep referencing\n * var deepObj = {\n * green: { tea: 'matcha' }\n * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n * };\n *\n * expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n *\n * You can also use an array as the starting point of a `deep.property`\n * assertion, or traverse nested arrays.\n *\n * var arr = [\n * [ 'chai', 'matcha', 'konacha' ]\n * , [ { tea: 'chai' }\n * , { tea: 'matcha' }\n * , { tea: 'konacha' } ]\n * ];\n *\n * expect(arr).to.have.deep.property('[0][1]', 'matcha');\n * expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n *\n * Furthermore, `property` changes the subject of the assertion\n * to be the value of that property from the original object. This\n * permits for further chainable assertions on that property.\n *\n * expect(obj).to.have.property('foo')\n * .that.is.a('string');\n * expect(deepObj).to.have.property('green')\n * .that.is.an('object')\n * .that.deep.equals({ tea: 'matcha' });\n * expect(deepObj).to.have.property('teas')\n * .that.is.an('array')\n * .with.deep.property('[2]')\n * .that.deep.equals({ tea: 'konacha' });\n *\n * Note that dots and bracket in `name` must be backslash-escaped when\n * the `deep` flag is set, while they must NOT be escaped when the `deep`\n * flag is not set.\n *\n * // simple referencing\n * var css = { '.link[target]': 42 };\n * expect(css).to.have.property('.link[target]', 42);\n *\n * // deep referencing\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name property\n * @alias deep.property\n * @param {String} name\n * @param {Mixed} value (optional)\n * @param {String} message _optional_\n * @returns value of property for chaining\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('property', function (name, val, msg) {\n if (msg) flag(this, 'message', msg);\n\n var isDeep = !!flag(this, 'deep')\n , descriptor = isDeep ? 'deep property ' : 'property '\n , negate = flag(this, 'negate')\n , obj = flag(this, 'object')\n , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n , hasProperty = isDeep\n ? pathInfo.exists\n : _.hasProperty(name, obj)\n , value = isDeep\n ? pathInfo.value\n : obj[name];\n\n if (negate && arguments.length > 1) {\n if (undefined === value) {\n msg = (msg != null) ? msg + ': ' : '';\n throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n }\n } else {\n this.assert(\n hasProperty\n , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n }\n\n if (arguments.length > 1) {\n this.assert(\n val === value\n , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n , val\n , value\n );\n }\n\n flag(this, 'object', value);\n });\n\n\n /**\n * ### .ownProperty(name)\n *\n * Asserts that the target has an own property `name`.\n *\n * expect('test').to.have.ownProperty('length');\n *\n * @name ownProperty\n * @alias haveOwnProperty\n * @param {String} name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnProperty (name, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n obj.hasOwnProperty(name)\n , 'expected #{this} to have own property ' + _.inspect(name)\n , 'expected #{this} to not have own property ' + _.inspect(name)\n );\n }\n\n Assertion.addMethod('ownProperty', assertOwnProperty);\n Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n /**\n * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n *\n * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n *\n * expect('test').to.have.ownPropertyDescriptor('length');\n * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n * expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n *\n * @name ownPropertyDescriptor\n * @alias haveOwnPropertyDescriptor\n * @param {String} name\n * @param {Object} descriptor _optional_\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnPropertyDescriptor (name, descriptor, msg) {\n if (typeof descriptor === 'string') {\n msg = descriptor;\n descriptor = null;\n }\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n if (actualDescriptor && descriptor) {\n this.assert(\n _.eql(descriptor, actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n , descriptor\n , actualDescriptor\n , true\n );\n } else {\n this.assert(\n actualDescriptor\n , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n );\n }\n flag(this, 'object', actualDescriptor);\n }\n\n Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n /**\n * ### .length\n *\n * Sets the `doLength` flag later used as a chain precursor to a value\n * comparison for the `length` property.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * *Deprecation notice:* Using `length` as an assertion will be deprecated\n * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n * asserting for `length` property value using `length(value)` should be\n * switched to use `lengthOf(value)` instead.\n *\n * @name length\n * @namespace BDD\n * @api public\n */\n\n /**\n * ### .lengthOf(value[, message])\n *\n * Asserts that the target's `length` property has\n * the expected value.\n *\n * expect([ 1, 2, 3]).to.have.lengthOf(3);\n * expect('foobar').to.have.lengthOf(6);\n *\n * @name lengthOf\n * @param {Number} length\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLengthChain () {\n flag(this, 'doLength', true);\n }\n\n function assertLength (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n\n this.assert(\n len == n\n , 'expected #{this} to have a length of #{exp} but got #{act}'\n , 'expected #{this} to not have a length of #{act}'\n , n\n , len\n );\n }\n\n Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n Assertion.addMethod('lengthOf', assertLength);\n\n /**\n * ### .match(regexp)\n *\n * Asserts that the target matches a regular expression.\n *\n * expect('foobar').to.match(/^foo/);\n *\n * @name match\n * @alias matches\n * @param {RegExp} RegularExpression\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n function assertMatch(re, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n re.exec(obj)\n , 'expected #{this} to match ' + re\n , 'expected #{this} not to match ' + re\n );\n }\n\n Assertion.addMethod('match', assertMatch);\n Assertion.addMethod('matches', assertMatch);\n\n /**\n * ### .string(string)\n *\n * Asserts that the string target contains another string.\n *\n * expect('foobar').to.have.string('bar');\n *\n * @name string\n * @param {String} string\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('string', function (str, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('string');\n\n this.assert(\n ~obj.indexOf(str)\n , 'expected #{this} to contain ' + _.inspect(str)\n , 'expected #{this} to not contain ' + _.inspect(str)\n );\n });\n\n\n /**\n * ### .keys(key1, [key2], [...])\n *\n * Asserts that the target contains any or all of the passed-in keys.\n * Use in combination with `any`, `all`, `contains`, or `have` will affect\n * what will pass.\n *\n * When used in conjunction with `any`, at least one key that is passed\n * in must exist in the target object. This is regardless whether or not\n * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n * should be used in the assertion. If neither are used, the assertion is\n * defaulted to `all`.\n *\n * When both `all` and `contain` are used, the target object must have at\n * least all of the passed-in keys but may have more keys not listed.\n *\n * When both `all` and `have` are used, the target object must both contain\n * all of the passed-in keys AND the number of keys in the target object must\n * match the number of keys passed in (in other words, a target object must\n * have all and only all of the passed-in keys).\n *\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n *\n *\n * @name keys\n * @alias key\n * @param {...String|Array|Object} keys\n * @namespace BDD\n * @api public\n */\n\n function assertKeys (keys) {\n var obj = flag(this, 'object')\n , str\n , ok = true\n , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n switch (_.type(keys)) {\n case \"array\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n break;\n case \"object\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n keys = Object.keys(keys);\n break;\n default:\n keys = Array.prototype.slice.call(arguments);\n }\n\n if (!keys.length) throw new Error('keys required');\n\n var actual = Object.keys(obj)\n , expected = keys\n , len = keys.length\n , any = flag(this, 'any')\n , all = flag(this, 'all');\n\n if (!any && !all) {\n all = true;\n }\n\n // Has any\n if (any) {\n var intersection = expected.filter(function(key) {\n return ~actual.indexOf(key);\n });\n ok = intersection.length > 0;\n }\n\n // Has all\n if (all) {\n ok = keys.every(function(key){\n return ~actual.indexOf(key);\n });\n if (!flag(this, 'negate') && !flag(this, 'contains')) {\n ok = ok && keys.length == actual.length;\n }\n }\n\n // Key string\n if (len > 1) {\n keys = keys.map(function(key){\n return _.inspect(key);\n });\n var last = keys.pop();\n if (all) {\n str = keys.join(', ') + ', and ' + last;\n }\n if (any) {\n str = keys.join(', ') + ', or ' + last;\n }\n } else {\n str = _.inspect(keys[0]);\n }\n\n // Form\n str = (len > 1 ? 'keys ' : 'key ') + str;\n\n // Have / include\n str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n // Assertion\n this.assert(\n ok\n , 'expected #{this} to ' + str\n , 'expected #{this} to not ' + str\n , expected.slice(0).sort()\n , actual.sort()\n , true\n );\n }\n\n Assertion.addMethod('keys', assertKeys);\n Assertion.addMethod('key', assertKeys);\n\n /**\n * ### .throw(constructor)\n *\n * Asserts that the function target will throw a specific error, or specific type of error\n * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n * for the error's message.\n *\n * var err = new ReferenceError('This is a bad function.');\n * var fn = function () { throw err; }\n * expect(fn).to.throw(ReferenceError);\n * expect(fn).to.throw(Error);\n * expect(fn).to.throw(/bad function/);\n * expect(fn).to.not.throw('good function');\n * expect(fn).to.throw(ReferenceError, /bad function/);\n * expect(fn).to.throw(err);\n *\n * Please note that when a throw expectation is negated, it will check each\n * parameter independently, starting with error constructor type. The appropriate way\n * to check for the existence of a type of error but for a message that does not match\n * is to use `and`.\n *\n * expect(fn).to.throw(ReferenceError)\n * .and.not.throw(/good function/);\n *\n * @name throw\n * @alias throws\n * @alias Throw\n * @param {ErrorConstructor} constructor\n * @param {String|RegExp} expected error message\n * @param {String} message _optional_\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @returns error for chaining (null if no error)\n * @namespace BDD\n * @api public\n */\n\n function assertThrows (constructor, errMsg, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('function');\n\n var thrown = false\n , desiredError = null\n , name = null\n , thrownError = null;\n\n if (arguments.length === 0) {\n errMsg = null;\n constructor = null;\n } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n errMsg = constructor;\n constructor = null;\n } else if (constructor && constructor instanceof Error) {\n desiredError = constructor;\n constructor = null;\n errMsg = null;\n } else if (typeof constructor === 'function') {\n name = constructor.prototype.name;\n if (!name || (name === 'Error' && constructor !== Error)) {\n name = constructor.name || (new constructor()).name;\n }\n } else {\n constructor = null;\n }\n\n try {\n obj();\n } catch (err) {\n // first, check desired error\n if (desiredError) {\n this.assert(\n err === desiredError\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp}'\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (err instanceof Error ? err.toString() : err)\n );\n\n flag(this, 'object', err);\n return this;\n }\n\n // next, check constructor\n if (constructor) {\n this.assert(\n err instanceof constructor\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n , name\n , (err instanceof Error ? err.toString() : err)\n );\n\n if (!errMsg) {\n flag(this, 'object', err);\n return this;\n }\n }\n\n // next, check message\n var message = 'error' === _.type(err) && \"message\" in err\n ? err.message\n : '' + err;\n\n if ((message != null) && errMsg && errMsg instanceof RegExp) {\n this.assert(\n errMsg.exec(message)\n , 'expected #{this} to throw error matching #{exp} but got #{act}'\n , 'expected #{this} to throw error not matching #{exp}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n this.assert(\n ~message.indexOf(errMsg)\n , 'expected #{this} to throw error including #{exp} but got #{act}'\n , 'expected #{this} to throw error not including #{act}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else {\n thrown = true;\n thrownError = err;\n }\n }\n\n var actuallyGot = ''\n , expectedThrown = name !== null\n ? name\n : desiredError\n ? '#{exp}' //_.inspect(desiredError)\n : 'an error';\n\n if (thrown) {\n actuallyGot = ' but #{act} was thrown'\n }\n\n this.assert(\n thrown === true\n , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n );\n\n flag(this, 'object', thrownError);\n };\n\n Assertion.addMethod('throw', assertThrows);\n Assertion.addMethod('throws', assertThrows);\n Assertion.addMethod('Throw', assertThrows);\n\n /**\n * ### .respondTo(method)\n *\n * Asserts that the object or class target will respond to a method.\n *\n * Klass.prototype.bar = function(){};\n * expect(Klass).to.respondTo('bar');\n * expect(obj).to.respondTo('bar');\n *\n * To check if a constructor will respond to a static function,\n * set the `itself` flag.\n *\n * Klass.baz = function(){};\n * expect(Klass).itself.to.respondTo('baz');\n *\n * @name respondTo\n * @alias respondsTo\n * @param {String} method\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function respondTo (method, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , itself = flag(this, 'itself')\n , context = ('function' === _.type(obj) && !itself)\n ? obj.prototype[method]\n : obj[method];\n\n this.assert(\n 'function' === typeof context\n , 'expected #{this} to respond to ' + _.inspect(method)\n , 'expected #{this} to not respond to ' + _.inspect(method)\n );\n }\n\n Assertion.addMethod('respondTo', respondTo);\n Assertion.addMethod('respondsTo', respondTo);\n\n /**\n * ### .itself\n *\n * Sets the `itself` flag, later used by the `respondTo` assertion.\n *\n * function Foo() {}\n * Foo.bar = function() {}\n * Foo.prototype.baz = function() {}\n *\n * expect(Foo).itself.to.respondTo('bar');\n * expect(Foo).itself.not.to.respondTo('baz');\n *\n * @name itself\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('itself', function () {\n flag(this, 'itself', true);\n });\n\n /**\n * ### .satisfy(method)\n *\n * Asserts that the target passes a given truth test.\n *\n * expect(1).to.satisfy(function(num) { return num > 0; });\n *\n * @name satisfy\n * @alias satisfies\n * @param {Function} matcher\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function satisfy (matcher, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var result = matcher(obj);\n this.assert(\n result\n , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n , this.negate ? false : true\n , result\n );\n }\n\n Assertion.addMethod('satisfy', satisfy);\n Assertion.addMethod('satisfies', satisfy);\n\n /**\n * ### .closeTo(expected, delta)\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * expect(1.5).to.be.closeTo(1, 0.5);\n *\n * @name closeTo\n * @alias approximately\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function closeTo(expected, delta, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj, msg).is.a('number');\n if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n throw new Error('the arguments to closeTo or approximately must be numbers');\n }\n\n this.assert(\n Math.abs(obj - expected) <= delta\n , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n );\n }\n\n Assertion.addMethod('closeTo', closeTo);\n Assertion.addMethod('approximately', closeTo);\n\n function isSubsetOf(subset, superset, cmp) {\n return subset.every(function(elem) {\n if (!cmp) return superset.indexOf(elem) !== -1;\n\n return superset.some(function(elem2) {\n return cmp(elem, elem2);\n });\n })\n }\n\n /**\n * ### .members(set)\n *\n * Asserts that the target is a superset of `set`,\n * or that the target and `set` have the same strictly-equal (===) members.\n * Alternately, if the `deep` flag is set, set members are compared for deep\n * equality.\n *\n * expect([1, 2, 3]).to.include.members([3, 2]);\n * expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n *\n * expect([4, 2]).to.have.members([2, 4]);\n * expect([5, 2]).to.not.have.members([5, 2, 1]);\n *\n * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n *\n * @name members\n * @param {Array} set\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('members', function (subset, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj).to.be.an('array');\n new Assertion(subset).to.be.an('array');\n\n var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n if (flag(this, 'contains')) {\n return this.assert(\n isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to be a superset of #{act}'\n , 'expected #{this} to not be a superset of #{act}'\n , obj\n , subset\n );\n }\n\n this.assert(\n isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to have the same members as #{act}'\n , 'expected #{this} to not have the same members as #{act}'\n , obj\n , subset\n );\n });\n\n /**\n * ### .oneOf(list)\n *\n * Assert that a value appears somewhere in the top level of array `list`.\n *\n * expect('a').to.be.oneOf(['a', 'b', 'c']);\n * expect(9).to.not.be.oneOf(['z']);\n * expect([3]).to.not.be.oneOf([1, 2, [3]]);\n *\n * var three = [3];\n * // for object-types, contents are not compared\n * expect(three).to.not.be.oneOf([1, 2, [3]]);\n * // comparing references works\n * expect(three).to.be.oneOf([1, 2, three]);\n *\n * @name oneOf\n * @param {Array<*>} list\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function oneOf (list, msg) {\n if (msg) flag(this, 'message', msg);\n var expected = flag(this, 'object');\n new Assertion(list).to.be.an('array');\n\n this.assert(\n list.indexOf(expected) > -1\n , 'expected #{this} to be one of #{exp}'\n , 'expected #{this} to not be one of #{exp}'\n , list\n , expected\n );\n }\n\n Assertion.addMethod('oneOf', oneOf);\n\n\n /**\n * ### .change(function)\n *\n * Asserts that a function changes an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val += 3 };\n * var noChangeFn = function() { return 'foo' + 'bar'; }\n * expect(fn).to.change(obj, 'val');\n * expect(noChangeFn).to.not.change(obj, 'val')\n *\n * @name change\n * @alias changes\n * @alias Change\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertChanges (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n initial !== object[prop]\n , 'expected .' + prop + ' to change'\n , 'expected .' + prop + ' to not change'\n );\n }\n\n Assertion.addChainableMethod('change', assertChanges);\n Assertion.addChainableMethod('changes', assertChanges);\n\n /**\n * ### .increase(function)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * expect(fn).to.increase(obj, 'val');\n *\n * @name increase\n * @alias increases\n * @alias Increase\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertIncreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial > 0\n , 'expected .' + prop + ' to increase'\n , 'expected .' + prop + ' to not increase'\n );\n }\n\n Assertion.addChainableMethod('increase', assertIncreases);\n Assertion.addChainableMethod('increases', assertIncreases);\n\n /**\n * ### .decrease(function)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * expect(fn).to.decrease(obj, 'val');\n *\n * @name decrease\n * @alias decreases\n * @alias Decrease\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertDecreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial < 0\n , 'expected .' + prop + ' to decrease'\n , 'expected .' + prop + ' to not decrease'\n );\n }\n\n Assertion.addChainableMethod('decrease', assertDecreases);\n Assertion.addChainableMethod('decreases', assertDecreases);\n\n /**\n * ### .extensible\n *\n * Asserts that the target is extensible (can have new properties added to\n * it).\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect({}).to.be.extensible;\n * expect(nonExtensibleObject).to.not.be.extensible;\n * expect(sealedObject).to.not.be.extensible;\n * expect(frozenObject).to.not.be.extensible;\n *\n * @name extensible\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('extensible', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isExtensible;\n\n try {\n isExtensible = Object.isExtensible(obj);\n } catch (err) {\n if (err instanceof TypeError) isExtensible = false;\n else throw err;\n }\n\n this.assert(\n isExtensible\n , 'expected #{this} to be extensible'\n , 'expected #{this} to not be extensible'\n );\n });\n\n /**\n * ### .sealed\n *\n * Asserts that the target is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect(sealedObject).to.be.sealed;\n * expect(frozenObject).to.be.sealed;\n * expect({}).to.not.be.sealed;\n *\n * @name sealed\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('sealed', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isSealed;\n\n try {\n isSealed = Object.isSealed(obj);\n } catch (err) {\n if (err instanceof TypeError) isSealed = true;\n else throw err;\n }\n\n this.assert(\n isSealed\n , 'expected #{this} to be sealed'\n , 'expected #{this} to not be sealed'\n );\n });\n\n /**\n * ### .frozen\n *\n * Asserts that the target is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n *\n * expect(frozenObject).to.be.frozen;\n * expect({}).to.not.be.frozen;\n *\n * @name frozen\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('frozen', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isFrozen;\n\n try {\n isFrozen = Object.isFrozen(obj);\n } catch (err) {\n if (err instanceof TypeError) isFrozen = true;\n else throw err;\n }\n\n this.assert(\n isFrozen\n , 'expected #{this} to be frozen'\n , 'expected #{this} to not be frozen'\n );\n });\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n /*!\n * Chai dependencies.\n */\n\n var Assertion = chai.Assertion\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n /**\n * ### assert(expression, message)\n *\n * Write your own test expressions.\n *\n * assert('foo' !== 'bar', 'foo is not bar');\n * assert(Array.isArray([]), 'empty arrays are arrays');\n *\n * @param {Mixed} expression to test for truthiness\n * @param {String} message to display on error\n * @name assert\n * @namespace Assert\n * @api public\n */\n\n var assert = chai.assert = function (express, errmsg) {\n var test = new Assertion(null, null, chai.assert);\n test.assert(\n express\n , errmsg\n , '[ negation message unavailable ]'\n );\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure. Node.js `assert` module-compatible.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Assert\n * @api public\n */\n\n assert.fail = function (actual, expected, message, operator) {\n message = message || 'assert.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, assert.fail);\n };\n\n /**\n * ### .isOk(object, [message])\n *\n * Asserts that `object` is truthy.\n *\n * assert.isOk('everything', 'everything is ok');\n * assert.isOk(false, 'this will fail');\n *\n * @name isOk\n * @alias ok\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isOk = function (val, msg) {\n new Assertion(val, msg).is.ok;\n };\n\n /**\n * ### .isNotOk(object, [message])\n *\n * Asserts that `object` is falsy.\n *\n * assert.isNotOk('everything', 'this will fail');\n * assert.isNotOk(false, 'this will pass');\n *\n * @name isNotOk\n * @alias notOk\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotOk = function (val, msg) {\n new Assertion(val, msg).is.not.ok;\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * assert.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.equal = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.equal);\n\n test.assert(\n exp == flag(test, 'object')\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .notEqual(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * assert.notEqual(3, 4, 'these numbers are not equal');\n *\n * @name notEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notEqual = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.notEqual);\n\n test.assert(\n exp != flag(test, 'object')\n , 'expected #{this} to not equal #{exp}'\n , 'expected #{this} to equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .strictEqual(actual, expected, [message])\n *\n * Asserts strict equality (`===`) of `actual` and `expected`.\n *\n * assert.strictEqual(true, true, 'these booleans are strictly equal');\n *\n * @name strictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.strictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.equal(exp);\n };\n\n /**\n * ### .notStrictEqual(actual, expected, [message])\n *\n * Asserts strict inequality (`!==`) of `actual` and `expected`.\n *\n * assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n *\n * @name notStrictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notStrictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.equal(exp);\n };\n\n /**\n * ### .deepEqual(actual, expected, [message])\n *\n * Asserts that `actual` is deeply equal to `expected`.\n *\n * assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n *\n * @name deepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.eql(exp);\n };\n\n /**\n * ### .notDeepEqual(actual, expected, [message])\n *\n * Assert that `actual` is not deeply equal to `expected`.\n *\n * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n *\n * @name notDeepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.eql(exp);\n };\n\n /**\n * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n *\n * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n *\n * assert.isAbove(5, 2, '5 is strictly greater than 2');\n *\n * @name isAbove\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAbove\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAbove = function (val, abv, msg) {\n new Assertion(val, msg).to.be.above(abv);\n };\n\n /**\n * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n *\n * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n *\n * assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n * assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n *\n * @name isAtLeast\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtLeast\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtLeast = function (val, atlst, msg) {\n new Assertion(val, msg).to.be.least(atlst);\n };\n\n /**\n * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n *\n * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n *\n * assert.isBelow(3, 6, '3 is strictly less than 6');\n *\n * @name isBelow\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeBelow\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBelow = function (val, blw, msg) {\n new Assertion(val, msg).to.be.below(blw);\n };\n\n /**\n * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n *\n * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n *\n * assert.isAtMost(3, 6, '3 is less than or equal to 6');\n * assert.isAtMost(4, 4, '4 is less than or equal to 4');\n *\n * @name isAtMost\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtMost\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtMost = function (val, atmst, msg) {\n new Assertion(val, msg).to.be.most(atmst);\n };\n\n /**\n * ### .isTrue(value, [message])\n *\n * Asserts that `value` is true.\n *\n * var teaServed = true;\n * assert.isTrue(teaServed, 'the tea has been served');\n *\n * @name isTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isTrue = function (val, msg) {\n new Assertion(val, msg).is['true'];\n };\n\n /**\n * ### .isNotTrue(value, [message])\n *\n * Asserts that `value` is not true.\n *\n * var tea = 'tasty chai';\n * assert.isNotTrue(tea, 'great, time for tea!');\n *\n * @name isNotTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotTrue = function (val, msg) {\n new Assertion(val, msg).to.not.equal(true);\n };\n\n /**\n * ### .isFalse(value, [message])\n *\n * Asserts that `value` is false.\n *\n * var teaServed = false;\n * assert.isFalse(teaServed, 'no tea yet? hmm...');\n *\n * @name isFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFalse = function (val, msg) {\n new Assertion(val, msg).is['false'];\n };\n\n /**\n * ### .isNotFalse(value, [message])\n *\n * Asserts that `value` is not false.\n *\n * var tea = 'tasty chai';\n * assert.isNotFalse(tea, 'great, time for tea!');\n *\n * @name isNotFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFalse = function (val, msg) {\n new Assertion(val, msg).to.not.equal(false);\n };\n\n /**\n * ### .isNull(value, [message])\n *\n * Asserts that `value` is null.\n *\n * assert.isNull(err, 'there was no error');\n *\n * @name isNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNull = function (val, msg) {\n new Assertion(val, msg).to.equal(null);\n };\n\n /**\n * ### .isNotNull(value, [message])\n *\n * Asserts that `value` is not null.\n *\n * var tea = 'tasty chai';\n * assert.isNotNull(tea, 'great, time for tea!');\n *\n * @name isNotNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNull = function (val, msg) {\n new Assertion(val, msg).to.not.equal(null);\n };\n\n /**\n * ### .isNaN\n * Asserts that value is NaN\n *\n * assert.isNaN('foo', 'foo is NaN');\n *\n * @name isNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNaN = function (val, msg) {\n new Assertion(val, msg).to.be.NaN;\n };\n\n /**\n * ### .isNotNaN\n * Asserts that value is not NaN\n *\n * assert.isNotNaN(4, '4 is not NaN');\n *\n * @name isNotNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n assert.isNotNaN = function (val, msg) {\n new Assertion(val, msg).not.to.be.NaN;\n };\n\n /**\n * ### .isUndefined(value, [message])\n *\n * Asserts that `value` is `undefined`.\n *\n * var tea;\n * assert.isUndefined(tea, 'no tea defined');\n *\n * @name isUndefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isUndefined = function (val, msg) {\n new Assertion(val, msg).to.equal(undefined);\n };\n\n /**\n * ### .isDefined(value, [message])\n *\n * Asserts that `value` is not `undefined`.\n *\n * var tea = 'cup of chai';\n * assert.isDefined(tea, 'tea has been defined');\n *\n * @name isDefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isDefined = function (val, msg) {\n new Assertion(val, msg).to.not.equal(undefined);\n };\n\n /**\n * ### .isFunction(value, [message])\n *\n * Asserts that `value` is a function.\n *\n * function serveTea() { return 'cup of tea'; };\n * assert.isFunction(serveTea, 'great, we can have tea now');\n *\n * @name isFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFunction = function (val, msg) {\n new Assertion(val, msg).to.be.a('function');\n };\n\n /**\n * ### .isNotFunction(value, [message])\n *\n * Asserts that `value` is _not_ a function.\n *\n * var serveTea = [ 'heat', 'pour', 'sip' ];\n * assert.isNotFunction(serveTea, 'great, we have listed the steps');\n *\n * @name isNotFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFunction = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('function');\n };\n\n /**\n * ### .isObject(value, [message])\n *\n * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n * _The assertion does not match subclassed objects._\n *\n * var selection = { name: 'Chai', serve: 'with spices' };\n * assert.isObject(selection, 'tea selection is an object');\n *\n * @name isObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isObject = function (val, msg) {\n new Assertion(val, msg).to.be.a('object');\n };\n\n /**\n * ### .isNotObject(value, [message])\n *\n * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n *\n * var selection = 'chai'\n * assert.isNotObject(selection, 'tea selection is not an object');\n * assert.isNotObject(null, 'null is not an object');\n *\n * @name isNotObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotObject = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('object');\n };\n\n /**\n * ### .isArray(value, [message])\n *\n * Asserts that `value` is an array.\n *\n * var menu = [ 'green', 'chai', 'oolong' ];\n * assert.isArray(menu, 'what kind of tea do we want?');\n *\n * @name isArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isArray = function (val, msg) {\n new Assertion(val, msg).to.be.an('array');\n };\n\n /**\n * ### .isNotArray(value, [message])\n *\n * Asserts that `value` is _not_ an array.\n *\n * var menu = 'green|chai|oolong';\n * assert.isNotArray(menu, 'what kind of tea do we want?');\n *\n * @name isNotArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotArray = function (val, msg) {\n new Assertion(val, msg).to.not.be.an('array');\n };\n\n /**\n * ### .isString(value, [message])\n *\n * Asserts that `value` is a string.\n *\n * var teaOrder = 'chai';\n * assert.isString(teaOrder, 'order placed');\n *\n * @name isString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isString = function (val, msg) {\n new Assertion(val, msg).to.be.a('string');\n };\n\n /**\n * ### .isNotString(value, [message])\n *\n * Asserts that `value` is _not_ a string.\n *\n * var teaOrder = 4;\n * assert.isNotString(teaOrder, 'order placed');\n *\n * @name isNotString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotString = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('string');\n };\n\n /**\n * ### .isNumber(value, [message])\n *\n * Asserts that `value` is a number.\n *\n * var cups = 2;\n * assert.isNumber(cups, 'how many cups');\n *\n * @name isNumber\n * @param {Number} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNumber = function (val, msg) {\n new Assertion(val, msg).to.be.a('number');\n };\n\n /**\n * ### .isNotNumber(value, [message])\n *\n * Asserts that `value` is _not_ a number.\n *\n * var cups = '2 cups please';\n * assert.isNotNumber(cups, 'how many cups');\n *\n * @name isNotNumber\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNumber = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('number');\n };\n\n /**\n * ### .isBoolean(value, [message])\n *\n * Asserts that `value` is a boolean.\n *\n * var teaReady = true\n * , teaServed = false;\n *\n * assert.isBoolean(teaReady, 'is the tea ready');\n * assert.isBoolean(teaServed, 'has tea been served');\n *\n * @name isBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBoolean = function (val, msg) {\n new Assertion(val, msg).to.be.a('boolean');\n };\n\n /**\n * ### .isNotBoolean(value, [message])\n *\n * Asserts that `value` is _not_ a boolean.\n *\n * var teaReady = 'yep'\n * , teaServed = 'nope';\n *\n * assert.isNotBoolean(teaReady, 'is the tea ready');\n * assert.isNotBoolean(teaServed, 'has tea been served');\n *\n * @name isNotBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotBoolean = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('boolean');\n };\n\n /**\n * ### .typeOf(value, name, [message])\n *\n * Asserts that `value`'s type is `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n * assert.typeOf('tea', 'string', 'we have a string');\n * assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n * assert.typeOf(null, 'null', 'we have a null');\n * assert.typeOf(undefined, 'undefined', 'we have an undefined');\n *\n * @name typeOf\n * @param {Mixed} value\n * @param {String} name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.typeOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.a(type);\n };\n\n /**\n * ### .notTypeOf(value, name, [message])\n *\n * Asserts that `value`'s type is _not_ `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.notTypeOf('tea', 'number', 'strings are not numbers');\n *\n * @name notTypeOf\n * @param {Mixed} value\n * @param {String} typeof name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notTypeOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.a(type);\n };\n\n /**\n * ### .instanceOf(object, constructor, [message])\n *\n * Asserts that `value` is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new Tea('chai');\n *\n * assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n *\n * @name instanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.instanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.instanceOf(type);\n };\n\n /**\n * ### .notInstanceOf(object, constructor, [message])\n *\n * Asserts `value` is not an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new String('chai');\n *\n * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n *\n * @name notInstanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInstanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.instanceOf(type);\n };\n\n /**\n * ### .include(haystack, needle, [message])\n *\n * Asserts that `haystack` includes `needle`. Works\n * for strings and arrays.\n *\n * assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n * assert.include([ 1, 2, 3 ], 3, 'array contains value');\n *\n * @name include\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.include = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.include).include(inc);\n };\n\n /**\n * ### .notInclude(haystack, needle, [message])\n *\n * Asserts that `haystack` does not include `needle`. Works\n * for strings and arrays.\n *\n * assert.notInclude('foobar', 'baz', 'string not include substring');\n * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n *\n * @name notInclude\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInclude = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.notInclude).not.include(inc);\n };\n\n /**\n * ### .match(value, regexp, [message])\n *\n * Asserts that `value` matches the regular expression `regexp`.\n *\n * assert.match('foobar', /^foo/, 'regexp matches');\n *\n * @name match\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.match = function (exp, re, msg) {\n new Assertion(exp, msg).to.match(re);\n };\n\n /**\n * ### .notMatch(value, regexp, [message])\n *\n * Asserts that `value` does not match the regular expression `regexp`.\n *\n * assert.notMatch('foobar', /^foo/, 'regexp does not match');\n *\n * @name notMatch\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notMatch = function (exp, re, msg) {\n new Assertion(exp, msg).to.not.match(re);\n };\n\n /**\n * ### .property(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`.\n *\n * assert.property({ tea: { green: 'matcha' }}, 'tea');\n *\n * @name property\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.property = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.property(prop);\n };\n\n /**\n * ### .notProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`.\n *\n * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n *\n * @name notProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.property(prop);\n };\n\n /**\n * ### .deepProperty(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`, which can be a\n * string using dot- and bracket-notation for deep reference.\n *\n * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n *\n * @name deepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop);\n };\n\n /**\n * ### .notDeepProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`, which\n * can be a string using dot- and bracket-notation for deep reference.\n *\n * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n *\n * @name notDeepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop);\n };\n\n /**\n * ### .propertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`.\n *\n * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n *\n * @name propertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.property(prop, val);\n };\n\n /**\n * ### .propertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`.\n *\n * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n *\n * @name propertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.property(prop, val);\n };\n\n /**\n * ### .deepPropertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`. `property` can use dot- and bracket-notation for deep\n * reference.\n *\n * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n *\n * @name deepPropertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop, val);\n };\n\n /**\n * ### .deepPropertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`. `property` can use dot- and\n * bracket-notation for deep reference.\n *\n * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n *\n * @name deepPropertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n };\n\n /**\n * ### .lengthOf(object, length, [message])\n *\n * Asserts that `object` has a `length` property with the expected value.\n *\n * assert.lengthOf([1,2,3], 3, 'array has length of 3');\n * assert.lengthOf('foobar', 6, 'string has length of 6');\n *\n * @name lengthOf\n * @param {Mixed} object\n * @param {Number} length\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.lengthOf = function (exp, len, msg) {\n new Assertion(exp, msg).to.have.length(len);\n };\n\n /**\n * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * assert.throws(fn, 'function throws a reference error');\n * assert.throws(fn, /function throws a reference error/);\n * assert.throws(fn, ReferenceError);\n * assert.throws(fn, ReferenceError, 'function throws a reference error');\n * assert.throws(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throws\n * @alias throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.throws = function (fn, errt, errs, msg) {\n if ('string' === typeof errt || errt instanceof RegExp) {\n errs = errt;\n errt = null;\n }\n\n var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n return flag(assertErr, 'object');\n };\n\n /**\n * ### .doesNotThrow(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * assert.doesNotThrow(fn, Error, 'function does not throw');\n *\n * @name doesNotThrow\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotThrow = function (fn, type, msg) {\n if ('string' === typeof type) {\n msg = type;\n type = null;\n }\n\n new Assertion(fn, msg).to.not.Throw(type);\n };\n\n /**\n * ### .operator(val1, operator, val2, [message])\n *\n * Compares two values using `operator`.\n *\n * assert.operator(1, '<', 2, 'everything is ok');\n * assert.operator(1, '>', 2, 'this will fail');\n *\n * @name operator\n * @param {Mixed} val1\n * @param {String} operator\n * @param {Mixed} val2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.operator = function (val, operator, val2, msg) {\n var ok;\n switch(operator) {\n case '==':\n ok = val == val2;\n break;\n case '===':\n ok = val === val2;\n break;\n case '>':\n ok = val > val2;\n break;\n case '>=':\n ok = val >= val2;\n break;\n case '<':\n ok = val < val2;\n break;\n case '<=':\n ok = val <= val2;\n break;\n case '!=':\n ok = val != val2;\n break;\n case '!==':\n ok = val !== val2;\n break;\n default:\n throw new Error('Invalid operator \"' + operator + '\"');\n }\n var test = new Assertion(ok, msg);\n test.assert(\n true === flag(test, 'object')\n , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n };\n\n /**\n * ### .closeTo(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n *\n * @name closeTo\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.closeTo = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.closeTo(exp, delta);\n };\n\n /**\n * ### .approximately(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.approximately(1.5, 1, 0.5, 'numbers are close');\n *\n * @name approximately\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.approximately = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.approximately(exp, delta);\n };\n\n /**\n * ### .sameMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members.\n * Order is not taken into account.\n *\n * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n *\n * @name sameMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.members(set2);\n }\n\n /**\n * ### .sameDeepMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n * Order is not taken into account.\n *\n * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n *\n * @name sameDeepMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameDeepMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.deep.members(set2);\n }\n\n /**\n * ### .includeMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset`.\n * Order is not taken into account.\n *\n * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n *\n * @name includeMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.members(subset);\n }\n\n /**\n * ### .includeDeepMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset` - using deep equality checking.\n * Order is not taken into account.\n * Duplicates are ignored.\n *\n * assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n *\n * @name includeDeepMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeDeepMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.deep.members(subset);\n }\n\n /**\n * ### .oneOf(inList, list, [message])\n *\n * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n *\n * assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n *\n * @name oneOf\n * @param {*} inList\n * @param {Array<*>} list\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.oneOf = function (inList, list, msg) {\n new Assertion(inList, msg).to.be.oneOf(list);\n }\n\n /**\n * ### .changes(function, object, property)\n *\n * Asserts that a function changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 22 };\n * assert.changes(fn, obj, 'val');\n *\n * @name changes\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.changes = function (fn, obj, prop) {\n new Assertion(fn).to.change(obj, prop);\n }\n\n /**\n * ### .doesNotChange(function, object, property)\n *\n * Asserts that a function does not changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { console.log('foo'); };\n * assert.doesNotChange(fn, obj, 'val');\n *\n * @name doesNotChange\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotChange = function (fn, obj, prop) {\n new Assertion(fn).to.not.change(obj, prop);\n }\n\n /**\n * ### .increases(function, object, property)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 13 };\n * assert.increases(fn, obj, 'val');\n *\n * @name increases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.increases = function (fn, obj, prop) {\n new Assertion(fn).to.increase(obj, prop);\n }\n\n /**\n * ### .doesNotIncrease(function, object, property)\n *\n * Asserts that a function does not increase object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 8 };\n * assert.doesNotIncrease(fn, obj, 'val');\n *\n * @name doesNotIncrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotIncrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.increase(obj, prop);\n }\n\n /**\n * ### .decreases(function, object, property)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * assert.decreases(fn, obj, 'val');\n *\n * @name decreases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.decreases = function (fn, obj, prop) {\n new Assertion(fn).to.decrease(obj, prop);\n }\n\n /**\n * ### .doesNotDecrease(function, object, property)\n *\n * Asserts that a function does not decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * assert.doesNotDecrease(fn, obj, 'val');\n *\n * @name doesNotDecrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotDecrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.decrease(obj, prop);\n }\n\n /*!\n * ### .ifError(object)\n *\n * Asserts if value is not a false value, and throws if it is a true value.\n * This is added to allow for chai to be a drop-in replacement for Node's\n * assert class.\n *\n * var err = new Error('I am a custom error');\n * assert.ifError(err); // Rethrows err!\n *\n * @name ifError\n * @param {Object} object\n * @namespace Assert\n * @api public\n */\n\n assert.ifError = function (val) {\n if (val) {\n throw(val);\n }\n };\n\n /**\n * ### .isExtensible(object)\n *\n * Asserts that `object` is extensible (can have new properties added to it).\n *\n * assert.isExtensible({});\n *\n * @name isExtensible\n * @alias extensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.be.extensible;\n };\n\n /**\n * ### .isNotExtensible(object)\n *\n * Asserts that `object` is _not_ extensible.\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freese({});\n *\n * assert.isNotExtensible(nonExtensibleObject);\n * assert.isNotExtensible(sealedObject);\n * assert.isNotExtensible(frozenObject);\n *\n * @name isNotExtensible\n * @alias notExtensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.extensible;\n };\n\n /**\n * ### .isSealed(object)\n *\n * Asserts that `object` is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.seal({});\n *\n * assert.isSealed(sealedObject);\n * assert.isSealed(frozenObject);\n *\n * @name isSealed\n * @alias sealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isSealed = function (obj, msg) {\n new Assertion(obj, msg).to.be.sealed;\n };\n\n /**\n * ### .isNotSealed(object)\n *\n * Asserts that `object` is _not_ sealed.\n *\n * assert.isNotSealed({});\n *\n * @name isNotSealed\n * @alias notSealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotSealed = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.sealed;\n };\n\n /**\n * ### .isFrozen(object)\n *\n * Asserts that `object` is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n * assert.frozen(frozenObject);\n *\n * @name isFrozen\n * @alias frozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.be.frozen;\n };\n\n /**\n * ### .isNotFrozen(object)\n *\n * Asserts that `object` is _not_ frozen.\n *\n * assert.isNotFrozen({});\n *\n * @name isNotFrozen\n * @alias notFrozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.frozen;\n };\n\n /*!\n * Aliases.\n */\n\n (function alias(name, as){\n assert[as] = assert[name];\n return alias;\n })\n ('isOk', 'ok')\n ('isNotOk', 'notOk')\n ('throws', 'throw')\n ('throws', 'Throw')\n ('isExtensible', 'extensible')\n ('isNotExtensible', 'notExtensible')\n ('isSealed', 'sealed')\n ('isNotSealed', 'notSealed')\n ('isFrozen', 'frozen')\n ('isNotFrozen', 'notFrozen');\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n chai.expect = function (val, message) {\n return new chai.Assertion(val, message);\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Expect\n * @api public\n */\n\n chai.expect.fail = function (actual, expected, message, operator) {\n message = message || 'expect.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, chai.expect.fail);\n };\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n var Assertion = chai.Assertion;\n\n function loadShould () {\n // explicitly define this method as function as to have it's name to include as `ssfi`\n function shouldGetter() {\n if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n return new Assertion(this.valueOf(), null, shouldGetter);\n }\n return new Assertion(this, null, shouldGetter);\n }\n function shouldSetter(value) {\n // See https://github.com/chaijs/chai/issues/86: this makes\n // `whatever.should = someValue` actually set `someValue`, which is\n // especially useful for `global.should = require('chai').should()`.\n //\n // Note that we have to use [[DefineProperty]] instead of [[Put]]\n // since otherwise we would trigger this very setter!\n Object.defineProperty(this, 'should', {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n }\n // modify Object.prototype to have `should`\n Object.defineProperty(Object.prototype, 'should', {\n set: shouldSetter\n , get: shouldGetter\n , configurable: true\n });\n\n var should = {};\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Should\n * @api public\n */\n\n should.fail = function (actual, expected, message, operator) {\n message = message || 'should.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, should.fail);\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * should.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * should.throw(fn, 'function throws a reference error');\n * should.throw(fn, /function throws a reference error/);\n * should.throw(fn, ReferenceError);\n * should.throw(fn, ReferenceError, 'function throws a reference error');\n * should.throw(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.Throw(errt, errs);\n };\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi';\n *\n * should.exist(foo, 'foo exists');\n *\n * @name exist\n * @namespace Should\n * @api public\n */\n\n should.exist = function (val, msg) {\n new Assertion(val, msg).to.exist;\n }\n\n // negation\n should.not = {}\n\n /**\n * ### .not.equal(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * should.not.equal(3, 4, 'these numbers are not equal');\n *\n * @name not.equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.not.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.not.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * should.not.throw(fn, Error, 'function does not throw');\n *\n * @name not.throw\n * @alias not.Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.not.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.not.Throw(errt, errs);\n };\n\n /**\n * ### .not.exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var bar = null;\n *\n * should.not.exist(bar, 'bar does not exist');\n *\n * @name not.exist\n * @namespace Should\n * @api public\n */\n\n should.not.exist = function (val, msg) {\n new Assertion(val, msg).to.not.exist;\n }\n\n should['throw'] = should['Throw'];\n should.not['throw'] = should.not['Throw'];\n\n return should;\n };\n\n chai.should = loadShould;\n chai.Should = loadShould;\n};\n","/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call = Function.prototype.call,\n apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n * expect(fooStr).to.be.foo('bar');\n * expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n if (typeof chainingBehavior !== 'function') {\n chainingBehavior = function () { };\n }\n\n var chainableBehavior = {\n method: method\n , chainingBehavior: chainingBehavior\n };\n\n // save the methods so we can overwrite them later, if we need to.\n if (!ctx.__methods) {\n ctx.__methods = {};\n }\n ctx.__methods[name] = chainableBehavior;\n\n Object.defineProperty(ctx, name,\n { get: function () {\n chainableBehavior.chainingBehavior.call(this);\n\n var assert = function assert() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', assert);\n var result = chainableBehavior.method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n\n // Use `__proto__` if available\n if (hasProtoSupport) {\n // Inherit all properties from the object by replacing the `Function` prototype\n var prototype = assert.__proto__ = Object.create(this);\n // Restore the `call` and `apply` methods from `Function`\n prototype.call = call;\n prototype.apply = apply;\n }\n // Otherwise, redefine all properties (slow!)\n else {\n var asserterNames = Object.getOwnPropertyNames(ctx);\n asserterNames.forEach(function (asserterName) {\n if (!excludeNames.test(asserterName)) {\n var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n Object.defineProperty(assert, asserterName, pd);\n }\n });\n }\n\n transferFlags(this, assert);\n return assert;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n ctx[name] = function () {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', ctx[name]);\n var result = method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n * utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.instanceof(Foo);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n Object.defineProperty(ctx, name,\n { get: function addProperty() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', addProperty);\n\n var result = getter.call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n * utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n var obj = flag(obj, 'object');\n types = types.map(function (t) { return t.toLowerCase(); });\n types.sort();\n\n // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n var str = types.map(function (t, index) {\n var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n return or + art + ' ' + t;\n }).join(', ');\n\n if (!types.some(function (expected) { return type(obj) === expected; })) {\n throw new AssertionError(\n 'object tested must be ' + str + ', but ' + type(obj) + ' given'\n );\n }\n};\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n * utils.flag(this, 'foo', 'bar'); // setter\n * utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n var flags = obj.__flags || (obj.__flags = Object.create(null));\n if (arguments.length === 3) {\n flags[key] = value;\n } else {\n return flags[key];\n }\n};\n","/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n return args.length > 4 ? args[4] : obj._obj;\n};\n","/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n var result = [];\n for (var name in object) {\n result.push(name);\n }\n return result;\n};\n","/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n , getActual = require('./getActual')\n , inspect = require('./inspect')\n , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , val = flag(obj, 'object')\n , expected = args[3]\n , actual = getActual(obj, args)\n , msg = negate ? args[2] : args[1]\n , flagMsg = flag(obj, 'message');\n\n if(typeof msg === \"function\") msg = msg();\n msg = msg || '';\n msg = msg\n .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n","/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n if (func.name) return func.name;\n\n var match = /^\\s?function ([^(]*)\\(/.exec(func);\n return match && match[1] ? match[1] : \"\";\n};\n","/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n var parsed = parsePath(path),\n last = parsed[parsed.length - 1];\n\n var info = {\n parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n name: last.p || last.i,\n value: _getPathValue(parsed, obj)\n };\n info.exists = hasProperty(info.name, info.parent);\n\n return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n * var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n return parts.map(function (value) {\n var re = /^\\[(\\d+)\\]$/\n , mArr = re.exec(value);\n if (mArr) return { i: parseFloat(mArr[1]) };\n else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n * var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n var tmp = obj\n , res;\n\n index = (index === undefined ? parsed.length : index);\n\n for (var i = 0, l = index; i < l; i++) {\n var part = parsed[i];\n if (tmp) {\n if ('undefined' !== typeof part.p)\n tmp = tmp[part.p];\n else if ('undefined' !== typeof part.i)\n tmp = tmp[part.i];\n if (i == (l - 1)) res = tmp;\n } else {\n res = undefined;\n }\n }\n return res;\n}\n","/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer \n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n * var obj = {\n * prop1: {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n * , prop2: {\n * arr: [ { nested: 'Universe' } ]\n * , str: 'Hello again!'\n * }\n * }\n *\n * The following would be the results.\n *\n * getPathValue('prop1.str', obj); // Hello\n * getPathValue('prop1.att[2]', obj); // b\n * getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n var info = getPathInfo(path, obj);\n return info.value;\n};\n","/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n var result = Object.getOwnPropertyNames(object);\n\n function addProperty(property) {\n if (result.indexOf(property) === -1) {\n result.push(property);\n }\n }\n\n var proto = Object.getPrototypeOf(object);\n while (proto !== null) {\n Object.getOwnPropertyNames(proto).forEach(addProperty);\n proto = Object.getPrototypeOf(proto);\n }\n\n return result;\n};\n","/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n * var obj = {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n *\n * The following would be the results.\n *\n * hasProperty('str', obj); // true\n * hasProperty('constructor', obj); // true\n * hasProperty('bar', obj); // false\n *\n * hasProperty('length', obj.str); // true\n * hasProperty(1, obj.str); // true\n * hasProperty(5, obj.str); // false\n *\n * hasProperty('length', obj.arr); // true\n * hasProperty(2, obj.arr); // true\n * hasProperty(3, obj.arr); // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n 'number': Number\n , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n var ot = type(obj);\n\n // Bad Object, obviously no props at all\n if(ot === 'null' || ot === 'undefined')\n return false;\n\n // The `in` operator does not work with certain literals\n // box these before the check\n if(literals[ot] && typeof obj !== 'object')\n obj = new literals[ot](obj);\n\n return name in obj;\n};\n","/*!\n * chai\n * Copyright(c) 2011 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n","// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n * properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n * output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n var ctx = {\n showHidden: showHidden,\n seen: [],\n stylize: function (str) { return str; }\n };\n return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n if (typeof HTMLElement === 'object') {\n return object instanceof HTMLElement;\n } else {\n return object &&\n typeof object === 'object' &&\n object.nodeType === 1 &&\n typeof object.nodeName === 'string';\n }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (value && typeof value.inspect === 'function' &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes);\n if (typeof ret !== 'string') {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // If this is a DOM element, try to get the outer HTML.\n if (isDOMElement(value)) {\n if ('outerHTML' in value) {\n return value.outerHTML;\n // This value does not have an outerHTML attribute,\n // it could still be an XML element\n } else {\n // Attempt to serialize it\n try {\n if (document.xmlVersion) {\n var xmlSerializer = new XMLSerializer();\n return xmlSerializer.serializeToString(value);\n } else {\n // Firefox 11- do not support outerHTML\n // It does, however, support innerHTML\n // Use the following to render the element\n var ns = \"http://www.w3.org/1999/xhtml\";\n var container = document.createElementNS(ns, '_');\n\n container.appendChild(value.cloneNode(false));\n html = container.innerHTML\n .replace('><', '>' + value.innerHTML + '<');\n container.innerHTML = '';\n return html;\n }\n } catch (err) {\n // This could be a non-native DOM implementation,\n // continue with the normal flow:\n // printing the element as if it is an object.\n }\n }\n }\n\n // Look up the keys of the object.\n var visibleKeys = getEnumerableProperties(value);\n var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n // Some type of object without properties can be shortcutted.\n // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n // a `stack` plus `description` property; ignore those for consistency.\n if (keys.length === 0 || (isError(value) && (\n (keys.length === 1 && keys[0] === 'stack') ||\n (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n ))) {\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n base = ' [Function' + nameSuffix + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n return formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n switch (typeof value) {\n case 'undefined':\n return ctx.stylize('undefined', 'undefined');\n\n case 'string':\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n\n case 'number':\n if (value === 0 && (1/value) === -Infinity) {\n return ctx.stylize('-0', 'number');\n }\n return ctx.stylize('' + value, 'number');\n\n case 'boolean':\n return ctx.stylize('' + value, 'boolean');\n }\n // For some reason typeof null is \"object\", so special case here.\n if (value === null) {\n return ctx.stylize('null', 'null');\n }\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str;\n if (value.__lookupGetter__) {\n if (value.__lookupGetter__(key)) {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n }\n if (visibleKeys.indexOf(key) < 0) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(value[key]) < 0) {\n if (recurseTimes === null) {\n str = formatValue(ctx, value[key], null);\n } else {\n str = formatValue(ctx, value[key], recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (typeof name === 'undefined') {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n return Array.isArray(ar) ||\n (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n var str = inspect(obj)\n , type = Object.prototype.toString.call(obj);\n\n if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n if (type === '[object Function]') {\n return !obj.name || obj.name === ''\n ? '[Function]'\n : '[Function: ' + obj.name + ']';\n } else if (type === '[object Array]') {\n return '[ Array(' + obj.length + ') ]';\n } else if (type === '[object Object]') {\n var keys = Object.keys(obj)\n , kstr = keys.length > 2\n ? keys.splice(0, 2).join(', ') + ', ...'\n : keys.join(', ');\n return '{ Object (' + kstr + ') }';\n } else {\n return str;\n }\n } else {\n return str;\n }\n};\n","/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property. Must return functions to be used for\n * name.\n *\n * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n * function (_super) {\n * }\n * , function (_super) {\n * }\n * );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.have.length(3);\n * expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n var chainableBehavior = ctx.__methods[name];\n\n var _chainingBehavior = chainableBehavior.chainingBehavior;\n chainableBehavior.chainingBehavior = function () {\n var result = chainingBehavior(_chainingBehavior).call(this);\n return result === undefined ? this : result;\n };\n\n var _method = chainableBehavior.method;\n chainableBehavior.method = function () {\n var result = method(_method).apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n * return function (str) {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.value).to.equal(str);\n * } else {\n * _super.apply(this, arguments);\n * }\n * }\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n var _method = ctx[name]\n , _super = function () { return this; };\n\n if (_method && 'function' === typeof _method)\n _super = _method;\n\n ctx[name] = function () {\n var result = method(_super).apply(this, arguments);\n return result === undefined ? this : result;\n }\n};\n","/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n * return function () {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.name).to.equal('bar');\n * } else {\n * _super.call(this);\n * }\n * }\n * });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n var _get = Object.getOwnPropertyDescriptor(ctx, name)\n , _super = function () {};\n\n if (_get && 'function' === typeof _get.get)\n _super = _get.get\n\n Object.defineProperty(ctx, name,\n { get: function () {\n var result = getter(_super).call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , expr = args[0];\n return negate ? !expr : expr;\n};\n","/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n * var newAssertion = new Assertion();\n * utils.transferFlags(assertion, newAssertion);\n *\n * var anotherAsseriton = new Assertion(myObj);\n * utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n if (!object.__flags) {\n object.__flags = Object.create(null);\n }\n\n includeAll = arguments.length === 3 ? includeAll : true;\n\n for (var flag in flags) {\n if (includeAll ||\n (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n object.__flags[flag] = flags[flag];\n }\n }\n};\n","\"use strict\";\n\nfunction dedent(strings) {\n\n var raw = void 0;\n if (typeof strings === \"string\") {\n // dedent can be used as a plain function\n raw = [strings];\n } else {\n raw = strings.raw;\n }\n\n // first, perform interpolation\n var result = \"\";\n for (var i = 0; i < raw.length; i++) {\n result += raw[i].\n // join lines when there is a suppressed newline\n replace(/\\\\\\n[ \\t]*/g, \"\").\n\n // handle escaped backticks\n replace(/\\\\`/g, \"`\");\n\n if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) {\n result += arguments.length <= i + 1 ? undefined : arguments[i + 1];\n }\n }\n\n // now strip indentation\n var lines = result.split(\"\\n\");\n var mindent = null;\n lines.forEach(function (l) {\n var m = l.match(/^(\\s+)\\S+/);\n if (m) {\n var indent = m[1].length;\n if (!mindent) {\n // this is the first indented line\n mindent = indent;\n } else {\n mindent = Math.min(mindent, indent);\n }\n }\n });\n\n if (mindent !== null) {\n result = lines.map(function (l) {\n return l[0] === \" \" ? l.slice(mindent) : l;\n }).join(\"\\n\");\n }\n\n // dedent eats leading and trailing whitespace too\n result = result.trim();\n\n // handle escaped newlines at the end to ensure they don't get stripped too\n return result.replace(/\\\\n/g, \"\\n\");\n}\n\nif (typeof module !== \"undefined\") {\n module.exports = dedent;\n}\n","module.exports = require('./lib/eql');\n","/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n Buffer = {};\n Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n if (sameValue(a, b)) {\n return true;\n } else if ('date' === type(a)) {\n return dateEqual(a, b);\n } else if ('regexp' === type(a)) {\n return regexpEqual(a, b);\n } else if (Buffer.isBuffer(a)) {\n return bufferEqual(a, b);\n } else if ('arguments' === type(a)) {\n return argumentsEqual(a, b, m);\n } else if (!typeEqual(a, b)) {\n return false;\n } else if (('object' !== type(a) && 'object' !== type(b))\n && ('array' !== type(a) && 'array' !== type(b))) {\n return sameValue(a, b);\n } else {\n return objectEqual(a, b, m);\n }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n if (a === b) return a !== 0 || 1 / a === 1 / b;\n return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n if ('date' !== type(b)) return false;\n return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n if ('regexp' !== type(b)) return false;\n return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n if ('arguments' !== type(b)) return false;\n a = [].slice.call(a);\n b = [].slice.call(b);\n return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n var res = [];\n for (var key in a) res.push(key);\n return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n if (a.length !== b.length) return false;\n\n var i = 0;\n var match = true;\n\n for (; i < a.length; i++) {\n if (a[i] !== b[i]) {\n match = false;\n break;\n }\n }\n\n return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n if (!Buffer.isBuffer(b)) return false;\n return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n if (!isValue(a) || !isValue(b)) {\n return false;\n }\n\n if (a.prototype !== b.prototype) {\n return false;\n }\n\n var i;\n if (m) {\n for (i = 0; i < m.length; i++) {\n if ((m[i][0] === a && m[i][1] === b)\n || (m[i][0] === b && m[i][1] === a)) {\n return true;\n }\n }\n } else {\n m = [];\n }\n\n try {\n var ka = enumerable(a);\n var kb = enumerable(b);\n } catch (ex) {\n return false;\n }\n\n ka.sort();\n kb.sort();\n\n if (!iterableEqual(ka, kb)) {\n return false;\n }\n\n m.push([ a, b ]);\n\n var key;\n for (i = ka.length - 1; i >= 0; i--) {\n key = ka[i];\n if (!deepEqual(a[key], b[key], m)) {\n return false;\n }\n }\n\n return true;\n}\n","/*!\n localForage -- Offline Storage, Improved\n Version 1.5.0\n https://localforage.github.io/localForage\n (c) 2013-2017 Mozilla, Apache License 2.0\n*/\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.localforage = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw (f.code=\"MODULE_NOT_FOUND\", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o element; its readystatechange event will be fired asynchronously once it is inserted\n // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.\n var scriptEl = global.document.createElement('script');\n scriptEl.onreadystatechange = function () {\n nextTick();\n\n scriptEl.onreadystatechange = null;\n scriptEl.parentNode.removeChild(scriptEl);\n scriptEl = null;\n };\n global.document.documentElement.appendChild(scriptEl);\n };\n } else {\n scheduleDrain = function () {\n setTimeout(nextTick, 0);\n };\n }\n}\n\nvar draining;\nvar queue = [];\n//named nextTick for less confusing stack traces\nfunction nextTick() {\n draining = true;\n var i, oldQueue;\n var len = queue.length;\n while (len) {\n oldQueue = queue;\n queue = [];\n i = -1;\n while (++i < len) {\n oldQueue[i]();\n }\n len = queue.length;\n }\n draining = false;\n}\n\nmodule.exports = immediate;\nfunction immediate(task) {\n if (queue.push(task) === 1 && !draining) {\n scheduleDrain();\n }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],2:[function(_dereq_,module,exports){\n'use strict';\nvar immediate = _dereq_(1);\n\n/* istanbul ignore next */\nfunction INTERNAL() {}\n\nvar handlers = {};\n\nvar REJECTED = ['REJECTED'];\nvar FULFILLED = ['FULFILLED'];\nvar PENDING = ['PENDING'];\n\nmodule.exports = exports = Promise;\n\nfunction Promise(resolver) {\n if (typeof resolver !== 'function') {\n throw new TypeError('resolver must be a function');\n }\n this.state = PENDING;\n this.queue = [];\n this.outcome = void 0;\n if (resolver !== INTERNAL) {\n safelyResolveThenable(this, resolver);\n }\n}\n\nPromise.prototype[\"catch\"] = function (onRejected) {\n return this.then(null, onRejected);\n};\nPromise.prototype.then = function (onFulfilled, onRejected) {\n if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||\n typeof onRejected !== 'function' && this.state === REJECTED) {\n return this;\n }\n var promise = new this.constructor(INTERNAL);\n if (this.state !== PENDING) {\n var resolver = this.state === FULFILLED ? onFulfilled : onRejected;\n unwrap(promise, resolver, this.outcome);\n } else {\n this.queue.push(new QueueItem(promise, onFulfilled, onRejected));\n }\n\n return promise;\n};\nfunction QueueItem(promise, onFulfilled, onRejected) {\n this.promise = promise;\n if (typeof onFulfilled === 'function') {\n this.onFulfilled = onFulfilled;\n this.callFulfilled = this.otherCallFulfilled;\n }\n if (typeof onRejected === 'function') {\n this.onRejected = onRejected;\n this.callRejected = this.otherCallRejected;\n }\n}\nQueueItem.prototype.callFulfilled = function (value) {\n handlers.resolve(this.promise, value);\n};\nQueueItem.prototype.otherCallFulfilled = function (value) {\n unwrap(this.promise, this.onFulfilled, value);\n};\nQueueItem.prototype.callRejected = function (value) {\n handlers.reject(this.promise, value);\n};\nQueueItem.prototype.otherCallRejected = function (value) {\n unwrap(this.promise, this.onRejected, value);\n};\n\nfunction unwrap(promise, func, value) {\n immediate(function () {\n var returnValue;\n try {\n returnValue = func(value);\n } catch (e) {\n return handlers.reject(promise, e);\n }\n if (returnValue === promise) {\n handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));\n } else {\n handlers.resolve(promise, returnValue);\n }\n });\n}\n\nhandlers.resolve = function (self, value) {\n var result = tryCatch(getThen, value);\n if (result.status === 'error') {\n return handlers.reject(self, result.value);\n }\n var thenable = result.value;\n\n if (thenable) {\n safelyResolveThenable(self, thenable);\n } else {\n self.state = FULFILLED;\n self.outcome = value;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callFulfilled(value);\n }\n }\n return self;\n};\nhandlers.reject = function (self, error) {\n self.state = REJECTED;\n self.outcome = error;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callRejected(error);\n }\n return self;\n};\n\nfunction getThen(obj) {\n // Make sure we only access the accessor once as required by the spec\n var then = obj && obj.then;\n if (obj && typeof obj === 'object' && typeof then === 'function') {\n return function appyThen() {\n then.apply(obj, arguments);\n };\n }\n}\n\nfunction safelyResolveThenable(self, thenable) {\n // Either fulfill, reject or reject with error\n var called = false;\n function onError(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.reject(self, value);\n }\n\n function onSuccess(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.resolve(self, value);\n }\n\n function tryToUnwrap() {\n thenable(onSuccess, onError);\n }\n\n var result = tryCatch(tryToUnwrap);\n if (result.status === 'error') {\n onError(result.value);\n }\n}\n\nfunction tryCatch(func, value) {\n var out = {};\n try {\n out.value = func(value);\n out.status = 'success';\n } catch (e) {\n out.status = 'error';\n out.value = e;\n }\n return out;\n}\n\nexports.resolve = resolve;\nfunction resolve(value) {\n if (value instanceof this) {\n return value;\n }\n return handlers.resolve(new this(INTERNAL), value);\n}\n\nexports.reject = reject;\nfunction reject(reason) {\n var promise = new this(INTERNAL);\n return handlers.reject(promise, reason);\n}\n\nexports.all = all;\nfunction all(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var values = new Array(len);\n var resolved = 0;\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n allResolver(iterable[i], i);\n }\n return promise;\n function allResolver(value, i) {\n self.resolve(value).then(resolveFromAll, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n function resolveFromAll(outValue) {\n values[i] = outValue;\n if (++resolved === len && !called) {\n called = true;\n handlers.resolve(promise, values);\n }\n }\n }\n}\n\nexports.race = race;\nfunction race(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n resolver(iterable[i]);\n }\n return promise;\n function resolver(value) {\n self.resolve(value).then(function (response) {\n if (!called) {\n called = true;\n handlers.resolve(promise, response);\n }\n }, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n }\n}\n\n},{\"1\":1}],3:[function(_dereq_,module,exports){\n(function (global){\n'use strict';\nif (typeof global.Promise !== 'function') {\n global.Promise = _dereq_(2);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"2\":2}],4:[function(_dereq_,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction getIDB() {\n /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */\n try {\n if (typeof indexedDB !== 'undefined') {\n return indexedDB;\n }\n if (typeof webkitIndexedDB !== 'undefined') {\n return webkitIndexedDB;\n }\n if (typeof mozIndexedDB !== 'undefined') {\n return mozIndexedDB;\n }\n if (typeof OIndexedDB !== 'undefined') {\n return OIndexedDB;\n }\n if (typeof msIndexedDB !== 'undefined') {\n return msIndexedDB;\n }\n } catch (e) {}\n}\n\nvar idb = getIDB();\n\nfunction isIndexedDBValid() {\n try {\n // Initialize IndexedDB; fall back to vendor-prefixed versions\n // if needed.\n if (!idb) {\n return false;\n }\n // We mimic PouchDB here;\n //\n // We test for openDatabase because IE Mobile identifies itself\n // as Safari. Oh the lulz...\n var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform);\n\n var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1;\n\n // Safari <10.1 does not meet our requirements for IDB support (#5572)\n // since Safari 10.1 shipped with fetch, we can use that to detect it\n return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' &&\n // some outdated implementations of IDB that appear on Samsung\n // and HTC Android devices <4.4 are missing IDBKeyRange\n typeof IDBKeyRange !== 'undefined';\n } catch (e) {\n return false;\n }\n}\n\nfunction isWebSQLValid() {\n return typeof openDatabase === 'function';\n}\n\nfunction isLocalStorageValid() {\n try {\n return typeof localStorage !== 'undefined' && 'setItem' in localStorage && localStorage.setItem;\n } catch (e) {\n return false;\n }\n}\n\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\nfunction createBlob(parts, properties) {\n /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */\n parts = parts || [];\n properties = properties || {};\n try {\n return new Blob(parts, properties);\n } catch (e) {\n if (e.name !== 'TypeError') {\n throw e;\n }\n var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder;\n var builder = new Builder();\n for (var i = 0; i < parts.length; i += 1) {\n builder.append(parts[i]);\n }\n return builder.getBlob(properties.type);\n }\n}\n\n// This is CommonJS because lie is an external dependency, so Rollup\n// can just ignore it.\nif (typeof Promise === 'undefined') {\n // In the \"nopromises\" build this will just throw if you don't have\n // a global promise object, but it would throw anyway later.\n _dereq_(3);\n}\nvar Promise$1 = Promise;\n\nfunction executeCallback(promise, callback) {\n if (callback) {\n promise.then(function (result) {\n callback(null, result);\n }, function (error) {\n callback(error);\n });\n }\n}\n\nfunction executeTwoCallbacks(promise, callback, errorCallback) {\n if (typeof callback === 'function') {\n promise.then(callback);\n }\n\n if (typeof errorCallback === 'function') {\n promise[\"catch\"](errorCallback);\n }\n}\n\n// Some code originally from async_storage.js in\n// [Gaia](https://github.com/mozilla-b2g/gaia).\n\nvar DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support';\nvar supportsBlobs;\nvar dbContexts;\nvar toString = Object.prototype.toString;\n\n// Transform a binary string to an array buffer, because otherwise\n// weird stuff happens when you try to work with the binary string directly.\n// It is known.\n// From http://stackoverflow.com/questions/14967647/ (continues on next line)\n// encode-decode-image-with-base64-breaks-image (2013-04-21)\nfunction _binStringToArrayBuffer(bin) {\n var length = bin.length;\n var buf = new ArrayBuffer(length);\n var arr = new Uint8Array(buf);\n for (var i = 0; i < length; i++) {\n arr[i] = bin.charCodeAt(i);\n }\n return buf;\n}\n\n//\n// Blobs are not supported in all versions of IndexedDB, notably\n// Chrome <37 and Android <5. In those versions, storing a blob will throw.\n//\n// Various other blob bugs exist in Chrome v37-42 (inclusive).\n// Detecting them is expensive and confusing to users, and Chrome 37-42\n// is at very low usage worldwide, so we do a hacky userAgent check instead.\n//\n// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120\n// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916\n// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836\n//\n// Code borrowed from PouchDB. See:\n// https://github.com/pouchdb/pouchdb/blob/master/packages/node_modules/pouchdb-adapter-idb/src/blobSupport.js\n//\nfunction _checkBlobSupportWithoutCaching(idb) {\n return new Promise$1(function (resolve) {\n var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, 'readwrite');\n var blob = createBlob(['']);\n txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');\n\n txn.onabort = function (e) {\n // If the transaction aborts now its due to not being able to\n // write to the database, likely due to the disk being full\n e.preventDefault();\n e.stopPropagation();\n resolve(false);\n };\n\n txn.oncomplete = function () {\n var matchedChrome = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n var matchedEdge = navigator.userAgent.match(/Edge\\//);\n // MS Edge pretends to be Chrome 42:\n // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx\n resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43);\n };\n })[\"catch\"](function () {\n return false; // error, so assume unsupported\n });\n}\n\nfunction _checkBlobSupport(idb) {\n if (typeof supportsBlobs === 'boolean') {\n return Promise$1.resolve(supportsBlobs);\n }\n return _checkBlobSupportWithoutCaching(idb).then(function (value) {\n supportsBlobs = value;\n return supportsBlobs;\n });\n}\n\nfunction _deferReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Create a deferred object representing the current database operation.\n var deferredOperation = {};\n\n deferredOperation.promise = new Promise$1(function (resolve) {\n deferredOperation.resolve = resolve;\n });\n\n // Enqueue the deferred operation.\n dbContext.deferredOperations.push(deferredOperation);\n\n // Chain its promise to the database readiness.\n if (!dbContext.dbReady) {\n dbContext.dbReady = deferredOperation.promise;\n } else {\n dbContext.dbReady = dbContext.dbReady.then(function () {\n return deferredOperation.promise;\n });\n }\n}\n\nfunction _advanceReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Dequeue a deferred operation.\n var deferredOperation = dbContext.deferredOperations.pop();\n\n // Resolve its promise (which is part of the database readiness\n // chain of promises).\n if (deferredOperation) {\n deferredOperation.resolve();\n }\n}\n\nfunction _getConnection(dbInfo, upgradeNeeded) {\n return new Promise$1(function (resolve, reject) {\n\n if (dbInfo.db) {\n if (upgradeNeeded) {\n _deferReadiness(dbInfo);\n dbInfo.db.close();\n } else {\n return resolve(dbInfo.db);\n }\n }\n\n var dbArgs = [dbInfo.name];\n\n if (upgradeNeeded) {\n dbArgs.push(dbInfo.version);\n }\n\n var openreq = idb.open.apply(idb, dbArgs);\n\n if (upgradeNeeded) {\n openreq.onupgradeneeded = function (e) {\n var db = openreq.result;\n try {\n db.createObjectStore(dbInfo.storeName);\n if (e.oldVersion <= 1) {\n // Added when support for blob shims was added\n db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);\n }\n } catch (ex) {\n if (ex.name === 'ConstraintError') {\n console.warn('The database \"' + dbInfo.name + '\"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage \"' + dbInfo.storeName + '\" already exists.');\n } else {\n throw ex;\n }\n }\n };\n }\n\n openreq.onerror = function (e) {\n e.preventDefault();\n reject(openreq.error);\n };\n\n openreq.onsuccess = function () {\n resolve(openreq.result);\n _advanceReadiness(dbInfo);\n };\n });\n}\n\nfunction _getOriginalConnection(dbInfo) {\n return _getConnection(dbInfo, false);\n}\n\nfunction _getUpgradedConnection(dbInfo) {\n return _getConnection(dbInfo, true);\n}\n\nfunction _isUpgradeNeeded(dbInfo, defaultVersion) {\n if (!dbInfo.db) {\n return true;\n }\n\n var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName);\n var isDowngrade = dbInfo.version < dbInfo.db.version;\n var isUpgrade = dbInfo.version > dbInfo.db.version;\n\n if (isDowngrade) {\n // If the version is not the default one\n // then warn for impossible downgrade.\n if (dbInfo.version !== defaultVersion) {\n console.warn('The database \"' + dbInfo.name + '\"' + ' can\\'t be downgraded from version ' + dbInfo.db.version + ' to version ' + dbInfo.version + '.');\n }\n // Align the versions to prevent errors.\n dbInfo.version = dbInfo.db.version;\n }\n\n if (isUpgrade || isNewStore) {\n // If the store is new then increment the version (if needed).\n // This will trigger an \"upgradeneeded\" event which is required\n // for creating a store.\n if (isNewStore) {\n var incVersion = dbInfo.db.version + 1;\n if (incVersion > dbInfo.version) {\n dbInfo.version = incVersion;\n }\n }\n\n return true;\n }\n\n return false;\n}\n\n// encode a blob for indexeddb engines that don't support blobs\nfunction _encodeBlob(blob) {\n return new Promise$1(function (resolve, reject) {\n var reader = new FileReader();\n reader.onerror = reject;\n reader.onloadend = function (e) {\n var base64 = btoa(e.target.result || '');\n resolve({\n __local_forage_encoded_blob: true,\n data: base64,\n type: blob.type\n });\n };\n reader.readAsBinaryString(blob);\n });\n}\n\n// decode an encoded blob\nfunction _decodeBlob(encodedBlob) {\n var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data));\n return createBlob([arrayBuff], { type: encodedBlob.type });\n}\n\n// is this one of our fancy encoded blobs?\nfunction _isEncodedBlob(value) {\n return value && value.__local_forage_encoded_blob;\n}\n\n// Specialize the default `ready()` function by making it dependent\n// on the current database operations. Thus, the driver will be actually\n// ready when it's been initialized (default) *and* there are no pending\n// operations on the database (initiated by some other instances).\nfunction _fullyReady(callback) {\n var self = this;\n\n var promise = self._initReady().then(function () {\n var dbContext = dbContexts[self._dbInfo.name];\n\n if (dbContext && dbContext.dbReady) {\n return dbContext.dbReady;\n }\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n}\n\n// Open the IndexedDB database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n // Initialize a singleton container for all running localForages.\n if (!dbContexts) {\n dbContexts = {};\n }\n\n // Get the current context of the database;\n var dbContext = dbContexts[dbInfo.name];\n\n // ...or create a new context.\n if (!dbContext) {\n dbContext = {\n // Running localForages sharing a database.\n forages: [],\n // Shared database.\n db: null,\n // Database readiness (promise).\n dbReady: null,\n // Deferred operations on the database.\n deferredOperations: []\n };\n // Register the new context in the global container.\n dbContexts[dbInfo.name] = dbContext;\n }\n\n // Register itself as a running localForage in the current context.\n dbContext.forages.push(self);\n\n // Replace the default `ready()` function with the specialized one.\n if (!self._initReady) {\n self._initReady = self.ready;\n self.ready = _fullyReady;\n }\n\n // Create an array of initialization states of the related localForages.\n var initPromises = [];\n\n function ignoreErrors() {\n // Don't handle errors here,\n // just makes sure related localForages aren't pending.\n return Promise$1.resolve();\n }\n\n for (var j = 0; j < dbContext.forages.length; j++) {\n var forage = dbContext.forages[j];\n if (forage !== self) {\n // Don't wait for itself...\n initPromises.push(forage._initReady()[\"catch\"](ignoreErrors));\n }\n }\n\n // Take a snapshot of the related localForages.\n var forages = dbContext.forages.slice(0);\n\n // Initialize the connection process only when\n // all the related localForages aren't pending.\n return Promise$1.all(initPromises).then(function () {\n dbInfo.db = dbContext.db;\n // Get the connection or open a new one without upgrade.\n return _getOriginalConnection(dbInfo);\n }).then(function (db) {\n dbInfo.db = db;\n if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) {\n // Reopen the database for upgrading.\n return _getUpgradedConnection(dbInfo);\n }\n return db;\n }).then(function (db) {\n dbInfo.db = dbContext.db = db;\n self._dbInfo = dbInfo;\n // Share the final connection amongst related localForages.\n for (var k = 0; k < forages.length; k++) {\n var forage = forages[k];\n if (forage !== self) {\n // Self is already up-to-date.\n forage._dbInfo.db = dbInfo.db;\n forage._dbInfo.version = dbInfo.version;\n }\n }\n });\n}\n\nfunction getItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.get(key);\n\n req.onsuccess = function () {\n var value = req.result;\n if (value === undefined) {\n value = null;\n }\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n resolve(value);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items stored in database.\nfunction iterate(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var iterationNumber = 1;\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (cursor) {\n var value = cursor.value;\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n var result = iterator(value, cursor.key, iterationNumber++);\n\n if (result !== void 0) {\n resolve(result);\n } else {\n cursor[\"continue\"]();\n }\n } else {\n resolve();\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n\n return promise;\n}\n\nfunction setItem(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n var dbInfo;\n self.ready().then(function () {\n dbInfo = self._dbInfo;\n if (toString.call(value) === '[object Blob]') {\n return _checkBlobSupport(dbInfo.db).then(function (blobSupport) {\n if (blobSupport) {\n return value;\n }\n return _encodeBlob(value);\n });\n }\n return value;\n }).then(function (value) {\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.put(value, key);\n\n // The reason we don't _save_ null is because IE 10 does\n // not support saving the `null` type in IndexedDB. How\n // ironic, given the bug below!\n // See: https://github.com/mozilla/localForage/issues/161\n if (value === null) {\n value = undefined;\n }\n\n transaction.oncomplete = function () {\n // Cast to undefined so the value passed to\n // callback/promise is the same as what one would get out\n // of `getItem()` later. This leads to some weirdness\n // (setItem('foo', undefined) will return `null`), but\n // it's not my fault localStorage is our baseline and that\n // it's weird.\n if (value === undefined) {\n value = null;\n }\n\n resolve(value);\n };\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction removeItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n\n // We use a Grunt task to make this safe for IE and some\n // versions of Android (including those used by Cordova).\n // Normally IE won't like `.delete()` and will insist on\n // using `['delete']()`, but we have a build step that\n // fixes this for us now.\n var req = store[\"delete\"](key);\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onerror = function () {\n reject(req.error);\n };\n\n // The request will be also be aborted if we've exceeded our storage\n // space.\n transaction.onabort = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction clear(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.clear();\n\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction length(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.count();\n\n req.onsuccess = function () {\n resolve(req.result);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction key(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n if (n < 0) {\n resolve(null);\n\n return;\n }\n\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var advanced = false;\n var req = store.openCursor();\n req.onsuccess = function () {\n var cursor = req.result;\n if (!cursor) {\n // this means there weren't enough keys\n resolve(null);\n\n return;\n }\n\n if (n === 0) {\n // We have the first key, return it if that's what they\n // wanted.\n resolve(cursor.key);\n } else {\n if (!advanced) {\n // Otherwise, ask the cursor to skip ahead n\n // records.\n advanced = true;\n cursor.advance(n);\n } else {\n // When we get here, we've got the nth key.\n resolve(cursor.key);\n }\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var keys = [];\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (!cursor) {\n resolve(keys);\n return;\n }\n\n keys.push(cursor.key);\n cursor[\"continue\"]();\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar asyncStorage = {\n _driver: 'asyncStorage',\n _initStorage: _initStorage,\n iterate: iterate,\n getItem: getItem,\n setItem: setItem,\n removeItem: removeItem,\n clear: clear,\n length: length,\n key: key,\n keys: keys\n};\n\n// Sadly, the best way to save binary data in WebSQL/localStorage is serializing\n// it to Base64, so this is how we store it to prevent very strange errors with less\n// verbose ways of binary <-> string data storage.\nvar BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\nvar BLOB_TYPE_PREFIX = '~~local_forage_type~';\nvar BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;\n\nvar SERIALIZED_MARKER = '__lfsc__:';\nvar SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;\n\n// OMG the serializations!\nvar TYPE_ARRAYBUFFER = 'arbf';\nvar TYPE_BLOB = 'blob';\nvar TYPE_INT8ARRAY = 'si08';\nvar TYPE_UINT8ARRAY = 'ui08';\nvar TYPE_UINT8CLAMPEDARRAY = 'uic8';\nvar TYPE_INT16ARRAY = 'si16';\nvar TYPE_INT32ARRAY = 'si32';\nvar TYPE_UINT16ARRAY = 'ur16';\nvar TYPE_UINT32ARRAY = 'ui32';\nvar TYPE_FLOAT32ARRAY = 'fl32';\nvar TYPE_FLOAT64ARRAY = 'fl64';\nvar TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;\n\nvar toString$1 = Object.prototype.toString;\n\nfunction stringToBuffer(serializedString) {\n // Fill the string into a ArrayBuffer.\n var bufferLength = serializedString.length * 0.75;\n var len = serializedString.length;\n var i;\n var p = 0;\n var encoded1, encoded2, encoded3, encoded4;\n\n if (serializedString[serializedString.length - 1] === '=') {\n bufferLength--;\n if (serializedString[serializedString.length - 2] === '=') {\n bufferLength--;\n }\n }\n\n var buffer = new ArrayBuffer(bufferLength);\n var bytes = new Uint8Array(buffer);\n\n for (i = 0; i < len; i += 4) {\n encoded1 = BASE_CHARS.indexOf(serializedString[i]);\n encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);\n encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);\n encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);\n\n /*jslint bitwise: true */\n bytes[p++] = encoded1 << 2 | encoded2 >> 4;\n bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;\n bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;\n }\n return buffer;\n}\n\n// Converts a buffer to a string to store, serialized, in the backend\n// storage library.\nfunction bufferToString(buffer) {\n // base64-arraybuffer\n var bytes = new Uint8Array(buffer);\n var base64String = '';\n var i;\n\n for (i = 0; i < bytes.length; i += 3) {\n /*jslint bitwise: true */\n base64String += BASE_CHARS[bytes[i] >> 2];\n base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];\n base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];\n base64String += BASE_CHARS[bytes[i + 2] & 63];\n }\n\n if (bytes.length % 3 === 2) {\n base64String = base64String.substring(0, base64String.length - 1) + '=';\n } else if (bytes.length % 3 === 1) {\n base64String = base64String.substring(0, base64String.length - 2) + '==';\n }\n\n return base64String;\n}\n\n// Serialize a value, afterwards executing a callback (which usually\n// instructs the `setItem()` callback/promise to be executed). This is how\n// we store binary data with localStorage.\nfunction serialize(value, callback) {\n var valueType = '';\n if (value) {\n valueType = toString$1.call(value);\n }\n\n // Cannot use `value instanceof ArrayBuffer` or such here, as these\n // checks fail when running the tests using casper.js...\n //\n // TODO: See why those tests fail and use a better solution.\n if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) {\n // Convert binary arrays to a string and prefix the string with\n // a special marker.\n var buffer;\n var marker = SERIALIZED_MARKER;\n\n if (value instanceof ArrayBuffer) {\n buffer = value;\n marker += TYPE_ARRAYBUFFER;\n } else {\n buffer = value.buffer;\n\n if (valueType === '[object Int8Array]') {\n marker += TYPE_INT8ARRAY;\n } else if (valueType === '[object Uint8Array]') {\n marker += TYPE_UINT8ARRAY;\n } else if (valueType === '[object Uint8ClampedArray]') {\n marker += TYPE_UINT8CLAMPEDARRAY;\n } else if (valueType === '[object Int16Array]') {\n marker += TYPE_INT16ARRAY;\n } else if (valueType === '[object Uint16Array]') {\n marker += TYPE_UINT16ARRAY;\n } else if (valueType === '[object Int32Array]') {\n marker += TYPE_INT32ARRAY;\n } else if (valueType === '[object Uint32Array]') {\n marker += TYPE_UINT32ARRAY;\n } else if (valueType === '[object Float32Array]') {\n marker += TYPE_FLOAT32ARRAY;\n } else if (valueType === '[object Float64Array]') {\n marker += TYPE_FLOAT64ARRAY;\n } else {\n callback(new Error('Failed to get type for BinaryArray'));\n }\n }\n\n callback(marker + bufferToString(buffer));\n } else if (valueType === '[object Blob]') {\n // Conver the blob to a binaryArray and then to a string.\n var fileReader = new FileReader();\n\n fileReader.onload = function () {\n // Backwards-compatible prefix for the blob type.\n var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result);\n\n callback(SERIALIZED_MARKER + TYPE_BLOB + str);\n };\n\n fileReader.readAsArrayBuffer(value);\n } else {\n try {\n callback(JSON.stringify(value));\n } catch (e) {\n console.error(\"Couldn't convert value into a JSON string: \", value);\n\n callback(null, e);\n }\n }\n}\n\n// Deserialize data we've inserted into a value column/field. We place\n// special markers into our strings to mark them as encoded; this isn't\n// as nice as a meta field, but it's the only sane thing we can do whilst\n// keeping localStorage support intact.\n//\n// Oftentimes this will just deserialize JSON content, but if we have a\n// special marker (SERIALIZED_MARKER, defined above), we will extract\n// some kind of arraybuffer/binary data/typed array out of the string.\nfunction deserialize(value) {\n // If we haven't marked this string as being specially serialized (i.e.\n // something other than serialized JSON), we can just return it and be\n // done with it.\n if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {\n return JSON.parse(value);\n }\n\n // The following code deals with deserializing some kind of Blob or\n // TypedArray. First we separate out the type of data we're dealing\n // with from the data itself.\n var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);\n var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH);\n\n var blobType;\n // Backwards-compatible blob type serialization strategy.\n // DBs created with older versions of localForage will simply not have the blob type.\n if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {\n var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);\n blobType = matcher[1];\n serializedString = serializedString.substring(matcher[0].length);\n }\n var buffer = stringToBuffer(serializedString);\n\n // Return the right type based on the code/type set during\n // serialization.\n switch (type) {\n case TYPE_ARRAYBUFFER:\n return buffer;\n case TYPE_BLOB:\n return createBlob([buffer], { type: blobType });\n case TYPE_INT8ARRAY:\n return new Int8Array(buffer);\n case TYPE_UINT8ARRAY:\n return new Uint8Array(buffer);\n case TYPE_UINT8CLAMPEDARRAY:\n return new Uint8ClampedArray(buffer);\n case TYPE_INT16ARRAY:\n return new Int16Array(buffer);\n case TYPE_UINT16ARRAY:\n return new Uint16Array(buffer);\n case TYPE_INT32ARRAY:\n return new Int32Array(buffer);\n case TYPE_UINT32ARRAY:\n return new Uint32Array(buffer);\n case TYPE_FLOAT32ARRAY:\n return new Float32Array(buffer);\n case TYPE_FLOAT64ARRAY:\n return new Float64Array(buffer);\n default:\n throw new Error('Unkown type: ' + type);\n }\n}\n\nvar localforageSerializer = {\n serialize: serialize,\n deserialize: deserialize,\n stringToBuffer: stringToBuffer,\n bufferToString: bufferToString\n};\n\n/*\n * Includes code from:\n *\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n// Open the WebSQL database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage$1(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i];\n }\n }\n\n var dbInfoPromise = new Promise$1(function (resolve, reject) {\n // Open the database; the openDatabase API will automatically\n // create it for us if it doesn't exist.\n try {\n dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size);\n } catch (e) {\n return reject(e);\n }\n\n // Create our key/value table if it doesn't exist.\n dbInfo.db.transaction(function (t) {\n t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' (id INTEGER PRIMARY KEY, key unique, value)', [], function () {\n self._dbInfo = dbInfo;\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n });\n\n dbInfo.serializer = localforageSerializer;\n return dbInfoPromise;\n}\n\nfunction getItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).value : null;\n\n // Check to see if this is serialized content we need to\n // unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction iterate$1(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName, [], function (t, results) {\n var rows = results.rows;\n var length = rows.length;\n\n for (var i = 0; i < length; i++) {\n var item = rows.item(i);\n var result = item.value;\n\n // Check to see if this is serialized content\n // we need to unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n result = iterator(result, item.key, i + 1);\n\n // void(0) prevents problems with redefinition\n // of `undefined`.\n if (result !== void 0) {\n resolve(result);\n return;\n }\n }\n\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction _setItem(key, value, callback, retriesLeft) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n // The localStorage API doesn't return undefined values in an\n // \"expected\" way, so undefined is always cast to null in all\n // drivers. See: https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n dbInfo.db.transaction(function (t) {\n t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + ' (key, value) VALUES (?, ?)', [key, value], function () {\n resolve(originalValue);\n }, function (t, error) {\n reject(error);\n });\n }, function (sqlError) {\n // The transaction failed; check\n // to see if it's a quota error.\n if (sqlError.code === sqlError.QUOTA_ERR) {\n // We reject the callback outright for now, but\n // it's worth trying to re-run the transaction.\n // Even if the user accepts the prompt to use\n // more storage on Safari, this error will\n // be called.\n //\n // Try to re-run the transaction.\n if (retriesLeft > 0) {\n resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1]));\n return;\n }\n reject(sqlError);\n }\n });\n }\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction setItem$1(key, value, callback) {\n return _setItem.apply(this, [key, value, callback, 1]);\n}\n\nfunction removeItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () {\n resolve();\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Deletes every item in the table.\n// TODO: Find out if this resets the AUTO_INCREMENT number.\nfunction clear$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function () {\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Does a simple `COUNT(key)` to get the number of items stored in\n// localForage.\nfunction length$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n // Ahhh, SQL makes this one soooooo easy.\n t.executeSql('SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) {\n var result = results.rows.item(0).c;\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Return the key located at key index X; essentially gets the key from a\n// `WHERE id = ?`. This is the most efficient way I can think to implement\n// this rarely-used (in my experience) part of the API, but it can seem\n// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so\n// the ID of each key will change every time it's updated. Perhaps a stored\n// procedure for the `setItem()` SQL would solve this problem?\n// TODO: Don't change ID on `setItem()`.\nfunction key$1(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).key : null;\n resolve(result);\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName, [], function (t, results) {\n var keys = [];\n\n for (var i = 0; i < results.rows.length; i++) {\n keys.push(results.rows.item(i).key);\n }\n\n resolve(keys);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar webSQLStorage = {\n _driver: 'webSQLStorage',\n _initStorage: _initStorage$1,\n iterate: iterate$1,\n getItem: getItem$1,\n setItem: setItem$1,\n removeItem: removeItem$1,\n clear: clear$1,\n length: length$1,\n key: key$1,\n keys: keys$1\n};\n\n// Config the localStorage backend, using options set in the config.\nfunction _initStorage$2(options) {\n var self = this;\n var dbInfo = {};\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n dbInfo.keyPrefix = dbInfo.name + '/';\n\n if (dbInfo.storeName !== self._defaultConfig.storeName) {\n dbInfo.keyPrefix += dbInfo.storeName + '/';\n }\n\n self._dbInfo = dbInfo;\n dbInfo.serializer = localforageSerializer;\n\n return Promise$1.resolve();\n}\n\n// Remove all keys from the datastore, effectively destroying all data in\n// the app's key/value store!\nfunction clear$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var keyPrefix = self._dbInfo.keyPrefix;\n\n for (var i = localStorage.length - 1; i >= 0; i--) {\n var key = localStorage.key(i);\n\n if (key.indexOf(keyPrefix) === 0) {\n localStorage.removeItem(key);\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Retrieve an item from the store. Unlike the original async_storage\n// library in Gaia, we don't modify return values at all. If a key's value\n// is `undefined`, we pass that value to the callback function.\nfunction getItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result = localStorage.getItem(dbInfo.keyPrefix + key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the key\n // is likely undefined and we'll pass it straight to the\n // callback.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items in the store.\nfunction iterate$2(iterator, callback) {\n var self = this;\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var keyPrefix = dbInfo.keyPrefix;\n var keyPrefixLength = keyPrefix.length;\n var length = localStorage.length;\n\n // We use a dedicated iterator instead of the `i` variable below\n // so other keys we fetch in localStorage aren't counted in\n // the `iterationNumber` argument passed to the `iterate()`\n // callback.\n //\n // See: github.com/mozilla/localForage/pull/435#discussion_r38061530\n var iterationNumber = 1;\n\n for (var i = 0; i < length; i++) {\n var key = localStorage.key(i);\n if (key.indexOf(keyPrefix) !== 0) {\n continue;\n }\n var value = localStorage.getItem(key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the\n // key is likely undefined and we'll pass it straight\n // to the iterator.\n if (value) {\n value = dbInfo.serializer.deserialize(value);\n }\n\n value = iterator(value, key.substring(keyPrefixLength), iterationNumber++);\n\n if (value !== void 0) {\n return value;\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Same as localStorage's key() method, except takes a callback.\nfunction key$2(n, callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result;\n try {\n result = localStorage.key(n);\n } catch (error) {\n result = null;\n }\n\n // Remove the prefix from the key, if a key is found.\n if (result) {\n result = result.substring(dbInfo.keyPrefix.length);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var length = localStorage.length;\n var keys = [];\n\n for (var i = 0; i < length; i++) {\n if (localStorage.key(i).indexOf(dbInfo.keyPrefix) === 0) {\n keys.push(localStorage.key(i).substring(dbInfo.keyPrefix.length));\n }\n }\n\n return keys;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Supply the number of keys in the datastore to the callback function.\nfunction length$2(callback) {\n var self = this;\n var promise = self.keys().then(function (keys) {\n return keys.length;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Remove an item from the store, nice and simple.\nfunction removeItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n localStorage.removeItem(dbInfo.keyPrefix + key);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Set a key's value and run an optional callback once the value is set.\n// Unlike Gaia's implementation, the callback function is passed the value,\n// in case you want to operate on that value only after you're sure it\n// saved, or something like that.\nfunction setItem$2(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n // Convert undefined values to null.\n // https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n return new Promise$1(function (resolve, reject) {\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n try {\n localStorage.setItem(dbInfo.keyPrefix + key, value);\n resolve(originalValue);\n } catch (e) {\n // localStorage capacity exceeded.\n // TODO: Make this a specific error/event.\n if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {\n reject(e);\n }\n reject(e);\n }\n }\n });\n });\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar localStorageWrapper = {\n _driver: 'localStorageWrapper',\n _initStorage: _initStorage$2,\n // Default API, from Gaia/localStorage.\n iterate: iterate$2,\n getItem: getItem$2,\n setItem: setItem$2,\n removeItem: removeItem$2,\n clear: clear$2,\n length: length$2,\n key: key$2,\n keys: keys$2\n};\n\n// Custom drivers are stored here when `defineDriver()` is called.\n// They are shared across all instances of localForage.\nvar CustomDrivers = {};\n\nvar DriverType = {\n INDEXEDDB: 'asyncStorage',\n LOCALSTORAGE: 'localStorageWrapper',\n WEBSQL: 'webSQLStorage'\n};\n\nvar DefaultDriverOrder = [DriverType.INDEXEDDB, DriverType.WEBSQL, DriverType.LOCALSTORAGE];\n\nvar LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem'];\n\nvar DefaultConfig = {\n description: '',\n driver: DefaultDriverOrder.slice(),\n name: 'localforage',\n // Default DB size is _JUST UNDER_ 5MB, as it's the highest size\n // we can use without a prompt.\n size: 4980736,\n storeName: 'keyvaluepairs',\n version: 1.0\n};\n\nvar driverSupport = {};\n// Check to see if IndexedDB is available and if it is the latest\n// implementation; it's our preferred backend library. We use \"_spec_test\"\n// as the name of the database because it's not the one we'll operate on,\n// but it's useful to make sure its using the right spec.\n// See: https://github.com/mozilla/localForage/issues/128\ndriverSupport[DriverType.INDEXEDDB] = isIndexedDBValid();\n\ndriverSupport[DriverType.WEBSQL] = isWebSQLValid();\n\ndriverSupport[DriverType.LOCALSTORAGE] = isLocalStorageValid();\n\nvar isArray = Array.isArray || function (arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n};\n\nfunction callWhenReady(localForageInstance, libraryMethod) {\n localForageInstance[libraryMethod] = function () {\n var _args = arguments;\n return localForageInstance.ready().then(function () {\n return localForageInstance[libraryMethod].apply(localForageInstance, _args);\n });\n };\n}\n\nfunction extend() {\n for (var i = 1; i < arguments.length; i++) {\n var arg = arguments[i];\n\n if (arg) {\n for (var key in arg) {\n if (arg.hasOwnProperty(key)) {\n if (isArray(arg[key])) {\n arguments[0][key] = arg[key].slice();\n } else {\n arguments[0][key] = arg[key];\n }\n }\n }\n }\n }\n\n return arguments[0];\n}\n\nfunction isLibraryDriver(driverName) {\n for (var driver in DriverType) {\n if (DriverType.hasOwnProperty(driver) && DriverType[driver] === driverName) {\n return true;\n }\n }\n\n return false;\n}\n\nvar LocalForage = function () {\n function LocalForage(options) {\n _classCallCheck(this, LocalForage);\n\n this.INDEXEDDB = DriverType.INDEXEDDB;\n this.LOCALSTORAGE = DriverType.LOCALSTORAGE;\n this.WEBSQL = DriverType.WEBSQL;\n\n this._defaultConfig = extend({}, DefaultConfig);\n this._config = extend({}, this._defaultConfig, options);\n this._driverSet = null;\n this._initDriver = null;\n this._ready = false;\n this._dbInfo = null;\n\n this._wrapLibraryMethodsWithReady();\n this.setDriver(this._config.driver)[\"catch\"](function () {});\n }\n\n // Set any config values for localForage; can be called anytime before\n // the first API call (e.g. `getItem`, `setItem`).\n // We loop through options so we don't overwrite existing config\n // values.\n\n\n LocalForage.prototype.config = function config(options) {\n // If the options argument is an object, we use it to set values.\n // Otherwise, we return either a specified config value or all\n // config values.\n if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {\n // If localforage is ready and fully initialized, we can't set\n // any new configuration values. Instead, we return an error.\n if (this._ready) {\n return new Error(\"Can't call config() after localforage \" + 'has been used.');\n }\n\n for (var i in options) {\n if (i === 'storeName') {\n options[i] = options[i].replace(/\\W/g, '_');\n }\n\n if (i === 'version' && typeof options[i] !== 'number') {\n return new Error('Database version must be a number.');\n }\n\n this._config[i] = options[i];\n }\n\n // after all config options are set and\n // the driver option is used, try setting it\n if ('driver' in options && options.driver) {\n return this.setDriver(this._config.driver);\n }\n\n return true;\n } else if (typeof options === 'string') {\n return this._config[options];\n } else {\n return this._config;\n }\n };\n\n // Used to define a custom driver, shared across all instances of\n // localForage.\n\n\n LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) {\n var promise = new Promise$1(function (resolve, reject) {\n try {\n var driverName = driverObject._driver;\n var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver');\n var namingError = new Error('Custom driver name already in use: ' + driverObject._driver);\n\n // A driver name should be defined and not overlap with the\n // library-defined, default drivers.\n if (!driverObject._driver) {\n reject(complianceError);\n return;\n }\n if (isLibraryDriver(driverObject._driver)) {\n reject(namingError);\n return;\n }\n\n var customDriverMethods = LibraryMethods.concat('_initStorage');\n for (var i = 0; i < customDriverMethods.length; i++) {\n var customDriverMethod = customDriverMethods[i];\n if (!customDriverMethod || !driverObject[customDriverMethod] || typeof driverObject[customDriverMethod] !== 'function') {\n reject(complianceError);\n return;\n }\n }\n\n var supportPromise = Promise$1.resolve(true);\n if ('_support' in driverObject) {\n if (driverObject._support && typeof driverObject._support === 'function') {\n supportPromise = driverObject._support();\n } else {\n supportPromise = Promise$1.resolve(!!driverObject._support);\n }\n }\n\n supportPromise.then(function (supportResult) {\n driverSupport[driverName] = supportResult;\n CustomDrivers[driverName] = driverObject;\n resolve();\n }, reject);\n } catch (e) {\n reject(e);\n }\n });\n\n executeTwoCallbacks(promise, callback, errorCallback);\n return promise;\n };\n\n LocalForage.prototype.driver = function driver() {\n return this._driver || null;\n };\n\n LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) {\n var self = this;\n var getDriverPromise = Promise$1.resolve().then(function () {\n if (isLibraryDriver(driverName)) {\n switch (driverName) {\n case self.INDEXEDDB:\n return asyncStorage;\n case self.LOCALSTORAGE:\n return localStorageWrapper;\n case self.WEBSQL:\n return webSQLStorage;\n }\n } else if (CustomDrivers[driverName]) {\n return CustomDrivers[driverName];\n } else {\n throw new Error('Driver not found.');\n }\n });\n executeTwoCallbacks(getDriverPromise, callback, errorCallback);\n return getDriverPromise;\n };\n\n LocalForage.prototype.getSerializer = function getSerializer(callback) {\n var serializerPromise = Promise$1.resolve(localforageSerializer);\n executeTwoCallbacks(serializerPromise, callback);\n return serializerPromise;\n };\n\n LocalForage.prototype.ready = function ready(callback) {\n var self = this;\n\n var promise = self._driverSet.then(function () {\n if (self._ready === null) {\n self._ready = self._initDriver();\n }\n\n return self._ready;\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n };\n\n LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) {\n var self = this;\n\n if (!isArray(drivers)) {\n drivers = [drivers];\n }\n\n var supportedDrivers = this._getSupportedDrivers(drivers);\n\n function setDriverToConfig() {\n self._config.driver = self.driver();\n }\n\n function extendSelfWithDriver(driver) {\n self._extend(driver);\n setDriverToConfig();\n\n self._ready = self._initStorage(self._config);\n return self._ready;\n }\n\n function initDriver(supportedDrivers) {\n return function () {\n var currentDriverIndex = 0;\n\n function driverPromiseLoop() {\n while (currentDriverIndex < supportedDrivers.length) {\n var driverName = supportedDrivers[currentDriverIndex];\n currentDriverIndex++;\n\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(extendSelfWithDriver)[\"catch\"](driverPromiseLoop);\n }\n\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n }\n\n return driverPromiseLoop();\n };\n }\n\n // There might be a driver initialization in progress\n // so wait for it to finish in order to avoid a possible\n // race condition to set _dbInfo\n var oldDriverSetDone = this._driverSet !== null ? this._driverSet[\"catch\"](function () {\n return Promise$1.resolve();\n }) : Promise$1.resolve();\n\n this._driverSet = oldDriverSetDone.then(function () {\n var driverName = supportedDrivers[0];\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(function (driver) {\n self._driver = driver._driver;\n setDriverToConfig();\n self._wrapLibraryMethodsWithReady();\n self._initDriver = initDriver(supportedDrivers);\n });\n })[\"catch\"](function () {\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n });\n\n executeTwoCallbacks(this._driverSet, callback, errorCallback);\n return this._driverSet;\n };\n\n LocalForage.prototype.supports = function supports(driverName) {\n return !!driverSupport[driverName];\n };\n\n LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) {\n extend(this, libraryMethodsAndProperties);\n };\n\n LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) {\n var supportedDrivers = [];\n for (var i = 0, len = drivers.length; i < len; i++) {\n var driverName = drivers[i];\n if (this.supports(driverName)) {\n supportedDrivers.push(driverName);\n }\n }\n return supportedDrivers;\n };\n\n LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() {\n // Add a stub for each driver API method that delays the call to the\n // corresponding driver method until localForage is ready. These stubs\n // will be replaced by the driver methods as soon as the driver is\n // loaded, so there is no performance impact.\n for (var i = 0; i < LibraryMethods.length; i++) {\n callWhenReady(this, LibraryMethods[i]);\n }\n };\n\n LocalForage.prototype.createInstance = function createInstance(options) {\n return new LocalForage(options);\n };\n\n return LocalForage;\n}();\n\n// The actual localForage object that we expose as a module or via a\n// global. It's extended by pulling in one of our other libraries.\n\n\nvar localforage_js = new LocalForage();\n\nmodule.exports = localforage_js;\n\n},{\"3\":3}]},{},[4])(4)\n});","module.exports = require('./lib/type');\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n '[object Array]': 'array'\n , '[object RegExp]': 'regexp'\n , '[object Function]': 'function'\n , '[object Arguments]': 'arguments'\n , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n var str = Object.prototype.toString.call(obj);\n if (natives[str]) return natives[str];\n if (obj === null) return 'null';\n if (obj === undefined) return 'undefined';\n if (obj === Object(obj)) return 'object';\n return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n // Let \"new String('')\" return 'object'\n if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n // PhantomJS has type \"DOMWindow\" for null\n if (obj === null) return 'null';\n // PhantomJS has type \"DOMWindow\" for undefined\n if (obj === undefined) return 'undefined';\n return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n if (!(this instanceof Library)) return new Library();\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","(function (document, window) {\n // DEPENDENCIES\n // ============================================================\n\n const localforage = require('localforage');\n const probs = require('pjs-problems');\n const dedent = require('dedent');\n const assert = require('chai').assert;\n\n // PROBLEM TEMPLATE NICE-IFICATION\n // ============================================================\n\n function dedentStrings(problems) {\n return problems.map(prob => {\n prob.given = dedent(prob.given)\n prob.answer = dedent(prob.answer)\n return prob\n });\n }\n\n\n // PROBLEMS\n // ============================================================\n\n let problems = [];\n Object.keys(probs).forEach(subject => {\n problems.push(...probs[subject]);\n });\n problems = dedentStrings(problems)\n console.log('problems:', problems);\n\n\n\n // CONFIG\n // ============================================================\n\n // Hoist current problem\n let currentProblem;\n // Keys to ignore while user is navigating around the textarea but not changing any code\n const ignoreKeyCodes = [\n 9, // Tab\n 37, // Left arrow\n 39, // Right arrow\n 38, // Up arrow\n 40 // Down arrow\n ];\n\n let config = {\n shuffle: true,\n timer: false,\n currentIndex: 0\n };\n\n // Pull config from localforage\n localforage\n .getItem('js_practice_config')\n .then(val => {\n console.log('localforage val:', val);\n if (val) {\n config = val;\n }\n loadApp(config);\n })\n .catch(err => {\n console.log('localforage err:', err);\n loadApp(config);\n });\n\n function updateLocalstore(config) {\n return localforage\n .setItem('js_practice_config', config)\n .then(val => {\n console.log('Settings updated:', val);\n })\n .catch(err => {\n console.log('Settings update error:', err);\n });\n }\n\n\n // UI\n // ============================================================\n\n // elements\n const problemEl = document.getElementById('problem');\n const codeEl = document.getElementById('code');\n const testSuiteEl = document.getElementById('test-suite');\n const testTotalEl = document.getElementById('test-total');\n const evalConsoleEl = document.getElementById('eval-output');\n const assertConsoleEl = document.getElementById('assert-output');\n const shuffleProblemsButtonEl = document.getElementById('shuffle-problems');\n const previousProblemButtonEl = document.getElementById('prev-problem');\n const nextProblemButtonEl = document.getElementById('next-problem');\n\n // Get indexes\n function getRandomIndex(problemsArr) {\n const ind = Math.floor(Math.random() * problemsArr.length);\n config.currentIndex = ind;\n updateLocalstore(config);\n return ind;\n }\n\n function getPreviousIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at beginning, go to end\n if (currentIndex === 0) {\n probInd = problemsArr.length - 1;\n } else {\n probInd = currentIndex - 1;\n }\n return probInd;\n }\n\n function getNextIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at end or invalid, restart series\n if (currentIndex >= problemsArr.length - 1 || currentIndex < 0) {\n probInd = 0;\n } else {\n probInd = currentIndex + 1;\n }\n return probInd;\n }\n\n // Get problems\n function getCurrentProblem(problemsArr) {\n return problemsArr[config.currentIndex];\n }\n\n function previousProblem() {\n console.log('previousProblem!');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getPreviousIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function nextProblem() {\n console.log('nextProblem!');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getNextIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function toggleShuffle() {\n console.log('toggle shuffle!');\n config.shuffle = !config.shuffle; // Flip it\n shuffleProblemsButtonEl.classList.toggle('active');\n updateLocalstore(config);\n }\n\n function loadProblem(problemObj) {\n currentProblem = problemObj;\n // Prob question\n problemEl.innerText = problemObj.prompt;\n // Prob given code\n if (problemObj.given) {\n codeEl.value = problemObj.given;\n }\n // Seed the tests, pass (init = true) as second param\n testSuite(null, true);\n }\n\n function updateTests(testStatus, init) {\n if (init === true) {\n buildTests(currentProblem.tests);\n }\n updateTestStatus(testStatus);\n }\n\n function buildTests(tests) {\n if (tests) {\n const testsDom = tests\n .map(test => {\n return `
\n
[✘]
\n
${test.name}
\n
`;\n })\n .join('');\n testSuiteEl.innerHTML = testsDom;\n }\n }\n\n function updateTestStatus(testStatuses) {\n if (!testStatuses) {\n throw new Error('No testStatuses provided.');\n }\n // Find out if all tests have passed or not\n let allPassed = true;\n testStatuses.forEach(testPassed => {\n if (testPassed !== true) {\n allPassed = false;\n }\n });\n const testEls = Array.from(testSuiteEl.querySelectorAll('.test-state'));\n testEls.forEach((testStatusEl, iter) => {\n if (testStatuses[iter] === true) {\n testStatusEl.innerHTML = '[✓]';\n testStatusEl.classList.remove('fail');\n testStatusEl.classList.add('pass');\n } else {\n testStatusEl.innerHTML = '[✘]';\n testStatusEl.classList.remove('pass');\n testStatusEl.classList.add('fail');\n }\n });\n\n if (allPassed === true) {\n testTotalEl.innerText = 'PASS';\n testTotalEl.classList.remove('fail');\n testTotalEl.classList.add('pass');\n } else {\n testTotalEl.innerText = 'FAIL';\n testTotalEl.classList.remove('pass');\n testTotalEl.classList.add('fail');\n }\n }\n\n function printAssertError(errObj) {\n // Make element string\n let inner = '';\n if (errObj !== null) {\n inner = `\n
\n Expected: ${JSON.stringify(errObj.expected)}\n Actual: ${JSON.stringify(errObj.actual)}\n
`;\n }\n\n // Prepend element\n assertConsoleEl.innerHTML = inner;\n }\n\n function printEvalOutput(errObj, output) {\n // Make element string\n let inner = '';\n if (errObj && errObj.message !== undefined) {\n inner = `\n
\n Syntax Error: ${JSON.stringify(errObj.message)}\n
`;\n } else if (output) {\n inner = `\n
\n Output: ${JSON.stringify(output)}\n
`;\n }\n // Prepend element\n evalConsoleEl.innerHTML = inner;\n }\n\n\n // VERIFICATION LOGIC\n // ============================================================\n\n function testSuite(init) {\n // Run stuff\n const output = getOutput(codeEl.value);\n // Run tests on code, return object/array of test results\n const tested = runTests(output);\n // Update UI with results\n updateTests(tested, init);\n }\n\n function getOutput(code) {\n let evald = false;\n try {\n evald = eval(`(function(){${code}})()`); // eslint-disable-line no-eval\n printEvalOutput(null, evald); // Print current output\n } catch (err) {\n printEvalOutput(err);\n }\n return evald;\n }\n\n function runTests(output) {\n let tested = false;\n tested = currentProblem.tests.map(test => {\n let testOutcome = false;\n try {\n if (output) {\n // const testEval = eval(test.test);\n\n testOutcome = eval(test.test);\n console.log('testOutcome:', testOutcome);\n\n }\n printAssertError(null);\n } catch (err) {\n printAssertError(err);\n }\n return testOutcome;\n });\n return tested;\n }\n\n // Wrapped to prevent race with local config retrieval\n function loadApp(config) {\n console.log('loading app!');\n\n // Show current toggle state\n if (config.shuffle === true) {\n shuffleProblemsButtonEl.classList.add('active');\n }\n\n // Bind it up\n codeEl.addEventListener('keyup', e => {\n // If not arrow keys or other non-character keys\n if (ignoreKeyCodes.indexOf(e.keyCode) === -1) {\n // Run test suite\n testSuite();\n }\n });\n shuffleProblemsButtonEl.addEventListener('click', toggleShuffle);\n previousProblemButtonEl.addEventListener('click', previousProblem);\n nextProblemButtonEl.addEventListener('click', nextProblem);\n\n // Start it up!\n // Load current problem\n const currProb = getCurrentProblem(problems);\n loadProblem(currProb);\n // Initalized test suite with starting failures\n testSuite(true);\n }\n})(document, window);\n"],"preExistingComment":"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2Jyb3dzZXItcGFjay82LjAuMi9ub2RlX21vZHVsZXMvYnJvd3Nlci1wYWNrL19wcmVsdWRlLmpzIiwibm9kZV9tb2R1bGVzLy5naXRodWIuY29tL3ByYWN0aWNlamF2YXNjcmlwdC9wanMtcHJvYmxlbXMvMDgyM2NjMWNmZmI5OTkzNTJlM2YwY2FlZDI5NWRmODYzM2YxMzkxNi9ub2RlX21vZHVsZXMvcGpzLXByb2JsZW1zL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzLy5naXRodWIuY29tL3ByYWN0aWNlamF2YXNjcmlwdC9wanMtcHJvYmxlbXMvMDgyM2NjMWNmZmI5OTkzNTJlM2YwY2FlZDI5NWRmODYzM2YxMzkxNi9ub2RlX21vZHVsZXMvcGpzLXByb2JsZW1zL3Byb2JsZW1zL2FycmF5cy5qcyIsIm5vZGVfbW9kdWxlcy8uZ2l0aHViLmNvbS9wcmFjdGljZWphdmFzY3JpcHQvcGpzLXByb2JsZW1zLzA4MjNjYzFjZmZiOTk5MzUyZTNmMGNhZWQyOTVkZjg2MzNmMTM5MTYvbm9kZV9tb2R1bGVzL3Bqcy1wcm9ibGVtcy9wcm9ibGVtcy9pbml0aWFsLmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvYXNzZXJ0aW9uLWVycm9yLzEuMC4yL25vZGVfbW9kdWxlcy9hc3NlcnRpb24tZXJyb3IvaW5kZXguanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvYXNzZXJ0aW9uLmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS9jb25maWcuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL2NvcmUvYXNzZXJ0aW9ucy5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvaW50ZXJmYWNlL2Fzc2VydC5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvaW50ZXJmYWNlL2V4cGVjdC5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvaW50ZXJmYWNlL3Nob3VsZC5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvYWRkQ2hhaW5hYmxlTWV0aG9kLmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9hZGRNZXRob2QuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2FkZFByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9leHBlY3RUeXBlcy5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZmxhZy5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0QWN0dWFsLmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9nZXRFbnVtZXJhYmxlUHJvcGVydGllcy5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0TWVzc2FnZS5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0TmFtZS5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0UGF0aEluZm8uanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2dldFBhdGhWYWx1ZS5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvZ2V0UHJvcGVydGllcy5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvaGFzUHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9pbnNwZWN0LmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9vYmpEaXNwbGF5LmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvY2hhaS8zLjUuMC9ub2RlX21vZHVsZXMvY2hhaS9saWIvY2hhaS91dGlscy9vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL292ZXJ3cml0ZU1ldGhvZC5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2NoYWkvMy41LjAvbm9kZV9tb2R1bGVzL2NoYWkvbGliL2NoYWkvdXRpbHMvb3ZlcndyaXRlUHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL3Rlc3QuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9jaGFpLzMuNS4wL25vZGVfbW9kdWxlcy9jaGFpL2xpYi9jaGFpL3V0aWxzL3RyYW5zZmVyRmxhZ3MuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy9kZWRlbnQvMC43LjAvbm9kZV9tb2R1bGVzL2RlZGVudC9kaXN0L2RlZGVudC5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2RlZXAtZXFsLzAuMS4zL25vZGVfbW9kdWxlcy9kZWVwLWVxbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy8ucmVnaXN0cnkubnBtanMub3JnL2RlZXAtZXFsLzAuMS4zL25vZGVfbW9kdWxlcy9kZWVwLWVxbC9saWIvZXFsLmpzIiwibm9kZV9tb2R1bGVzLy5yZWdpc3RyeS5ucG1qcy5vcmcvbG9jYWxmb3JhZ2UvMS41LjAvbm9kZV9tb2R1bGVzL2xvY2FsZm9yYWdlL2Rpc3Qvbm9kZV9tb2R1bGVzL2xvY2FsZm9yYWdlL2Rpc3QvbG9jYWxmb3JhZ2UuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy90eXBlLWRldGVjdC8wLjEuMS9ub2RlX21vZHVsZXMvdHlwZS1kZXRlY3QvaW5kZXguanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy90eXBlLWRldGVjdC8wLjEuMS9ub2RlX21vZHVsZXMvdHlwZS1kZXRlY3QvbGliL3R5cGUuanMiLCJub2RlX21vZHVsZXMvLnJlZ2lzdHJ5Lm5wbWpzLm9yZy90eXBlLWRldGVjdC8xLjAuMC9ub2RlX21vZHVsZXMvdHlwZS1kZXRlY3QvbGliL3R5cGUuanMiLCJzcmMvanMvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFlQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSEE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25JQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwMERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN21EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9VQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3REQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNEQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDalFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3h3RUE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDOUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0FDdElBLENBQUMsVUFBVSxRQUFWLEVBQW9CLE1BQXBCLEVBQTRCO0FBQzNCO0FBQ0E7O0FBRUEsTUFBTSxjQUFjLFFBQVEsYUFBUixDQUFwQjtBQUNBLE1BQU0sUUFBUSxRQUFRLGNBQVIsQ0FBZDtBQUNBLE1BQU0sU0FBUyxRQUFRLFFBQVIsQ0FBZjtBQUNBLE1BQU0sU0FBUyxRQUFRLE1BQVIsRUFBZ0IsTUFBL0I7O0FBRUE7QUFDQTs7QUFFQSxXQUFTLGFBQVQsQ0FBdUIsUUFBdkIsRUFBaUM7QUFDL0IsV0FBTyxTQUFTLEdBQVQsQ0FBYSxnQkFBUTtBQUMxQixXQUFLLEtBQUwsR0FBYSxPQUFPLEtBQUssS0FBWixDQUFi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QSxXQUFPLGdCQUFQLENBQXdCLE9BQXhCLEVBQWlDLGFBQUs7QUFDcEM7QUFDQSxVQUFJLGVBQWUsT0FBZixDQUF1QixFQUFFLE9BQXpCLE1BQXNDLENBQUMsQ0FBM0MsRUFBOEM7QUFDNUM7QUFDQTtBQUNEO0FBQ0YsS0FORDtBQU9BLDRCQUF3QixnQkFBeEIsQ0FBeUMsT0FBekMsRUFBa0QsYUFBbEQ7QUFDQSw0QkFBd0IsZ0JBQXhCLENBQXlDLE9BQXpDLEVBQWtELGVBQWxEO0FBQ0Esd0JBQW9CLGdCQUFwQixDQUFxQyxPQUFyQyxFQUE4QyxXQUE5Qzs7QUFFQTtBQUNBO0FBQ0EsUUFBTSxXQUFXLGtCQUFrQixRQUFsQixDQUFqQjtBQUNBLGdCQUFZLFFBQVo7QUFDQTtBQUNBLGNBQVUsSUFBVjtBQUNEO0FBQ0YsQ0E1VUQsRUE0VUcsUUE1VUgsRUE0VWEsTUE1VWIiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIGluaXRpYWw6IHJlcXVpcmUoJy4vcHJvYmxlbXMvaW5pdGlhbCcpLFxuICBhcnJheXM6IHJlcXVpcmUoJy4vcHJvYmxlbXMvYXJyYXlzJylcbn07IiwibW9kdWxlLmV4cG9ydHMgPSBbXG4gIHtcbiAgICBuYW1lOiAnQWNjZXNzIEFycmF5IGJ5IGluZGV4IChmaXJzdCknLFxuICAgIHRpbWU6IDEwLFxuICAgIHByb21wdDogJ1JldHVybiB0aGUgZmlyc3QgdmFsdWUgb2YgdGhlIEFycmF5JyxcbiAgICBnaXZlbjogYGNvbnN0IGZydWl0cyA9IFsnYXBwbGUnLCAnYmFuYW5hJ107XFxyYCxcbiAgICBhbnN3ZXI6IGBjb25zdCBmcnVpdHMgPSBbJ2FwcGxlJywgJ2JhbmFuYSddO1xuICAgICAgICAgICAgIHJldHVybiBmcnVpdHNbMF07YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiAnYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXQsIFxcJ2FwcGxlXFwnKSA9PT0gdW5kZWZpbmVkJ1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ1JldHVybnMgYSBTdHJpbmcnLFxuICAgICAgICB0ZXN0OiAnYXNzZXJ0LmlzU3RyaW5nKG91dHB1dCkgPT09IHVuZGVmaW5lZCdcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQWNjZXNzIEFycmF5IGJ5IGluZGV4IChsYXN0KScsXG4gICAgdGltZTogMTAsXG4gICAgcHJvbXB0OiAnUmV0dXJuIHRoZSBsYXN0IHZhbHVlIG9mIHRoZSBBcnJheScsXG4gICAgZ2l2ZW46IGBjb25zdCBmcnVpdHMgPSBbJ2FwcGxlJywgJ2JhbmFuYScsICdvcmFuZ2UnXTtcXHJgLFxuICAgIGFuc3dlcjogYGNvbnN0IGZydWl0cyA9IFsnYXBwbGUnLCAnYmFuYW5hJywgJ29yYW5nZSddO1xuICAgICAgICAgICAgIHJldHVybiBmcnVpdHNbZnJ1aXRzLmxlbmd0aCAtIDFdO2AsXG4gICAgdGVzdHM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0NvcnJlY3Qgb3V0cHV0JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCAnb3JhbmdlJykgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnUmV0dXJucyBhIFN0cmluZycsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuaXNTdHJpbmcob3V0cHV0KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQWNjZXNzIEFycmF5IGJ5IGluZGV4IChzZWNvbmQpJyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6ICdSZXR1cm4gdGhlIHNlY29uZCB2YWx1ZSBvZiB0aGUgQXJyYXknLFxuICAgIGdpdmVuOiBgY29uc3QgZnJ1aXRzID0gWydhcHBsZScsICdiYW5hbmEnXTtcXHJgLFxuICAgIGFuc3dlcjogYGNvbnN0IGZydWl0cyA9IFsnYXBwbGUnLCAnYmFuYW5hJ107XG4gICAgICAgICAgICAgcmV0dXJuIGZydWl0c1sxXTtgLFxuICAgIHRlc3RzOiBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdDb3JyZWN0IG91dHB1dCcsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuZGVlcEVxdWFsKG91dHB1dCwgJ2JhbmFuYScpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ1JldHVybnMgYSBTdHJpbmcnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzU3RyaW5nKG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9XG4gICAgXVxuICB9LFxuICB7XG4gICAgbmFtZTogJ0FycmF5LmZvckVhY2goKScsXG4gICAgdGltZTogMjAsXG4gICAgcHJvbXB0OiAnTG9vcCBvdmVyIHRoZSBhcnJheSwgYWRkIGFuIFxcJ3hcXCcgdG8gdGhlIGVuZCBvZiBlYWNoIG5hbWUsIHB1c2ggZWFjaCBmcnVpdCBpbnRvIGEgbmV3IGFycmF5LCB0aGVuIHJldHVybiB0aGUgbmV3IGFycmF5LicsXG4gICAgZ2l2ZW46IGBjb25zdCBmcnVpdHMgPSBbJ2FwcGxlJywgJ2JhbmFuYSddO1xccmAsXG4gICAgYW5zd2VyOiBgY29uc3QgZnJ1aXRzID0gWydhcHBsZScsICdiYW5hbmEnXTtcbiAgICAgICAgICAgICBjb25zdCBuZXdGcnVpdHMgPSBbXTtcbiAgICAgICAgICAgICBmcnVpdHMuZm9yRWFjaChmdW5jdGlvbihpdGVtKSB7XG4gICAgICAgICAgICAgICBuZXdGcnVpdHMucHVzaChpdGVtKyd4Jyk7XG4gICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgcmV0dXJuIG5ld0ZydWl0cztgLFxuICAgIHRlc3RzOiBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdDb3JyZWN0IG91dHB1dCcsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuZGVlcEVxdWFsKG91dHB1dCwgWydhcHBsZXgnLCAnYmFuYW5heCddKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGFuIEFycmF5JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc0FycmF5KG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnQXJyYXkgaGFzIDIgaXRlbXMnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0Lmxlbmd0aE9mKG91dHB1dCwgMikgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9XG4gICAgXVxuICB9LFxuICB7XG4gICAgbmFtZTogJ0FycmF5LnB1c2goKScsXG4gICAgdGltZTogMTAsXG4gICAgcHJvbXB0OiBgQWRkICdvcmFuZ2UnIHRvIHRoZSBlbmQgb2YgdGhlICdmcnVpdHMnIGFycmF5IGFuZCByZXR1cm4gJ2ZydWl0cycuYCxcbiAgICBnaXZlbjogYGNvbnN0IGZydWl0cyA9IFsnYXBwbGUnLCAnYmFuYW5hJ107XFxyYCxcbiAgICBhbnN3ZXI6IGBjb25zdCBmcnVpdHMgPSBbJ2FwcGxlJywgJ2JhbmFuYSddO1xuICAgICAgICAgICAgIGZydWl0cy5wdXNoKCdvcmFuZ2UnKTtcbiAgICAgICAgICAgICByZXR1cm4gZnJ1aXRzO2AsXG4gICAgdGVzdHM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0NvcnJlY3Qgb3V0cHV0JyxcbiAgICAgICAgdGVzdDogYChhc3NlcnQuZGVlcEVxdWFsKG91dHB1dCwgWydhcHBsZScsICdiYW5hbmEnLCAnb3JhbmdlJ10pID09PSB1bmRlZmluZWQpO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGFuIEFycmF5JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc0FycmF5KG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnQXJyYXkgaGFzIDMgaXRlbXMnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0Lmxlbmd0aE9mKG91dHB1dCwgMykgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9XG4gICAgXVxuICB9LFxuICB7XG4gICAgbmFtZTogJ0FycmF5LnNoaWZ0KCknLFxuICAgIHRpbWU6IDEwLFxuICAgIHByb21wdDogYFJlbW92ZSAnYXBwbGUnIGZyb20gdGhlIGZyb250IG9mIHRoZSAnZnJ1aXRzJyBhcnJheSBhbmQgcmV0dXJuICdmcnVpdHMnLmAsXG4gICAgZ2l2ZW46IGBjb25zdCBmcnVpdHMgPSBbJ2FwcGxlJywgJ2JhbmFuYScsICdvcmFuZ2UnXTtcXHJgLFxuICAgIGFuc3dlcjogYGNvbnN0IGZydWl0cyA9IFsnYXBwbGUnLCAnYmFuYW5hJywgJ29yYW5nZSddO1xuICAgICAgICAgICAgIGZydWl0cy5zaGlmdCgpO1xuICAgICAgICAgICAgIHJldHVybiBmcnVpdHM7YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnT3V0cHV0IG11c3QgYmUgY29ycmVjdCcsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuZGVlcEVxdWFsKG91dHB1dCwgWydiYW5hbmEnLCAnb3JhbmdlJ10pID09PSB1bmRlZmluZWQ7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ1JldHVybnMgYW4gQXJyYXknLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzQXJyYXkob3V0cHV0KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdBcnJheSBoYXMgMiBpdGVtcycsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQubGVuZ3RoT2Yob3V0cHV0LCAyKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQXJyYXkudW5zaGlmdCgpJyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6IGBBZGQgJ3N0cmF3YmVycnknIHRvIHRoZSBmcm9udCBvZiB0aGUgJ2ZydWl0cycgYXJyYXkgYW5kIHJldHVybiAnZnJ1aXRzJy5gLFxuICAgIGdpdmVuOiBgY29uc3QgZnJ1aXRzID0gWydhcHBsZScsICdiYW5hbmEnLCAnb3JhbmdlJ107XFxyYCxcbiAgICBhbnN3ZXI6IGBjb25zdCBmcnVpdHMgPSBbJ2FwcGxlJywgJ2JhbmFuYScsICdvcmFuZ2UnXTtcbiAgICAgICAgICAgICBmcnVpdHMudW5zaGlmdCgnc3RyYXdiZXJyeScpO1xuICAgICAgICAgICAgIHJldHVybiBmcnVpdHM7YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnT3V0cHV0IG11c3QgYmUgY29ycmVjdCcsXG4gICAgICAgIHRlc3Q6IGAoYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXQsIFtcbiAgICAgICAgICAgICAgICAgICdzdHJhd2JlcnJ5JyxcbiAgICAgICAgICAgICAgICAgICdhcHBsZScsXG4gICAgICAgICAgICAgICAgICAnYmFuYW5hJyxcbiAgICAgICAgICAgICAgICAgICdvcmFuZ2UnXG4gICAgICAgICAgICAgICAgXSkgPT09IHVuZGVmaW5lZClgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnTXVzdCByZXR1cm4gYW4gQXJyYXknLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzQXJyYXkob3V0cHV0KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdBcnJheSBoYXMgNCBpdGVtcycsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQubGVuZ3RoT2Yob3V0cHV0LCA0KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQXJyYXkuaW5kZXhPZigpJyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6IGBSZXR1cm4gdGhlIGluZGV4IG9mICdiYW5hbmEnIGluIHRoZSBBcnJheS5gLFxuICAgIGdpdmVuOiBgY29uc3QgZnJ1aXRzID0gWydzdHJhd2JlcnJ5JywgJ2JhbmFuYScsICdtYW5nbyddO1xccmAsXG4gICAgYW5zd2VyOiBgY29uc3QgZnJ1aXRzID0gWydzdHJhd2JlcnJ5JywgJ2JhbmFuYScsICdtYW5nbyddO1xuICAgICAgICAgICAgIGNvbnN0IGluZCA9IGZydWl0cy5pbmRleE9mKCdiYW5hbmEnKTtcbiAgICAgICAgICAgICByZXR1cm4gaW5kO2AsXG4gICAgdGVzdHM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0NvcnJlY3Qgb3V0cHV0JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCAxKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGEgTnVtYmVyJyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc051bWJlcihvdXRwdXQpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIG5hbWU6ICdBcnJheS5jb25jYXQoKScsXG4gICAgdGltZTogMTAsXG4gICAgcHJvbXB0OiBgTWVyZ2UgdGhlIHR3byBhcnJheXMgdXNpbmcgQXJyYXkncyAnY29uY2F0KCknIG1ldGhvZC4gUmV0dXJuIHRoZSByZXN1bHRpbmcgYXJyYXkuYCxcbiAgICBnaXZlbjogYGNvbnN0IGZydWl0cyA9IFsnc3RyYXdiZXJyeScsICdiYW5hbmEnXTtcXHJjb25zdCBvdGhlckZydWl0cyA9IFsncGVhcicsJ3BlYWNoJ107XFxyYCxcbiAgICBhbnN3ZXI6IGBjb25zdCBmcnVpdHMgPSBbJ3N0cmF3YmVycnknLCAnYmFuYW5hJ107XG4gICAgICAgICAgICBjb25zdCBvdGhlckZydWl0cyA9IFsncGVhcicsJ3BlYWNoJ107XG4gICAgICAgICAgICBjb25zdCBhbGxUaGVGcnVpdHMgPSBmcnVpdHMuY29uY2F0KG90aGVyRnJ1aXRzKTtcbiAgICAgICAgICAgIHJldHVybiBhbGxUaGVGcnVpdHM7XFxyYCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiBgKGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCBbXG4gICAgICAgICAgICAgICAgICAnc3RyYXdiZXJyeScsXG4gICAgICAgICAgICAgICAgICAnYmFuYW5hJyxcbiAgICAgICAgICAgICAgICAgICdwZWFyJyxcbiAgICAgICAgICAgICAgICAgICdwZWFjaCdcbiAgICAgICAgICAgICAgICBdKSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICk7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ1JldHVybnMgYW4gQXJyYXknLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzQXJyYXkob3V0cHV0KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdBcnJheSBoYXMgNCBpdGVtcycsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQubGVuZ3RoT2Yob3V0cHV0LCA0KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQXJyYXkuam9pbigpJyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6IGBNaXggdGhlIHR3byBmbGF2b3JzIHdpdGggYSAnLScgdXNpbmcgQXJyYXkncyAnam9pbicgbWV0aG9kLiBSZXR1cm4gdGhlIHJlc3VsdGluZyBoeWJyaWQgZmxhdm9yLmAsXG4gICAgZ2l2ZW46IGBjb25zdCBmcnVpdHMgPSBbJ3N0cmF3YmVycnknLCAnYmFuYW5hJ107XFxyYCxcbiAgICBhbnN3ZXI6IGBjb25zdCBmcnVpdHMgPSBbJ3N0cmF3YmVycnknLCAnYmFuYW5hJ107XG4gICAgICAgICAgICAgY29uc3QgaHlicmlkID0gZnJ1aXRzLmpvaW4oJy0nKTtcbiAgICAgICAgICAgICByZXR1cm4gaHlicmlkO1xccmAsXG4gICAgdGVzdHM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0NvcnJlY3Qgb3V0cHV0JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCAnc3RyYXdiZXJyeS1iYW5hbmEnKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGEgU3RyaW5nJyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc1N0cmluZyhvdXRwdXQpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIG5hbWU6ICdBcnJheS5zbGljZSgpJyxcbiAgICB0aW1lOiAyMCxcbiAgICBwcm9tcHQ6IGBSZXR1cm4ganVzdCB0aGUgY2l0cnVzIGZydWl0cyBmcm9tIHRoZSAnZnJ1aXRzJyBhcnJheSB1c2luZyAnQXJyYXkuc2xpY2UoKSdgLFxuICAgIGdpdmVuOiBgY29uc3QgZnJ1aXRzID0gWydzdHJhd2JlcnJ5JywgJ29yYW5nZScsICdsZW1vbicsICdiYW5hbmEnXTtcXHJgLFxuICAgIGFuc3dlcjogYGNvbnN0IGZydWl0cyA9IFsnc3RyYXdiZXJyeScsICdvcmFuZ2UnLCAnbGVtb24nLCAnYmFuYW5hJ107XG4gICAgICAgICAgICAgY29uc3QgY2l0cnVzID0gZnJ1aXRzLnNsaWNlKDEsIDMpO1xuICAgICAgICAgICAgIHJldHVybiBjaXRydXM7YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXQsIFsnb3JhbmdlJywgJ2xlbW9uJ10pID09PSB1bmRlZmluZWQ7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ1JldHVybnMgYW4gQXJyYXknLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzQXJyYXkob3V0cHV0KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdBcnJheSBoYXMgMiBpdGVtcycsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQubGVuZ3RoT2Yob3V0cHV0LCAyKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQXJyYXkucmV2ZXJzZSgpJyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6IGBSZXZlcnNlIHRoZSBvcmRlciBvZiB0aGUgJ2ZydWl0JyBhcnJheSB1c2luZyAnQXJyYXkucmV2ZXJzZSgpJ2AsXG4gICAgZ2l2ZW46IGBjb25zdCBmcnVpdHMgPSBbJ3N0cmF3YmVycnknLCAnb3JhbmdlJywgJ2xlbW9uJywgJ2JhbmFuYSddO1xccmAsXG4gICAgYW5zd2VyOiBgY29uc3QgZnJ1aXRzID0gWydzdHJhd2JlcnJ5JywgJ29yYW5nZScsICdsZW1vbicsICdiYW5hbmEnXTtcbiAgICAgICAgICAgICBjb25zdCBzdGl1cmYgPSBmcnVpdHMucmV2ZXJzZSgpO1xuICAgICAgICAgICAgIHJldHVybiBzdGl1cmY7YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiBgKGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCBbXG4gICAgICAgICAgICAgICAgICAnYmFuYW5hJyxcbiAgICAgICAgICAgICAgICAgICdsZW1vbicsXG4gICAgICAgICAgICAgICAgICAnb3JhbmdlJyxcbiAgICAgICAgICAgICAgICAgICdzdHJhd2JlcnJ5J1xuICAgICAgICAgICAgICAgIF0pID09PSB1bmRlZmluZWQpO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGFuIEFycmF5JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc0FycmF5KG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnQXJyYXkgaGFzIDQgaXRlbXMnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0Lmxlbmd0aE9mKG91dHB1dCwgNCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiBgRmlyc3QgaXRlbSBpcyAnYmFuYW5hJ2AsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuZGVlcEVxdWFsKG91dHB1dFswXSwgJ2JhbmFuYScpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIG5hbWU6ICdBcnJheS5zb3J0KCknLFxuICAgIHRpbWU6IDEwLFxuICAgIHByb21wdDogYFJldHVybiB0aGUgJ2ZydWl0cycgQXJyYXkgYWZ0ZXIgc29ydGluZyB0aGVtIHVzaW5nICdBcnJheS5zb3J0KCknLmAsXG4gICAgZ2l2ZW46IGBjb25zdCBmcnVpdHMgPSBbJ3N0cmF3YmVycnknLCAnb3JhbmdlJywgJ2xlbW9uJywgJ2JhbmFuYSddO1xccmAsXG4gICAgYW5zd2VyOiBgY29uc3QgZnJ1aXRzID0gWydzdHJhd2JlcnJ5JywgJ29yYW5nZScsICdsZW1vbicsICdiYW5hbmEnXTtcbiAgICAgICAgICAgICBjb25zdCBvcmRlcmx5RnJ1aXQgPSBmcnVpdHMuc29ydCgpO1xuICAgICAgICAgICAgIHJldHVybiBvcmRlcmx5RnJ1aXQ7YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiBgKGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCBbXG4gICAgICAgICAgICAgICAgICAnYmFuYW5hJyxcbiAgICAgICAgICAgICAgICAgICdsZW1vbicsXG4gICAgICAgICAgICAgICAgICAnb3JhbmdlJyxcbiAgICAgICAgICAgICAgICAgICdzdHJhd2JlcnJ5J1xuICAgICAgICAgICAgICAgIF0pID09PSB1bmRlZmluZWQpO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGFuIEFycmF5JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc0FycmF5KG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnQXJyYXkgaGFzIDQgaXRlbXMnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0Lmxlbmd0aE9mKG91dHB1dCwgNCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiBgRmlyc3QgaXRlbSBpcyAnYmFuYW5hJ2AsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuZGVlcEVxdWFsKG91dHB1dFswXSwgJ2JhbmFuYScpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIG5hbWU6ICdBcnJheS5sYXN0SW5kZXhPZigpJyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6IGBSZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBsYXN0ICdwZWFjaCcgaW5zdGFuY2UgaW4gdGhlICdmcnVpdCcgYXJyYXkgdXNpbmcgJ0FycmF5Lmxhc3RJbmRleE9mKCknYCxcbiAgICBnaXZlbjogYGNvbnN0IGZydWl0cyA9IFsncGVhY2gnLCAnb3JhbmdlJywgJ2xlbW9uJywgJ3BlYWNoJ107XFxyYCxcbiAgICBhbnN3ZXI6IGBjb25zdCBmcnVpdHMgPSBbJ3BlYWNoJywgJ29yYW5nZScsICdsZW1vbicsICdwZWFjaCddO1xuICAgICAgICAgICAgIGNvbnN0IHdoZXJlc1RoZUxhc3RQZWFjaCA9IGZydWl0cy5sYXN0SW5kZXhPZigncGVhY2gnKTtcbiAgICAgICAgICAgICByZXR1cm4gd2hlcmVzVGhlTGFzdFBlYWNoO2AsXG4gICAgdGVzdHM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0NvcnJlY3Qgb3V0cHV0JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCAzKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGEgTnVtYmVyJyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc051bWJlcihvdXRwdXQpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIG5hbWU6ICdBcnJheS5maWx0ZXIoKScsXG4gICAgdGltZTogMTAsXG4gICAgcHJvbXB0OiBgUmV0dXJuIGFuIGFycmF5IG9mIHRoZSBudW1iZXJzIGdyZWF0ZXIgdGhhbiA1IGluICdudW1iZXJzJyB1c2luZyAnQXJyYXkuZmlsdGVyKCknYCxcbiAgICBnaXZlbjogYGNvbnN0IG51bWJlcnMgPSBbMSwgMSwgMiwgMywgNSwgOCwgMTMsIDIxXTtcXHJgLFxuICAgIGFuc3dlcjogYGNvbnN0IG51bWJlcnMgPSBbMSwgMSwgMiwgMywgNSwgOCwgMTMsIDIxXTtcbiAgICAgICAgICAgICBjb25zdCBvdmVyRml2ZSA9IG51bWJlcnMuZmlsdGVyKG51bSA9PiBudW0gPiA1KTtcbiAgICAgICAgICAgICByZXR1cm4gb3ZlckZpdmU7YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXQsIFs4LCAxMywgMjFdKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGFuIEFycmF5JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc0FycmF5KG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnQXJyYXkgaGFzIDMgaXRlbXMnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0Lmxlbmd0aE9mKG91dHB1dCwgMykgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiBgRmlyc3QgaXRlbSBpcyA4YCxcbiAgICAgICAgdGVzdDogYGFzc2VydC5kZWVwRXF1YWwob3V0cHV0WzBdLCA4KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQXJyYXkubWFwKCknLFxuICAgIHRpbWU6IDEwLFxuICAgIHByb21wdDogYFJldHVybiBhbiBhcnJheSBvZiAnbnVtYmVycycgYXJyYXkncyBzcXVhcmUgcm9vdHMsIHVzaW5nICdBcnJheS5tYXAoKScgYW5kICdNYXRoLnNxcnQoKSdgLFxuICAgIGdpdmVuOiBgY29uc3QgbnVtYmVycyA9IFsyNSwgMTIxLCAxNjldO1xccmAsXG4gICAgYW5zd2VyOiBgY29uc3QgbnVtYmVycyA9IFsyNSwgMTIxLCAxNjldO1xuICAgICAgICAgICAgIGNvbnN0IHJvb3RzID0gbnVtYmVycy5tYXAobnVtID0+IE1hdGguc3FydChudW0pKTtcbiAgICAgICAgICAgICByZXR1cm4gcm9vdHM7YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXQsIFs1LCAxMSwgMTNdKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdSZXR1cm5zIGFuIEFycmF5JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc0FycmF5KG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnQXJyYXkgaGFzIDMgaXRlbXMnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0Lmxlbmd0aE9mKG91dHB1dCwgMykgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiBgRmlyc3QgaXRlbSBpcyA1YCxcbiAgICAgICAgdGVzdDogYGFzc2VydC5kZWVwRXF1YWwob3V0cHV0WzBdLCA1KSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6IGBMYXN0IGl0ZW0gaXMgMTNgLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXRbb3V0cHV0Lmxlbmd0aCAtIDFdLCAxMykgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9XG4gICAgXVxuICB9LFxuICB7XG4gICAgbmFtZTogJ0FycmF5LmV2ZXJ5KCknLFxuICAgIHRpbWU6IDEwLFxuICAgIHByb21wdDogYFJldHVybiBvYmplY3QgdGhhdCByZXR1cm5zIHdoZXRoZXIgZWFjaCBhcnJheSBjb250YWlucyBhbGwgZXZlbiBudW1iZXJzIHVzaW5nIEFycmF5LmV2ZXJ5KCkuYCxcbiAgICBnaXZlbjogYGNvbnN0IGV2ZW5OdW1iZXJzID0gWzIsIDQsIDYsIDhdO1xuICAgICAgICAgICAgY29uc3Qgc29tZU9kZE51bWJlcnMgPSBbMiwgNSwgNiwgOF07XG4gICAgICAgICAgICBmdW5jdGlvbiBpc0V2ZW4oZWxlbWVudCkge1xuICAgICAgICAgICAgXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBldmVuTnVtYmVyczogZXZlbk51bWJlcnMuLFxuICAgICAgICAgICAgICBzb21lT2RkTnVtYmVyczogc29tZU9kZE51bWJlcnMuXG4gICAgICAgICAgICB9O2AsXG4gICAgYW5zd2VyOiBgY29uc3QgZXZlbk51bWJlcnMgPSBbMiwgNCwgNiwgOF07XG4gICAgICAgICAgICAgY29uc3Qgc29tZU9kZE51bWJlcnMgPSBbMiwgNSwgNiwgOF07XG4gICAgICAgICAgICAgZnVuY3Rpb24gaXNFdmVuKGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50ICUgMiA9PT0gMFxuICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgZXZlbk51bWJlcnM6IGV2ZW5OdW1iZXJzLmV2ZXJ5KGlzRXZlbiksXG4gICAgICAgICAgICAgICBzb21lT2RkTnVtYmVyczogc29tZU9kZE51bWJlcnMuZXZlcnkoaXNFdmVuKVxuICAgICAgICAgICAgIH07YCxcbiAgICB0ZXN0czogW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnQ29ycmVjdCBvdXRwdXQnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmRlZXBFcXVhbChvdXRwdXQsIHtcbiAgICAgICAgICAgIGV2ZW5OdW1iZXJzOiB0cnVlLFxuICAgICAgICAgICAgc29tZU9kZE51bWJlcnM6IGZhbHNlXG4gICAgICAgICAgfSkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnUmV0dXJucyBhbiBPYmplY3QnLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzT2JqZWN0KG91dHB1dCkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnT2JqZWN0IGhhcyAyIGl0ZW1zJyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5sZW5ndGhPZihPYmplY3Qua2V5cyhvdXRwdXQpLCAyKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6IGBGaXJzdCB2YWx1ZSBpcyB0cnVlYCxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc1RydWUob3V0cHV0LmV2ZW5OdW1iZXJzKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6IGBTZWNvbmQgdmFsdWUgaXMgZmFsc2VgLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzRmFsc2Uob3V0cHV0LnNvbWVPZGROdW1iZXJzKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBuYW1lOiAnQXJyYXkuc29tZSgpJyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6IGBSZXR1cm4gJ09iamVjdCcgdGhhdCByZXR1cm5zIHdoZXRoZXIgZWFjaCBhcnJheSBjb250YWlucyBzb21lIG9kZCBudW1iZXJzIHVzaW5nICdBcnJheS5zb21lKCknLmAsXG4gICAgZ2l2ZW46IGBjb25zdCBldmVuTnVtYmVycyA9IFsyLCA0LCA2LCA4XTtcbiAgICAgICAgICAgIGNvbnN0IHNvbWVPZGROdW1iZXJzID0gWzIsIDQsIDcsIDhdO1xuICAgICAgICAgICAgZnVuY3Rpb24gaXNPZGQoZWxlbWVudCkge1xuICAgICAgICAgICAgICBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGV2ZW5OdW1iZXJzOiBldmVuTnVtYmVycy4sXG4gICAgICAgICAgICAgIHNvbWVPZGROdW1iZXJzOiBzb21lT2RkTnVtYmVycy5cbiAgICAgICAgICAgIH07YCxcbiAgICBhbnN3ZXI6IGBjb25zdCBldmVuTnVtYmVycyA9IFsxLCAzLCA1LCA3XTtcbiAgICAgICAgICAgICBjb25zdCBzb21lT2RkTnVtYmVycyA9IFsxLCAzLCA2LCA3XTtcbiAgICAgICAgICAgICBmdW5jdGlvbiBpc09kZChlbGVtZW50KSB7XG4gICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudCAlIDIgIT09IDA7XG4gICAgICAgICAgICAgfVxuICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICBldmVuTnVtYmVyczogZXZlbk51bWJlcnMuc29tZShpc09kZCksXG4gICAgICAgICAgICAgICBzb21lT2RkTnVtYmVyczogc29tZU9kZE51bWJlcnMuc29tZShpc09kZClcbiAgICAgICAgICAgICB9O2AsXG4gICAgdGVzdHM6IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0NvcnJlY3Qgb3V0cHV0JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5kZWVwRXF1YWwob3V0cHV0LCB7XG4gICAgICAgICAgICBldmVuTnVtYmVyczogZmFsc2UsXG4gICAgICAgICAgICBzb21lT2RkTnVtYmVyczogdHJ1ZVxuICAgICAgICAgIH0pID09PSB1bmRlZmluZWQ7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ1JldHVybnMgYW4gT2JqZWN0JyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5pc09iamVjdChvdXRwdXQpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ09iamVjdCBoYXMgMiBpdGVtcycsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQubGVuZ3RoT2YoT2JqZWN0LmtleXMob3V0cHV0KSwgMikgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiBgRmlyc3QgdmFsdWUgaXMgZmFsc2VgLFxuICAgICAgICB0ZXN0OiBgYXNzZXJ0LmlzRmFsc2Uob3V0cHV0LmV2ZW5OdW1iZXJzKSA9PT0gdW5kZWZpbmVkO2BcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6IGBTZWNvbmQgdmFsdWUgaXMgdHJ1ZWAsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuaXNUcnVlKG91dHB1dC5zb21lT2RkTnVtYmVycykgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9XG4gICAgXVxuICB9XG4gIC8vIE5leHQgcHJvYmxlbXMgdG8gY3JlYXRlOlxuICAvLyBmb3JFYWNoPyBmaXggb25lIGFib3ZlIHRoYXQgdHJpZWQsIGJ1dCBjYW4ndCB2ZXJpZnkgZm9yRWFjaCB3YXMgdXNlZFxuICAvLyBzb21lXG4gIC8vIHJlZHVjZVxuICAvLyByZWR1Y2VSaWdodFxuICAvLyBBcnJheS5mcm9tIGFuZCBvdGhlciB3YXlzIHRvIHR1cm4gYXJyYXktbGlrZSBpbnRvIGFycmF5XG5dO1xuIiwibW9kdWxlLmV4cG9ydHMgPSBbXG4gIHtcbiAgICBuYW1lOiAnQ3JlYXRlIEFycmF5JyxcbiAgICB0aW1lOiAxMCxcbiAgICBwcm9tcHQ6ICdDcmVhdGUgYW5kIHJldHVybiBhbiBhcnJheSB0aGF0IGNvbnRhaW5zIFxcJ2FwcGxlXFwnIGFuZCBcXCdiYW5hbmFcXCcnLFxuICAgIGdpdmVuOiBgY29uc3QgZnJ1aXRzID0gW107XFxycmV0dXJuIGZydWl0cztgLFxuICAgIGFuc3dlcjogYGNvbnN0IGZydWl0cyA9IFsnYXBwbGUnLCAnYmFuYW5hJ107XG4gICAgICAgICAgICAgcmV0dXJuIGZydWl0cztgLFxuICAgIHRlc3RzOiBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdDb3JyZWN0IG91dHB1dCcsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuZGVlcEVxdWFsKG91dHB1dCwgWydhcHBsZScsICdiYW5hbmEnXSkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnUmV0dXJucyBhbiBBcnJheScsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuaXNBcnJheShvdXRwdXQpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0FycmF5IGhhcyAyIGl0ZW1zJyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5sZW5ndGhPZihvdXRwdXQsIDIpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIG5hbWU6ICdBcnJheS5wb3AoKScsXG4gICAgdGltZTogMTAsXG4gICAgcHJvbXB0OiBgUmVtb3ZlICdvcmFuZ2UnIGZyb20gdGhlIGVuZCBvZiB0aGUgJ2ZydWl0cycgYXJyYXkgYW5kIHJldHVybiAnZnJ1aXRzJy5gLFxuICAgIGdpdmVuOiBgY29uc3QgZnJ1aXRzID0gWydhcHBsZScsICdiYW5hbmEnLCAnb3JhbmdlJ107XFxyYCxcbiAgICBhbnN3ZXI6IGBjb25zdCBmcnVpdHMgPSBbJ2FwcGxlJywgJ2JhbmFuYScsICdvcmFuZ2UnXTtcbiAgICAgICAgICAgICBmcnVpdHMucG9wKCk7XG4gICAgICAgICAgICAgcmV0dXJuIGZydWl0cztgLFxuICAgIHRlc3RzOiBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdDb3JyZWN0IG91dHB1dCcsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuZGVlcEVxdWFsKG91dHB1dCwgWydhcHBsZScsICdiYW5hbmEnXSkgPT09IHVuZGVmaW5lZDtgXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnUmV0dXJucyBhbiBBcnJheScsXG4gICAgICAgIHRlc3Q6IGBhc3NlcnQuaXNBcnJheShvdXRwdXQpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ0FycmF5IGhhcyAyIGl0ZW1zJyxcbiAgICAgICAgdGVzdDogYGFzc2VydC5sZW5ndGhPZihvdXRwdXQsIDIpID09PSB1bmRlZmluZWQ7YFxuICAgICAgfVxuICAgIF1cbiAgfSxcbl1cbiIsIi8qIVxuICogYXNzZXJ0aW9uLWVycm9yXG4gKiBDb3B5cmlnaHQoYykgMjAxMyBKYWtlIEx1ZXIgPGpha2VAcXVhbGlhbmN5LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qIVxuICogUmV0dXJuIGEgZnVuY3Rpb24gdGhhdCB3aWxsIGNvcHkgcHJvcGVydGllcyBmcm9tXG4gKiBvbmUgb2JqZWN0IHRvIGFub3RoZXIgZXhjbHVkaW5nIGFueSBvcmlnaW5hbGx5XG4gKiBsaXN0ZWQuIFJldHVybmVkIGZ1bmN0aW9uIHdpbGwgY3JlYXRlIGEgbmV3IGB7fWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV4Y2x1ZGVkIHByb3BlcnRpZXMgLi4uXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuXG5mdW5jdGlvbiBleGNsdWRlICgpIHtcbiAgdmFyIGV4Y2x1ZGVzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXG4gIGZ1bmN0aW9uIGV4Y2x1ZGVQcm9wcyAocmVzLCBvYmopIHtcbiAgICBPYmplY3Qua2V5cyhvYmopLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgaWYgKCF+ZXhjbHVkZXMuaW5kZXhPZihrZXkpKSByZXNba2V5XSA9IG9ialtrZXldO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIGV4dGVuZEV4Y2x1ZGUgKCkge1xuICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMpXG4gICAgICAsIGkgPSAwXG4gICAgICAsIHJlcyA9IHt9O1xuXG4gICAgZm9yICg7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBleGNsdWRlUHJvcHMocmVzLCBhcmdzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzO1xuICB9O1xufTtcblxuLyohXG4gKiBQcmltYXJ5IEV4cG9ydHNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFzc2VydGlvbkVycm9yO1xuXG4vKipcbiAqICMjIyBBc3NlcnRpb25FcnJvclxuICpcbiAqIEFuIGV4dGVuc2lvbiBvZiB0aGUgSmF2YVNjcmlwdCBgRXJyb3JgIGNvbnN0cnVjdG9yIGZvclxuICogYXNzZXJ0aW9uIGFuZCB2YWxpZGF0aW9uIHNjZW5hcmlvcy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICogQHBhcmFtIHtPYmplY3R9IHByb3BlcnRpZXMgdG8gaW5jbHVkZSAob3B0aW9uYWwpXG4gKiBAcGFyYW0ge2NhbGxlZX0gc3RhcnQgc3RhY2sgZnVuY3Rpb24gKG9wdGlvbmFsKVxuICovXG5cbmZ1bmN0aW9uIEFzc2VydGlvbkVycm9yIChtZXNzYWdlLCBfcHJvcHMsIHNzZikge1xuICB2YXIgZXh0ZW5kID0gZXhjbHVkZSgnbmFtZScsICdtZXNzYWdlJywgJ3N0YWNrJywgJ2NvbnN0cnVjdG9yJywgJ3RvSlNPTicpXG4gICAgLCBwcm9wcyA9IGV4dGVuZChfcHJvcHMgfHwge30pO1xuXG4gIC8vIGRlZmF1bHQgdmFsdWVzXG4gIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2UgfHwgJ1Vuc3BlY2lmaWVkIEFzc2VydGlvbkVycm9yJztcbiAgdGhpcy5zaG93RGlmZiA9IGZhbHNlO1xuXG4gIC8vIGNvcHkgZnJvbSBwcm9wZXJ0aWVzXG4gIGZvciAodmFyIGtleSBpbiBwcm9wcykge1xuICAgIHRoaXNba2V5XSA9IHByb3BzW2tleV07XG4gIH1cblxuICAvLyBjYXB0dXJlIHN0YWNrIHRyYWNlXG4gIHNzZiA9IHNzZiB8fCBhcmd1bWVudHMuY2FsbGVlO1xuICBpZiAoc3NmICYmIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgc3NmKTtcbiAgfSBlbHNlIHtcbiAgICB0cnkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgfSBjYXRjaChlKSB7XG4gICAgICB0aGlzLnN0YWNrID0gZS5zdGFjaztcbiAgICB9XG4gIH1cbn1cblxuLyohXG4gKiBJbmhlcml0IGZyb20gRXJyb3IucHJvdG90eXBlXG4gKi9cblxuQXNzZXJ0aW9uRXJyb3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShFcnJvci5wcm90b3R5cGUpO1xuXG4vKiFcbiAqIFN0YXRpY2FsbHkgc2V0IG5hbWVcbiAqL1xuXG5Bc3NlcnRpb25FcnJvci5wcm90b3R5cGUubmFtZSA9ICdBc3NlcnRpb25FcnJvcic7XG5cbi8qIVxuICogRW5zdXJlIGNvcnJlY3QgY29uc3RydWN0b3JcbiAqL1xuXG5Bc3NlcnRpb25FcnJvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBBc3NlcnRpb25FcnJvcjtcblxuLyoqXG4gKiBBbGxvdyBlcnJvcnMgdG8gYmUgY29udmVydGVkIHRvIEpTT04gZm9yIHN0YXRpYyB0cmFuc2Zlci5cbiAqXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGluY2x1ZGUgc3RhY2sgKGRlZmF1bHQ6IGB0cnVlYClcbiAqIEByZXR1cm4ge09iamVjdH0gb2JqZWN0IHRoYXQgY2FuIGJlIGBKU09OLnN0cmluZ2lmeWBcbiAqL1xuXG5Bc3NlcnRpb25FcnJvci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gKHN0YWNrKSB7XG4gIHZhciBleHRlbmQgPSBleGNsdWRlKCdjb25zdHJ1Y3RvcicsICd0b0pTT04nLCAnc3RhY2snKVxuICAgICwgcHJvcHMgPSBleHRlbmQoeyBuYW1lOiB0aGlzLm5hbWUgfSwgdGhpcyk7XG5cbiAgLy8gaW5jbHVkZSBzdGFjayBpZiBleGlzdHMgYW5kIG5vdCB0dXJuZWQgb2ZmXG4gIGlmIChmYWxzZSAhPT0gc3RhY2sgJiYgdGhpcy5zdGFjaykge1xuICAgIHByb3BzLnN0YWNrID0gdGhpcy5zdGFjaztcbiAgfVxuXG4gIHJldHVybiBwcm9wcztcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL2NoYWknKTtcbiIsIi8qIVxuICogY2hhaVxuICogQ29weXJpZ2h0KGMpIDIwMTEtMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbnZhciB1c2VkID0gW11cbiAgLCBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLyohXG4gKiBDaGFpIHZlcnNpb25cbiAqL1xuXG5leHBvcnRzLnZlcnNpb24gPSAnMy41LjAnO1xuXG4vKiFcbiAqIEFzc2VydGlvbiBFcnJvclxuICovXG5cbmV4cG9ydHMuQXNzZXJ0aW9uRXJyb3IgPSByZXF1aXJlKCdhc3NlcnRpb24tZXJyb3InKTtcblxuLyohXG4gKiBVdGlscyBmb3IgcGx1Z2lucyAobm90IGV4cG9ydGVkKVxuICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi9jaGFpL3V0aWxzJyk7XG5cbi8qKlxuICogIyAudXNlKGZ1bmN0aW9uKVxuICpcbiAqIFByb3ZpZGVzIGEgd2F5IHRvIGV4dGVuZCB0aGUgaW50ZXJuYWxzIG9mIENoYWlcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufVxuICogQHJldHVybnMge3RoaXN9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnVzZSA9IGZ1bmN0aW9uIChmbikge1xuICBpZiAoIX51c2VkLmluZGV4T2YoZm4pKSB7XG4gICAgZm4odGhpcywgdXRpbCk7XG4gICAgdXNlZC5wdXNoKGZuKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyohXG4gKiBVdGlsaXR5IEZ1bmN0aW9uc1xuICovXG5cbmV4cG9ydHMudXRpbCA9IHV0aWw7XG5cbi8qIVxuICogQ29uZmlndXJhdGlvblxuICovXG5cbnZhciBjb25maWcgPSByZXF1aXJlKCcuL2NoYWkvY29uZmlnJyk7XG5leHBvcnRzLmNvbmZpZyA9IGNvbmZpZztcblxuLyohXG4gKiBQcmltYXJ5IGBBc3NlcnRpb25gIHByb3RvdHlwZVxuICovXG5cbnZhciBhc3NlcnRpb24gPSByZXF1aXJlKCcuL2NoYWkvYXNzZXJ0aW9uJyk7XG5leHBvcnRzLnVzZShhc3NlcnRpb24pO1xuXG4vKiFcbiAqIENvcmUgQXNzZXJ0aW9uc1xuICovXG5cbnZhciBjb3JlID0gcmVxdWlyZSgnLi9jaGFpL2NvcmUvYXNzZXJ0aW9ucycpO1xuZXhwb3J0cy51c2UoY29yZSk7XG5cbi8qIVxuICogRXhwZWN0IGludGVyZmFjZVxuICovXG5cbnZhciBleHBlY3QgPSByZXF1aXJlKCcuL2NoYWkvaW50ZXJmYWNlL2V4cGVjdCcpO1xuZXhwb3J0cy51c2UoZXhwZWN0KTtcblxuLyohXG4gKiBTaG91bGQgaW50ZXJmYWNlXG4gKi9cblxudmFyIHNob3VsZCA9IHJlcXVpcmUoJy4vY2hhaS9pbnRlcmZhY2Uvc2hvdWxkJyk7XG5leHBvcnRzLnVzZShzaG91bGQpO1xuXG4vKiFcbiAqIEFzc2VydCBpbnRlcmZhY2VcbiAqL1xuXG52YXIgYXNzZXJ0ID0gcmVxdWlyZSgnLi9jaGFpL2ludGVyZmFjZS9hc3NlcnQnKTtcbmV4cG9ydHMudXNlKGFzc2VydCk7XG4iLCIvKiFcbiAqIGNoYWlcbiAqIGh0dHA6Ly9jaGFpanMuY29tXG4gKiBDb3B5cmlnaHQoYykgMjAxMS0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4vY29uZmlnJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKF9jaGFpLCB1dGlsKSB7XG4gIC8qIVxuICAgKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICAgKi9cblxuICB2YXIgQXNzZXJ0aW9uRXJyb3IgPSBfY2hhaS5Bc3NlcnRpb25FcnJvclxuICAgICwgZmxhZyA9IHV0aWwuZmxhZztcblxuICAvKiFcbiAgICogTW9kdWxlIGV4cG9ydC5cbiAgICovXG5cbiAgX2NoYWkuQXNzZXJ0aW9uID0gQXNzZXJ0aW9uO1xuXG4gIC8qIVxuICAgKiBBc3NlcnRpb24gQ29uc3RydWN0b3JcbiAgICpcbiAgICogQ3JlYXRlcyBvYmplY3QgZm9yIGNoYWluaW5nLlxuICAgKlxuICAgKiBAYXBpIHByaXZhdGVcbiAgICovXG5cbiAgZnVuY3Rpb24gQXNzZXJ0aW9uIChvYmosIG1zZywgc3RhY2spIHtcbiAgICBmbGFnKHRoaXMsICdzc2ZpJywgc3RhY2sgfHwgYXJndW1lbnRzLmNhbGxlZSk7XG4gICAgZmxhZyh0aGlzLCAnb2JqZWN0Jywgb2JqKTtcbiAgICBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgfVxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShBc3NlcnRpb24sICdpbmNsdWRlU3RhY2snLCB7XG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnNvbGUud2FybignQXNzZXJ0aW9uLmluY2x1ZGVTdGFjayBpcyBkZXByZWNhdGVkLCB1c2UgY2hhaS5jb25maWcuaW5jbHVkZVN0YWNrIGluc3RlYWQuJyk7XG4gICAgICByZXR1cm4gY29uZmlnLmluY2x1ZGVTdGFjaztcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGNvbnNvbGUud2FybignQXNzZXJ0aW9uLmluY2x1ZGVTdGFjayBpcyBkZXByZWNhdGVkLCB1c2UgY2hhaS5jb25maWcuaW5jbHVkZVN0YWNrIGluc3RlYWQuJyk7XG4gICAgICBjb25maWcuaW5jbHVkZVN0YWNrID0gdmFsdWU7XG4gICAgfVxuICB9KTtcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQXNzZXJ0aW9uLCAnc2hvd0RpZmYnLCB7XG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnNvbGUud2FybignQXNzZXJ0aW9uLnNob3dEaWZmIGlzIGRlcHJlY2F0ZWQsIHVzZSBjaGFpLmNvbmZpZy5zaG93RGlmZiBpbnN0ZWFkLicpO1xuICAgICAgcmV0dXJuIGNvbmZpZy5zaG93RGlmZjtcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGNvbnNvbGUud2FybignQXNzZXJ0aW9uLnNob3dEaWZmIGlzIGRlcHJlY2F0ZWQsIHVzZSBjaGFpLmNvbmZpZy5zaG93RGlmZiBpbnN0ZWFkLicpO1xuICAgICAgY29uZmlnLnNob3dEaWZmID0gdmFsdWU7XG4gICAgfVxuICB9KTtcblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkgPSBmdW5jdGlvbiAobmFtZSwgZm4pIHtcbiAgICB1dGlsLmFkZFByb3BlcnR5KHRoaXMucHJvdG90eXBlLCBuYW1lLCBmbik7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCA9IGZ1bmN0aW9uIChuYW1lLCBmbikge1xuICAgIHV0aWwuYWRkTWV0aG9kKHRoaXMucHJvdG90eXBlLCBuYW1lLCBmbik7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCA9IGZ1bmN0aW9uIChuYW1lLCBmbiwgY2hhaW5pbmdCZWhhdmlvcikge1xuICAgIHV0aWwuYWRkQ2hhaW5hYmxlTWV0aG9kKHRoaXMucHJvdG90eXBlLCBuYW1lLCBmbiwgY2hhaW5pbmdCZWhhdmlvcik7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLm92ZXJ3cml0ZVByb3BlcnR5ID0gZnVuY3Rpb24gKG5hbWUsIGZuKSB7XG4gICAgdXRpbC5vdmVyd3JpdGVQcm9wZXJ0eSh0aGlzLnByb3RvdHlwZSwgbmFtZSwgZm4pO1xuICB9O1xuXG4gIEFzc2VydGlvbi5vdmVyd3JpdGVNZXRob2QgPSBmdW5jdGlvbiAobmFtZSwgZm4pIHtcbiAgICB1dGlsLm92ZXJ3cml0ZU1ldGhvZCh0aGlzLnByb3RvdHlwZSwgbmFtZSwgZm4pO1xuICB9O1xuXG4gIEFzc2VydGlvbi5vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QgPSBmdW5jdGlvbiAobmFtZSwgZm4sIGNoYWluaW5nQmVoYXZpb3IpIHtcbiAgICB1dGlsLm92ZXJ3cml0ZUNoYWluYWJsZU1ldGhvZCh0aGlzLnByb3RvdHlwZSwgbmFtZSwgZm4sIGNoYWluaW5nQmVoYXZpb3IpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmFzc2VydChleHByZXNzaW9uLCBtZXNzYWdlLCBuZWdhdGVNZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsLCBzaG93RGlmZilcbiAgICpcbiAgICogRXhlY3V0ZXMgYW4gZXhwcmVzc2lvbiBhbmQgY2hlY2sgZXhwZWN0YXRpb25zLiBUaHJvd3MgQXNzZXJ0aW9uRXJyb3IgZm9yIHJlcG9ydGluZyBpZiB0ZXN0IGRvZXNuJ3QgcGFzcy5cbiAgICpcbiAgICogQG5hbWUgYXNzZXJ0XG4gICAqIEBwYXJhbSB7UGhpbG9zb3BoaWNhbH0gZXhwcmVzc2lvbiB0byBiZSB0ZXN0ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IG1lc3NhZ2Ugb3IgZnVuY3Rpb24gdGhhdCByZXR1cm5zIG1lc3NhZ2UgdG8gZGlzcGxheSBpZiBleHByZXNzaW9uIGZhaWxzXG4gICAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSBuZWdhdGVkTWVzc2FnZSBvciBmdW5jdGlvbiB0aGF0IHJldHVybnMgbmVnYXRlZE1lc3NhZ2UgdG8gZGlzcGxheSBpZiBuZWdhdGVkIGV4cHJlc3Npb24gZmFpbHNcbiAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWQgdmFsdWUgKHJlbWVtYmVyIHRvIGNoZWNrIGZvciBuZWdhdGlvbilcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsIChvcHRpb25hbCkgd2lsbCBkZWZhdWx0IHRvIGB0aGlzLm9iamBcbiAgICogQHBhcmFtIHtCb29sZWFufSBzaG93RGlmZiAob3B0aW9uYWwpIHdoZW4gc2V0IHRvIGB0cnVlYCwgYXNzZXJ0IHdpbGwgZGlzcGxheSBhIGRpZmYgaW4gYWRkaXRpb24gdG8gdGhlIG1lc3NhZ2UgaWYgZXhwcmVzc2lvbiBmYWlsc1xuICAgKiBAYXBpIHByaXZhdGVcbiAgICovXG5cbiAgQXNzZXJ0aW9uLnByb3RvdHlwZS5hc3NlcnQgPSBmdW5jdGlvbiAoZXhwciwgbXNnLCBuZWdhdGVNc2csIGV4cGVjdGVkLCBfYWN0dWFsLCBzaG93RGlmZikge1xuICAgIHZhciBvayA9IHV0aWwudGVzdCh0aGlzLCBhcmd1bWVudHMpO1xuICAgIGlmICh0cnVlICE9PSBzaG93RGlmZikgc2hvd0RpZmYgPSBmYWxzZTtcbiAgICBpZiAodHJ1ZSAhPT0gY29uZmlnLnNob3dEaWZmKSBzaG93RGlmZiA9IGZhbHNlO1xuXG4gICAgaWYgKCFvaykge1xuICAgICAgdmFyIG1zZyA9IHV0aWwuZ2V0TWVzc2FnZSh0aGlzLCBhcmd1bWVudHMpXG4gICAgICAgICwgYWN0dWFsID0gdXRpbC5nZXRBY3R1YWwodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtc2csIHtcbiAgICAgICAgICBhY3R1YWw6IGFjdHVhbFxuICAgICAgICAsIGV4cGVjdGVkOiBleHBlY3RlZFxuICAgICAgICAsIHNob3dEaWZmOiBzaG93RGlmZlxuICAgICAgfSwgKGNvbmZpZy5pbmNsdWRlU3RhY2spID8gdGhpcy5hc3NlcnQgOiBmbGFnKHRoaXMsICdzc2ZpJykpO1xuICAgIH1cbiAgfTtcblxuICAvKiFcbiAgICogIyMjIC5fb2JqXG4gICAqXG4gICAqIFF1aWNrIHJlZmVyZW5jZSB0byBzdG9yZWQgYGFjdHVhbGAgdmFsdWUgZm9yIHBsdWdpbiBkZXZlbG9wZXJzLlxuICAgKlxuICAgKiBAYXBpIHByaXZhdGVcbiAgICovXG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFzc2VydGlvbi5wcm90b3R5cGUsICdfb2JqJyxcbiAgICB7IGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgICB9XG4gICAgLCBzZXQ6IGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgZmxhZyh0aGlzLCAnb2JqZWN0JywgdmFsKTtcbiAgICAgIH1cbiAgfSk7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG5cbiAgLyoqXG4gICAqICMjIyBjb25maWcuaW5jbHVkZVN0YWNrXG4gICAqXG4gICAqIFVzZXIgY29uZmlndXJhYmxlIHByb3BlcnR5LCBpbmZsdWVuY2VzIHdoZXRoZXIgc3RhY2sgdHJhY2VcbiAgICogaXMgaW5jbHVkZWQgaW4gQXNzZXJ0aW9uIGVycm9yIG1lc3NhZ2UuIERlZmF1bHQgb2YgZmFsc2VcbiAgICogc3VwcHJlc3NlcyBzdGFjayB0cmFjZSBpbiB0aGUgZXJyb3IgbWVzc2FnZS5cbiAgICpcbiAgICogICAgIGNoYWkuY29uZmlnLmluY2x1ZGVTdGFjayA9IHRydWU7ICAvLyBlbmFibGUgc3RhY2sgb24gZXJyb3JcbiAgICpcbiAgICogQHBhcmFtIHtCb29sZWFufVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICAgaW5jbHVkZVN0YWNrOiBmYWxzZSxcblxuICAvKipcbiAgICogIyMjIGNvbmZpZy5zaG93RGlmZlxuICAgKlxuICAgKiBVc2VyIGNvbmZpZ3VyYWJsZSBwcm9wZXJ0eSwgaW5mbHVlbmNlcyB3aGV0aGVyIG9yIG5vdFxuICAgKiB0aGUgYHNob3dEaWZmYCBmbGFnIHNob3VsZCBiZSBpbmNsdWRlZCBpbiB0aGUgdGhyb3duXG4gICAqIEFzc2VydGlvbkVycm9ycy4gYGZhbHNlYCB3aWxsIGFsd2F5cyBiZSBgZmFsc2VgOyBgdHJ1ZWBcbiAgICogd2lsbCBiZSB0cnVlIHdoZW4gdGhlIGFzc2VydGlvbiBoYXMgcmVxdWVzdGVkIGEgZGlmZlxuICAgKiBiZSBzaG93bi5cbiAgICpcbiAgICogQHBhcmFtIHtCb29sZWFufVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBzaG93RGlmZjogdHJ1ZSxcblxuICAvKipcbiAgICogIyMjIGNvbmZpZy50cnVuY2F0ZVRocmVzaG9sZFxuICAgKlxuICAgKiBVc2VyIGNvbmZpZ3VyYWJsZSBwcm9wZXJ0eSwgc2V0cyBsZW5ndGggdGhyZXNob2xkIGZvciBhY3R1YWwgYW5kXG4gICAqIGV4cGVjdGVkIHZhbHVlcyBpbiBhc3NlcnRpb24gZXJyb3JzLiBJZiB0aGlzIHRocmVzaG9sZCBpcyBleGNlZWRlZCwgZm9yXG4gICAqIGV4YW1wbGUgZm9yIGxhcmdlIGRhdGEgc3RydWN0dXJlcywgdGhlIHZhbHVlIGlzIHJlcGxhY2VkIHdpdGggc29tZXRoaW5nXG4gICAqIGxpa2UgYFsgQXJyYXkoMykgXWAgb3IgYHsgT2JqZWN0IChwcm9wMSwgcHJvcDIpIH1gLlxuICAgKlxuICAgKiBTZXQgaXQgdG8gemVybyBpZiB5b3Ugd2FudCB0byBkaXNhYmxlIHRydW5jYXRpbmcgYWx0b2dldGhlci5cbiAgICpcbiAgICogVGhpcyBpcyBlc3BlY2lhbGx5IHVzZXJmdWwgd2hlbiBkb2luZyBhc3NlcnRpb25zIG9uIGFycmF5czogaGF2aW5nIHRoaXNcbiAgICogc2V0IHRvIGEgcmVhc29uYWJsZSBsYXJnZSB2YWx1ZSBtYWtlcyB0aGUgZmFpbHVyZSBtZXNzYWdlcyByZWFkaWx5XG4gICAqIGluc3BlY3RhYmxlLlxuICAgKlxuICAgKiAgICAgY2hhaS5jb25maWcudHJ1bmNhdGVUaHJlc2hvbGQgPSAwOyAgLy8gZGlzYWJsZSB0cnVuY2F0aW5nXG4gICAqXG4gICAqIEBwYXJhbSB7TnVtYmVyfVxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICB0cnVuY2F0ZVRocmVzaG9sZDogNDBcblxufTtcbiIsIi8qIVxuICogY2hhaVxuICogaHR0cDovL2NoYWlqcy5jb21cbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjaGFpLCBfKSB7XG4gIHZhciBBc3NlcnRpb24gPSBjaGFpLkFzc2VydGlvblxuICAgICwgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nXG4gICAgLCBmbGFnID0gXy5mbGFnO1xuXG4gIC8qKlxuICAgKiAjIyMgTGFuZ3VhZ2UgQ2hhaW5zXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgYXJlIHByb3ZpZGVkIGFzIGNoYWluYWJsZSBnZXR0ZXJzIHRvXG4gICAqIGltcHJvdmUgdGhlIHJlYWRhYmlsaXR5IG9mIHlvdXIgYXNzZXJ0aW9ucy4gVGhleVxuICAgKiBkbyBub3QgcHJvdmlkZSB0ZXN0aW5nIGNhcGFiaWxpdGllcyB1bmxlc3MgdGhleVxuICAgKiBoYXZlIGJlZW4gb3ZlcndyaXR0ZW4gYnkgYSBwbHVnaW4uXG4gICAqXG4gICAqICoqQ2hhaW5zKipcbiAgICpcbiAgICogLSB0b1xuICAgKiAtIGJlXG4gICAqIC0gYmVlblxuICAgKiAtIGlzXG4gICAqIC0gdGhhdFxuICAgKiAtIHdoaWNoXG4gICAqIC0gYW5kXG4gICAqIC0gaGFzXG4gICAqIC0gaGF2ZVxuICAgKiAtIHdpdGhcbiAgICogLSBhdFxuICAgKiAtIG9mXG4gICAqIC0gc2FtZVxuICAgKlxuICAgKiBAbmFtZSBsYW5ndWFnZSBjaGFpbnNcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgWyAndG8nLCAnYmUnLCAnYmVlbidcbiAgLCAnaXMnLCAnYW5kJywgJ2hhcycsICdoYXZlJ1xuICAsICd3aXRoJywgJ3RoYXQnLCAnd2hpY2gnLCAnYXQnXG4gICwgJ29mJywgJ3NhbWUnIF0uZm9yRWFjaChmdW5jdGlvbiAoY2hhaW4pIHtcbiAgICBBc3NlcnRpb24uYWRkUHJvcGVydHkoY2hhaW4sIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0pO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5ub3RcbiAgICpcbiAgICogTmVnYXRlcyBhbnkgb2YgYXNzZXJ0aW9ucyBmb2xsb3dpbmcgaW4gdGhlIGNoYWluLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KGZvbykudG8ubm90LmVxdWFsKCdiYXInKTtcbiAgICogICAgIGV4cGVjdChnb29kRm4pLnRvLm5vdC50aHJvdyhFcnJvcik7XG4gICAqICAgICBleHBlY3QoeyBmb286ICdiYXonIH0pLnRvLmhhdmUucHJvcGVydHkoJ2ZvbycpXG4gICAqICAgICAgIC5hbmQubm90LmVxdWFsKCdiYXInKTtcbiAgICpcbiAgICogQG5hbWUgbm90XG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnbm90JywgZnVuY3Rpb24gKCkge1xuICAgIGZsYWcodGhpcywgJ25lZ2F0ZScsIHRydWUpO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5kZWVwXG4gICAqXG4gICAqIFNldHMgdGhlIGBkZWVwYCBmbGFnLCBsYXRlciB1c2VkIGJ5IHRoZSBgZXF1YWxgIGFuZFxuICAgKiBgcHJvcGVydHlgIGFzc2VydGlvbnMuXG4gICAqXG4gICAqICAgICBleHBlY3QoZm9vKS50by5kZWVwLmVxdWFsKHsgYmFyOiAnYmF6JyB9KTtcbiAgICogICAgIGV4cGVjdCh7IGZvbzogeyBiYXI6IHsgYmF6OiAncXV1eCcgfSB9IH0pXG4gICAqICAgICAgIC50by5oYXZlLmRlZXAucHJvcGVydHkoJ2Zvby5iYXIuYmF6JywgJ3F1dXgnKTtcbiAgICpcbiAgICogYC5kZWVwLnByb3BlcnR5YCBzcGVjaWFsIGNoYXJhY3RlcnMgY2FuIGJlIGVzY2FwZWRcbiAgICogYnkgYWRkaW5nIHR3byBzbGFzaGVzIGJlZm9yZSB0aGUgYC5gIG9yIGBbXWAuXG4gICAqXG4gICAqICAgICB2YXIgZGVlcENzcyA9IHsgJy5saW5rJzogeyAnW3RhcmdldF0nOiA0MiB9fTtcbiAgICogICAgIGV4cGVjdChkZWVwQ3NzKS50by5oYXZlLmRlZXAucHJvcGVydHkoJ1xcXFwubGluay5cXFxcW3RhcmdldFxcXFxdJywgNDIpO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZGVlcCcsIGZ1bmN0aW9uICgpIHtcbiAgICBmbGFnKHRoaXMsICdkZWVwJywgdHJ1ZSk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmFueVxuICAgKlxuICAgKiBTZXRzIHRoZSBgYW55YCBmbGFnLCAob3Bwb3NpdGUgb2YgdGhlIGBhbGxgIGZsYWcpXG4gICAqIGxhdGVyIHVzZWQgaW4gdGhlIGBrZXlzYCBhc3NlcnRpb24uXG4gICAqXG4gICAqICAgICBleHBlY3QoZm9vKS50by5oYXZlLmFueS5rZXlzKCdiYXInLCAnYmF6Jyk7XG4gICAqXG4gICAqIEBuYW1lIGFueVxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2FueScsIGZ1bmN0aW9uICgpIHtcbiAgICBmbGFnKHRoaXMsICdhbnknLCB0cnVlKTtcbiAgICBmbGFnKHRoaXMsICdhbGwnLCBmYWxzZSlcbiAgfSk7XG5cblxuICAvKipcbiAgICogIyMjIC5hbGxcbiAgICpcbiAgICogU2V0cyB0aGUgYGFsbGAgZmxhZyAob3Bwb3NpdGUgb2YgdGhlIGBhbnlgIGZsYWcpXG4gICAqIGxhdGVyIHVzZWQgYnkgdGhlIGBrZXlzYCBhc3NlcnRpb24uXG4gICAqXG4gICAqICAgICBleHBlY3QoZm9vKS50by5oYXZlLmFsbC5rZXlzKCdiYXInLCAnYmF6Jyk7XG4gICAqXG4gICAqIEBuYW1lIGFsbFxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2FsbCcsIGZ1bmN0aW9uICgpIHtcbiAgICBmbGFnKHRoaXMsICdhbGwnLCB0cnVlKTtcbiAgICBmbGFnKHRoaXMsICdhbnknLCBmYWxzZSk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmEodHlwZSlcbiAgICpcbiAgICogVGhlIGBhYCBhbmQgYGFuYCBhc3NlcnRpb25zIGFyZSBhbGlhc2VzIHRoYXQgY2FuIGJlXG4gICAqIHVzZWQgZWl0aGVyIGFzIGxhbmd1YWdlIGNoYWlucyBvciB0byBhc3NlcnQgYSB2YWx1ZSdzXG4gICAqIHR5cGUuXG4gICAqXG4gICAqICAgICAvLyB0eXBlb2ZcbiAgICogICAgIGV4cGVjdCgndGVzdCcpLnRvLmJlLmEoJ3N0cmluZycpO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAnYmFyJyB9KS50by5iZS5hbignb2JqZWN0Jyk7XG4gICAqICAgICBleHBlY3QobnVsbCkudG8uYmUuYSgnbnVsbCcpO1xuICAgKiAgICAgZXhwZWN0KHVuZGVmaW5lZCkudG8uYmUuYW4oJ3VuZGVmaW5lZCcpO1xuICAgKiAgICAgZXhwZWN0KG5ldyBFcnJvcikudG8uYmUuYW4oJ2Vycm9yJyk7XG4gICAqICAgICBleHBlY3QobmV3IFByb21pc2UpLnRvLmJlLmEoJ3Byb21pc2UnKTtcbiAgICogICAgIGV4cGVjdChuZXcgRmxvYXQzMkFycmF5KCkpLnRvLmJlLmEoJ2Zsb2F0MzJhcnJheScpO1xuICAgKiAgICAgZXhwZWN0KFN5bWJvbCgpKS50by5iZS5hKCdzeW1ib2wnKTtcbiAgICpcbiAgICogICAgIC8vIGVzNiBvdmVycmlkZXNcbiAgICogICAgIGV4cGVjdCh7W1N5bWJvbC50b1N0cmluZ1RhZ106KCk9Pidmb28nfSkudG8uYmUuYSgnZm9vJyk7XG4gICAqXG4gICAqICAgICAvLyBsYW5ndWFnZSBjaGFpblxuICAgKiAgICAgZXhwZWN0KGZvbykudG8uYmUuYW4uaW5zdGFuY2VvZihGb28pO1xuICAgKlxuICAgKiBAbmFtZSBhXG4gICAqIEBhbGlhcyBhblxuICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFuICh0eXBlLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB0eXBlID0gdHlwZS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBhcnRpY2xlID0gflsgJ2EnLCAnZScsICdpJywgJ28nLCAndScgXS5pbmRleE9mKHR5cGUuY2hhckF0KDApKSA/ICdhbiAnIDogJ2EgJztcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICB0eXBlID09PSBfLnR5cGUob2JqKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSAnICsgYXJ0aWNsZSArIHR5cGVcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIGJlICcgKyBhcnRpY2xlICsgdHlwZVxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdhbicsIGFuKTtcbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnYScsIGFuKTtcblxuICAvKipcbiAgICogIyMjIC5pbmNsdWRlKHZhbHVlKVxuICAgKlxuICAgKiBUaGUgYGluY2x1ZGVgIGFuZCBgY29udGFpbmAgYXNzZXJ0aW9ucyBjYW4gYmUgdXNlZCBhcyBlaXRoZXIgcHJvcGVydHlcbiAgICogYmFzZWQgbGFuZ3VhZ2UgY2hhaW5zIG9yIGFzIG1ldGhvZHMgdG8gYXNzZXJ0IHRoZSBpbmNsdXNpb24gb2YgYW4gb2JqZWN0XG4gICAqIGluIGFuIGFycmF5IG9yIGEgc3Vic3RyaW5nIGluIGEgc3RyaW5nLiBXaGVuIHVzZWQgYXMgbGFuZ3VhZ2UgY2hhaW5zLFxuICAgKiB0aGV5IHRvZ2dsZSB0aGUgYGNvbnRhaW5zYCBmbGFnIGZvciB0aGUgYGtleXNgIGFzc2VydGlvbi5cbiAgICpcbiAgICogICAgIGV4cGVjdChbMSwyLDNdKS50by5pbmNsdWRlKDIpO1xuICAgKiAgICAgZXhwZWN0KCdmb29iYXInKS50by5jb250YWluKCdmb28nKTtcbiAgICogICAgIGV4cGVjdCh7IGZvbzogJ2JhcicsIGhlbGxvOiAndW5pdmVyc2UnIH0pLnRvLmluY2x1ZGUua2V5cygnZm9vJyk7XG4gICAqXG4gICAqIEBuYW1lIGluY2x1ZGVcbiAgICogQGFsaWFzIGNvbnRhaW5cbiAgICogQGFsaWFzIGluY2x1ZGVzXG4gICAqIEBhbGlhcyBjb250YWluc1xuICAgKiBAcGFyYW0ge09iamVjdHxTdHJpbmd8TnVtYmVyfSBvYmpcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBpbmNsdWRlQ2hhaW5pbmdCZWhhdmlvciAoKSB7XG4gICAgZmxhZyh0aGlzLCAnY29udGFpbnMnLCB0cnVlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluY2x1ZGUgKHZhbCwgbXNnKSB7XG4gICAgXy5leHBlY3RUeXBlcyh0aGlzLCBbJ2FycmF5JywgJ29iamVjdCcsICdzdHJpbmcnXSk7XG5cbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgdmFyIGV4cGVjdGVkID0gZmFsc2U7XG5cbiAgICBpZiAoXy50eXBlKG9iaikgPT09ICdhcnJheScgJiYgXy50eXBlKHZhbCkgPT09ICdvYmplY3QnKSB7XG4gICAgICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgICAgICBpZiAoXy5lcWwob2JqW2ldLCB2YWwpKSB7XG4gICAgICAgICAgZXhwZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChfLnR5cGUodmFsKSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmICghZmxhZyh0aGlzLCAnbmVnYXRlJykpIHtcbiAgICAgICAgZm9yICh2YXIgayBpbiB2YWwpIG5ldyBBc3NlcnRpb24ob2JqKS5wcm9wZXJ0eShrLCB2YWxba10pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgc3Vic2V0ID0ge307XG4gICAgICBmb3IgKHZhciBrIGluIHZhbCkgc3Vic2V0W2tdID0gb2JqW2tdO1xuICAgICAgZXhwZWN0ZWQgPSBfLmVxbChzdWJzZXQsIHZhbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4cGVjdGVkID0gKG9iaiAhPSB1bmRlZmluZWQpICYmIH5vYmouaW5kZXhPZih2YWwpO1xuICAgIH1cbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgZXhwZWN0ZWRcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gaW5jbHVkZSAnICsgXy5pbnNwZWN0KHZhbClcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGluY2x1ZGUgJyArIF8uaW5zcGVjdCh2YWwpKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2luY2x1ZGUnLCBpbmNsdWRlLCBpbmNsdWRlQ2hhaW5pbmdCZWhhdmlvcik7XG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2NvbnRhaW4nLCBpbmNsdWRlLCBpbmNsdWRlQ2hhaW5pbmdCZWhhdmlvcik7XG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2NvbnRhaW5zJywgaW5jbHVkZSwgaW5jbHVkZUNoYWluaW5nQmVoYXZpb3IpO1xuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdpbmNsdWRlcycsIGluY2x1ZGUsIGluY2x1ZGVDaGFpbmluZ0JlaGF2aW9yKTtcblxuICAvKipcbiAgICogIyMjIC5va1xuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyB0cnV0aHkuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2V2ZXJ5dGhpbmcnKS50by5iZS5vaztcbiAgICogICAgIGV4cGVjdCgxKS50by5iZS5vaztcbiAgICogICAgIGV4cGVjdChmYWxzZSkudG8ubm90LmJlLm9rO1xuICAgKiAgICAgZXhwZWN0KHVuZGVmaW5lZCkudG8ubm90LmJlLm9rO1xuICAgKiAgICAgZXhwZWN0KG51bGwpLnRvLm5vdC5iZS5vaztcbiAgICpcbiAgICogQG5hbWUgb2tcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdvaycsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgdHJ1dGh5J1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBmYWxzeScpO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC50cnVlXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGB0cnVlYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCh0cnVlKS50by5iZS50cnVlO1xuICAgKiAgICAgZXhwZWN0KDEpLnRvLm5vdC5iZS50cnVlO1xuICAgKlxuICAgKiBAbmFtZSB0cnVlXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgndHJ1ZScsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgdHJ1ZSA9PT0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgdHJ1ZSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgZmFsc2UnXG4gICAgICAsIHRoaXMubmVnYXRlID8gZmFsc2UgOiB0cnVlXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuZmFsc2VcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgYGZhbHNlYC5cbiAgICpcbiAgICogICAgIGV4cGVjdChmYWxzZSkudG8uYmUuZmFsc2U7XG4gICAqICAgICBleHBlY3QoMCkudG8ubm90LmJlLmZhbHNlO1xuICAgKlxuICAgKiBAbmFtZSBmYWxzZVxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2ZhbHNlJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBmYWxzZSA9PT0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgZmFsc2UnXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIHRydWUnXG4gICAgICAsIHRoaXMubmVnYXRlID8gdHJ1ZSA6IGZhbHNlXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAubnVsbFxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBgbnVsbGAuXG4gICAqXG4gICAqICAgICBleHBlY3QobnVsbCkudG8uYmUubnVsbDtcbiAgICogICAgIGV4cGVjdCh1bmRlZmluZWQpLnRvLm5vdC5iZS5udWxsO1xuICAgKlxuICAgKiBAbmFtZSBudWxsXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnbnVsbCcsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgbnVsbCA9PT0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgbnVsbCdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIGJlIG51bGwnXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAudW5kZWZpbmVkXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGB1bmRlZmluZWRgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHVuZGVmaW5lZCkudG8uYmUudW5kZWZpbmVkO1xuICAgKiAgICAgZXhwZWN0KG51bGwpLnRvLm5vdC5iZS51bmRlZmluZWQ7XG4gICAqXG4gICAqIEBuYW1lIHVuZGVmaW5lZFxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ3VuZGVmaW5lZCcsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgdW5kZWZpbmVkID09PSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSB1bmRlZmluZWQnXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSB1bmRlZmluZWQnXG4gICAgKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqICMjIyAuTmFOXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGBOYU5gLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5iZS5OYU47XG4gICAqICAgICBleHBlY3QoNCkubm90LnRvLmJlLk5hTjtcbiAgICpcbiAgICogQG5hbWUgTmFOXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnTmFOJywgZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBpc05hTihmbGFnKHRoaXMsICdvYmplY3QnKSlcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBOYU4nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIGJlIE5hTidcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5leGlzdFxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBuZWl0aGVyIGBudWxsYCBub3IgYHVuZGVmaW5lZGAuXG4gICAqXG4gICAqICAgICB2YXIgZm9vID0gJ2hpJ1xuICAgKiAgICAgICAsIGJhciA9IG51bGxcbiAgICogICAgICAgLCBiYXo7XG4gICAqXG4gICAqICAgICBleHBlY3QoZm9vKS50by5leGlzdDtcbiAgICogICAgIGV4cGVjdChiYXIpLnRvLm5vdC5leGlzdDtcbiAgICogICAgIGV4cGVjdChiYXopLnRvLm5vdC5leGlzdDtcbiAgICpcbiAgICogQG5hbWUgZXhpc3RcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdleGlzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgbnVsbCAhPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBleGlzdCdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGV4aXN0J1xuICAgICk7XG4gIH0pO1xuXG5cbiAgLyoqXG4gICAqICMjIyAuZW1wdHlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQncyBsZW5ndGggaXMgYDBgLiBGb3IgYXJyYXlzIGFuZCBzdHJpbmdzLCBpdCBjaGVja3NcbiAgICogdGhlIGBsZW5ndGhgIHByb3BlcnR5LiBGb3Igb2JqZWN0cywgaXQgZ2V0cyB0aGUgY291bnQgb2ZcbiAgICogZW51bWVyYWJsZSBrZXlzLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KFtdKS50by5iZS5lbXB0eTtcbiAgICogICAgIGV4cGVjdCgnJykudG8uYmUuZW1wdHk7XG4gICAqICAgICBleHBlY3Qoe30pLnRvLmJlLmVtcHR5O1xuICAgKlxuICAgKiBAbmFtZSBlbXB0eVxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2VtcHR5JywgZnVuY3Rpb24gKCkge1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKVxuICAgICAgLCBleHBlY3RlZCA9IG9iajtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikgfHwgJ3N0cmluZycgPT09IHR5cGVvZiBvYmplY3QpIHtcbiAgICAgIGV4cGVjdGVkID0gb2JqLmxlbmd0aDtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnKSB7XG4gICAgICBleHBlY3RlZCA9IE9iamVjdC5rZXlzKG9iaikubGVuZ3RoO1xuICAgIH1cblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAhZXhwZWN0ZWRcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgZW1wdHknXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IG5vdCB0byBiZSBlbXB0eSdcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5hcmd1bWVudHNcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgYW4gYXJndW1lbnRzIG9iamVjdC5cbiAgICpcbiAgICogICAgIGZ1bmN0aW9uIHRlc3QgKCkge1xuICAgKiAgICAgICBleHBlY3QoYXJndW1lbnRzKS50by5iZS5hcmd1bWVudHM7XG4gICAqICAgICB9XG4gICAqXG4gICAqIEBuYW1lIGFyZ3VtZW50c1xuICAgKiBAYWxpYXMgQXJndW1lbnRzXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGNoZWNrQXJndW1lbnRzICgpIHtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0JylcbiAgICAgICwgdHlwZSA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopO1xuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAnW29iamVjdCBBcmd1bWVudHNdJyA9PT0gdHlwZVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBhcmd1bWVudHMgYnV0IGdvdCAnICsgdHlwZVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgYXJndW1lbnRzJ1xuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkUHJvcGVydHkoJ2FyZ3VtZW50cycsIGNoZWNrQXJndW1lbnRzKTtcbiAgQXNzZXJ0aW9uLmFkZFByb3BlcnR5KCdBcmd1bWVudHMnLCBjaGVja0FyZ3VtZW50cyk7XG5cbiAgLyoqXG4gICAqICMjIyAuZXF1YWwodmFsdWUpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIHN0cmljdGx5IGVxdWFsIChgPT09YCkgdG8gYHZhbHVlYC5cbiAgICogQWx0ZXJuYXRlbHksIGlmIHRoZSBgZGVlcGAgZmxhZyBpcyBzZXQsIGFzc2VydHMgdGhhdFxuICAgKiB0aGUgdGFyZ2V0IGlzIGRlZXBseSBlcXVhbCB0byBgdmFsdWVgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdoZWxsbycpLnRvLmVxdWFsKCdoZWxsbycpO1xuICAgKiAgICAgZXhwZWN0KDQyKS50by5lcXVhbCg0Mik7XG4gICAqICAgICBleHBlY3QoMSkudG8ubm90LmVxdWFsKHRydWUpO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAnYmFyJyB9KS50by5ub3QuZXF1YWwoeyBmb286ICdiYXInIH0pO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAnYmFyJyB9KS50by5kZWVwLmVxdWFsKHsgZm9vOiAnYmFyJyB9KTtcbiAgICpcbiAgICogQG5hbWUgZXF1YWxcbiAgICogQGFsaWFzIGVxdWFsc1xuICAgKiBAYWxpYXMgZXFcbiAgICogQGFsaWFzIGRlZXAuZXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRFcXVhbCAodmFsLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgaWYgKGZsYWcodGhpcywgJ2RlZXAnKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZXFsKHZhbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIHZhbCA9PT0gb2JqXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gZXF1YWwgI3tleHB9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBlcXVhbCAje2V4cH0nXG4gICAgICAgICwgdmFsXG4gICAgICAgICwgdGhpcy5fb2JqXG4gICAgICAgICwgdHJ1ZVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdlcXVhbCcsIGFzc2VydEVxdWFsKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZXF1YWxzJywgYXNzZXJ0RXF1YWwpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdlcScsIGFzc2VydEVxdWFsKTtcblxuICAvKipcbiAgICogIyMjIC5lcWwodmFsdWUpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGRlZXBseSBlcXVhbCB0byBgdmFsdWVgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAnYmFyJyB9KS50by5lcWwoeyBmb286ICdiYXInIH0pO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5lcWwoWyAxLCAyLCAzIF0pO1xuICAgKlxuICAgKiBAbmFtZSBlcWxcbiAgICogQGFsaWFzIGVxbHNcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRFcWwob2JqLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgXy5lcWwob2JqLCBmbGFnKHRoaXMsICdvYmplY3QnKSlcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gZGVlcGx5IGVxdWFsICN7ZXhwfSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGRlZXBseSBlcXVhbCAje2V4cH0nXG4gICAgICAsIG9ialxuICAgICAgLCB0aGlzLl9vYmpcbiAgICAgICwgdHJ1ZVxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdlcWwnLCBhc3NlcnRFcWwpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdlcWxzJywgYXNzZXJ0RXFsKTtcblxuICAvKipcbiAgICogIyMjIC5hYm92ZSh2YWx1ZSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgZ3JlYXRlciB0aGFuIGB2YWx1ZWAuXG4gICAqXG4gICAqICAgICBleHBlY3QoMTApLnRvLmJlLmFib3ZlKDUpO1xuICAgKlxuICAgKiBDYW4gYWxzbyBiZSB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggYGxlbmd0aGAgdG9cbiAgICogYXNzZXJ0IGEgbWluaW11bSBsZW5ndGguIFRoZSBiZW5lZml0IGJlaW5nIGFcbiAgICogbW9yZSBpbmZvcm1hdGl2ZSBlcnJvciBtZXNzYWdlIHRoYW4gaWYgdGhlIGxlbmd0aFxuICAgKiB3YXMgc3VwcGxpZWQgZGlyZWN0bHkuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoLmFib3ZlKDIpO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5oYXZlLmxlbmd0aC5hYm92ZSgyKTtcbiAgICpcbiAgICogQG5hbWUgYWJvdmVcbiAgICogQGFsaWFzIGd0XG4gICAqIEBhbGlhcyBncmVhdGVyVGhhblxuICAgKiBAcGFyYW0ge051bWJlcn0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRBYm92ZSAobiwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIGlmIChmbGFnKHRoaXMsICdkb0xlbmd0aCcpKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICAgIHZhciBsZW4gPSBvYmoubGVuZ3RoO1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgbGVuID4gblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSBsZW5ndGggYWJvdmUgI3tleHB9IGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlIGEgbGVuZ3RoIGFib3ZlICN7ZXhwfSdcbiAgICAgICAgLCBuXG4gICAgICAgICwgbGVuXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBvYmogPiBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYWJvdmUgJyArIG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBhdCBtb3N0ICcgKyBuXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2Fib3ZlJywgYXNzZXJ0QWJvdmUpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdndCcsIGFzc2VydEFib3ZlKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZ3JlYXRlclRoYW4nLCBhc3NlcnRBYm92ZSk7XG5cbiAgLyoqXG4gICAqICMjIyAubGVhc3QodmFsdWUpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBgdmFsdWVgLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDEwKS50by5iZS5hdC5sZWFzdCgxMCk7XG4gICAqXG4gICAqIENhbiBhbHNvIGJlIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCBgbGVuZ3RoYCB0b1xuICAgKiBhc3NlcnQgYSBtaW5pbXVtIGxlbmd0aC4gVGhlIGJlbmVmaXQgYmVpbmcgYVxuICAgKiBtb3JlIGluZm9ybWF0aXZlIGVycm9yIG1lc3NhZ2UgdGhhbiBpZiB0aGUgbGVuZ3RoXG4gICAqIHdhcyBzdXBwbGllZCBkaXJlY3RseS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGgub2YuYXQubGVhc3QoMik7XG4gICAqICAgICBleHBlY3QoWyAxLCAyLCAzIF0pLnRvLmhhdmUubGVuZ3RoLm9mLmF0LmxlYXN0KDMpO1xuICAgKlxuICAgKiBAbmFtZSBsZWFzdFxuICAgKiBAYWxpYXMgZ3RlXG4gICAqIEBwYXJhbSB7TnVtYmVyfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydExlYXN0IChuLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgaWYgKGZsYWcodGhpcywgJ2RvTGVuZ3RoJykpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLnRvLmhhdmUucHJvcGVydHkoJ2xlbmd0aCcpO1xuICAgICAgdmFyIGxlbiA9IG9iai5sZW5ndGg7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBsZW4gPj0gblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSBsZW5ndGggYXQgbGVhc3QgI3tleHB9IGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSBsZW5ndGggYmVsb3cgI3tleHB9J1xuICAgICAgICAsIG5cbiAgICAgICAgLCBsZW5cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIG9iaiA+PSBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYXQgbGVhc3QgJyArIG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBiZWxvdyAnICsgblxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdsZWFzdCcsIGFzc2VydExlYXN0KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZ3RlJywgYXNzZXJ0TGVhc3QpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmJlbG93KHZhbHVlKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBsZXNzIHRoYW4gYHZhbHVlYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCg1KS50by5iZS5iZWxvdygxMCk7XG4gICAqXG4gICAqIENhbiBhbHNvIGJlIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCBgbGVuZ3RoYCB0b1xuICAgKiBhc3NlcnQgYSBtYXhpbXVtIGxlbmd0aC4gVGhlIGJlbmVmaXQgYmVpbmcgYVxuICAgKiBtb3JlIGluZm9ybWF0aXZlIGVycm9yIG1lc3NhZ2UgdGhhbiBpZiB0aGUgbGVuZ3RoXG4gICAqIHdhcyBzdXBwbGllZCBkaXJlY3RseS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGguYmVsb3coNCk7XG4gICAqICAgICBleHBlY3QoWyAxLCAyLCAzIF0pLnRvLmhhdmUubGVuZ3RoLmJlbG93KDQpO1xuICAgKlxuICAgKiBAbmFtZSBiZWxvd1xuICAgKiBAYWxpYXMgbHRcbiAgICogQGFsaWFzIGxlc3NUaGFuXG4gICAqIEBwYXJhbSB7TnVtYmVyfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydEJlbG93IChuLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgaWYgKGZsYWcodGhpcywgJ2RvTGVuZ3RoJykpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLnRvLmhhdmUucHJvcGVydHkoJ2xlbmd0aCcpO1xuICAgICAgdmFyIGxlbiA9IG9iai5sZW5ndGg7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBsZW4gPCBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSBhIGxlbmd0aCBiZWxvdyAje2V4cH0gYnV0IGdvdCAje2FjdH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgYSBsZW5ndGggYmVsb3cgI3tleHB9J1xuICAgICAgICAsIG5cbiAgICAgICAgLCBsZW5cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIG9iaiA8IG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBiZWxvdyAnICsgblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGF0IGxlYXN0ICcgKyBuXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2JlbG93JywgYXNzZXJ0QmVsb3cpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdsdCcsIGFzc2VydEJlbG93KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbGVzc1RoYW4nLCBhc3NlcnRCZWxvdyk7XG5cbiAgLyoqXG4gICAqICMjIyAubW9zdCh2YWx1ZSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGB2YWx1ZWAuXG4gICAqXG4gICAqICAgICBleHBlY3QoNSkudG8uYmUuYXQubW9zdCg1KTtcbiAgICpcbiAgICogQ2FuIGFsc28gYmUgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGBsZW5ndGhgIHRvXG4gICAqIGFzc2VydCBhIG1heGltdW0gbGVuZ3RoLiBUaGUgYmVuZWZpdCBiZWluZyBhXG4gICAqIG1vcmUgaW5mb3JtYXRpdmUgZXJyb3IgbWVzc2FnZSB0aGFuIGlmIHRoZSBsZW5ndGhcbiAgICogd2FzIHN1cHBsaWVkIGRpcmVjdGx5LlxuICAgKlxuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5oYXZlLmxlbmd0aC5vZi5hdC5tb3N0KDQpO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5oYXZlLmxlbmd0aC5vZi5hdC5tb3N0KDMpO1xuICAgKlxuICAgKiBAbmFtZSBtb3N0XG4gICAqIEBhbGlhcyBsdGVcbiAgICogQHBhcmFtIHtOdW1iZXJ9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0TW9zdCAobiwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIGlmIChmbGFnKHRoaXMsICdkb0xlbmd0aCcpKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICAgIHZhciBsZW4gPSBvYmoubGVuZ3RoO1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgbGVuIDw9IG5cbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgbGVuZ3RoIGF0IG1vc3QgI3tleHB9IGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSBsZW5ndGggYWJvdmUgI3tleHB9J1xuICAgICAgICAsIG5cbiAgICAgICAgLCBsZW5cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIG9iaiA8PSBuXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYXQgbW9zdCAnICsgblxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGFib3ZlICcgKyBuXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ21vc3QnLCBhc3NlcnRNb3N0KTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbHRlJywgYXNzZXJ0TW9zdCk7XG5cbiAgLyoqXG4gICAqICMjIyAud2l0aGluKHN0YXJ0LCBmaW5pc2gpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIHdpdGhpbiBhIHJhbmdlLlxuICAgKlxuICAgKiAgICAgZXhwZWN0KDcpLnRvLmJlLndpdGhpbig1LDEwKTtcbiAgICpcbiAgICogQ2FuIGFsc28gYmUgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGBsZW5ndGhgIHRvXG4gICAqIGFzc2VydCBhIGxlbmd0aCByYW5nZS4gVGhlIGJlbmVmaXQgYmVpbmcgYVxuICAgKiBtb3JlIGluZm9ybWF0aXZlIGVycm9yIG1lc3NhZ2UgdGhhbiBpZiB0aGUgbGVuZ3RoXG4gICAqIHdhcyBzdXBwbGllZCBkaXJlY3RseS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGgud2l0aGluKDIsNCk7XG4gICAqICAgICBleHBlY3QoWyAxLCAyLCAzIF0pLnRvLmhhdmUubGVuZ3RoLndpdGhpbigyLDQpO1xuICAgKlxuICAgKiBAbmFtZSB3aXRoaW5cbiAgICogQHBhcmFtIHtOdW1iZXJ9IHN0YXJ0IGxvd2VyYm91bmQgaW5jbHVzaXZlXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBmaW5pc2ggdXBwZXJib3VuZCBpbmNsdXNpdmVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCd3aXRoaW4nLCBmdW5jdGlvbiAoc3RhcnQsIGZpbmlzaCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIHJhbmdlID0gc3RhcnQgKyAnLi4nICsgZmluaXNoO1xuICAgIGlmIChmbGFnKHRoaXMsICdkb0xlbmd0aCcpKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICAgIHZhciBsZW4gPSBvYmoubGVuZ3RoO1xuICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgbGVuID49IHN0YXJ0ICYmIGxlbiA8PSBmaW5pc2hcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgbGVuZ3RoIHdpdGhpbiAnICsgcmFuZ2VcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgaGF2ZSBhIGxlbmd0aCB3aXRoaW4gJyArIHJhbmdlXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBvYmogPj0gc3RhcnQgJiYgb2JqIDw9IGZpbmlzaFxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIHdpdGhpbiAnICsgcmFuZ2VcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgd2l0aGluICcgKyByYW5nZVxuICAgICAgKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLmluc3RhbmNlb2YoY29uc3RydWN0b3IpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGFuIGluc3RhbmNlIG9mIGBjb25zdHJ1Y3RvcmAuXG4gICAqXG4gICAqICAgICB2YXIgVGVhID0gZnVuY3Rpb24gKG5hbWUpIHsgdGhpcy5uYW1lID0gbmFtZTsgfVxuICAgKiAgICAgICAsIENoYWkgPSBuZXcgVGVhKCdjaGFpJyk7XG4gICAqXG4gICAqICAgICBleHBlY3QoQ2hhaSkudG8uYmUuYW4uaW5zdGFuY2VvZihUZWEpO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5iZS5pbnN0YW5jZW9mKEFycmF5KTtcbiAgICpcbiAgICogQG5hbWUgaW5zdGFuY2VvZlxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yfSBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBhbGlhcyBpbnN0YW5jZU9mXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFzc2VydEluc3RhbmNlT2YgKGNvbnN0cnVjdG9yLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgbmFtZSA9IF8uZ2V0TmFtZShjb25zdHJ1Y3Rvcik7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIGZsYWcodGhpcywgJ29iamVjdCcpIGluc3RhbmNlb2YgY29uc3RydWN0b3JcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgYW4gaW5zdGFuY2Ugb2YgJyArIG5hbWVcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIGFuIGluc3RhbmNlIG9mICcgKyBuYW1lXG4gICAgKTtcbiAgfTtcblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdpbnN0YW5jZW9mJywgYXNzZXJ0SW5zdGFuY2VPZik7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2luc3RhbmNlT2YnLCBhc3NlcnRJbnN0YW5jZU9mKTtcblxuICAvKipcbiAgICogIyMjIC5wcm9wZXJ0eShuYW1lLCBbdmFsdWVdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBoYXMgYSBwcm9wZXJ0eSBgbmFtZWAsIG9wdGlvbmFsbHkgYXNzZXJ0aW5nIHRoYXRcbiAgICogdGhlIHZhbHVlIG9mIHRoYXQgcHJvcGVydHkgaXMgc3RyaWN0bHkgZXF1YWwgdG8gIGB2YWx1ZWAuXG4gICAqIElmIHRoZSBgZGVlcGAgZmxhZyBpcyBzZXQsIHlvdSBjYW4gdXNlIGRvdC0gYW5kIGJyYWNrZXQtbm90YXRpb24gZm9yIGRlZXBcbiAgICogcmVmZXJlbmNlcyBpbnRvIG9iamVjdHMgYW5kIGFycmF5cy5cbiAgICpcbiAgICogICAgIC8vIHNpbXBsZSByZWZlcmVuY2luZ1xuICAgKiAgICAgdmFyIG9iaiA9IHsgZm9vOiAnYmFyJyB9O1xuICAgKiAgICAgZXhwZWN0KG9iaikudG8uaGF2ZS5wcm9wZXJ0eSgnZm9vJyk7XG4gICAqICAgICBleHBlY3Qob2JqKS50by5oYXZlLnByb3BlcnR5KCdmb28nLCAnYmFyJyk7XG4gICAqXG4gICAqICAgICAvLyBkZWVwIHJlZmVyZW5jaW5nXG4gICAqICAgICB2YXIgZGVlcE9iaiA9IHtcbiAgICogICAgICAgICBncmVlbjogeyB0ZWE6ICdtYXRjaGEnIH1cbiAgICogICAgICAgLCB0ZWFzOiBbICdjaGFpJywgJ21hdGNoYScsIHsgdGVhOiAna29uYWNoYScgfSBdXG4gICAqICAgICB9O1xuICAgKlxuICAgKiAgICAgZXhwZWN0KGRlZXBPYmopLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eSgnZ3JlZW4udGVhJywgJ21hdGNoYScpO1xuICAgKiAgICAgZXhwZWN0KGRlZXBPYmopLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eSgndGVhc1sxXScsICdtYXRjaGEnKTtcbiAgICogICAgIGV4cGVjdChkZWVwT2JqKS50by5oYXZlLmRlZXAucHJvcGVydHkoJ3RlYXNbMl0udGVhJywgJ2tvbmFjaGEnKTtcbiAgICpcbiAgICogWW91IGNhbiBhbHNvIHVzZSBhbiBhcnJheSBhcyB0aGUgc3RhcnRpbmcgcG9pbnQgb2YgYSBgZGVlcC5wcm9wZXJ0eWBcbiAgICogYXNzZXJ0aW9uLCBvciB0cmF2ZXJzZSBuZXN0ZWQgYXJyYXlzLlxuICAgKlxuICAgKiAgICAgdmFyIGFyciA9IFtcbiAgICogICAgICAgICBbICdjaGFpJywgJ21hdGNoYScsICdrb25hY2hhJyBdXG4gICAqICAgICAgICwgWyB7IHRlYTogJ2NoYWknIH1cbiAgICogICAgICAgICAsIHsgdGVhOiAnbWF0Y2hhJyB9XG4gICAqICAgICAgICAgLCB7IHRlYTogJ2tvbmFjaGEnIH0gXVxuICAgKiAgICAgXTtcbiAgICpcbiAgICogICAgIGV4cGVjdChhcnIpLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eSgnWzBdWzFdJywgJ21hdGNoYScpO1xuICAgKiAgICAgZXhwZWN0KGFycikudG8uaGF2ZS5kZWVwLnByb3BlcnR5KCdbMV1bMl0udGVhJywgJ2tvbmFjaGEnKTtcbiAgICpcbiAgICogRnVydGhlcm1vcmUsIGBwcm9wZXJ0eWAgY2hhbmdlcyB0aGUgc3ViamVjdCBvZiB0aGUgYXNzZXJ0aW9uXG4gICAqIHRvIGJlIHRoZSB2YWx1ZSBvZiB0aGF0IHByb3BlcnR5IGZyb20gdGhlIG9yaWdpbmFsIG9iamVjdC4gVGhpc1xuICAgKiBwZXJtaXRzIGZvciBmdXJ0aGVyIGNoYWluYWJsZSBhc3NlcnRpb25zIG9uIHRoYXQgcHJvcGVydHkuXG4gICAqXG4gICAqICAgICBleHBlY3Qob2JqKS50by5oYXZlLnByb3BlcnR5KCdmb28nKVxuICAgKiAgICAgICAudGhhdC5pcy5hKCdzdHJpbmcnKTtcbiAgICogICAgIGV4cGVjdChkZWVwT2JqKS50by5oYXZlLnByb3BlcnR5KCdncmVlbicpXG4gICAqICAgICAgIC50aGF0LmlzLmFuKCdvYmplY3QnKVxuICAgKiAgICAgICAudGhhdC5kZWVwLmVxdWFscyh7IHRlYTogJ21hdGNoYScgfSk7XG4gICAqICAgICBleHBlY3QoZGVlcE9iaikudG8uaGF2ZS5wcm9wZXJ0eSgndGVhcycpXG4gICAqICAgICAgIC50aGF0LmlzLmFuKCdhcnJheScpXG4gICAqICAgICAgIC53aXRoLmRlZXAucHJvcGVydHkoJ1syXScpXG4gICAqICAgICAgICAgLnRoYXQuZGVlcC5lcXVhbHMoeyB0ZWE6ICdrb25hY2hhJyB9KTtcbiAgICpcbiAgICogTm90ZSB0aGF0IGRvdHMgYW5kIGJyYWNrZXQgaW4gYG5hbWVgIG11c3QgYmUgYmFja3NsYXNoLWVzY2FwZWQgd2hlblxuICAgKiB0aGUgYGRlZXBgIGZsYWcgaXMgc2V0LCB3aGlsZSB0aGV5IG11c3QgTk9UIGJlIGVzY2FwZWQgd2hlbiB0aGUgYGRlZXBgXG4gICAqIGZsYWcgaXMgbm90IHNldC5cbiAgICpcbiAgICogICAgIC8vIHNpbXBsZSByZWZlcmVuY2luZ1xuICAgKiAgICAgdmFyIGNzcyA9IHsgJy5saW5rW3RhcmdldF0nOiA0MiB9O1xuICAgKiAgICAgZXhwZWN0KGNzcykudG8uaGF2ZS5wcm9wZXJ0eSgnLmxpbmtbdGFyZ2V0XScsIDQyKTtcbiAgICpcbiAgICogICAgIC8vIGRlZXAgcmVmZXJlbmNpbmdcbiAgICogICAgIHZhciBkZWVwQ3NzID0geyAnLmxpbmsnOiB7ICdbdGFyZ2V0XSc6IDQyIH19O1xuICAgKiAgICAgZXhwZWN0KGRlZXBDc3MpLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eSgnXFxcXC5saW5rLlxcXFxbdGFyZ2V0XFxcXF0nLCA0Mik7XG4gICAqXG4gICAqIEBuYW1lIHByb3BlcnR5XG4gICAqIEBhbGlhcyBkZWVwLnByb3BlcnR5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlIChvcHRpb25hbClcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAcmV0dXJucyB2YWx1ZSBvZiBwcm9wZXJ0eSBmb3IgY2hhaW5pbmdcbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgncHJvcGVydHknLCBmdW5jdGlvbiAobmFtZSwgdmFsLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcblxuICAgIHZhciBpc0RlZXAgPSAhIWZsYWcodGhpcywgJ2RlZXAnKVxuICAgICAgLCBkZXNjcmlwdG9yID0gaXNEZWVwID8gJ2RlZXAgcHJvcGVydHkgJyA6ICdwcm9wZXJ0eSAnXG4gICAgICAsIG5lZ2F0ZSA9IGZsYWcodGhpcywgJ25lZ2F0ZScpXG4gICAgICAsIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIHBhdGhJbmZvID0gaXNEZWVwID8gXy5nZXRQYXRoSW5mbyhuYW1lLCBvYmopIDogbnVsbFxuICAgICAgLCBoYXNQcm9wZXJ0eSA9IGlzRGVlcFxuICAgICAgICA/IHBhdGhJbmZvLmV4aXN0c1xuICAgICAgICA6IF8uaGFzUHJvcGVydHkobmFtZSwgb2JqKVxuICAgICAgLCB2YWx1ZSA9IGlzRGVlcFxuICAgICAgICA/IHBhdGhJbmZvLnZhbHVlXG4gICAgICAgIDogb2JqW25hbWVdO1xuXG4gICAgaWYgKG5lZ2F0ZSAmJiBhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgaWYgKHVuZGVmaW5lZCA9PT0gdmFsdWUpIHtcbiAgICAgICAgbXNnID0gKG1zZyAhPSBudWxsKSA/IG1zZyArICc6ICcgOiAnJztcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyArIF8uaW5zcGVjdChvYmopICsgJyBoYXMgbm8gJyArIGRlc2NyaXB0b3IgKyBfLmluc3BlY3QobmFtZSkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBoYXNQcm9wZXJ0eVxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgYSAnICsgZGVzY3JpcHRvciArIF8uaW5zcGVjdChuYW1lKVxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlICcgKyBkZXNjcmlwdG9yICsgXy5pbnNwZWN0KG5hbWUpKTtcbiAgICB9XG5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIHZhbCA9PT0gdmFsdWVcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgJyArIGRlc2NyaXB0b3IgKyBfLmluc3BlY3QobmFtZSkgKyAnIG9mICN7ZXhwfSwgYnV0IGdvdCAje2FjdH0nXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgYSAnICsgZGVzY3JpcHRvciArIF8uaW5zcGVjdChuYW1lKSArICcgb2YgI3thY3R9J1xuICAgICAgICAsIHZhbFxuICAgICAgICAsIHZhbHVlXG4gICAgICApO1xuICAgIH1cblxuICAgIGZsYWcodGhpcywgJ29iamVjdCcsIHZhbHVlKTtcbiAgfSk7XG5cblxuICAvKipcbiAgICogIyMjIC5vd25Qcm9wZXJ0eShuYW1lKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBoYXMgYW4gb3duIHByb3BlcnR5IGBuYW1lYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgndGVzdCcpLnRvLmhhdmUub3duUHJvcGVydHkoJ2xlbmd0aCcpO1xuICAgKlxuICAgKiBAbmFtZSBvd25Qcm9wZXJ0eVxuICAgKiBAYWxpYXMgaGF2ZU93blByb3BlcnR5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0T3duUHJvcGVydHkgKG5hbWUsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgb2JqLmhhc093blByb3BlcnR5KG5hbWUpXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGhhdmUgb3duIHByb3BlcnR5ICcgKyBfLmluc3BlY3QobmFtZSlcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgb3duIHByb3BlcnR5ICcgKyBfLmluc3BlY3QobmFtZSlcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnb3duUHJvcGVydHknLCBhc3NlcnRPd25Qcm9wZXJ0eSk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2hhdmVPd25Qcm9wZXJ0eScsIGFzc2VydE93blByb3BlcnR5KTtcblxuICAvKipcbiAgICogIyMjIC5vd25Qcm9wZXJ0eURlc2NyaXB0b3IobmFtZVssIGRlc2NyaXB0b3JbLCBtZXNzYWdlXV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGhhcyBhbiBvd24gcHJvcGVydHkgZGVzY3JpcHRvciBgbmFtZWAsIHRoYXQgb3B0aW9uYWxseSBtYXRjaGVzIGBkZXNjcmlwdG9yYC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgndGVzdCcpLnRvLmhhdmUub3duUHJvcGVydHlEZXNjcmlwdG9yKCdsZW5ndGgnKTtcbiAgICogICAgIGV4cGVjdCgndGVzdCcpLnRvLmhhdmUub3duUHJvcGVydHlEZXNjcmlwdG9yKCdsZW5ndGgnLCB7IGVudW1lcmFibGU6IGZhbHNlLCBjb25maWd1cmFibGU6IGZhbHNlLCB3cml0YWJsZTogZmFsc2UsIHZhbHVlOiA0IH0pO1xuICAgKiAgICAgZXhwZWN0KCd0ZXN0Jykubm90LnRvLmhhdmUub3duUHJvcGVydHlEZXNjcmlwdG9yKCdsZW5ndGgnLCB7IGVudW1lcmFibGU6IGZhbHNlLCBjb25maWd1cmFibGU6IGZhbHNlLCB3cml0YWJsZTogZmFsc2UsIHZhbHVlOiAzIH0pO1xuICAgKiAgICAgZXhwZWN0KCd0ZXN0Jykub3duUHJvcGVydHlEZXNjcmlwdG9yKCdsZW5ndGgnKS50by5oYXZlLnByb3BlcnR5KCdlbnVtZXJhYmxlJywgZmFsc2UpO1xuICAgKiAgICAgZXhwZWN0KCd0ZXN0Jykub3duUHJvcGVydHlEZXNjcmlwdG9yKCdsZW5ndGgnKS50by5oYXZlLmtleXMoJ3ZhbHVlJyk7XG4gICAqXG4gICAqIEBuYW1lIG93blByb3BlcnR5RGVzY3JpcHRvclxuICAgKiBAYWxpYXMgaGF2ZU93blByb3BlcnR5RGVzY3JpcHRvclxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgKiBAcGFyYW0ge09iamVjdH0gZGVzY3JpcHRvciBfb3B0aW9uYWxfXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0T3duUHJvcGVydHlEZXNjcmlwdG9yIChuYW1lLCBkZXNjcmlwdG9yLCBtc2cpIHtcbiAgICBpZiAodHlwZW9mIGRlc2NyaXB0b3IgPT09ICdzdHJpbmcnKSB7XG4gICAgICBtc2cgPSBkZXNjcmlwdG9yO1xuICAgICAgZGVzY3JpcHRvciA9IG51bGw7XG4gICAgfVxuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICB2YXIgYWN0dWFsRGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoT2JqZWN0KG9iaiksIG5hbWUpO1xuICAgIGlmIChhY3R1YWxEZXNjcmlwdG9yICYmIGRlc2NyaXB0b3IpIHtcbiAgICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIF8uZXFsKGRlc2NyaXB0b3IsIGFjdHVhbERlc2NyaXB0b3IpXG4gICAgICAgICwgJ2V4cGVjdGVkIHRoZSBvd24gcHJvcGVydHkgZGVzY3JpcHRvciBmb3IgJyArIF8uaW5zcGVjdChuYW1lKSArICcgb24gI3t0aGlzfSB0byBtYXRjaCAnICsgXy5pbnNwZWN0KGRlc2NyaXB0b3IpICsgJywgZ290ICcgKyBfLmluc3BlY3QoYWN0dWFsRGVzY3JpcHRvcilcbiAgICAgICAgLCAnZXhwZWN0ZWQgdGhlIG93biBwcm9wZXJ0eSBkZXNjcmlwdG9yIGZvciAnICsgXy5pbnNwZWN0KG5hbWUpICsgJyBvbiAje3RoaXN9IHRvIG5vdCBtYXRjaCAnICsgXy5pbnNwZWN0KGRlc2NyaXB0b3IpXG4gICAgICAgICwgZGVzY3JpcHRvclxuICAgICAgICAsIGFjdHVhbERlc2NyaXB0b3JcbiAgICAgICAgLCB0cnVlXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICBhY3R1YWxEZXNjcmlwdG9yXG4gICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gaGF2ZSBhbiBvd24gcHJvcGVydHkgZGVzY3JpcHRvciBmb3IgJyArIF8uaW5zcGVjdChuYW1lKVxuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlIGFuIG93biBwcm9wZXJ0eSBkZXNjcmlwdG9yIGZvciAnICsgXy5pbnNwZWN0KG5hbWUpXG4gICAgICApO1xuICAgIH1cbiAgICBmbGFnKHRoaXMsICdvYmplY3QnLCBhY3R1YWxEZXNjcmlwdG9yKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ293blByb3BlcnR5RGVzY3JpcHRvcicsIGFzc2VydE93blByb3BlcnR5RGVzY3JpcHRvcik7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2hhdmVPd25Qcm9wZXJ0eURlc2NyaXB0b3InLCBhc3NlcnRPd25Qcm9wZXJ0eURlc2NyaXB0b3IpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmxlbmd0aFxuICAgKlxuICAgKiBTZXRzIHRoZSBgZG9MZW5ndGhgIGZsYWcgbGF0ZXIgdXNlZCBhcyBhIGNoYWluIHByZWN1cnNvciB0byBhIHZhbHVlXG4gICAqIGNvbXBhcmlzb24gZm9yIHRoZSBgbGVuZ3RoYCBwcm9wZXJ0eS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vJykudG8uaGF2ZS5sZW5ndGguYWJvdmUoMik7XG4gICAqICAgICBleHBlY3QoWyAxLCAyLCAzIF0pLnRvLmhhdmUubGVuZ3RoLmFib3ZlKDIpO1xuICAgKiAgICAgZXhwZWN0KCdmb28nKS50by5oYXZlLmxlbmd0aC5iZWxvdyg0KTtcbiAgICogICAgIGV4cGVjdChbIDEsIDIsIDMgXSkudG8uaGF2ZS5sZW5ndGguYmVsb3coNCk7XG4gICAqICAgICBleHBlY3QoJ2ZvbycpLnRvLmhhdmUubGVuZ3RoLndpdGhpbigyLDQpO1xuICAgKiAgICAgZXhwZWN0KFsgMSwgMiwgMyBdKS50by5oYXZlLmxlbmd0aC53aXRoaW4oMiw0KTtcbiAgICpcbiAgICogKkRlcHJlY2F0aW9uIG5vdGljZToqIFVzaW5nIGBsZW5ndGhgIGFzIGFuIGFzc2VydGlvbiB3aWxsIGJlIGRlcHJlY2F0ZWRcbiAgICogaW4gdmVyc2lvbiAyLjQuMCBhbmQgcmVtb3ZlZCBpbiAzLjAuMC4gQ29kZSB1c2luZyB0aGUgb2xkIHN0eWxlIG9mXG4gICAqIGFzc2VydGluZyBmb3IgYGxlbmd0aGAgcHJvcGVydHkgdmFsdWUgdXNpbmcgYGxlbmd0aCh2YWx1ZSlgIHNob3VsZCBiZVxuICAgKiBzd2l0Y2hlZCB0byB1c2UgYGxlbmd0aE9mKHZhbHVlKWAgaW5zdGVhZC5cbiAgICpcbiAgICogQG5hbWUgbGVuZ3RoXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIC8qKlxuICAgKiAjIyMgLmxlbmd0aE9mKHZhbHVlWywgbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0J3MgYGxlbmd0aGAgcHJvcGVydHkgaGFzXG4gICAqIHRoZSBleHBlY3RlZCB2YWx1ZS5cbiAgICpcbiAgICogICAgIGV4cGVjdChbIDEsIDIsIDNdKS50by5oYXZlLmxlbmd0aE9mKDMpO1xuICAgKiAgICAgZXhwZWN0KCdmb29iYXInKS50by5oYXZlLmxlbmd0aE9mKDYpO1xuICAgKlxuICAgKiBAbmFtZSBsZW5ndGhPZlxuICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0TGVuZ3RoQ2hhaW4gKCkge1xuICAgIGZsYWcodGhpcywgJ2RvTGVuZ3RoJywgdHJ1ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBhc3NlcnRMZW5ndGggKG4sIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KCdsZW5ndGgnKTtcbiAgICB2YXIgbGVuID0gb2JqLmxlbmd0aDtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBsZW4gPT0gblxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIGEgbGVuZ3RoIG9mICN7ZXhwfSBidXQgZ290ICN7YWN0fSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGhhdmUgYSBsZW5ndGggb2YgI3thY3R9J1xuICAgICAgLCBuXG4gICAgICAsIGxlblxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdsZW5ndGgnLCBhc3NlcnRMZW5ndGgsIGFzc2VydExlbmd0aENoYWluKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbGVuZ3RoT2YnLCBhc3NlcnRMZW5ndGgpO1xuXG4gIC8qKlxuICAgKiAjIyMgLm1hdGNoKHJlZ2V4cClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgbWF0Y2hlcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbi5cbiAgICpcbiAgICogICAgIGV4cGVjdCgnZm9vYmFyJykudG8ubWF0Y2goL15mb28vKTtcbiAgICpcbiAgICogQG5hbWUgbWF0Y2hcbiAgICogQGFsaWFzIG1hdGNoZXNcbiAgICogQHBhcmFtIHtSZWdFeHB9IFJlZ3VsYXJFeHByZXNzaW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG4gIGZ1bmN0aW9uIGFzc2VydE1hdGNoKHJlLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIHJlLmV4ZWMob2JqKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBtYXRjaCAnICsgcmVcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gbm90IHRvIG1hdGNoICcgKyByZVxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdtYXRjaCcsIGFzc2VydE1hdGNoKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbWF0Y2hlcycsIGFzc2VydE1hdGNoKTtcblxuICAvKipcbiAgICogIyMjIC5zdHJpbmcoc3RyaW5nKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHN0cmluZyB0YXJnZXQgY29udGFpbnMgYW5vdGhlciBzdHJpbmcuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2Zvb2JhcicpLnRvLmhhdmUuc3RyaW5nKCdiYXInKTtcbiAgICpcbiAgICogQG5hbWUgc3RyaW5nXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHJpbmdcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdzdHJpbmcnLCBmdW5jdGlvbiAoc3RyLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgb2JqID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykuaXMuYSgnc3RyaW5nJyk7XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgfm9iai5pbmRleE9mKHN0cilcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gY29udGFpbiAnICsgXy5pbnNwZWN0KHN0cilcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGNvbnRhaW4gJyArIF8uaW5zcGVjdChzdHIpXG4gICAgKTtcbiAgfSk7XG5cblxuICAvKipcbiAgICogIyMjIC5rZXlzKGtleTEsIFtrZXkyXSwgWy4uLl0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGNvbnRhaW5zIGFueSBvciBhbGwgb2YgdGhlIHBhc3NlZC1pbiBrZXlzLlxuICAgKiBVc2UgaW4gY29tYmluYXRpb24gd2l0aCBgYW55YCwgYGFsbGAsIGBjb250YWluc2AsIG9yIGBoYXZlYCB3aWxsIGFmZmVjdFxuICAgKiB3aGF0IHdpbGwgcGFzcy5cbiAgICpcbiAgICogV2hlbiB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggYGFueWAsIGF0IGxlYXN0IG9uZSBrZXkgdGhhdCBpcyBwYXNzZWRcbiAgICogaW4gbXVzdCBleGlzdCBpbiB0aGUgdGFyZ2V0IG9iamVjdC4gVGhpcyBpcyByZWdhcmRsZXNzIHdoZXRoZXIgb3Igbm90XG4gICAqIHRoZSBgaGF2ZWAgb3IgYGNvbnRhaW5gIHF1YWxpZmllcnMgYXJlIHVzZWQuIE5vdGUsIGVpdGhlciBgYW55YCBvciBgYWxsYFxuICAgKiBzaG91bGQgYmUgdXNlZCBpbiB0aGUgYXNzZXJ0aW9uLiBJZiBuZWl0aGVyIGFyZSB1c2VkLCB0aGUgYXNzZXJ0aW9uIGlzXG4gICAqIGRlZmF1bHRlZCB0byBgYWxsYC5cbiAgICpcbiAgICogV2hlbiBib3RoIGBhbGxgIGFuZCBgY29udGFpbmAgYXJlIHVzZWQsIHRoZSB0YXJnZXQgb2JqZWN0IG11c3QgaGF2ZSBhdFxuICAgKiBsZWFzdCBhbGwgb2YgdGhlIHBhc3NlZC1pbiBrZXlzIGJ1dCBtYXkgaGF2ZSBtb3JlIGtleXMgbm90IGxpc3RlZC5cbiAgICpcbiAgICogV2hlbiBib3RoIGBhbGxgIGFuZCBgaGF2ZWAgYXJlIHVzZWQsIHRoZSB0YXJnZXQgb2JqZWN0IG11c3QgYm90aCBjb250YWluXG4gICAqIGFsbCBvZiB0aGUgcGFzc2VkLWluIGtleXMgQU5EIHRoZSBudW1iZXIgb2Yga2V5cyBpbiB0aGUgdGFyZ2V0IG9iamVjdCBtdXN0XG4gICAqIG1hdGNoIHRoZSBudW1iZXIgb2Yga2V5cyBwYXNzZWQgaW4gKGluIG90aGVyIHdvcmRzLCBhIHRhcmdldCBvYmplY3QgbXVzdFxuICAgKiBoYXZlIGFsbCBhbmQgb25seSBhbGwgb2YgdGhlIHBhc3NlZC1pbiBrZXlzKS5cbiAgICpcbiAgICogICAgIGV4cGVjdCh7IGZvbzogMSwgYmFyOiAyIH0pLnRvLmhhdmUuYW55LmtleXMoJ2ZvbycsICdiYXonKTtcbiAgICogICAgIGV4cGVjdCh7IGZvbzogMSwgYmFyOiAyIH0pLnRvLmhhdmUuYW55LmtleXMoJ2ZvbycpO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAxLCBiYXI6IDIgfSkudG8uY29udGFpbi5hbnkua2V5cygnYmFyJywgJ2JheicpO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAxLCBiYXI6IDIgfSkudG8uY29udGFpbi5hbnkua2V5cyhbJ2ZvbyddKTtcbiAgICogICAgIGV4cGVjdCh7IGZvbzogMSwgYmFyOiAyIH0pLnRvLmNvbnRhaW4uYW55LmtleXMoeydmb28nOiA2fSk7XG4gICAqICAgICBleHBlY3QoeyBmb286IDEsIGJhcjogMiB9KS50by5oYXZlLmFsbC5rZXlzKFsnYmFyJywgJ2ZvbyddKTtcbiAgICogICAgIGV4cGVjdCh7IGZvbzogMSwgYmFyOiAyIH0pLnRvLmhhdmUuYWxsLmtleXMoeydiYXInOiA2LCAnZm9vJzogN30pO1xuICAgKiAgICAgZXhwZWN0KHsgZm9vOiAxLCBiYXI6IDIsIGJhejogMyB9KS50by5jb250YWluLmFsbC5rZXlzKFsnYmFyJywgJ2ZvbyddKTtcbiAgICogICAgIGV4cGVjdCh7IGZvbzogMSwgYmFyOiAyLCBiYXo6IDMgfSkudG8uY29udGFpbi5hbGwua2V5cyh7J2Jhcic6IDZ9KTtcbiAgICpcbiAgICpcbiAgICogQG5hbWUga2V5c1xuICAgKiBAYWxpYXMga2V5XG4gICAqIEBwYXJhbSB7Li4uU3RyaW5nfEFycmF5fE9iamVjdH0ga2V5c1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRLZXlzIChrZXlzKSB7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIHN0clxuICAgICAgLCBvayA9IHRydWVcbiAgICAgICwgbWl4ZWRBcmdzTXNnID0gJ2tleXMgbXVzdCBiZSBnaXZlbiBzaW5nbGUgYXJndW1lbnQgb2YgQXJyYXl8T2JqZWN0fFN0cmluZywgb3IgbXVsdGlwbGUgU3RyaW5nIGFyZ3VtZW50cyc7XG5cbiAgICBzd2l0Y2ggKF8udHlwZShrZXlzKSkge1xuICAgICAgY2FzZSBcImFycmF5XCI6XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkgdGhyb3cgKG5ldyBFcnJvcihtaXhlZEFyZ3NNc2cpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkgdGhyb3cgKG5ldyBFcnJvcihtaXhlZEFyZ3NNc2cpKTtcbiAgICAgICAga2V5cyA9IE9iamVjdC5rZXlzKGtleXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGtleXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIGlmICgha2V5cy5sZW5ndGgpIHRocm93IG5ldyBFcnJvcigna2V5cyByZXF1aXJlZCcpO1xuXG4gICAgdmFyIGFjdHVhbCA9IE9iamVjdC5rZXlzKG9iailcbiAgICAgICwgZXhwZWN0ZWQgPSBrZXlzXG4gICAgICAsIGxlbiA9IGtleXMubGVuZ3RoXG4gICAgICAsIGFueSA9IGZsYWcodGhpcywgJ2FueScpXG4gICAgICAsIGFsbCA9IGZsYWcodGhpcywgJ2FsbCcpO1xuXG4gICAgaWYgKCFhbnkgJiYgIWFsbCkge1xuICAgICAgYWxsID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBIYXMgYW55XG4gICAgaWYgKGFueSkge1xuICAgICAgdmFyIGludGVyc2VjdGlvbiA9IGV4cGVjdGVkLmZpbHRlcihmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgcmV0dXJuIH5hY3R1YWwuaW5kZXhPZihrZXkpO1xuICAgICAgfSk7XG4gICAgICBvayA9IGludGVyc2VjdGlvbi5sZW5ndGggPiAwO1xuICAgIH1cblxuICAgIC8vIEhhcyBhbGxcbiAgICBpZiAoYWxsKSB7XG4gICAgICBvayA9IGtleXMuZXZlcnkoZnVuY3Rpb24oa2V5KXtcbiAgICAgICAgcmV0dXJuIH5hY3R1YWwuaW5kZXhPZihrZXkpO1xuICAgICAgfSk7XG4gICAgICBpZiAoIWZsYWcodGhpcywgJ25lZ2F0ZScpICYmICFmbGFnKHRoaXMsICdjb250YWlucycpKSB7XG4gICAgICAgIG9rID0gb2sgJiYga2V5cy5sZW5ndGggPT0gYWN0dWFsLmxlbmd0aDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBLZXkgc3RyaW5nXG4gICAgaWYgKGxlbiA+IDEpIHtcbiAgICAgIGtleXMgPSBrZXlzLm1hcChmdW5jdGlvbihrZXkpe1xuICAgICAgICByZXR1cm4gXy5pbnNwZWN0KGtleSk7XG4gICAgICB9KTtcbiAgICAgIHZhciBsYXN0ID0ga2V5cy5wb3AoKTtcbiAgICAgIGlmIChhbGwpIHtcbiAgICAgICAgc3RyID0ga2V5cy5qb2luKCcsICcpICsgJywgYW5kICcgKyBsYXN0O1xuICAgICAgfVxuICAgICAgaWYgKGFueSkge1xuICAgICAgICBzdHIgPSBrZXlzLmpvaW4oJywgJykgKyAnLCBvciAnICsgbGFzdDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gXy5pbnNwZWN0KGtleXNbMF0pO1xuICAgIH1cblxuICAgIC8vIEZvcm1cbiAgICBzdHIgPSAobGVuID4gMSA/ICdrZXlzICcgOiAna2V5ICcpICsgc3RyO1xuXG4gICAgLy8gSGF2ZSAvIGluY2x1ZGVcbiAgICBzdHIgPSAoZmxhZyh0aGlzLCAnY29udGFpbnMnKSA/ICdjb250YWluICcgOiAnaGF2ZSAnKSArIHN0cjtcblxuICAgIC8vIEFzc2VydGlvblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBva1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byAnICsgc3RyXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCAnICsgc3RyXG4gICAgICAsIGV4cGVjdGVkLnNsaWNlKDApLnNvcnQoKVxuICAgICAgLCBhY3R1YWwuc29ydCgpXG4gICAgICAsIHRydWVcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgna2V5cycsIGFzc2VydEtleXMpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdrZXknLCBhc3NlcnRLZXlzKTtcblxuICAvKipcbiAgICogIyMjIC50aHJvdyhjb25zdHJ1Y3RvcilcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSBmdW5jdGlvbiB0YXJnZXQgd2lsbCB0aHJvdyBhIHNwZWNpZmljIGVycm9yLCBvciBzcGVjaWZpYyB0eXBlIG9mIGVycm9yXG4gICAqIChhcyBkZXRlcm1pbmVkIHVzaW5nIGBpbnN0YW5jZW9mYCksIG9wdGlvbmFsbHkgd2l0aCBhIFJlZ0V4cCBvciBzdHJpbmcgaW5jbHVzaW9uIHRlc3RcbiAgICogZm9yIHRoZSBlcnJvcidzIG1lc3NhZ2UuXG4gICAqXG4gICAqICAgICB2YXIgZXJyID0gbmV3IFJlZmVyZW5jZUVycm9yKCdUaGlzIGlzIGEgYmFkIGZ1bmN0aW9uLicpO1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24gKCkgeyB0aHJvdyBlcnI7IH1cbiAgICogICAgIGV4cGVjdChmbikudG8udGhyb3coUmVmZXJlbmNlRXJyb3IpO1xuICAgKiAgICAgZXhwZWN0KGZuKS50by50aHJvdyhFcnJvcik7XG4gICAqICAgICBleHBlY3QoZm4pLnRvLnRocm93KC9iYWQgZnVuY3Rpb24vKTtcbiAgICogICAgIGV4cGVjdChmbikudG8ubm90LnRocm93KCdnb29kIGZ1bmN0aW9uJyk7XG4gICAqICAgICBleHBlY3QoZm4pLnRvLnRocm93KFJlZmVyZW5jZUVycm9yLCAvYmFkIGZ1bmN0aW9uLyk7XG4gICAqICAgICBleHBlY3QoZm4pLnRvLnRocm93KGVycik7XG4gICAqXG4gICAqIFBsZWFzZSBub3RlIHRoYXQgd2hlbiBhIHRocm93IGV4cGVjdGF0aW9uIGlzIG5lZ2F0ZWQsIGl0IHdpbGwgY2hlY2sgZWFjaFxuICAgKiBwYXJhbWV0ZXIgaW5kZXBlbmRlbnRseSwgc3RhcnRpbmcgd2l0aCBlcnJvciBjb25zdHJ1Y3RvciB0eXBlLiBUaGUgYXBwcm9wcmlhdGUgd2F5XG4gICAqIHRvIGNoZWNrIGZvciB0aGUgZXhpc3RlbmNlIG9mIGEgdHlwZSBvZiBlcnJvciBidXQgZm9yIGEgbWVzc2FnZSB0aGF0IGRvZXMgbm90IG1hdGNoXG4gICAqIGlzIHRvIHVzZSBgYW5kYC5cbiAgICpcbiAgICogICAgIGV4cGVjdChmbikudG8udGhyb3coUmVmZXJlbmNlRXJyb3IpXG4gICAqICAgICAgICAuYW5kLm5vdC50aHJvdygvZ29vZCBmdW5jdGlvbi8pO1xuICAgKlxuICAgKiBAbmFtZSB0aHJvd1xuICAgKiBAYWxpYXMgdGhyb3dzXG4gICAqIEBhbGlhcyBUaHJvd1xuICAgKiBAcGFyYW0ge0Vycm9yQ29uc3RydWN0b3J9IGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXhwZWN0ZWQgZXJyb3IgbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRXJyb3IjRXJyb3JfdHlwZXNcbiAgICogQHJldHVybnMgZXJyb3IgZm9yIGNoYWluaW5nIChudWxsIGlmIG5vIGVycm9yKVxuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBhc3NlcnRUaHJvd3MgKGNvbnN0cnVjdG9yLCBlcnJNc2csIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS5pcy5hKCdmdW5jdGlvbicpO1xuXG4gICAgdmFyIHRocm93biA9IGZhbHNlXG4gICAgICAsIGRlc2lyZWRFcnJvciA9IG51bGxcbiAgICAgICwgbmFtZSA9IG51bGxcbiAgICAgICwgdGhyb3duRXJyb3IgPSBudWxsO1xuXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGVyck1zZyA9IG51bGw7XG4gICAgICBjb25zdHJ1Y3RvciA9IG51bGw7XG4gICAgfSBlbHNlIGlmIChjb25zdHJ1Y3RvciAmJiAoY29uc3RydWN0b3IgaW5zdGFuY2VvZiBSZWdFeHAgfHwgJ3N0cmluZycgPT09IHR5cGVvZiBjb25zdHJ1Y3RvcikpIHtcbiAgICAgIGVyck1zZyA9IGNvbnN0cnVjdG9yO1xuICAgICAgY29uc3RydWN0b3IgPSBudWxsO1xuICAgIH0gZWxzZSBpZiAoY29uc3RydWN0b3IgJiYgY29uc3RydWN0b3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgZGVzaXJlZEVycm9yID0gY29uc3RydWN0b3I7XG4gICAgICBjb25zdHJ1Y3RvciA9IG51bGw7XG4gICAgICBlcnJNc2cgPSBudWxsO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGNvbnN0cnVjdG9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBuYW1lID0gY29uc3RydWN0b3IucHJvdG90eXBlLm5hbWU7XG4gICAgICBpZiAoIW5hbWUgfHwgKG5hbWUgPT09ICdFcnJvcicgJiYgY29uc3RydWN0b3IgIT09IEVycm9yKSkge1xuICAgICAgICBuYW1lID0gY29uc3RydWN0b3IubmFtZSB8fCAobmV3IGNvbnN0cnVjdG9yKCkpLm5hbWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0cnVjdG9yID0gbnVsbDtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgb2JqKCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBmaXJzdCwgY2hlY2sgZGVzaXJlZCBlcnJvclxuICAgICAgaWYgKGRlc2lyZWRFcnJvcikge1xuICAgICAgICB0aGlzLmFzc2VydChcbiAgICAgICAgICAgIGVyciA9PT0gZGVzaXJlZEVycm9yXG4gICAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byB0aHJvdyAje2V4cH0gYnV0ICN7YWN0fSB3YXMgdGhyb3duJ1xuICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IHRocm93ICN7ZXhwfSdcbiAgICAgICAgICAsIChkZXNpcmVkRXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGRlc2lyZWRFcnJvci50b1N0cmluZygpIDogZGVzaXJlZEVycm9yKVxuICAgICAgICAgICwgKGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLnRvU3RyaW5nKCkgOiBlcnIpXG4gICAgICAgICk7XG5cbiAgICAgICAgZmxhZyh0aGlzLCAnb2JqZWN0JywgZXJyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIG5leHQsIGNoZWNrIGNvbnN0cnVjdG9yXG4gICAgICBpZiAoY29uc3RydWN0b3IpIHtcbiAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICBlcnIgaW5zdGFuY2VvZiBjb25zdHJ1Y3RvclxuICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gdGhyb3cgI3tleHB9IGJ1dCAje2FjdH0gd2FzIHRocm93bidcbiAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCB0aHJvdyAje2V4cH0gYnV0ICN7YWN0fSB3YXMgdGhyb3duJ1xuICAgICAgICAgICwgbmFtZVxuICAgICAgICAgICwgKGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLnRvU3RyaW5nKCkgOiBlcnIpXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKCFlcnJNc2cpIHtcbiAgICAgICAgICBmbGFnKHRoaXMsICdvYmplY3QnLCBlcnIpO1xuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIG5leHQsIGNoZWNrIG1lc3NhZ2VcbiAgICAgIHZhciBtZXNzYWdlID0gJ2Vycm9yJyA9PT0gXy50eXBlKGVycikgJiYgXCJtZXNzYWdlXCIgaW4gZXJyXG4gICAgICAgID8gZXJyLm1lc3NhZ2VcbiAgICAgICAgOiAnJyArIGVycjtcblxuICAgICAgaWYgKChtZXNzYWdlICE9IG51bGwpICYmIGVyck1zZyAmJiBlcnJNc2cgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICBlcnJNc2cuZXhlYyhtZXNzYWdlKVxuICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gdGhyb3cgZXJyb3IgbWF0Y2hpbmcgI3tleHB9IGJ1dCBnb3QgI3thY3R9J1xuICAgICAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gdGhyb3cgZXJyb3Igbm90IG1hdGNoaW5nICN7ZXhwfSdcbiAgICAgICAgICAsIGVyck1zZ1xuICAgICAgICAgICwgbWVzc2FnZVxuICAgICAgICApO1xuXG4gICAgICAgIGZsYWcodGhpcywgJ29iamVjdCcsIGVycik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfSBlbHNlIGlmICgobWVzc2FnZSAhPSBudWxsKSAmJiBlcnJNc2cgJiYgJ3N0cmluZycgPT09IHR5cGVvZiBlcnJNc2cpIHtcbiAgICAgICAgdGhpcy5hc3NlcnQoXG4gICAgICAgICAgICB+bWVzc2FnZS5pbmRleE9mKGVyck1zZylcbiAgICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIHRocm93IGVycm9yIGluY2x1ZGluZyAje2V4cH0gYnV0IGdvdCAje2FjdH0nXG4gICAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byB0aHJvdyBlcnJvciBub3QgaW5jbHVkaW5nICN7YWN0fSdcbiAgICAgICAgICAsIGVyck1zZ1xuICAgICAgICAgICwgbWVzc2FnZVxuICAgICAgICApO1xuXG4gICAgICAgIGZsYWcodGhpcywgJ29iamVjdCcsIGVycik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3duID0gdHJ1ZTtcbiAgICAgICAgdGhyb3duRXJyb3IgPSBlcnI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGFjdHVhbGx5R290ID0gJydcbiAgICAgICwgZXhwZWN0ZWRUaHJvd24gPSBuYW1lICE9PSBudWxsXG4gICAgICAgID8gbmFtZVxuICAgICAgICA6IGRlc2lyZWRFcnJvclxuICAgICAgICAgID8gJyN7ZXhwfScgLy9fLmluc3BlY3QoZGVzaXJlZEVycm9yKVxuICAgICAgICAgIDogJ2FuIGVycm9yJztcblxuICAgIGlmICh0aHJvd24pIHtcbiAgICAgIGFjdHVhbGx5R290ID0gJyBidXQgI3thY3R9IHdhcyB0aHJvd24nXG4gICAgfVxuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIHRocm93biA9PT0gdHJ1ZVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byB0aHJvdyAnICsgZXhwZWN0ZWRUaHJvd24gKyBhY3R1YWxseUdvdFxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgdGhyb3cgJyArIGV4cGVjdGVkVGhyb3duICsgYWN0dWFsbHlHb3RcbiAgICAgICwgKGRlc2lyZWRFcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZGVzaXJlZEVycm9yLnRvU3RyaW5nKCkgOiBkZXNpcmVkRXJyb3IpXG4gICAgICAsICh0aHJvd25FcnJvciBpbnN0YW5jZW9mIEVycm9yID8gdGhyb3duRXJyb3IudG9TdHJpbmcoKSA6IHRocm93bkVycm9yKVxuICAgICk7XG5cbiAgICBmbGFnKHRoaXMsICdvYmplY3QnLCB0aHJvd25FcnJvcik7XG4gIH07XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgndGhyb3cnLCBhc3NlcnRUaHJvd3MpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCd0aHJvd3MnLCBhc3NlcnRUaHJvd3MpO1xuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdUaHJvdycsIGFzc2VydFRocm93cyk7XG5cbiAgLyoqXG4gICAqICMjIyAucmVzcG9uZFRvKG1ldGhvZClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSBvYmplY3Qgb3IgY2xhc3MgdGFyZ2V0IHdpbGwgcmVzcG9uZCB0byBhIG1ldGhvZC5cbiAgICpcbiAgICogICAgIEtsYXNzLnByb3RvdHlwZS5iYXIgPSBmdW5jdGlvbigpe307XG4gICAqICAgICBleHBlY3QoS2xhc3MpLnRvLnJlc3BvbmRUbygnYmFyJyk7XG4gICAqICAgICBleHBlY3Qob2JqKS50by5yZXNwb25kVG8oJ2JhcicpO1xuICAgKlxuICAgKiBUbyBjaGVjayBpZiBhIGNvbnN0cnVjdG9yIHdpbGwgcmVzcG9uZCB0byBhIHN0YXRpYyBmdW5jdGlvbixcbiAgICogc2V0IHRoZSBgaXRzZWxmYCBmbGFnLlxuICAgKlxuICAgKiAgICAgS2xhc3MuYmF6ID0gZnVuY3Rpb24oKXt9O1xuICAgKiAgICAgZXhwZWN0KEtsYXNzKS5pdHNlbGYudG8ucmVzcG9uZFRvKCdiYXonKTtcbiAgICpcbiAgICogQG5hbWUgcmVzcG9uZFRvXG4gICAqIEBhbGlhcyByZXNwb25kc1RvXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiByZXNwb25kVG8gKG1ldGhvZCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpXG4gICAgICAsIGl0c2VsZiA9IGZsYWcodGhpcywgJ2l0c2VsZicpXG4gICAgICAsIGNvbnRleHQgPSAoJ2Z1bmN0aW9uJyA9PT0gXy50eXBlKG9iaikgJiYgIWl0c2VsZilcbiAgICAgICAgPyBvYmoucHJvdG90eXBlW21ldGhvZF1cbiAgICAgICAgOiBvYmpbbWV0aG9kXTtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICAnZnVuY3Rpb24nID09PSB0eXBlb2YgY29udGV4dFxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byByZXNwb25kIHRvICcgKyBfLmluc3BlY3QobWV0aG9kKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgcmVzcG9uZCB0byAnICsgXy5pbnNwZWN0KG1ldGhvZClcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgncmVzcG9uZFRvJywgcmVzcG9uZFRvKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgncmVzcG9uZHNUbycsIHJlc3BvbmRUbyk7XG5cbiAgLyoqXG4gICAqICMjIyAuaXRzZWxmXG4gICAqXG4gICAqIFNldHMgdGhlIGBpdHNlbGZgIGZsYWcsIGxhdGVyIHVzZWQgYnkgdGhlIGByZXNwb25kVG9gIGFzc2VydGlvbi5cbiAgICpcbiAgICogICAgIGZ1bmN0aW9uIEZvbygpIHt9XG4gICAqICAgICBGb28uYmFyID0gZnVuY3Rpb24oKSB7fVxuICAgKiAgICAgRm9vLnByb3RvdHlwZS5iYXogPSBmdW5jdGlvbigpIHt9XG4gICAqXG4gICAqICAgICBleHBlY3QoRm9vKS5pdHNlbGYudG8ucmVzcG9uZFRvKCdiYXInKTtcbiAgICogICAgIGV4cGVjdChGb28pLml0c2VsZi5ub3QudG8ucmVzcG9uZFRvKCdiYXonKTtcbiAgICpcbiAgICogQG5hbWUgaXRzZWxmXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnaXRzZWxmJywgZnVuY3Rpb24gKCkge1xuICAgIGZsYWcodGhpcywgJ2l0c2VsZicsIHRydWUpO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5zYXRpc2Z5KG1ldGhvZClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgcGFzc2VzIGEgZ2l2ZW4gdHJ1dGggdGVzdC5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxKS50by5zYXRpc2Z5KGZ1bmN0aW9uKG51bSkgeyByZXR1cm4gbnVtID4gMDsgfSk7XG4gICAqXG4gICAqIEBuYW1lIHNhdGlzZnlcbiAgICogQGFsaWFzIHNhdGlzZmllc1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtYXRjaGVyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gc2F0aXNmeSAobWF0Y2hlciwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIHZhciByZXN1bHQgPSBtYXRjaGVyKG9iaik7XG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICAgIHJlc3VsdFxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBzYXRpc2Z5ICcgKyBfLm9iakRpc3BsYXkobWF0Y2hlcilcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IHNhdGlzZnknICsgXy5vYmpEaXNwbGF5KG1hdGNoZXIpXG4gICAgICAsIHRoaXMubmVnYXRlID8gZmFsc2UgOiB0cnVlXG4gICAgICAsIHJlc3VsdFxuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkTWV0aG9kKCdzYXRpc2Z5Jywgc2F0aXNmeSk7XG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ3NhdGlzZmllcycsIHNhdGlzZnkpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmNsb3NlVG8oZXhwZWN0ZWQsIGRlbHRhKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCBgZXhwZWN0ZWRgLCB0byB3aXRoaW4gYSArLy0gYGRlbHRhYCByYW5nZS5cbiAgICpcbiAgICogICAgIGV4cGVjdCgxLjUpLnRvLmJlLmNsb3NlVG8oMSwgMC41KTtcbiAgICpcbiAgICogQG5hbWUgY2xvc2VUb1xuICAgKiBAYWxpYXMgYXBwcm94aW1hdGVseVxuICAgKiBAcGFyYW0ge051bWJlcn0gZXhwZWN0ZWRcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGRlbHRhXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gY2xvc2VUbyhleHBlY3RlZCwgZGVsdGEsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcblxuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLmlzLmEoJ251bWJlcicpO1xuICAgIGlmIChfLnR5cGUoZXhwZWN0ZWQpICE9PSAnbnVtYmVyJyB8fCBfLnR5cGUoZGVsdGEpICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgYXJndW1lbnRzIHRvIGNsb3NlVG8gb3IgYXBwcm94aW1hdGVseSBtdXN0IGJlIG51bWJlcnMnKTtcbiAgICB9XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgICAgTWF0aC5hYnMob2JqIC0gZXhwZWN0ZWQpIDw9IGRlbHRhXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGNsb3NlIHRvICcgKyBleHBlY3RlZCArICcgKy8tICcgKyBkZWx0YVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSBub3QgdG8gYmUgY2xvc2UgdG8gJyArIGV4cGVjdGVkICsgJyArLy0gJyArIGRlbHRhXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRNZXRob2QoJ2Nsb3NlVG8nLCBjbG9zZVRvKTtcbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnYXBwcm94aW1hdGVseScsIGNsb3NlVG8pO1xuXG4gIGZ1bmN0aW9uIGlzU3Vic2V0T2Yoc3Vic2V0LCBzdXBlcnNldCwgY21wKSB7XG4gICAgcmV0dXJuIHN1YnNldC5ldmVyeShmdW5jdGlvbihlbGVtKSB7XG4gICAgICBpZiAoIWNtcCkgcmV0dXJuIHN1cGVyc2V0LmluZGV4T2YoZWxlbSkgIT09IC0xO1xuXG4gICAgICByZXR1cm4gc3VwZXJzZXQuc29tZShmdW5jdGlvbihlbGVtMikge1xuICAgICAgICByZXR1cm4gY21wKGVsZW0sIGVsZW0yKTtcbiAgICAgIH0pO1xuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogIyMjIC5tZW1iZXJzKHNldClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgYSBzdXBlcnNldCBvZiBgc2V0YCxcbiAgICogb3IgdGhhdCB0aGUgdGFyZ2V0IGFuZCBgc2V0YCBoYXZlIHRoZSBzYW1lIHN0cmljdGx5LWVxdWFsICg9PT0pIG1lbWJlcnMuXG4gICAqIEFsdGVybmF0ZWx5LCBpZiB0aGUgYGRlZXBgIGZsYWcgaXMgc2V0LCBzZXQgbWVtYmVycyBhcmUgY29tcGFyZWQgZm9yIGRlZXBcbiAgICogZXF1YWxpdHkuXG4gICAqXG4gICAqICAgICBleHBlY3QoWzEsIDIsIDNdKS50by5pbmNsdWRlLm1lbWJlcnMoWzMsIDJdKTtcbiAgICogICAgIGV4cGVjdChbMSwgMiwgM10pLnRvLm5vdC5pbmNsdWRlLm1lbWJlcnMoWzMsIDIsIDhdKTtcbiAgICpcbiAgICogICAgIGV4cGVjdChbNCwgMl0pLnRvLmhhdmUubWVtYmVycyhbMiwgNF0pO1xuICAgKiAgICAgZXhwZWN0KFs1LCAyXSkudG8ubm90LmhhdmUubWVtYmVycyhbNSwgMiwgMV0pO1xuICAgKlxuICAgKiAgICAgZXhwZWN0KFt7IGlkOiAxIH1dKS50by5kZWVwLmluY2x1ZGUubWVtYmVycyhbeyBpZDogMSB9XSk7XG4gICAqXG4gICAqIEBuYW1lIG1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnbWVtYmVycycsIGZ1bmN0aW9uIChzdWJzZXQsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcblxuICAgIG5ldyBBc3NlcnRpb24ob2JqKS50by5iZS5hbignYXJyYXknKTtcbiAgICBuZXcgQXNzZXJ0aW9uKHN1YnNldCkudG8uYmUuYW4oJ2FycmF5Jyk7XG5cbiAgICB2YXIgY21wID0gZmxhZyh0aGlzLCAnZGVlcCcpID8gXy5lcWwgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAoZmxhZyh0aGlzLCAnY29udGFpbnMnKSkge1xuICAgICAgcmV0dXJuIHRoaXMuYXNzZXJ0KFxuICAgICAgICAgIGlzU3Vic2V0T2Yoc3Vic2V0LCBvYmosIGNtcClcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBhIHN1cGVyc2V0IG9mICN7YWN0fSdcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgYSBzdXBlcnNldCBvZiAje2FjdH0nXG4gICAgICAgICwgb2JqXG4gICAgICAgICwgc3Vic2V0XG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBpc1N1YnNldE9mKG9iaiwgc3Vic2V0LCBjbXApICYmIGlzU3Vic2V0T2Yoc3Vic2V0LCBvYmosIGNtcClcbiAgICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBoYXZlIHRoZSBzYW1lIG1lbWJlcnMgYXMgI3thY3R9J1xuICAgICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBoYXZlIHRoZSBzYW1lIG1lbWJlcnMgYXMgI3thY3R9J1xuICAgICAgICAsIG9ialxuICAgICAgICAsIHN1YnNldFxuICAgICk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAjIyMgLm9uZU9mKGxpc3QpXG4gICAqXG4gICAqIEFzc2VydCB0aGF0IGEgdmFsdWUgYXBwZWFycyBzb21ld2hlcmUgaW4gdGhlIHRvcCBsZXZlbCBvZiBhcnJheSBgbGlzdGAuXG4gICAqXG4gICAqICAgICBleHBlY3QoJ2EnKS50by5iZS5vbmVPZihbJ2EnLCAnYicsICdjJ10pO1xuICAgKiAgICAgZXhwZWN0KDkpLnRvLm5vdC5iZS5vbmVPZihbJ3onXSk7XG4gICAqICAgICBleHBlY3QoWzNdKS50by5ub3QuYmUub25lT2YoWzEsIDIsIFszXV0pO1xuICAgKlxuICAgKiAgICAgdmFyIHRocmVlID0gWzNdO1xuICAgKiAgICAgLy8gZm9yIG9iamVjdC10eXBlcywgY29udGVudHMgYXJlIG5vdCBjb21wYXJlZFxuICAgKiAgICAgZXhwZWN0KHRocmVlKS50by5ub3QuYmUub25lT2YoWzEsIDIsIFszXV0pO1xuICAgKiAgICAgLy8gY29tcGFyaW5nIHJlZmVyZW5jZXMgd29ya3NcbiAgICogICAgIGV4cGVjdCh0aHJlZSkudG8uYmUub25lT2YoWzEsIDIsIHRocmVlXSk7XG4gICAqXG4gICAqIEBuYW1lIG9uZU9mXG4gICAqIEBwYXJhbSB7QXJyYXk8Kj59IGxpc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEJERFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBmdW5jdGlvbiBvbmVPZiAobGlzdCwgbXNnKSB7XG4gICAgaWYgKG1zZykgZmxhZyh0aGlzLCAnbWVzc2FnZScsIG1zZyk7XG4gICAgdmFyIGV4cGVjdGVkID0gZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gICAgbmV3IEFzc2VydGlvbihsaXN0KS50by5iZS5hbignYXJyYXknKTtcblxuICAgIHRoaXMuYXNzZXJ0KFxuICAgICAgICBsaXN0LmluZGV4T2YoZXhwZWN0ZWQpID4gLTFcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gYmUgb25lIG9mICN7ZXhwfSdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIG9uZSBvZiAje2V4cH0nXG4gICAgICAsIGxpc3RcbiAgICAgICwgZXhwZWN0ZWRcbiAgICApO1xuICB9XG5cbiAgQXNzZXJ0aW9uLmFkZE1ldGhvZCgnb25lT2YnLCBvbmVPZik7XG5cblxuICAvKipcbiAgICogIyMjIC5jaGFuZ2UoZnVuY3Rpb24pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGNoYW5nZXMgYW4gb2JqZWN0IHByb3BlcnR5XG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCArPSAzIH07XG4gICAqICAgICB2YXIgbm9DaGFuZ2VGbiA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gJ2ZvbycgKyAnYmFyJzsgfVxuICAgKiAgICAgZXhwZWN0KGZuKS50by5jaGFuZ2Uob2JqLCAndmFsJyk7XG4gICAqICAgICBleHBlY3Qobm9DaGFuZ2VGbikudG8ubm90LmNoYW5nZShvYmosICd2YWwnKVxuICAgKlxuICAgKiBAbmFtZSBjaGFuZ2VcbiAgICogQGFsaWFzIGNoYW5nZXNcbiAgICogQGFsaWFzIENoYW5nZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0Q2hhbmdlcyAob2JqZWN0LCBwcm9wLCBtc2cpIHtcbiAgICBpZiAobXNnKSBmbGFnKHRoaXMsICdtZXNzYWdlJywgbXNnKTtcbiAgICB2YXIgZm4gPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iamVjdCwgbXNnKS50by5oYXZlLnByb3BlcnR5KHByb3ApO1xuICAgIG5ldyBBc3NlcnRpb24oZm4pLmlzLmEoJ2Z1bmN0aW9uJyk7XG5cbiAgICB2YXIgaW5pdGlhbCA9IG9iamVjdFtwcm9wXTtcbiAgICBmbigpO1xuXG4gICAgdGhpcy5hc3NlcnQoXG4gICAgICBpbml0aWFsICE9PSBvYmplY3RbcHJvcF1cbiAgICAgICwgJ2V4cGVjdGVkIC4nICsgcHJvcCArICcgdG8gY2hhbmdlJ1xuICAgICAgLCAnZXhwZWN0ZWQgLicgKyBwcm9wICsgJyB0byBub3QgY2hhbmdlJ1xuICAgICk7XG4gIH1cblxuICBBc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdjaGFuZ2UnLCBhc3NlcnRDaGFuZ2VzKTtcbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnY2hhbmdlcycsIGFzc2VydENoYW5nZXMpO1xuXG4gIC8qKlxuICAgKiAjIyMgLmluY3JlYXNlKGZ1bmN0aW9uKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYSBmdW5jdGlvbiBpbmNyZWFzZXMgYW4gb2JqZWN0IHByb3BlcnR5XG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCA9IDE1IH07XG4gICAqICAgICBleHBlY3QoZm4pLnRvLmluY3JlYXNlKG9iaiwgJ3ZhbCcpO1xuICAgKlxuICAgKiBAbmFtZSBpbmNyZWFzZVxuICAgKiBAYWxpYXMgaW5jcmVhc2VzXG4gICAqIEBhbGlhcyBJbmNyZWFzZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0SW5jcmVhc2VzIChvYmplY3QsIHByb3AsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBmbiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIG5ldyBBc3NlcnRpb24ob2JqZWN0LCBtc2cpLnRvLmhhdmUucHJvcGVydHkocHJvcCk7XG4gICAgbmV3IEFzc2VydGlvbihmbikuaXMuYSgnZnVuY3Rpb24nKTtcblxuICAgIHZhciBpbml0aWFsID0gb2JqZWN0W3Byb3BdO1xuICAgIGZuKCk7XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgIG9iamVjdFtwcm9wXSAtIGluaXRpYWwgPiAwXG4gICAgICAsICdleHBlY3RlZCAuJyArIHByb3AgKyAnIHRvIGluY3JlYXNlJ1xuICAgICAgLCAnZXhwZWN0ZWQgLicgKyBwcm9wICsgJyB0byBub3QgaW5jcmVhc2UnXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2luY3JlYXNlJywgYXNzZXJ0SW5jcmVhc2VzKTtcbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnaW5jcmVhc2VzJywgYXNzZXJ0SW5jcmVhc2VzKTtcblxuICAvKipcbiAgICogIyMjIC5kZWNyZWFzZShmdW5jdGlvbilcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gZGVjcmVhc2VzIGFuIG9iamVjdCBwcm9wZXJ0eVxuICAgKlxuICAgKiAgICAgdmFyIG9iaiA9IHsgdmFsOiAxMCB9O1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7IG9iai52YWwgPSA1IH07XG4gICAqICAgICBleHBlY3QoZm4pLnRvLmRlY3JlYXNlKG9iaiwgJ3ZhbCcpO1xuICAgKlxuICAgKiBAbmFtZSBkZWNyZWFzZVxuICAgKiBAYWxpYXMgZGVjcmVhc2VzXG4gICAqIEBhbGlhcyBEZWNyZWFzZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBCRERcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgZnVuY3Rpb24gYXNzZXJ0RGVjcmVhc2VzIChvYmplY3QsIHByb3AsIG1zZykge1xuICAgIGlmIChtc2cpIGZsYWcodGhpcywgJ21lc3NhZ2UnLCBtc2cpO1xuICAgIHZhciBmbiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuICAgIG5ldyBBc3NlcnRpb24ob2JqZWN0LCBtc2cpLnRvLmhhdmUucHJvcGVydHkocHJvcCk7XG4gICAgbmV3IEFzc2VydGlvbihmbikuaXMuYSgnZnVuY3Rpb24nKTtcblxuICAgIHZhciBpbml0aWFsID0gb2JqZWN0W3Byb3BdO1xuICAgIGZuKCk7XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgIG9iamVjdFtwcm9wXSAtIGluaXRpYWwgPCAwXG4gICAgICAsICdleHBlY3RlZCAuJyArIHByb3AgKyAnIHRvIGRlY3JlYXNlJ1xuICAgICAgLCAnZXhwZWN0ZWQgLicgKyBwcm9wICsgJyB0byBub3QgZGVjcmVhc2UnXG4gICAgKTtcbiAgfVxuXG4gIEFzc2VydGlvbi5hZGRDaGFpbmFibGVNZXRob2QoJ2RlY3JlYXNlJywgYXNzZXJ0RGVjcmVhc2VzKTtcbiAgQXNzZXJ0aW9uLmFkZENoYWluYWJsZU1ldGhvZCgnZGVjcmVhc2VzJywgYXNzZXJ0RGVjcmVhc2VzKTtcblxuICAvKipcbiAgICogIyMjIC5leHRlbnNpYmxlXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGV4dGVuc2libGUgKGNhbiBoYXZlIG5ldyBwcm9wZXJ0aWVzIGFkZGVkIHRvXG4gICAqIGl0KS5cbiAgICpcbiAgICogICAgIHZhciBub25FeHRlbnNpYmxlT2JqZWN0ID0gT2JqZWN0LnByZXZlbnRFeHRlbnNpb25zKHt9KTtcbiAgICogICAgIHZhciBzZWFsZWRPYmplY3QgPSBPYmplY3Quc2VhbCh7fSk7XG4gICAqICAgICB2YXIgZnJvemVuT2JqZWN0ID0gT2JqZWN0LmZyZWV6ZSh7fSk7XG4gICAqXG4gICAqICAgICBleHBlY3Qoe30pLnRvLmJlLmV4dGVuc2libGU7XG4gICAqICAgICBleHBlY3Qobm9uRXh0ZW5zaWJsZU9iamVjdCkudG8ubm90LmJlLmV4dGVuc2libGU7XG4gICAqICAgICBleHBlY3Qoc2VhbGVkT2JqZWN0KS50by5ub3QuYmUuZXh0ZW5zaWJsZTtcbiAgICogICAgIGV4cGVjdChmcm96ZW5PYmplY3QpLnRvLm5vdC5iZS5leHRlbnNpYmxlO1xuICAgKlxuICAgKiBAbmFtZSBleHRlbnNpYmxlXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZXh0ZW5zaWJsZScsIGZ1bmN0aW9uKCkge1xuICAgIHZhciBvYmogPSBmbGFnKHRoaXMsICdvYmplY3QnKTtcblxuICAgIC8vIEluIEVTNSwgaWYgdGhlIGFyZ3VtZW50IHRvIHRoaXMgbWV0aG9kIGlzIG5vdCBhbiBvYmplY3QgKGEgcHJpbWl0aXZlKSwgdGhlbiBpdCB3aWxsIGNhdXNlIGEgVHlwZUVycm9yLlxuICAgIC8vIEluIEVTNiwgYSBub24tb2JqZWN0IGFyZ3VtZW50IHdpbGwgYmUgdHJlYXRlZCBhcyBpZiBpdCB3YXMgYSBub24tZXh0ZW5zaWJsZSBvcmRpbmFyeSBvYmplY3QsIHNpbXBseSByZXR1cm4gZmFsc2UuXG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L2lzRXh0ZW5zaWJsZVxuICAgIC8vIFRoZSBmb2xsb3dpbmcgcHJvdmlkZXMgRVM2IGJlaGF2aW9yIHdoZW4gYSBUeXBlRXJyb3IgaXMgdGhyb3duIHVuZGVyIEVTNS5cblxuICAgIHZhciBpc0V4dGVuc2libGU7XG5cbiAgICB0cnkge1xuICAgICAgaXNFeHRlbnNpYmxlID0gT2JqZWN0LmlzRXh0ZW5zaWJsZShvYmopO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIFR5cGVFcnJvcikgaXNFeHRlbnNpYmxlID0gZmFsc2U7XG4gICAgICBlbHNlIHRocm93IGVycjtcbiAgICB9XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgIGlzRXh0ZW5zaWJsZVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBiZSBleHRlbnNpYmxlJ1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgYmUgZXh0ZW5zaWJsZSdcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5zZWFsZWRcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgc2VhbGVkIChjYW5ub3QgaGF2ZSBuZXcgcHJvcGVydGllcyBhZGRlZCB0byBpdFxuICAgKiBhbmQgaXRzIGV4aXN0aW5nIHByb3BlcnRpZXMgY2Fubm90IGJlIHJlbW92ZWQpLlxuICAgKlxuICAgKiAgICAgdmFyIHNlYWxlZE9iamVjdCA9IE9iamVjdC5zZWFsKHt9KTtcbiAgICogICAgIHZhciBmcm96ZW5PYmplY3QgPSBPYmplY3QuZnJlZXplKHt9KTtcbiAgICpcbiAgICogICAgIGV4cGVjdChzZWFsZWRPYmplY3QpLnRvLmJlLnNlYWxlZDtcbiAgICogICAgIGV4cGVjdChmcm96ZW5PYmplY3QpLnRvLmJlLnNlYWxlZDtcbiAgICogICAgIGV4cGVjdCh7fSkudG8ubm90LmJlLnNlYWxlZDtcbiAgICpcbiAgICogQG5hbWUgc2VhbGVkXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnc2VhbGVkJywgZnVuY3Rpb24oKSB7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuXG4gICAgLy8gSW4gRVM1LCBpZiB0aGUgYXJndW1lbnQgdG8gdGhpcyBtZXRob2QgaXMgbm90IGFuIG9iamVjdCAoYSBwcmltaXRpdmUpLCB0aGVuIGl0IHdpbGwgY2F1c2UgYSBUeXBlRXJyb3IuXG4gICAgLy8gSW4gRVM2LCBhIG5vbi1vYmplY3QgYXJndW1lbnQgd2lsbCBiZSB0cmVhdGVkIGFzIGlmIGl0IHdhcyBhIHNlYWxlZCBvcmRpbmFyeSBvYmplY3QsIHNpbXBseSByZXR1cm4gdHJ1ZS5cbiAgICAvLyBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L2lzU2VhbGVkXG4gICAgLy8gVGhlIGZvbGxvd2luZyBwcm92aWRlcyBFUzYgYmVoYXZpb3Igd2hlbiBhIFR5cGVFcnJvciBpcyB0aHJvd24gdW5kZXIgRVM1LlxuXG4gICAgdmFyIGlzU2VhbGVkO1xuXG4gICAgdHJ5IHtcbiAgICAgIGlzU2VhbGVkID0gT2JqZWN0LmlzU2VhbGVkKG9iaik7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoZXJyIGluc3RhbmNlb2YgVHlwZUVycm9yKSBpc1NlYWxlZCA9IHRydWU7XG4gICAgICBlbHNlIHRocm93IGVycjtcbiAgICB9XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgIGlzU2VhbGVkXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIHNlYWxlZCdcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIHNlYWxlZCdcbiAgICApO1xuICB9KTtcblxuICAvKipcbiAgICogIyMjIC5mcm96ZW5cbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgZnJvemVuIChjYW5ub3QgaGF2ZSBuZXcgcHJvcGVydGllcyBhZGRlZCB0byBpdFxuICAgKiBhbmQgaXRzIGV4aXN0aW5nIHByb3BlcnRpZXMgY2Fubm90IGJlIG1vZGlmaWVkKS5cbiAgICpcbiAgICogICAgIHZhciBmcm96ZW5PYmplY3QgPSBPYmplY3QuZnJlZXplKHt9KTtcbiAgICpcbiAgICogICAgIGV4cGVjdChmcm96ZW5PYmplY3QpLnRvLmJlLmZyb3plbjtcbiAgICogICAgIGV4cGVjdCh7fSkudG8ubm90LmJlLmZyb3plbjtcbiAgICpcbiAgICogQG5hbWUgZnJvemVuXG4gICAqIEBuYW1lc3BhY2UgQkREXG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIEFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZnJvemVuJywgZnVuY3Rpb24oKSB7XG4gICAgdmFyIG9iaiA9IGZsYWcodGhpcywgJ29iamVjdCcpO1xuXG4gICAgLy8gSW4gRVM1LCBpZiB0aGUgYXJndW1lbnQgdG8gdGhpcyBtZXRob2QgaXMgbm90IGFuIG9iamVjdCAoYSBwcmltaXRpdmUpLCB0aGVuIGl0IHdpbGwgY2F1c2UgYSBUeXBlRXJyb3IuXG4gICAgLy8gSW4gRVM2LCBhIG5vbi1vYmplY3QgYXJndW1lbnQgd2lsbCBiZSB0cmVhdGVkIGFzIGlmIGl0IHdhcyBhIGZyb3plbiBvcmRpbmFyeSBvYmplY3QsIHNpbXBseSByZXR1cm4gdHJ1ZS5cbiAgICAvLyBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L2lzRnJvemVuXG4gICAgLy8gVGhlIGZvbGxvd2luZyBwcm92aWRlcyBFUzYgYmVoYXZpb3Igd2hlbiBhIFR5cGVFcnJvciBpcyB0aHJvd24gdW5kZXIgRVM1LlxuXG4gICAgdmFyIGlzRnJvemVuO1xuXG4gICAgdHJ5IHtcbiAgICAgIGlzRnJvemVuID0gT2JqZWN0LmlzRnJvemVuKG9iaik7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoZXJyIGluc3RhbmNlb2YgVHlwZUVycm9yKSBpc0Zyb3plbiA9IHRydWU7XG4gICAgICBlbHNlIHRocm93IGVycjtcbiAgICB9XG5cbiAgICB0aGlzLmFzc2VydChcbiAgICAgIGlzRnJvemVuXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIGJlIGZyb3plbidcbiAgICAgICwgJ2V4cGVjdGVkICN7dGhpc30gdG8gbm90IGJlIGZyb3plbidcbiAgICApO1xuICB9KTtcbn07XG4iLCIvKiFcbiAqIGNoYWlcbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGNoYWksIHV0aWwpIHtcblxuICAvKiFcbiAgICogQ2hhaSBkZXBlbmRlbmNpZXMuXG4gICAqL1xuXG4gIHZhciBBc3NlcnRpb24gPSBjaGFpLkFzc2VydGlvblxuICAgICwgZmxhZyA9IHV0aWwuZmxhZztcblxuICAvKiFcbiAgICogTW9kdWxlIGV4cG9ydC5cbiAgICovXG5cbiAgLyoqXG4gICAqICMjIyBhc3NlcnQoZXhwcmVzc2lvbiwgbWVzc2FnZSlcbiAgICpcbiAgICogV3JpdGUgeW91ciBvd24gdGVzdCBleHByZXNzaW9ucy5cbiAgICpcbiAgICogICAgIGFzc2VydCgnZm9vJyAhPT0gJ2JhcicsICdmb28gaXMgbm90IGJhcicpO1xuICAgKiAgICAgYXNzZXJ0KEFycmF5LmlzQXJyYXkoW10pLCAnZW1wdHkgYXJyYXlzIGFyZSBhcnJheXMnKTtcbiAgICpcbiAgICogQHBhcmFtIHtNaXhlZH0gZXhwcmVzc2lvbiB0byB0ZXN0IGZvciB0cnV0aGluZXNzXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIHRvIGRpc3BsYXkgb24gZXJyb3JcbiAgICogQG5hbWUgYXNzZXJ0XG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIHZhciBhc3NlcnQgPSBjaGFpLmFzc2VydCA9IGZ1bmN0aW9uIChleHByZXNzLCBlcnJtc2cpIHtcbiAgICB2YXIgdGVzdCA9IG5ldyBBc3NlcnRpb24obnVsbCwgbnVsbCwgY2hhaS5hc3NlcnQpO1xuICAgIHRlc3QuYXNzZXJ0KFxuICAgICAgICBleHByZXNzXG4gICAgICAsIGVycm1zZ1xuICAgICAgLCAnWyBuZWdhdGlvbiBtZXNzYWdlIHVuYXZhaWxhYmxlIF0nXG4gICAgKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5mYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSwgW29wZXJhdG9yXSlcbiAgICpcbiAgICogVGhyb3cgYSBmYWlsdXJlLiBOb2RlLmpzIGBhc3NlcnRgIG1vZHVsZS1jb21wYXRpYmxlLlxuICAgKlxuICAgKiBAbmFtZSBmYWlsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gb3BlcmF0b3JcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmZhaWwgPSBmdW5jdGlvbiAoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgb3BlcmF0b3IpIHtcbiAgICBtZXNzYWdlID0gbWVzc2FnZSB8fCAnYXNzZXJ0LmZhaWwoKSc7XG4gICAgdGhyb3cgbmV3IGNoYWkuQXNzZXJ0aW9uRXJyb3IobWVzc2FnZSwge1xuICAgICAgICBhY3R1YWw6IGFjdHVhbFxuICAgICAgLCBleHBlY3RlZDogZXhwZWN0ZWRcbiAgICAgICwgb3BlcmF0b3I6IG9wZXJhdG9yXG4gICAgfSwgYXNzZXJ0LmZhaWwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzT2sob2JqZWN0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBpcyB0cnV0aHkuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNPaygnZXZlcnl0aGluZycsICdldmVyeXRoaW5nIGlzIG9rJyk7XG4gICAqICAgICBhc3NlcnQuaXNPayhmYWxzZSwgJ3RoaXMgd2lsbCBmYWlsJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzT2tcbiAgICogQGFsaWFzIG9rXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdCB0byB0ZXN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc09rID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykuaXMub2s7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RPayhvYmplY3QsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGlzIGZhbHN5LlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTm90T2soJ2V2ZXJ5dGhpbmcnLCAndGhpcyB3aWxsIGZhaWwnKTtcbiAgICogICAgIGFzc2VydC5pc05vdE9rKGZhbHNlLCAndGhpcyB3aWxsIHBhc3MnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RPa1xuICAgKiBAYWxpYXMgbm90T2tcbiAgICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0IHRvIHRlc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90T2sgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS5pcy5ub3Qub2s7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIG5vbi1zdHJpY3QgZXF1YWxpdHkgKGA9PWApIG9mIGBhY3R1YWxgIGFuZCBgZXhwZWN0ZWRgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmVxdWFsKDMsICczJywgJz09IGNvZXJjZXMgdmFsdWVzIHRvIHN0cmluZ3MnKTtcbiAgICpcbiAgICogQG5hbWUgZXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5lcXVhbCA9IGZ1bmN0aW9uIChhY3QsIGV4cCwgbXNnKSB7XG4gICAgdmFyIHRlc3QgPSBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnLCBhc3NlcnQuZXF1YWwpO1xuXG4gICAgdGVzdC5hc3NlcnQoXG4gICAgICAgIGV4cCA9PSBmbGFnKHRlc3QsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBlcXVhbCAje2V4cH0nXG4gICAgICAsICdleHBlY3RlZCAje3RoaXN9IHRvIG5vdCBlcXVhbCAje2FjdH0nXG4gICAgICAsIGV4cFxuICAgICAgLCBhY3RcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBub24tc3RyaWN0IGluZXF1YWxpdHkgKGAhPWApIG9mIGBhY3R1YWxgIGFuZCBgZXhwZWN0ZWRgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdEVxdWFsKDMsIDQsICd0aGVzZSBudW1iZXJzIGFyZSBub3QgZXF1YWwnKTtcbiAgICpcbiAgICogQG5hbWUgbm90RXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RFcXVhbCA9IGZ1bmN0aW9uIChhY3QsIGV4cCwgbXNnKSB7XG4gICAgdmFyIHRlc3QgPSBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnLCBhc3NlcnQubm90RXF1YWwpO1xuXG4gICAgdGVzdC5hc3NlcnQoXG4gICAgICAgIGV4cCAhPSBmbGFnKHRlc3QsICdvYmplY3QnKVxuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBub3QgZXF1YWwgI3tleHB9J1xuICAgICAgLCAnZXhwZWN0ZWQgI3t0aGlzfSB0byBlcXVhbCAje2FjdH0nXG4gICAgICAsIGV4cFxuICAgICAgLCBhY3RcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLnN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBzdHJpY3QgZXF1YWxpdHkgKGA9PT1gKSBvZiBgYWN0dWFsYCBhbmQgYGV4cGVjdGVkYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0cnVlLCB0cnVlLCAndGhlc2UgYm9vbGVhbnMgYXJlIHN0cmljdGx5IGVxdWFsJyk7XG4gICAqXG4gICAqIEBuYW1lIHN0cmljdEVxdWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuc3RyaWN0RXF1YWwgPSBmdW5jdGlvbiAoYWN0LCBleHAsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oYWN0LCBtc2cpLnRvLmVxdWFsKGV4cCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHN0cmljdCBpbmVxdWFsaXR5IChgIT09YCkgb2YgYGFjdHVhbGAgYW5kIGBleHBlY3RlZGAuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90U3RyaWN0RXF1YWwoMywgJzMnLCAnbm8gY29lcmNpb24gZm9yIHN0cmljdCBlcXVhbGl0eScpO1xuICAgKlxuICAgKiBAbmFtZSBub3RTdHJpY3RFcXVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBhY3R1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsID0gZnVuY3Rpb24gKGFjdCwgZXhwLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnKS50by5ub3QuZXF1YWwoZXhwKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYGFjdHVhbGAgaXMgZGVlcGx5IGVxdWFsIHRvIGBleHBlY3RlZGAuXG4gICAqXG4gICAqICAgICBhc3NlcnQuZGVlcEVxdWFsKHsgdGVhOiAnZ3JlZW4nIH0sIHsgdGVhOiAnZ3JlZW4nIH0pO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwRXF1YWxcbiAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kZWVwRXF1YWwgPSBmdW5jdGlvbiAoYWN0LCBleHAsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oYWN0LCBtc2cpLnRvLmVxbChleHApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydCB0aGF0IGBhY3R1YWxgIGlzIG5vdCBkZWVwbHkgZXF1YWwgdG8gYGV4cGVjdGVkYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3REZWVwRXF1YWwoeyB0ZWE6ICdncmVlbicgfSwgeyB0ZWE6ICdqYXNtaW5lJyB9KTtcbiAgICpcbiAgICogQG5hbWUgbm90RGVlcEVxdWFsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90RGVlcEVxdWFsID0gZnVuY3Rpb24gKGFjdCwgZXhwLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnKS50by5ub3QuZXFsKGV4cCk7XG4gIH07XG5cbiAgIC8qKlxuICAgKiAjIyMgLmlzQWJvdmUodmFsdWVUb0NoZWNrLCB2YWx1ZVRvQmVBYm92ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIGB2YWx1ZVRvQ2hlY2tgIGlzIHN0cmljdGx5IGdyZWF0ZXIgdGhhbiAoPikgYHZhbHVlVG9CZUFib3ZlYFxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzQWJvdmUoNSwgMiwgJzUgaXMgc3RyaWN0bHkgZ3JlYXRlciB0aGFuIDInKTtcbiAgICpcbiAgICogQG5hbWUgaXNBYm92ZVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVRvQ2hlY2tcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVUb0JlQWJvdmVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzQWJvdmUgPSBmdW5jdGlvbiAodmFsLCBhYnYsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLmFib3ZlKGFidik7XG4gIH07XG5cbiAgIC8qKlxuICAgKiAjIyMgLmlzQXRMZWFzdCh2YWx1ZVRvQ2hlY2ssIHZhbHVlVG9CZUF0TGVhc3QsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyBgdmFsdWVUb0NoZWNrYCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gKD49KSBgdmFsdWVUb0JlQXRMZWFzdGBcbiAgICpcbiAgICogICAgIGFzc2VydC5pc0F0TGVhc3QoNSwgMiwgJzUgaXMgZ3JlYXRlciBvciBlcXVhbCB0byAyJyk7XG4gICAqICAgICBhc3NlcnQuaXNBdExlYXN0KDMsIDMsICczIGlzIGdyZWF0ZXIgb3IgZXF1YWwgdG8gMycpO1xuICAgKlxuICAgKiBAbmFtZSBpc0F0TGVhc3RcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVUb0NoZWNrXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlVG9CZUF0TGVhc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzQXRMZWFzdCA9IGZ1bmN0aW9uICh2YWwsIGF0bHN0LCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5iZS5sZWFzdChhdGxzdCk7XG4gIH07XG5cbiAgIC8qKlxuICAgKiAjIyMgLmlzQmVsb3codmFsdWVUb0NoZWNrLCB2YWx1ZVRvQmVCZWxvdywgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIGB2YWx1ZVRvQ2hlY2tgIGlzIHN0cmljdGx5IGxlc3MgdGhhbiAoPCkgYHZhbHVlVG9CZUJlbG93YFxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzQmVsb3coMywgNiwgJzMgaXMgc3RyaWN0bHkgbGVzcyB0aGFuIDYnKTtcbiAgICpcbiAgICogQG5hbWUgaXNCZWxvd1xuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVRvQ2hlY2tcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVUb0JlQmVsb3dcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzQmVsb3cgPSBmdW5jdGlvbiAodmFsLCBibHcsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLmJlbG93KGJsdyk7XG4gIH07XG5cbiAgIC8qKlxuICAgKiAjIyMgLmlzQXRNb3N0KHZhbHVlVG9DaGVjaywgdmFsdWVUb0JlQXRNb3N0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgYHZhbHVlVG9DaGVja2AgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICg8PSkgYHZhbHVlVG9CZUF0TW9zdGBcbiAgICpcbiAgICogICAgIGFzc2VydC5pc0F0TW9zdCgzLCA2LCAnMyBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gNicpO1xuICAgKiAgICAgYXNzZXJ0LmlzQXRNb3N0KDQsIDQsICc0IGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byA0Jyk7XG4gICAqXG4gICAqIEBuYW1lIGlzQXRNb3N0XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlVG9DaGVja1xuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVRvQmVBdE1vc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzQXRNb3N0ID0gZnVuY3Rpb24gKHZhbCwgYXRtc3QsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLm1vc3QoYXRtc3QpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzVHJ1ZSh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyB0cnVlLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYVNlcnZlZCA9IHRydWU7XG4gICAqICAgICBhc3NlcnQuaXNUcnVlKHRlYVNlcnZlZCwgJ3RoZSB0ZWEgaGFzIGJlZW4gc2VydmVkJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzVHJ1ZVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNUcnVlID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykuaXNbJ3RydWUnXTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdFRydWUodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgbm90IHRydWUuXG4gICAqXG4gICAqICAgICB2YXIgdGVhID0gJ3Rhc3R5IGNoYWknO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90VHJ1ZSh0ZWEsICdncmVhdCwgdGltZSBmb3IgdGVhIScpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdFRydWVcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90VHJ1ZSA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLm5vdC5lcXVhbCh0cnVlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0ZhbHNlKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIGZhbHNlLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYVNlcnZlZCA9IGZhbHNlO1xuICAgKiAgICAgYXNzZXJ0LmlzRmFsc2UodGVhU2VydmVkLCAnbm8gdGVhIHlldD8gaG1tLi4uJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzRmFsc2VcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzRmFsc2UgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS5pc1snZmFsc2UnXTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdEZhbHNlKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIG5vdCBmYWxzZS5cbiAgICpcbiAgICogICAgIHZhciB0ZWEgPSAndGFzdHkgY2hhaSc7XG4gICAqICAgICBhc3NlcnQuaXNOb3RGYWxzZSh0ZWEsICdncmVhdCwgdGltZSBmb3IgdGVhIScpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdEZhbHNlXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdEZhbHNlID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmVxdWFsKGZhbHNlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc051bGwodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgbnVsbC5cbiAgICpcbiAgICogICAgIGFzc2VydC5pc051bGwoZXJyLCAndGhlcmUgd2FzIG5vIGVycm9yJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzTnVsbFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOdWxsID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8uZXF1YWwobnVsbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3ROdWxsKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIG5vdCBudWxsLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYSA9ICd0YXN0eSBjaGFpJztcbiAgICogICAgIGFzc2VydC5pc05vdE51bGwodGVhLCAnZ3JlYXQsIHRpbWUgZm9yIHRlYSEnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3ROdWxsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdE51bGwgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5ub3QuZXF1YWwobnVsbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOYU5cbiAgICogQXNzZXJ0cyB0aGF0IHZhbHVlIGlzIE5hTlxuICAgKlxuICAgKiAgICBhc3NlcnQuaXNOYU4oJ2ZvbycsICdmb28gaXMgTmFOJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzTmFOXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05hTiA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLk5hTjtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc05vdE5hTlxuICAgKiBBc3NlcnRzIHRoYXQgdmFsdWUgaXMgbm90IE5hTlxuICAgKlxuICAgKiAgICBhc3NlcnQuaXNOb3ROYU4oNCwgJzQgaXMgbm90IE5hTicpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdE5hTlxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cbiAgYXNzZXJ0LmlzTm90TmFOID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykubm90LnRvLmJlLk5hTjtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc1VuZGVmaW5lZCh2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYC5cbiAgICpcbiAgICogICAgIHZhciB0ZWE7XG4gICAqICAgICBhc3NlcnQuaXNVbmRlZmluZWQodGVhLCAnbm8gdGVhIGRlZmluZWQnKTtcbiAgICpcbiAgICogQG5hbWUgaXNVbmRlZmluZWRcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzVW5kZWZpbmVkID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8uZXF1YWwodW5kZWZpbmVkKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0RlZmluZWQodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgbm90IGB1bmRlZmluZWRgLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYSA9ICdjdXAgb2YgY2hhaSc7XG4gICAqICAgICBhc3NlcnQuaXNEZWZpbmVkKHRlYSwgJ3RlYSBoYXMgYmVlbiBkZWZpbmVkJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzRGVmaW5lZFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNEZWZpbmVkID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmVxdWFsKHVuZGVmaW5lZCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNGdW5jdGlvbih2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBhIGZ1bmN0aW9uLlxuICAgKlxuICAgKiAgICAgZnVuY3Rpb24gc2VydmVUZWEoKSB7IHJldHVybiAnY3VwIG9mIHRlYSc7IH07XG4gICAqICAgICBhc3NlcnQuaXNGdW5jdGlvbihzZXJ2ZVRlYSwgJ2dyZWF0LCB3ZSBjYW4gaGF2ZSB0ZWEgbm93Jyk7XG4gICAqXG4gICAqIEBuYW1lIGlzRnVuY3Rpb25cbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzRnVuY3Rpb24gPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5iZS5hKCdmdW5jdGlvbicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90RnVuY3Rpb24odmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgX25vdF8gYSBmdW5jdGlvbi5cbiAgICpcbiAgICogICAgIHZhciBzZXJ2ZVRlYSA9IFsgJ2hlYXQnLCAncG91cicsICdzaXAnIF07XG4gICAqICAgICBhc3NlcnQuaXNOb3RGdW5jdGlvbihzZXJ2ZVRlYSwgJ2dyZWF0LCB3ZSBoYXZlIGxpc3RlZCB0aGUgc3RlcHMnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RGdW5jdGlvblxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RGdW5jdGlvbiA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLm5vdC5iZS5hKCdmdW5jdGlvbicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzT2JqZWN0KHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIGFuIG9iamVjdCBvZiB0eXBlICdPYmplY3QnIChhcyByZXZlYWxlZCBieSBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2ApLlxuICAgKiBfVGhlIGFzc2VydGlvbiBkb2VzIG5vdCBtYXRjaCBzdWJjbGFzc2VkIG9iamVjdHMuX1xuICAgKlxuICAgKiAgICAgdmFyIHNlbGVjdGlvbiA9IHsgbmFtZTogJ0NoYWknLCBzZXJ2ZTogJ3dpdGggc3BpY2VzJyB9O1xuICAgKiAgICAgYXNzZXJ0LmlzT2JqZWN0KHNlbGVjdGlvbiwgJ3RlYSBzZWxlY3Rpb24gaXMgYW4gb2JqZWN0Jyk7XG4gICAqXG4gICAqIEBuYW1lIGlzT2JqZWN0XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc09iamVjdCA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLmEoJ29iamVjdCcpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90T2JqZWN0KHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIF9ub3RfIGFuIG9iamVjdCBvZiB0eXBlICdPYmplY3QnIChhcyByZXZlYWxlZCBieSBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2ApLlxuICAgKlxuICAgKiAgICAgdmFyIHNlbGVjdGlvbiA9ICdjaGFpJ1xuICAgKiAgICAgYXNzZXJ0LmlzTm90T2JqZWN0KHNlbGVjdGlvbiwgJ3RlYSBzZWxlY3Rpb24gaXMgbm90IGFuIG9iamVjdCcpO1xuICAgKiAgICAgYXNzZXJ0LmlzTm90T2JqZWN0KG51bGwsICdudWxsIGlzIG5vdCBhbiBvYmplY3QnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RPYmplY3RcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90T2JqZWN0ID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmJlLmEoJ29iamVjdCcpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzQXJyYXkodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgYW4gYXJyYXkuXG4gICAqXG4gICAqICAgICB2YXIgbWVudSA9IFsgJ2dyZWVuJywgJ2NoYWknLCAnb29sb25nJyBdO1xuICAgKiAgICAgYXNzZXJ0LmlzQXJyYXkobWVudSwgJ3doYXQga2luZCBvZiB0ZWEgZG8gd2Ugd2FudD8nKTtcbiAgICpcbiAgICogQG5hbWUgaXNBcnJheVxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNBcnJheSA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLmFuKCdhcnJheScpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90QXJyYXkodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgX25vdF8gYW4gYXJyYXkuXG4gICAqXG4gICAqICAgICB2YXIgbWVudSA9ICdncmVlbnxjaGFpfG9vbG9uZyc7XG4gICAqICAgICBhc3NlcnQuaXNOb3RBcnJheShtZW51LCAnd2hhdCBraW5kIG9mIHRlYSBkbyB3ZSB3YW50PycpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdEFycmF5XG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdEFycmF5ID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmJlLmFuKCdhcnJheScpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzU3RyaW5nKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIGEgc3RyaW5nLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYU9yZGVyID0gJ2NoYWknO1xuICAgKiAgICAgYXNzZXJ0LmlzU3RyaW5nKHRlYU9yZGVyLCAnb3JkZXIgcGxhY2VkJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzU3RyaW5nXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc1N0cmluZyA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLmEoJ3N0cmluZycpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90U3RyaW5nKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIF9ub3RfIGEgc3RyaW5nLlxuICAgKlxuICAgKiAgICAgdmFyIHRlYU9yZGVyID0gNDtcbiAgICogICAgIGFzc2VydC5pc05vdFN0cmluZyh0ZWFPcmRlciwgJ29yZGVyIHBsYWNlZCcpO1xuICAgKlxuICAgKiBAbmFtZSBpc05vdFN0cmluZ1xuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RTdHJpbmcgPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5ub3QuYmUuYSgnc3RyaW5nJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOdW1iZXIodmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgaXMgYSBudW1iZXIuXG4gICAqXG4gICAqICAgICB2YXIgY3VwcyA9IDI7XG4gICAqICAgICBhc3NlcnQuaXNOdW1iZXIoY3VwcywgJ2hvdyBtYW55IGN1cHMnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOdW1iZXJcbiAgICogQHBhcmFtIHtOdW1iZXJ9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc051bWJlciA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24odmFsLCBtc2cpLnRvLmJlLmEoJ251bWJlcicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90TnVtYmVyKHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIF9ub3RfIGEgbnVtYmVyLlxuICAgKlxuICAgKiAgICAgdmFyIGN1cHMgPSAnMiBjdXBzIHBsZWFzZSc7XG4gICAqICAgICBhc3NlcnQuaXNOb3ROdW1iZXIoY3VwcywgJ2hvdyBtYW55IGN1cHMnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3ROdW1iZXJcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90TnVtYmVyID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmJlLmEoJ251bWJlcicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzQm9vbGVhbih2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBhIGJvb2xlYW4uXG4gICAqXG4gICAqICAgICB2YXIgdGVhUmVhZHkgPSB0cnVlXG4gICAqICAgICAgICwgdGVhU2VydmVkID0gZmFsc2U7XG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNCb29sZWFuKHRlYVJlYWR5LCAnaXMgdGhlIHRlYSByZWFkeScpO1xuICAgKiAgICAgYXNzZXJ0LmlzQm9vbGVhbih0ZWFTZXJ2ZWQsICdoYXMgdGVhIGJlZW4gc2VydmVkJyk7XG4gICAqXG4gICAqIEBuYW1lIGlzQm9vbGVhblxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNCb29sZWFuID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8uYmUuYSgnYm9vbGVhbicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmlzTm90Qm9vbGVhbih2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBpcyBfbm90XyBhIGJvb2xlYW4uXG4gICAqXG4gICAqICAgICB2YXIgdGVhUmVhZHkgPSAneWVwJ1xuICAgKiAgICAgICAsIHRlYVNlcnZlZCA9ICdub3BlJztcbiAgICpcbiAgICogICAgIGFzc2VydC5pc05vdEJvb2xlYW4odGVhUmVhZHksICdpcyB0aGUgdGVhIHJlYWR5Jyk7XG4gICAqICAgICBhc3NlcnQuaXNOb3RCb29sZWFuKHRlYVNlcnZlZCwgJ2hhcyB0ZWEgYmVlbiBzZXJ2ZWQnKTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RCb29sZWFuXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pc05vdEJvb2xlYW4gPSBmdW5jdGlvbiAodmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5ub3QuYmUuYSgnYm9vbGVhbicpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLnR5cGVPZih2YWx1ZSwgbmFtZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCdzIHR5cGUgaXMgYG5hbWVgLCBhcyBkZXRlcm1pbmVkIGJ5XG4gICAqIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYC5cbiAgICpcbiAgICogICAgIGFzc2VydC50eXBlT2YoeyB0ZWE6ICdjaGFpJyB9LCAnb2JqZWN0JywgJ3dlIGhhdmUgYW4gb2JqZWN0Jyk7XG4gICAqICAgICBhc3NlcnQudHlwZU9mKFsnY2hhaScsICdqYXNtaW5lJ10sICdhcnJheScsICd3ZSBoYXZlIGFuIGFycmF5Jyk7XG4gICAqICAgICBhc3NlcnQudHlwZU9mKCd0ZWEnLCAnc3RyaW5nJywgJ3dlIGhhdmUgYSBzdHJpbmcnKTtcbiAgICogICAgIGFzc2VydC50eXBlT2YoL3RlYS8sICdyZWdleHAnLCAnd2UgaGF2ZSBhIHJlZ3VsYXIgZXhwcmVzc2lvbicpO1xuICAgKiAgICAgYXNzZXJ0LnR5cGVPZihudWxsLCAnbnVsbCcsICd3ZSBoYXZlIGEgbnVsbCcpO1xuICAgKiAgICAgYXNzZXJ0LnR5cGVPZih1bmRlZmluZWQsICd1bmRlZmluZWQnLCAnd2UgaGF2ZSBhbiB1bmRlZmluZWQnKTtcbiAgICpcbiAgICogQG5hbWUgdHlwZU9mXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC50eXBlT2YgPSBmdW5jdGlvbiAodmFsLCB0eXBlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5iZS5hKHR5cGUpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdFR5cGVPZih2YWx1ZSwgbmFtZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCdzIHR5cGUgaXMgX25vdF8gYG5hbWVgLCBhcyBkZXRlcm1pbmVkIGJ5XG4gICAqIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RUeXBlT2YoJ3RlYScsICdudW1iZXInLCAnc3RyaW5ncyBhcmUgbm90IG51bWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgbm90VHlwZU9mXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlb2YgbmFtZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90VHlwZU9mID0gZnVuY3Rpb24gKHZhbCwgdHlwZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmJlLmEodHlwZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaW5zdGFuY2VPZihvYmplY3QsIGNvbnN0cnVjdG9yLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgdmFsdWVgIGlzIGFuIGluc3RhbmNlIG9mIGBjb25zdHJ1Y3RvcmAuXG4gICAqXG4gICAqICAgICB2YXIgVGVhID0gZnVuY3Rpb24gKG5hbWUpIHsgdGhpcy5uYW1lID0gbmFtZTsgfVxuICAgKiAgICAgICAsIGNoYWkgPSBuZXcgVGVhKCdjaGFpJyk7XG4gICAqXG4gICAqICAgICBhc3NlcnQuaW5zdGFuY2VPZihjaGFpLCBUZWEsICdjaGFpIGlzIGFuIGluc3RhbmNlIG9mIHRlYScpO1xuICAgKlxuICAgKiBAbmFtZSBpbnN0YW5jZU9mXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3Rvcn0gY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lmluc3RhbmNlT2YgPSBmdW5jdGlvbiAodmFsLCB0eXBlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5iZS5pbnN0YW5jZU9mKHR5cGUpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdEluc3RhbmNlT2Yob2JqZWN0LCBjb25zdHJ1Y3RvciwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIGB2YWx1ZWAgaXMgbm90IGFuIGluc3RhbmNlIG9mIGBjb25zdHJ1Y3RvcmAuXG4gICAqXG4gICAqICAgICB2YXIgVGVhID0gZnVuY3Rpb24gKG5hbWUpIHsgdGhpcy5uYW1lID0gbmFtZTsgfVxuICAgKiAgICAgICAsIGNoYWkgPSBuZXcgU3RyaW5nKCdjaGFpJyk7XG4gICAqXG4gICAqICAgICBhc3NlcnQubm90SW5zdGFuY2VPZihjaGFpLCBUZWEsICdjaGFpIGlzIG5vdCBhbiBpbnN0YW5jZSBvZiB0ZWEnKTtcbiAgICpcbiAgICogQG5hbWUgbm90SW5zdGFuY2VPZlxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3J9IGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RJbnN0YW5jZU9mID0gZnVuY3Rpb24gKHZhbCwgdHlwZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8ubm90LmJlLmluc3RhbmNlT2YodHlwZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaW5jbHVkZShoYXlzdGFjaywgbmVlZGxlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgaGF5c3RhY2tgIGluY2x1ZGVzIGBuZWVkbGVgLiBXb3Jrc1xuICAgKiBmb3Igc3RyaW5ncyBhbmQgYXJyYXlzLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmluY2x1ZGUoJ2Zvb2JhcicsICdiYXInLCAnZm9vYmFyIGNvbnRhaW5zIHN0cmluZyBcImJhclwiJyk7XG4gICAqICAgICBhc3NlcnQuaW5jbHVkZShbIDEsIDIsIDMgXSwgMywgJ2FycmF5IGNvbnRhaW5zIHZhbHVlJyk7XG4gICAqXG4gICAqIEBuYW1lIGluY2x1ZGVcbiAgICogQHBhcmFtIHtBcnJheXxTdHJpbmd9IGhheXN0YWNrXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG5lZWRsZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaW5jbHVkZSA9IGZ1bmN0aW9uIChleHAsIGluYywgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZywgYXNzZXJ0LmluY2x1ZGUpLmluY2x1ZGUoaW5jKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3RJbmNsdWRlKGhheXN0YWNrLCBuZWVkbGUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBoYXlzdGFja2AgZG9lcyBub3QgaW5jbHVkZSBgbmVlZGxlYC4gV29ya3NcbiAgICogZm9yIHN0cmluZ3MgYW5kIGFycmF5cy5cbiAgICpcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlKCdmb29iYXInLCAnYmF6JywgJ3N0cmluZyBub3QgaW5jbHVkZSBzdWJzdHJpbmcnKTtcbiAgICogICAgIGFzc2VydC5ub3RJbmNsdWRlKFsgMSwgMiwgMyBdLCA0LCAnYXJyYXkgbm90IGluY2x1ZGUgY29udGFpbiB2YWx1ZScpO1xuICAgKlxuICAgKiBAbmFtZSBub3RJbmNsdWRlXG4gICAqIEBwYXJhbSB7QXJyYXl8U3RyaW5nfSBoYXlzdGFja1xuICAgKiBAcGFyYW0ge01peGVkfSBuZWVkbGVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm5vdEluY2x1ZGUgPSBmdW5jdGlvbiAoZXhwLCBpbmMsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oZXhwLCBtc2csIGFzc2VydC5ub3RJbmNsdWRlKS5ub3QuaW5jbHVkZShpbmMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm1hdGNoKHZhbHVlLCByZWdleHAsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGB2YWx1ZWAgbWF0Y2hlcyB0aGUgcmVndWxhciBleHByZXNzaW9uIGByZWdleHBgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm1hdGNoKCdmb29iYXInLCAvXmZvby8sICdyZWdleHAgbWF0Y2hlcycpO1xuICAgKlxuICAgKiBAbmFtZSBtYXRjaFxuICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZVxuICAgKiBAcGFyYW0ge1JlZ0V4cH0gcmVnZXhwXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5tYXRjaCA9IGZ1bmN0aW9uIChleHAsIHJlLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGV4cCwgbXNnKS50by5tYXRjaChyZSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAubm90TWF0Y2godmFsdWUsIHJlZ2V4cCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHZhbHVlYCBkb2VzIG5vdCBtYXRjaCB0aGUgcmVndWxhciBleHByZXNzaW9uIGByZWdleHBgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdE1hdGNoKCdmb29iYXInLCAvXmZvby8sICdyZWdleHAgZG9lcyBub3QgbWF0Y2gnKTtcbiAgICpcbiAgICogQG5hbWUgbm90TWF0Y2hcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90TWF0Y2ggPSBmdW5jdGlvbiAoZXhwLCByZSwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZykudG8ubm90Lm1hdGNoKHJlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5wcm9wZXJ0eShvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnByb3BlcnR5KHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9fSwgJ3RlYScpO1xuICAgKlxuICAgKiBAbmFtZSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQucHJvcGVydHkgPSBmdW5jdGlvbiAob2JqLCBwcm9wLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KHByb3ApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLm5vdFByb3BlcnR5KG9iamVjdCwgcHJvcGVydHksIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGRvZXMgX25vdF8gaGF2ZSBhIHByb3BlcnR5IG5hbWVkIGJ5IGBwcm9wZXJ0eWAuXG4gICAqXG4gICAqICAgICBhc3NlcnQubm90UHJvcGVydHkoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH19LCAnY29mZmVlJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdFByb3BlcnR5XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5ub3RQcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmosIHByb3AsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLnRvLm5vdC5oYXZlLnByb3BlcnR5KHByb3ApO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmRlZXBQcm9wZXJ0eShvYmplY3QsIHByb3BlcnR5LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgLCB3aGljaCBjYW4gYmUgYVxuICAgKiBzdHJpbmcgdXNpbmcgZG90LSBhbmQgYnJhY2tldC1ub3RhdGlvbiBmb3IgZGVlcCByZWZlcmVuY2UuXG4gICAqXG4gICAqICAgICBhc3NlcnQuZGVlcFByb3BlcnR5KHsgdGVhOiB7IGdyZWVuOiAnbWF0Y2hhJyB9fSwgJ3RlYS5ncmVlbicpO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwUHJvcGVydHlcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlZXBQcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmosIHByb3AsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eShwcm9wKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5ub3REZWVwUHJvcGVydHkob2JqZWN0LCBwcm9wZXJ0eSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgZG9lcyBfbm90XyBoYXZlIGEgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCwgd2hpY2hcbiAgICogY2FuIGJlIGEgc3RyaW5nIHVzaW5nIGRvdC0gYW5kIGJyYWNrZXQtbm90YXRpb24gZm9yIGRlZXAgcmVmZXJlbmNlLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0Lm5vdERlZXBQcm9wZXJ0eSh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfX0sICd0ZWEub29sb25nJyk7XG4gICAqXG4gICAqIEBuYW1lIG5vdERlZXBQcm9wZXJ0eVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQubm90RGVlcFByb3BlcnR5ID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8ubm90LmhhdmUuZGVlcC5wcm9wZXJ0eShwcm9wKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5wcm9wZXJ0eVZhbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGEgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCB3aXRoIHZhbHVlIGdpdmVuXG4gICAqIGJ5IGB2YWx1ZWAuXG4gICAqXG4gICAqICAgICBhc3NlcnQucHJvcGVydHlWYWwoeyB0ZWE6ICdpcyBnb29kJyB9LCAndGVhJywgJ2lzIGdvb2QnKTtcbiAgICpcbiAgICogQG5hbWUgcHJvcGVydHlWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LnByb3BlcnR5VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5oYXZlLnByb3BlcnR5KHByb3AsIHZhbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAucHJvcGVydHlOb3RWYWwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGhhcyBhIHByb3BlcnR5IG5hbWVkIGJ5IGBwcm9wZXJ0eWAsIGJ1dCB3aXRoIGEgdmFsdWVcbiAgICogZGlmZmVyZW50IGZyb20gdGhhdCBnaXZlbiBieSBgdmFsdWVgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnByb3BlcnR5Tm90VmFsKHsgdGVhOiAnaXMgZ29vZCcgfSwgJ3RlYScsICdpcyBiYWQnKTtcbiAgICpcbiAgICogQG5hbWUgcHJvcGVydHlOb3RWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LnByb3BlcnR5Tm90VmFsID0gZnVuY3Rpb24gKG9iaiwgcHJvcCwgdmFsLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5ub3QuaGF2ZS5wcm9wZXJ0eShwcm9wLCB2YWwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmRlZXBQcm9wZXJ0eVZhbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaGFzIGEgcHJvcGVydHkgbmFtZWQgYnkgYHByb3BlcnR5YCB3aXRoIHZhbHVlIGdpdmVuXG4gICAqIGJ5IGB2YWx1ZWAuIGBwcm9wZXJ0eWAgY2FuIHVzZSBkb3QtIGFuZCBicmFja2V0LW5vdGF0aW9uIGZvciBkZWVwXG4gICAqIHJlZmVyZW5jZS5cbiAgICpcbiAgICogICAgIGFzc2VydC5kZWVwUHJvcGVydHlWYWwoeyB0ZWE6IHsgZ3JlZW46ICdtYXRjaGEnIH19LCAndGVhLmdyZWVuJywgJ21hdGNoYScpO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwUHJvcGVydHlWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlZXBQcm9wZXJ0eVZhbCA9IGZ1bmN0aW9uIChvYmosIHByb3AsIHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8uaGF2ZS5kZWVwLnByb3BlcnR5KHByb3AsIHZhbCk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuZGVlcFByb3BlcnR5Tm90VmFsKG9iamVjdCwgcHJvcGVydHksIHZhbHVlLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBwcm9wZXJ0eSBuYW1lZCBieSBgcHJvcGVydHlgLCBidXQgd2l0aCBhIHZhbHVlXG4gICAqIGRpZmZlcmVudCBmcm9tIHRoYXQgZ2l2ZW4gYnkgYHZhbHVlYC4gYHByb3BlcnR5YCBjYW4gdXNlIGRvdC0gYW5kXG4gICAqIGJyYWNrZXQtbm90YXRpb24gZm9yIGRlZXAgcmVmZXJlbmNlLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmRlZXBQcm9wZXJ0eU5vdFZhbCh7IHRlYTogeyBncmVlbjogJ21hdGNoYScgfX0sICd0ZWEuZ3JlZW4nLCAna29uYWNoYScpO1xuICAgKlxuICAgKiBAbmFtZSBkZWVwUHJvcGVydHlOb3RWYWxcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHlcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRlZXBQcm9wZXJ0eU5vdFZhbCA9IGZ1bmN0aW9uIChvYmosIHByb3AsIHZhbCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8ubm90LmhhdmUuZGVlcC5wcm9wZXJ0eShwcm9wLCB2YWwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLmxlbmd0aE9mKG9iamVjdCwgbGVuZ3RoLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBoYXMgYSBgbGVuZ3RoYCBwcm9wZXJ0eSB3aXRoIHRoZSBleHBlY3RlZCB2YWx1ZS5cbiAgICpcbiAgICogICAgIGFzc2VydC5sZW5ndGhPZihbMSwyLDNdLCAzLCAnYXJyYXkgaGFzIGxlbmd0aCBvZiAzJyk7XG4gICAqICAgICBhc3NlcnQubGVuZ3RoT2YoJ2Zvb2JhcicsIDYsICdzdHJpbmcgaGFzIGxlbmd0aCBvZiA2Jyk7XG4gICAqXG4gICAqIEBuYW1lIGxlbmd0aE9mXG4gICAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5sZW5ndGhPZiA9IGZ1bmN0aW9uIChleHAsIGxlbiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihleHAsIG1zZykudG8uaGF2ZS5sZW5ndGgobGVuKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC50aHJvd3MoZnVuY3Rpb24sIFtjb25zdHJ1Y3Rvci9zdHJpbmcvcmVnZXhwXSwgW3N0cmluZy9yZWdleHBdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgZnVuY3Rpb25gIHdpbGwgdGhyb3cgYW4gZXJyb3IgdGhhdCBpcyBhbiBpbnN0YW5jZSBvZlxuICAgKiBgY29uc3RydWN0b3JgLCBvciBhbHRlcm5hdGVseSB0aGF0IGl0IHdpbGwgdGhyb3cgYW4gZXJyb3Igd2l0aCBtZXNzYWdlXG4gICAqIG1hdGNoaW5nIGByZWdleHBgLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnRocm93cyhmbiwgJ2Z1bmN0aW9uIHRocm93cyBhIHJlZmVyZW5jZSBlcnJvcicpO1xuICAgKiAgICAgYXNzZXJ0LnRocm93cyhmbiwgL2Z1bmN0aW9uIHRocm93cyBhIHJlZmVyZW5jZSBlcnJvci8pO1xuICAgKiAgICAgYXNzZXJ0LnRocm93cyhmbiwgUmVmZXJlbmNlRXJyb3IpO1xuICAgKiAgICAgYXNzZXJ0LnRocm93cyhmbiwgUmVmZXJlbmNlRXJyb3IsICdmdW5jdGlvbiB0aHJvd3MgYSByZWZlcmVuY2UgZXJyb3InKTtcbiAgICogICAgIGFzc2VydC50aHJvd3MoZm4sIFJlZmVyZW5jZUVycm9yLCAvZnVuY3Rpb24gdGhyb3dzIGEgcmVmZXJlbmNlIGVycm9yLyk7XG4gICAqXG4gICAqIEBuYW1lIHRocm93c1xuICAgKiBAYWxpYXMgdGhyb3dcbiAgICogQGFsaWFzIFRocm93XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7RXJyb3JDb25zdHJ1Y3Rvcn0gY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Vycm9yI0Vycm9yX3R5cGVzXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC50aHJvd3MgPSBmdW5jdGlvbiAoZm4sIGVycnQsIGVycnMsIG1zZykge1xuICAgIGlmICgnc3RyaW5nJyA9PT0gdHlwZW9mIGVycnQgfHwgZXJydCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgZXJycyA9IGVycnQ7XG4gICAgICBlcnJ0ID0gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgYXNzZXJ0RXJyID0gbmV3IEFzc2VydGlvbihmbiwgbXNnKS50by50aHJvdyhlcnJ0LCBlcnJzKTtcbiAgICByZXR1cm4gZmxhZyhhc3NlcnRFcnIsICdvYmplY3QnKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5kb2VzTm90VGhyb3coZnVuY3Rpb24sIFtjb25zdHJ1Y3Rvci9yZWdleHBdLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgZnVuY3Rpb25gIHdpbGwgX25vdF8gdGhyb3cgYW4gZXJyb3IgdGhhdCBpcyBhbiBpbnN0YW5jZSBvZlxuICAgKiBgY29uc3RydWN0b3JgLCBvciBhbHRlcm5hdGVseSB0aGF0IGl0IHdpbGwgbm90IHRocm93IGFuIGVycm9yIHdpdGggbWVzc2FnZVxuICAgKiBtYXRjaGluZyBgcmVnZXhwYC5cbiAgICpcbiAgICogICAgIGFzc2VydC5kb2VzTm90VGhyb3coZm4sIEVycm9yLCAnZnVuY3Rpb24gZG9lcyBub3QgdGhyb3cnKTtcbiAgICpcbiAgICogQG5hbWUgZG9lc05vdFRocm93XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7RXJyb3JDb25zdHJ1Y3Rvcn0gY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Vycm9yI0Vycm9yX3R5cGVzXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kb2VzTm90VGhyb3cgPSBmdW5jdGlvbiAoZm4sIHR5cGUsIG1zZykge1xuICAgIGlmICgnc3RyaW5nJyA9PT0gdHlwZW9mIHR5cGUpIHtcbiAgICAgIG1zZyA9IHR5cGU7XG4gICAgICB0eXBlID0gbnVsbDtcbiAgICB9XG5cbiAgICBuZXcgQXNzZXJ0aW9uKGZuLCBtc2cpLnRvLm5vdC5UaHJvdyh0eXBlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5vcGVyYXRvcih2YWwxLCBvcGVyYXRvciwgdmFsMiwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBDb21wYXJlcyB0d28gdmFsdWVzIHVzaW5nIGBvcGVyYXRvcmAuXG4gICAqXG4gICAqICAgICBhc3NlcnQub3BlcmF0b3IoMSwgJzwnLCAyLCAnZXZlcnl0aGluZyBpcyBvaycpO1xuICAgKiAgICAgYXNzZXJ0Lm9wZXJhdG9yKDEsICc+JywgMiwgJ3RoaXMgd2lsbCBmYWlsJyk7XG4gICAqXG4gICAqIEBuYW1lIG9wZXJhdG9yXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbDFcbiAgICogQHBhcmFtIHtTdHJpbmd9IG9wZXJhdG9yXG4gICAqIEBwYXJhbSB7TWl4ZWR9IHZhbDJcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm9wZXJhdG9yID0gZnVuY3Rpb24gKHZhbCwgb3BlcmF0b3IsIHZhbDIsIG1zZykge1xuICAgIHZhciBvaztcbiAgICBzd2l0Y2gob3BlcmF0b3IpIHtcbiAgICAgIGNhc2UgJz09JzpcbiAgICAgICAgb2sgPSB2YWwgPT0gdmFsMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICc9PT0nOlxuICAgICAgICBvayA9IHZhbCA9PT0gdmFsMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICc+JzpcbiAgICAgICAgb2sgPSB2YWwgPiB2YWwyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJz49JzpcbiAgICAgICAgb2sgPSB2YWwgPj0gdmFsMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICc8JzpcbiAgICAgICAgb2sgPSB2YWwgPCB2YWwyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzw9JzpcbiAgICAgICAgb2sgPSB2YWwgPD0gdmFsMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICchPSc6XG4gICAgICAgIG9rID0gdmFsICE9IHZhbDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnIT09JzpcbiAgICAgICAgb2sgPSB2YWwgIT09IHZhbDI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG9wZXJhdG9yIFwiJyArIG9wZXJhdG9yICsgJ1wiJyk7XG4gICAgfVxuICAgIHZhciB0ZXN0ID0gbmV3IEFzc2VydGlvbihvaywgbXNnKTtcbiAgICB0ZXN0LmFzc2VydChcbiAgICAgICAgdHJ1ZSA9PT0gZmxhZyh0ZXN0LCAnb2JqZWN0JylcbiAgICAgICwgJ2V4cGVjdGVkICcgKyB1dGlsLmluc3BlY3QodmFsKSArICcgdG8gYmUgJyArIG9wZXJhdG9yICsgJyAnICsgdXRpbC5pbnNwZWN0KHZhbDIpXG4gICAgICAsICdleHBlY3RlZCAnICsgdXRpbC5pbnNwZWN0KHZhbCkgKyAnIHRvIG5vdCBiZSAnICsgb3BlcmF0b3IgKyAnICcgKyB1dGlsLmluc3BlY3QodmFsMikgKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5jbG9zZVRvKGFjdHVhbCwgZXhwZWN0ZWQsIGRlbHRhLCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCB0aGUgdGFyZ2V0IGlzIGVxdWFsIGBleHBlY3RlZGAsIHRvIHdpdGhpbiBhICsvLSBgZGVsdGFgIHJhbmdlLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmNsb3NlVG8oMS41LCAxLCAwLjUsICdudW1iZXJzIGFyZSBjbG9zZScpO1xuICAgKlxuICAgKiBAbmFtZSBjbG9zZVRvXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBhY3R1YWxcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGV4cGVjdGVkXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBkZWx0YVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuY2xvc2VUbyA9IGZ1bmN0aW9uIChhY3QsIGV4cCwgZGVsdGEsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oYWN0LCBtc2cpLnRvLmJlLmNsb3NlVG8oZXhwLCBkZWx0YSk7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuYXBwcm94aW1hdGVseShhY3R1YWwsIGV4cGVjdGVkLCBkZWx0YSwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgdGhlIHRhcmdldCBpcyBlcXVhbCBgZXhwZWN0ZWRgLCB0byB3aXRoaW4gYSArLy0gYGRlbHRhYCByYW5nZS5cbiAgICpcbiAgICogICAgIGFzc2VydC5hcHByb3hpbWF0ZWx5KDEuNSwgMSwgMC41LCAnbnVtYmVycyBhcmUgY2xvc2UnKTtcbiAgICpcbiAgICogQG5hbWUgYXBwcm94aW1hdGVseVxuICAgKiBAcGFyYW0ge051bWJlcn0gYWN0dWFsXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge051bWJlcn0gZGVsdGFcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmFwcHJveGltYXRlbHkgPSBmdW5jdGlvbiAoYWN0LCBleHAsIGRlbHRhLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGFjdCwgbXNnKS50by5iZS5hcHByb3hpbWF0ZWx5KGV4cCwgZGVsdGEpO1xuICB9O1xuXG4gIC8qKlxuICAgKiAjIyMgLnNhbWVNZW1iZXJzKHNldDEsIHNldDIsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBzZXQxYCBhbmQgYHNldDJgIGhhdmUgdGhlIHNhbWUgbWVtYmVycy5cbiAgICogT3JkZXIgaXMgbm90IHRha2VuIGludG8gYWNjb3VudC5cbiAgICpcbiAgICogICAgIGFzc2VydC5zYW1lTWVtYmVycyhbIDEsIDIsIDMgXSwgWyAyLCAxLCAzIF0sICdzYW1lIG1lbWJlcnMnKTtcbiAgICpcbiAgICogQG5hbWUgc2FtZU1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MVxuICAgKiBAcGFyYW0ge0FycmF5fSBzZXQyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5zYW1lTWVtYmVycyA9IGZ1bmN0aW9uIChzZXQxLCBzZXQyLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHNldDEsIG1zZykudG8uaGF2ZS5zYW1lLm1lbWJlcnMoc2V0Mik7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5zYW1lRGVlcE1lbWJlcnMoc2V0MSwgc2V0MiwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHNldDFgIGFuZCBgc2V0MmAgaGF2ZSB0aGUgc2FtZSBtZW1iZXJzIC0gdXNpbmcgYSBkZWVwIGVxdWFsaXR5IGNoZWNraW5nLlxuICAgKiBPcmRlciBpcyBub3QgdGFrZW4gaW50byBhY2NvdW50LlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LnNhbWVEZWVwTWVtYmVycyhbIHtiOiAzfSwge2E6IDJ9LCB7YzogNX0gXSwgWyB7YzogNX0sIHtiOiAzfSwge2E6IDJ9IF0sICdzYW1lIGRlZXAgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBzYW1lRGVlcE1lbWJlcnNcbiAgICogQHBhcmFtIHtBcnJheX0gc2V0MVxuICAgKiBAcGFyYW0ge0FycmF5fSBzZXQyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5zYW1lRGVlcE1lbWJlcnMgPSBmdW5jdGlvbiAoc2V0MSwgc2V0MiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihzZXQxLCBtc2cpLnRvLmhhdmUuc2FtZS5kZWVwLm1lbWJlcnMoc2V0Mik7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5pbmNsdWRlTWVtYmVycyhzdXBlcnNldCwgc3Vic2V0LCBbbWVzc2FnZV0pXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgc3Vic2V0YCBpcyBpbmNsdWRlZCBpbiBgc3VwZXJzZXRgLlxuICAgKiBPcmRlciBpcyBub3QgdGFrZW4gaW50byBhY2NvdW50LlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmluY2x1ZGVNZW1iZXJzKFsgMSwgMiwgMyBdLCBbIDIsIDEgXSwgJ2luY2x1ZGUgbWVtYmVycycpO1xuICAgKlxuICAgKiBAbmFtZSBpbmNsdWRlTWVtYmVyc1xuICAgKiBAcGFyYW0ge0FycmF5fSBzdXBlcnNldFxuICAgKiBAcGFyYW0ge0FycmF5fSBzdWJzZXRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmluY2x1ZGVNZW1iZXJzID0gZnVuY3Rpb24gKHN1cGVyc2V0LCBzdWJzZXQsIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24oc3VwZXJzZXQsIG1zZykudG8uaW5jbHVkZS5tZW1iZXJzKHN1YnNldCk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5pbmNsdWRlRGVlcE1lbWJlcnMoc3VwZXJzZXQsIHN1YnNldCwgW21lc3NhZ2VdKVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYHN1YnNldGAgaXMgaW5jbHVkZWQgaW4gYHN1cGVyc2V0YCAtIHVzaW5nIGRlZXAgZXF1YWxpdHkgY2hlY2tpbmcuXG4gICAqIE9yZGVyIGlzIG5vdCB0YWtlbiBpbnRvIGFjY291bnQuXG4gICAqIER1cGxpY2F0ZXMgYXJlIGlnbm9yZWQuXG4gICAqXG4gICAqICAgICBhc3NlcnQuaW5jbHVkZURlZXBNZW1iZXJzKFsge2E6IDF9LCB7YjogMn0sIHtjOiAzfSBdLCBbIHtiOiAyfSwge2E6IDF9LCB7YjogMn0gXSwgJ2luY2x1ZGUgZGVlcCBtZW1iZXJzJyk7XG4gICAqXG4gICAqIEBuYW1lIGluY2x1ZGVEZWVwTWVtYmVyc1xuICAgKiBAcGFyYW0ge0FycmF5fSBzdXBlcnNldFxuICAgKiBAcGFyYW0ge0FycmF5fSBzdWJzZXRcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmluY2x1ZGVEZWVwTWVtYmVycyA9IGZ1bmN0aW9uIChzdXBlcnNldCwgc3Vic2V0LCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKHN1cGVyc2V0LCBtc2cpLnRvLmluY2x1ZGUuZGVlcC5tZW1iZXJzKHN1YnNldCk7XG4gIH1cblxuICAvKipcbiAgICogIyMjIC5vbmVPZihpbkxpc3QsIGxpc3QsIFttZXNzYWdlXSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IG5vbi1vYmplY3QsIG5vbi1hcnJheSB2YWx1ZSBgaW5MaXN0YCBhcHBlYXJzIGluIHRoZSBmbGF0IGFycmF5IGBsaXN0YC5cbiAgICpcbiAgICogICAgIGFzc2VydC5vbmVPZigxLCBbIDIsIDEgXSwgJ05vdCBmb3VuZCBpbiBsaXN0Jyk7XG4gICAqXG4gICAqIEBuYW1lIG9uZU9mXG4gICAqIEBwYXJhbSB7Kn0gaW5MaXN0XG4gICAqIEBwYXJhbSB7QXJyYXk8Kj59IGxpc3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0Lm9uZU9mID0gZnVuY3Rpb24gKGluTGlzdCwgbGlzdCwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihpbkxpc3QsIG1zZykudG8uYmUub25lT2YobGlzdCk7XG4gIH1cblxuICAgLyoqXG4gICAqICMjIyAuY2hhbmdlcyhmdW5jdGlvbiwgb2JqZWN0LCBwcm9wZXJ0eSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gY2hhbmdlcyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eVxuICAgKlxuICAgKiAgICAgdmFyIG9iaiA9IHsgdmFsOiAxMCB9O1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7IG9iai52YWwgPSAyMiB9O1xuICAgKiAgICAgYXNzZXJ0LmNoYW5nZXMoZm4sIG9iaiwgJ3ZhbCcpO1xuICAgKlxuICAgKiBAbmFtZSBjaGFuZ2VzXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG1vZGlmaWVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IG5hbWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuY2hhbmdlcyA9IGZ1bmN0aW9uIChmbiwgb2JqLCBwcm9wKSB7XG4gICAgbmV3IEFzc2VydGlvbihmbikudG8uY2hhbmdlKG9iaiwgcHJvcCk7XG4gIH1cblxuICAgLyoqXG4gICAqICMjIyAuZG9lc05vdENoYW5nZShmdW5jdGlvbiwgb2JqZWN0LCBwcm9wZXJ0eSlcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGEgZnVuY3Rpb24gZG9lcyBub3QgY2hhbmdlcyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eVxuICAgKlxuICAgKiAgICAgdmFyIG9iaiA9IHsgdmFsOiAxMCB9O1xuICAgKiAgICAgdmFyIGZuID0gZnVuY3Rpb24oKSB7IGNvbnNvbGUubG9nKCdmb28nKTsgfTtcbiAgICogICAgIGFzc2VydC5kb2VzTm90Q2hhbmdlKGZuLCBvYmosICd2YWwnKTtcbiAgICpcbiAgICogQG5hbWUgZG9lc05vdENoYW5nZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtb2RpZmllciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRvZXNOb3RDaGFuZ2UgPSBmdW5jdGlvbiAoZm4sIG9iaiwgcHJvcCkge1xuICAgIG5ldyBBc3NlcnRpb24oZm4pLnRvLm5vdC5jaGFuZ2Uob2JqLCBwcm9wKTtcbiAgfVxuXG4gICAvKipcbiAgICogIyMjIC5pbmNyZWFzZXMoZnVuY3Rpb24sIG9iamVjdCwgcHJvcGVydHkpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBhIGZ1bmN0aW9uIGluY3JlYXNlcyBhbiBvYmplY3QgcHJvcGVydHlcbiAgICpcbiAgICogICAgIHZhciBvYmogPSB7IHZhbDogMTAgfTtcbiAgICogICAgIHZhciBmbiA9IGZ1bmN0aW9uKCkgeyBvYmoudmFsID0gMTMgfTtcbiAgICogICAgIGFzc2VydC5pbmNyZWFzZXMoZm4sIG9iaiwgJ3ZhbCcpO1xuICAgKlxuICAgKiBAbmFtZSBpbmNyZWFzZXNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbW9kaWZpZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHkgbmFtZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5pbmNyZWFzZXMgPSBmdW5jdGlvbiAoZm4sIG9iaiwgcHJvcCkge1xuICAgIG5ldyBBc3NlcnRpb24oZm4pLnRvLmluY3JlYXNlKG9iaiwgcHJvcCk7XG4gIH1cblxuICAgLyoqXG4gICAqICMjIyAuZG9lc05vdEluY3JlYXNlKGZ1bmN0aW9uLCBvYmplY3QsIHByb3BlcnR5KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYSBmdW5jdGlvbiBkb2VzIG5vdCBpbmNyZWFzZSBvYmplY3QgcHJvcGVydHlcbiAgICpcbiAgICogICAgIHZhciBvYmogPSB7IHZhbDogMTAgfTtcbiAgICogICAgIHZhciBmbiA9IGZ1bmN0aW9uKCkgeyBvYmoudmFsID0gOCB9O1xuICAgKiAgICAgYXNzZXJ0LmRvZXNOb3RJbmNyZWFzZShmbiwgb2JqLCAndmFsJyk7XG4gICAqXG4gICAqIEBuYW1lIGRvZXNOb3RJbmNyZWFzZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBtb2RpZmllciBmdW5jdGlvblxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBuYW1lXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmRvZXNOb3RJbmNyZWFzZSA9IGZ1bmN0aW9uIChmbiwgb2JqLCBwcm9wKSB7XG4gICAgbmV3IEFzc2VydGlvbihmbikudG8ubm90LmluY3JlYXNlKG9iaiwgcHJvcCk7XG4gIH1cblxuICAgLyoqXG4gICAqICMjIyAuZGVjcmVhc2VzKGZ1bmN0aW9uLCBvYmplY3QsIHByb3BlcnR5KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYSBmdW5jdGlvbiBkZWNyZWFzZXMgYW4gb2JqZWN0IHByb3BlcnR5XG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCA9IDUgfTtcbiAgICogICAgIGFzc2VydC5kZWNyZWFzZXMoZm4sIG9iaiwgJ3ZhbCcpO1xuICAgKlxuICAgKiBAbmFtZSBkZWNyZWFzZXNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbW9kaWZpZXIgZnVuY3Rpb25cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJvcGVydHkgbmFtZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBfb3B0aW9uYWxfXG4gICAqIEBuYW1lc3BhY2UgQXNzZXJ0XG4gICAqIEBhcGkgcHVibGljXG4gICAqL1xuXG4gIGFzc2VydC5kZWNyZWFzZXMgPSBmdW5jdGlvbiAoZm4sIG9iaiwgcHJvcCkge1xuICAgIG5ldyBBc3NlcnRpb24oZm4pLnRvLmRlY3JlYXNlKG9iaiwgcHJvcCk7XG4gIH1cblxuICAgLyoqXG4gICAqICMjIyAuZG9lc05vdERlY3JlYXNlKGZ1bmN0aW9uLCBvYmplY3QsIHByb3BlcnR5KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYSBmdW5jdGlvbiBkb2VzIG5vdCBkZWNyZWFzZXMgYW4gb2JqZWN0IHByb3BlcnR5XG4gICAqXG4gICAqICAgICB2YXIgb2JqID0geyB2YWw6IDEwIH07XG4gICAqICAgICB2YXIgZm4gPSBmdW5jdGlvbigpIHsgb2JqLnZhbCA9IDE1IH07XG4gICAqICAgICBhc3NlcnQuZG9lc05vdERlY3JlYXNlKGZuLCBvYmosICd2YWwnKTtcbiAgICpcbiAgICogQG5hbWUgZG9lc05vdERlY3JlYXNlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG1vZGlmaWVyIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5IG5hbWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuZG9lc05vdERlY3JlYXNlID0gZnVuY3Rpb24gKGZuLCBvYmosIHByb3ApIHtcbiAgICBuZXcgQXNzZXJ0aW9uKGZuKS50by5ub3QuZGVjcmVhc2Uob2JqLCBwcm9wKTtcbiAgfVxuXG4gIC8qIVxuICAgKiAjIyMgLmlmRXJyb3Iob2JqZWN0KVxuICAgKlxuICAgKiBBc3NlcnRzIGlmIHZhbHVlIGlzIG5vdCBhIGZhbHNlIHZhbHVlLCBhbmQgdGhyb3dzIGlmIGl0IGlzIGEgdHJ1ZSB2YWx1ZS5cbiAgICogVGhpcyBpcyBhZGRlZCB0byBhbGxvdyBmb3IgY2hhaSB0byBiZSBhIGRyb3AtaW4gcmVwbGFjZW1lbnQgZm9yIE5vZGUnc1xuICAgKiBhc3NlcnQgY2xhc3MuXG4gICAqXG4gICAqICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdJIGFtIGEgY3VzdG9tIGVycm9yJyk7XG4gICAqICAgICBhc3NlcnQuaWZFcnJvcihlcnIpOyAvLyBSZXRocm93cyBlcnIhXG4gICAqXG4gICAqIEBuYW1lIGlmRXJyb3JcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaWZFcnJvciA9IGZ1bmN0aW9uICh2YWwpIHtcbiAgICBpZiAodmFsKSB7XG4gICAgICB0aHJvdyh2YWwpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0V4dGVuc2libGUob2JqZWN0KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaXMgZXh0ZW5zaWJsZSAoY2FuIGhhdmUgbmV3IHByb3BlcnRpZXMgYWRkZWQgdG8gaXQpLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzRXh0ZW5zaWJsZSh7fSk7XG4gICAqXG4gICAqIEBuYW1lIGlzRXh0ZW5zaWJsZVxuICAgKiBAYWxpYXMgZXh0ZW5zaWJsZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzRXh0ZW5zaWJsZSA9IGZ1bmN0aW9uIChvYmosIG1zZykge1xuICAgIG5ldyBBc3NlcnRpb24ob2JqLCBtc2cpLnRvLmJlLmV4dGVuc2libGU7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RFeHRlbnNpYmxlKG9iamVjdClcbiAgICpcbiAgICogQXNzZXJ0cyB0aGF0IGBvYmplY3RgIGlzIF9ub3RfIGV4dGVuc2libGUuXG4gICAqXG4gICAqICAgICB2YXIgbm9uRXh0ZW5zaWJsZU9iamVjdCA9IE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucyh7fSk7XG4gICAqICAgICB2YXIgc2VhbGVkT2JqZWN0ID0gT2JqZWN0LnNlYWwoe30pO1xuICAgKiAgICAgdmFyIGZyb3plbk9iamVjdCA9IE9iamVjdC5mcmVlc2Uoe30pO1xuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTm90RXh0ZW5zaWJsZShub25FeHRlbnNpYmxlT2JqZWN0KTtcbiAgICogICAgIGFzc2VydC5pc05vdEV4dGVuc2libGUoc2VhbGVkT2JqZWN0KTtcbiAgICogICAgIGFzc2VydC5pc05vdEV4dGVuc2libGUoZnJvemVuT2JqZWN0KTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RFeHRlbnNpYmxlXG4gICAqIEBhbGlhcyBub3RFeHRlbnNpYmxlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNOb3RFeHRlbnNpYmxlID0gZnVuY3Rpb24gKG9iaiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8ubm90LmJlLmV4dGVuc2libGU7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNTZWFsZWQob2JqZWN0KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaXMgc2VhbGVkIChjYW5ub3QgaGF2ZSBuZXcgcHJvcGVydGllcyBhZGRlZCB0byBpdFxuICAgKiBhbmQgaXRzIGV4aXN0aW5nIHByb3BlcnRpZXMgY2Fubm90IGJlIHJlbW92ZWQpLlxuICAgKlxuICAgKiAgICAgdmFyIHNlYWxlZE9iamVjdCA9IE9iamVjdC5zZWFsKHt9KTtcbiAgICogICAgIHZhciBmcm96ZW5PYmplY3QgPSBPYmplY3Quc2VhbCh7fSk7XG4gICAqXG4gICAqICAgICBhc3NlcnQuaXNTZWFsZWQoc2VhbGVkT2JqZWN0KTtcbiAgICogICAgIGFzc2VydC5pc1NlYWxlZChmcm96ZW5PYmplY3QpO1xuICAgKlxuICAgKiBAbmFtZSBpc1NlYWxlZFxuICAgKiBAYWxpYXMgc2VhbGVkXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNTZWFsZWQgPSBmdW5jdGlvbiAob2JqLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5iZS5zZWFsZWQ7XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RTZWFsZWQob2JqZWN0KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaXMgX25vdF8gc2VhbGVkLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTm90U2VhbGVkKHt9KTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RTZWFsZWRcbiAgICogQGFsaWFzIG5vdFNlYWxlZFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90U2VhbGVkID0gZnVuY3Rpb24gKG9iaiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8ubm90LmJlLnNlYWxlZDtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5pc0Zyb3plbihvYmplY3QpXG4gICAqXG4gICAqIEFzc2VydHMgdGhhdCBgb2JqZWN0YCBpcyBmcm96ZW4gKGNhbm5vdCBoYXZlIG5ldyBwcm9wZXJ0aWVzIGFkZGVkIHRvIGl0XG4gICAqIGFuZCBpdHMgZXhpc3RpbmcgcHJvcGVydGllcyBjYW5ub3QgYmUgbW9kaWZpZWQpLlxuICAgKlxuICAgKiAgICAgdmFyIGZyb3plbk9iamVjdCA9IE9iamVjdC5mcmVlemUoe30pO1xuICAgKiAgICAgYXNzZXJ0LmZyb3plbihmcm96ZW5PYmplY3QpO1xuICAgKlxuICAgKiBAbmFtZSBpc0Zyb3plblxuICAgKiBAYWxpYXMgZnJvemVuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgX29wdGlvbmFsX1xuICAgKiBAbmFtZXNwYWNlIEFzc2VydFxuICAgKiBAYXBpIHB1YmxpY1xuICAgKi9cblxuICBhc3NlcnQuaXNGcm96ZW4gPSBmdW5jdGlvbiAob2JqLCBtc2cpIHtcbiAgICBuZXcgQXNzZXJ0aW9uKG9iaiwgbXNnKS50by5iZS5mcm96ZW47XG4gIH07XG5cbiAgLyoqXG4gICAqICMjIyAuaXNOb3RGcm96ZW4ob2JqZWN0KVxuICAgKlxuICAgKiBBc3NlcnRzIHRoYXQgYG9iamVjdGAgaXMgX25vdF8gZnJvemVuLlxuICAgKlxuICAgKiAgICAgYXNzZXJ0LmlzTm90RnJvemVuKHt9KTtcbiAgICpcbiAgICogQG5hbWUgaXNOb3RGcm96ZW5cbiAgICogQGFsaWFzIG5vdEZyb3plblxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIF9vcHRpb25hbF9cbiAgICogQG5hbWVzcGFjZSBBc3NlcnRcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgYXNzZXJ0LmlzTm90RnJvemVuID0gZnVuY3Rpb24gKG9iaiwgbXNnKSB7XG4gICAgbmV3IEFzc2VydGlvbihvYmosIG1zZykudG8ubm90LmJlLmZyb3plbjtcbiAgfTtcblxuICAvKiFcbiAgICogQWxpYXNlcy5cbiAgICovXG5cbiAgKGZ1bmN0aW9uIGFsaWFzKG5hbWUsIGFzKXtcbiAgICBhc3NlcnRbYXNdID0gYXNzZXJ0W25hbWVdO1xuICAgIHJldHVybiBhbGlhcztcbiAgfSlcbiAgKCdpc09rJywgJ29rJylcbiAgKCdpc05vdE9rJywgJ25vdE9rJylcbiAgKCd0aHJvd3MnLCAndGhyb3cnKVxuICAoJ3Rocm93cycsICdUaHJvdycpXG4gICgnaXNFeHRlbnNpYmxlJywgJ2V4dGVuc2libGUnKVxuICAoJ2lzTm90RXh0ZW5zaWJsZScsICdub3RFeHRlbnNpYmxlJylcbiAgKCdpc1NlYWxlZCcsICdzZWFsZWQnKVxuICAoJ2lzTm90U2VhbGVkJywgJ25vdFNlYWxlZCcpXG4gICgnaXNGcm96ZW4nLCAnZnJvemVuJylcbiAgKCdpc05vdEZyb3plbicsICdub3RGcm96ZW4nKTtcbn07XG4iLCIvKiFcbiAqIGNoYWlcbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjaGFpLCB1dGlsKSB7XG4gIGNoYWkuZXhwZWN0ID0gZnVuY3Rpb24gKHZhbCwgbWVzc2FnZSkge1xuICAgIHJldHVybiBuZXcgY2hhaS5Bc3NlcnRpb24odmFsLCBtZXNzYWdlKTtcbiAgfTtcblxuICAvKipcbiAgICogIyMjIC5mYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSwgW29wZXJhdG9yXSlcbiAgICpcbiAgICogVGhyb3cgYSBmYWlsdXJlLlxuICAgKlxuICAgKiBAbmFtZSBmYWlsXG4gICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgKiBAcGFyYW0ge01peGVkfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gb3BlcmF0b3JcbiAgICogQG5hbWVzcGFjZSBFeHBlY3RcbiAgICogQGFwaSBwdWJsaWNcbiAgICovXG5cbiAgY2hhaS5leHBlY3QuZmFpbCA9IGZ1bmN0aW9uIChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCBvcGVyYXRvcikge1xuICAgIG1lc3NhZ2UgPSBtZXNzYWdlIHx8ICdleHBlY3QuZmFpbCgpJztcbiAgICB0aHJvdyBuZXcgY2hhaS5Bc3NlcnRpb25FcnJvcihtZXNzYWdlLCB7XG4gICAgICAgIGFjdHVhbDogYWN0dWFsXG4gICAgICAsIGV4cGVjdGVkOiBleHBlY3RlZFxuICAgICAgLCBvcGVyYXRvcjogb3BlcmF0b3JcbiAgICB9LCBjaGFpLmV4cGVjdC5mYWlsKTtcbiAgfTtcbn07XG4iLCIvKiFcbiAqIGNoYWlcbiAqIENvcHlyaWdodChjKSAyMDExLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjaGFpLCB1dGlsKSB7XG4gIHZhciBBc3NlcnRpb24gPSBjaGFpLkFzc2VydGlvbjtcblxuICBmdW5jdGlvbiBsb2FkU2hvdWxkICgpIHtcbiAgICAvLyBleHBsaWNpdGx5IGRlZmluZSB0aGlzIG1ldGhvZCBhcyBmdW5jdGlvbiBhcyB0byBoYXZlIGl0J3MgbmFtZSB0byBpbmNsdWRlIGFzIGBzc2ZpYFxuICAgIGZ1bmN0aW9uIHNob3VsZEdldHRlcigpIHtcbiAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgU3RyaW5nIHx8IHRoaXMgaW5zdGFuY2VvZiBOdW1iZXIgfHwgdGhpcyBpbnN0YW5jZW9mIEJvb2xlYW4gKSB7XG4gICAgICAgIHJldHVybiBuZXcgQXNzZXJ0aW9uKHRoaXMudmFsdWVPZigpLCBudWxsLCBzaG91bGRHZXR0ZXIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBBc3NlcnRpb24odGhpcywgbnVsbCwgc2hvdWxkR2V0dGVyKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gc2hvdWxkU2V0dGVyKHZhbHVlKSB7XG4gICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYWlqcy9jaGFpL2lzc3Vlcy84NjogdGhpcyBtYWtlc1xuICAgICAgLy8gYHdoYXRldmVyLnNob3VsZCA9IHNvbWVWYWx1ZWAgYWN0dWFsbHkgc2V0IGBzb21lVmFsdWVgLCB3aGljaCBpc1xuICAgICAgLy8gZXNwZWNpYWxseSB1c2VmdWwgZm9yIGBnbG9iYWwuc2hvdWxkID0gcmVxdWlyZSgnY2hhaScpLnNob3VsZCgpYC5cbiAgICAgIC8vXG4gICAgICAvLyBOb3RlIHRoYXQgd2UgaGF2ZSB0byB1c2UgW1tEZWZpbmVQcm9wZXJ0eV1dIGluc3RlYWQgb2YgW1tQdXRdXVxuICAgICAgLy8gc2luY2Ugb3RoZXJ3aXNlIHdlIHdvdWxkIHRyaWdnZXIgdGhpcyB2ZXJ5IHNldHRlciFcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnc2hvdWxkJywge1xuICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWVcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBtb2RpZnkgT2JqZWN0LnByb3RvdHlwZSB0byBoYXZlIGBzaG91bGRgXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5wcm90b3R5cGUsICdzaG91bGQnLCB7XG4gICAgICBzZXQ6IHNob3VsZFNldHRlclxuICAgICAgLCBnZXQ6IHNob3VsZEdldHRlclxuICAgICAgLCBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KTtcblxuICAgIHZhciBzaG91bGQgPSB7fTtcblxuICAgIC8qKlxuICAgICAqICMjIyAuZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0sIFtvcGVyYXRvcl0pXG4gICAgICpcbiAgICAgKiBUaHJvdyBhIGZhaWx1cmUuXG4gICAgICpcbiAgICAgKiBAbmFtZSBmYWlsXG4gICAgICogQHBhcmFtIHtNaXhlZH0gYWN0dWFsXG4gICAgICogQHBhcmFtIHtNaXhlZH0gZXhwZWN0ZWRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBvcGVyYXRvclxuICAgICAqIEBuYW1lc3BhY2UgU2hvdWxkXG4gICAgICogQGFwaSBwdWJsaWNcbiAgICAgKi9cblxuICAgIHNob3VsZC5mYWlsID0gZnVuY3Rpb24gKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wZXJhdG9yKSB7XG4gICAgICBtZXNzYWdlID0gbWVzc2FnZSB8fCAnc2hvdWxkLmZhaWwoKSc7XG4gICAgICB0aHJvdyBuZXcgY2hhaS5Bc3NlcnRpb25FcnJvcihtZXNzYWdlLCB7XG4gICAgICAgICAgYWN0dWFsOiBhY3R1YWxcbiAgICAgICAgLCBleHBlY3RlZDogZXhwZWN0ZWRcbiAgICAgICAgLCBvcGVyYXRvcjogb3BlcmF0b3JcbiAgICAgIH0sIHNob3VsZC5mYWlsKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogIyMjIC5lcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBbbWVzc2FnZV0pXG4gICAgICpcbiAgICAgKiBBc3NlcnRzIG5vbi1zdHJpY3QgZXF1YWxpdHkgKGA9PWApIG9mIGBhY3R1YWxgIGFuZCBgZXhwZWN0ZWRgLlxuICAgICAqXG4gICAgICogICAgIHNob3VsZC5lcXVhbCgzLCAnMycsICc9PSBjb2VyY2VzIHZhbHVlcyB0byBzdHJpbmdzJyk7XG4gICAgICpcbiAgICAgKiBAbmFtZSBlcXVhbFxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICAgKiBAbmFtZXNwYWNlIFNob3VsZFxuICAgICAqIEBhcGkgcHVibGljXG4gICAgICovXG5cbiAgICBzaG91bGQuZXF1YWwgPSBmdW5jdGlvbiAodmFsMSwgdmFsMiwgbXNnKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKHZhbDEsIG1zZykudG8uZXF1YWwodmFsMik7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqICMjIyAudGhyb3coZnVuY3Rpb24sIFtjb25zdHJ1Y3Rvci9zdHJpbmcvcmVnZXhwXSwgW3N0cmluZy9yZWdleHBdLCBbbWVzc2FnZV0pXG4gICAgICpcbiAgICAgKiBBc3NlcnRzIHRoYXQgYGZ1bmN0aW9uYCB3aWxsIHRocm93IGFuIGVycm9yIHRoYXQgaXMgYW4gaW5zdGFuY2Ugb2ZcbiAgICAgKiBgY29uc3RydWN0b3JgLCBvciBhbHRlcm5hdGVseSB0aGF0IGl0IHdpbGwgdGhyb3cgYW4gZXJyb3Igd2l0aCBtZXNzYWdlXG4gICAgICogbWF0Y2hpbmcgYHJlZ2V4cGAuXG4gICAgICpcbiAgICAgKiAgICAgc2hvdWxkLnRocm93KGZuLCAnZnVuY3Rpb24gdGhyb3dzIGEgcmVmZXJlbmNlIGVycm9yJyk7XG4gICAgICogICAgIHNob3VsZC50aHJvdyhmbiwgL2Z1bmN0aW9uIHRocm93cyBhIHJlZmVyZW5jZSBlcnJvci8pO1xuICAgICAqICAgICBzaG91bGQudGhyb3coZm4sIFJlZmVyZW5jZUVycm9yKTtcbiAgICAgKiAgICAgc2hvdWxkLnRocm93KGZuLCBSZWZlcmVuY2VFcnJvciwgJ2Z1bmN0aW9uIHRocm93cyBhIHJlZmVyZW5jZSBlcnJvcicpO1xuICAgICAqICAgICBzaG91bGQudGhyb3coZm4sIFJlZmVyZW5jZUVycm9yLCAvZnVuY3Rpb24gdGhyb3dzIGEgcmVmZXJlbmNlIGVycm9yLyk7XG4gICAgICpcbiAgICAgKiBAbmFtZSB0aHJvd1xuICAgICAqIEBhbGlhcyBUaHJvd1xuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtFcnJvckNvbnN0cnVjdG9yfSBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7UmVnRXhwfSByZWdleHBcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRXJyb3IjRXJyb3JfdHlwZXNcbiAgICAgKiBAbmFtZXNwYWNlIFNob3VsZFxuICAgICAqIEBhcGkgcHVibGljXG4gICAgICovXG5cbiAgICBzaG91bGQuVGhyb3cgPSBmdW5jdGlvbiAoZm4sIGVycnQsIGVycnMsIG1zZykge1xuICAgICAgbmV3IEFzc2VydGlvbihmbiwgbXNnKS50by5UaHJvdyhlcnJ0LCBlcnJzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogIyMjIC5leGlzdFxuICAgICAqXG4gICAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgbmVpdGhlciBgbnVsbGAgbm9yIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogICAgIHZhciBmb28gPSAnaGknO1xuICAgICAqXG4gICAgICogICAgIHNob3VsZC5leGlzdChmb28sICdmb28gZXhpc3RzJyk7XG4gICAgICpcbiAgICAgKiBAbmFtZSBleGlzdFxuICAgICAqIEBuYW1lc3BhY2UgU2hvdWxkXG4gICAgICogQGFwaSBwdWJsaWNcbiAgICAgKi9cblxuICAgIHNob3VsZC5leGlzdCA9IGZ1bmN0aW9uICh2YWwsIG1zZykge1xuICAgICAgbmV3IEFzc2VydGlvbih2YWwsIG1zZykudG8uZXhpc3Q7XG4gICAgfVxuXG4gICAgLy8gbmVnYXRpb25cbiAgICBzaG91bGQubm90ID0ge31cblxuICAgIC8qKlxuICAgICAqICMjIyAubm90LmVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIFttZXNzYWdlXSlcbiAgICAgKlxuICAgICAqIEFzc2VydHMgbm9uLXN0cmljdCBpbmVxdWFsaXR5IChgIT1gKSBvZiBgYWN0dWFsYCBhbmQgYGV4cGVjdGVkYC5cbiAgICAgKlxuICAgICAqICAgICBzaG91bGQubm90LmVxdWFsKDMsIDQsICd0aGVzZSBudW1iZXJzIGFyZSBub3QgZXF1YWwnKTtcbiAgICAgKlxuICAgICAqIEBuYW1lIG5vdC5lcXVhbFxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IGFjdHVhbFxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IGV4cGVjdGVkXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICAgKiBAbmFtZXNwYWNlIFNob3VsZFxuICAgICAqIEBhcGkgcHVibGljXG4gICAgICovXG5cbiAgICBzaG91bGQubm90LmVxdWFsID0gZnVuY3Rpb24gKHZhbDEsIHZhbDIsIG1zZykge1xuICAgICAgbmV3IEFzc2VydGlvbih2YWwxLCBtc2cpLnRvLm5vdC5lcXVhbCh2YWwyKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogIyMjIC50aHJvdyhmdW5jdGlvbiwgW2NvbnN0cnVjdG9yL3JlZ2V4cF0sIFttZXNzYWdlXSlcbiAgICAgKlxuICAgICAqIEFzc2VydHMgdGhhdCBgZnVuY3Rpb25gIHdpbGwgX25vdF8gdGhyb3cgYW4gZXJyb3IgdGhhdCBpcyBhbiBpbnN0YW5jZSBvZlxuICAgICAqIGBjb25zdHJ1Y3RvcmAsIG9yIGFsdGVybmF0ZWx5IHRoYXQgaXQgd2lsbCBub3QgdGhyb3cgYW4gZXJyb3Igd2l0aCBtZXNzYWdlXG4gICAgICogbWF0Y2hpbmcgYHJlZ2V4cGAuXG4gICAgICpcbiAgICAgKiAgICAgc2hvdWxkLm5vdC50aHJvdyhmbiwgRXJyb3IsICdmdW5jdGlvbiBkb2VzIG5vdCB0aHJvdycpO1xuICAgICAqXG4gICAgICogQG5hbWUgbm90LnRocm93XG4gICAgICogQGFsaWFzIG5vdC5UaHJvd1xuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIHtFcnJvckNvbnN0cnVjdG9yfSBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7UmVnRXhwfSByZWdleHBcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZVxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRXJyb3IjRXJyb3JfdHlwZXNcbiAgICAgKiBAbmFtZXNwYWNlIFNob3VsZFxuICAgICAqIEBhcGkgcHVibGljXG4gICAgICovXG5cbiAgICBzaG91bGQubm90LlRocm93ID0gZnVuY3Rpb24gKGZuLCBlcnJ0LCBlcnJzLCBtc2cpIHtcbiAgICAgIG5ldyBBc3NlcnRpb24oZm4sIG1zZykudG8ubm90LlRocm93KGVycnQsIGVycnMpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiAjIyMgLm5vdC5leGlzdFxuICAgICAqXG4gICAgICogQXNzZXJ0cyB0aGF0IHRoZSB0YXJnZXQgaXMgbmVpdGhlciBgbnVsbGAgbm9yIGB1bmRlZmluZWRgLlxuICAgICAqXG4gICAgICogICAgIHZhciBiYXIgPSBudWxsO1xuICAgICAqXG4gICAgICogICAgIHNob3VsZC5ub3QuZXhpc3QoYmFyLCAnYmFyIGRvZXMgbm90IGV4aXN0Jyk7XG4gICAgICpcbiAgICAgKiBAbmFtZSBub3QuZXhpc3RcbiAgICAgKiBAbmFtZXNwYWNlIFNob3VsZFxuICAgICAqIEBhcGkgcHVibGljXG4gICAgICovXG5cbiAgICBzaG91bGQubm90LmV4aXN0ID0gZnVuY3Rpb24gKHZhbCwgbXNnKSB7XG4gICAgICBuZXcgQXNzZXJ0aW9uKHZhbCwgbXNnKS50by5ub3QuZXhpc3Q7XG4gICAgfVxuXG4gICAgc2hvdWxkWyd0aHJvdyddID0gc2hvdWxkWydUaHJvdyddO1xuICAgIHNob3VsZC5ub3RbJ3Rocm93J10gPSBzaG91bGQubm90WydUaHJvdyddO1xuXG4gICAgcmV0dXJuIHNob3VsZDtcbiAgfTtcblxuICBjaGFpLnNob3VsZCA9IGxvYWRTaG91bGQ7XG4gIGNoYWkuU2hvdWxkID0gbG9hZFNob3VsZDtcbn07XG4iLCIvKiFcbiAqIENoYWkgLSBhZGRDaGFpbmluZ01ldGhvZCB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzXG4gKi9cblxudmFyIHRyYW5zZmVyRmxhZ3MgPSByZXF1aXJlKCcuL3RyYW5zZmVyRmxhZ3MnKTtcbnZhciBmbGFnID0gcmVxdWlyZSgnLi9mbGFnJyk7XG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJyk7XG5cbi8qIVxuICogTW9kdWxlIHZhcmlhYmxlc1xuICovXG5cbi8vIENoZWNrIHdoZXRoZXIgYF9fcHJvdG9fX2AgaXMgc3VwcG9ydGVkXG52YXIgaGFzUHJvdG9TdXBwb3J0ID0gJ19fcHJvdG9fXycgaW4gT2JqZWN0O1xuXG4vLyBXaXRob3V0IGBfX3Byb3RvX19gIHN1cHBvcnQsIHRoaXMgbW9kdWxlIHdpbGwgbmVlZCB0byBhZGQgcHJvcGVydGllcyB0byBhIGZ1bmN0aW9uLlxuLy8gSG93ZXZlciwgc29tZSBGdW5jdGlvbi5wcm90b3R5cGUgbWV0aG9kcyBjYW5ub3QgYmUgb3ZlcndyaXR0ZW4sXG4vLyBhbmQgdGhlcmUgc2VlbXMgbm8gZWFzeSBjcm9zcy1wbGF0Zm9ybSB3YXkgdG8gZGV0ZWN0IHRoZW0gKEBzZWUgY2hhaWpzL2NoYWkvaXNzdWVzLzY5KS5cbnZhciBleGNsdWRlTmFtZXMgPSAvXig/Omxlbmd0aHxuYW1lfGFyZ3VtZW50c3xjYWxsZXIpJC87XG5cbi8vIENhY2hlIGBGdW5jdGlvbmAgcHJvcGVydGllc1xudmFyIGNhbGwgID0gRnVuY3Rpb24ucHJvdG90eXBlLmNhbGwsXG4gICAgYXBwbHkgPSBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHk7XG5cbi8qKlxuICogIyMjIGFkZENoYWluYWJsZU1ldGhvZCAoY3R4LCBuYW1lLCBtZXRob2QsIGNoYWluaW5nQmVoYXZpb3IpXG4gKlxuICogQWRkcyBhIG1ldGhvZCB0byBhbiBvYmplY3QsIHN1Y2ggdGhhdCB0aGUgbWV0aG9kIGNhbiBhbHNvIGJlIGNoYWluZWQuXG4gKlxuICogICAgIHV0aWxzLmFkZENoYWluYWJsZU1ldGhvZChjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsICdmb28nLCBmdW5jdGlvbiAoc3RyKSB7XG4gKiAgICAgICB2YXIgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gKiAgICAgICBuZXcgY2hhaS5Bc3NlcnRpb24ob2JqKS50by5iZS5lcXVhbChzdHIpO1xuICogICAgIH0pO1xuICpcbiAqIENhbiBhbHNvIGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGZyb20gYGNoYWkuQXNzZXJ0aW9uYC5cbiAqXG4gKiAgICAgY2hhaS5Bc3NlcnRpb24uYWRkQ2hhaW5hYmxlTWV0aG9kKCdmb28nLCBmbiwgY2hhaW5pbmdCZWhhdmlvcik7XG4gKlxuICogVGhlIHJlc3VsdCBjYW4gdGhlbiBiZSB1c2VkIGFzIGJvdGggYSBtZXRob2QgYXNzZXJ0aW9uLCBleGVjdXRpbmcgYm90aCBgbWV0aG9kYCBhbmRcbiAqIGBjaGFpbmluZ0JlaGF2aW9yYCwgb3IgYXMgYSBsYW5ndWFnZSBjaGFpbiwgd2hpY2ggb25seSBleGVjdXRlcyBgY2hhaW5pbmdCZWhhdmlvcmAuXG4gKlxuICogICAgIGV4cGVjdChmb29TdHIpLnRvLmJlLmZvbygnYmFyJyk7XG4gKiAgICAgZXhwZWN0KGZvb1N0cikudG8uYmUuZm9vLmVxdWFsKCdmb28nKTtcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY3R4IG9iamVjdCB0byB3aGljaCB0aGUgbWV0aG9kIGlzIGFkZGVkXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBvZiBtZXRob2QgdG8gYWRkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXRob2QgZnVuY3Rpb24gdG8gYmUgdXNlZCBmb3IgYG5hbWVgLCB3aGVuIGNhbGxlZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2hhaW5pbmdCZWhhdmlvciBmdW5jdGlvbiB0byBiZSBjYWxsZWQgZXZlcnkgdGltZSB0aGUgcHJvcGVydHkgaXMgYWNjZXNzZWRcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGFkZENoYWluYWJsZU1ldGhvZFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjdHgsIG5hbWUsIG1ldGhvZCwgY2hhaW5pbmdCZWhhdmlvcikge1xuICBpZiAodHlwZW9mIGNoYWluaW5nQmVoYXZpb3IgIT09ICdmdW5jdGlvbicpIHtcbiAgICBjaGFpbmluZ0JlaGF2aW9yID0gZnVuY3Rpb24gKCkgeyB9O1xuICB9XG5cbiAgdmFyIGNoYWluYWJsZUJlaGF2aW9yID0ge1xuICAgICAgbWV0aG9kOiBtZXRob2RcbiAgICAsIGNoYWluaW5nQmVoYXZpb3I6IGNoYWluaW5nQmVoYXZpb3JcbiAgfTtcblxuICAvLyBzYXZlIHRoZSBtZXRob2RzIHNvIHdlIGNhbiBvdmVyd3JpdGUgdGhlbSBsYXRlciwgaWYgd2UgbmVlZCB0by5cbiAgaWYgKCFjdHguX19tZXRob2RzKSB7XG4gICAgY3R4Ll9fbWV0aG9kcyA9IHt9O1xuICB9XG4gIGN0eC5fX21ldGhvZHNbbmFtZV0gPSBjaGFpbmFibGVCZWhhdmlvcjtcblxuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBuYW1lLFxuICAgIHsgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNoYWluYWJsZUJlaGF2aW9yLmNoYWluaW5nQmVoYXZpb3IuY2FsbCh0aGlzKTtcblxuICAgICAgICB2YXIgYXNzZXJ0ID0gZnVuY3Rpb24gYXNzZXJ0KCkge1xuICAgICAgICAgIHZhciBvbGRfc3NmaSA9IGZsYWcodGhpcywgJ3NzZmknKTtcbiAgICAgICAgICBpZiAob2xkX3NzZmkgJiYgY29uZmlnLmluY2x1ZGVTdGFjayA9PT0gZmFsc2UpXG4gICAgICAgICAgICBmbGFnKHRoaXMsICdzc2ZpJywgYXNzZXJ0KTtcbiAgICAgICAgICB2YXIgcmVzdWx0ID0gY2hhaW5hYmxlQmVoYXZpb3IubWV0aG9kLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gdGhpcyA6IHJlc3VsdDtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBVc2UgYF9fcHJvdG9fX2AgaWYgYXZhaWxhYmxlXG4gICAgICAgIGlmIChoYXNQcm90b1N1cHBvcnQpIHtcbiAgICAgICAgICAvLyBJbmhlcml0IGFsbCBwcm9wZXJ0aWVzIGZyb20gdGhlIG9iamVjdCBieSByZXBsYWNpbmcgdGhlIGBGdW5jdGlvbmAgcHJvdG90eXBlXG4gICAgICAgICAgdmFyIHByb3RvdHlwZSA9IGFzc2VydC5fX3Byb3RvX18gPSBPYmplY3QuY3JlYXRlKHRoaXMpO1xuICAgICAgICAgIC8vIFJlc3RvcmUgdGhlIGBjYWxsYCBhbmQgYGFwcGx5YCBtZXRob2RzIGZyb20gYEZ1bmN0aW9uYFxuICAgICAgICAgIHByb3RvdHlwZS5jYWxsID0gY2FsbDtcbiAgICAgICAgICBwcm90b3R5cGUuYXBwbHkgPSBhcHBseTtcbiAgICAgICAgfVxuICAgICAgICAvLyBPdGhlcndpc2UsIHJlZGVmaW5lIGFsbCBwcm9wZXJ0aWVzIChzbG93ISlcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdmFyIGFzc2VydGVyTmFtZXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhjdHgpO1xuICAgICAgICAgIGFzc2VydGVyTmFtZXMuZm9yRWFjaChmdW5jdGlvbiAoYXNzZXJ0ZXJOYW1lKSB7XG4gICAgICAgICAgICBpZiAoIWV4Y2x1ZGVOYW1lcy50ZXN0KGFzc2VydGVyTmFtZSkpIHtcbiAgICAgICAgICAgICAgdmFyIHBkID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihjdHgsIGFzc2VydGVyTmFtZSk7XG4gICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhc3NlcnQsIGFzc2VydGVyTmFtZSwgcGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJhbnNmZXJGbGFncyh0aGlzLCBhc3NlcnQpO1xuICAgICAgICByZXR1cm4gYXNzZXJ0O1xuICAgICAgfVxuICAgICwgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pO1xufTtcbiIsIi8qIVxuICogQ2hhaSAtIGFkZE1ldGhvZCB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxudmFyIGNvbmZpZyA9IHJlcXVpcmUoJy4uL2NvbmZpZycpO1xuXG4vKipcbiAqICMjIyAuYWRkTWV0aG9kIChjdHgsIG5hbWUsIG1ldGhvZClcbiAqXG4gKiBBZGRzIGEgbWV0aG9kIHRvIHRoZSBwcm90b3R5cGUgb2YgYW4gb2JqZWN0LlxuICpcbiAqICAgICB1dGlscy5hZGRNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCAnZm9vJywgZnVuY3Rpb24gKHN0cikge1xuICogICAgICAgdmFyIG9iaiA9IHV0aWxzLmZsYWcodGhpcywgJ29iamVjdCcpO1xuICogICAgICAgbmV3IGNoYWkuQXNzZXJ0aW9uKG9iaikudG8uYmUuZXF1YWwoc3RyKTtcbiAqICAgICB9KTtcbiAqXG4gKiBDYW4gYWxzbyBiZSBhY2Nlc3NlZCBkaXJlY3RseSBmcm9tIGBjaGFpLkFzc2VydGlvbmAuXG4gKlxuICogICAgIGNoYWkuQXNzZXJ0aW9uLmFkZE1ldGhvZCgnZm9vJywgZm4pO1xuICpcbiAqIFRoZW4gY2FuIGJlIHVzZWQgYXMgYW55IG90aGVyIGFzc2VydGlvbi5cbiAqXG4gKiAgICAgZXhwZWN0KGZvb1N0cikudG8uYmUuZm9vKCdiYXInKTtcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY3R4IG9iamVjdCB0byB3aGljaCB0aGUgbWV0aG9kIGlzIGFkZGVkXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBvZiBtZXRob2QgdG8gYWRkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXRob2QgZnVuY3Rpb24gdG8gYmUgdXNlZCBmb3IgbmFtZVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgYWRkTWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjdHgsIG5hbWUsIG1ldGhvZCkge1xuICBjdHhbbmFtZV0gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG9sZF9zc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpO1xuICAgIGlmIChvbGRfc3NmaSAmJiBjb25maWcuaW5jbHVkZVN0YWNrID09PSBmYWxzZSlcbiAgICAgIGZsYWcodGhpcywgJ3NzZmknLCBjdHhbbmFtZV0pO1xuICAgIHZhciByZXN1bHQgPSBtZXRob2QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICByZXR1cm4gcmVzdWx0ID09PSB1bmRlZmluZWQgPyB0aGlzIDogcmVzdWx0O1xuICB9O1xufTtcbiIsIi8qIVxuICogQ2hhaSAtIGFkZFByb3BlcnR5IHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJyk7XG52YXIgZmxhZyA9IHJlcXVpcmUoJy4vZmxhZycpO1xuXG4vKipcbiAqICMjIyBhZGRQcm9wZXJ0eSAoY3R4LCBuYW1lLCBnZXR0ZXIpXG4gKlxuICogQWRkcyBhIHByb3BlcnR5IHRvIHRoZSBwcm90b3R5cGUgb2YgYW4gb2JqZWN0LlxuICpcbiAqICAgICB1dGlscy5hZGRQcm9wZXJ0eShjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsICdmb28nLCBmdW5jdGlvbiAoKSB7XG4gKiAgICAgICB2YXIgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gKiAgICAgICBuZXcgY2hhaS5Bc3NlcnRpb24ob2JqKS50by5iZS5pbnN0YW5jZW9mKEZvbyk7XG4gKiAgICAgfSk7XG4gKlxuICogQ2FuIGFsc28gYmUgYWNjZXNzZWQgZGlyZWN0bHkgZnJvbSBgY2hhaS5Bc3NlcnRpb25gLlxuICpcbiAqICAgICBjaGFpLkFzc2VydGlvbi5hZGRQcm9wZXJ0eSgnZm9vJywgZm4pO1xuICpcbiAqIFRoZW4gY2FuIGJlIHVzZWQgYXMgYW55IG90aGVyIGFzc2VydGlvbi5cbiAqXG4gKiAgICAgZXhwZWN0KG15Rm9vKS50by5iZS5mb287XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGN0eCBvYmplY3QgdG8gd2hpY2ggdGhlIHByb3BlcnR5IGlzIGFkZGVkXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBvZiBwcm9wZXJ0eSB0byBhZGRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGdldHRlciBmdW5jdGlvbiB0byBiZSB1c2VkIGZvciBuYW1lXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBhZGRQcm9wZXJ0eVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjdHgsIG5hbWUsIGdldHRlcikge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY3R4LCBuYW1lLFxuICAgIHsgZ2V0OiBmdW5jdGlvbiBhZGRQcm9wZXJ0eSgpIHtcbiAgICAgICAgdmFyIG9sZF9zc2ZpID0gZmxhZyh0aGlzLCAnc3NmaScpO1xuICAgICAgICBpZiAob2xkX3NzZmkgJiYgY29uZmlnLmluY2x1ZGVTdGFjayA9PT0gZmFsc2UpXG4gICAgICAgICAgZmxhZyh0aGlzLCAnc3NmaScsIGFkZFByb3BlcnR5KTtcblxuICAgICAgICB2YXIgcmVzdWx0ID0gZ2V0dGVyLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCA/IHRoaXMgOiByZXN1bHQ7XG4gICAgICB9XG4gICAgLCBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gZXhwZWN0VHlwZXMgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIGV4cGVjdFR5cGVzKG9iaiwgdHlwZXMpXG4gKlxuICogRW5zdXJlcyB0aGF0IHRoZSBvYmplY3QgYmVpbmcgdGVzdGVkIGFnYWluc3QgaXMgb2YgYSB2YWxpZCB0eXBlLlxuICpcbiAqICAgICB1dGlscy5leHBlY3RUeXBlcyh0aGlzLCBbJ2FycmF5JywgJ29iamVjdCcsICdzdHJpbmcnXSk7XG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqIGNvbnN0cnVjdGVkIEFzc2VydGlvblxuICogQHBhcmFtIHtBcnJheX0gdHlwZSBBIGxpc3Qgb2YgYWxsb3dlZCB0eXBlcyBmb3IgdGhpcyBhc3NlcnRpb25cbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGV4cGVjdFR5cGVzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnZhciBBc3NlcnRpb25FcnJvciA9IHJlcXVpcmUoJ2Fzc2VydGlvbi1lcnJvcicpO1xudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcbnZhciB0eXBlID0gcmVxdWlyZSgndHlwZS1kZXRlY3QnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqLCB0eXBlcykge1xuICB2YXIgb2JqID0gZmxhZyhvYmosICdvYmplY3QnKTtcbiAgdHlwZXMgPSB0eXBlcy5tYXAoZnVuY3Rpb24gKHQpIHsgcmV0dXJuIHQudG9Mb3dlckNhc2UoKTsgfSk7XG4gIHR5cGVzLnNvcnQoKTtcblxuICAvLyBUcmFuc2Zvcm1zIFsnbG9yZW0nLCAnaXBzdW0nXSBpbnRvICdhIGxpcnVtLCBvciBhbiBpcHN1bSdcbiAgdmFyIHN0ciA9IHR5cGVzLm1hcChmdW5jdGlvbiAodCwgaW5kZXgpIHtcbiAgICB2YXIgYXJ0ID0gflsgJ2EnLCAnZScsICdpJywgJ28nLCAndScgXS5pbmRleE9mKHQuY2hhckF0KDApKSA/ICdhbicgOiAnYSc7XG4gICAgdmFyIG9yID0gdHlwZXMubGVuZ3RoID4gMSAmJiBpbmRleCA9PT0gdHlwZXMubGVuZ3RoIC0gMSA/ICdvciAnIDogJyc7XG4gICAgcmV0dXJuIG9yICsgYXJ0ICsgJyAnICsgdDtcbiAgfSkuam9pbignLCAnKTtcblxuICBpZiAoIXR5cGVzLnNvbWUoZnVuY3Rpb24gKGV4cGVjdGVkKSB7IHJldHVybiB0eXBlKG9iaikgPT09IGV4cGVjdGVkOyB9KSkge1xuICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihcbiAgICAgICdvYmplY3QgdGVzdGVkIG11c3QgYmUgJyArIHN0ciArICcsIGJ1dCAnICsgdHlwZShvYmopICsgJyBnaXZlbidcbiAgICApO1xuICB9XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gZmxhZyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyoqXG4gKiAjIyMgZmxhZyhvYmplY3QsIGtleSwgW3ZhbHVlXSlcbiAqXG4gKiBHZXQgb3Igc2V0IGEgZmxhZyB2YWx1ZSBvbiBhbiBvYmplY3QuIElmIGFcbiAqIHZhbHVlIGlzIHByb3ZpZGVkIGl0IHdpbGwgYmUgc2V0LCBlbHNlIGl0IHdpbGxcbiAqIHJldHVybiB0aGUgY3VycmVudGx5IHNldCB2YWx1ZSBvciBgdW5kZWZpbmVkYCBpZlxuICogdGhlIHZhbHVlIGlzIG5vdCBzZXQuXG4gKlxuICogICAgIHV0aWxzLmZsYWcodGhpcywgJ2ZvbycsICdiYXInKTsgLy8gc2V0dGVyXG4gKiAgICAgdXRpbHMuZmxhZyh0aGlzLCAnZm9vJyk7IC8vIGdldHRlciwgcmV0dXJucyBgYmFyYFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgY29uc3RydWN0ZWQgQXNzZXJ0aW9uXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gKiBAcGFyYW0ge01peGVkfSB2YWx1ZSAob3B0aW9uYWwpXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBmbGFnXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmosIGtleSwgdmFsdWUpIHtcbiAgdmFyIGZsYWdzID0gb2JqLl9fZmxhZ3MgfHwgKG9iai5fX2ZsYWdzID0gT2JqZWN0LmNyZWF0ZShudWxsKSk7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgZmxhZ3Nba2V5XSA9IHZhbHVlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmbGFnc1trZXldO1xuICB9XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gZ2V0QWN0dWFsIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKipcbiAqICMgZ2V0QWN0dWFsKG9iamVjdCwgW2FjdHVhbF0pXG4gKlxuICogUmV0dXJucyB0aGUgYGFjdHVhbGAgdmFsdWUgZm9yIGFuIEFzc2VydGlvblxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgKGNvbnN0cnVjdGVkIEFzc2VydGlvbilcbiAqIEBwYXJhbSB7QXJndW1lbnRzfSBjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUuYXNzZXJ0IGFyZ3VtZW50c1xuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZ2V0QWN0dWFsXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqLCBhcmdzKSB7XG4gIHJldHVybiBhcmdzLmxlbmd0aCA+IDQgPyBhcmdzWzRdIDogb2JqLl9vYmo7XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gZ2V0RW51bWVyYWJsZVByb3BlcnRpZXMgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIC5nZXRFbnVtZXJhYmxlUHJvcGVydGllcyhvYmplY3QpXG4gKlxuICogVGhpcyBhbGxvd3MgdGhlIHJldHJpZXZhbCBvZiBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGFuIG9iamVjdCxcbiAqIGluaGVyaXRlZCBvciBub3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdFxuICogQHJldHVybnMge0FycmF5fVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZ2V0RW51bWVyYWJsZVByb3BlcnRpZXNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRFbnVtZXJhYmxlUHJvcGVydGllcyhvYmplY3QpIHtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBmb3IgKHZhciBuYW1lIGluIG9iamVjdCkge1xuICAgIHJlc3VsdC5wdXNoKG5hbWUpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gbWVzc2FnZSBjb21wb3NpdGlvbiB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNb2R1bGUgZGVwZW5kYW5jaWVzXG4gKi9cblxudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKVxuICAsIGdldEFjdHVhbCA9IHJlcXVpcmUoJy4vZ2V0QWN0dWFsJylcbiAgLCBpbnNwZWN0ID0gcmVxdWlyZSgnLi9pbnNwZWN0JylcbiAgLCBvYmpEaXNwbGF5ID0gcmVxdWlyZSgnLi9vYmpEaXNwbGF5Jyk7XG5cbi8qKlxuICogIyMjIC5nZXRNZXNzYWdlKG9iamVjdCwgbWVzc2FnZSwgbmVnYXRlTWVzc2FnZSlcbiAqXG4gKiBDb25zdHJ1Y3QgdGhlIGVycm9yIG1lc3NhZ2UgYmFzZWQgb24gZmxhZ3NcbiAqIGFuZCB0ZW1wbGF0ZSB0YWdzLiBUZW1wbGF0ZSB0YWdzIHdpbGwgcmV0dXJuXG4gKiBhIHN0cmluZ2lmaWVkIGluc3BlY3Rpb24gb2YgdGhlIG9iamVjdCByZWZlcmVuY2VkLlxuICpcbiAqIE1lc3NhZ2UgdGVtcGxhdGUgdGFnczpcbiAqIC0gYCN7dGhpc31gIGN1cnJlbnQgYXNzZXJ0ZWQgb2JqZWN0XG4gKiAtIGAje2FjdH1gIGFjdHVhbCB2YWx1ZVxuICogLSBgI3tleHB9YCBleHBlY3RlZCB2YWx1ZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgKGNvbnN0cnVjdGVkIEFzc2VydGlvbilcbiAqIEBwYXJhbSB7QXJndW1lbnRzfSBjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUuYXNzZXJ0IGFyZ3VtZW50c1xuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZ2V0TWVzc2FnZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmosIGFyZ3MpIHtcbiAgdmFyIG5lZ2F0ZSA9IGZsYWcob2JqLCAnbmVnYXRlJylcbiAgICAsIHZhbCA9IGZsYWcob2JqLCAnb2JqZWN0JylcbiAgICAsIGV4cGVjdGVkID0gYXJnc1szXVxuICAgICwgYWN0dWFsID0gZ2V0QWN0dWFsKG9iaiwgYXJncylcbiAgICAsIG1zZyA9IG5lZ2F0ZSA/IGFyZ3NbMl0gOiBhcmdzWzFdXG4gICAgLCBmbGFnTXNnID0gZmxhZyhvYmosICdtZXNzYWdlJyk7XG5cbiAgaWYodHlwZW9mIG1zZyA9PT0gXCJmdW5jdGlvblwiKSBtc2cgPSBtc2coKTtcbiAgbXNnID0gbXNnIHx8ICcnO1xuICBtc2cgPSBtc2dcbiAgICAucmVwbGFjZSgvI1xce3RoaXNcXH0vZywgZnVuY3Rpb24gKCkgeyByZXR1cm4gb2JqRGlzcGxheSh2YWwpOyB9KVxuICAgIC5yZXBsYWNlKC8jXFx7YWN0XFx9L2csIGZ1bmN0aW9uICgpIHsgcmV0dXJuIG9iakRpc3BsYXkoYWN0dWFsKTsgfSlcbiAgICAucmVwbGFjZSgvI1xce2V4cFxcfS9nLCBmdW5jdGlvbiAoKSB7IHJldHVybiBvYmpEaXNwbGF5KGV4cGVjdGVkKTsgfSk7XG5cbiAgcmV0dXJuIGZsYWdNc2cgPyBmbGFnTXNnICsgJzogJyArIG1zZyA6IG1zZztcbn07XG4iLCIvKiFcbiAqIENoYWkgLSBnZXROYW1lIHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKipcbiAqICMgZ2V0TmFtZShmdW5jKVxuICpcbiAqIEdldHMgdGhlIG5hbWUgb2YgYSBmdW5jdGlvbiwgaW4gYSBjcm9zcy1icm93c2VyIHdheS5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBhIGZ1bmN0aW9uICh1c3VhbGx5IGEgY29uc3RydWN0b3IpXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBnZXROYW1lXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZnVuYykge1xuICBpZiAoZnVuYy5uYW1lKSByZXR1cm4gZnVuYy5uYW1lO1xuXG4gIHZhciBtYXRjaCA9IC9eXFxzP2Z1bmN0aW9uIChbXihdKilcXCgvLmV4ZWMoZnVuYyk7XG4gIHJldHVybiBtYXRjaCAmJiBtYXRjaFsxXSA/IG1hdGNoWzFdIDogXCJcIjtcbn07XG4iLCIvKiFcbiAqIENoYWkgLSBnZXRQYXRoSW5mbyB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxudmFyIGhhc1Byb3BlcnR5ID0gcmVxdWlyZSgnLi9oYXNQcm9wZXJ0eScpO1xuXG4vKipcbiAqICMjIyAuZ2V0UGF0aEluZm8ocGF0aCwgb2JqZWN0KVxuICpcbiAqIFRoaXMgYWxsb3dzIHRoZSByZXRyaWV2YWwgb2YgcHJvcGVydHkgaW5mbyBpbiBhblxuICogb2JqZWN0IGdpdmVuIGEgc3RyaW5nIHBhdGguXG4gKlxuICogVGhlIHBhdGggaW5mbyBjb25zaXN0cyBvZiBhbiBvYmplY3Qgd2l0aCB0aGVcbiAqIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICpcbiAqICogcGFyZW50IC0gVGhlIHBhcmVudCBvYmplY3Qgb2YgdGhlIHByb3BlcnR5IHJlZmVyZW5jZWQgYnkgYHBhdGhgXG4gKiAqIG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZmluYWwgcHJvcGVydHksIGEgbnVtYmVyIGlmIGl0IHdhcyBhbiBhcnJheSBpbmRleGVyXG4gKiAqIHZhbHVlIC0gVGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSwgaWYgaXQgZXhpc3RzLCBvdGhlcndpc2UgYHVuZGVmaW5lZGBcbiAqICogZXhpc3RzIC0gV2hldGhlciB0aGUgcHJvcGVydHkgZXhpc3RzIG9yIG5vdFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gKiBAcmV0dXJucyB7T2JqZWN0fSBpbmZvXG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBnZXRQYXRoSW5mb1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGdldFBhdGhJbmZvKHBhdGgsIG9iaikge1xuICB2YXIgcGFyc2VkID0gcGFyc2VQYXRoKHBhdGgpLFxuICAgICAgbGFzdCA9IHBhcnNlZFtwYXJzZWQubGVuZ3RoIC0gMV07XG5cbiAgdmFyIGluZm8gPSB7XG4gICAgcGFyZW50OiBwYXJzZWQubGVuZ3RoID4gMSA/IF9nZXRQYXRoVmFsdWUocGFyc2VkLCBvYmosIHBhcnNlZC5sZW5ndGggLSAxKSA6IG9iaixcbiAgICBuYW1lOiBsYXN0LnAgfHwgbGFzdC5pLFxuICAgIHZhbHVlOiBfZ2V0UGF0aFZhbHVlKHBhcnNlZCwgb2JqKVxuICB9O1xuICBpbmZvLmV4aXN0cyA9IGhhc1Byb3BlcnR5KGluZm8ubmFtZSwgaW5mby5wYXJlbnQpO1xuXG4gIHJldHVybiBpbmZvO1xufTtcblxuXG4vKiFcbiAqICMjIHBhcnNlUGF0aChwYXRoKVxuICpcbiAqIEhlbHBlciBmdW5jdGlvbiB1c2VkIHRvIHBhcnNlIHN0cmluZyBvYmplY3RcbiAqIHBhdGhzLiBVc2UgaW4gY29uanVuY3Rpb24gd2l0aCBgX2dldFBhdGhWYWx1ZWAuXG4gKlxuICogICAgICB2YXIgcGFyc2VkID0gcGFyc2VQYXRoKCdteW9iamVjdC5wcm9wZXJ0eS5zdWJwcm9wJyk7XG4gKlxuICogIyMjIFBhdGhzOlxuICpcbiAqICogQ2FuIGJlIGFzIG5lYXIgaW5maW5pdGVseSBkZWVwIGFuZCBuZXN0ZWRcbiAqICogQXJyYXlzIGFyZSBhbHNvIHZhbGlkIHVzaW5nIHRoZSBmb3JtYWwgYG15b2JqZWN0LmRvY3VtZW50WzNdLnByb3BlcnR5YC5cbiAqICogTGl0ZXJhbCBkb3RzIGFuZCBicmFja2V0cyAobm90IGRlbGltaXRlcikgbXVzdCBiZSBiYWNrc2xhc2gtZXNjYXBlZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcGF0aFxuICogQHJldHVybnMge09iamVjdH0gcGFyc2VkXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBwYXJzZVBhdGggKHBhdGgpIHtcbiAgdmFyIHN0ciA9IHBhdGgucmVwbGFjZSgvKFteXFxcXF0pXFxbL2csICckMS5bJylcbiAgICAsIHBhcnRzID0gc3RyLm1hdGNoKC8oXFxcXFxcLnxbXi5dKz8pKy9nKTtcbiAgcmV0dXJuIHBhcnRzLm1hcChmdW5jdGlvbiAodmFsdWUpIHtcbiAgICB2YXIgcmUgPSAvXlxcWyhcXGQrKVxcXSQvXG4gICAgICAsIG1BcnIgPSByZS5leGVjKHZhbHVlKTtcbiAgICBpZiAobUFycikgcmV0dXJuIHsgaTogcGFyc2VGbG9hdChtQXJyWzFdKSB9O1xuICAgIGVsc2UgcmV0dXJuIHsgcDogdmFsdWUucmVwbGFjZSgvXFxcXChbLlxcW1xcXV0pL2csICckMScpIH07XG4gIH0pO1xufVxuXG5cbi8qIVxuICogIyMgX2dldFBhdGhWYWx1ZShwYXJzZWQsIG9iailcbiAqXG4gKiBIZWxwZXIgY29tcGFuaW9uIGZ1bmN0aW9uIGZvciBgLnBhcnNlUGF0aGAgdGhhdCByZXR1cm5zXG4gKiB0aGUgdmFsdWUgbG9jYXRlZCBhdCB0aGUgcGFyc2VkIGFkZHJlc3MuXG4gKlxuICogICAgICB2YXIgdmFsdWUgPSBnZXRQYXRoVmFsdWUocGFyc2VkLCBvYmopO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYXJzZWQgZGVmaW5pdGlvbiBmcm9tIGBwYXJzZVBhdGhgLlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCB0byBzZWFyY2ggYWdhaW5zdFxuICogQHBhcmFtIHtOdW1iZXJ9IG9iamVjdCB0byBzZWFyY2ggYWdhaW5zdFxuICogQHJldHVybnMge09iamVjdHxVbmRlZmluZWR9IHZhbHVlXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBfZ2V0UGF0aFZhbHVlIChwYXJzZWQsIG9iaiwgaW5kZXgpIHtcbiAgdmFyIHRtcCA9IG9ialxuICAgICwgcmVzO1xuXG4gIGluZGV4ID0gKGluZGV4ID09PSB1bmRlZmluZWQgPyBwYXJzZWQubGVuZ3RoIDogaW5kZXgpO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsID0gaW5kZXg7IGkgPCBsOyBpKyspIHtcbiAgICB2YXIgcGFydCA9IHBhcnNlZFtpXTtcbiAgICBpZiAodG1wKSB7XG4gICAgICBpZiAoJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiBwYXJ0LnApXG4gICAgICAgIHRtcCA9IHRtcFtwYXJ0LnBdO1xuICAgICAgZWxzZSBpZiAoJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiBwYXJ0LmkpXG4gICAgICAgIHRtcCA9IHRtcFtwYXJ0LmldO1xuICAgICAgaWYgKGkgPT0gKGwgLSAxKSkgcmVzID0gdG1wO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXMgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXM7XG59XG4iLCIvKiFcbiAqIENoYWkgLSBnZXRQYXRoVmFsdWUgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2xvZ2ljYWxwYXJhZG94L2ZpbHRyXG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG52YXIgZ2V0UGF0aEluZm8gPSByZXF1aXJlKCcuL2dldFBhdGhJbmZvJyk7XG5cbi8qKlxuICogIyMjIC5nZXRQYXRoVmFsdWUocGF0aCwgb2JqZWN0KVxuICpcbiAqIFRoaXMgYWxsb3dzIHRoZSByZXRyaWV2YWwgb2YgdmFsdWVzIGluIGFuXG4gKiBvYmplY3QgZ2l2ZW4gYSBzdHJpbmcgcGF0aC5cbiAqXG4gKiAgICAgdmFyIG9iaiA9IHtcbiAqICAgICAgICAgcHJvcDE6IHtcbiAqICAgICAgICAgICAgIGFycjogWydhJywgJ2InLCAnYyddXG4gKiAgICAgICAgICAgLCBzdHI6ICdIZWxsbydcbiAqICAgICAgICAgfVxuICogICAgICAgLCBwcm9wMjoge1xuICogICAgICAgICAgICAgYXJyOiBbIHsgbmVzdGVkOiAnVW5pdmVyc2UnIH0gXVxuICogICAgICAgICAgICwgc3RyOiAnSGVsbG8gYWdhaW4hJ1xuICogICAgICAgICB9XG4gKiAgICAgfVxuICpcbiAqIFRoZSBmb2xsb3dpbmcgd291bGQgYmUgdGhlIHJlc3VsdHMuXG4gKlxuICogICAgIGdldFBhdGhWYWx1ZSgncHJvcDEuc3RyJywgb2JqKTsgLy8gSGVsbG9cbiAqICAgICBnZXRQYXRoVmFsdWUoJ3Byb3AxLmF0dFsyXScsIG9iaik7IC8vIGJcbiAqICAgICBnZXRQYXRoVmFsdWUoJ3Byb3AyLmFyclswXS5uZXN0ZWQnLCBvYmopOyAvLyBVbml2ZXJzZVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0XG4gKiBAcmV0dXJucyB7T2JqZWN0fSB2YWx1ZSBvciBgdW5kZWZpbmVkYFxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgZ2V0UGF0aFZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHBhdGgsIG9iaikge1xuICB2YXIgaW5mbyA9IGdldFBhdGhJbmZvKHBhdGgsIG9iaik7XG4gIHJldHVybiBpbmZvLnZhbHVlO1xufTtcbiIsIi8qIVxuICogQ2hhaSAtIGdldFByb3BlcnRpZXMgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIC5nZXRQcm9wZXJ0aWVzKG9iamVjdClcbiAqXG4gKiBUaGlzIGFsbG93cyB0aGUgcmV0cmlldmFsIG9mIHByb3BlcnR5IG5hbWVzIG9mIGFuIG9iamVjdCwgZW51bWVyYWJsZSBvciBub3QsXG4gKiBpbmhlcml0ZWQgb3Igbm90LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3RcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGdldFByb3BlcnRpZXNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBnZXRQcm9wZXJ0aWVzKG9iamVjdCkge1xuICB2YXIgcmVzdWx0ID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMob2JqZWN0KTtcblxuICBmdW5jdGlvbiBhZGRQcm9wZXJ0eShwcm9wZXJ0eSkge1xuICAgIGlmIChyZXN1bHQuaW5kZXhPZihwcm9wZXJ0eSkgPT09IC0xKSB7XG4gICAgICByZXN1bHQucHVzaChwcm9wZXJ0eSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdCk7XG4gIHdoaWxlIChwcm90byAhPT0gbnVsbCkge1xuICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHByb3RvKS5mb3JFYWNoKGFkZFByb3BlcnR5KTtcbiAgICBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufTtcbiIsIi8qIVxuICogQ2hhaSAtIGhhc1Byb3BlcnR5IHV0aWxpdHlcbiAqIENvcHlyaWdodChjKSAyMDEyLTIwMTQgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG52YXIgdHlwZSA9IHJlcXVpcmUoJ3R5cGUtZGV0ZWN0Jyk7XG5cbi8qKlxuICogIyMjIC5oYXNQcm9wZXJ0eShvYmplY3QsIG5hbWUpXG4gKlxuICogVGhpcyBhbGxvd3MgY2hlY2tpbmcgd2hldGhlciBhbiBvYmplY3QgaGFzXG4gKiBuYW1lZCBwcm9wZXJ0eSBvciBudW1lcmljIGFycmF5IGluZGV4LlxuICpcbiAqIEJhc2ljYWxseSBkb2VzIHRoZSBzYW1lIHRoaW5nIGFzIHRoZSBgaW5gXG4gKiBvcGVyYXRvciBidXQgd29ya3MgcHJvcGVybHkgd2l0aCBuYXRpdmVzXG4gKiBhbmQgbnVsbC91bmRlZmluZWQgdmFsdWVzLlxuICpcbiAqICAgICB2YXIgb2JqID0ge1xuICogICAgICAgICBhcnI6IFsnYScsICdiJywgJ2MnXVxuICogICAgICAgLCBzdHI6ICdIZWxsbydcbiAqICAgICB9XG4gKlxuICogVGhlIGZvbGxvd2luZyB3b3VsZCBiZSB0aGUgcmVzdWx0cy5cbiAqXG4gKiAgICAgaGFzUHJvcGVydHkoJ3N0cicsIG9iaik7ICAvLyB0cnVlXG4gKiAgICAgaGFzUHJvcGVydHkoJ2NvbnN0cnVjdG9yJywgb2JqKTsgIC8vIHRydWVcbiAqICAgICBoYXNQcm9wZXJ0eSgnYmFyJywgb2JqKTsgIC8vIGZhbHNlXG4gKlxuICogICAgIGhhc1Byb3BlcnR5KCdsZW5ndGgnLCBvYmouc3RyKTsgLy8gdHJ1ZVxuICogICAgIGhhc1Byb3BlcnR5KDEsIG9iai5zdHIpOyAgLy8gdHJ1ZVxuICogICAgIGhhc1Byb3BlcnR5KDUsIG9iai5zdHIpOyAgLy8gZmFsc2VcbiAqXG4gKiAgICAgaGFzUHJvcGVydHkoJ2xlbmd0aCcsIG9iai5hcnIpOyAgLy8gdHJ1ZVxuICogICAgIGhhc1Byb3BlcnR5KDIsIG9iai5hcnIpOyAgLy8gdHJ1ZVxuICogICAgIGhhc1Byb3BlcnR5KDMsIG9iai5hcnIpOyAgLy8gZmFsc2VcbiAqXG4gKiBAcGFyYW0ge09ianVlY3R9IG9iamVjdFxuICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSBuYW1lXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gd2hldGhlciBpdCBleGlzdHNcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGdldFBhdGhJbmZvXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnZhciBsaXRlcmFscyA9IHtcbiAgICAnbnVtYmVyJzogTnVtYmVyXG4gICwgJ3N0cmluZyc6IFN0cmluZ1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoYXNQcm9wZXJ0eShuYW1lLCBvYmopIHtcbiAgdmFyIG90ID0gdHlwZShvYmopO1xuXG4gIC8vIEJhZCBPYmplY3QsIG9idmlvdXNseSBubyBwcm9wcyBhdCBhbGxcbiAgaWYob3QgPT09ICdudWxsJyB8fCBvdCA9PT0gJ3VuZGVmaW5lZCcpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIFRoZSBgaW5gIG9wZXJhdG9yIGRvZXMgbm90IHdvcmsgd2l0aCBjZXJ0YWluIGxpdGVyYWxzXG4gIC8vIGJveCB0aGVzZSBiZWZvcmUgdGhlIGNoZWNrXG4gIGlmKGxpdGVyYWxzW290XSAmJiB0eXBlb2Ygb2JqICE9PSAnb2JqZWN0JylcbiAgICBvYmogPSBuZXcgbGl0ZXJhbHNbb3RdKG9iaik7XG5cbiAgcmV0dXJuIG5hbWUgaW4gb2JqO1xufTtcbiIsIi8qIVxuICogY2hhaVxuICogQ29weXJpZ2h0KGMpIDIwMTEgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKiFcbiAqIE1haW4gZXhwb3J0c1xuICovXG5cbnZhciBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxuLyohXG4gKiB0ZXN0IHV0aWxpdHlcbiAqL1xuXG5leHBvcnRzLnRlc3QgPSByZXF1aXJlKCcuL3Rlc3QnKTtcblxuLyohXG4gKiB0eXBlIHV0aWxpdHlcbiAqL1xuXG5leHBvcnRzLnR5cGUgPSByZXF1aXJlKCd0eXBlLWRldGVjdCcpO1xuXG4vKiFcbiAqIGV4cGVjdFR5cGVzIHV0aWxpdHlcbiAqL1xuZXhwb3J0cy5leHBlY3RUeXBlcyA9IHJlcXVpcmUoJy4vZXhwZWN0VHlwZXMnKTtcblxuLyohXG4gKiBtZXNzYWdlIHV0aWxpdHlcbiAqL1xuXG5leHBvcnRzLmdldE1lc3NhZ2UgPSByZXF1aXJlKCcuL2dldE1lc3NhZ2UnKTtcblxuLyohXG4gKiBhY3R1YWwgdXRpbGl0eVxuICovXG5cbmV4cG9ydHMuZ2V0QWN0dWFsID0gcmVxdWlyZSgnLi9nZXRBY3R1YWwnKTtcblxuLyohXG4gKiBJbnNwZWN0IHV0aWxcbiAqL1xuXG5leHBvcnRzLmluc3BlY3QgPSByZXF1aXJlKCcuL2luc3BlY3QnKTtcblxuLyohXG4gKiBPYmplY3QgRGlzcGxheSB1dGlsXG4gKi9cblxuZXhwb3J0cy5vYmpEaXNwbGF5ID0gcmVxdWlyZSgnLi9vYmpEaXNwbGF5Jyk7XG5cbi8qIVxuICogRmxhZyB1dGlsaXR5XG4gKi9cblxuZXhwb3J0cy5mbGFnID0gcmVxdWlyZSgnLi9mbGFnJyk7XG5cbi8qIVxuICogRmxhZyB0cmFuc2ZlcnJpbmcgdXRpbGl0eVxuICovXG5cbmV4cG9ydHMudHJhbnNmZXJGbGFncyA9IHJlcXVpcmUoJy4vdHJhbnNmZXJGbGFncycpO1xuXG4vKiFcbiAqIERlZXAgZXF1YWwgdXRpbGl0eVxuICovXG5cbmV4cG9ydHMuZXFsID0gcmVxdWlyZSgnZGVlcC1lcWwnKTtcblxuLyohXG4gKiBEZWVwIHBhdGggdmFsdWVcbiAqL1xuXG5leHBvcnRzLmdldFBhdGhWYWx1ZSA9IHJlcXVpcmUoJy4vZ2V0UGF0aFZhbHVlJyk7XG5cbi8qIVxuICogRGVlcCBwYXRoIGluZm9cbiAqL1xuXG5leHBvcnRzLmdldFBhdGhJbmZvID0gcmVxdWlyZSgnLi9nZXRQYXRoSW5mbycpO1xuXG4vKiFcbiAqIENoZWNrIGlmIGEgcHJvcGVydHkgZXhpc3RzXG4gKi9cblxuZXhwb3J0cy5oYXNQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vaGFzUHJvcGVydHknKTtcblxuLyohXG4gKiBGdW5jdGlvbiBuYW1lXG4gKi9cblxuZXhwb3J0cy5nZXROYW1lID0gcmVxdWlyZSgnLi9nZXROYW1lJyk7XG5cbi8qIVxuICogYWRkIFByb3BlcnR5XG4gKi9cblxuZXhwb3J0cy5hZGRQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vYWRkUHJvcGVydHknKTtcblxuLyohXG4gKiBhZGQgTWV0aG9kXG4gKi9cblxuZXhwb3J0cy5hZGRNZXRob2QgPSByZXF1aXJlKCcuL2FkZE1ldGhvZCcpO1xuXG4vKiFcbiAqIG92ZXJ3cml0ZSBQcm9wZXJ0eVxuICovXG5cbmV4cG9ydHMub3ZlcndyaXRlUHJvcGVydHkgPSByZXF1aXJlKCcuL292ZXJ3cml0ZVByb3BlcnR5Jyk7XG5cbi8qIVxuICogb3ZlcndyaXRlIE1ldGhvZFxuICovXG5cbmV4cG9ydHMub3ZlcndyaXRlTWV0aG9kID0gcmVxdWlyZSgnLi9vdmVyd3JpdGVNZXRob2QnKTtcblxuLyohXG4gKiBBZGQgYSBjaGFpbmFibGUgbWV0aG9kXG4gKi9cblxuZXhwb3J0cy5hZGRDaGFpbmFibGVNZXRob2QgPSByZXF1aXJlKCcuL2FkZENoYWluYWJsZU1ldGhvZCcpO1xuXG4vKiFcbiAqIE92ZXJ3cml0ZSBjaGFpbmFibGUgbWV0aG9kXG4gKi9cblxuZXhwb3J0cy5vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QgPSByZXF1aXJlKCcuL292ZXJ3cml0ZUNoYWluYWJsZU1ldGhvZCcpO1xuIiwiLy8gVGhpcyBpcyAoYWxtb3N0KSBkaXJlY3RseSBmcm9tIE5vZGUuanMgdXRpbHNcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9qb3llbnQvbm9kZS9ibG9iL2Y4YzMzNWQwY2FmNDdmMTZkMzE0MTNmODlhYTI4ZWRhMzg3OGUzYWEvbGliL3V0aWwuanNcblxudmFyIGdldE5hbWUgPSByZXF1aXJlKCcuL2dldE5hbWUnKTtcbnZhciBnZXRQcm9wZXJ0aWVzID0gcmVxdWlyZSgnLi9nZXRQcm9wZXJ0aWVzJyk7XG52YXIgZ2V0RW51bWVyYWJsZVByb3BlcnRpZXMgPSByZXF1aXJlKCcuL2dldEVudW1lcmFibGVQcm9wZXJ0aWVzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gaW5zcGVjdDtcblxuLyoqXG4gKiBFY2hvcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJ5cyB0byBwcmludCB0aGUgdmFsdWUgb3V0XG4gKiBpbiB0aGUgYmVzdCB3YXkgcG9zc2libGUgZ2l2ZW4gdGhlIGRpZmZlcmVudCB0eXBlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gcHJpbnQgb3V0LlxuICogQHBhcmFtIHtCb29sZWFufSBzaG93SGlkZGVuIEZsYWcgdGhhdCBzaG93cyBoaWRkZW4gKG5vdCBlbnVtZXJhYmxlKVxuICogICAgcHJvcGVydGllcyBvZiBvYmplY3RzLlxuICogQHBhcmFtIHtOdW1iZXJ9IGRlcHRoIERlcHRoIGluIHdoaWNoIHRvIGRlc2NlbmQgaW4gb2JqZWN0LiBEZWZhdWx0IGlzIDIuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGNvbG9ycyBGbGFnIHRvIHR1cm4gb24gQU5TSSBlc2NhcGUgY29kZXMgdG8gY29sb3IgdGhlXG4gKiAgICBvdXRwdXQuIERlZmF1bHQgaXMgZmFsc2UgKG5vIGNvbG9yaW5nKS5cbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIGluc3BlY3RcbiAqL1xuZnVuY3Rpb24gaW5zcGVjdChvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMpIHtcbiAgdmFyIGN0eCA9IHtcbiAgICBzaG93SGlkZGVuOiBzaG93SGlkZGVuLFxuICAgIHNlZW46IFtdLFxuICAgIHN0eWxpemU6IGZ1bmN0aW9uIChzdHIpIHsgcmV0dXJuIHN0cjsgfVxuICB9O1xuICByZXR1cm4gZm9ybWF0VmFsdWUoY3R4LCBvYmosICh0eXBlb2YgZGVwdGggPT09ICd1bmRlZmluZWQnID8gMiA6IGRlcHRoKSk7XG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiBvYmplY3QgaXMgYSBET00gZWxlbWVudC5cbnZhciBpc0RPTUVsZW1lbnQgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgPT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBvYmplY3QgJiZcbiAgICAgIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnICYmXG4gICAgICBvYmplY3Qubm9kZVR5cGUgPT09IDEgJiZcbiAgICAgIHR5cGVvZiBvYmplY3Qubm9kZU5hbWUgPT09ICdzdHJpbmcnO1xuICB9XG59O1xuXG5mdW5jdGlvbiBmb3JtYXRWYWx1ZShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMpIHtcbiAgLy8gUHJvdmlkZSBhIGhvb2sgZm9yIHVzZXItc3BlY2lmaWVkIGluc3BlY3QgZnVuY3Rpb25zLlxuICAvLyBDaGVjayB0aGF0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFuIGluc3BlY3QgZnVuY3Rpb24gb24gaXRcbiAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZS5pbnNwZWN0ID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAvLyBGaWx0ZXIgb3V0IHRoZSB1dGlsIG1vZHVsZSwgaXQncyBpbnNwZWN0IGZ1bmN0aW9uIGlzIHNwZWNpYWxcbiAgICAgIHZhbHVlLmluc3BlY3QgIT09IGV4cG9ydHMuaW5zcGVjdCAmJlxuICAgICAgLy8gQWxzbyBmaWx0ZXIgb3V0IGFueSBwcm90b3R5cGUgb2JqZWN0cyB1c2luZyB0aGUgY2lyY3VsYXIgY2hlY2suXG4gICAgICAhKHZhbHVlLmNvbnN0cnVjdG9yICYmIHZhbHVlLmNvbnN0cnVjdG9yLnByb3RvdHlwZSA9PT0gdmFsdWUpKSB7XG4gICAgdmFyIHJldCA9IHZhbHVlLmluc3BlY3QocmVjdXJzZVRpbWVzKTtcbiAgICBpZiAodHlwZW9mIHJldCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldCA9IGZvcm1hdFZhbHVlKGN0eCwgcmV0LCByZWN1cnNlVGltZXMpO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLy8gUHJpbWl0aXZlIHR5cGVzIGNhbm5vdCBoYXZlIHByb3BlcnRpZXNcbiAgdmFyIHByaW1pdGl2ZSA9IGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKTtcbiAgaWYgKHByaW1pdGl2ZSkge1xuICAgIHJldHVybiBwcmltaXRpdmU7XG4gIH1cblxuICAvLyBJZiB0aGlzIGlzIGEgRE9NIGVsZW1lbnQsIHRyeSB0byBnZXQgdGhlIG91dGVyIEhUTUwuXG4gIGlmIChpc0RPTUVsZW1lbnQodmFsdWUpKSB7XG4gICAgaWYgKCdvdXRlckhUTUwnIGluIHZhbHVlKSB7XG4gICAgICByZXR1cm4gdmFsdWUub3V0ZXJIVE1MO1xuICAgICAgLy8gVGhpcyB2YWx1ZSBkb2VzIG5vdCBoYXZlIGFuIG91dGVySFRNTCBhdHRyaWJ1dGUsXG4gICAgICAvLyAgIGl0IGNvdWxkIHN0aWxsIGJlIGFuIFhNTCBlbGVtZW50XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEF0dGVtcHQgdG8gc2VyaWFsaXplIGl0XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoZG9jdW1lbnQueG1sVmVyc2lvbikge1xuICAgICAgICAgIHZhciB4bWxTZXJpYWxpemVyID0gbmV3IFhNTFNlcmlhbGl6ZXIoKTtcbiAgICAgICAgICByZXR1cm4geG1sU2VyaWFsaXplci5zZXJpYWxpemVUb1N0cmluZyh2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gRmlyZWZveCAxMS0gZG8gbm90IHN1cHBvcnQgb3V0ZXJIVE1MXG4gICAgICAgICAgLy8gICBJdCBkb2VzLCBob3dldmVyLCBzdXBwb3J0IGlubmVySFRNTFxuICAgICAgICAgIC8vICAgVXNlIHRoZSBmb2xsb3dpbmcgdG8gcmVuZGVyIHRoZSBlbGVtZW50XG4gICAgICAgICAgdmFyIG5zID0gXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI7XG4gICAgICAgICAgdmFyIGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhucywgJ18nKTtcblxuICAgICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCh2YWx1ZS5jbG9uZU5vZGUoZmFsc2UpKTtcbiAgICAgICAgICBodG1sID0gY29udGFpbmVyLmlubmVySFRNTFxuICAgICAgICAgICAgLnJlcGxhY2UoJz48JywgJz4nICsgdmFsdWUuaW5uZXJIVE1MICsgJzwnKTtcbiAgICAgICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gJyc7XG4gICAgICAgICAgcmV0dXJuIGh0bWw7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAvLyBUaGlzIGNvdWxkIGJlIGEgbm9uLW5hdGl2ZSBET00gaW1wbGVtZW50YXRpb24sXG4gICAgICAgIC8vICAgY29udGludWUgd2l0aCB0aGUgbm9ybWFsIGZsb3c6XG4gICAgICAgIC8vICAgcHJpbnRpbmcgdGhlIGVsZW1lbnQgYXMgaWYgaXQgaXMgYW4gb2JqZWN0LlxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIExvb2sgdXAgdGhlIGtleXMgb2YgdGhlIG9iamVjdC5cbiAgdmFyIHZpc2libGVLZXlzID0gZ2V0RW51bWVyYWJsZVByb3BlcnRpZXModmFsdWUpO1xuICB2YXIga2V5cyA9IGN0eC5zaG93SGlkZGVuID8gZ2V0UHJvcGVydGllcyh2YWx1ZSkgOiB2aXNpYmxlS2V5cztcblxuICAvLyBTb21lIHR5cGUgb2Ygb2JqZWN0IHdpdGhvdXQgcHJvcGVydGllcyBjYW4gYmUgc2hvcnRjdXR0ZWQuXG4gIC8vIEluIElFLCBlcnJvcnMgaGF2ZSBhIHNpbmdsZSBgc3RhY2tgIHByb3BlcnR5LCBvciBpZiB0aGV5IGFyZSB2YW5pbGxhIGBFcnJvcmAsXG4gIC8vIGEgYHN0YWNrYCBwbHVzIGBkZXNjcmlwdGlvbmAgcHJvcGVydHk7IGlnbm9yZSB0aG9zZSBmb3IgY29uc2lzdGVuY3kuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCB8fCAoaXNFcnJvcih2YWx1ZSkgJiYgKFxuICAgICAgKGtleXMubGVuZ3RoID09PSAxICYmIGtleXNbMF0gPT09ICdzdGFjaycpIHx8XG4gICAgICAoa2V5cy5sZW5ndGggPT09IDIgJiYga2V5c1swXSA9PT0gJ2Rlc2NyaXB0aW9uJyAmJiBrZXlzWzFdID09PSAnc3RhY2snKVxuICAgICApKSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZhciBuYW1lID0gZ2V0TmFtZSh2YWx1ZSk7XG4gICAgICB2YXIgbmFtZVN1ZmZpeCA9IG5hbWUgPyAnOiAnICsgbmFtZSA6ICcnO1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbRnVuY3Rpb24nICsgbmFtZVN1ZmZpeCArICddJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9XG4gICAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShEYXRlLnByb3RvdHlwZS50b1VUQ1N0cmluZy5jYWxsKHZhbHVlKSwgJ2RhdGUnKTtcbiAgICB9XG4gICAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBiYXNlID0gJycsIGFycmF5ID0gZmFsc2UsIGJyYWNlcyA9IFsneycsICd9J107XG5cbiAgLy8gTWFrZSBBcnJheSBzYXkgdGhhdCB0aGV5IGFyZSBBcnJheVxuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBhcnJheSA9IHRydWU7XG4gICAgYnJhY2VzID0gWydbJywgJ10nXTtcbiAgfVxuXG4gIC8vIE1ha2UgZnVuY3Rpb25zIHNheSB0aGF0IHRoZXkgYXJlIGZ1bmN0aW9uc1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdmFyIG5hbWUgPSBnZXROYW1lKHZhbHVlKTtcbiAgICB2YXIgbmFtZVN1ZmZpeCA9IG5hbWUgPyAnOiAnICsgbmFtZSA6ICcnO1xuICAgIGJhc2UgPSAnIFtGdW5jdGlvbicgKyBuYW1lU3VmZml4ICsgJ10nO1xuICB9XG5cbiAgLy8gTWFrZSBSZWdFeHBzIHNheSB0aGF0IHRoZXkgYXJlIFJlZ0V4cHNcbiAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBkYXRlcyB3aXRoIHByb3BlcnRpZXMgZmlyc3Qgc2F5IHRoZSBkYXRlXG4gIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIERhdGUucHJvdG90eXBlLnRvVVRDU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBlcnJvciB3aXRoIG1lc3NhZ2UgZmlyc3Qgc2F5IHRoZSBlcnJvclxuICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwICYmICghYXJyYXkgfHwgdmFsdWUubGVuZ3RoID09IDApKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyBicmFjZXNbMV07XG4gIH1cblxuICBpZiAocmVjdXJzZVRpbWVzIDwgMCkge1xuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW09iamVjdF0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuXG4gIGN0eC5zZWVuLnB1c2godmFsdWUpO1xuXG4gIHZhciBvdXRwdXQ7XG4gIGlmIChhcnJheSkge1xuICAgIG91dHB1dCA9IGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpO1xuICB9IGVsc2Uge1xuICAgIG91dHB1dCA9IGtleXMubWFwKGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpO1xuICAgIH0pO1xuICB9XG5cbiAgY3R4LnNlZW4ucG9wKCk7XG5cbiAgcmV0dXJuIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKTtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSkge1xuICBzd2l0Y2ggKHR5cGVvZiB2YWx1ZSkge1xuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcblxuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICB2YXIgc2ltcGxlID0gJ1xcJycgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkucmVwbGFjZSgvXlwifFwiJC9nLCAnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpICsgJ1xcJyc7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoc2ltcGxlLCAnc3RyaW5nJyk7XG5cbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgaWYgKHZhbHVlID09PSAwICYmICgxL3ZhbHVlKSA9PT0gLUluZmluaXR5KSB7XG4gICAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnLTAnLCAnbnVtYmVyJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ251bWJlcicpO1xuXG4gICAgY2FzZSAnYm9vbGVhbic6XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ2Jvb2xlYW4nKTtcbiAgfVxuICAvLyBGb3Igc29tZSByZWFzb24gdHlwZW9mIG51bGwgaXMgXCJvYmplY3RcIiwgc28gc3BlY2lhbCBjYXNlIGhlcmUuXG4gIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnbnVsbCcsICdudWxsJyk7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRFcnJvcih2YWx1ZSkge1xuICByZXR1cm4gJ1snICsgRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpICsgJ10nO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpIHtcbiAgdmFyIG91dHB1dCA9IFtdO1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7ICsraSkge1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIFN0cmluZyhpKSkpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAgU3RyaW5nKGkpLCB0cnVlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICB9XG4gIH1cbiAga2V5cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICgha2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBrZXksIHRydWUpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb3V0cHV0O1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpIHtcbiAgdmFyIG5hbWUsIHN0cjtcbiAgaWYgKHZhbHVlLl9fbG9va3VwR2V0dGVyX18pIHtcbiAgICBpZiAodmFsdWUuX19sb29rdXBHZXR0ZXJfXyhrZXkpKSB7XG4gICAgICBpZiAodmFsdWUuX19sb29rdXBTZXR0ZXJfXyhrZXkpKSB7XG4gICAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyL1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHZhbHVlLl9fbG9va3VwU2V0dGVyX18oa2V5KSkge1xuICAgICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAodmlzaWJsZUtleXMuaW5kZXhPZihrZXkpIDwgMCkge1xuICAgIG5hbWUgPSAnWycgKyBrZXkgKyAnXSc7XG4gIH1cbiAgaWYgKCFzdHIpIHtcbiAgICBpZiAoY3R4LnNlZW4uaW5kZXhPZih2YWx1ZVtrZXldKSA8IDApIHtcbiAgICAgIGlmIChyZWN1cnNlVGltZXMgPT09IG51bGwpIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCB2YWx1ZVtrZXldLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgdmFsdWVba2V5XSwgcmVjdXJzZVRpbWVzIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgaWYgKGFycmF5KSB7XG4gICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpLnN1YnN0cigyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdHIgPSAnXFxuJyArIHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAodHlwZW9mIG5hbWUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKGFycmF5ICYmIGtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICAgIG5hbWUgPSBKU09OLnN0cmluZ2lmeSgnJyArIGtleSk7XG4gICAgaWYgKG5hbWUubWF0Y2goL15cIihbYS16QS1aX11bYS16QS1aXzAtOV0qKVwiJC8pKSB7XG4gICAgICBuYW1lID0gbmFtZS5zdWJzdHIoMSwgbmFtZS5sZW5ndGggLSAyKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnbmFtZScpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvKF5cInxcIiQpL2csIFwiJ1wiKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnc3RyaW5nJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5hbWUgKyAnOiAnICsgc3RyO1xufVxuXG5cbmZ1bmN0aW9uIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKSB7XG4gIHZhciBudW1MaW5lc0VzdCA9IDA7XG4gIHZhciBsZW5ndGggPSBvdXRwdXQucmVkdWNlKGZ1bmN0aW9uKHByZXYsIGN1cikge1xuICAgIG51bUxpbmVzRXN0Kys7XG4gICAgaWYgKGN1ci5pbmRleE9mKCdcXG4nKSA+PSAwKSBudW1MaW5lc0VzdCsrO1xuICAgIHJldHVybiBwcmV2ICsgY3VyLmxlbmd0aCArIDE7XG4gIH0sIDApO1xuXG4gIGlmIChsZW5ndGggPiA2MCkge1xuICAgIHJldHVybiBicmFjZXNbMF0gK1xuICAgICAgICAgICAoYmFzZSA9PT0gJycgPyAnJyA6IGJhc2UgKyAnXFxuICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgb3V0cHV0LmpvaW4oJyxcXG4gICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgYnJhY2VzWzFdO1xuICB9XG5cbiAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyAnICcgKyBvdXRwdXQuam9pbignLCAnKSArICcgJyArIGJyYWNlc1sxXTtcbn1cblxuZnVuY3Rpb24gaXNBcnJheShhcikge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheShhcikgfHxcbiAgICAgICAgICh0eXBlb2YgYXIgPT09ICdvYmplY3QnICYmIG9iamVjdFRvU3RyaW5nKGFyKSA9PT0gJ1tvYmplY3QgQXJyYXldJyk7XG59XG5cbmZ1bmN0aW9uIGlzUmVnRXhwKHJlKSB7XG4gIHJldHVybiB0eXBlb2YgcmUgPT09ICdvYmplY3QnICYmIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiB0eXBlb2YgZCA9PT0gJ29iamVjdCcgJiYgb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cblxuZnVuY3Rpb24gaXNFcnJvcihlKSB7XG4gIHJldHVybiB0eXBlb2YgZSA9PT0gJ29iamVjdCcgJiYgb2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXSc7XG59XG5cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cbiIsIi8qIVxuICogQ2hhaSAtIGZsYWcgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qIVxuICogTW9kdWxlIGRlcGVuZGFuY2llc1xuICovXG5cbnZhciBpbnNwZWN0ID0gcmVxdWlyZSgnLi9pbnNwZWN0Jyk7XG52YXIgY29uZmlnID0gcmVxdWlyZSgnLi4vY29uZmlnJyk7XG5cbi8qKlxuICogIyMjIC5vYmpEaXNwbGF5IChvYmplY3QpXG4gKlxuICogRGV0ZXJtaW5lcyBpZiBhbiBvYmplY3Qgb3IgYW4gYXJyYXkgbWF0Y2hlc1xuICogY3JpdGVyaWEgdG8gYmUgaW5zcGVjdGVkIGluLWxpbmUgZm9yIGVycm9yXG4gKiBtZXNzYWdlcyBvciBzaG91bGQgYmUgdHJ1bmNhdGVkLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IGphdmFzY3JpcHQgb2JqZWN0IHRvIGluc3BlY3RcbiAqIEBuYW1lIG9iakRpc3BsYXlcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBzdHIgPSBpbnNwZWN0KG9iailcbiAgICAsIHR5cGUgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKTtcblxuICBpZiAoY29uZmlnLnRydW5jYXRlVGhyZXNob2xkICYmIHN0ci5sZW5ndGggPj0gY29uZmlnLnRydW5jYXRlVGhyZXNob2xkKSB7XG4gICAgaWYgKHR5cGUgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXScpIHtcbiAgICAgIHJldHVybiAhb2JqLm5hbWUgfHwgb2JqLm5hbWUgPT09ICcnXG4gICAgICAgID8gJ1tGdW5jdGlvbl0nXG4gICAgICAgIDogJ1tGdW5jdGlvbjogJyArIG9iai5uYW1lICsgJ10nO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ1tvYmplY3QgQXJyYXldJykge1xuICAgICAgcmV0dXJuICdbIEFycmF5KCcgKyBvYmoubGVuZ3RoICsgJykgXSc7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnW29iamVjdCBPYmplY3RdJykge1xuICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopXG4gICAgICAgICwga3N0ciA9IGtleXMubGVuZ3RoID4gMlxuICAgICAgICAgID8ga2V5cy5zcGxpY2UoMCwgMikuam9pbignLCAnKSArICcsIC4uLidcbiAgICAgICAgICA6IGtleXMuam9pbignLCAnKTtcbiAgICAgIHJldHVybiAneyBPYmplY3QgKCcgKyBrc3RyICsgJykgfSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbn07XG4iLCIvKiFcbiAqIENoYWkgLSBvdmVyd3JpdGVDaGFpbmFibGVNZXRob2QgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIG92ZXJ3cml0ZUNoYWluYWJsZU1ldGhvZCAoY3R4LCBuYW1lLCBtZXRob2QsIGNoYWluaW5nQmVoYXZpb3IpXG4gKlxuICogT3ZlcndpdGVzIGFuIGFscmVhZHkgZXhpc3RpbmcgY2hhaW5hYmxlIG1ldGhvZFxuICogYW5kIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgcHJldmlvdXMgZnVuY3Rpb24gb3JcbiAqIHByb3BlcnR5LiAgTXVzdCByZXR1cm4gZnVuY3Rpb25zIHRvIGJlIHVzZWQgZm9yXG4gKiBuYW1lLlxuICpcbiAqICAgICB1dGlscy5vdmVyd3JpdGVDaGFpbmFibGVNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCAnbGVuZ3RoJyxcbiAqICAgICAgIGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAqICAgICAgIH1cbiAqICAgICAsIGZ1bmN0aW9uIChfc3VwZXIpIHtcbiAqICAgICAgIH1cbiAqICAgICApO1xuICpcbiAqIENhbiBhbHNvIGJlIGFjY2Vzc2VkIGRpcmVjdGx5IGZyb20gYGNoYWkuQXNzZXJ0aW9uYC5cbiAqXG4gKiAgICAgY2hhaS5Bc3NlcnRpb24ub3ZlcndyaXRlQ2hhaW5hYmxlTWV0aG9kKCdmb28nLCBmbiwgZm4pO1xuICpcbiAqIFRoZW4gY2FuIGJlIHVzZWQgYXMgYW55IG90aGVyIGFzc2VydGlvbi5cbiAqXG4gKiAgICAgZXhwZWN0KG15Rm9vKS50by5oYXZlLmxlbmd0aCgzKTtcbiAqICAgICBleHBlY3QobXlGb28pLnRvLmhhdmUubGVuZ3RoLmFib3ZlKDMpO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjdHggb2JqZWN0IHdob3NlIG1ldGhvZCAvIHByb3BlcnR5IGlzIHRvIGJlIG92ZXJ3cml0dGVuXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBvZiBtZXRob2QgLyBwcm9wZXJ0eSB0byBvdmVyd3JpdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG1ldGhvZCBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBmdW5jdGlvbiB0byBiZSB1c2VkIGZvciBuYW1lXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjaGFpbmluZ0JlaGF2aW9yIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIGZ1bmN0aW9uIHRvIGJlIHVzZWQgZm9yIHByb3BlcnR5XG4gKiBAbmFtZXNwYWNlIFV0aWxzXG4gKiBAbmFtZSBvdmVyd3JpdGVDaGFpbmFibGVNZXRob2RcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoY3R4LCBuYW1lLCBtZXRob2QsIGNoYWluaW5nQmVoYXZpb3IpIHtcbiAgdmFyIGNoYWluYWJsZUJlaGF2aW9yID0gY3R4Ll9fbWV0aG9kc1tuYW1lXTtcblxuICB2YXIgX2NoYWluaW5nQmVoYXZpb3IgPSBjaGFpbmFibGVCZWhhdmlvci5jaGFpbmluZ0JlaGF2aW9yO1xuICBjaGFpbmFibGVCZWhhdmlvci5jaGFpbmluZ0JlaGF2aW9yID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciByZXN1bHQgPSBjaGFpbmluZ0JlaGF2aW9yKF9jaGFpbmluZ0JlaGF2aW9yKS5jYWxsKHRoaXMpO1xuICAgIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCA/IHRoaXMgOiByZXN1bHQ7XG4gIH07XG5cbiAgdmFyIF9tZXRob2QgPSBjaGFpbmFibGVCZWhhdmlvci5tZXRob2Q7XG4gIGNoYWluYWJsZUJlaGF2aW9yLm1ldGhvZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcmVzdWx0ID0gbWV0aG9kKF9tZXRob2QpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gdGhpcyA6IHJlc3VsdDtcbiAgfTtcbn07XG4iLCIvKiFcbiAqIENoYWkgLSBvdmVyd3JpdGVNZXRob2QgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIG92ZXJ3cml0ZU1ldGhvZCAoY3R4LCBuYW1lLCBmbilcbiAqXG4gKiBPdmVyd2l0ZXMgYW4gYWxyZWFkeSBleGlzdGluZyBtZXRob2QgYW5kIHByb3ZpZGVzXG4gKiBhY2Nlc3MgdG8gcHJldmlvdXMgZnVuY3Rpb24uIE11c3QgcmV0dXJuIGZ1bmN0aW9uXG4gKiB0byBiZSB1c2VkIGZvciBuYW1lLlxuICpcbiAqICAgICB1dGlscy5vdmVyd3JpdGVNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCAnZXF1YWwnLCBmdW5jdGlvbiAoX3N1cGVyKSB7XG4gKiAgICAgICByZXR1cm4gZnVuY3Rpb24gKHN0cikge1xuICogICAgICAgICB2YXIgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gKiAgICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBGb28pIHtcbiAqICAgICAgICAgICBuZXcgY2hhaS5Bc3NlcnRpb24ob2JqLnZhbHVlKS50by5lcXVhbChzdHIpO1xuICogICAgICAgICB9IGVsc2Uge1xuICogICAgICAgICAgIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICogICAgICAgICB9XG4gKiAgICAgICB9XG4gKiAgICAgfSk7XG4gKlxuICogQ2FuIGFsc28gYmUgYWNjZXNzZWQgZGlyZWN0bHkgZnJvbSBgY2hhaS5Bc3NlcnRpb25gLlxuICpcbiAqICAgICBjaGFpLkFzc2VydGlvbi5vdmVyd3JpdGVNZXRob2QoJ2ZvbycsIGZuKTtcbiAqXG4gKiBUaGVuIGNhbiBiZSB1c2VkIGFzIGFueSBvdGhlciBhc3NlcnRpb24uXG4gKlxuICogICAgIGV4cGVjdChteUZvbykudG8uZXF1YWwoJ2JhcicpO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjdHggb2JqZWN0IHdob3NlIG1ldGhvZCBpcyB0byBiZSBvdmVyd3JpdHRlblxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgb2YgbWV0aG9kIHRvIG92ZXJ3cml0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gbWV0aG9kIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIGZ1bmN0aW9uIHRvIGJlIHVzZWQgZm9yIG5hbWVcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIG92ZXJ3cml0ZU1ldGhvZFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjdHgsIG5hbWUsIG1ldGhvZCkge1xuICB2YXIgX21ldGhvZCA9IGN0eFtuYW1lXVxuICAgICwgX3N1cGVyID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfTtcblxuICBpZiAoX21ldGhvZCAmJiAnZnVuY3Rpb24nID09PSB0eXBlb2YgX21ldGhvZClcbiAgICBfc3VwZXIgPSBfbWV0aG9kO1xuXG4gIGN0eFtuYW1lXSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcmVzdWx0ID0gbWV0aG9kKF9zdXBlcikuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICByZXR1cm4gcmVzdWx0ID09PSB1bmRlZmluZWQgPyB0aGlzIDogcmVzdWx0O1xuICB9XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gb3ZlcndyaXRlUHJvcGVydHkgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIG92ZXJ3cml0ZVByb3BlcnR5IChjdHgsIG5hbWUsIGZuKVxuICpcbiAqIE92ZXJ3aXRlcyBhbiBhbHJlYWR5IGV4aXN0aW5nIHByb3BlcnR5IGdldHRlciBhbmQgcHJvdmlkZXNcbiAqIGFjY2VzcyB0byBwcmV2aW91cyB2YWx1ZS4gTXVzdCByZXR1cm4gZnVuY3Rpb24gdG8gdXNlIGFzIGdldHRlci5cbiAqXG4gKiAgICAgdXRpbHMub3ZlcndyaXRlUHJvcGVydHkoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCAnb2snLCBmdW5jdGlvbiAoX3N1cGVyKSB7XG4gKiAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICogICAgICAgICB2YXIgb2JqID0gdXRpbHMuZmxhZyh0aGlzLCAnb2JqZWN0Jyk7XG4gKiAgICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBGb28pIHtcbiAqICAgICAgICAgICBuZXcgY2hhaS5Bc3NlcnRpb24ob2JqLm5hbWUpLnRvLmVxdWFsKCdiYXInKTtcbiAqICAgICAgICAgfSBlbHNlIHtcbiAqICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzKTtcbiAqICAgICAgICAgfVxuICogICAgICAgfVxuICogICAgIH0pO1xuICpcbiAqXG4gKiBDYW4gYWxzbyBiZSBhY2Nlc3NlZCBkaXJlY3RseSBmcm9tIGBjaGFpLkFzc2VydGlvbmAuXG4gKlxuICogICAgIGNoYWkuQXNzZXJ0aW9uLm92ZXJ3cml0ZVByb3BlcnR5KCdmb28nLCBmbik7XG4gKlxuICogVGhlbiBjYW4gYmUgdXNlZCBhcyBhbnkgb3RoZXIgYXNzZXJ0aW9uLlxuICpcbiAqICAgICBleHBlY3QobXlGb28pLnRvLmJlLm9rO1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjdHggb2JqZWN0IHdob3NlIHByb3BlcnR5IGlzIHRvIGJlIG92ZXJ3cml0dGVuXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBvZiBwcm9wZXJ0eSB0byBvdmVyd3JpdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGdldHRlciBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBnZXR0ZXIgZnVuY3Rpb24gdG8gYmUgdXNlZCBmb3IgbmFtZVxuICogQG5hbWVzcGFjZSBVdGlsc1xuICogQG5hbWUgb3ZlcndyaXRlUHJvcGVydHlcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoY3R4LCBuYW1lLCBnZXR0ZXIpIHtcbiAgdmFyIF9nZXQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGN0eCwgbmFtZSlcbiAgICAsIF9zdXBlciA9IGZ1bmN0aW9uICgpIHt9O1xuXG4gIGlmIChfZ2V0ICYmICdmdW5jdGlvbicgPT09IHR5cGVvZiBfZ2V0LmdldClcbiAgICBfc3VwZXIgPSBfZ2V0LmdldFxuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjdHgsIG5hbWUsXG4gICAgeyBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGdldHRlcihfc3VwZXIpLmNhbGwodGhpcyk7XG4gICAgICAgIHJldHVybiByZXN1bHQgPT09IHVuZGVmaW5lZCA/IHRoaXMgOiByZXN1bHQ7XG4gICAgICB9XG4gICAgLCBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG59O1xuIiwiLyohXG4gKiBDaGFpIC0gdGVzdCB1dGlsaXR5XG4gKiBDb3B5cmlnaHQoYykgMjAxMi0yMDE0IEpha2UgTHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBNb2R1bGUgZGVwZW5kYW5jaWVzXG4gKi9cblxudmFyIGZsYWcgPSByZXF1aXJlKCcuL2ZsYWcnKTtcblxuLyoqXG4gKiAjIHRlc3Qob2JqZWN0LCBleHByZXNzaW9uKVxuICpcbiAqIFRlc3QgYW5kIG9iamVjdCBmb3IgZXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IChjb25zdHJ1Y3RlZCBBc3NlcnRpb24pXG4gKiBAcGFyYW0ge0FyZ3VtZW50c30gY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLmFzc2VydCBhcmd1bWVudHNcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIHRlc3RcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmosIGFyZ3MpIHtcbiAgdmFyIG5lZ2F0ZSA9IGZsYWcob2JqLCAnbmVnYXRlJylcbiAgICAsIGV4cHIgPSBhcmdzWzBdO1xuICByZXR1cm4gbmVnYXRlID8gIWV4cHIgOiBleHByO1xufTtcbiIsIi8qIVxuICogQ2hhaSAtIHRyYW5zZmVyRmxhZ3MgdXRpbGl0eVxuICogQ29weXJpZ2h0KGMpIDIwMTItMjAxNCBKYWtlIEx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qKlxuICogIyMjIHRyYW5zZmVyRmxhZ3MoYXNzZXJ0aW9uLCBvYmplY3QsIGluY2x1ZGVBbGwgPSB0cnVlKVxuICpcbiAqIFRyYW5zZmVyIGFsbCB0aGUgZmxhZ3MgZm9yIGBhc3NlcnRpb25gIHRvIGBvYmplY3RgLiBJZlxuICogYGluY2x1ZGVBbGxgIGlzIHNldCB0byBgZmFsc2VgLCB0aGVuIHRoZSBiYXNlIENoYWlcbiAqIGFzc2VydGlvbiBmbGFncyAobmFtZWx5IGBvYmplY3RgLCBgc3NmaWAsIGFuZCBgbWVzc2FnZWApXG4gKiB3aWxsIG5vdCBiZSB0cmFuc2ZlcnJlZC5cbiAqXG4gKlxuICogICAgIHZhciBuZXdBc3NlcnRpb24gPSBuZXcgQXNzZXJ0aW9uKCk7XG4gKiAgICAgdXRpbHMudHJhbnNmZXJGbGFncyhhc3NlcnRpb24sIG5ld0Fzc2VydGlvbik7XG4gKlxuICogICAgIHZhciBhbm90aGVyQXNzZXJpdG9uID0gbmV3IEFzc2VydGlvbihteU9iaik7XG4gKiAgICAgdXRpbHMudHJhbnNmZXJGbGFncyhhc3NlcnRpb24sIGFub3RoZXJBc3NlcnRpb24sIGZhbHNlKTtcbiAqXG4gKiBAcGFyYW0ge0Fzc2VydGlvbn0gYXNzZXJ0aW9uIHRoZSBhc3NlcnRpb24gdG8gdHJhbnNmZXIgdGhlIGZsYWdzIGZyb21cbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgdGhlIG9iamVjdCB0byB0cmFuc2ZlciB0aGUgZmxhZ3MgdG87IHVzdWFsbHkgYSBuZXcgYXNzZXJ0aW9uXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGluY2x1ZGVBbGxcbiAqIEBuYW1lc3BhY2UgVXRpbHNcbiAqIEBuYW1lIHRyYW5zZmVyRmxhZ3NcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGFzc2VydGlvbiwgb2JqZWN0LCBpbmNsdWRlQWxsKSB7XG4gIHZhciBmbGFncyA9IGFzc2VydGlvbi5fX2ZsYWdzIHx8IChhc3NlcnRpb24uX19mbGFncyA9IE9iamVjdC5jcmVhdGUobnVsbCkpO1xuXG4gIGlmICghb2JqZWN0Ll9fZmxhZ3MpIHtcbiAgICBvYmplY3QuX19mbGFncyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIH1cblxuICBpbmNsdWRlQWxsID0gYXJndW1lbnRzLmxlbmd0aCA9PT0gMyA/IGluY2x1ZGVBbGwgOiB0cnVlO1xuXG4gIGZvciAodmFyIGZsYWcgaW4gZmxhZ3MpIHtcbiAgICBpZiAoaW5jbHVkZUFsbCB8fFxuICAgICAgICAoZmxhZyAhPT0gJ29iamVjdCcgJiYgZmxhZyAhPT0gJ3NzZmknICYmIGZsYWcgIT0gJ21lc3NhZ2UnKSkge1xuICAgICAgb2JqZWN0Ll9fZmxhZ3NbZmxhZ10gPSBmbGFnc1tmbGFnXTtcbiAgICB9XG4gIH1cbn07XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuZnVuY3Rpb24gZGVkZW50KHN0cmluZ3MpIHtcblxuICB2YXIgcmF3ID0gdm9pZCAwO1xuICBpZiAodHlwZW9mIHN0cmluZ3MgPT09IFwic3RyaW5nXCIpIHtcbiAgICAvLyBkZWRlbnQgY2FuIGJlIHVzZWQgYXMgYSBwbGFpbiBmdW5jdGlvblxuICAgIHJhdyA9IFtzdHJpbmdzXTtcbiAgfSBlbHNlIHtcbiAgICByYXcgPSBzdHJpbmdzLnJhdztcbiAgfVxuXG4gIC8vIGZpcnN0LCBwZXJmb3JtIGludGVycG9sYXRpb25cbiAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmF3Lmxlbmd0aDsgaSsrKSB7XG4gICAgcmVzdWx0ICs9IHJhd1tpXS5cbiAgICAvLyBqb2luIGxpbmVzIHdoZW4gdGhlcmUgaXMgYSBzdXBwcmVzc2VkIG5ld2xpbmVcbiAgICByZXBsYWNlKC9cXFxcXFxuWyBcXHRdKi9nLCBcIlwiKS5cblxuICAgIC8vIGhhbmRsZSBlc2NhcGVkIGJhY2t0aWNrc1xuICAgIHJlcGxhY2UoL1xcXFxgL2csIFwiYFwiKTtcblxuICAgIGlmIChpIDwgKGFyZ3VtZW50cy5sZW5ndGggPD0gMSA/IDAgOiBhcmd1bWVudHMubGVuZ3RoIC0gMSkpIHtcbiAgICAgIHJlc3VsdCArPSBhcmd1bWVudHMubGVuZ3RoIDw9IGkgKyAxID8gdW5kZWZpbmVkIDogYXJndW1lbnRzW2kgKyAxXTtcbiAgICB9XG4gIH1cblxuICAvLyBub3cgc3RyaXAgaW5kZW50YXRpb25cbiAgdmFyIGxpbmVzID0gcmVzdWx0LnNwbGl0KFwiXFxuXCIpO1xuICB2YXIgbWluZGVudCA9IG51bGw7XG4gIGxpbmVzLmZvckVhY2goZnVuY3Rpb24gKGwpIHtcbiAgICB2YXIgbSA9IGwubWF0Y2goL14oXFxzKylcXFMrLyk7XG4gICAgaWYgKG0pIHtcbiAgICAgIHZhciBpbmRlbnQgPSBtWzFdLmxlbmd0aDtcbiAgICAgIGlmICghbWluZGVudCkge1xuICAgICAgICAvLyB0aGlzIGlzIHRoZSBmaXJzdCBpbmRlbnRlZCBsaW5lXG4gICAgICAgIG1pbmRlbnQgPSBpbmRlbnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtaW5kZW50ID0gTWF0aC5taW4obWluZGVudCwgaW5kZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGlmIChtaW5kZW50ICE9PSBudWxsKSB7XG4gICAgcmVzdWx0ID0gbGluZXMubWFwKGZ1bmN0aW9uIChsKSB7XG4gICAgICByZXR1cm4gbFswXSA9PT0gXCIgXCIgPyBsLnNsaWNlKG1pbmRlbnQpIDogbDtcbiAgICB9KS5qb2luKFwiXFxuXCIpO1xuICB9XG5cbiAgLy8gZGVkZW50IGVhdHMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSB0b29cbiAgcmVzdWx0ID0gcmVzdWx0LnRyaW0oKTtcblxuICAvLyBoYW5kbGUgZXNjYXBlZCBuZXdsaW5lcyBhdCB0aGUgZW5kIHRvIGVuc3VyZSB0aGV5IGRvbid0IGdldCBzdHJpcHBlZCB0b29cbiAgcmV0dXJuIHJlc3VsdC5yZXBsYWNlKC9cXFxcbi9nLCBcIlxcblwiKTtcbn1cblxuaWYgKHR5cGVvZiBtb2R1bGUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBkZWRlbnQ7XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL2VxbCcpO1xuIiwiLyohXG4gKiBkZWVwLWVxbFxuICogQ29weXJpZ2h0KGMpIDIwMTMgSmFrZSBMdWVyIDxqYWtlQGFsb2dpY2FscGFyYWRveC5jb20+XG4gKiBNSVQgTGljZW5zZWRcbiAqL1xuXG4vKiFcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXNcbiAqL1xuXG52YXIgdHlwZSA9IHJlcXVpcmUoJ3R5cGUtZGV0ZWN0Jyk7XG5cbi8qIVxuICogQnVmZmVyLmlzQnVmZmVyIGJyb3dzZXIgc2hpbVxuICovXG5cbnZhciBCdWZmZXI7XG50cnkgeyBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7IH1cbmNhdGNoKGV4KSB7XG4gIEJ1ZmZlciA9IHt9O1xuICBCdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbigpIHsgcmV0dXJuIGZhbHNlOyB9XG59XG5cbi8qIVxuICogUHJpbWFyeSBFeHBvcnRcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlZXBFcXVhbDtcblxuLyoqXG4gKiBBc3NlcnQgc3VwZXItc3RyaWN0IChlZ2FsKSBlcXVhbGl0eSBiZXR3ZWVuXG4gKiB0d28gb2JqZWN0cyBvZiBhbnkgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBhXG4gKiBAcGFyYW0ge01peGVkfSBiXG4gKiBAcGFyYW0ge0FycmF5fSBtZW1vaXNlZCAob3B0aW9uYWwpXG4gKiBAcmV0dXJuIHtCb29sZWFufSBlcXVhbCBtYXRjaFxuICovXG5cbmZ1bmN0aW9uIGRlZXBFcXVhbChhLCBiLCBtKSB7XG4gIGlmIChzYW1lVmFsdWUoYSwgYikpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmICgnZGF0ZScgPT09IHR5cGUoYSkpIHtcbiAgICByZXR1cm4gZGF0ZUVxdWFsKGEsIGIpO1xuICB9IGVsc2UgaWYgKCdyZWdleHAnID09PSB0eXBlKGEpKSB7XG4gICAgcmV0dXJuIHJlZ2V4cEVxdWFsKGEsIGIpO1xuICB9IGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcihhKSkge1xuICAgIHJldHVybiBidWZmZXJFcXVhbChhLCBiKTtcbiAgfSBlbHNlIGlmICgnYXJndW1lbnRzJyA9PT0gdHlwZShhKSkge1xuICAgIHJldHVybiBhcmd1bWVudHNFcXVhbChhLCBiLCBtKTtcbiAgfSBlbHNlIGlmICghdHlwZUVxdWFsKGEsIGIpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IGVsc2UgaWYgKCgnb2JqZWN0JyAhPT0gdHlwZShhKSAmJiAnb2JqZWN0JyAhPT0gdHlwZShiKSlcbiAgJiYgKCdhcnJheScgIT09IHR5cGUoYSkgJiYgJ2FycmF5JyAhPT0gdHlwZShiKSkpIHtcbiAgICByZXR1cm4gc2FtZVZhbHVlKGEsIGIpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBvYmplY3RFcXVhbChhLCBiLCBtKTtcbiAgfVxufVxuXG4vKiFcbiAqIFN0cmljdCAoZWdhbCkgZXF1YWxpdHkgdGVzdC4gRW5zdXJlcyB0aGF0IE5hTiBhbHdheXNcbiAqIGVxdWFscyBOYU4gYW5kIGAtMGAgZG9lcyBub3QgZXF1YWwgYCswYC5cbiAqXG4gKiBAcGFyYW0ge01peGVkfSBhXG4gKiBAcGFyYW0ge01peGVkfSBiXG4gKiBAcmV0dXJuIHtCb29sZWFufSBlcXVhbCBtYXRjaFxuICovXG5cbmZ1bmN0aW9uIHNhbWVWYWx1ZShhLCBiKSB7XG4gIGlmIChhID09PSBiKSByZXR1cm4gYSAhPT0gMCB8fCAxIC8gYSA9PT0gMSAvIGI7XG4gIHJldHVybiBhICE9PSBhICYmIGIgIT09IGI7XG59XG5cbi8qIVxuICogQ29tcGFyZSB0aGUgdHlwZXMgb2YgdHdvIGdpdmVuIG9iamVjdHMgYW5kXG4gKiByZXR1cm4gaWYgdGhleSBhcmUgZXF1YWwuIE5vdGUgdGhhdCBhbiBBcnJheVxuICogaGFzIGEgdHlwZSBvZiBgYXJyYXlgIChub3QgYG9iamVjdGApIGFuZCBhcmd1bWVudHNcbiAqIGhhdmUgYSB0eXBlIG9mIGBhcmd1bWVudHNgIChub3QgYGFycmF5YC9gb2JqZWN0YCkuXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gYVxuICogQHBhcmFtIHtNaXhlZH0gYlxuICogQHJldHVybiB7Qm9vbGVhbn0gcmVzdWx0XG4gKi9cblxuZnVuY3Rpb24gdHlwZUVxdWFsKGEsIGIpIHtcbiAgcmV0dXJuIHR5cGUoYSkgPT09IHR5cGUoYik7XG59XG5cbi8qIVxuICogQ29tcGFyZSB0d28gRGF0ZSBvYmplY3RzIGJ5IGFzc2VydGluZyB0aGF0XG4gKiB0aGUgdGltZSB2YWx1ZXMgYXJlIGVxdWFsIHVzaW5nIGBzYXZlVmFsdWVgLlxuICpcbiAqIEBwYXJhbSB7RGF0ZX0gYVxuICogQHBhcmFtIHtEYXRlfSBiXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuXG5mdW5jdGlvbiBkYXRlRXF1YWwoYSwgYikge1xuICBpZiAoJ2RhdGUnICE9PSB0eXBlKGIpKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBzYW1lVmFsdWUoYS5nZXRUaW1lKCksIGIuZ2V0VGltZSgpKTtcbn1cblxuLyohXG4gKiBDb21wYXJlIHR3byByZWd1bGFyIGV4cHJlc3Npb25zIGJ5IGNvbnZlcnRpbmcgdGhlbVxuICogdG8gc3RyaW5nIGFuZCBjaGVja2luZyBmb3IgYHNhbWVWYWx1ZWAuXG4gKlxuICogQHBhcmFtIHtSZWdFeHB9IGFcbiAqIEBwYXJhbSB7UmVnRXhwfSBiXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuXG5mdW5jdGlvbiByZWdleHBFcXVhbChhLCBiKSB7XG4gIGlmICgncmVnZXhwJyAhPT0gdHlwZShiKSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gc2FtZVZhbHVlKGEudG9TdHJpbmcoKSwgYi50b1N0cmluZygpKTtcbn1cblxuLyohXG4gKiBBc3NlcnQgZGVlcCBlcXVhbGl0eSBvZiB0d28gYGFyZ3VtZW50c2Agb2JqZWN0cy5cbiAqIFVuZm9ydHVuYXRlbHksIHRoZXNlIG11c3QgYmUgc2xpY2VkIHRvIGFycmF5c1xuICogcHJpb3IgdG8gdGVzdCB0byBlbnN1cmUgbm8gYmFkIGJlaGF2aW9yLlxuICpcbiAqIEBwYXJhbSB7QXJndW1lbnRzfSBhXG4gKiBAcGFyYW0ge0FyZ3VtZW50c30gYlxuICogQHBhcmFtIHtBcnJheX0gbWVtb2l6ZSAob3B0aW9uYWwpXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuXG5mdW5jdGlvbiBhcmd1bWVudHNFcXVhbChhLCBiLCBtKSB7XG4gIGlmICgnYXJndW1lbnRzJyAhPT0gdHlwZShiKSkgcmV0dXJuIGZhbHNlO1xuICBhID0gW10uc2xpY2UuY2FsbChhKTtcbiAgYiA9IFtdLnNsaWNlLmNhbGwoYik7XG4gIHJldHVybiBkZWVwRXF1YWwoYSwgYiwgbSk7XG59XG5cbi8qIVxuICogR2V0IGVudW1lcmFibGUgcHJvcGVydGllcyBvZiBhIGdpdmVuIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gYVxuICogQHJldHVybiB7QXJyYXl9IHByb3BlcnR5IG5hbWVzXG4gKi9cblxuZnVuY3Rpb24gZW51bWVyYWJsZShhKSB7XG4gIHZhciByZXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIGEpIHJlcy5wdXNoKGtleSk7XG4gIHJldHVybiByZXM7XG59XG5cbi8qIVxuICogU2ltcGxlIGVxdWFsaXR5IGZvciBmbGF0IGl0ZXJhYmxlIG9iamVjdHNcbiAqIHN1Y2ggYXMgQXJyYXlzIG9yIE5vZGUuanMgYnVmZmVycy5cbiAqXG4gKiBAcGFyYW0ge0l0ZXJhYmxlfSBhXG4gKiBAcGFyYW0ge0l0ZXJhYmxlfSBiXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqL1xuXG5mdW5jdGlvbiBpdGVyYWJsZUVxdWFsKGEsIGIpIHtcbiAgaWYgKGEubGVuZ3RoICE9PSAgYi5sZW5ndGgpIHJldHVybiBmYWxzZTtcblxuICB2YXIgaSA9IDA7XG4gIHZhciBtYXRjaCA9IHRydWU7XG5cbiAgZm9yICg7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGFbaV0gIT09IGJbaV0pIHtcbiAgICAgIG1hdGNoID0gZmFsc2U7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWF0Y2g7XG59XG5cbi8qIVxuICogRXh0ZW5zaW9uIHRvIGBpdGVyYWJsZUVxdWFsYCBzcGVjaWZpY2FsbHlcbiAqIGZvciBOb2RlLmpzIEJ1ZmZlcnMuXG4gKlxuICogQHBhcmFtIHtCdWZmZXJ9IGFcbiAqIEBwYXJhbSB7TWl4ZWR9IGJcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHJlc3VsdFxuICovXG5cbmZ1bmN0aW9uIGJ1ZmZlckVxdWFsKGEsIGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIGl0ZXJhYmxlRXF1YWwoYSwgYik7XG59XG5cbi8qIVxuICogQmxvY2sgZm9yIGBvYmplY3RFcXVhbGAgZW5zdXJpbmcgbm9uLWV4aXN0aW5nXG4gKiB2YWx1ZXMgZG9uJ3QgZ2V0IGluLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IG9iamVjdFxuICogQHJldHVybiB7Qm9vbGVhbn0gcmVzdWx0XG4gKi9cblxuZnVuY3Rpb24gaXNWYWx1ZShhKSB7XG4gIHJldHVybiBhICE9PSBudWxsICYmIGEgIT09IHVuZGVmaW5lZDtcbn1cblxuLyohXG4gKiBSZWN1cnNpdmVseSBjaGVjayB0aGUgZXF1YWxpdHkgb2YgdHdvIG9iamVjdHMuXG4gKiBPbmNlIGJhc2ljIHNhbWVuZXNzIGhhcyBiZWVuIGVzdGFibGlzaGVkIGl0IHdpbGxcbiAqIGRlZmVyIHRvIGBkZWVwRXF1YWxgIGZvciBlYWNoIGVudW1lcmFibGUga2V5XG4gKiBpbiB0aGUgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IGFcbiAqIEBwYXJhbSB7TWl4ZWR9IGJcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHJlc3VsdFxuICovXG5cbmZ1bmN0aW9uIG9iamVjdEVxdWFsKGEsIGIsIG0pIHtcbiAgaWYgKCFpc1ZhbHVlKGEpIHx8ICFpc1ZhbHVlKGIpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGEucHJvdG90eXBlICE9PSBiLnByb3RvdHlwZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBpO1xuICBpZiAobSkge1xuICAgIGZvciAoaSA9IDA7IGkgPCBtLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoKG1baV1bMF0gPT09IGEgJiYgbVtpXVsxXSA9PT0gYilcbiAgICAgIHx8ICAobVtpXVswXSA9PT0gYiAmJiBtW2ldWzFdID09PSBhKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgbSA9IFtdO1xuICB9XG5cbiAgdHJ5IHtcbiAgICB2YXIga2EgPSBlbnVtZXJhYmxlKGEpO1xuICAgIHZhciBrYiA9IGVudW1lcmFibGUoYik7XG4gIH0gY2F0Y2ggKGV4KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAga2Euc29ydCgpO1xuICBrYi5zb3J0KCk7XG5cbiAgaWYgKCFpdGVyYWJsZUVxdWFsKGthLCBrYikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBtLnB1c2goWyBhLCBiIF0pO1xuXG4gIHZhciBrZXk7XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAga2V5ID0ga2FbaV07XG4gICAgaWYgKCFkZWVwRXF1YWwoYVtrZXldLCBiW2tleV0sIG0pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG4iLCIvKiFcbiAgICBsb2NhbEZvcmFnZSAtLSBPZmZsaW5lIFN0b3JhZ2UsIEltcHJvdmVkXG4gICAgVmVyc2lvbiAxLjUuMFxuICAgIGh0dHBzOi8vbG9jYWxmb3JhZ2UuZ2l0aHViLmlvL2xvY2FsRm9yYWdlXG4gICAgKGMpIDIwMTMtMjAxNyBNb3ppbGxhLCBBcGFjaGUgTGljZW5zZSAyLjBcbiovXG4oZnVuY3Rpb24oZil7aWYodHlwZW9mIGV4cG9ydHM9PT1cIm9iamVjdFwiJiZ0eXBlb2YgbW9kdWxlIT09XCJ1bmRlZmluZWRcIil7bW9kdWxlLmV4cG9ydHM9ZigpfWVsc2UgaWYodHlwZW9mIGRlZmluZT09PVwiZnVuY3Rpb25cIiYmZGVmaW5lLmFtZCl7ZGVmaW5lKFtdLGYpfWVsc2V7dmFyIGc7aWYodHlwZW9mIHdpbmRvdyE9PVwidW5kZWZpbmVkXCIpe2c9d2luZG93fWVsc2UgaWYodHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCIpe2c9Z2xvYmFsfWVsc2UgaWYodHlwZW9mIHNlbGYhPT1cInVuZGVmaW5lZFwiKXtnPXNlbGZ9ZWxzZXtnPXRoaXN9Zy5sb2NhbGZvcmFnZSA9IGYoKX19KShmdW5jdGlvbigpe3ZhciBkZWZpbmUsbW9kdWxlLGV4cG9ydHM7cmV0dXJuIChmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyAoZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLCBmKX12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pKHsxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbihmdW5jdGlvbiAoZ2xvYmFsKXtcbid1c2Ugc3RyaWN0JztcbnZhciBNdXRhdGlvbiA9IGdsb2JhbC5NdXRhdGlvbk9ic2VydmVyIHx8IGdsb2JhbC5XZWJLaXRNdXRhdGlvbk9ic2VydmVyO1xuXG52YXIgc2NoZWR1bGVEcmFpbjtcblxue1xuICBpZiAoTXV0YXRpb24pIHtcbiAgICB2YXIgY2FsbGVkID0gMDtcbiAgICB2YXIgb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb24obmV4dFRpY2spO1xuICAgIHZhciBlbGVtZW50ID0gZ2xvYmFsLmRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcnKTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKGVsZW1lbnQsIHtcbiAgICAgIGNoYXJhY3RlckRhdGE6IHRydWVcbiAgICB9KTtcbiAgICBzY2hlZHVsZURyYWluID0gZnVuY3Rpb24gKCkge1xuICAgICAgZWxlbWVudC5kYXRhID0gKGNhbGxlZCA9ICsrY2FsbGVkICUgMik7XG4gICAgfTtcbiAgfSBlbHNlIGlmICghZ2xvYmFsLnNldEltbWVkaWF0ZSAmJiB0eXBlb2YgZ2xvYmFsLk1lc3NhZ2VDaGFubmVsICE9PSAndW5kZWZpbmVkJykge1xuICAgIHZhciBjaGFubmVsID0gbmV3IGdsb2JhbC5NZXNzYWdlQ2hhbm5lbCgpO1xuICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gbmV4dFRpY2s7XG4gICAgc2NoZWR1bGVEcmFpbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4gICAgfTtcbiAgfSBlbHNlIGlmICgnZG9jdW1lbnQnIGluIGdsb2JhbCAmJiAnb25yZWFkeXN0YXRlY2hhbmdlJyBpbiBnbG9iYWwuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0JykpIHtcbiAgICBzY2hlZHVsZURyYWluID0gZnVuY3Rpb24gKCkge1xuXG4gICAgICAvLyBDcmVhdGUgYSA8c2NyaXB0PiBlbGVtZW50OyBpdHMgcmVhZHlzdGF0ZWNoYW5nZSBldmVudCB3aWxsIGJlIGZpcmVkIGFzeW5jaHJvbm91c2x5IG9uY2UgaXQgaXMgaW5zZXJ0ZWRcbiAgICAgIC8vIGludG8gdGhlIGRvY3VtZW50LiBEbyBzbywgdGh1cyBxdWV1aW5nIHVwIHRoZSB0YXNrLiBSZW1lbWJlciB0byBjbGVhbiB1cCBvbmNlIGl0J3MgYmVlbiBjYWxsZWQuXG4gICAgICB2YXIgc2NyaXB0RWwgPSBnbG9iYWwuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gICAgICBzY3JpcHRFbC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5leHRUaWNrKCk7XG5cbiAgICAgICAgc2NyaXB0RWwub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbDtcbiAgICAgICAgc2NyaXB0RWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChzY3JpcHRFbCk7XG4gICAgICAgIHNjcmlwdEVsID0gbnVsbDtcbiAgICAgIH07XG4gICAgICBnbG9iYWwuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKHNjcmlwdEVsKTtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHNjaGVkdWxlRHJhaW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICBzZXRUaW1lb3V0KG5leHRUaWNrLCAwKTtcbiAgICB9O1xuICB9XG59XG5cbnZhciBkcmFpbmluZztcbnZhciBxdWV1ZSA9IFtdO1xuLy9uYW1lZCBuZXh0VGljayBmb3IgbGVzcyBjb25mdXNpbmcgc3RhY2sgdHJhY2VzXG5mdW5jdGlvbiBuZXh0VGljaygpIHtcbiAgZHJhaW5pbmcgPSB0cnVlO1xuICB2YXIgaSwgb2xkUXVldWU7XG4gIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gIHdoaWxlIChsZW4pIHtcbiAgICBvbGRRdWV1ZSA9IHF1ZXVlO1xuICAgIHF1ZXVlID0gW107XG4gICAgaSA9IC0xO1xuICAgIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICAgIG9sZFF1ZXVlW2ldKCk7XG4gICAgfVxuICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgfVxuICBkcmFpbmluZyA9IGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGltbWVkaWF0ZTtcbmZ1bmN0aW9uIGltbWVkaWF0ZSh0YXNrKSB7XG4gIGlmIChxdWV1ZS5wdXNoKHRhc2spID09PSAxICYmICFkcmFpbmluZykge1xuICAgIHNjaGVkdWxlRHJhaW4oKTtcbiAgfVxufVxuXG59KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSlcbn0se31dLDI6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xudmFyIGltbWVkaWF0ZSA9IF9kZXJlcV8oMSk7XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBJTlRFUk5BTCgpIHt9XG5cbnZhciBoYW5kbGVycyA9IHt9O1xuXG52YXIgUkVKRUNURUQgPSBbJ1JFSkVDVEVEJ107XG52YXIgRlVMRklMTEVEID0gWydGVUxGSUxMRUQnXTtcbnZhciBQRU5ESU5HID0gWydQRU5ESU5HJ107XG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IFByb21pc2U7XG5cbmZ1bmN0aW9uIFByb21pc2UocmVzb2x2ZXIpIHtcbiAgaWYgKHR5cGVvZiByZXNvbHZlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3Jlc29sdmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB9XG4gIHRoaXMuc3RhdGUgPSBQRU5ESU5HO1xuICB0aGlzLnF1ZXVlID0gW107XG4gIHRoaXMub3V0Y29tZSA9IHZvaWQgMDtcbiAgaWYgKHJlc29sdmVyICE9PSBJTlRFUk5BTCkge1xuICAgIHNhZmVseVJlc29sdmVUaGVuYWJsZSh0aGlzLCByZXNvbHZlcik7XG4gIH1cbn1cblxuUHJvbWlzZS5wcm90b3R5cGVbXCJjYXRjaFwiXSA9IGZ1bmN0aW9uIChvblJlamVjdGVkKSB7XG4gIHJldHVybiB0aGlzLnRoZW4obnVsbCwgb25SZWplY3RlZCk7XG59O1xuUHJvbWlzZS5wcm90b3R5cGUudGhlbiA9IGZ1bmN0aW9uIChvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuICBpZiAodHlwZW9mIG9uRnVsZmlsbGVkICE9PSAnZnVuY3Rpb24nICYmIHRoaXMuc3RhdGUgPT09IEZVTEZJTExFRCB8fFxuICAgIHR5cGVvZiBvblJlamVjdGVkICE9PSAnZnVuY3Rpb24nICYmIHRoaXMuc3RhdGUgPT09IFJFSkVDVEVEKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgdmFyIHByb21pc2UgPSBuZXcgdGhpcy5jb25zdHJ1Y3RvcihJTlRFUk5BTCk7XG4gIGlmICh0aGlzLnN0YXRlICE9PSBQRU5ESU5HKSB7XG4gICAgdmFyIHJlc29sdmVyID0gdGhpcy5zdGF0ZSA9PT0gRlVMRklMTEVEID8gb25GdWxmaWxsZWQgOiBvblJlamVjdGVkO1xuICAgIHVud3JhcChwcm9taXNlLCByZXNvbHZlciwgdGhpcy5vdXRjb21lKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnF1ZXVlLnB1c2gobmV3IFF1ZXVlSXRlbShwcm9taXNlLCBvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkpO1xuICB9XG5cbiAgcmV0dXJuIHByb21pc2U7XG59O1xuZnVuY3Rpb24gUXVldWVJdGVtKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKSB7XG4gIHRoaXMucHJvbWlzZSA9IHByb21pc2U7XG4gIGlmICh0eXBlb2Ygb25GdWxmaWxsZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0aGlzLm9uRnVsZmlsbGVkID0gb25GdWxmaWxsZWQ7XG4gICAgdGhpcy5jYWxsRnVsZmlsbGVkID0gdGhpcy5vdGhlckNhbGxGdWxmaWxsZWQ7XG4gIH1cbiAgaWYgKHR5cGVvZiBvblJlamVjdGVkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhpcy5vblJlamVjdGVkID0gb25SZWplY3RlZDtcbiAgICB0aGlzLmNhbGxSZWplY3RlZCA9IHRoaXMub3RoZXJDYWxsUmVqZWN0ZWQ7XG4gIH1cbn1cblF1ZXVlSXRlbS5wcm90b3R5cGUuY2FsbEZ1bGZpbGxlZCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICBoYW5kbGVycy5yZXNvbHZlKHRoaXMucHJvbWlzZSwgdmFsdWUpO1xufTtcblF1ZXVlSXRlbS5wcm90b3R5cGUub3RoZXJDYWxsRnVsZmlsbGVkID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gIHVud3JhcCh0aGlzLnByb21pc2UsIHRoaXMub25GdWxmaWxsZWQsIHZhbHVlKTtcbn07XG5RdWV1ZUl0ZW0ucHJvdG90eXBlLmNhbGxSZWplY3RlZCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICBoYW5kbGVycy5yZWplY3QodGhpcy5wcm9taXNlLCB2YWx1ZSk7XG59O1xuUXVldWVJdGVtLnByb3RvdHlwZS5vdGhlckNhbGxSZWplY3RlZCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICB1bndyYXAodGhpcy5wcm9taXNlLCB0aGlzLm9uUmVqZWN0ZWQsIHZhbHVlKTtcbn07XG5cbmZ1bmN0aW9uIHVud3JhcChwcm9taXNlLCBmdW5jLCB2YWx1ZSkge1xuICBpbW1lZGlhdGUoZnVuY3Rpb24gKCkge1xuICAgIHZhciByZXR1cm5WYWx1ZTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuVmFsdWUgPSBmdW5jKHZhbHVlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gaGFuZGxlcnMucmVqZWN0KHByb21pc2UsIGUpO1xuICAgIH1cbiAgICBpZiAocmV0dXJuVmFsdWUgPT09IHByb21pc2UpIHtcbiAgICAgIGhhbmRsZXJzLnJlamVjdChwcm9taXNlLCBuZXcgVHlwZUVycm9yKCdDYW5ub3QgcmVzb2x2ZSBwcm9taXNlIHdpdGggaXRzZWxmJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICBoYW5kbGVycy5yZXNvbHZlKHByb21pc2UsIHJldHVyblZhbHVlKTtcbiAgICB9XG4gIH0pO1xufVxuXG5oYW5kbGVycy5yZXNvbHZlID0gZnVuY3Rpb24gKHNlbGYsIHZhbHVlKSB7XG4gIHZhciByZXN1bHQgPSB0cnlDYXRjaChnZXRUaGVuLCB2YWx1ZSk7XG4gIGlmIChyZXN1bHQuc3RhdHVzID09PSAnZXJyb3InKSB7XG4gICAgcmV0dXJuIGhhbmRsZXJzLnJlamVjdChzZWxmLCByZXN1bHQudmFsdWUpO1xuICB9XG4gIHZhciB0aGVuYWJsZSA9IHJlc3VsdC52YWx1ZTtcblxuICBpZiAodGhlbmFibGUpIHtcbiAgICBzYWZlbHlSZXNvbHZlVGhlbmFibGUoc2VsZiwgdGhlbmFibGUpO1xuICB9IGVsc2Uge1xuICAgIHNlbGYuc3RhdGUgPSBGVUxGSUxMRUQ7XG4gICAgc2VsZi5vdXRjb21lID0gdmFsdWU7XG4gICAgdmFyIGkgPSAtMTtcbiAgICB2YXIgbGVuID0gc2VsZi5xdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgICAgc2VsZi5xdWV1ZVtpXS5jYWxsRnVsZmlsbGVkKHZhbHVlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHNlbGY7XG59O1xuaGFuZGxlcnMucmVqZWN0ID0gZnVuY3Rpb24gKHNlbGYsIGVycm9yKSB7XG4gIHNlbGYuc3RhdGUgPSBSRUpFQ1RFRDtcbiAgc2VsZi5vdXRjb21lID0gZXJyb3I7XG4gIHZhciBpID0gLTE7XG4gIHZhciBsZW4gPSBzZWxmLnF1ZXVlLmxlbmd0aDtcbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIHNlbGYucXVldWVbaV0uY2FsbFJlamVjdGVkKGVycm9yKTtcbiAgfVxuICByZXR1cm4gc2VsZjtcbn07XG5cbmZ1bmN0aW9uIGdldFRoZW4ob2JqKSB7XG4gIC8vIE1ha2Ugc3VyZSB3ZSBvbmx5IGFjY2VzcyB0aGUgYWNjZXNzb3Igb25jZSBhcyByZXF1aXJlZCBieSB0aGUgc3BlY1xuICB2YXIgdGhlbiA9IG9iaiAmJiBvYmoudGhlbjtcbiAgaWYgKG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgdGhlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBmdW5jdGlvbiBhcHB5VGhlbigpIHtcbiAgICAgIHRoZW4uYXBwbHkob2JqLCBhcmd1bWVudHMpO1xuICAgIH07XG4gIH1cbn1cblxuZnVuY3Rpb24gc2FmZWx5UmVzb2x2ZVRoZW5hYmxlKHNlbGYsIHRoZW5hYmxlKSB7XG4gIC8vIEVpdGhlciBmdWxmaWxsLCByZWplY3Qgb3IgcmVqZWN0IHdpdGggZXJyb3JcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBvbkVycm9yKHZhbHVlKSB7XG4gICAgaWYgKGNhbGxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjYWxsZWQgPSB0cnVlO1xuICAgIGhhbmRsZXJzLnJlamVjdChzZWxmLCB2YWx1ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBvblN1Y2Nlc3ModmFsdWUpIHtcbiAgICBpZiAoY2FsbGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNhbGxlZCA9IHRydWU7XG4gICAgaGFuZGxlcnMucmVzb2x2ZShzZWxmLCB2YWx1ZSk7XG4gIH1cblxuICBmdW5jdGlvbiB0cnlUb1Vud3JhcCgpIHtcbiAgICB0aGVuYWJsZShvblN1Y2Nlc3MsIG9uRXJyb3IpO1xuICB9XG5cbiAgdmFyIHJlc3VsdCA9IHRyeUNhdGNoKHRyeVRvVW53cmFwKTtcbiAgaWYgKHJlc3VsdC5zdGF0dXMgPT09ICdlcnJvcicpIHtcbiAgICBvbkVycm9yKHJlc3VsdC52YWx1ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gdHJ5Q2F0Y2goZnVuYywgdmFsdWUpIHtcbiAgdmFyIG91dCA9IHt9O1xuICB0cnkge1xuICAgIG91dC52YWx1ZSA9IGZ1bmModmFsdWUpO1xuICAgIG91dC5zdGF0dXMgPSAnc3VjY2Vzcyc7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBvdXQuc3RhdHVzID0gJ2Vycm9yJztcbiAgICBvdXQudmFsdWUgPSBlO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbmV4cG9ydHMucmVzb2x2ZSA9IHJlc29sdmU7XG5mdW5jdGlvbiByZXNvbHZlKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIHRoaXMpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIGhhbmRsZXJzLnJlc29sdmUobmV3IHRoaXMoSU5URVJOQUwpLCB2YWx1ZSk7XG59XG5cbmV4cG9ydHMucmVqZWN0ID0gcmVqZWN0O1xuZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICB2YXIgcHJvbWlzZSA9IG5ldyB0aGlzKElOVEVSTkFMKTtcbiAgcmV0dXJuIGhhbmRsZXJzLnJlamVjdChwcm9taXNlLCByZWFzb24pO1xufVxuXG5leHBvcnRzLmFsbCA9IGFsbDtcbmZ1bmN0aW9uIGFsbChpdGVyYWJsZSkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaXRlcmFibGUpICE9PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgcmV0dXJuIHRoaXMucmVqZWN0KG5ldyBUeXBlRXJyb3IoJ211c3QgYmUgYW4gYXJyYXknKSk7XG4gIH1cblxuICB2YXIgbGVuID0gaXRlcmFibGUubGVuZ3RoO1xuICB2YXIgY2FsbGVkID0gZmFsc2U7XG4gIGlmICghbGVuKSB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZShbXSk7XG4gIH1cblxuICB2YXIgdmFsdWVzID0gbmV3IEFycmF5KGxlbik7XG4gIHZhciByZXNvbHZlZCA9IDA7XG4gIHZhciBpID0gLTE7XG4gIHZhciBwcm9taXNlID0gbmV3IHRoaXMoSU5URVJOQUwpO1xuXG4gIHdoaWxlICgrK2kgPCBsZW4pIHtcbiAgICBhbGxSZXNvbHZlcihpdGVyYWJsZVtpXSwgaSk7XG4gIH1cbiAgcmV0dXJuIHByb21pc2U7XG4gIGZ1bmN0aW9uIGFsbFJlc29sdmVyKHZhbHVlLCBpKSB7XG4gICAgc2VsZi5yZXNvbHZlKHZhbHVlKS50aGVuKHJlc29sdmVGcm9tQWxsLCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGlmICghY2FsbGVkKSB7XG4gICAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICAgIGhhbmRsZXJzLnJlamVjdChwcm9taXNlLCBlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgZnVuY3Rpb24gcmVzb2x2ZUZyb21BbGwob3V0VmFsdWUpIHtcbiAgICAgIHZhbHVlc1tpXSA9IG91dFZhbHVlO1xuICAgICAgaWYgKCsrcmVzb2x2ZWQgPT09IGxlbiAmJiAhY2FsbGVkKSB7XG4gICAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICAgIGhhbmRsZXJzLnJlc29sdmUocHJvbWlzZSwgdmFsdWVzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0cy5yYWNlID0gcmFjZTtcbmZ1bmN0aW9uIHJhY2UoaXRlcmFibGUpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGl0ZXJhYmxlKSAhPT0gJ1tvYmplY3QgQXJyYXldJykge1xuICAgIHJldHVybiB0aGlzLnJlamVjdChuZXcgVHlwZUVycm9yKCdtdXN0IGJlIGFuIGFycmF5JykpO1xuICB9XG5cbiAgdmFyIGxlbiA9IGl0ZXJhYmxlLmxlbmd0aDtcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICBpZiAoIWxlbikge1xuICAgIHJldHVybiB0aGlzLnJlc29sdmUoW10pO1xuICB9XG5cbiAgdmFyIGkgPSAtMTtcbiAgdmFyIHByb21pc2UgPSBuZXcgdGhpcyhJTlRFUk5BTCk7XG5cbiAgd2hpbGUgKCsraSA8IGxlbikge1xuICAgIHJlc29sdmVyKGl0ZXJhYmxlW2ldKTtcbiAgfVxuICByZXR1cm4gcHJvbWlzZTtcbiAgZnVuY3Rpb24gcmVzb2x2ZXIodmFsdWUpIHtcbiAgICBzZWxmLnJlc29sdmUodmFsdWUpLnRoZW4oZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICBpZiAoIWNhbGxlZCkge1xuICAgICAgICBjYWxsZWQgPSB0cnVlO1xuICAgICAgICBoYW5kbGVycy5yZXNvbHZlKHByb21pc2UsIHJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGlmICghY2FsbGVkKSB7XG4gICAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICAgIGhhbmRsZXJzLnJlamVjdChwcm9taXNlLCBlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxufSx7XCIxXCI6MX1dLDM6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuKGZ1bmN0aW9uIChnbG9iYWwpe1xuJ3VzZSBzdHJpY3QnO1xuaWYgKHR5cGVvZiBnbG9iYWwuUHJvbWlzZSAhPT0gJ2Z1bmN0aW9uJykge1xuICBnbG9iYWwuUHJvbWlzZSA9IF9kZXJlcV8oMik7XG59XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KVxufSx7XCIyXCI6Mn1dLDQ6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiID8gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfSA6IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTsgfSB9XG5cbmZ1bmN0aW9uIGdldElEQigpIHtcbiAgICAvKiBnbG9iYWwgaW5kZXhlZERCLHdlYmtpdEluZGV4ZWREQixtb3pJbmRleGVkREIsT0luZGV4ZWREQixtc0luZGV4ZWREQiAqL1xuICAgIHRyeSB7XG4gICAgICAgIGlmICh0eXBlb2YgaW5kZXhlZERCICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcmV0dXJuIGluZGV4ZWREQjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHdlYmtpdEluZGV4ZWREQiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHJldHVybiB3ZWJraXRJbmRleGVkREI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBtb3pJbmRleGVkREIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICByZXR1cm4gbW96SW5kZXhlZERCO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgT0luZGV4ZWREQiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHJldHVybiBPSW5kZXhlZERCO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgbXNJbmRleGVkREIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICByZXR1cm4gbXNJbmRleGVkREI7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7fVxufVxuXG52YXIgaWRiID0gZ2V0SURCKCk7XG5cbmZ1bmN0aW9uIGlzSW5kZXhlZERCVmFsaWQoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBJbmRleGVkREI7IGZhbGwgYmFjayB0byB2ZW5kb3ItcHJlZml4ZWQgdmVyc2lvbnNcbiAgICAgICAgLy8gaWYgbmVlZGVkLlxuICAgICAgICBpZiAoIWlkYikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIC8vIFdlIG1pbWljIFBvdWNoREIgaGVyZTtcbiAgICAgICAgLy9cbiAgICAgICAgLy8gV2UgdGVzdCBmb3Igb3BlbkRhdGFiYXNlIGJlY2F1c2UgSUUgTW9iaWxlIGlkZW50aWZpZXMgaXRzZWxmXG4gICAgICAgIC8vIGFzIFNhZmFyaS4gT2ggdGhlIGx1bHouLi5cbiAgICAgICAgdmFyIGlzU2FmYXJpID0gdHlwZW9mIG9wZW5EYXRhYmFzZSAhPT0gJ3VuZGVmaW5lZCcgJiYgLyhTYWZhcml8aVBob25lfGlQYWR8aVBvZCkvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgJiYgIS9DaHJvbWUvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgJiYgIS9CbGFja0JlcnJ5Ly50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSk7XG5cbiAgICAgICAgdmFyIGhhc0ZldGNoID0gdHlwZW9mIGZldGNoID09PSAnZnVuY3Rpb24nICYmIGZldGNoLnRvU3RyaW5nKCkuaW5kZXhPZignW25hdGl2ZSBjb2RlJykgIT09IC0xO1xuXG4gICAgICAgIC8vIFNhZmFyaSA8MTAuMSBkb2VzIG5vdCBtZWV0IG91ciByZXF1aXJlbWVudHMgZm9yIElEQiBzdXBwb3J0ICgjNTU3MilcbiAgICAgICAgLy8gc2luY2UgU2FmYXJpIDEwLjEgc2hpcHBlZCB3aXRoIGZldGNoLCB3ZSBjYW4gdXNlIHRoYXQgdG8gZGV0ZWN0IGl0XG4gICAgICAgIHJldHVybiAoIWlzU2FmYXJpIHx8IGhhc0ZldGNoKSAmJiB0eXBlb2YgaW5kZXhlZERCICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAvLyBzb21lIG91dGRhdGVkIGltcGxlbWVudGF0aW9ucyBvZiBJREIgdGhhdCBhcHBlYXIgb24gU2Ftc3VuZ1xuICAgICAgICAvLyBhbmQgSFRDIEFuZHJvaWQgZGV2aWNlcyA8NC40IGFyZSBtaXNzaW5nIElEQktleVJhbmdlXG4gICAgICAgIHR5cGVvZiBJREJLZXlSYW5nZSAhPT0gJ3VuZGVmaW5lZCc7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc1dlYlNRTFZhbGlkKCkge1xuICAgIHJldHVybiB0eXBlb2Ygb3BlbkRhdGFiYXNlID09PSAnZnVuY3Rpb24nO1xufVxuXG5mdW5jdGlvbiBpc0xvY2FsU3RvcmFnZVZhbGlkKCkge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgbG9jYWxTdG9yYWdlICE9PSAndW5kZWZpbmVkJyAmJiAnc2V0SXRlbScgaW4gbG9jYWxTdG9yYWdlICYmIGxvY2FsU3RvcmFnZS5zZXRJdGVtO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cblxuLy8gQWJzdHJhY3RzIGNvbnN0cnVjdGluZyBhIEJsb2Igb2JqZWN0LCBzbyBpdCBhbHNvIHdvcmtzIGluIG9sZGVyXG4vLyBicm93c2VycyB0aGF0IGRvbid0IHN1cHBvcnQgdGhlIG5hdGl2ZSBCbG9iIGNvbnN0cnVjdG9yLiAoaS5lLlxuLy8gb2xkIFF0V2ViS2l0IHZlcnNpb25zLCBhdCBsZWFzdCkuXG4vLyBBYnN0cmFjdHMgY29uc3RydWN0aW5nIGEgQmxvYiBvYmplY3QsIHNvIGl0IGFsc28gd29ya3MgaW4gb2xkZXJcbi8vIGJyb3dzZXJzIHRoYXQgZG9uJ3Qgc3VwcG9ydCB0aGUgbmF0aXZlIEJsb2IgY29uc3RydWN0b3IuIChpLmUuXG4vLyBvbGQgUXRXZWJLaXQgdmVyc2lvbnMsIGF0IGxlYXN0KS5cbmZ1bmN0aW9uIGNyZWF0ZUJsb2IocGFydHMsIHByb3BlcnRpZXMpIHtcbiAgICAvKiBnbG9iYWwgQmxvYkJ1aWxkZXIsTVNCbG9iQnVpbGRlcixNb3pCbG9iQnVpbGRlcixXZWJLaXRCbG9iQnVpbGRlciAqL1xuICAgIHBhcnRzID0gcGFydHMgfHwgW107XG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgfHwge307XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5ldyBCbG9iKHBhcnRzLCBwcm9wZXJ0aWVzKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChlLm5hbWUgIT09ICdUeXBlRXJyb3InKSB7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBCdWlsZGVyID0gdHlwZW9mIEJsb2JCdWlsZGVyICE9PSAndW5kZWZpbmVkJyA/IEJsb2JCdWlsZGVyIDogdHlwZW9mIE1TQmxvYkJ1aWxkZXIgIT09ICd1bmRlZmluZWQnID8gTVNCbG9iQnVpbGRlciA6IHR5cGVvZiBNb3pCbG9iQnVpbGRlciAhPT0gJ3VuZGVmaW5lZCcgPyBNb3pCbG9iQnVpbGRlciA6IFdlYktpdEJsb2JCdWlsZGVyO1xuICAgICAgICB2YXIgYnVpbGRlciA9IG5ldyBCdWlsZGVyKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGJ1aWxkZXIuYXBwZW5kKHBhcnRzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYnVpbGRlci5nZXRCbG9iKHByb3BlcnRpZXMudHlwZSk7XG4gICAgfVxufVxuXG4vLyBUaGlzIGlzIENvbW1vbkpTIGJlY2F1c2UgbGllIGlzIGFuIGV4dGVybmFsIGRlcGVuZGVuY3ksIHNvIFJvbGx1cFxuLy8gY2FuIGp1c3QgaWdub3JlIGl0LlxuaWYgKHR5cGVvZiBQcm9taXNlID09PSAndW5kZWZpbmVkJykge1xuICAgIC8vIEluIHRoZSBcIm5vcHJvbWlzZXNcIiBidWlsZCB0aGlzIHdpbGwganVzdCB0aHJvdyBpZiB5b3UgZG9uJ3QgaGF2ZVxuICAgIC8vIGEgZ2xvYmFsIHByb21pc2Ugb2JqZWN0LCBidXQgaXQgd291bGQgdGhyb3cgYW55d2F5IGxhdGVyLlxuICAgIF9kZXJlcV8oMyk7XG59XG52YXIgUHJvbWlzZSQxID0gUHJvbWlzZTtcblxuZnVuY3Rpb24gZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgIHByb21pc2UudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgICAgICBjYWxsYmFjayhudWxsLCByZXN1bHQpO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBleGVjdXRlVHdvQ2FsbGJhY2tzKHByb21pc2UsIGNhbGxiYWNrLCBlcnJvckNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwcm9taXNlLnRoZW4oY2FsbGJhY2spO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZXJyb3JDYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwcm9taXNlW1wiY2F0Y2hcIl0oZXJyb3JDYWxsYmFjayk7XG4gICAgfVxufVxuXG4vLyBTb21lIGNvZGUgb3JpZ2luYWxseSBmcm9tIGFzeW5jX3N0b3JhZ2UuanMgaW5cbi8vIFtHYWlhXShodHRwczovL2dpdGh1Yi5jb20vbW96aWxsYS1iMmcvZ2FpYSkuXG5cbnZhciBERVRFQ1RfQkxPQl9TVVBQT1JUX1NUT1JFID0gJ2xvY2FsLWZvcmFnZS1kZXRlY3QtYmxvYi1zdXBwb3J0JztcbnZhciBzdXBwb3J0c0Jsb2JzO1xudmFyIGRiQ29udGV4dHM7XG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vLyBUcmFuc2Zvcm0gYSBiaW5hcnkgc3RyaW5nIHRvIGFuIGFycmF5IGJ1ZmZlciwgYmVjYXVzZSBvdGhlcndpc2Vcbi8vIHdlaXJkIHN0dWZmIGhhcHBlbnMgd2hlbiB5b3UgdHJ5IHRvIHdvcmsgd2l0aCB0aGUgYmluYXJ5IHN0cmluZyBkaXJlY3RseS5cbi8vIEl0IGlzIGtub3duLlxuLy8gRnJvbSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzE0OTY3NjQ3LyAoY29udGludWVzIG9uIG5leHQgbGluZSlcbi8vIGVuY29kZS1kZWNvZGUtaW1hZ2Utd2l0aC1iYXNlNjQtYnJlYWtzLWltYWdlICgyMDEzLTA0LTIxKVxuZnVuY3Rpb24gX2JpblN0cmluZ1RvQXJyYXlCdWZmZXIoYmluKSB7XG4gICAgdmFyIGxlbmd0aCA9IGJpbi5sZW5ndGg7XG4gICAgdmFyIGJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcihsZW5ndGgpO1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheShidWYpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYXJyW2ldID0gYmluLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuICAgIHJldHVybiBidWY7XG59XG5cbi8vXG4vLyBCbG9icyBhcmUgbm90IHN1cHBvcnRlZCBpbiBhbGwgdmVyc2lvbnMgb2YgSW5kZXhlZERCLCBub3RhYmx5XG4vLyBDaHJvbWUgPDM3IGFuZCBBbmRyb2lkIDw1LiBJbiB0aG9zZSB2ZXJzaW9ucywgc3RvcmluZyBhIGJsb2Igd2lsbCB0aHJvdy5cbi8vXG4vLyBWYXJpb3VzIG90aGVyIGJsb2IgYnVncyBleGlzdCBpbiBDaHJvbWUgdjM3LTQyIChpbmNsdXNpdmUpLlxuLy8gRGV0ZWN0aW5nIHRoZW0gaXMgZXhwZW5zaXZlIGFuZCBjb25mdXNpbmcgdG8gdXNlcnMsIGFuZCBDaHJvbWUgMzctNDJcbi8vIGlzIGF0IHZlcnkgbG93IHVzYWdlIHdvcmxkd2lkZSwgc28gd2UgZG8gYSBoYWNreSB1c2VyQWdlbnQgY2hlY2sgaW5zdGVhZC5cbi8vXG4vLyBjb250ZW50LXR5cGUgYnVnOiBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NDA4MTIwXG4vLyA0MDQgYnVnOiBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NDQ3OTE2XG4vLyBGaWxlUmVhZGVyIGJ1ZzogaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTQ0NzgzNlxuLy9cbi8vIENvZGUgYm9ycm93ZWQgZnJvbSBQb3VjaERCLiBTZWU6XG4vLyBodHRwczovL2dpdGh1Yi5jb20vcG91Y2hkYi9wb3VjaGRiL2Jsb2IvbWFzdGVyL3BhY2thZ2VzL25vZGVfbW9kdWxlcy9wb3VjaGRiLWFkYXB0ZXItaWRiL3NyYy9ibG9iU3VwcG9ydC5qc1xuLy9cbmZ1bmN0aW9uIF9jaGVja0Jsb2JTdXBwb3J0V2l0aG91dENhY2hpbmcoaWRiKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgdmFyIHR4biA9IGlkYi50cmFuc2FjdGlvbihERVRFQ1RfQkxPQl9TVVBQT1JUX1NUT1JFLCAncmVhZHdyaXRlJyk7XG4gICAgICAgIHZhciBibG9iID0gY3JlYXRlQmxvYihbJyddKTtcbiAgICAgICAgdHhuLm9iamVjdFN0b3JlKERFVEVDVF9CTE9CX1NVUFBPUlRfU1RPUkUpLnB1dChibG9iLCAna2V5Jyk7XG5cbiAgICAgICAgdHhuLm9uYWJvcnQgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgLy8gSWYgdGhlIHRyYW5zYWN0aW9uIGFib3J0cyBub3cgaXRzIGR1ZSB0byBub3QgYmVpbmcgYWJsZSB0b1xuICAgICAgICAgICAgLy8gd3JpdGUgdG8gdGhlIGRhdGFiYXNlLCBsaWtlbHkgZHVlIHRvIHRoZSBkaXNrIGJlaW5nIGZ1bGxcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgfTtcblxuICAgICAgICB0eG4ub25jb21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBtYXRjaGVkQ2hyb21lID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQ2hyb21lXFwvKFxcZCspLyk7XG4gICAgICAgICAgICB2YXIgbWF0Y2hlZEVkZ2UgPSBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9FZGdlXFwvLyk7XG4gICAgICAgICAgICAvLyBNUyBFZGdlIHByZXRlbmRzIHRvIGJlIENocm9tZSA0MjpcbiAgICAgICAgICAgIC8vIGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaGg4NjkzMDElMjh2PXZzLjg1JTI5LmFzcHhcbiAgICAgICAgICAgIHJlc29sdmUobWF0Y2hlZEVkZ2UgfHwgIW1hdGNoZWRDaHJvbWUgfHwgcGFyc2VJbnQobWF0Y2hlZENocm9tZVsxXSwgMTApID49IDQzKTtcbiAgICAgICAgfTtcbiAgICB9KVtcImNhdGNoXCJdKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBlcnJvciwgc28gYXNzdW1lIHVuc3VwcG9ydGVkXG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIF9jaGVja0Jsb2JTdXBwb3J0KGlkYikge1xuICAgIGlmICh0eXBlb2Ygc3VwcG9ydHNCbG9icyA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlJDEucmVzb2x2ZShzdXBwb3J0c0Jsb2JzKTtcbiAgICB9XG4gICAgcmV0dXJuIF9jaGVja0Jsb2JTdXBwb3J0V2l0aG91dENhY2hpbmcoaWRiKS50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBzdXBwb3J0c0Jsb2JzID0gdmFsdWU7XG4gICAgICAgIHJldHVybiBzdXBwb3J0c0Jsb2JzO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBfZGVmZXJSZWFkaW5lc3MoZGJJbmZvKSB7XG4gICAgdmFyIGRiQ29udGV4dCA9IGRiQ29udGV4dHNbZGJJbmZvLm5hbWVdO1xuXG4gICAgLy8gQ3JlYXRlIGEgZGVmZXJyZWQgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBkYXRhYmFzZSBvcGVyYXRpb24uXG4gICAgdmFyIGRlZmVycmVkT3BlcmF0aW9uID0ge307XG5cbiAgICBkZWZlcnJlZE9wZXJhdGlvbi5wcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICBkZWZlcnJlZE9wZXJhdGlvbi5yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICB9KTtcblxuICAgIC8vIEVucXVldWUgdGhlIGRlZmVycmVkIG9wZXJhdGlvbi5cbiAgICBkYkNvbnRleHQuZGVmZXJyZWRPcGVyYXRpb25zLnB1c2goZGVmZXJyZWRPcGVyYXRpb24pO1xuXG4gICAgLy8gQ2hhaW4gaXRzIHByb21pc2UgdG8gdGhlIGRhdGFiYXNlIHJlYWRpbmVzcy5cbiAgICBpZiAoIWRiQ29udGV4dC5kYlJlYWR5KSB7XG4gICAgICAgIGRiQ29udGV4dC5kYlJlYWR5ID0gZGVmZXJyZWRPcGVyYXRpb24ucHJvbWlzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBkYkNvbnRleHQuZGJSZWFkeSA9IGRiQ29udGV4dC5kYlJlYWR5LnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGRlZmVycmVkT3BlcmF0aW9uLnByb21pc2U7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gX2FkdmFuY2VSZWFkaW5lc3MoZGJJbmZvKSB7XG4gICAgdmFyIGRiQ29udGV4dCA9IGRiQ29udGV4dHNbZGJJbmZvLm5hbWVdO1xuXG4gICAgLy8gRGVxdWV1ZSBhIGRlZmVycmVkIG9wZXJhdGlvbi5cbiAgICB2YXIgZGVmZXJyZWRPcGVyYXRpb24gPSBkYkNvbnRleHQuZGVmZXJyZWRPcGVyYXRpb25zLnBvcCgpO1xuXG4gICAgLy8gUmVzb2x2ZSBpdHMgcHJvbWlzZSAod2hpY2ggaXMgcGFydCBvZiB0aGUgZGF0YWJhc2UgcmVhZGluZXNzXG4gICAgLy8gY2hhaW4gb2YgcHJvbWlzZXMpLlxuICAgIGlmIChkZWZlcnJlZE9wZXJhdGlvbikge1xuICAgICAgICBkZWZlcnJlZE9wZXJhdGlvbi5yZXNvbHZlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBfZ2V0Q29ubmVjdGlvbihkYkluZm8sIHVwZ3JhZGVOZWVkZWQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG5cbiAgICAgICAgaWYgKGRiSW5mby5kYikge1xuICAgICAgICAgICAgaWYgKHVwZ3JhZGVOZWVkZWQpIHtcbiAgICAgICAgICAgICAgICBfZGVmZXJSZWFkaW5lc3MoZGJJbmZvKTtcbiAgICAgICAgICAgICAgICBkYkluZm8uZGIuY2xvc2UoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoZGJJbmZvLmRiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBkYkFyZ3MgPSBbZGJJbmZvLm5hbWVdO1xuXG4gICAgICAgIGlmICh1cGdyYWRlTmVlZGVkKSB7XG4gICAgICAgICAgICBkYkFyZ3MucHVzaChkYkluZm8udmVyc2lvbik7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgb3BlbnJlcSA9IGlkYi5vcGVuLmFwcGx5KGlkYiwgZGJBcmdzKTtcblxuICAgICAgICBpZiAodXBncmFkZU5lZWRlZCkge1xuICAgICAgICAgICAgb3BlbnJlcS5vbnVwZ3JhZGVuZWVkZWQgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIHZhciBkYiA9IG9wZW5yZXEucmVzdWx0O1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGRiLmNyZWF0ZU9iamVjdFN0b3JlKGRiSW5mby5zdG9yZU5hbWUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZS5vbGRWZXJzaW9uIDw9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZGVkIHdoZW4gc3VwcG9ydCBmb3IgYmxvYiBzaGltcyB3YXMgYWRkZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIGRiLmNyZWF0ZU9iamVjdFN0b3JlKERFVEVDVF9CTE9CX1NVUFBPUlRfU1RPUkUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV4Lm5hbWUgPT09ICdDb25zdHJhaW50RXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1RoZSBkYXRhYmFzZSBcIicgKyBkYkluZm8ubmFtZSArICdcIicgKyAnIGhhcyBiZWVuIHVwZ3JhZGVkIGZyb20gdmVyc2lvbiAnICsgZS5vbGRWZXJzaW9uICsgJyB0byB2ZXJzaW9uICcgKyBlLm5ld1ZlcnNpb24gKyAnLCBidXQgdGhlIHN0b3JhZ2UgXCInICsgZGJJbmZvLnN0b3JlTmFtZSArICdcIiBhbHJlYWR5IGV4aXN0cy4nKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGV4O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIG9wZW5yZXEub25lcnJvciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICByZWplY3Qob3BlbnJlcS5lcnJvcik7XG4gICAgICAgIH07XG5cbiAgICAgICAgb3BlbnJlcS5vbnN1Y2Nlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXNvbHZlKG9wZW5yZXEucmVzdWx0KTtcbiAgICAgICAgICAgIF9hZHZhbmNlUmVhZGluZXNzKGRiSW5mbyk7XG4gICAgICAgIH07XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIF9nZXRPcmlnaW5hbENvbm5lY3Rpb24oZGJJbmZvKSB7XG4gICAgcmV0dXJuIF9nZXRDb25uZWN0aW9uKGRiSW5mbywgZmFsc2UpO1xufVxuXG5mdW5jdGlvbiBfZ2V0VXBncmFkZWRDb25uZWN0aW9uKGRiSW5mbykge1xuICAgIHJldHVybiBfZ2V0Q29ubmVjdGlvbihkYkluZm8sIHRydWUpO1xufVxuXG5mdW5jdGlvbiBfaXNVcGdyYWRlTmVlZGVkKGRiSW5mbywgZGVmYXVsdFZlcnNpb24pIHtcbiAgICBpZiAoIWRiSW5mby5kYikge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgaXNOZXdTdG9yZSA9ICFkYkluZm8uZGIub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhkYkluZm8uc3RvcmVOYW1lKTtcbiAgICB2YXIgaXNEb3duZ3JhZGUgPSBkYkluZm8udmVyc2lvbiA8IGRiSW5mby5kYi52ZXJzaW9uO1xuICAgIHZhciBpc1VwZ3JhZGUgPSBkYkluZm8udmVyc2lvbiA+IGRiSW5mby5kYi52ZXJzaW9uO1xuXG4gICAgaWYgKGlzRG93bmdyYWRlKSB7XG4gICAgICAgIC8vIElmIHRoZSB2ZXJzaW9uIGlzIG5vdCB0aGUgZGVmYXVsdCBvbmVcbiAgICAgICAgLy8gdGhlbiB3YXJuIGZvciBpbXBvc3NpYmxlIGRvd25ncmFkZS5cbiAgICAgICAgaWYgKGRiSW5mby52ZXJzaW9uICE9PSBkZWZhdWx0VmVyc2lvbikge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdUaGUgZGF0YWJhc2UgXCInICsgZGJJbmZvLm5hbWUgKyAnXCInICsgJyBjYW5cXCd0IGJlIGRvd25ncmFkZWQgZnJvbSB2ZXJzaW9uICcgKyBkYkluZm8uZGIudmVyc2lvbiArICcgdG8gdmVyc2lvbiAnICsgZGJJbmZvLnZlcnNpb24gKyAnLicpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEFsaWduIHRoZSB2ZXJzaW9ucyB0byBwcmV2ZW50IGVycm9ycy5cbiAgICAgICAgZGJJbmZvLnZlcnNpb24gPSBkYkluZm8uZGIudmVyc2lvbjtcbiAgICB9XG5cbiAgICBpZiAoaXNVcGdyYWRlIHx8IGlzTmV3U3RvcmUpIHtcbiAgICAgICAgLy8gSWYgdGhlIHN0b3JlIGlzIG5ldyB0aGVuIGluY3JlbWVudCB0aGUgdmVyc2lvbiAoaWYgbmVlZGVkKS5cbiAgICAgICAgLy8gVGhpcyB3aWxsIHRyaWdnZXIgYW4gXCJ1cGdyYWRlbmVlZGVkXCIgZXZlbnQgd2hpY2ggaXMgcmVxdWlyZWRcbiAgICAgICAgLy8gZm9yIGNyZWF0aW5nIGEgc3RvcmUuXG4gICAgICAgIGlmIChpc05ld1N0b3JlKSB7XG4gICAgICAgICAgICB2YXIgaW5jVmVyc2lvbiA9IGRiSW5mby5kYi52ZXJzaW9uICsgMTtcbiAgICAgICAgICAgIGlmIChpbmNWZXJzaW9uID4gZGJJbmZvLnZlcnNpb24pIHtcbiAgICAgICAgICAgICAgICBkYkluZm8udmVyc2lvbiA9IGluY1ZlcnNpb247XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8vIGVuY29kZSBhIGJsb2IgZm9yIGluZGV4ZWRkYiBlbmdpbmVzIHRoYXQgZG9uJ3Qgc3VwcG9ydCBibG9ic1xuZnVuY3Rpb24gX2VuY29kZUJsb2IoYmxvYikge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICAgIHJlYWRlci5vbmVycm9yID0gcmVqZWN0O1xuICAgICAgICByZWFkZXIub25sb2FkZW5kID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIHZhciBiYXNlNjQgPSBidG9hKGUudGFyZ2V0LnJlc3VsdCB8fCAnJyk7XG4gICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICBfX2xvY2FsX2ZvcmFnZV9lbmNvZGVkX2Jsb2I6IHRydWUsXG4gICAgICAgICAgICAgICAgZGF0YTogYmFzZTY0LFxuICAgICAgICAgICAgICAgIHR5cGU6IGJsb2IudHlwZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIHJlYWRlci5yZWFkQXNCaW5hcnlTdHJpbmcoYmxvYik7XG4gICAgfSk7XG59XG5cbi8vIGRlY29kZSBhbiBlbmNvZGVkIGJsb2JcbmZ1bmN0aW9uIF9kZWNvZGVCbG9iKGVuY29kZWRCbG9iKSB7XG4gICAgdmFyIGFycmF5QnVmZiA9IF9iaW5TdHJpbmdUb0FycmF5QnVmZmVyKGF0b2IoZW5jb2RlZEJsb2IuZGF0YSkpO1xuICAgIHJldHVybiBjcmVhdGVCbG9iKFthcnJheUJ1ZmZdLCB7IHR5cGU6IGVuY29kZWRCbG9iLnR5cGUgfSk7XG59XG5cbi8vIGlzIHRoaXMgb25lIG9mIG91ciBmYW5jeSBlbmNvZGVkIGJsb2JzP1xuZnVuY3Rpb24gX2lzRW5jb2RlZEJsb2IodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgJiYgdmFsdWUuX19sb2NhbF9mb3JhZ2VfZW5jb2RlZF9ibG9iO1xufVxuXG4vLyBTcGVjaWFsaXplIHRoZSBkZWZhdWx0IGByZWFkeSgpYCBmdW5jdGlvbiBieSBtYWtpbmcgaXQgZGVwZW5kZW50XG4vLyBvbiB0aGUgY3VycmVudCBkYXRhYmFzZSBvcGVyYXRpb25zLiBUaHVzLCB0aGUgZHJpdmVyIHdpbGwgYmUgYWN0dWFsbHlcbi8vIHJlYWR5IHdoZW4gaXQncyBiZWVuIGluaXRpYWxpemVkIChkZWZhdWx0KSAqYW5kKiB0aGVyZSBhcmUgbm8gcGVuZGluZ1xuLy8gb3BlcmF0aW9ucyBvbiB0aGUgZGF0YWJhc2UgKGluaXRpYXRlZCBieSBzb21lIG90aGVyIGluc3RhbmNlcykuXG5mdW5jdGlvbiBfZnVsbHlSZWFkeShjYWxsYmFjaykge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBwcm9taXNlID0gc2VsZi5faW5pdFJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkYkNvbnRleHQgPSBkYkNvbnRleHRzW3NlbGYuX2RiSW5mby5uYW1lXTtcblxuICAgICAgICBpZiAoZGJDb250ZXh0ICYmIGRiQ29udGV4dC5kYlJlYWR5KSB7XG4gICAgICAgICAgICByZXR1cm4gZGJDb250ZXh0LmRiUmVhZHk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGV4ZWN1dGVUd29DYWxsYmFja3MocHJvbWlzZSwgY2FsbGJhY2ssIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuLy8gT3BlbiB0aGUgSW5kZXhlZERCIGRhdGFiYXNlIChhdXRvbWF0aWNhbGx5IGNyZWF0ZXMgb25lIGlmIG9uZSBkaWRuJ3Rcbi8vIHByZXZpb3VzbHkgZXhpc3QpLCB1c2luZyBhbnkgb3B0aW9ucyBzZXQgaW4gdGhlIGNvbmZpZy5cbmZ1bmN0aW9uIF9pbml0U3RvcmFnZShvcHRpb25zKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHZhciBkYkluZm8gPSB7XG4gICAgICAgIGRiOiBudWxsXG4gICAgfTtcblxuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICAgIGZvciAodmFyIGkgaW4gb3B0aW9ucykge1xuICAgICAgICAgICAgZGJJbmZvW2ldID0gb3B0aW9uc1tpXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEluaXRpYWxpemUgYSBzaW5nbGV0b24gY29udGFpbmVyIGZvciBhbGwgcnVubmluZyBsb2NhbEZvcmFnZXMuXG4gICAgaWYgKCFkYkNvbnRleHRzKSB7XG4gICAgICAgIGRiQ29udGV4dHMgPSB7fTtcbiAgICB9XG5cbiAgICAvLyBHZXQgdGhlIGN1cnJlbnQgY29udGV4dCBvZiB0aGUgZGF0YWJhc2U7XG4gICAgdmFyIGRiQ29udGV4dCA9IGRiQ29udGV4dHNbZGJJbmZvLm5hbWVdO1xuXG4gICAgLy8gLi4ub3IgY3JlYXRlIGEgbmV3IGNvbnRleHQuXG4gICAgaWYgKCFkYkNvbnRleHQpIHtcbiAgICAgICAgZGJDb250ZXh0ID0ge1xuICAgICAgICAgICAgLy8gUnVubmluZyBsb2NhbEZvcmFnZXMgc2hhcmluZyBhIGRhdGFiYXNlLlxuICAgICAgICAgICAgZm9yYWdlczogW10sXG4gICAgICAgICAgICAvLyBTaGFyZWQgZGF0YWJhc2UuXG4gICAgICAgICAgICBkYjogbnVsbCxcbiAgICAgICAgICAgIC8vIERhdGFiYXNlIHJlYWRpbmVzcyAocHJvbWlzZSkuXG4gICAgICAgICAgICBkYlJlYWR5OiBudWxsLFxuICAgICAgICAgICAgLy8gRGVmZXJyZWQgb3BlcmF0aW9ucyBvbiB0aGUgZGF0YWJhc2UuXG4gICAgICAgICAgICBkZWZlcnJlZE9wZXJhdGlvbnM6IFtdXG4gICAgICAgIH07XG4gICAgICAgIC8vIFJlZ2lzdGVyIHRoZSBuZXcgY29udGV4dCBpbiB0aGUgZ2xvYmFsIGNvbnRhaW5lci5cbiAgICAgICAgZGJDb250ZXh0c1tkYkluZm8ubmFtZV0gPSBkYkNvbnRleHQ7XG4gICAgfVxuXG4gICAgLy8gUmVnaXN0ZXIgaXRzZWxmIGFzIGEgcnVubmluZyBsb2NhbEZvcmFnZSBpbiB0aGUgY3VycmVudCBjb250ZXh0LlxuICAgIGRiQ29udGV4dC5mb3JhZ2VzLnB1c2goc2VsZik7XG5cbiAgICAvLyBSZXBsYWNlIHRoZSBkZWZhdWx0IGByZWFkeSgpYCBmdW5jdGlvbiB3aXRoIHRoZSBzcGVjaWFsaXplZCBvbmUuXG4gICAgaWYgKCFzZWxmLl9pbml0UmVhZHkpIHtcbiAgICAgICAgc2VsZi5faW5pdFJlYWR5ID0gc2VsZi5yZWFkeTtcbiAgICAgICAgc2VsZi5yZWFkeSA9IF9mdWxseVJlYWR5O1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBhbiBhcnJheSBvZiBpbml0aWFsaXphdGlvbiBzdGF0ZXMgb2YgdGhlIHJlbGF0ZWQgbG9jYWxGb3JhZ2VzLlxuICAgIHZhciBpbml0UHJvbWlzZXMgPSBbXTtcblxuICAgIGZ1bmN0aW9uIGlnbm9yZUVycm9ycygpIHtcbiAgICAgICAgLy8gRG9uJ3QgaGFuZGxlIGVycm9ycyBoZXJlLFxuICAgICAgICAvLyBqdXN0IG1ha2VzIHN1cmUgcmVsYXRlZCBsb2NhbEZvcmFnZXMgYXJlbid0IHBlbmRpbmcuXG4gICAgICAgIHJldHVybiBQcm9taXNlJDEucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgZGJDb250ZXh0LmZvcmFnZXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgdmFyIGZvcmFnZSA9IGRiQ29udGV4dC5mb3JhZ2VzW2pdO1xuICAgICAgICBpZiAoZm9yYWdlICE9PSBzZWxmKSB7XG4gICAgICAgICAgICAvLyBEb24ndCB3YWl0IGZvciBpdHNlbGYuLi5cbiAgICAgICAgICAgIGluaXRQcm9taXNlcy5wdXNoKGZvcmFnZS5faW5pdFJlYWR5KClbXCJjYXRjaFwiXShpZ25vcmVFcnJvcnMpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRha2UgYSBzbmFwc2hvdCBvZiB0aGUgcmVsYXRlZCBsb2NhbEZvcmFnZXMuXG4gICAgdmFyIGZvcmFnZXMgPSBkYkNvbnRleHQuZm9yYWdlcy5zbGljZSgwKTtcblxuICAgIC8vIEluaXRpYWxpemUgdGhlIGNvbm5lY3Rpb24gcHJvY2VzcyBvbmx5IHdoZW5cbiAgICAvLyBhbGwgdGhlIHJlbGF0ZWQgbG9jYWxGb3JhZ2VzIGFyZW4ndCBwZW5kaW5nLlxuICAgIHJldHVybiBQcm9taXNlJDEuYWxsKGluaXRQcm9taXNlcykudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRiSW5mby5kYiA9IGRiQ29udGV4dC5kYjtcbiAgICAgICAgLy8gR2V0IHRoZSBjb25uZWN0aW9uIG9yIG9wZW4gYSBuZXcgb25lIHdpdGhvdXQgdXBncmFkZS5cbiAgICAgICAgcmV0dXJuIF9nZXRPcmlnaW5hbENvbm5lY3Rpb24oZGJJbmZvKTtcbiAgICB9KS50aGVuKGZ1bmN0aW9uIChkYikge1xuICAgICAgICBkYkluZm8uZGIgPSBkYjtcbiAgICAgICAgaWYgKF9pc1VwZ3JhZGVOZWVkZWQoZGJJbmZvLCBzZWxmLl9kZWZhdWx0Q29uZmlnLnZlcnNpb24pKSB7XG4gICAgICAgICAgICAvLyBSZW9wZW4gdGhlIGRhdGFiYXNlIGZvciB1cGdyYWRpbmcuXG4gICAgICAgICAgICByZXR1cm4gX2dldFVwZ3JhZGVkQ29ubmVjdGlvbihkYkluZm8pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkYjtcbiAgICB9KS50aGVuKGZ1bmN0aW9uIChkYikge1xuICAgICAgICBkYkluZm8uZGIgPSBkYkNvbnRleHQuZGIgPSBkYjtcbiAgICAgICAgc2VsZi5fZGJJbmZvID0gZGJJbmZvO1xuICAgICAgICAvLyBTaGFyZSB0aGUgZmluYWwgY29ubmVjdGlvbiBhbW9uZ3N0IHJlbGF0ZWQgbG9jYWxGb3JhZ2VzLlxuICAgICAgICBmb3IgKHZhciBrID0gMDsgayA8IGZvcmFnZXMubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICAgIHZhciBmb3JhZ2UgPSBmb3JhZ2VzW2tdO1xuICAgICAgICAgICAgaWYgKGZvcmFnZSAhPT0gc2VsZikge1xuICAgICAgICAgICAgICAgIC8vIFNlbGYgaXMgYWxyZWFkeSB1cC10by1kYXRlLlxuICAgICAgICAgICAgICAgIGZvcmFnZS5fZGJJbmZvLmRiID0gZGJJbmZvLmRiO1xuICAgICAgICAgICAgICAgIGZvcmFnZS5fZGJJbmZvLnZlcnNpb24gPSBkYkluZm8udmVyc2lvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBnZXRJdGVtKGtleSwgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAvLyBDYXN0IHRoZSBrZXkgdG8gYSBzdHJpbmcsIGFzIHRoYXQncyBhbGwgd2UgY2FuIHNldCBhcyBhIGtleS5cbiAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGtleSArICcgdXNlZCBhcyBhIGtleSwgYnV0IGl0IGlzIG5vdCBhIHN0cmluZy4nKTtcbiAgICAgICAga2V5ID0gU3RyaW5nKGtleSk7XG4gICAgfVxuXG4gICAgdmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgc2VsZi5yZWFkeSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgICAgIHZhciBzdG9yZSA9IGRiSW5mby5kYi50cmFuc2FjdGlvbihkYkluZm8uc3RvcmVOYW1lLCAncmVhZG9ubHknKS5vYmplY3RTdG9yZShkYkluZm8uc3RvcmVOYW1lKTtcbiAgICAgICAgICAgIHZhciByZXEgPSBzdG9yZS5nZXQoa2V5KTtcblxuICAgICAgICAgICAgcmVxLm9uc3VjY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSByZXEucmVzdWx0O1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKF9pc0VuY29kZWRCbG9iKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IF9kZWNvZGVCbG9iKHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh2YWx1ZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXEub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZWplY3QocmVxLmVycm9yKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbi8vIEl0ZXJhdGUgb3ZlciBhbGwgaXRlbXMgc3RvcmVkIGluIGRhdGFiYXNlLlxuZnVuY3Rpb24gaXRlcmF0ZShpdGVyYXRvciwgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgZGJJbmZvID0gc2VsZi5fZGJJbmZvO1xuICAgICAgICAgICAgdmFyIHN0b3JlID0gZGJJbmZvLmRiLnRyYW5zYWN0aW9uKGRiSW5mby5zdG9yZU5hbWUsICdyZWFkb25seScpLm9iamVjdFN0b3JlKGRiSW5mby5zdG9yZU5hbWUpO1xuXG4gICAgICAgICAgICB2YXIgcmVxID0gc3RvcmUub3BlbkN1cnNvcigpO1xuICAgICAgICAgICAgdmFyIGl0ZXJhdGlvbk51bWJlciA9IDE7XG5cbiAgICAgICAgICAgIHJlcS5vbnN1Y2Nlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnNvciA9IHJlcS5yZXN1bHQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoY3Vyc29yKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IGN1cnNvci52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc0VuY29kZWRCbG9iKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBfZGVjb2RlQmxvYih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGl0ZXJhdG9yKHZhbHVlLCBjdXJzb3Iua2V5LCBpdGVyYXRpb25OdW1iZXIrKyk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPT0gdm9pZCAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJzb3JbXCJjb250aW51ZVwiXSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHJlcS5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChyZXEuZXJyb3IpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSlbXCJjYXRjaFwiXShyZWplY3QpO1xuICAgIH0pO1xuXG4gICAgZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKTtcblxuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5mdW5jdGlvbiBzZXRJdGVtKGtleSwgdmFsdWUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgLy8gQ2FzdCB0aGUga2V5IHRvIGEgc3RyaW5nLCBhcyB0aGF0J3MgYWxsIHdlIGNhbiBzZXQgYXMgYSBrZXkuXG4gICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihrZXkgKyAnIHVzZWQgYXMgYSBrZXksIGJ1dCBpdCBpcyBub3QgYSBzdHJpbmcuJyk7XG4gICAgICAgIGtleSA9IFN0cmluZyhrZXkpO1xuICAgIH1cblxuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHZhciBkYkluZm87XG4gICAgICAgIHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgICAgIGlmICh0b1N0cmluZy5jYWxsKHZhbHVlKSA9PT0gJ1tvYmplY3QgQmxvYl0nKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jaGVja0Jsb2JTdXBwb3J0KGRiSW5mby5kYikudGhlbihmdW5jdGlvbiAoYmxvYlN1cHBvcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJsb2JTdXBwb3J0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9lbmNvZGVCbG9iKHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSkudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIHZhciB0cmFuc2FjdGlvbiA9IGRiSW5mby5kYi50cmFuc2FjdGlvbihkYkluZm8uc3RvcmVOYW1lLCAncmVhZHdyaXRlJyk7XG4gICAgICAgICAgICB2YXIgc3RvcmUgPSB0cmFuc2FjdGlvbi5vYmplY3RTdG9yZShkYkluZm8uc3RvcmVOYW1lKTtcbiAgICAgICAgICAgIHZhciByZXEgPSBzdG9yZS5wdXQodmFsdWUsIGtleSk7XG5cbiAgICAgICAgICAgIC8vIFRoZSByZWFzb24gd2UgZG9uJ3QgX3NhdmVfIG51bGwgaXMgYmVjYXVzZSBJRSAxMCBkb2VzXG4gICAgICAgICAgICAvLyBub3Qgc3VwcG9ydCBzYXZpbmcgdGhlIGBudWxsYCB0eXBlIGluIEluZGV4ZWREQi4gSG93XG4gICAgICAgICAgICAvLyBpcm9uaWMsIGdpdmVuIHRoZSBidWcgYmVsb3chXG4gICAgICAgICAgICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9tb3ppbGxhL2xvY2FsRm9yYWdlL2lzc3Vlcy8xNjFcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0cmFuc2FjdGlvbi5vbmNvbXBsZXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIC8vIENhc3QgdG8gdW5kZWZpbmVkIHNvIHRoZSB2YWx1ZSBwYXNzZWQgdG9cbiAgICAgICAgICAgICAgICAvLyBjYWxsYmFjay9wcm9taXNlIGlzIHRoZSBzYW1lIGFzIHdoYXQgb25lIHdvdWxkIGdldCBvdXRcbiAgICAgICAgICAgICAgICAvLyBvZiBgZ2V0SXRlbSgpYCBsYXRlci4gVGhpcyBsZWFkcyB0byBzb21lIHdlaXJkbmVzc1xuICAgICAgICAgICAgICAgIC8vIChzZXRJdGVtKCdmb28nLCB1bmRlZmluZWQpIHdpbGwgcmV0dXJuIGBudWxsYCksIGJ1dFxuICAgICAgICAgICAgICAgIC8vIGl0J3Mgbm90IG15IGZhdWx0IGxvY2FsU3RvcmFnZSBpcyBvdXIgYmFzZWxpbmUgYW5kIHRoYXRcbiAgICAgICAgICAgICAgICAvLyBpdCdzIHdlaXJkLlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0cmFuc2FjdGlvbi5vbmFib3J0ID0gdHJhbnNhY3Rpb24ub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXJyID0gcmVxLmVycm9yID8gcmVxLmVycm9yIDogcmVxLnRyYW5zYWN0aW9uLmVycm9yO1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSlbXCJjYXRjaFwiXShyZWplY3QpO1xuICAgIH0pO1xuXG4gICAgZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlSXRlbShrZXksIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgLy8gQ2FzdCB0aGUga2V5IHRvIGEgc3RyaW5nLCBhcyB0aGF0J3MgYWxsIHdlIGNhbiBzZXQgYXMgYSBrZXkuXG4gICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihrZXkgKyAnIHVzZWQgYXMgYSBrZXksIGJ1dCBpdCBpcyBub3QgYSBzdHJpbmcuJyk7XG4gICAgICAgIGtleSA9IFN0cmluZyhrZXkpO1xuICAgIH1cblxuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgICAgICB2YXIgdHJhbnNhY3Rpb24gPSBkYkluZm8uZGIudHJhbnNhY3Rpb24oZGJJbmZvLnN0b3JlTmFtZSwgJ3JlYWR3cml0ZScpO1xuICAgICAgICAgICAgdmFyIHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUoZGJJbmZvLnN0b3JlTmFtZSk7XG5cbiAgICAgICAgICAgIC8vIFdlIHVzZSBhIEdydW50IHRhc2sgdG8gbWFrZSB0aGlzIHNhZmUgZm9yIElFIGFuZCBzb21lXG4gICAgICAgICAgICAvLyB2ZXJzaW9ucyBvZiBBbmRyb2lkIChpbmNsdWRpbmcgdGhvc2UgdXNlZCBieSBDb3Jkb3ZhKS5cbiAgICAgICAgICAgIC8vIE5vcm1hbGx5IElFIHdvbid0IGxpa2UgYC5kZWxldGUoKWAgYW5kIHdpbGwgaW5zaXN0IG9uXG4gICAgICAgICAgICAvLyB1c2luZyBgWydkZWxldGUnXSgpYCwgYnV0IHdlIGhhdmUgYSBidWlsZCBzdGVwIHRoYXRcbiAgICAgICAgICAgIC8vIGZpeGVzIHRoaXMgZm9yIHVzIG5vdy5cbiAgICAgICAgICAgIHZhciByZXEgPSBzdG9yZVtcImRlbGV0ZVwiXShrZXkpO1xuICAgICAgICAgICAgdHJhbnNhY3Rpb24ub25jb21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0cmFuc2FjdGlvbi5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChyZXEuZXJyb3IpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gVGhlIHJlcXVlc3Qgd2lsbCBiZSBhbHNvIGJlIGFib3J0ZWQgaWYgd2UndmUgZXhjZWVkZWQgb3VyIHN0b3JhZ2VcbiAgICAgICAgICAgIC8vIHNwYWNlLlxuICAgICAgICAgICAgdHJhbnNhY3Rpb24ub25hYm9ydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXJyID0gcmVxLmVycm9yID8gcmVxLmVycm9yIDogcmVxLnRyYW5zYWN0aW9uLmVycm9yO1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSlbXCJjYXRjaFwiXShyZWplY3QpO1xuICAgIH0pO1xuXG4gICAgZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuZnVuY3Rpb24gY2xlYXIoY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgZGJJbmZvID0gc2VsZi5fZGJJbmZvO1xuICAgICAgICAgICAgdmFyIHRyYW5zYWN0aW9uID0gZGJJbmZvLmRiLnRyYW5zYWN0aW9uKGRiSW5mby5zdG9yZU5hbWUsICdyZWFkd3JpdGUnKTtcbiAgICAgICAgICAgIHZhciBzdG9yZSA9IHRyYW5zYWN0aW9uLm9iamVjdFN0b3JlKGRiSW5mby5zdG9yZU5hbWUpO1xuICAgICAgICAgICAgdmFyIHJlcSA9IHN0b3JlLmNsZWFyKCk7XG5cbiAgICAgICAgICAgIHRyYW5zYWN0aW9uLm9uY29tcGxldGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdHJhbnNhY3Rpb24ub25hYm9ydCA9IHRyYW5zYWN0aW9uLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVyciA9IHJlcS5lcnJvciA/IHJlcS5lcnJvciA6IHJlcS50cmFuc2FjdGlvbi5lcnJvcjtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbmZ1bmN0aW9uIGxlbmd0aChjYWxsYmFjaykge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgICAgICB2YXIgc3RvcmUgPSBkYkluZm8uZGIudHJhbnNhY3Rpb24oZGJJbmZvLnN0b3JlTmFtZSwgJ3JlYWRvbmx5Jykub2JqZWN0U3RvcmUoZGJJbmZvLnN0b3JlTmFtZSk7XG4gICAgICAgICAgICB2YXIgcmVxID0gc3RvcmUuY291bnQoKTtcblxuICAgICAgICAgICAgcmVxLm9uc3VjY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHJlcS5yZXN1bHQpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmVxLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KHJlcS5lcnJvcik7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KVtcImNhdGNoXCJdKHJlamVjdCk7XG4gICAgfSk7XG5cbiAgICBleGVjdXRlQ2FsbGJhY2socHJvbWlzZSwgY2FsbGJhY2spO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5mdW5jdGlvbiBrZXkobiwgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBpZiAobiA8IDApIHtcbiAgICAgICAgICAgIHJlc29sdmUobnVsbCk7XG5cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgICAgICB2YXIgc3RvcmUgPSBkYkluZm8uZGIudHJhbnNhY3Rpb24oZGJJbmZvLnN0b3JlTmFtZSwgJ3JlYWRvbmx5Jykub2JqZWN0U3RvcmUoZGJJbmZvLnN0b3JlTmFtZSk7XG5cbiAgICAgICAgICAgIHZhciBhZHZhbmNlZCA9IGZhbHNlO1xuICAgICAgICAgICAgdmFyIHJlcSA9IHN0b3JlLm9wZW5DdXJzb3IoKTtcbiAgICAgICAgICAgIHJlcS5vbnN1Y2Nlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnNvciA9IHJlcS5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgaWYgKCFjdXJzb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyBtZWFucyB0aGVyZSB3ZXJlbid0IGVub3VnaCBrZXlzXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUobnVsbCk7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChuID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdlIGhhdmUgdGhlIGZpcnN0IGtleSwgcmV0dXJuIGl0IGlmIHRoYXQncyB3aGF0IHRoZXlcbiAgICAgICAgICAgICAgICAgICAgLy8gd2FudGVkLlxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGN1cnNvci5rZXkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghYWR2YW5jZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSwgYXNrIHRoZSBjdXJzb3IgdG8gc2tpcCBhaGVhZCBuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyByZWNvcmRzLlxuICAgICAgICAgICAgICAgICAgICAgICAgYWR2YW5jZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3Vyc29yLmFkdmFuY2Uobik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHdlIGdldCBoZXJlLCB3ZSd2ZSBnb3QgdGhlIG50aCBrZXkuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGN1cnNvci5rZXkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmVxLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KHJlcS5lcnJvcik7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KVtcImNhdGNoXCJdKHJlamVjdCk7XG4gICAgfSk7XG5cbiAgICBleGVjdXRlQ2FsbGJhY2socHJvbWlzZSwgY2FsbGJhY2spO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5mdW5jdGlvbiBrZXlzKGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgc2VsZi5yZWFkeSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgICAgIHZhciBzdG9yZSA9IGRiSW5mby5kYi50cmFuc2FjdGlvbihkYkluZm8uc3RvcmVOYW1lLCAncmVhZG9ubHknKS5vYmplY3RTdG9yZShkYkluZm8uc3RvcmVOYW1lKTtcblxuICAgICAgICAgICAgdmFyIHJlcSA9IHN0b3JlLm9wZW5DdXJzb3IoKTtcbiAgICAgICAgICAgIHZhciBrZXlzID0gW107XG5cbiAgICAgICAgICAgIHJlcS5vbnN1Y2Nlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnNvciA9IHJlcS5yZXN1bHQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoIWN1cnNvcikge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGtleXMpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAga2V5cy5wdXNoKGN1cnNvci5rZXkpO1xuICAgICAgICAgICAgICAgIGN1cnNvcltcImNvbnRpbnVlXCJdKCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXEub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZWplY3QocmVxLmVycm9yKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbnZhciBhc3luY1N0b3JhZ2UgPSB7XG4gICAgX2RyaXZlcjogJ2FzeW5jU3RvcmFnZScsXG4gICAgX2luaXRTdG9yYWdlOiBfaW5pdFN0b3JhZ2UsXG4gICAgaXRlcmF0ZTogaXRlcmF0ZSxcbiAgICBnZXRJdGVtOiBnZXRJdGVtLFxuICAgIHNldEl0ZW06IHNldEl0ZW0sXG4gICAgcmVtb3ZlSXRlbTogcmVtb3ZlSXRlbSxcbiAgICBjbGVhcjogY2xlYXIsXG4gICAgbGVuZ3RoOiBsZW5ndGgsXG4gICAga2V5OiBrZXksXG4gICAga2V5czoga2V5c1xufTtcblxuLy8gU2FkbHksIHRoZSBiZXN0IHdheSB0byBzYXZlIGJpbmFyeSBkYXRhIGluIFdlYlNRTC9sb2NhbFN0b3JhZ2UgaXMgc2VyaWFsaXppbmdcbi8vIGl0IHRvIEJhc2U2NCwgc28gdGhpcyBpcyBob3cgd2Ugc3RvcmUgaXQgdG8gcHJldmVudCB2ZXJ5IHN0cmFuZ2UgZXJyb3JzIHdpdGggbGVzc1xuLy8gdmVyYm9zZSB3YXlzIG9mIGJpbmFyeSA8LT4gc3RyaW5nIGRhdGEgc3RvcmFnZS5cbnZhciBCQVNFX0NIQVJTID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXG52YXIgQkxPQl9UWVBFX1BSRUZJWCA9ICd+fmxvY2FsX2ZvcmFnZV90eXBlfic7XG52YXIgQkxPQl9UWVBFX1BSRUZJWF9SRUdFWCA9IC9efn5sb2NhbF9mb3JhZ2VfdHlwZX4oW15+XSspfi87XG5cbnZhciBTRVJJQUxJWkVEX01BUktFUiA9ICdfX2xmc2NfXzonO1xudmFyIFNFUklBTElaRURfTUFSS0VSX0xFTkdUSCA9IFNFUklBTElaRURfTUFSS0VSLmxlbmd0aDtcblxuLy8gT01HIHRoZSBzZXJpYWxpemF0aW9ucyFcbnZhciBUWVBFX0FSUkFZQlVGRkVSID0gJ2FyYmYnO1xudmFyIFRZUEVfQkxPQiA9ICdibG9iJztcbnZhciBUWVBFX0lOVDhBUlJBWSA9ICdzaTA4JztcbnZhciBUWVBFX1VJTlQ4QVJSQVkgPSAndWkwOCc7XG52YXIgVFlQRV9VSU5UOENMQU1QRURBUlJBWSA9ICd1aWM4JztcbnZhciBUWVBFX0lOVDE2QVJSQVkgPSAnc2kxNic7XG52YXIgVFlQRV9JTlQzMkFSUkFZID0gJ3NpMzInO1xudmFyIFRZUEVfVUlOVDE2QVJSQVkgPSAndXIxNic7XG52YXIgVFlQRV9VSU5UMzJBUlJBWSA9ICd1aTMyJztcbnZhciBUWVBFX0ZMT0FUMzJBUlJBWSA9ICdmbDMyJztcbnZhciBUWVBFX0ZMT0FUNjRBUlJBWSA9ICdmbDY0JztcbnZhciBUWVBFX1NFUklBTElaRURfTUFSS0VSX0xFTkdUSCA9IFNFUklBTElaRURfTUFSS0VSX0xFTkdUSCArIFRZUEVfQVJSQVlCVUZGRVIubGVuZ3RoO1xuXG52YXIgdG9TdHJpbmckMSA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbmZ1bmN0aW9uIHN0cmluZ1RvQnVmZmVyKHNlcmlhbGl6ZWRTdHJpbmcpIHtcbiAgICAvLyBGaWxsIHRoZSBzdHJpbmcgaW50byBhIEFycmF5QnVmZmVyLlxuICAgIHZhciBidWZmZXJMZW5ndGggPSBzZXJpYWxpemVkU3RyaW5nLmxlbmd0aCAqIDAuNzU7XG4gICAgdmFyIGxlbiA9IHNlcmlhbGl6ZWRTdHJpbmcubGVuZ3RoO1xuICAgIHZhciBpO1xuICAgIHZhciBwID0gMDtcbiAgICB2YXIgZW5jb2RlZDEsIGVuY29kZWQyLCBlbmNvZGVkMywgZW5jb2RlZDQ7XG5cbiAgICBpZiAoc2VyaWFsaXplZFN0cmluZ1tzZXJpYWxpemVkU3RyaW5nLmxlbmd0aCAtIDFdID09PSAnPScpIHtcbiAgICAgICAgYnVmZmVyTGVuZ3RoLS07XG4gICAgICAgIGlmIChzZXJpYWxpemVkU3RyaW5nW3NlcmlhbGl6ZWRTdHJpbmcubGVuZ3RoIC0gMl0gPT09ICc9Jykge1xuICAgICAgICAgICAgYnVmZmVyTGVuZ3RoLS07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgYnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKGJ1ZmZlckxlbmd0aCk7XG4gICAgdmFyIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkgKz0gNCkge1xuICAgICAgICBlbmNvZGVkMSA9IEJBU0VfQ0hBUlMuaW5kZXhPZihzZXJpYWxpemVkU3RyaW5nW2ldKTtcbiAgICAgICAgZW5jb2RlZDIgPSBCQVNFX0NIQVJTLmluZGV4T2Yoc2VyaWFsaXplZFN0cmluZ1tpICsgMV0pO1xuICAgICAgICBlbmNvZGVkMyA9IEJBU0VfQ0hBUlMuaW5kZXhPZihzZXJpYWxpemVkU3RyaW5nW2kgKyAyXSk7XG4gICAgICAgIGVuY29kZWQ0ID0gQkFTRV9DSEFSUy5pbmRleE9mKHNlcmlhbGl6ZWRTdHJpbmdbaSArIDNdKTtcblxuICAgICAgICAvKmpzbGludCBiaXR3aXNlOiB0cnVlICovXG4gICAgICAgIGJ5dGVzW3ArK10gPSBlbmNvZGVkMSA8PCAyIHwgZW5jb2RlZDIgPj4gNDtcbiAgICAgICAgYnl0ZXNbcCsrXSA9IChlbmNvZGVkMiAmIDE1KSA8PCA0IHwgZW5jb2RlZDMgPj4gMjtcbiAgICAgICAgYnl0ZXNbcCsrXSA9IChlbmNvZGVkMyAmIDMpIDw8IDYgfCBlbmNvZGVkNCAmIDYzO1xuICAgIH1cbiAgICByZXR1cm4gYnVmZmVyO1xufVxuXG4vLyBDb252ZXJ0cyBhIGJ1ZmZlciB0byBhIHN0cmluZyB0byBzdG9yZSwgc2VyaWFsaXplZCwgaW4gdGhlIGJhY2tlbmRcbi8vIHN0b3JhZ2UgbGlicmFyeS5cbmZ1bmN0aW9uIGJ1ZmZlclRvU3RyaW5nKGJ1ZmZlcikge1xuICAgIC8vIGJhc2U2NC1hcnJheWJ1ZmZlclxuICAgIHZhciBieXRlcyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XG4gICAgdmFyIGJhc2U2NFN0cmluZyA9ICcnO1xuICAgIHZhciBpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgICAgIC8qanNsaW50IGJpdHdpc2U6IHRydWUgKi9cbiAgICAgICAgYmFzZTY0U3RyaW5nICs9IEJBU0VfQ0hBUlNbYnl0ZXNbaV0gPj4gMl07XG4gICAgICAgIGJhc2U2NFN0cmluZyArPSBCQVNFX0NIQVJTWyhieXRlc1tpXSAmIDMpIDw8IDQgfCBieXRlc1tpICsgMV0gPj4gNF07XG4gICAgICAgIGJhc2U2NFN0cmluZyArPSBCQVNFX0NIQVJTWyhieXRlc1tpICsgMV0gJiAxNSkgPDwgMiB8IGJ5dGVzW2kgKyAyXSA+PiA2XTtcbiAgICAgICAgYmFzZTY0U3RyaW5nICs9IEJBU0VfQ0hBUlNbYnl0ZXNbaSArIDJdICYgNjNdO1xuICAgIH1cblxuICAgIGlmIChieXRlcy5sZW5ndGggJSAzID09PSAyKSB7XG4gICAgICAgIGJhc2U2NFN0cmluZyA9IGJhc2U2NFN0cmluZy5zdWJzdHJpbmcoMCwgYmFzZTY0U3RyaW5nLmxlbmd0aCAtIDEpICsgJz0nO1xuICAgIH0gZWxzZSBpZiAoYnl0ZXMubGVuZ3RoICUgMyA9PT0gMSkge1xuICAgICAgICBiYXNlNjRTdHJpbmcgPSBiYXNlNjRTdHJpbmcuc3Vic3RyaW5nKDAsIGJhc2U2NFN0cmluZy5sZW5ndGggLSAyKSArICc9PSc7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJhc2U2NFN0cmluZztcbn1cblxuLy8gU2VyaWFsaXplIGEgdmFsdWUsIGFmdGVyd2FyZHMgZXhlY3V0aW5nIGEgY2FsbGJhY2sgKHdoaWNoIHVzdWFsbHlcbi8vIGluc3RydWN0cyB0aGUgYHNldEl0ZW0oKWAgY2FsbGJhY2svcHJvbWlzZSB0byBiZSBleGVjdXRlZCkuIFRoaXMgaXMgaG93XG4vLyB3ZSBzdG9yZSBiaW5hcnkgZGF0YSB3aXRoIGxvY2FsU3RvcmFnZS5cbmZ1bmN0aW9uIHNlcmlhbGl6ZSh2YWx1ZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgdmFsdWVUeXBlID0gJyc7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICAgIHZhbHVlVHlwZSA9IHRvU3RyaW5nJDEuY2FsbCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLy8gQ2Fubm90IHVzZSBgdmFsdWUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcmAgb3Igc3VjaCBoZXJlLCBhcyB0aGVzZVxuICAgIC8vIGNoZWNrcyBmYWlsIHdoZW4gcnVubmluZyB0aGUgdGVzdHMgdXNpbmcgY2FzcGVyLmpzLi4uXG4gICAgLy9cbiAgICAvLyBUT0RPOiBTZWUgd2h5IHRob3NlIHRlc3RzIGZhaWwgYW5kIHVzZSBhIGJldHRlciBzb2x1dGlvbi5cbiAgICBpZiAodmFsdWUgJiYgKHZhbHVlVHlwZSA9PT0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyB8fCB2YWx1ZS5idWZmZXIgJiYgdG9TdHJpbmckMS5jYWxsKHZhbHVlLmJ1ZmZlcikgPT09ICdbb2JqZWN0IEFycmF5QnVmZmVyXScpKSB7XG4gICAgICAgIC8vIENvbnZlcnQgYmluYXJ5IGFycmF5cyB0byBhIHN0cmluZyBhbmQgcHJlZml4IHRoZSBzdHJpbmcgd2l0aFxuICAgICAgICAvLyBhIHNwZWNpYWwgbWFya2VyLlxuICAgICAgICB2YXIgYnVmZmVyO1xuICAgICAgICB2YXIgbWFya2VyID0gU0VSSUFMSVpFRF9NQVJLRVI7XG5cbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgICAgICAgIGJ1ZmZlciA9IHZhbHVlO1xuICAgICAgICAgICAgbWFya2VyICs9IFRZUEVfQVJSQVlCVUZGRVI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBidWZmZXIgPSB2YWx1ZS5idWZmZXI7XG5cbiAgICAgICAgICAgIGlmICh2YWx1ZVR5cGUgPT09ICdbb2JqZWN0IEludDhBcnJheV0nKSB7XG4gICAgICAgICAgICAgICAgbWFya2VyICs9IFRZUEVfSU5UOEFSUkFZO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZVR5cGUgPT09ICdbb2JqZWN0IFVpbnQ4QXJyYXldJykge1xuICAgICAgICAgICAgICAgIG1hcmtlciArPSBUWVBFX1VJTlQ4QVJSQVk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlVHlwZSA9PT0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJykge1xuICAgICAgICAgICAgICAgIG1hcmtlciArPSBUWVBFX1VJTlQ4Q0xBTVBFREFSUkFZO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZVR5cGUgPT09ICdbb2JqZWN0IEludDE2QXJyYXldJykge1xuICAgICAgICAgICAgICAgIG1hcmtlciArPSBUWVBFX0lOVDE2QVJSQVk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlVHlwZSA9PT0gJ1tvYmplY3QgVWludDE2QXJyYXldJykge1xuICAgICAgICAgICAgICAgIG1hcmtlciArPSBUWVBFX1VJTlQxNkFSUkFZO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZVR5cGUgPT09ICdbb2JqZWN0IEludDMyQXJyYXldJykge1xuICAgICAgICAgICAgICAgIG1hcmtlciArPSBUWVBFX0lOVDMyQVJSQVk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlVHlwZSA9PT0gJ1tvYmplY3QgVWludDMyQXJyYXldJykge1xuICAgICAgICAgICAgICAgIG1hcmtlciArPSBUWVBFX1VJTlQzMkFSUkFZO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZVR5cGUgPT09ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nKSB7XG4gICAgICAgICAgICAgICAgbWFya2VyICs9IFRZUEVfRkxPQVQzMkFSUkFZO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZVR5cGUgPT09ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nKSB7XG4gICAgICAgICAgICAgICAgbWFya2VyICs9IFRZUEVfRkxPQVQ2NEFSUkFZO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhuZXcgRXJyb3IoJ0ZhaWxlZCB0byBnZXQgdHlwZSBmb3IgQmluYXJ5QXJyYXknKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjYWxsYmFjayhtYXJrZXIgKyBidWZmZXJUb1N0cmluZyhidWZmZXIpKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlVHlwZSA9PT0gJ1tvYmplY3QgQmxvYl0nKSB7XG4gICAgICAgIC8vIENvbnZlciB0aGUgYmxvYiB0byBhIGJpbmFyeUFycmF5IGFuZCB0aGVuIHRvIGEgc3RyaW5nLlxuICAgICAgICB2YXIgZmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG5cbiAgICAgICAgZmlsZVJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBCYWNrd2FyZHMtY29tcGF0aWJsZSBwcmVmaXggZm9yIHRoZSBibG9iIHR5cGUuXG4gICAgICAgICAgICB2YXIgc3RyID0gQkxPQl9UWVBFX1BSRUZJWCArIHZhbHVlLnR5cGUgKyAnficgKyBidWZmZXJUb1N0cmluZyh0aGlzLnJlc3VsdCk7XG5cbiAgICAgICAgICAgIGNhbGxiYWNrKFNFUklBTElaRURfTUFSS0VSICsgVFlQRV9CTE9CICsgc3RyKTtcbiAgICAgICAgfTtcblxuICAgICAgICBmaWxlUmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY2FsbGJhY2soSlNPTi5zdHJpbmdpZnkodmFsdWUpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkNvdWxkbid0IGNvbnZlcnQgdmFsdWUgaW50byBhIEpTT04gc3RyaW5nOiBcIiwgdmFsdWUpO1xuXG4gICAgICAgICAgICBjYWxsYmFjayhudWxsLCBlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy8gRGVzZXJpYWxpemUgZGF0YSB3ZSd2ZSBpbnNlcnRlZCBpbnRvIGEgdmFsdWUgY29sdW1uL2ZpZWxkLiBXZSBwbGFjZVxuLy8gc3BlY2lhbCBtYXJrZXJzIGludG8gb3VyIHN0cmluZ3MgdG8gbWFyayB0aGVtIGFzIGVuY29kZWQ7IHRoaXMgaXNuJ3Rcbi8vIGFzIG5pY2UgYXMgYSBtZXRhIGZpZWxkLCBidXQgaXQncyB0aGUgb25seSBzYW5lIHRoaW5nIHdlIGNhbiBkbyB3aGlsc3Rcbi8vIGtlZXBpbmcgbG9jYWxTdG9yYWdlIHN1cHBvcnQgaW50YWN0LlxuLy9cbi8vIE9mdGVudGltZXMgdGhpcyB3aWxsIGp1c3QgZGVzZXJpYWxpemUgSlNPTiBjb250ZW50LCBidXQgaWYgd2UgaGF2ZSBhXG4vLyBzcGVjaWFsIG1hcmtlciAoU0VSSUFMSVpFRF9NQVJLRVIsIGRlZmluZWQgYWJvdmUpLCB3ZSB3aWxsIGV4dHJhY3Rcbi8vIHNvbWUga2luZCBvZiBhcnJheWJ1ZmZlci9iaW5hcnkgZGF0YS90eXBlZCBhcnJheSBvdXQgb2YgdGhlIHN0cmluZy5cbmZ1bmN0aW9uIGRlc2VyaWFsaXplKHZhbHVlKSB7XG4gICAgLy8gSWYgd2UgaGF2ZW4ndCBtYXJrZWQgdGhpcyBzdHJpbmcgYXMgYmVpbmcgc3BlY2lhbGx5IHNlcmlhbGl6ZWQgKGkuZS5cbiAgICAvLyBzb21ldGhpbmcgb3RoZXIgdGhhbiBzZXJpYWxpemVkIEpTT04pLCB3ZSBjYW4ganVzdCByZXR1cm4gaXQgYW5kIGJlXG4gICAgLy8gZG9uZSB3aXRoIGl0LlxuICAgIGlmICh2YWx1ZS5zdWJzdHJpbmcoMCwgU0VSSUFMSVpFRF9NQVJLRVJfTEVOR1RIKSAhPT0gU0VSSUFMSVpFRF9NQVJLRVIpIHtcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UodmFsdWUpO1xuICAgIH1cblxuICAgIC8vIFRoZSBmb2xsb3dpbmcgY29kZSBkZWFscyB3aXRoIGRlc2VyaWFsaXppbmcgc29tZSBraW5kIG9mIEJsb2Igb3JcbiAgICAvLyBUeXBlZEFycmF5LiBGaXJzdCB3ZSBzZXBhcmF0ZSBvdXQgdGhlIHR5cGUgb2YgZGF0YSB3ZSdyZSBkZWFsaW5nXG4gICAgLy8gd2l0aCBmcm9tIHRoZSBkYXRhIGl0c2VsZi5cbiAgICB2YXIgc2VyaWFsaXplZFN0cmluZyA9IHZhbHVlLnN1YnN0cmluZyhUWVBFX1NFUklBTElaRURfTUFSS0VSX0xFTkdUSCk7XG4gICAgdmFyIHR5cGUgPSB2YWx1ZS5zdWJzdHJpbmcoU0VSSUFMSVpFRF9NQVJLRVJfTEVOR1RILCBUWVBFX1NFUklBTElaRURfTUFSS0VSX0xFTkdUSCk7XG5cbiAgICB2YXIgYmxvYlR5cGU7XG4gICAgLy8gQmFja3dhcmRzLWNvbXBhdGlibGUgYmxvYiB0eXBlIHNlcmlhbGl6YXRpb24gc3RyYXRlZ3kuXG4gICAgLy8gREJzIGNyZWF0ZWQgd2l0aCBvbGRlciB2ZXJzaW9ucyBvZiBsb2NhbEZvcmFnZSB3aWxsIHNpbXBseSBub3QgaGF2ZSB0aGUgYmxvYiB0eXBlLlxuICAgIGlmICh0eXBlID09PSBUWVBFX0JMT0IgJiYgQkxPQl9UWVBFX1BSRUZJWF9SRUdFWC50ZXN0KHNlcmlhbGl6ZWRTdHJpbmcpKSB7XG4gICAgICAgIHZhciBtYXRjaGVyID0gc2VyaWFsaXplZFN0cmluZy5tYXRjaChCTE9CX1RZUEVfUFJFRklYX1JFR0VYKTtcbiAgICAgICAgYmxvYlR5cGUgPSBtYXRjaGVyWzFdO1xuICAgICAgICBzZXJpYWxpemVkU3RyaW5nID0gc2VyaWFsaXplZFN0cmluZy5zdWJzdHJpbmcobWF0Y2hlclswXS5sZW5ndGgpO1xuICAgIH1cbiAgICB2YXIgYnVmZmVyID0gc3RyaW5nVG9CdWZmZXIoc2VyaWFsaXplZFN0cmluZyk7XG5cbiAgICAvLyBSZXR1cm4gdGhlIHJpZ2h0IHR5cGUgYmFzZWQgb24gdGhlIGNvZGUvdHlwZSBzZXQgZHVyaW5nXG4gICAgLy8gc2VyaWFsaXphdGlvbi5cbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSBUWVBFX0FSUkFZQlVGRkVSOlxuICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlcjtcbiAgICAgICAgY2FzZSBUWVBFX0JMT0I6XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlQmxvYihbYnVmZmVyXSwgeyB0eXBlOiBibG9iVHlwZSB9KTtcbiAgICAgICAgY2FzZSBUWVBFX0lOVDhBUlJBWTpcbiAgICAgICAgICAgIHJldHVybiBuZXcgSW50OEFycmF5KGJ1ZmZlcik7XG4gICAgICAgIGNhc2UgVFlQRV9VSU5UOEFSUkFZOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7XG4gICAgICAgIGNhc2UgVFlQRV9VSU5UOENMQU1QRURBUlJBWTpcbiAgICAgICAgICAgIHJldHVybiBuZXcgVWludDhDbGFtcGVkQXJyYXkoYnVmZmVyKTtcbiAgICAgICAgY2FzZSBUWVBFX0lOVDE2QVJSQVk6XG4gICAgICAgICAgICByZXR1cm4gbmV3IEludDE2QXJyYXkoYnVmZmVyKTtcbiAgICAgICAgY2FzZSBUWVBFX1VJTlQxNkFSUkFZOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBVaW50MTZBcnJheShidWZmZXIpO1xuICAgICAgICBjYXNlIFRZUEVfSU5UMzJBUlJBWTpcbiAgICAgICAgICAgIHJldHVybiBuZXcgSW50MzJBcnJheShidWZmZXIpO1xuICAgICAgICBjYXNlIFRZUEVfVUlOVDMyQVJSQVk6XG4gICAgICAgICAgICByZXR1cm4gbmV3IFVpbnQzMkFycmF5KGJ1ZmZlcik7XG4gICAgICAgIGNhc2UgVFlQRV9GTE9BVDMyQVJSQVk6XG4gICAgICAgICAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShidWZmZXIpO1xuICAgICAgICBjYXNlIFRZUEVfRkxPQVQ2NEFSUkFZOlxuICAgICAgICAgICAgcmV0dXJuIG5ldyBGbG9hdDY0QXJyYXkoYnVmZmVyKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5rb3duIHR5cGU6ICcgKyB0eXBlKTtcbiAgICB9XG59XG5cbnZhciBsb2NhbGZvcmFnZVNlcmlhbGl6ZXIgPSB7XG4gICAgc2VyaWFsaXplOiBzZXJpYWxpemUsXG4gICAgZGVzZXJpYWxpemU6IGRlc2VyaWFsaXplLFxuICAgIHN0cmluZ1RvQnVmZmVyOiBzdHJpbmdUb0J1ZmZlcixcbiAgICBidWZmZXJUb1N0cmluZzogYnVmZmVyVG9TdHJpbmdcbn07XG5cbi8qXG4gKiBJbmNsdWRlcyBjb2RlIGZyb206XG4gKlxuICogYmFzZTY0LWFycmF5YnVmZmVyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vbmlrbGFzdmgvYmFzZTY0LWFycmF5YnVmZmVyXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEyIE5pa2xhcyB2b24gSGVydHplblxuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxuICovXG4vLyBPcGVuIHRoZSBXZWJTUUwgZGF0YWJhc2UgKGF1dG9tYXRpY2FsbHkgY3JlYXRlcyBvbmUgaWYgb25lIGRpZG4ndFxuLy8gcHJldmlvdXNseSBleGlzdCksIHVzaW5nIGFueSBvcHRpb25zIHNldCBpbiB0aGUgY29uZmlnLlxuZnVuY3Rpb24gX2luaXRTdG9yYWdlJDEob3B0aW9ucykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGJJbmZvID0ge1xuICAgICAgICBkYjogbnVsbFxuICAgIH07XG5cbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgICBmb3IgKHZhciBpIGluIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGRiSW5mb1tpXSA9IHR5cGVvZiBvcHRpb25zW2ldICE9PSAnc3RyaW5nJyA/IG9wdGlvbnNbaV0udG9TdHJpbmcoKSA6IG9wdGlvbnNbaV07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZGJJbmZvUHJvbWlzZSA9IG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAvLyBPcGVuIHRoZSBkYXRhYmFzZTsgdGhlIG9wZW5EYXRhYmFzZSBBUEkgd2lsbCBhdXRvbWF0aWNhbGx5XG4gICAgICAgIC8vIGNyZWF0ZSBpdCBmb3IgdXMgaWYgaXQgZG9lc24ndCBleGlzdC5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGRiSW5mby5kYiA9IG9wZW5EYXRhYmFzZShkYkluZm8ubmFtZSwgU3RyaW5nKGRiSW5mby52ZXJzaW9uKSwgZGJJbmZvLmRlc2NyaXB0aW9uLCBkYkluZm8uc2l6ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QoZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgb3VyIGtleS92YWx1ZSB0YWJsZSBpZiBpdCBkb2Vzbid0IGV4aXN0LlxuICAgICAgICBkYkluZm8uZGIudHJhbnNhY3Rpb24oZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgIHQuZXhlY3V0ZVNxbCgnQ1JFQVRFIFRBQkxFIElGIE5PVCBFWElTVFMgJyArIGRiSW5mby5zdG9yZU5hbWUgKyAnIChpZCBJTlRFR0VSIFBSSU1BUlkgS0VZLCBrZXkgdW5pcXVlLCB2YWx1ZSknLCBbXSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNlbGYuX2RiSW5mbyA9IGRiSW5mbztcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAodCwgZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGJJbmZvLnNlcmlhbGl6ZXIgPSBsb2NhbGZvcmFnZVNlcmlhbGl6ZXI7XG4gICAgcmV0dXJuIGRiSW5mb1Byb21pc2U7XG59XG5cbmZ1bmN0aW9uIGdldEl0ZW0kMShrZXksIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgLy8gQ2FzdCB0aGUga2V5IHRvIGEgc3RyaW5nLCBhcyB0aGF0J3MgYWxsIHdlIGNhbiBzZXQgYXMgYSBrZXkuXG4gICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihrZXkgKyAnIHVzZWQgYXMgYSBrZXksIGJ1dCBpdCBpcyBub3QgYSBzdHJpbmcuJyk7XG4gICAgICAgIGtleSA9IFN0cmluZyhrZXkpO1xuICAgIH1cblxuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgICAgICBkYkluZm8uZGIudHJhbnNhY3Rpb24oZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgICAgICB0LmV4ZWN1dGVTcWwoJ1NFTEVDVCAqIEZST00gJyArIGRiSW5mby5zdG9yZU5hbWUgKyAnIFdIRVJFIGtleSA9ID8gTElNSVQgMScsIFtrZXldLCBmdW5jdGlvbiAodCwgcmVzdWx0cykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gcmVzdWx0cy5yb3dzLmxlbmd0aCA/IHJlc3VsdHMucm93cy5pdGVtKDApLnZhbHVlIDogbnVsbDtcblxuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayB0byBzZWUgaWYgdGhpcyBpcyBzZXJpYWxpemVkIGNvbnRlbnQgd2UgbmVlZCB0b1xuICAgICAgICAgICAgICAgICAgICAvLyB1bnBhY2suXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRiSW5mby5zZXJpYWxpemVyLmRlc2VyaWFsaXplKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgfSwgZnVuY3Rpb24gKHQsIGVycm9yKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVtcImNhdGNoXCJdKHJlamVjdCk7XG4gICAgfSk7XG5cbiAgICBleGVjdXRlQ2FsbGJhY2socHJvbWlzZSwgY2FsbGJhY2spO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5mdW5jdGlvbiBpdGVyYXRlJDEoaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgc2VsZi5yZWFkeSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcblxuICAgICAgICAgICAgZGJJbmZvLmRiLnRyYW5zYWN0aW9uKGZ1bmN0aW9uICh0KSB7XG4gICAgICAgICAgICAgICAgdC5leGVjdXRlU3FsKCdTRUxFQ1QgKiBGUk9NICcgKyBkYkluZm8uc3RvcmVOYW1lLCBbXSwgZnVuY3Rpb24gKHQsIHJlc3VsdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJvd3MgPSByZXN1bHRzLnJvd3M7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsZW5ndGggPSByb3dzLmxlbmd0aDtcblxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXRlbSA9IHJvd3MuaXRlbShpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBpdGVtLnZhbHVlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayB0byBzZWUgaWYgdGhpcyBpcyBzZXJpYWxpemVkIGNvbnRlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gdW5wYWNrLlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRiSW5mby5zZXJpYWxpemVyLmRlc2VyaWFsaXplKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGl0ZXJhdG9yKHJlc3VsdCwgaXRlbS5rZXksIGkgKyAxKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdm9pZCgwKSBwcmV2ZW50cyBwcm9ibGVtcyB3aXRoIHJlZGVmaW5pdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gb2YgYHVuZGVmaW5lZGAuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9PSB2b2lkIDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uICh0LCBlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbmZ1bmN0aW9uIF9zZXRJdGVtKGtleSwgdmFsdWUsIGNhbGxiYWNrLCByZXRyaWVzTGVmdCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIC8vIENhc3QgdGhlIGtleSB0byBhIHN0cmluZywgYXMgdGhhdCdzIGFsbCB3ZSBjYW4gc2V0IGFzIGEga2V5LlxuICAgIGlmICh0eXBlb2Yga2V5ICE9PSAnc3RyaW5nJykge1xuICAgICAgICBjb25zb2xlLndhcm4oa2V5ICsgJyB1c2VkIGFzIGEga2V5LCBidXQgaXQgaXMgbm90IGEgc3RyaW5nLicpO1xuICAgICAgICBrZXkgPSBTdHJpbmcoa2V5KTtcbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBUaGUgbG9jYWxTdG9yYWdlIEFQSSBkb2Vzbid0IHJldHVybiB1bmRlZmluZWQgdmFsdWVzIGluIGFuXG4gICAgICAgICAgICAvLyBcImV4cGVjdGVkXCIgd2F5LCBzbyB1bmRlZmluZWQgaXMgYWx3YXlzIGNhc3QgdG8gbnVsbCBpbiBhbGxcbiAgICAgICAgICAgIC8vIGRyaXZlcnMuIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL21vemlsbGEvbG9jYWxGb3JhZ2UvcHVsbC80MlxuICAgICAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNhdmUgdGhlIG9yaWdpbmFsIHZhbHVlIHRvIHBhc3MgdG8gdGhlIGNhbGxiYWNrLlxuICAgICAgICAgICAgdmFyIG9yaWdpbmFsVmFsdWUgPSB2YWx1ZTtcblxuICAgICAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgICAgIGRiSW5mby5zZXJpYWxpemVyLnNlcmlhbGl6ZSh2YWx1ZSwgZnVuY3Rpb24gKHZhbHVlLCBlcnJvcikge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRiSW5mby5kYi50cmFuc2FjdGlvbihmdW5jdGlvbiAodCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdC5leGVjdXRlU3FsKCdJTlNFUlQgT1IgUkVQTEFDRSBJTlRPICcgKyBkYkluZm8uc3RvcmVOYW1lICsgJyAoa2V5LCB2YWx1ZSkgVkFMVUVTICg/LCA/KScsIFtrZXksIHZhbHVlXSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUob3JpZ2luYWxWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBmdW5jdGlvbiAodCwgZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChzcWxFcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIHRyYW5zYWN0aW9uIGZhaWxlZDsgY2hlY2tcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRvIHNlZSBpZiBpdCdzIGEgcXVvdGEgZXJyb3IuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3FsRXJyb3IuY29kZSA9PT0gc3FsRXJyb3IuUVVPVEFfRVJSKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UgcmVqZWN0IHRoZSBjYWxsYmFjayBvdXRyaWdodCBmb3Igbm93LCBidXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpdCdzIHdvcnRoIHRyeWluZyB0byByZS1ydW4gdGhlIHRyYW5zYWN0aW9uLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV2ZW4gaWYgdGhlIHVzZXIgYWNjZXB0cyB0aGUgcHJvbXB0IHRvIHVzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1vcmUgc3RvcmFnZSBvbiBTYWZhcmksIHRoaXMgZXJyb3Igd2lsbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJlIGNhbGxlZC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRyeSB0byByZS1ydW4gdGhlIHRyYW5zYWN0aW9uLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXRyaWVzTGVmdCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShfc2V0SXRlbS5hcHBseShzZWxmLCBba2V5LCBvcmlnaW5hbFZhbHVlLCBjYWxsYmFjaywgcmV0cmllc0xlZnQgLSAxXSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChzcWxFcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVtcImNhdGNoXCJdKHJlamVjdCk7XG4gICAgfSk7XG5cbiAgICBleGVjdXRlQ2FsbGJhY2socHJvbWlzZSwgY2FsbGJhY2spO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5mdW5jdGlvbiBzZXRJdGVtJDEoa2V5LCB2YWx1ZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gX3NldEl0ZW0uYXBwbHkodGhpcywgW2tleSwgdmFsdWUsIGNhbGxiYWNrLCAxXSk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUl0ZW0kMShrZXksIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgLy8gQ2FzdCB0aGUga2V5IHRvIGEgc3RyaW5nLCBhcyB0aGF0J3MgYWxsIHdlIGNhbiBzZXQgYXMgYSBrZXkuXG4gICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihrZXkgKyAnIHVzZWQgYXMgYSBrZXksIGJ1dCBpdCBpcyBub3QgYSBzdHJpbmcuJyk7XG4gICAgICAgIGtleSA9IFN0cmluZyhrZXkpO1xuICAgIH1cblxuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgICAgICBkYkluZm8uZGIudHJhbnNhY3Rpb24oZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgICAgICB0LmV4ZWN1dGVTcWwoJ0RFTEVURSBGUk9NICcgKyBkYkluZm8uc3RvcmVOYW1lICsgJyBXSEVSRSBrZXkgPSA/JywgW2tleV0sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uICh0LCBlcnJvcikge1xuXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSlbXCJjYXRjaFwiXShyZWplY3QpO1xuICAgIH0pO1xuXG4gICAgZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuLy8gRGVsZXRlcyBldmVyeSBpdGVtIGluIHRoZSB0YWJsZS5cbi8vIFRPRE86IEZpbmQgb3V0IGlmIHRoaXMgcmVzZXRzIHRoZSBBVVRPX0lOQ1JFTUVOVCBudW1iZXIuXG5mdW5jdGlvbiBjbGVhciQxKGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgc2VsZi5yZWFkeSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgICAgIGRiSW5mby5kYi50cmFuc2FjdGlvbihmdW5jdGlvbiAodCkge1xuICAgICAgICAgICAgICAgIHQuZXhlY3V0ZVNxbCgnREVMRVRFIEZST00gJyArIGRiSW5mby5zdG9yZU5hbWUsIFtdLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9LCBmdW5jdGlvbiAodCwgZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVtcImNhdGNoXCJdKHJlamVjdCk7XG4gICAgfSk7XG5cbiAgICBleGVjdXRlQ2FsbGJhY2socHJvbWlzZSwgY2FsbGJhY2spO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG4vLyBEb2VzIGEgc2ltcGxlIGBDT1VOVChrZXkpYCB0byBnZXQgdGhlIG51bWJlciBvZiBpdGVtcyBzdG9yZWQgaW5cbi8vIGxvY2FsRm9yYWdlLlxuZnVuY3Rpb24gbGVuZ3RoJDEoY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlJDEoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgZGJJbmZvID0gc2VsZi5fZGJJbmZvO1xuICAgICAgICAgICAgZGJJbmZvLmRiLnRyYW5zYWN0aW9uKGZ1bmN0aW9uICh0KSB7XG4gICAgICAgICAgICAgICAgLy8gQWhoaCwgU1FMIG1ha2VzIHRoaXMgb25lIHNvb29vb28gZWFzeS5cbiAgICAgICAgICAgICAgICB0LmV4ZWN1dGVTcWwoJ1NFTEVDVCBDT1VOVChrZXkpIGFzIGMgRlJPTSAnICsgZGJJbmZvLnN0b3JlTmFtZSwgW10sIGZ1bmN0aW9uICh0LCByZXN1bHRzKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSByZXN1bHRzLnJvd3MuaXRlbSgwKS5jO1xuXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgICAgICAgICB9LCBmdW5jdGlvbiAodCwgZXJyb3IpIHtcblxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbi8vIFJldHVybiB0aGUga2V5IGxvY2F0ZWQgYXQga2V5IGluZGV4IFg7IGVzc2VudGlhbGx5IGdldHMgdGhlIGtleSBmcm9tIGFcbi8vIGBXSEVSRSBpZCA9ID9gLiBUaGlzIGlzIHRoZSBtb3N0IGVmZmljaWVudCB3YXkgSSBjYW4gdGhpbmsgdG8gaW1wbGVtZW50XG4vLyB0aGlzIHJhcmVseS11c2VkIChpbiBteSBleHBlcmllbmNlKSBwYXJ0IG9mIHRoZSBBUEksIGJ1dCBpdCBjYW4gc2VlbVxuLy8gaW5jb25zaXN0ZW50LCBiZWNhdXNlIHdlIGRvIGBJTlNFUlQgT1IgUkVQTEFDRSBJTlRPYCBvbiBgc2V0SXRlbSgpYCwgc29cbi8vIHRoZSBJRCBvZiBlYWNoIGtleSB3aWxsIGNoYW5nZSBldmVyeSB0aW1lIGl0J3MgdXBkYXRlZC4gUGVyaGFwcyBhIHN0b3JlZFxuLy8gcHJvY2VkdXJlIGZvciB0aGUgYHNldEl0ZW0oKWAgU1FMIHdvdWxkIHNvbHZlIHRoaXMgcHJvYmxlbT9cbi8vIFRPRE86IERvbid0IGNoYW5nZSBJRCBvbiBgc2V0SXRlbSgpYC5cbmZ1bmN0aW9uIGtleSQxKG4sIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHByb21pc2UgPSBuZXcgUHJvbWlzZSQxKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgc2VsZi5yZWFkeSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgICAgIGRiSW5mby5kYi50cmFuc2FjdGlvbihmdW5jdGlvbiAodCkge1xuICAgICAgICAgICAgICAgIHQuZXhlY3V0ZVNxbCgnU0VMRUNUIGtleSBGUk9NICcgKyBkYkluZm8uc3RvcmVOYW1lICsgJyBXSEVSRSBpZCA9ID8gTElNSVQgMScsIFtuICsgMV0sIGZ1bmN0aW9uICh0LCByZXN1bHRzKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSByZXN1bHRzLnJvd3MubGVuZ3RoID8gcmVzdWx0cy5yb3dzLml0ZW0oMCkua2V5IDogbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uICh0LCBlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbmZ1bmN0aW9uIGtleXMkMShjYWxsYmFjaykge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgICAgICBkYkluZm8uZGIudHJhbnNhY3Rpb24oZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgICAgICAgICB0LmV4ZWN1dGVTcWwoJ1NFTEVDVCBrZXkgRlJPTSAnICsgZGJJbmZvLnN0b3JlTmFtZSwgW10sIGZ1bmN0aW9uICh0LCByZXN1bHRzKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBrZXlzID0gW107XG5cbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXN1bHRzLnJvd3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleXMucHVzaChyZXN1bHRzLnJvd3MuaXRlbShpKS5rZXkpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShrZXlzKTtcbiAgICAgICAgICAgICAgICB9LCBmdW5jdGlvbiAodCwgZXJyb3IpIHtcblxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pW1wiY2F0Y2hcIl0ocmVqZWN0KTtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbnZhciB3ZWJTUUxTdG9yYWdlID0ge1xuICAgIF9kcml2ZXI6ICd3ZWJTUUxTdG9yYWdlJyxcbiAgICBfaW5pdFN0b3JhZ2U6IF9pbml0U3RvcmFnZSQxLFxuICAgIGl0ZXJhdGU6IGl0ZXJhdGUkMSxcbiAgICBnZXRJdGVtOiBnZXRJdGVtJDEsXG4gICAgc2V0SXRlbTogc2V0SXRlbSQxLFxuICAgIHJlbW92ZUl0ZW06IHJlbW92ZUl0ZW0kMSxcbiAgICBjbGVhcjogY2xlYXIkMSxcbiAgICBsZW5ndGg6IGxlbmd0aCQxLFxuICAgIGtleToga2V5JDEsXG4gICAga2V5czoga2V5cyQxXG59O1xuXG4vLyBDb25maWcgdGhlIGxvY2FsU3RvcmFnZSBiYWNrZW5kLCB1c2luZyBvcHRpb25zIHNldCBpbiB0aGUgY29uZmlnLlxuZnVuY3Rpb24gX2luaXRTdG9yYWdlJDIob3B0aW9ucykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGJJbmZvID0ge307XG4gICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgICAgZm9yICh2YXIgaSBpbiBvcHRpb25zKSB7XG4gICAgICAgICAgICBkYkluZm9baV0gPSBvcHRpb25zW2ldO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGJJbmZvLmtleVByZWZpeCA9IGRiSW5mby5uYW1lICsgJy8nO1xuXG4gICAgaWYgKGRiSW5mby5zdG9yZU5hbWUgIT09IHNlbGYuX2RlZmF1bHRDb25maWcuc3RvcmVOYW1lKSB7XG4gICAgICAgIGRiSW5mby5rZXlQcmVmaXggKz0gZGJJbmZvLnN0b3JlTmFtZSArICcvJztcbiAgICB9XG5cbiAgICBzZWxmLl9kYkluZm8gPSBkYkluZm87XG4gICAgZGJJbmZvLnNlcmlhbGl6ZXIgPSBsb2NhbGZvcmFnZVNlcmlhbGl6ZXI7XG5cbiAgICByZXR1cm4gUHJvbWlzZSQxLnJlc29sdmUoKTtcbn1cblxuLy8gUmVtb3ZlIGFsbCBrZXlzIGZyb20gdGhlIGRhdGFzdG9yZSwgZWZmZWN0aXZlbHkgZGVzdHJveWluZyBhbGwgZGF0YSBpblxuLy8gdGhlIGFwcCdzIGtleS92YWx1ZSBzdG9yZSFcbmZ1bmN0aW9uIGNsZWFyJDIoY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIHByb21pc2UgPSBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBrZXlQcmVmaXggPSBzZWxmLl9kYkluZm8ua2V5UHJlZml4O1xuXG4gICAgICAgIGZvciAodmFyIGkgPSBsb2NhbFN0b3JhZ2UubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBsb2NhbFN0b3JhZ2Uua2V5KGkpO1xuXG4gICAgICAgICAgICBpZiAoa2V5LmluZGV4T2Yoa2V5UHJlZml4KSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbi8vIFJldHJpZXZlIGFuIGl0ZW0gZnJvbSB0aGUgc3RvcmUuIFVubGlrZSB0aGUgb3JpZ2luYWwgYXN5bmNfc3RvcmFnZVxuLy8gbGlicmFyeSBpbiBHYWlhLCB3ZSBkb24ndCBtb2RpZnkgcmV0dXJuIHZhbHVlcyBhdCBhbGwuIElmIGEga2V5J3MgdmFsdWVcbi8vIGlzIGB1bmRlZmluZWRgLCB3ZSBwYXNzIHRoYXQgdmFsdWUgdG8gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uLlxuZnVuY3Rpb24gZ2V0SXRlbSQyKGtleSwgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAvLyBDYXN0IHRoZSBrZXkgdG8gYSBzdHJpbmcsIGFzIHRoYXQncyBhbGwgd2UgY2FuIHNldCBhcyBhIGtleS5cbiAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGtleSArICcgdXNlZCBhcyBhIGtleSwgYnV0IGl0IGlzIG5vdCBhIHN0cmluZy4nKTtcbiAgICAgICAga2V5ID0gU3RyaW5nKGtleSk7XG4gICAgfVxuXG4gICAgdmFyIHByb21pc2UgPSBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgIHZhciByZXN1bHQgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShkYkluZm8ua2V5UHJlZml4ICsga2V5KTtcblxuICAgICAgICAvLyBJZiBhIHJlc3VsdCB3YXMgZm91bmQsIHBhcnNlIGl0IGZyb20gdGhlIHNlcmlhbGl6ZWRcbiAgICAgICAgLy8gc3RyaW5nIGludG8gYSBKUyBvYmplY3QuIElmIHJlc3VsdCBpc24ndCB0cnV0aHksIHRoZSBrZXlcbiAgICAgICAgLy8gaXMgbGlrZWx5IHVuZGVmaW5lZCBhbmQgd2UnbGwgcGFzcyBpdCBzdHJhaWdodCB0byB0aGVcbiAgICAgICAgLy8gY2FsbGJhY2suXG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGRiSW5mby5zZXJpYWxpemVyLmRlc2VyaWFsaXplKHJlc3VsdCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuXG4gICAgZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuLy8gSXRlcmF0ZSBvdmVyIGFsbCBpdGVtcyBpbiB0aGUgc3RvcmUuXG5mdW5jdGlvbiBpdGVyYXRlJDIoaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHByb21pc2UgPSBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgIHZhciBrZXlQcmVmaXggPSBkYkluZm8ua2V5UHJlZml4O1xuICAgICAgICB2YXIga2V5UHJlZml4TGVuZ3RoID0ga2V5UHJlZml4Lmxlbmd0aDtcbiAgICAgICAgdmFyIGxlbmd0aCA9IGxvY2FsU3RvcmFnZS5sZW5ndGg7XG5cbiAgICAgICAgLy8gV2UgdXNlIGEgZGVkaWNhdGVkIGl0ZXJhdG9yIGluc3RlYWQgb2YgdGhlIGBpYCB2YXJpYWJsZSBiZWxvd1xuICAgICAgICAvLyBzbyBvdGhlciBrZXlzIHdlIGZldGNoIGluIGxvY2FsU3RvcmFnZSBhcmVuJ3QgY291bnRlZCBpblxuICAgICAgICAvLyB0aGUgYGl0ZXJhdGlvbk51bWJlcmAgYXJndW1lbnQgcGFzc2VkIHRvIHRoZSBgaXRlcmF0ZSgpYFxuICAgICAgICAvLyBjYWxsYmFjay5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gU2VlOiBnaXRodWIuY29tL21vemlsbGEvbG9jYWxGb3JhZ2UvcHVsbC80MzUjZGlzY3Vzc2lvbl9yMzgwNjE1MzBcbiAgICAgICAgdmFyIGl0ZXJhdGlvbk51bWJlciA9IDE7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGtleSA9IGxvY2FsU3RvcmFnZS5rZXkoaSk7XG4gICAgICAgICAgICBpZiAoa2V5LmluZGV4T2Yoa2V5UHJlZml4KSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHZhbHVlID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oa2V5KTtcblxuICAgICAgICAgICAgLy8gSWYgYSByZXN1bHQgd2FzIGZvdW5kLCBwYXJzZSBpdCBmcm9tIHRoZSBzZXJpYWxpemVkXG4gICAgICAgICAgICAvLyBzdHJpbmcgaW50byBhIEpTIG9iamVjdC4gSWYgcmVzdWx0IGlzbid0IHRydXRoeSwgdGhlXG4gICAgICAgICAgICAvLyBrZXkgaXMgbGlrZWx5IHVuZGVmaW5lZCBhbmQgd2UnbGwgcGFzcyBpdCBzdHJhaWdodFxuICAgICAgICAgICAgLy8gdG8gdGhlIGl0ZXJhdG9yLlxuICAgICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBkYkluZm8uc2VyaWFsaXplci5kZXNlcmlhbGl6ZSh2YWx1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhbHVlID0gaXRlcmF0b3IodmFsdWUsIGtleS5zdWJzdHJpbmcoa2V5UHJlZml4TGVuZ3RoKSwgaXRlcmF0aW9uTnVtYmVyKyspO1xuXG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IHZvaWQgMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxuLy8gU2FtZSBhcyBsb2NhbFN0b3JhZ2UncyBrZXkoKSBtZXRob2QsIGV4Y2VwdCB0YWtlcyBhIGNhbGxiYWNrLlxuZnVuY3Rpb24ga2V5JDIobiwgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIHByb21pc2UgPSBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkYkluZm8gPSBzZWxmLl9kYkluZm87XG4gICAgICAgIHZhciByZXN1bHQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXN1bHQgPSBsb2NhbFN0b3JhZ2Uua2V5KG4pO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgcmVzdWx0ID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlbW92ZSB0aGUgcHJlZml4IGZyb20gdGhlIGtleSwgaWYgYSBrZXkgaXMgZm91bmQuXG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zdWJzdHJpbmcoZGJJbmZvLmtleVByZWZpeC5sZW5ndGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbmZ1bmN0aW9uIGtleXMkMihjYWxsYmFjaykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgcHJvbWlzZSA9IHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgdmFyIGxlbmd0aCA9IGxvY2FsU3RvcmFnZS5sZW5ndGg7XG4gICAgICAgIHZhciBrZXlzID0gW107XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKGxvY2FsU3RvcmFnZS5rZXkoaSkuaW5kZXhPZihkYkluZm8ua2V5UHJlZml4KSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGtleXMucHVzaChsb2NhbFN0b3JhZ2Uua2V5KGkpLnN1YnN0cmluZyhkYkluZm8ua2V5UHJlZml4Lmxlbmd0aCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGtleXM7XG4gICAgfSk7XG5cbiAgICBleGVjdXRlQ2FsbGJhY2socHJvbWlzZSwgY2FsbGJhY2spO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG4vLyBTdXBwbHkgdGhlIG51bWJlciBvZiBrZXlzIGluIHRoZSBkYXRhc3RvcmUgdG8gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uLlxuZnVuY3Rpb24gbGVuZ3RoJDIoY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIHByb21pc2UgPSBzZWxmLmtleXMoKS50aGVuKGZ1bmN0aW9uIChrZXlzKSB7XG4gICAgICAgIHJldHVybiBrZXlzLmxlbmd0aDtcbiAgICB9KTtcblxuICAgIGV4ZWN1dGVDYWxsYmFjayhwcm9taXNlLCBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHByb21pc2U7XG59XG5cbi8vIFJlbW92ZSBhbiBpdGVtIGZyb20gdGhlIHN0b3JlLCBuaWNlIGFuZCBzaW1wbGUuXG5mdW5jdGlvbiByZW1vdmVJdGVtJDIoa2V5LCBjYWxsYmFjaykge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIC8vIENhc3QgdGhlIGtleSB0byBhIHN0cmluZywgYXMgdGhhdCdzIGFsbCB3ZSBjYW4gc2V0IGFzIGEga2V5LlxuICAgIGlmICh0eXBlb2Yga2V5ICE9PSAnc3RyaW5nJykge1xuICAgICAgICBjb25zb2xlLndhcm4oa2V5ICsgJyB1c2VkIGFzIGEga2V5LCBidXQgaXQgaXMgbm90IGEgc3RyaW5nLicpO1xuICAgICAgICBrZXkgPSBTdHJpbmcoa2V5KTtcbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZSA9IHNlbGYucmVhZHkoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGRiSW5mbyA9IHNlbGYuX2RiSW5mbztcbiAgICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oZGJJbmZvLmtleVByZWZpeCArIGtleSk7XG4gICAgfSk7XG5cbiAgICBleGVjdXRlQ2FsbGJhY2socHJvbWlzZSwgY2FsbGJhY2spO1xuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG4vLyBTZXQgYSBrZXkncyB2YWx1ZSBhbmQgcnVuIGFuIG9wdGlvbmFsIGNhbGxiYWNrIG9uY2UgdGhlIHZhbHVlIGlzIHNldC5cbi8vIFVubGlrZSBHYWlhJ3MgaW1wbGVtZW50YXRpb24sIHRoZSBjYWxsYmFjayBmdW5jdGlvbiBpcyBwYXNzZWQgdGhlIHZhbHVlLFxuLy8gaW4gY2FzZSB5b3Ugd2FudCB0byBvcGVyYXRlIG9uIHRoYXQgdmFsdWUgb25seSBhZnRlciB5b3UncmUgc3VyZSBpdFxuLy8gc2F2ZWQsIG9yIHNvbWV0aGluZyBsaWtlIHRoYXQuXG5mdW5jdGlvbiBzZXRJdGVtJDIoa2V5LCB2YWx1ZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAvLyBDYXN0IHRoZSBrZXkgdG8gYSBzdHJpbmcsIGFzIHRoYXQncyBhbGwgd2UgY2FuIHNldCBhcyBhIGtleS5cbiAgICBpZiAodHlwZW9mIGtleSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGtleSArICcgdXNlZCBhcyBhIGtleSwgYnV0IGl0IGlzIG5vdCBhIHN0cmluZy4nKTtcbiAgICAgICAga2V5ID0gU3RyaW5nKGtleSk7XG4gICAgfVxuXG4gICAgdmFyIHByb21pc2UgPSBzZWxmLnJlYWR5KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIENvbnZlcnQgdW5kZWZpbmVkIHZhbHVlcyB0byBudWxsLlxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbW96aWxsYS9sb2NhbEZvcmFnZS9wdWxsLzQyXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTYXZlIHRoZSBvcmlnaW5hbCB2YWx1ZSB0byBwYXNzIHRvIHRoZSBjYWxsYmFjay5cbiAgICAgICAgdmFyIG9yaWdpbmFsVmFsdWUgPSB2YWx1ZTtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICB2YXIgZGJJbmZvID0gc2VsZi5fZGJJbmZvO1xuICAgICAgICAgICAgZGJJbmZvLnNlcmlhbGl6ZXIuc2VyaWFsaXplKHZhbHVlLCBmdW5jdGlvbiAodmFsdWUsIGVycm9yKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKGRiSW5mby5rZXlQcmVmaXggKyBrZXksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUob3JpZ2luYWxWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvY2FsU3RvcmFnZSBjYXBhY2l0eSBleGNlZWRlZC5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IE1ha2UgdGhpcyBhIHNwZWNpZmljIGVycm9yL2V2ZW50LlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUubmFtZSA9PT0gJ1F1b3RhRXhjZWVkZWRFcnJvcicgfHwgZS5uYW1lID09PSAnTlNfRVJST1JfRE9NX1FVT1RBX1JFQUNIRUQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZXhlY3V0ZUNhbGxiYWNrKHByb21pc2UsIGNhbGxiYWNrKTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbn1cblxudmFyIGxvY2FsU3RvcmFnZVdyYXBwZXIgPSB7XG4gICAgX2RyaXZlcjogJ2xvY2FsU3RvcmFnZVdyYXBwZXInLFxuICAgIF9pbml0U3RvcmFnZTogX2luaXRTdG9yYWdlJDIsXG4gICAgLy8gRGVmYXVsdCBBUEksIGZyb20gR2FpYS9sb2NhbFN0b3JhZ2UuXG4gICAgaXRlcmF0ZTogaXRlcmF0ZSQyLFxuICAgIGdldEl0ZW06IGdldEl0ZW0kMixcbiAgICBzZXRJdGVtOiBzZXRJdGVtJDIsXG4gICAgcmVtb3ZlSXRlbTogcmVtb3ZlSXRlbSQyLFxuICAgIGNsZWFyOiBjbGVhciQyLFxuICAgIGxlbmd0aDogbGVuZ3RoJDIsXG4gICAga2V5OiBrZXkkMixcbiAgICBrZXlzOiBrZXlzJDJcbn07XG5cbi8vIEN1c3RvbSBkcml2ZXJzIGFyZSBzdG9yZWQgaGVyZSB3aGVuIGBkZWZpbmVEcml2ZXIoKWAgaXMgY2FsbGVkLlxuLy8gVGhleSBhcmUgc2hhcmVkIGFjcm9zcyBhbGwgaW5zdGFuY2VzIG9mIGxvY2FsRm9yYWdlLlxudmFyIEN1c3RvbURyaXZlcnMgPSB7fTtcblxudmFyIERyaXZlclR5cGUgPSB7XG4gICAgSU5ERVhFRERCOiAnYXN5bmNTdG9yYWdlJyxcbiAgICBMT0NBTFNUT1JBR0U6ICdsb2NhbFN0b3JhZ2VXcmFwcGVyJyxcbiAgICBXRUJTUUw6ICd3ZWJTUUxTdG9yYWdlJ1xufTtcblxudmFyIERlZmF1bHREcml2ZXJPcmRlciA9IFtEcml2ZXJUeXBlLklOREVYRUREQiwgRHJpdmVyVHlwZS5XRUJTUUwsIERyaXZlclR5cGUuTE9DQUxTVE9SQUdFXTtcblxudmFyIExpYnJhcnlNZXRob2RzID0gWydjbGVhcicsICdnZXRJdGVtJywgJ2l0ZXJhdGUnLCAna2V5JywgJ2tleXMnLCAnbGVuZ3RoJywgJ3JlbW92ZUl0ZW0nLCAnc2V0SXRlbSddO1xuXG52YXIgRGVmYXVsdENvbmZpZyA9IHtcbiAgICBkZXNjcmlwdGlvbjogJycsXG4gICAgZHJpdmVyOiBEZWZhdWx0RHJpdmVyT3JkZXIuc2xpY2UoKSxcbiAgICBuYW1lOiAnbG9jYWxmb3JhZ2UnLFxuICAgIC8vIERlZmF1bHQgREIgc2l6ZSBpcyBfSlVTVCBVTkRFUl8gNU1CLCBhcyBpdCdzIHRoZSBoaWdoZXN0IHNpemVcbiAgICAvLyB3ZSBjYW4gdXNlIHdpdGhvdXQgYSBwcm9tcHQuXG4gICAgc2l6ZTogNDk4MDczNixcbiAgICBzdG9yZU5hbWU6ICdrZXl2YWx1ZXBhaXJzJyxcbiAgICB2ZXJzaW9uOiAxLjBcbn07XG5cbnZhciBkcml2ZXJTdXBwb3J0ID0ge307XG4vLyBDaGVjayB0byBzZWUgaWYgSW5kZXhlZERCIGlzIGF2YWlsYWJsZSBhbmQgaWYgaXQgaXMgdGhlIGxhdGVzdFxuLy8gaW1wbGVtZW50YXRpb247IGl0J3Mgb3VyIHByZWZlcnJlZCBiYWNrZW5kIGxpYnJhcnkuIFdlIHVzZSBcIl9zcGVjX3Rlc3RcIlxuLy8gYXMgdGhlIG5hbWUgb2YgdGhlIGRhdGFiYXNlIGJlY2F1c2UgaXQncyBub3QgdGhlIG9uZSB3ZSdsbCBvcGVyYXRlIG9uLFxuLy8gYnV0IGl0J3MgdXNlZnVsIHRvIG1ha2Ugc3VyZSBpdHMgdXNpbmcgdGhlIHJpZ2h0IHNwZWMuXG4vLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9tb3ppbGxhL2xvY2FsRm9yYWdlL2lzc3Vlcy8xMjhcbmRyaXZlclN1cHBvcnRbRHJpdmVyVHlwZS5JTkRFWEVEREJdID0gaXNJbmRleGVkREJWYWxpZCgpO1xuXG5kcml2ZXJTdXBwb3J0W0RyaXZlclR5cGUuV0VCU1FMXSA9IGlzV2ViU1FMVmFsaWQoKTtcblxuZHJpdmVyU3VwcG9ydFtEcml2ZXJUeXBlLkxPQ0FMU1RPUkFHRV0gPSBpc0xvY2FsU3RvcmFnZVZhbGlkKCk7XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJnKSB7XG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxuZnVuY3Rpb24gY2FsbFdoZW5SZWFkeShsb2NhbEZvcmFnZUluc3RhbmNlLCBsaWJyYXJ5TWV0aG9kKSB7XG4gICAgbG9jYWxGb3JhZ2VJbnN0YW5jZVtsaWJyYXJ5TWV0aG9kXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIF9hcmdzID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gbG9jYWxGb3JhZ2VJbnN0YW5jZS5yZWFkeSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGxvY2FsRm9yYWdlSW5zdGFuY2VbbGlicmFyeU1ldGhvZF0uYXBwbHkobG9jYWxGb3JhZ2VJbnN0YW5jZSwgX2FyZ3MpO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBleHRlbmQoKSB7XG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGFyZyA9IGFyZ3VtZW50c1tpXTtcblxuICAgICAgICBpZiAoYXJnKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gYXJnKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFyZy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FycmF5KGFyZ1trZXldKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzWzBdW2tleV0gPSBhcmdba2V5XS5zbGljZSgpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzWzBdW2tleV0gPSBhcmdba2V5XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhcmd1bWVudHNbMF07XG59XG5cbmZ1bmN0aW9uIGlzTGlicmFyeURyaXZlcihkcml2ZXJOYW1lKSB7XG4gICAgZm9yICh2YXIgZHJpdmVyIGluIERyaXZlclR5cGUpIHtcbiAgICAgICAgaWYgKERyaXZlclR5cGUuaGFzT3duUHJvcGVydHkoZHJpdmVyKSAmJiBEcml2ZXJUeXBlW2RyaXZlcl0gPT09IGRyaXZlck5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG52YXIgTG9jYWxGb3JhZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTG9jYWxGb3JhZ2Uob3B0aW9ucykge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTG9jYWxGb3JhZ2UpO1xuXG4gICAgICAgIHRoaXMuSU5ERVhFRERCID0gRHJpdmVyVHlwZS5JTkRFWEVEREI7XG4gICAgICAgIHRoaXMuTE9DQUxTVE9SQUdFID0gRHJpdmVyVHlwZS5MT0NBTFNUT1JBR0U7XG4gICAgICAgIHRoaXMuV0VCU1FMID0gRHJpdmVyVHlwZS5XRUJTUUw7XG5cbiAgICAgICAgdGhpcy5fZGVmYXVsdENvbmZpZyA9IGV4dGVuZCh7fSwgRGVmYXVsdENvbmZpZyk7XG4gICAgICAgIHRoaXMuX2NvbmZpZyA9IGV4dGVuZCh7fSwgdGhpcy5fZGVmYXVsdENvbmZpZywgb3B0aW9ucyk7XG4gICAgICAgIHRoaXMuX2RyaXZlclNldCA9IG51bGw7XG4gICAgICAgIHRoaXMuX2luaXREcml2ZXIgPSBudWxsO1xuICAgICAgICB0aGlzLl9yZWFkeSA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9kYkluZm8gPSBudWxsO1xuXG4gICAgICAgIHRoaXMuX3dyYXBMaWJyYXJ5TWV0aG9kc1dpdGhSZWFkeSgpO1xuICAgICAgICB0aGlzLnNldERyaXZlcih0aGlzLl9jb25maWcuZHJpdmVyKVtcImNhdGNoXCJdKGZ1bmN0aW9uICgpIHt9KTtcbiAgICB9XG5cbiAgICAvLyBTZXQgYW55IGNvbmZpZyB2YWx1ZXMgZm9yIGxvY2FsRm9yYWdlOyBjYW4gYmUgY2FsbGVkIGFueXRpbWUgYmVmb3JlXG4gICAgLy8gdGhlIGZpcnN0IEFQSSBjYWxsIChlLmcuIGBnZXRJdGVtYCwgYHNldEl0ZW1gKS5cbiAgICAvLyBXZSBsb29wIHRocm91Z2ggb3B0aW9ucyBzbyB3ZSBkb24ndCBvdmVyd3JpdGUgZXhpc3RpbmcgY29uZmlnXG4gICAgLy8gdmFsdWVzLlxuXG5cbiAgICBMb2NhbEZvcmFnZS5wcm90b3R5cGUuY29uZmlnID0gZnVuY3Rpb24gY29uZmlnKG9wdGlvbnMpIHtcbiAgICAgICAgLy8gSWYgdGhlIG9wdGlvbnMgYXJndW1lbnQgaXMgYW4gb2JqZWN0LCB3ZSB1c2UgaXQgdG8gc2V0IHZhbHVlcy5cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCB3ZSByZXR1cm4gZWl0aGVyIGEgc3BlY2lmaWVkIGNvbmZpZyB2YWx1ZSBvciBhbGxcbiAgICAgICAgLy8gY29uZmlnIHZhbHVlcy5cbiAgICAgICAgaWYgKCh0eXBlb2Ygb3B0aW9ucyA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2Yob3B0aW9ucykpID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgLy8gSWYgbG9jYWxmb3JhZ2UgaXMgcmVhZHkgYW5kIGZ1bGx5IGluaXRpYWxpemVkLCB3ZSBjYW4ndCBzZXRcbiAgICAgICAgICAgIC8vIGFueSBuZXcgY29uZmlndXJhdGlvbiB2YWx1ZXMuIEluc3RlYWQsIHdlIHJldHVybiBhbiBlcnJvci5cbiAgICAgICAgICAgIGlmICh0aGlzLl9yZWFkeSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRXJyb3IoXCJDYW4ndCBjYWxsIGNvbmZpZygpIGFmdGVyIGxvY2FsZm9yYWdlIFwiICsgJ2hhcyBiZWVuIHVzZWQuJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gb3B0aW9ucykge1xuICAgICAgICAgICAgICAgIGlmIChpID09PSAnc3RvcmVOYW1lJykge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zW2ldID0gb3B0aW9uc1tpXS5yZXBsYWNlKC9cXFcvZywgJ18nKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoaSA9PT0gJ3ZlcnNpb24nICYmIHR5cGVvZiBvcHRpb25zW2ldICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEVycm9yKCdEYXRhYmFzZSB2ZXJzaW9uIG11c3QgYmUgYSBudW1iZXIuJyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5fY29uZmlnW2ldID0gb3B0aW9uc1tpXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gYWZ0ZXIgYWxsIGNvbmZpZyBvcHRpb25zIGFyZSBzZXQgYW5kXG4gICAgICAgICAgICAvLyB0aGUgZHJpdmVyIG9wdGlvbiBpcyB1c2VkLCB0cnkgc2V0dGluZyBpdFxuICAgICAgICAgICAgaWYgKCdkcml2ZXInIGluIG9wdGlvbnMgJiYgb3B0aW9ucy5kcml2ZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZXREcml2ZXIodGhpcy5fY29uZmlnLmRyaXZlcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbmZpZ1tvcHRpb25zXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jb25maWc7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gVXNlZCB0byBkZWZpbmUgYSBjdXN0b20gZHJpdmVyLCBzaGFyZWQgYWNyb3NzIGFsbCBpbnN0YW5jZXMgb2ZcbiAgICAvLyBsb2NhbEZvcmFnZS5cblxuXG4gICAgTG9jYWxGb3JhZ2UucHJvdG90eXBlLmRlZmluZURyaXZlciA9IGZ1bmN0aW9uIGRlZmluZURyaXZlcihkcml2ZXJPYmplY3QsIGNhbGxiYWNrLCBlcnJvckNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBwcm9taXNlID0gbmV3IFByb21pc2UkMShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHZhciBkcml2ZXJOYW1lID0gZHJpdmVyT2JqZWN0Ll9kcml2ZXI7XG4gICAgICAgICAgICAgICAgdmFyIGNvbXBsaWFuY2VFcnJvciA9IG5ldyBFcnJvcignQ3VzdG9tIGRyaXZlciBub3QgY29tcGxpYW50OyBzZWUgJyArICdodHRwczovL21vemlsbGEuZ2l0aHViLmlvL2xvY2FsRm9yYWdlLyNkZWZpbmVkcml2ZXInKTtcbiAgICAgICAgICAgICAgICB2YXIgbmFtaW5nRXJyb3IgPSBuZXcgRXJyb3IoJ0N1c3RvbSBkcml2ZXIgbmFtZSBhbHJlYWR5IGluIHVzZTogJyArIGRyaXZlck9iamVjdC5fZHJpdmVyKTtcblxuICAgICAgICAgICAgICAgIC8vIEEgZHJpdmVyIG5hbWUgc2hvdWxkIGJlIGRlZmluZWQgYW5kIG5vdCBvdmVybGFwIHdpdGggdGhlXG4gICAgICAgICAgICAgICAgLy8gbGlicmFyeS1kZWZpbmVkLCBkZWZhdWx0IGRyaXZlcnMuXG4gICAgICAgICAgICAgICAgaWYgKCFkcml2ZXJPYmplY3QuX2RyaXZlcikge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoY29tcGxpYW5jZUVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoaXNMaWJyYXJ5RHJpdmVyKGRyaXZlck9iamVjdC5fZHJpdmVyKSkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QobmFtaW5nRXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIGN1c3RvbURyaXZlck1ldGhvZHMgPSBMaWJyYXJ5TWV0aG9kcy5jb25jYXQoJ19pbml0U3RvcmFnZScpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY3VzdG9tRHJpdmVyTWV0aG9kcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgY3VzdG9tRHJpdmVyTWV0aG9kID0gY3VzdG9tRHJpdmVyTWV0aG9kc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjdXN0b21Ecml2ZXJNZXRob2QgfHwgIWRyaXZlck9iamVjdFtjdXN0b21Ecml2ZXJNZXRob2RdIHx8IHR5cGVvZiBkcml2ZXJPYmplY3RbY3VzdG9tRHJpdmVyTWV0aG9kXSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGNvbXBsaWFuY2VFcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB2YXIgc3VwcG9ydFByb21pc2UgPSBQcm9taXNlJDEucmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgICAgICAgICBpZiAoJ19zdXBwb3J0JyBpbiBkcml2ZXJPYmplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRyaXZlck9iamVjdC5fc3VwcG9ydCAmJiB0eXBlb2YgZHJpdmVyT2JqZWN0Ll9zdXBwb3J0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0UHJvbWlzZSA9IGRyaXZlck9iamVjdC5fc3VwcG9ydCgpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3VwcG9ydFByb21pc2UgPSBQcm9taXNlJDEucmVzb2x2ZSghIWRyaXZlck9iamVjdC5fc3VwcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBzdXBwb3J0UHJvbWlzZS50aGVuKGZ1bmN0aW9uIChzdXBwb3J0UmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIGRyaXZlclN1cHBvcnRbZHJpdmVyTmFtZV0gPSBzdXBwb3J0UmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICBDdXN0b21Ecml2ZXJzW2RyaXZlck5hbWVdID0gZHJpdmVyT2JqZWN0O1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGV4ZWN1dGVUd29DYWxsYmFja3MocHJvbWlzZSwgY2FsbGJhY2ssIGVycm9yQ2FsbGJhY2spO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9O1xuXG4gICAgTG9jYWxGb3JhZ2UucHJvdG90eXBlLmRyaXZlciA9IGZ1bmN0aW9uIGRyaXZlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RyaXZlciB8fCBudWxsO1xuICAgIH07XG5cbiAgICBMb2NhbEZvcmFnZS5wcm90b3R5cGUuZ2V0RHJpdmVyID0gZnVuY3Rpb24gZ2V0RHJpdmVyKGRyaXZlck5hbWUsIGNhbGxiYWNrLCBlcnJvckNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdmFyIGdldERyaXZlclByb21pc2UgPSBQcm9taXNlJDEucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKGlzTGlicmFyeURyaXZlcihkcml2ZXJOYW1lKSkge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoZHJpdmVyTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIHNlbGYuSU5ERVhFRERCOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFzeW5jU3RvcmFnZTtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBzZWxmLkxPQ0FMU1RPUkFHRTpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbFN0b3JhZ2VXcmFwcGVyO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIHNlbGYuV0VCU1FMOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdlYlNRTFN0b3JhZ2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChDdXN0b21Ecml2ZXJzW2RyaXZlck5hbWVdKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEN1c3RvbURyaXZlcnNbZHJpdmVyTmFtZV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRHJpdmVyIG5vdCBmb3VuZC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGV4ZWN1dGVUd29DYWxsYmFja3MoZ2V0RHJpdmVyUHJvbWlzZSwgY2FsbGJhY2ssIGVycm9yQ2FsbGJhY2spO1xuICAgICAgICByZXR1cm4gZ2V0RHJpdmVyUHJvbWlzZTtcbiAgICB9O1xuXG4gICAgTG9jYWxGb3JhZ2UucHJvdG90eXBlLmdldFNlcmlhbGl6ZXIgPSBmdW5jdGlvbiBnZXRTZXJpYWxpemVyKGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBzZXJpYWxpemVyUHJvbWlzZSA9IFByb21pc2UkMS5yZXNvbHZlKGxvY2FsZm9yYWdlU2VyaWFsaXplcik7XG4gICAgICAgIGV4ZWN1dGVUd29DYWxsYmFja3Moc2VyaWFsaXplclByb21pc2UsIGNhbGxiYWNrKTtcbiAgICAgICAgcmV0dXJuIHNlcmlhbGl6ZXJQcm9taXNlO1xuICAgIH07XG5cbiAgICBMb2NhbEZvcmFnZS5wcm90b3R5cGUucmVhZHkgPSBmdW5jdGlvbiByZWFkeShjYWxsYmFjaykge1xuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHByb21pc2UgPSBzZWxmLl9kcml2ZXJTZXQudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoc2VsZi5fcmVhZHkgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBzZWxmLl9yZWFkeSA9IHNlbGYuX2luaXREcml2ZXIoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHNlbGYuX3JlYWR5O1xuICAgICAgICB9KTtcblxuICAgICAgICBleGVjdXRlVHdvQ2FsbGJhY2tzKHByb21pc2UsIGNhbGxiYWNrLCBjYWxsYmFjayk7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH07XG5cbiAgICBMb2NhbEZvcmFnZS5wcm90b3R5cGUuc2V0RHJpdmVyID0gZnVuY3Rpb24gc2V0RHJpdmVyKGRyaXZlcnMsIGNhbGxiYWNrLCBlcnJvckNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgICAgICBpZiAoIWlzQXJyYXkoZHJpdmVycykpIHtcbiAgICAgICAgICAgIGRyaXZlcnMgPSBbZHJpdmVyc107XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgc3VwcG9ydGVkRHJpdmVycyA9IHRoaXMuX2dldFN1cHBvcnRlZERyaXZlcnMoZHJpdmVycyk7XG5cbiAgICAgICAgZnVuY3Rpb24gc2V0RHJpdmVyVG9Db25maWcoKSB7XG4gICAgICAgICAgICBzZWxmLl9jb25maWcuZHJpdmVyID0gc2VsZi5kcml2ZXIoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGV4dGVuZFNlbGZXaXRoRHJpdmVyKGRyaXZlcikge1xuICAgICAgICAgICAgc2VsZi5fZXh0ZW5kKGRyaXZlcik7XG4gICAgICAgICAgICBzZXREcml2ZXJUb0NvbmZpZygpO1xuXG4gICAgICAgICAgICBzZWxmLl9yZWFkeSA9IHNlbGYuX2luaXRTdG9yYWdlKHNlbGYuX2NvbmZpZyk7XG4gICAgICAgICAgICByZXR1cm4gc2VsZi5fcmVhZHk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBpbml0RHJpdmVyKHN1cHBvcnRlZERyaXZlcnMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnJlbnREcml2ZXJJbmRleCA9IDA7XG5cbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBkcml2ZXJQcm9taXNlTG9vcCgpIHtcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGN1cnJlbnREcml2ZXJJbmRleCA8IHN1cHBvcnRlZERyaXZlcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZHJpdmVyTmFtZSA9IHN1cHBvcnRlZERyaXZlcnNbY3VycmVudERyaXZlckluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnREcml2ZXJJbmRleCsrO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9kYkluZm8gPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fcmVhZHkgPSBudWxsO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5nZXREcml2ZXIoZHJpdmVyTmFtZSkudGhlbihleHRlbmRTZWxmV2l0aERyaXZlcilbXCJjYXRjaFwiXShkcml2ZXJQcm9taXNlTG9vcCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBzZXREcml2ZXJUb0NvbmZpZygpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ05vIGF2YWlsYWJsZSBzdG9yYWdlIG1ldGhvZCBmb3VuZC4nKTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZHJpdmVyU2V0ID0gUHJvbWlzZSQxLnJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLl9kcml2ZXJTZXQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGRyaXZlclByb21pc2VMb29wKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGhlcmUgbWlnaHQgYmUgYSBkcml2ZXIgaW5pdGlhbGl6YXRpb24gaW4gcHJvZ3Jlc3NcbiAgICAgICAgLy8gc28gd2FpdCBmb3IgaXQgdG8gZmluaXNoIGluIG9yZGVyIHRvIGF2b2lkIGEgcG9zc2libGVcbiAgICAgICAgLy8gcmFjZSBjb25kaXRpb24gdG8gc2V0IF9kYkluZm9cbiAgICAgICAgdmFyIG9sZERyaXZlclNldERvbmUgPSB0aGlzLl9kcml2ZXJTZXQgIT09IG51bGwgPyB0aGlzLl9kcml2ZXJTZXRbXCJjYXRjaFwiXShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZSQxLnJlc29sdmUoKTtcbiAgICAgICAgfSkgOiBQcm9taXNlJDEucmVzb2x2ZSgpO1xuXG4gICAgICAgIHRoaXMuX2RyaXZlclNldCA9IG9sZERyaXZlclNldERvbmUudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgZHJpdmVyTmFtZSA9IHN1cHBvcnRlZERyaXZlcnNbMF07XG4gICAgICAgICAgICBzZWxmLl9kYkluZm8gPSBudWxsO1xuICAgICAgICAgICAgc2VsZi5fcmVhZHkgPSBudWxsO1xuXG4gICAgICAgICAgICByZXR1cm4gc2VsZi5nZXREcml2ZXIoZHJpdmVyTmFtZSkudGhlbihmdW5jdGlvbiAoZHJpdmVyKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5fZHJpdmVyID0gZHJpdmVyLl9kcml2ZXI7XG4gICAgICAgICAgICAgICAgc2V0RHJpdmVyVG9Db25maWcoKTtcbiAgICAgICAgICAgICAgICBzZWxmLl93cmFwTGlicmFyeU1ldGhvZHNXaXRoUmVhZHkoKTtcbiAgICAgICAgICAgICAgICBzZWxmLl9pbml0RHJpdmVyID0gaW5pdERyaXZlcihzdXBwb3J0ZWREcml2ZXJzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVtcImNhdGNoXCJdKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNldERyaXZlclRvQ29uZmlnKCk7XG4gICAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ05vIGF2YWlsYWJsZSBzdG9yYWdlIG1ldGhvZCBmb3VuZC4nKTtcbiAgICAgICAgICAgIHNlbGYuX2RyaXZlclNldCA9IFByb21pc2UkMS5yZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuIHNlbGYuX2RyaXZlclNldDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZXhlY3V0ZVR3b0NhbGxiYWNrcyh0aGlzLl9kcml2ZXJTZXQsIGNhbGxiYWNrLCBlcnJvckNhbGxiYWNrKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RyaXZlclNldDtcbiAgICB9O1xuXG4gICAgTG9jYWxGb3JhZ2UucHJvdG90eXBlLnN1cHBvcnRzID0gZnVuY3Rpb24gc3VwcG9ydHMoZHJpdmVyTmFtZSkge1xuICAgICAgICByZXR1cm4gISFkcml2ZXJTdXBwb3J0W2RyaXZlck5hbWVdO1xuICAgIH07XG5cbiAgICBMb2NhbEZvcmFnZS5wcm90b3R5cGUuX2V4dGVuZCA9IGZ1bmN0aW9uIF9leHRlbmQobGlicmFyeU1ldGhvZHNBbmRQcm9wZXJ0aWVzKSB7XG4gICAgICAgIGV4dGVuZCh0aGlzLCBsaWJyYXJ5TWV0aG9kc0FuZFByb3BlcnRpZXMpO1xuICAgIH07XG5cbiAgICBMb2NhbEZvcmFnZS5wcm90b3R5cGUuX2dldFN1cHBvcnRlZERyaXZlcnMgPSBmdW5jdGlvbiBfZ2V0U3VwcG9ydGVkRHJpdmVycyhkcml2ZXJzKSB7XG4gICAgICAgIHZhciBzdXBwb3J0ZWREcml2ZXJzID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBkcml2ZXJzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgZHJpdmVyTmFtZSA9IGRyaXZlcnNbaV07XG4gICAgICAgICAgICBpZiAodGhpcy5zdXBwb3J0cyhkcml2ZXJOYW1lKSkge1xuICAgICAgICAgICAgICAgIHN1cHBvcnRlZERyaXZlcnMucHVzaChkcml2ZXJOYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3VwcG9ydGVkRHJpdmVycztcbiAgICB9O1xuXG4gICAgTG9jYWxGb3JhZ2UucHJvdG90eXBlLl93cmFwTGlicmFyeU1ldGhvZHNXaXRoUmVhZHkgPSBmdW5jdGlvbiBfd3JhcExpYnJhcnlNZXRob2RzV2l0aFJlYWR5KCkge1xuICAgICAgICAvLyBBZGQgYSBzdHViIGZvciBlYWNoIGRyaXZlciBBUEkgbWV0aG9kIHRoYXQgZGVsYXlzIHRoZSBjYWxsIHRvIHRoZVxuICAgICAgICAvLyBjb3JyZXNwb25kaW5nIGRyaXZlciBtZXRob2QgdW50aWwgbG9jYWxGb3JhZ2UgaXMgcmVhZHkuIFRoZXNlIHN0dWJzXG4gICAgICAgIC8vIHdpbGwgYmUgcmVwbGFjZWQgYnkgdGhlIGRyaXZlciBtZXRob2RzIGFzIHNvb24gYXMgdGhlIGRyaXZlciBpc1xuICAgICAgICAvLyBsb2FkZWQsIHNvIHRoZXJlIGlzIG5vIHBlcmZvcm1hbmNlIGltcGFjdC5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBMaWJyYXJ5TWV0aG9kcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY2FsbFdoZW5SZWFkeSh0aGlzLCBMaWJyYXJ5TWV0aG9kc1tpXSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgTG9jYWxGb3JhZ2UucHJvdG90eXBlLmNyZWF0ZUluc3RhbmNlID0gZnVuY3Rpb24gY3JlYXRlSW5zdGFuY2Uob3B0aW9ucykge1xuICAgICAgICByZXR1cm4gbmV3IExvY2FsRm9yYWdlKG9wdGlvbnMpO1xuICAgIH07XG5cbiAgICByZXR1cm4gTG9jYWxGb3JhZ2U7XG59KCk7XG5cbi8vIFRoZSBhY3R1YWwgbG9jYWxGb3JhZ2Ugb2JqZWN0IHRoYXQgd2UgZXhwb3NlIGFzIGEgbW9kdWxlIG9yIHZpYSBhXG4vLyBnbG9iYWwuIEl0J3MgZXh0ZW5kZWQgYnkgcHVsbGluZyBpbiBvbmUgb2Ygb3VyIG90aGVyIGxpYnJhcmllcy5cblxuXG52YXIgbG9jYWxmb3JhZ2VfanMgPSBuZXcgTG9jYWxGb3JhZ2UoKTtcblxubW9kdWxlLmV4cG9ydHMgPSBsb2NhbGZvcmFnZV9qcztcblxufSx7XCIzXCI6M31dfSx7fSxbNF0pKDQpXG59KTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliL3R5cGUnKTtcbiIsIi8qIVxuICogdHlwZS1kZXRlY3RcbiAqIENvcHlyaWdodChjKSAyMDEzIGpha2UgbHVlciA8amFrZUBhbG9naWNhbHBhcmFkb3guY29tPlxuICogTUlUIExpY2Vuc2VkXG4gKi9cblxuLyohXG4gKiBQcmltYXJ5IEV4cG9ydHNcbiAqL1xuXG52YXIgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZ2V0VHlwZTtcblxuLyohXG4gKiBEZXRlY3RhYmxlIGphdmFzY3JpcHQgbmF0aXZlc1xuICovXG5cbnZhciBuYXRpdmVzID0ge1xuICAgICdbb2JqZWN0IEFycmF5XSc6ICdhcnJheSdcbiAgLCAnW29iamVjdCBSZWdFeHBdJzogJ3JlZ2V4cCdcbiAgLCAnW29iamVjdCBGdW5jdGlvbl0nOiAnZnVuY3Rpb24nXG4gICwgJ1tvYmplY3QgQXJndW1lbnRzXSc6ICdhcmd1bWVudHMnXG4gICwgJ1tvYmplY3QgRGF0ZV0nOiAnZGF0ZSdcbn07XG5cbi8qKlxuICogIyMjIHR5cGVPZiAob2JqKVxuICpcbiAqIFVzZSBzZXZlcmFsIGRpZmZlcmVudCB0ZWNobmlxdWVzIHRvIGRldGVybWluZVxuICogdGhlIHR5cGUgb2Ygb2JqZWN0IGJlaW5nIHRlc3RlZC5cbiAqXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gKiBAcmV0dXJuIHtTdHJpbmd9IG9iamVjdCB0eXBlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGdldFR5cGUgKG9iaikge1xuICB2YXIgc3RyID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaik7XG4gIGlmIChuYXRpdmVzW3N0cl0pIHJldHVybiBuYXRpdmVzW3N0cl07XG4gIGlmIChvYmogPT09IG51bGwpIHJldHVybiAnbnVsbCc7XG4gIGlmIChvYmogPT09IHVuZGVmaW5lZCkgcmV0dXJuICd1bmRlZmluZWQnO1xuICBpZiAob2JqID09PSBPYmplY3Qob2JqKSkgcmV0dXJuICdvYmplY3QnO1xuICByZXR1cm4gdHlwZW9mIG9iajtcbn1cblxuZXhwb3J0cy5MaWJyYXJ5ID0gTGlicmFyeTtcblxuLyoqXG4gKiAjIyMgTGlicmFyeVxuICpcbiAqIENyZWF0ZSBhIHJlcG9zaXRvcnkgZm9yIGN1c3RvbSB0eXBlIGRldGVjdGlvbi5cbiAqXG4gKiBgYGBqc1xuICogdmFyIGxpYiA9IG5ldyB0eXBlLkxpYnJhcnk7XG4gKiBgYGBcbiAqXG4gKi9cblxuZnVuY3Rpb24gTGlicmFyeSAoKSB7XG4gIHRoaXMudGVzdHMgPSB7fTtcbn1cblxuLyoqXG4gKiAjIyMjIC5vZiAob2JqKVxuICpcbiAqIEV4cG9zZSByZXBsYWNlbWVudCBgdHlwZW9mYCBkZXRlY3Rpb24gdG8gdGhlIGxpYnJhcnkuXG4gKlxuICogYGBganNcbiAqIGlmICgnc3RyaW5nJyA9PT0gbGliLm9mKCdoZWxsbyB3b3JsZCcpKSB7XG4gKiAgIC8vIC4uLlxuICogfVxuICogYGBgXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0IHRvIHRlc3RcbiAqIEByZXR1cm4ge1N0cmluZ30gdHlwZVxuICovXG5cbkxpYnJhcnkucHJvdG90eXBlLm9mID0gZ2V0VHlwZTtcblxuLyoqXG4gKiAjIyMjIC5kZWZpbmUgKHR5cGUsIHRlc3QpXG4gKlxuICogQWRkIGEgdGVzdCB0byBmb3IgdGhlIGAudGVzdCgpYCBhc3NlcnRpb24uXG4gKlxuICogQ2FuIGJlIGRlZmluZWQgYXMgYSByZWd1bGFyIGV4cHJlc3Npb246XG4gKlxuICogYGBganNcbiAqIGxpYi5kZWZpbmUoJ2ludCcsIC9eWzAtOV0rJC8pO1xuICogYGBgXG4gKlxuICogLi4uIG9yIGFzIGEgZnVuY3Rpb246XG4gKlxuICogYGBganNcbiAqIGxpYi5kZWZpbmUoJ2JsbicsIGZ1bmN0aW9uIChvYmopIHtcbiAqICAgaWYgKCdib29sZWFuJyA9PT0gbGliLm9mKG9iaikpIHJldHVybiB0cnVlO1xuICogICB2YXIgYmxucyA9IFsgJ3llcycsICdubycsICd0cnVlJywgJ2ZhbHNlJywgMSwgMCBdO1xuICogICBpZiAoJ3N0cmluZycgPT09IGxpYi5vZihvYmopKSBvYmogPSBvYmoudG9Mb3dlckNhc2UoKTtcbiAqICAgcmV0dXJuICEhIH5ibG5zLmluZGV4T2Yob2JqKTtcbiAqIH0pO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7UmVnRXhwfEZ1bmN0aW9ufSB0ZXN0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkxpYnJhcnkucHJvdG90eXBlLmRlZmluZSA9IGZ1bmN0aW9uICh0eXBlLCB0ZXN0KSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSByZXR1cm4gdGhpcy50ZXN0c1t0eXBlXTtcbiAgdGhpcy50ZXN0c1t0eXBlXSA9IHRlc3Q7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiAjIyMjIC50ZXN0IChvYmosIHRlc3QpXG4gKlxuICogQXNzZXJ0IHRoYXQgYW4gb2JqZWN0IGlzIG9mIHR5cGUuIFdpbGwgZmlyc3RcbiAqIGNoZWNrIG5hdGl2ZXMsIGFuZCBpZiB0aGF0IGRvZXMgbm90IHBhc3MgaXQgd2lsbFxuICogdXNlIHRoZSB1c2VyIGRlZmluZWQgY3VzdG9tIHRlc3RzLlxuICpcbiAqIGBgYGpzXG4gKiBhc3NlcnQobGliLnRlc3QoJzEnLCAnaW50JykpO1xuICogYXNzZXJ0KGxpYi50ZXN0KCd5ZXMnLCAnYmxuJykpO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICogQHJldHVybiB7Qm9vbGVhbn0gcmVzdWx0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkxpYnJhcnkucHJvdG90eXBlLnRlc3QgPSBmdW5jdGlvbiAob2JqLCB0eXBlKSB7XG4gIGlmICh0eXBlID09PSBnZXRUeXBlKG9iaikpIHJldHVybiB0cnVlO1xuICB2YXIgdGVzdCA9IHRoaXMudGVzdHNbdHlwZV07XG5cbiAgaWYgKHRlc3QgJiYgJ3JlZ2V4cCcgPT09IGdldFR5cGUodGVzdCkpIHtcbiAgICByZXR1cm4gdGVzdC50ZXN0KG9iaik7XG4gIH0gZWxzZSBpZiAodGVzdCAmJiAnZnVuY3Rpb24nID09PSBnZXRUeXBlKHRlc3QpKSB7XG4gICAgcmV0dXJuIHRlc3Qob2JqKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoJ1R5cGUgdGVzdCBcIicgKyB0eXBlICsgJ1wiIG5vdCBkZWZpbmVkIG9yIGludmFsaWQuJyk7XG4gIH1cbn07XG4iLCIvKiFcbiAqIHR5cGUtZGV0ZWN0XG4gKiBDb3B5cmlnaHQoYykgMjAxMyBqYWtlIGx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cbiAqIE1JVCBMaWNlbnNlZFxuICovXG5cbi8qIVxuICogUHJpbWFyeSBFeHBvcnRzXG4gKi9cblxudmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGdldFR5cGU7XG5cbi8qKlxuICogIyMjIHR5cGVPZiAob2JqKVxuICpcbiAqIFVzZSBzZXZlcmFsIGRpZmZlcmVudCB0ZWNobmlxdWVzIHRvIGRldGVybWluZVxuICogdGhlIHR5cGUgb2Ygb2JqZWN0IGJlaW5nIHRlc3RlZC5cbiAqXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0XG4gKiBAcmV0dXJuIHtTdHJpbmd9IG9iamVjdCB0eXBlXG4gKiBAYXBpIHB1YmxpY1xuICovXG52YXIgb2JqZWN0VHlwZVJlZ2V4cCA9IC9eXFxbb2JqZWN0ICguKilcXF0kLztcblxuZnVuY3Rpb24gZ2V0VHlwZShvYmopIHtcbiAgdmFyIHR5cGUgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKS5tYXRjaChvYmplY3RUeXBlUmVnZXhwKVsxXS50b0xvd2VyQ2FzZSgpO1xuICAvLyBMZXQgXCJuZXcgU3RyaW5nKCcnKVwiIHJldHVybiAnb2JqZWN0J1xuICBpZiAodHlwZW9mIFByb21pc2UgPT09ICdmdW5jdGlvbicgJiYgb2JqIGluc3RhbmNlb2YgUHJvbWlzZSkgcmV0dXJuICdwcm9taXNlJztcbiAgLy8gUGhhbnRvbUpTIGhhcyB0eXBlIFwiRE9NV2luZG93XCIgZm9yIG51bGxcbiAgaWYgKG9iaiA9PT0gbnVsbCkgcmV0dXJuICdudWxsJztcbiAgLy8gUGhhbnRvbUpTIGhhcyB0eXBlIFwiRE9NV2luZG93XCIgZm9yIHVuZGVmaW5lZFxuICBpZiAob2JqID09PSB1bmRlZmluZWQpIHJldHVybiAndW5kZWZpbmVkJztcbiAgcmV0dXJuIHR5cGU7XG59XG5cbmV4cG9ydHMuTGlicmFyeSA9IExpYnJhcnk7XG5cbi8qKlxuICogIyMjIExpYnJhcnlcbiAqXG4gKiBDcmVhdGUgYSByZXBvc2l0b3J5IGZvciBjdXN0b20gdHlwZSBkZXRlY3Rpb24uXG4gKlxuICogYGBganNcbiAqIHZhciBsaWIgPSBuZXcgdHlwZS5MaWJyYXJ5O1xuICogYGBgXG4gKlxuICovXG5cbmZ1bmN0aW9uIExpYnJhcnkoKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBMaWJyYXJ5KSkgcmV0dXJuIG5ldyBMaWJyYXJ5KCk7XG4gIHRoaXMudGVzdHMgPSB7fTtcbn1cblxuLyoqXG4gKiAjIyMjIC5vZiAob2JqKVxuICpcbiAqIEV4cG9zZSByZXBsYWNlbWVudCBgdHlwZW9mYCBkZXRlY3Rpb24gdG8gdGhlIGxpYnJhcnkuXG4gKlxuICogYGBganNcbiAqIGlmICgnc3RyaW5nJyA9PT0gbGliLm9mKCdoZWxsbyB3b3JsZCcpKSB7XG4gKiAgIC8vIC4uLlxuICogfVxuICogYGBgXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gb2JqZWN0IHRvIHRlc3RcbiAqIEByZXR1cm4ge1N0cmluZ30gdHlwZVxuICovXG5cbkxpYnJhcnkucHJvdG90eXBlLm9mID0gZ2V0VHlwZTtcblxuLyoqXG4gKiAjIyMjIC5kZWZpbmUgKHR5cGUsIHRlc3QpXG4gKlxuICogQWRkIGEgdGVzdCB0byBmb3IgdGhlIGAudGVzdCgpYCBhc3NlcnRpb24uXG4gKlxuICogQ2FuIGJlIGRlZmluZWQgYXMgYSByZWd1bGFyIGV4cHJlc3Npb246XG4gKlxuICogYGBganNcbiAqIGxpYi5kZWZpbmUoJ2ludCcsIC9eWzAtOV0rJC8pO1xuICogYGBgXG4gKlxuICogLi4uIG9yIGFzIGEgZnVuY3Rpb246XG4gKlxuICogYGBganNcbiAqIGxpYi5kZWZpbmUoJ2JsbicsIGZ1bmN0aW9uIChvYmopIHtcbiAqICAgaWYgKCdib29sZWFuJyA9PT0gbGliLm9mKG9iaikpIHJldHVybiB0cnVlO1xuICogICB2YXIgYmxucyA9IFsgJ3llcycsICdubycsICd0cnVlJywgJ2ZhbHNlJywgMSwgMCBdO1xuICogICBpZiAoJ3N0cmluZycgPT09IGxpYi5vZihvYmopKSBvYmogPSBvYmoudG9Mb3dlckNhc2UoKTtcbiAqICAgcmV0dXJuICEhIH5ibG5zLmluZGV4T2Yob2JqKTtcbiAqIH0pO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7UmVnRXhwfEZ1bmN0aW9ufSB0ZXN0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkxpYnJhcnkucHJvdG90eXBlLmRlZmluZSA9IGZ1bmN0aW9uKHR5cGUsIHRlc3QpIHtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHJldHVybiB0aGlzLnRlc3RzW3R5cGVdO1xuICB0aGlzLnRlc3RzW3R5cGVdID0gdGVzdDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqICMjIyMgLnRlc3QgKG9iaiwgdGVzdClcbiAqXG4gKiBBc3NlcnQgdGhhdCBhbiBvYmplY3QgaXMgb2YgdHlwZS4gV2lsbCBmaXJzdFxuICogY2hlY2sgbmF0aXZlcywgYW5kIGlmIHRoYXQgZG9lcyBub3QgcGFzcyBpdCB3aWxsXG4gKiB1c2UgdGhlIHVzZXIgZGVmaW5lZCBjdXN0b20gdGVzdHMuXG4gKlxuICogYGBganNcbiAqIGFzc2VydChsaWIudGVzdCgnMScsICdpbnQnKSk7XG4gKiBhc3NlcnQobGliLnRlc3QoJ3llcycsICdibG4nKSk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge01peGVkfSBvYmplY3RcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcmV0dXJuIHtCb29sZWFufSByZXN1bHRcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuTGlicmFyeS5wcm90b3R5cGUudGVzdCA9IGZ1bmN0aW9uKG9iaiwgdHlwZSkge1xuICBpZiAodHlwZSA9PT0gZ2V0VHlwZShvYmopKSByZXR1cm4gdHJ1ZTtcbiAgdmFyIHRlc3QgPSB0aGlzLnRlc3RzW3R5cGVdO1xuXG4gIGlmICh0ZXN0ICYmICdyZWdleHAnID09PSBnZXRUeXBlKHRlc3QpKSB7XG4gICAgcmV0dXJuIHRlc3QudGVzdChvYmopO1xuICB9IGVsc2UgaWYgKHRlc3QgJiYgJ2Z1bmN0aW9uJyA9PT0gZ2V0VHlwZSh0ZXN0KSkge1xuICAgIHJldHVybiB0ZXN0KG9iaik7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKCdUeXBlIHRlc3QgXCInICsgdHlwZSArICdcIiBub3QgZGVmaW5lZCBvciBpbnZhbGlkLicpO1xuICB9XG59O1xuIiwiKGZ1bmN0aW9uIChkb2N1bWVudCwgd2luZG93KSB7XG4gIC8vIERFUEVOREVOQ0lFU1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBjb25zdCBsb2NhbGZvcmFnZSA9IHJlcXVpcmUoJ2xvY2FsZm9yYWdlJyk7XG4gIGNvbnN0IHByb2JzID0gcmVxdWlyZSgncGpzLXByb2JsZW1zJyk7XG4gIGNvbnN0IGRlZGVudCA9IHJlcXVpcmUoJ2RlZGVudCcpO1xuICBjb25zdCBhc3NlcnQgPSByZXF1aXJlKCdjaGFpJykuYXNzZXJ0O1xuXG4gIC8vIFBST0JMRU0gVEVNUExBVEUgTklDRS1JRklDQVRJT05cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgZnVuY3Rpb24gZGVkZW50U3RyaW5ncyhwcm9ibGVtcykge1xuICAgIHJldHVybiBwcm9ibGVtcy5tYXAocHJvYiA9PiB7XG4gICAgICBwcm9iLmdpdmVuID0gZGVkZW50KHByb2IuZ2l2ZW4pXG4gICAgICBwcm9iLmFuc3dlciA9IGRlZGVudChwcm9iLmFuc3dlcilcbiAgICAgIHJldHVybiBwcm9iXG4gICAgfSk7XG4gIH1cblxuXG4gIC8vIFBST0JMRU1TXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGxldCBwcm9ibGVtcyA9IFtdO1xuICBPYmplY3Qua2V5cyhwcm9icykuZm9yRWFjaChzdWJqZWN0ID0+IHtcbiAgICBwcm9ibGVtcy5wdXNoKC4uLnByb2JzW3N1YmplY3RdKTtcbiAgfSk7XG4gIHByb2JsZW1zID0gZGVkZW50U3RyaW5ncyhwcm9ibGVtcylcbiAgY29uc29sZS5sb2coJ3Byb2JsZW1zOicsIHByb2JsZW1zKTtcblxuXG5cbiAgLy8gQ09ORklHXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIC8vIEhvaXN0IGN1cnJlbnQgcHJvYmxlbVxuICBsZXQgY3VycmVudFByb2JsZW07XG4gIC8vIEtleXMgdG8gaWdub3JlIHdoaWxlIHVzZXIgaXMgbmF2aWdhdGluZyBhcm91bmQgdGhlIHRleHRhcmVhIGJ1dCBub3QgY2hhbmdpbmcgYW55IGNvZGVcbiAgY29uc3QgaWdub3JlS2V5Q29kZXMgPSBbXG4gICAgOSwgLy8gVGFiXG4gICAgMzcsIC8vIExlZnQgYXJyb3dcbiAgICAzOSwgLy8gUmlnaHQgYXJyb3dcbiAgICAzOCwgLy8gVXAgYXJyb3dcbiAgICA0MCAvLyBEb3duIGFycm93XG4gIF07XG5cbiAgbGV0IGNvbmZpZyA9IHtcbiAgICBzaHVmZmxlOiB0cnVlLFxuICAgIHRpbWVyOiBmYWxzZSxcbiAgICBjdXJyZW50SW5kZXg6IDBcbiAgfTtcblxuICAvLyBQdWxsIGNvbmZpZyBmcm9tIGxvY2FsZm9yYWdlXG4gIGxvY2FsZm9yYWdlXG4gICAgLmdldEl0ZW0oJ2pzX3ByYWN0aWNlX2NvbmZpZycpXG4gICAgLnRoZW4odmFsID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKCdsb2NhbGZvcmFnZSB2YWw6JywgdmFsKTtcbiAgICAgIGlmICh2YWwpIHtcbiAgICAgICAgY29uZmlnID0gdmFsO1xuICAgICAgfVxuICAgICAgbG9hZEFwcChjb25maWcpO1xuICAgIH0pXG4gICAgLmNhdGNoKGVyciA9PiB7XG4gICAgICBjb25zb2xlLmxvZygnbG9jYWxmb3JhZ2UgZXJyOicsIGVycik7XG4gICAgICBsb2FkQXBwKGNvbmZpZyk7XG4gICAgfSk7XG5cbiAgZnVuY3Rpb24gdXBkYXRlTG9jYWxzdG9yZShjb25maWcpIHtcbiAgICByZXR1cm4gbG9jYWxmb3JhZ2VcbiAgICAgIC5zZXRJdGVtKCdqc19wcmFjdGljZV9jb25maWcnLCBjb25maWcpXG4gICAgICAudGhlbih2YWwgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnU2V0dGluZ3MgdXBkYXRlZDonLCB2YWwpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnU2V0dGluZ3MgdXBkYXRlIGVycm9yOicsIGVycik7XG4gICAgICB9KTtcbiAgfVxuXG5cbiAgLy8gVUlcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgLy8gZWxlbWVudHNcbiAgY29uc3QgcHJvYmxlbUVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Byb2JsZW0nKTtcbiAgY29uc3QgY29kZUVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NvZGUnKTtcbiAgY29uc3QgdGVzdFN1aXRlRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGVzdC1zdWl0ZScpO1xuICBjb25zdCB0ZXN0VG90YWxFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0ZXN0LXRvdGFsJyk7XG4gIGNvbnN0IGV2YWxDb25zb2xlRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZXZhbC1vdXRwdXQnKTtcbiAgY29uc3QgYXNzZXJ0Q29uc29sZUVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Fzc2VydC1vdXRwdXQnKTtcbiAgY29uc3Qgc2h1ZmZsZVByb2JsZW1zQnV0dG9uRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2h1ZmZsZS1wcm9ibGVtcycpO1xuICBjb25zdCBwcmV2aW91c1Byb2JsZW1CdXR0b25FbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwcmV2LXByb2JsZW0nKTtcbiAgY29uc3QgbmV4dFByb2JsZW1CdXR0b25FbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCduZXh0LXByb2JsZW0nKTtcblxuICAvLyBHZXQgaW5kZXhlc1xuICBmdW5jdGlvbiBnZXRSYW5kb21JbmRleChwcm9ibGVtc0Fycikge1xuICAgIGNvbnN0IGluZCA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHByb2JsZW1zQXJyLmxlbmd0aCk7XG4gICAgY29uZmlnLmN1cnJlbnRJbmRleCA9IGluZDtcbiAgICB1cGRhdGVMb2NhbHN0b3JlKGNvbmZpZyk7XG4gICAgcmV0dXJuIGluZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFByZXZpb3VzSW5kZXgocHJvYmxlbXNBcnIpIHtcbiAgICBsZXQgcHJvYkluZDtcbiAgICBjb25zdCBjdXJyZW50SW5kZXggPSBjb25maWcuY3VycmVudEluZGV4O1xuICAgIC8vIElmIGF0IGJlZ2lubmluZywgZ28gdG8gZW5kXG4gICAgaWYgKGN1cnJlbnRJbmRleCA9PT0gMCkge1xuICAgICAgcHJvYkluZCA9IHByb2JsZW1zQXJyLmxlbmd0aCAtIDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHByb2JJbmQgPSBjdXJyZW50SW5kZXggLSAxO1xuICAgIH1cbiAgICByZXR1cm4gcHJvYkluZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldE5leHRJbmRleChwcm9ibGVtc0Fycikge1xuICAgIGxldCBwcm9iSW5kO1xuICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IGNvbmZpZy5jdXJyZW50SW5kZXg7XG4gICAgLy8gSWYgYXQgZW5kIG9yIGludmFsaWQsIHJlc3RhcnQgc2VyaWVzXG4gICAgaWYgKGN1cnJlbnRJbmRleCA+PSBwcm9ibGVtc0Fyci5sZW5ndGggLSAxIHx8IGN1cnJlbnRJbmRleCA8IDApIHtcbiAgICAgIHByb2JJbmQgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm9iSW5kID0gY3VycmVudEluZGV4ICsgMTtcbiAgICB9XG4gICAgcmV0dXJuIHByb2JJbmQ7XG4gIH1cblxuICAvLyBHZXQgcHJvYmxlbXNcbiAgZnVuY3Rpb24gZ2V0Q3VycmVudFByb2JsZW0ocHJvYmxlbXNBcnIpIHtcbiAgICByZXR1cm4gcHJvYmxlbXNBcnJbY29uZmlnLmN1cnJlbnRJbmRleF07XG4gIH1cblxuICBmdW5jdGlvbiBwcmV2aW91c1Byb2JsZW0oKSB7XG4gICAgY29uc29sZS5sb2coJ3ByZXZpb3VzUHJvYmxlbSEnKTtcbiAgICBjb25maWcuY3VycmVudEluZGV4ID0gY29uZmlnLnNodWZmbGVcbiAgICAgID8gZ2V0UmFuZG9tSW5kZXgocHJvYmxlbXMpXG4gICAgICA6IGdldFByZXZpb3VzSW5kZXgocHJvYmxlbXMpO1xuICAgIHVwZGF0ZUxvY2Fsc3RvcmUoY29uZmlnKS50aGVuKCgpID0+IHtcbiAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG5leHRQcm9ibGVtKCkge1xuICAgIGNvbnNvbGUubG9nKCduZXh0UHJvYmxlbSEnKTtcbiAgICBjb25maWcuY3VycmVudEluZGV4ID0gY29uZmlnLnNodWZmbGVcbiAgICAgID8gZ2V0UmFuZG9tSW5kZXgocHJvYmxlbXMpXG4gICAgICA6IGdldE5leHRJbmRleChwcm9ibGVtcyk7XG4gICAgdXBkYXRlTG9jYWxzdG9yZShjb25maWcpLnRoZW4oKCkgPT4ge1xuICAgICAgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gdG9nZ2xlU2h1ZmZsZSgpIHtcbiAgICBjb25zb2xlLmxvZygndG9nZ2xlIHNodWZmbGUhJyk7XG4gICAgY29uZmlnLnNodWZmbGUgPSAhY29uZmlnLnNodWZmbGU7IC8vIEZsaXAgaXRcbiAgICBzaHVmZmxlUHJvYmxlbXNCdXR0b25FbC5jbGFzc0xpc3QudG9nZ2xlKCdhY3RpdmUnKTtcbiAgICB1cGRhdGVMb2NhbHN0b3JlKGNvbmZpZyk7XG4gIH1cblxuICBmdW5jdGlvbiBsb2FkUHJvYmxlbShwcm9ibGVtT2JqKSB7XG4gICAgY3VycmVudFByb2JsZW0gPSBwcm9ibGVtT2JqO1xuICAgIC8vIFByb2IgcXVlc3Rpb25cbiAgICBwcm9ibGVtRWwuaW5uZXJUZXh0ID0gcHJvYmxlbU9iai5wcm9tcHQ7XG4gICAgLy8gUHJvYiBnaXZlbiBjb2RlXG4gICAgaWYgKHByb2JsZW1PYmouZ2l2ZW4pIHtcbiAgICAgIGNvZGVFbC52YWx1ZSA9IHByb2JsZW1PYmouZ2l2ZW47XG4gICAgfVxuICAgIC8vIFNlZWQgdGhlIHRlc3RzLCBwYXNzIChpbml0ID0gdHJ1ZSkgYXMgc2Vjb25kIHBhcmFtXG4gICAgdGVzdFN1aXRlKG51bGwsIHRydWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlVGVzdHModGVzdFN0YXR1cywgaW5pdCkge1xuICAgIGlmIChpbml0ID09PSB0cnVlKSB7XG4gICAgICBidWlsZFRlc3RzKGN1cnJlbnRQcm9ibGVtLnRlc3RzKTtcbiAgICB9XG4gICAgdXBkYXRlVGVzdFN0YXR1cyh0ZXN0U3RhdHVzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1aWxkVGVzdHModGVzdHMpIHtcbiAgICBpZiAodGVzdHMpIHtcbiAgICAgIGNvbnN0IHRlc3RzRG9tID0gdGVzdHNcbiAgICAgICAgLm1hcCh0ZXN0ID0+IHtcbiAgICAgICAgICByZXR1cm4gYDxkaXYgY2xhc3M9XCJ0ZXN0IG1vbm9zcGFjZVwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRlc3Qtc3RhdGVcIj5bJiN4MjcxODtdPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGVzdC1uYW1lXCI+JHt0ZXN0Lm5hbWV9PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+YDtcbiAgICAgICAgfSlcbiAgICAgICAgLmpvaW4oJycpO1xuICAgICAgdGVzdFN1aXRlRWwuaW5uZXJIVE1MID0gdGVzdHNEb207XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlVGVzdFN0YXR1cyh0ZXN0U3RhdHVzZXMpIHtcbiAgICBpZiAoIXRlc3RTdGF0dXNlcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyB0ZXN0U3RhdHVzZXMgcHJvdmlkZWQuJyk7XG4gICAgfVxuICAgIC8vIEZpbmQgb3V0IGlmIGFsbCB0ZXN0cyBoYXZlIHBhc3NlZCBvciBub3RcbiAgICBsZXQgYWxsUGFzc2VkID0gdHJ1ZTtcbiAgICB0ZXN0U3RhdHVzZXMuZm9yRWFjaCh0ZXN0UGFzc2VkID0+IHtcbiAgICAgIGlmICh0ZXN0UGFzc2VkICE9PSB0cnVlKSB7XG4gICAgICAgIGFsbFBhc3NlZCA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbnN0IHRlc3RFbHMgPSBBcnJheS5mcm9tKHRlc3RTdWl0ZUVsLnF1ZXJ5U2VsZWN0b3JBbGwoJy50ZXN0LXN0YXRlJykpO1xuICAgIHRlc3RFbHMuZm9yRWFjaCgodGVzdFN0YXR1c0VsLCBpdGVyKSA9PiB7XG4gICAgICBpZiAodGVzdFN0YXR1c2VzW2l0ZXJdID09PSB0cnVlKSB7XG4gICAgICAgIHRlc3RTdGF0dXNFbC5pbm5lckhUTUwgPSAnWyYjeDI3MTM7XSc7XG4gICAgICAgIHRlc3RTdGF0dXNFbC5jbGFzc0xpc3QucmVtb3ZlKCdmYWlsJyk7XG4gICAgICAgIHRlc3RTdGF0dXNFbC5jbGFzc0xpc3QuYWRkKCdwYXNzJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ZXN0U3RhdHVzRWwuaW5uZXJIVE1MID0gJ1smI3gyNzE4O10nO1xuICAgICAgICB0ZXN0U3RhdHVzRWwuY2xhc3NMaXN0LnJlbW92ZSgncGFzcycpO1xuICAgICAgICB0ZXN0U3RhdHVzRWwuY2xhc3NMaXN0LmFkZCgnZmFpbCcpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKGFsbFBhc3NlZCA9PT0gdHJ1ZSkge1xuICAgICAgdGVzdFRvdGFsRWwuaW5uZXJUZXh0ID0gJ1BBU1MnO1xuICAgICAgdGVzdFRvdGFsRWwuY2xhc3NMaXN0LnJlbW92ZSgnZmFpbCcpO1xuICAgICAgdGVzdFRvdGFsRWwuY2xhc3NMaXN0LmFkZCgncGFzcycpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0ZXN0VG90YWxFbC5pbm5lclRleHQgPSAnRkFJTCc7XG4gICAgICB0ZXN0VG90YWxFbC5jbGFzc0xpc3QucmVtb3ZlKCdwYXNzJyk7XG4gICAgICB0ZXN0VG90YWxFbC5jbGFzc0xpc3QuYWRkKCdmYWlsJyk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcHJpbnRBc3NlcnRFcnJvcihlcnJPYmopIHtcbiAgICAvLyBNYWtlIGVsZW1lbnQgc3RyaW5nXG4gICAgbGV0IGlubmVyID0gJyc7XG4gICAgaWYgKGVyck9iaiAhPT0gbnVsbCkge1xuICAgICAgaW5uZXIgPSBgXG4gICAgICA8ZGl2IGNsYXNzPVwiYXNzZXJ0LWVycm9yXCI+XG4gICAgICAgIEV4cGVjdGVkOiAke0pTT04uc3RyaW5naWZ5KGVyck9iai5leHBlY3RlZCl9XG4gICAgICAgIEFjdHVhbDogJHtKU09OLnN0cmluZ2lmeShlcnJPYmouYWN0dWFsKX1cbiAgICAgIDwvZGl2PmA7XG4gICAgfVxuXG4gICAgLy8gUHJlcGVuZCBlbGVtZW50XG4gICAgYXNzZXJ0Q29uc29sZUVsLmlubmVySFRNTCA9IGlubmVyO1xuICB9XG5cbiAgZnVuY3Rpb24gcHJpbnRFdmFsT3V0cHV0KGVyck9iaiwgb3V0cHV0KSB7XG4gICAgLy8gTWFrZSBlbGVtZW50IHN0cmluZ1xuICAgIGxldCBpbm5lciA9ICcnO1xuICAgIGlmIChlcnJPYmogJiYgZXJyT2JqLm1lc3NhZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaW5uZXIgPSBgXG4gICAgICA8ZGl2IGNsYXNzPVwiYXNzZXJ0LWVycm9yXCI+XG4gICAgICAgIFN5bnRheCBFcnJvcjogJHtKU09OLnN0cmluZ2lmeShlcnJPYmoubWVzc2FnZSl9XG4gICAgICA8L2Rpdj5gO1xuICAgIH0gZWxzZSBpZiAob3V0cHV0KSB7XG4gICAgICBpbm5lciA9IGBcbiAgICAgIDxkaXYgY2xhc3M9XCJhc3NlcnQtZXJyb3JcIj5cbiAgICAgICAgT3V0cHV0OiAke0pTT04uc3RyaW5naWZ5KG91dHB1dCl9XG4gICAgICA8L2Rpdj5gO1xuICAgIH1cbiAgICAvLyBQcmVwZW5kIGVsZW1lbnRcbiAgICBldmFsQ29uc29sZUVsLmlubmVySFRNTCA9IGlubmVyO1xuICB9XG5cblxuICAvLyBWRVJJRklDQVRJT04gTE9HSUNcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgZnVuY3Rpb24gdGVzdFN1aXRlKGluaXQpIHtcbiAgICAvLyBSdW4gc3R1ZmZcbiAgICBjb25zdCBvdXRwdXQgPSBnZXRPdXRwdXQoY29kZUVsLnZhbHVlKTtcbiAgICAvLyBSdW4gdGVzdHMgb24gY29kZSwgcmV0dXJuIG9iamVjdC9hcnJheSBvZiB0ZXN0IHJlc3VsdHNcbiAgICBjb25zdCB0ZXN0ZWQgPSBydW5UZXN0cyhvdXRwdXQpO1xuICAgIC8vIFVwZGF0ZSBVSSB3aXRoIHJlc3VsdHNcbiAgICB1cGRhdGVUZXN0cyh0ZXN0ZWQsIGluaXQpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0T3V0cHV0KGNvZGUpIHtcbiAgICBsZXQgZXZhbGQgPSBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgZXZhbGQgPSBldmFsKGAoZnVuY3Rpb24oKXske2NvZGV9fSkoKWApOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWV2YWxcbiAgICAgIHByaW50RXZhbE91dHB1dChudWxsLCBldmFsZCk7IC8vIFByaW50IGN1cnJlbnQgb3V0cHV0XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBwcmludEV2YWxPdXRwdXQoZXJyKTtcbiAgICB9XG4gICAgcmV0dXJuIGV2YWxkO1xuICB9XG5cbiAgZnVuY3Rpb24gcnVuVGVzdHMob3V0cHV0KSB7XG4gICAgbGV0IHRlc3RlZCA9IGZhbHNlO1xuICAgIHRlc3RlZCA9IGN1cnJlbnRQcm9ibGVtLnRlc3RzLm1hcCh0ZXN0ID0+IHtcbiAgICAgIGxldCB0ZXN0T3V0Y29tZSA9IGZhbHNlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKG91dHB1dCkge1xuICAgICAgICAgIC8vIGNvbnN0IHRlc3RFdmFsID0gZXZhbCh0ZXN0LnRlc3QpO1xuXG4gICAgICAgICAgdGVzdE91dGNvbWUgPSBldmFsKHRlc3QudGVzdCk7XG4gICAgICAgICAgY29uc29sZS5sb2coJ3Rlc3RPdXRjb21lOicsIHRlc3RPdXRjb21lKTtcblxuICAgICAgICB9XG4gICAgICAgIHByaW50QXNzZXJ0RXJyb3IobnVsbCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgcHJpbnRBc3NlcnRFcnJvcihlcnIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRlc3RPdXRjb21lO1xuICAgIH0pO1xuICAgIHJldHVybiB0ZXN0ZWQ7XG4gIH1cblxuICAvLyBXcmFwcGVkIHRvIHByZXZlbnQgcmFjZSB3aXRoIGxvY2FsIGNvbmZpZyByZXRyaWV2YWxcbiAgZnVuY3Rpb24gbG9hZEFwcChjb25maWcpIHtcbiAgICBjb25zb2xlLmxvZygnbG9hZGluZyBhcHAhJyk7XG5cbiAgICAvLyBTaG93IGN1cnJlbnQgdG9nZ2xlIHN0YXRlXG4gICAgaWYgKGNvbmZpZy5zaHVmZmxlID09PSB0cnVlKSB7XG4gICAgICBzaHVmZmxlUHJvYmxlbXNCdXR0b25FbC5jbGFzc0xpc3QuYWRkKCdhY3RpdmUnKTtcbiAgICB9XG5cbiAgICAvLyBCaW5kIGl0IHVwXG4gICAgY29kZUVsLmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgZSA9PiB7XG4gICAgICAvLyBJZiBub3QgYXJyb3cga2V5cyBvciBvdGhlciBub24tY2hhcmFjdGVyIGtleXNcbiAgICAgIGlmIChpZ25vcmVLZXlDb2Rlcy5pbmRleE9mKGUua2V5Q29kZSkgPT09IC0xKSB7XG4gICAgICAgIC8vIFJ1biB0ZXN0IHN1aXRlXG4gICAgICAgIHRlc3RTdWl0ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHNodWZmbGVQcm9ibGVtc0J1dHRvbkVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdG9nZ2xlU2h1ZmZsZSk7XG4gICAgcHJldmlvdXNQcm9ibGVtQnV0dG9uRWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBwcmV2aW91c1Byb2JsZW0pO1xuICAgIG5leHRQcm9ibGVtQnV0dG9uRWwuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBuZXh0UHJvYmxlbSk7XG5cbiAgICAvLyBTdGFydCBpdCB1cCFcbiAgICAvLyBMb2FkIGN1cnJlbnQgcHJvYmxlbVxuICAgIGNvbnN0IGN1cnJQcm9iID0gZ2V0Q3VycmVudFByb2JsZW0ocHJvYmxlbXMpO1xuICAgIGxvYWRQcm9ibGVtKGN1cnJQcm9iKTtcbiAgICAvLyBJbml0YWxpemVkIHRlc3Qgc3VpdGUgd2l0aCBzdGFydGluZyBmYWlsdXJlc1xuICAgIHRlc3RTdWl0ZSh0cnVlKTtcbiAgfVxufSkoZG9jdW1lbnQsIHdpbmRvdyk7XG4iXX0="} ->>>>>>> working import of external problem content +{"version":3,"sources":["node_modules/.registry.npmjs.org/browser-pack/6.0.2/node_modules/browser-pack/_prelude.js","node_modules/.github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916/node_modules/pjs-problems/index.js","node_modules/.github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916/node_modules/pjs-problems/problems/arrays.js","node_modules/.github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916/node_modules/pjs-problems/problems/initial.js","node_modules/.registry.npmjs.org/assertion-error/1.0.2/node_modules/assertion-error/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/assertion.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/config.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/core/assertions.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/assert.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/expect.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/should.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addChainableMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/expectTypes.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/flag.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getActual.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getEnumerableProperties.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getMessage.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getName.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getPathInfo.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getPathValue.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getProperties.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/hasProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/inspect.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/objDisplay.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/test.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/transferFlags.js","node_modules/.registry.npmjs.org/dedent/0.7.0/node_modules/dedent/dist/dedent.js","node_modules/.registry.npmjs.org/deep-eql/0.1.3/node_modules/deep-eql/index.js","node_modules/.registry.npmjs.org/deep-eql/0.1.3/node_modules/deep-eql/lib/eql.js","node_modules/.registry.npmjs.org/localforage/1.5.0/node_modules/localforage/dist/node_modules/localforage/dist/localforage.js","node_modules/.registry.npmjs.org/type-detect/0.1.1/node_modules/type-detect/index.js","node_modules/.registry.npmjs.org/type-detect/0.1.1/node_modules/type-detect/lib/type.js","node_modules/.registry.npmjs.org/type-detect/1.0.0/node_modules/type-detect/lib/type.js","src/js/index.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length","1","module","initial","arrays","name","time","prompt","given","answer","tests","test","exclude","excludeProps","res","obj","Object","keys","forEach","key","excludes","indexOf","slice","arguments","args","AssertionError","message","_props","ssf","props","this","showDiff","callee","captureStackTrace","stack","prototype","create","constructor","toJSON","used","version","util","use","fn","push","config","assertion","core","expect","should","assert","_chai","Assertion","msg","flag","defineProperty","get","console","warn","includeStack","set","value","addProperty","addMethod","addChainableMethod","chainingBehavior","overwriteProperty","overwriteMethod","overwriteChainableMethod","expr","negateMsg","expected","_actual","ok","getMessage","actual","getActual","val","truncateThreshold","chai","_","an","type","toLowerCase","article","charAt","includeChainingBehavior","include","expectTypes","eql","k","property","subset","undefined","inspect","checkArguments","toString","assertEqual","_obj","assertEql","assertAbove","to","have","len","assertLeast","assertBelow","assertMost","assertInstanceOf","getName","assertOwnProperty","hasOwnProperty","assertOwnPropertyDescriptor","descriptor","actualDescriptor","getOwnPropertyDescriptor","assertLengthChain","assertLength","assertMatch","re","exec","assertKeys","str","mixedArgsMsg","Array","any","all","filter","every","last","map","pop","join","sort","assertThrows","errMsg","is","thrown","desiredError","thrownError","RegExp","err","actuallyGot","expectedThrown","respondTo","method","itself","context","satisfy","matcher","result","objDisplay","negate","closeTo","delta","Math","abs","isSubsetOf","superset","cmp","elem","some","elem2","oneOf","list","be","assertChanges","object","prop","assertIncreases","assertDecreases","chain","isNaN","isArray","start","finish","range","isDeep","pathInfo","getPathInfo","hasProperty","exists","isExtensible","TypeError","isSealed","isFrozen","express","errmsg","fail","operator","isOk","isNotOk","not","equal","act","exp","notEqual","strictEqual","notStrictEqual","deepEqual","notDeepEqual","isAbove","abv","above","isAtLeast","atlst","least","isBelow","blw","below","isAtMost","atmst","most","isTrue","isNotTrue","isFalse","isNotFalse","isNull","isNotNull","NaN","isNotNaN","isUndefined","isDefined","isFunction","isNotFunction","isObject","isNotObject","isNotArray","isString","isNotString","isNumber","isNotNumber","isBoolean","isNotBoolean","typeOf","notTypeOf","instanceOf","notInstanceOf","inc","notInclude","match","notMatch","notProperty","deepProperty","deep","notDeepProperty","propertyVal","propertyNotVal","deepPropertyVal","deepPropertyNotVal","lengthOf","throws","errt","errs","assertErr","throw","doesNotThrow","Throw","val2","approximately","sameMembers","set1","set2","same","members","sameDeepMembers","includeMembers","includeDeepMembers","inList","changes","change","doesNotChange","increases","increase","doesNotIncrease","decreases","decrease","doesNotDecrease","ifError","extensible","isNotExtensible","sealed","isNotSealed","frozen","isNotFrozen","alias","as","loadShould","shouldGetter","String","Number","Boolean","valueOf","shouldSetter","enumerable","configurable","writable","val1","exist","Should","transferFlags","hasProtoSupport","excludeNames","Function","apply","ctx","chainableBehavior","__methods","__proto__","getOwnPropertyNames","asserterName","pd","getter","types","index","art","flags","__flags","flagMsg","replace","func","parsePath","path","mArr","parseFloat","p","_getPathValue","parsed","tmp","part","info","parent","proto","getPrototypeOf","literals","number","string","ot","getPathValue","showHidden","depth","colors","formatValue","seen","stylize","recurseTimes","ret","primitive","formatPrimitive","isDOMElement","outerHTML","document","xmlVersion","XMLSerializer","serializeToString","container","createElementNS","appendChild","cloneNode","html","innerHTML","visibleKeys","getEnumerableProperties","getProperties","isError","nameSuffix","isRegExp","isDate","Date","toUTCString","formatError","base","array","braces","output","formatArray","formatProperty","reduceToSingleString","simple","JSON","stringify","Infinity","__lookupGetter__","__lookupSetter__","split","line","substr","numLinesEst","reduce","prev","cur","ar","objectToString","d","HTMLElement","nodeType","nodeName","splice","_chainingBehavior","_method","_super","_get","includeAll","dedent","strings","raw","lines","mindent","m","indent","min","trim","b","sameValue","dateEqual","regexpEqual","Buffer","isBuffer","bufferEqual","argumentsEqual","typeEqual","objectEqual","getTime","iterableEqual","isValue","ka","kb","ex","define","amd","window","global","self","localforage","_dereq_","nextTick","draining","oldQueue","queue","immediate","task","scheduleDrain","Mutation","MutationObserver","WebKitMutationObserver","called","observer","element","createTextNode","observe","characterData","data","setImmediate","MessageChannel","createElement","scriptEl","onreadystatechange","parentNode","removeChild","documentElement","setTimeout","channel","port1","onmessage","port2","postMessage","2","INTERNAL","Promise","resolver","state","PENDING","outcome","safelyResolveThenable","QueueItem","promise","onFulfilled","onRejected","callFulfilled","otherCallFulfilled","callRejected","otherCallRejected","unwrap","returnValue","handlers","reject","resolve","getThen","then","thenable","onError","onSuccess","tryToUnwrap","tryCatch","status","out","reason","iterable","values","resolved","resolveFromAll","outValue","error","race","response","REJECTED","FULFILLED","3","4","_classCallCheck","instance","Constructor","createBlob","parts","properties","Blob","builder","BlobBuilder","MSBlobBuilder","MozBlobBuilder","WebKitBlobBuilder","append","getBlob","executeCallback","callback","executeTwoCallbacks","errorCallback","_binStringToArrayBuffer","bin","buf","ArrayBuffer","arr","Uint8Array","charCodeAt","_checkBlobSupportWithoutCaching","idb","Promise$1","txn","transaction","DETECT_BLOB_SUPPORT_STORE","blob","objectStore","put","onabort","preventDefault","stopPropagation","oncomplete","matchedChrome","navigator","userAgent","matchedEdge","parseInt","_checkBlobSupport","supportsBlobs","_deferReadiness","dbInfo","dbContext","dbContexts","deferredOperation","deferredOperations","dbReady","_advanceReadiness","_getConnection","upgradeNeeded","db","close","dbArgs","openreq","open","onupgradeneeded","createObjectStore","storeName","oldVersion","newVersion","onerror","onsuccess","_getOriginalConnection","_getUpgradedConnection","_isUpgradeNeeded","defaultVersion","isNewStore","objectStoreNames","contains","isDowngrade","isUpgrade","incVersion","_encodeBlob","reader","FileReader","onloadend","base64","btoa","target","__local_forage_encoded_blob","readAsBinaryString","_decodeBlob","encodedBlob","atob","_isEncodedBlob","_fullyReady","_initReady","_dbInfo","_initStorage","options","ignoreErrors","forages","ready","initPromises","j","forage","_defaultConfig","getItem","req","iterate","iterator","openCursor","iterationNumber","cursor","setItem","blobSupport","removeItem","clear","count","advanced","advance","stringToBuffer","serializedString","encoded1","encoded2","encoded3","encoded4","bufferLength","buffer","bytes","BASE_CHARS","bufferToString","base64String","substring","serialize","valueType","toString$1","marker","SERIALIZED_MARKER","TYPE_ARRAYBUFFER","TYPE_INT8ARRAY","TYPE_UINT8ARRAY","TYPE_UINT8CLAMPEDARRAY","TYPE_INT16ARRAY","TYPE_UINT16ARRAY","TYPE_INT32ARRAY","TYPE_UINT32ARRAY","TYPE_FLOAT32ARRAY","TYPE_FLOAT64ARRAY","fileReader","onload","BLOB_TYPE_PREFIX","TYPE_BLOB","readAsArrayBuffer","deserialize","SERIALIZED_MARKER_LENGTH","parse","blobType","TYPE_SERIALIZED_MARKER_LENGTH","BLOB_TYPE_PREFIX_REGEX","Int8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","_initStorage$1","dbInfoPromise","openDatabase","description","size","executeSql","serializer","localforageSerializer","getItem$1","results","rows","item","iterate$1","_setItem","retriesLeft","originalValue","sqlError","QUOTA_ERR","setItem$1","removeItem$1","clear$1","length$1","c","key$1","keys$1","_initStorage$2","keyPrefix","clear$2","localStorage","getItem$2","iterate$2","keyPrefixLength","key$2","keys$2","length$2","removeItem$2","setItem$2","callWhenReady","localForageInstance","libraryMethod","_args","extend","arg","isLibraryDriver","driverName","driver","DriverType","_typeof","Symbol","indexedDB","webkitIndexedDB","mozIndexedDB","OIndexedDB","msIndexedDB","asyncStorage","_driver","webSQLStorage","localStorageWrapper","CustomDrivers","INDEXEDDB","LOCALSTORAGE","WEBSQL","LibraryMethods","DefaultConfig","driverSupport","isSafari","platform","hasFetch","fetch","IDBKeyRange","localforage_js","LocalForage","_config","_driverSet","_initDriver","_ready","_wrapLibraryMethodsWithReady","setDriver","defineDriver","driverObject","complianceError","namingError","customDriverMethods","concat","customDriverMethod","supportPromise","_support","supportResult","getDriver","getDriverPromise","getSerializer","serializerPromise","drivers","setDriverToConfig","extendSelfWithDriver","_extend","initDriver","supportedDrivers","driverPromiseLoop","currentDriverIndex","_getSupportedDrivers","oldDriverSetDone","supports","libraryMethodsAndProperties","createInstance","getType","natives","Library","[object Array]","[object RegExp]","[object Function]","[object Arguments]","[object Date]","of","ReferenceError","objectTypeRegexp","dedentStrings","problems","prob","updateLocalstore","catch","log","debounce","wait","timeout","later","callNow","clearTimeout","getRandomIndex","problemsArr","ind","floor","random","currentIndex","getPreviousIndex","getNextIndex","getCurrentProblem","previousProblem","previousProblemButtonEl","classList","add","shuffle","location","reload","nextProblem","nextProblemButtonEl","toggleShuffle","shuffleProblemsButtonEl","toggle","loadProblem","problemObj","currentProblem","problemEl","innerText","codeEl","testSuite","updateTests","testStatus","init","buildTests","updateTestStatus","testsDom","testSuiteEl","testStatuses","allPassed","testPassed","querySelectorAll","testStatusEl","iter","remove","testTotalEl","printAssertError","errObj","inner","assertConsoleEl","printEvalOutput","evalConsoleEl","tested","runTests","getOutput","evald","eval","testOutcome","loadApp","problemNav","keyCode","shiftKey","metaKey","ctrlKey","debouncedInputValidation","ignoreKeyCodes","addEventListener","probs","subject","_problems","_toConsumableArray","timer","getElementById"],"mappings":"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","file":"bundle.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o num > 5);\n return overFive;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, [8, 13, 21]) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n },\n {\n name: `First item is 8`,\n test: `assert.deepEqual(output[0], 8) === undefined;`\n }\n ]\n },\n {\n name: 'Array.map()',\n time: 10,\n prompt: `Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,\n given: `const numbers = [25, 121, 169];\\r`,\n answer: `const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, [5, 11, 13]) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n },\n {\n name: `First item is 5`,\n test: `assert.deepEqual(output[0], 5) === undefined;`\n },\n {\n name: `Last item is 13`,\n test: `assert.deepEqual(output[output.length - 1], 13) === undefined;`\n }\n ]\n },\n {\n name: 'Array.every()',\n time: 10,\n prompt: `Return object that returns whether each array contains all even numbers using Array.every().`,\n given: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,\n answer: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n return element % 2 === 0\n }\n return {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n };`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;`\n },\n {\n name: 'Returns an Object',\n test: `assert.isObject(output) === undefined;`\n },\n {\n name: 'Object has 2 items',\n test: `assert.lengthOf(Object.keys(output), 2) === undefined;`\n },\n {\n name: `First value is true`,\n test: `assert.isTrue(output.evenNumbers) === undefined;`\n },\n {\n name: `Second value is false`,\n test: `assert.isFalse(output.someOddNumbers) === undefined;`\n }\n ]\n },\n {\n name: 'Array.some()',\n time: 10,\n prompt: `Return 'Object' that returns whether each array contains some odd numbers using 'Array.some()'.`,\n given: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 4, 7, 8];\n function isOdd(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,\n answer: `const evenNumbers = [1, 3, 5, 7];\n const someOddNumbers = [1, 3, 6, 7];\n function isOdd(element) {\n return element % 2 !== 0;\n }\n return {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n };`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;`\n },\n {\n name: 'Returns an Object',\n test: `assert.isObject(output) === undefined;`\n },\n {\n name: 'Object has 2 items',\n test: `assert.lengthOf(Object.keys(output), 2) === undefined;`\n },\n {\n name: `First value is false`,\n test: `assert.isFalse(output.evenNumbers) === undefined;`\n },\n {\n name: `Second value is true`,\n test: `assert.isTrue(output.someOddNumbers) === undefined;`\n }\n ]\n }\n // Next problems to create:\n // forEach? fix one above that tried, but can't verify forEach was used\n // some\n // reduce\n // reduceRight\n // Array.from and other ways to turn array-like into array\n];\n","module.exports = [\n {\n name: 'Create Array',\n time: 10,\n prompt: 'Create and return an array that contains \\'apple\\' and \\'banana\\'',\n given: `const fruits = [];\\rreturn fruits;`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.pop()',\n time: 10,\n prompt: `Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n]\n","/*!\n * assertion-error\n * Copyright(c) 2013 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n var excludes = [].slice.call(arguments);\n\n function excludeProps (res, obj) {\n Object.keys(obj).forEach(function (key) {\n if (!~excludes.indexOf(key)) res[key] = obj[key];\n });\n }\n\n return function extendExclude () {\n var args = [].slice.call(arguments)\n , i = 0\n , res = {};\n\n for (; i < args.length; i++) {\n excludeProps(res, args[i]);\n }\n\n return res;\n };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n , props = extend(_props || {});\n\n // default values\n this.message = message || 'Unspecified AssertionError';\n this.showDiff = false;\n\n // copy from properties\n for (var key in props) {\n this[key] = props[key];\n }\n\n // capture stack trace\n ssf = ssf || arguments.callee;\n if (ssf && Error.captureStackTrace) {\n Error.captureStackTrace(this, ssf);\n } else {\n try {\n throw new Error();\n } catch(e) {\n this.stack = e.stack;\n }\n }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n var extend = exclude('constructor', 'toJSON', 'stack')\n , props = extend({ name: this.name }, this);\n\n // include stack if exists and not turned off\n if (false !== stack && this.stack) {\n props.stack = this.stack;\n }\n\n return props;\n};\n","module.exports = require('./lib/chai');\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar used = []\n , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n if (!~used.indexOf(fn)) {\n fn(this, util);\n used.push(fn);\n }\n\n return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n /*!\n * Module dependencies.\n */\n\n var AssertionError = _chai.AssertionError\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n _chai.Assertion = Assertion;\n\n /*!\n * Assertion Constructor\n *\n * Creates object for chaining.\n *\n * @api private\n */\n\n function Assertion (obj, msg, stack) {\n flag(this, 'ssfi', stack || arguments.callee);\n flag(this, 'object', obj);\n flag(this, 'message', msg);\n }\n\n Object.defineProperty(Assertion, 'includeStack', {\n get: function() {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n return config.includeStack;\n },\n set: function(value) {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n config.includeStack = value;\n }\n });\n\n Object.defineProperty(Assertion, 'showDiff', {\n get: function() {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n return config.showDiff;\n },\n set: function(value) {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n config.showDiff = value;\n }\n });\n\n Assertion.addProperty = function (name, fn) {\n util.addProperty(this.prototype, name, fn);\n };\n\n Assertion.addMethod = function (name, fn) {\n util.addMethod(this.prototype, name, fn);\n };\n\n Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n Assertion.overwriteProperty = function (name, fn) {\n util.overwriteProperty(this.prototype, name, fn);\n };\n\n Assertion.overwriteMethod = function (name, fn) {\n util.overwriteMethod(this.prototype, name, fn);\n };\n\n Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n /**\n * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n *\n * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n *\n * @name assert\n * @param {Philosophical} expression to be tested\n * @param {String|Function} message or function that returns message to display if expression fails\n * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n * @param {Mixed} expected value (remember to check for negation)\n * @param {Mixed} actual (optional) will default to `this.obj`\n * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n * @api private\n */\n\n Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n var ok = util.test(this, arguments);\n if (true !== showDiff) showDiff = false;\n if (true !== config.showDiff) showDiff = false;\n\n if (!ok) {\n var msg = util.getMessage(this, arguments)\n , actual = util.getActual(this, arguments);\n throw new AssertionError(msg, {\n actual: actual\n , expected: expected\n , showDiff: showDiff\n }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n }\n };\n\n /*!\n * ### ._obj\n *\n * Quick reference to stored `actual` value for plugin developers.\n *\n * @api private\n */\n\n Object.defineProperty(Assertion.prototype, '_obj',\n { get: function () {\n return flag(this, 'object');\n }\n , set: function (val) {\n flag(this, 'object', val);\n }\n });\n};\n","module.exports = {\n\n /**\n * ### config.includeStack\n *\n * User configurable property, influences whether stack trace\n * is included in Assertion error message. Default of false\n * suppresses stack trace in the error message.\n *\n * chai.config.includeStack = true; // enable stack on error\n *\n * @param {Boolean}\n * @api public\n */\n\n includeStack: false,\n\n /**\n * ### config.showDiff\n *\n * User configurable property, influences whether or not\n * the `showDiff` flag should be included in the thrown\n * AssertionErrors. `false` will always be `false`; `true`\n * will be true when the assertion has requested a diff\n * be shown.\n *\n * @param {Boolean}\n * @api public\n */\n\n showDiff: true,\n\n /**\n * ### config.truncateThreshold\n *\n * User configurable property, sets length threshold for actual and\n * expected values in assertion errors. If this threshold is exceeded, for\n * example for large data structures, the value is replaced with something\n * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n *\n * Set it to zero if you want to disable truncating altogether.\n *\n * This is especially userful when doing assertions on arrays: having this\n * set to a reasonable large value makes the failure messages readily\n * inspectable.\n *\n * chai.config.truncateThreshold = 0; // disable truncating\n *\n * @param {Number}\n * @api public\n */\n\n truncateThreshold: 40\n\n};\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n var Assertion = chai.Assertion\n , toString = Object.prototype.toString\n , flag = _.flag;\n\n /**\n * ### Language Chains\n *\n * The following are provided as chainable getters to\n * improve the readability of your assertions. They\n * do not provide testing capabilities unless they\n * have been overwritten by a plugin.\n *\n * **Chains**\n *\n * - to\n * - be\n * - been\n * - is\n * - that\n * - which\n * - and\n * - has\n * - have\n * - with\n * - at\n * - of\n * - same\n *\n * @name language chains\n * @namespace BDD\n * @api public\n */\n\n [ 'to', 'be', 'been'\n , 'is', 'and', 'has', 'have'\n , 'with', 'that', 'which', 'at'\n , 'of', 'same' ].forEach(function (chain) {\n Assertion.addProperty(chain, function () {\n return this;\n });\n });\n\n /**\n * ### .not\n *\n * Negates any of assertions following in the chain.\n *\n * expect(foo).to.not.equal('bar');\n * expect(goodFn).to.not.throw(Error);\n * expect({ foo: 'baz' }).to.have.property('foo')\n * .and.not.equal('bar');\n *\n * @name not\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('not', function () {\n flag(this, 'negate', true);\n });\n\n /**\n * ### .deep\n *\n * Sets the `deep` flag, later used by the `equal` and\n * `property` assertions.\n *\n * expect(foo).to.deep.equal({ bar: 'baz' });\n * expect({ foo: { bar: { baz: 'quux' } } })\n * .to.have.deep.property('foo.bar.baz', 'quux');\n *\n * `.deep.property` special characters can be escaped\n * by adding two slashes before the `.` or `[]`.\n *\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name deep\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('deep', function () {\n flag(this, 'deep', true);\n });\n\n /**\n * ### .any\n *\n * Sets the `any` flag, (opposite of the `all` flag)\n * later used in the `keys` assertion.\n *\n * expect(foo).to.have.any.keys('bar', 'baz');\n *\n * @name any\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('any', function () {\n flag(this, 'any', true);\n flag(this, 'all', false)\n });\n\n\n /**\n * ### .all\n *\n * Sets the `all` flag (opposite of the `any` flag)\n * later used by the `keys` assertion.\n *\n * expect(foo).to.have.all.keys('bar', 'baz');\n *\n * @name all\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('all', function () {\n flag(this, 'all', true);\n flag(this, 'any', false);\n });\n\n /**\n * ### .a(type)\n *\n * The `a` and `an` assertions are aliases that can be\n * used either as language chains or to assert a value's\n * type.\n *\n * // typeof\n * expect('test').to.be.a('string');\n * expect({ foo: 'bar' }).to.be.an('object');\n * expect(null).to.be.a('null');\n * expect(undefined).to.be.an('undefined');\n * expect(new Error).to.be.an('error');\n * expect(new Promise).to.be.a('promise');\n * expect(new Float32Array()).to.be.a('float32array');\n * expect(Symbol()).to.be.a('symbol');\n *\n * // es6 overrides\n * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n *\n * // language chain\n * expect(foo).to.be.an.instanceof(Foo);\n *\n * @name a\n * @alias an\n * @param {String} type\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function an (type, msg) {\n if (msg) flag(this, 'message', msg);\n type = type.toLowerCase();\n var obj = flag(this, 'object')\n , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n this.assert(\n type === _.type(obj)\n , 'expected #{this} to be ' + article + type\n , 'expected #{this} not to be ' + article + type\n );\n }\n\n Assertion.addChainableMethod('an', an);\n Assertion.addChainableMethod('a', an);\n\n /**\n * ### .include(value)\n *\n * The `include` and `contain` assertions can be used as either property\n * based language chains or as methods to assert the inclusion of an object\n * in an array or a substring in a string. When used as language chains,\n * they toggle the `contains` flag for the `keys` assertion.\n *\n * expect([1,2,3]).to.include(2);\n * expect('foobar').to.contain('foo');\n * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n *\n * @name include\n * @alias contain\n * @alias includes\n * @alias contains\n * @param {Object|String|Number} obj\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function includeChainingBehavior () {\n flag(this, 'contains', true);\n }\n\n function include (val, msg) {\n _.expectTypes(this, ['array', 'object', 'string']);\n\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var expected = false;\n\n if (_.type(obj) === 'array' && _.type(val) === 'object') {\n for (var i in obj) {\n if (_.eql(obj[i], val)) {\n expected = true;\n break;\n }\n }\n } else if (_.type(val) === 'object') {\n if (!flag(this, 'negate')) {\n for (var k in val) new Assertion(obj).property(k, val[k]);\n return;\n }\n var subset = {};\n for (var k in val) subset[k] = obj[k];\n expected = _.eql(subset, val);\n } else {\n expected = (obj != undefined) && ~obj.indexOf(val);\n }\n this.assert(\n expected\n , 'expected #{this} to include ' + _.inspect(val)\n , 'expected #{this} to not include ' + _.inspect(val));\n }\n\n Assertion.addChainableMethod('include', include, includeChainingBehavior);\n Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n /**\n * ### .ok\n *\n * Asserts that the target is truthy.\n *\n * expect('everything').to.be.ok;\n * expect(1).to.be.ok;\n * expect(false).to.not.be.ok;\n * expect(undefined).to.not.be.ok;\n * expect(null).to.not.be.ok;\n *\n * @name ok\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('ok', function () {\n this.assert(\n flag(this, 'object')\n , 'expected #{this} to be truthy'\n , 'expected #{this} to be falsy');\n });\n\n /**\n * ### .true\n *\n * Asserts that the target is `true`.\n *\n * expect(true).to.be.true;\n * expect(1).to.not.be.true;\n *\n * @name true\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('true', function () {\n this.assert(\n true === flag(this, 'object')\n , 'expected #{this} to be true'\n , 'expected #{this} to be false'\n , this.negate ? false : true\n );\n });\n\n /**\n * ### .false\n *\n * Asserts that the target is `false`.\n *\n * expect(false).to.be.false;\n * expect(0).to.not.be.false;\n *\n * @name false\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('false', function () {\n this.assert(\n false === flag(this, 'object')\n , 'expected #{this} to be false'\n , 'expected #{this} to be true'\n , this.negate ? true : false\n );\n });\n\n /**\n * ### .null\n *\n * Asserts that the target is `null`.\n *\n * expect(null).to.be.null;\n * expect(undefined).to.not.be.null;\n *\n * @name null\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('null', function () {\n this.assert(\n null === flag(this, 'object')\n , 'expected #{this} to be null'\n , 'expected #{this} not to be null'\n );\n });\n\n /**\n * ### .undefined\n *\n * Asserts that the target is `undefined`.\n *\n * expect(undefined).to.be.undefined;\n * expect(null).to.not.be.undefined;\n *\n * @name undefined\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('undefined', function () {\n this.assert(\n undefined === flag(this, 'object')\n , 'expected #{this} to be undefined'\n , 'expected #{this} not to be undefined'\n );\n });\n\n /**\n * ### .NaN\n * Asserts that the target is `NaN`.\n *\n * expect('foo').to.be.NaN;\n * expect(4).not.to.be.NaN;\n *\n * @name NaN\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('NaN', function () {\n this.assert(\n isNaN(flag(this, 'object'))\n , 'expected #{this} to be NaN'\n , 'expected #{this} not to be NaN'\n );\n });\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi'\n * , bar = null\n * , baz;\n *\n * expect(foo).to.exist;\n * expect(bar).to.not.exist;\n * expect(baz).to.not.exist;\n *\n * @name exist\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('exist', function () {\n this.assert(\n null != flag(this, 'object')\n , 'expected #{this} to exist'\n , 'expected #{this} to not exist'\n );\n });\n\n\n /**\n * ### .empty\n *\n * Asserts that the target's length is `0`. For arrays and strings, it checks\n * the `length` property. For objects, it gets the count of\n * enumerable keys.\n *\n * expect([]).to.be.empty;\n * expect('').to.be.empty;\n * expect({}).to.be.empty;\n *\n * @name empty\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('empty', function () {\n var obj = flag(this, 'object')\n , expected = obj;\n\n if (Array.isArray(obj) || 'string' === typeof object) {\n expected = obj.length;\n } else if (typeof obj === 'object') {\n expected = Object.keys(obj).length;\n }\n\n this.assert(\n !expected\n , 'expected #{this} to be empty'\n , 'expected #{this} not to be empty'\n );\n });\n\n /**\n * ### .arguments\n *\n * Asserts that the target is an arguments object.\n *\n * function test () {\n * expect(arguments).to.be.arguments;\n * }\n *\n * @name arguments\n * @alias Arguments\n * @namespace BDD\n * @api public\n */\n\n function checkArguments () {\n var obj = flag(this, 'object')\n , type = Object.prototype.toString.call(obj);\n this.assert(\n '[object Arguments]' === type\n , 'expected #{this} to be arguments but got ' + type\n , 'expected #{this} to not be arguments'\n );\n }\n\n Assertion.addProperty('arguments', checkArguments);\n Assertion.addProperty('Arguments', checkArguments);\n\n /**\n * ### .equal(value)\n *\n * Asserts that the target is strictly equal (`===`) to `value`.\n * Alternately, if the `deep` flag is set, asserts that\n * the target is deeply equal to `value`.\n *\n * expect('hello').to.equal('hello');\n * expect(42).to.equal(42);\n * expect(1).to.not.equal(true);\n * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n *\n * @name equal\n * @alias equals\n * @alias eq\n * @alias deep.equal\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEqual (val, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'deep')) {\n return this.eql(val);\n } else {\n this.assert(\n val === obj\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{exp}'\n , val\n , this._obj\n , true\n );\n }\n }\n\n Assertion.addMethod('equal', assertEqual);\n Assertion.addMethod('equals', assertEqual);\n Assertion.addMethod('eq', assertEqual);\n\n /**\n * ### .eql(value)\n *\n * Asserts that the target is deeply equal to `value`.\n *\n * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n *\n * @name eql\n * @alias eqls\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEql(obj, msg) {\n if (msg) flag(this, 'message', msg);\n this.assert(\n _.eql(obj, flag(this, 'object'))\n , 'expected #{this} to deeply equal #{exp}'\n , 'expected #{this} to not deeply equal #{exp}'\n , obj\n , this._obj\n , true\n );\n }\n\n Assertion.addMethod('eql', assertEql);\n Assertion.addMethod('eqls', assertEql);\n\n /**\n * ### .above(value)\n *\n * Asserts that the target is greater than `value`.\n *\n * expect(10).to.be.above(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n *\n * @name above\n * @alias gt\n * @alias greaterThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertAbove (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len > n\n , 'expected #{this} to have a length above #{exp} but got #{act}'\n , 'expected #{this} to not have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj > n\n , 'expected #{this} to be above ' + n\n , 'expected #{this} to be at most ' + n\n );\n }\n }\n\n Assertion.addMethod('above', assertAbove);\n Assertion.addMethod('gt', assertAbove);\n Assertion.addMethod('greaterThan', assertAbove);\n\n /**\n * ### .least(value)\n *\n * Asserts that the target is greater than or equal to `value`.\n *\n * expect(10).to.be.at.least(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.least(2);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n *\n * @name least\n * @alias gte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLeast (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= n\n , 'expected #{this} to have a length at least #{exp} but got #{act}'\n , 'expected #{this} to have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj >= n\n , 'expected #{this} to be at least ' + n\n , 'expected #{this} to be below ' + n\n );\n }\n }\n\n Assertion.addMethod('least', assertLeast);\n Assertion.addMethod('gte', assertLeast);\n\n /**\n * ### .below(value)\n *\n * Asserts that the target is less than `value`.\n *\n * expect(5).to.be.below(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n *\n * @name below\n * @alias lt\n * @alias lessThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertBelow (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len < n\n , 'expected #{this} to have a length below #{exp} but got #{act}'\n , 'expected #{this} to not have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj < n\n , 'expected #{this} to be below ' + n\n , 'expected #{this} to be at least ' + n\n );\n }\n }\n\n Assertion.addMethod('below', assertBelow);\n Assertion.addMethod('lt', assertBelow);\n Assertion.addMethod('lessThan', assertBelow);\n\n /**\n * ### .most(value)\n *\n * Asserts that the target is less than or equal to `value`.\n *\n * expect(5).to.be.at.most(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.most(4);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n *\n * @name most\n * @alias lte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertMost (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len <= n\n , 'expected #{this} to have a length at most #{exp} but got #{act}'\n , 'expected #{this} to have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj <= n\n , 'expected #{this} to be at most ' + n\n , 'expected #{this} to be above ' + n\n );\n }\n }\n\n Assertion.addMethod('most', assertMost);\n Assertion.addMethod('lte', assertMost);\n\n /**\n * ### .within(start, finish)\n *\n * Asserts that the target is within a range.\n *\n * expect(7).to.be.within(5,10);\n *\n * Can also be used in conjunction with `length` to\n * assert a length range. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * @name within\n * @param {Number} start lowerbound inclusive\n * @param {Number} finish upperbound inclusive\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('within', function (start, finish, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , range = start + '..' + finish;\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= start && len <= finish\n , 'expected #{this} to have a length within ' + range\n , 'expected #{this} to not have a length within ' + range\n );\n } else {\n this.assert(\n obj >= start && obj <= finish\n , 'expected #{this} to be within ' + range\n , 'expected #{this} to not be within ' + range\n );\n }\n });\n\n /**\n * ### .instanceof(constructor)\n *\n * Asserts that the target is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , Chai = new Tea('chai');\n *\n * expect(Chai).to.be.an.instanceof(Tea);\n * expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n *\n * @name instanceof\n * @param {Constructor} constructor\n * @param {String} message _optional_\n * @alias instanceOf\n * @namespace BDD\n * @api public\n */\n\n function assertInstanceOf (constructor, msg) {\n if (msg) flag(this, 'message', msg);\n var name = _.getName(constructor);\n this.assert(\n flag(this, 'object') instanceof constructor\n , 'expected #{this} to be an instance of ' + name\n , 'expected #{this} to not be an instance of ' + name\n );\n };\n\n Assertion.addMethod('instanceof', assertInstanceOf);\n Assertion.addMethod('instanceOf', assertInstanceOf);\n\n /**\n * ### .property(name, [value])\n *\n * Asserts that the target has a property `name`, optionally asserting that\n * the value of that property is strictly equal to `value`.\n * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n * references into objects and arrays.\n *\n * // simple referencing\n * var obj = { foo: 'bar' };\n * expect(obj).to.have.property('foo');\n * expect(obj).to.have.property('foo', 'bar');\n *\n * // deep referencing\n * var deepObj = {\n * green: { tea: 'matcha' }\n * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n * };\n *\n * expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n *\n * You can also use an array as the starting point of a `deep.property`\n * assertion, or traverse nested arrays.\n *\n * var arr = [\n * [ 'chai', 'matcha', 'konacha' ]\n * , [ { tea: 'chai' }\n * , { tea: 'matcha' }\n * , { tea: 'konacha' } ]\n * ];\n *\n * expect(arr).to.have.deep.property('[0][1]', 'matcha');\n * expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n *\n * Furthermore, `property` changes the subject of the assertion\n * to be the value of that property from the original object. This\n * permits for further chainable assertions on that property.\n *\n * expect(obj).to.have.property('foo')\n * .that.is.a('string');\n * expect(deepObj).to.have.property('green')\n * .that.is.an('object')\n * .that.deep.equals({ tea: 'matcha' });\n * expect(deepObj).to.have.property('teas')\n * .that.is.an('array')\n * .with.deep.property('[2]')\n * .that.deep.equals({ tea: 'konacha' });\n *\n * Note that dots and bracket in `name` must be backslash-escaped when\n * the `deep` flag is set, while they must NOT be escaped when the `deep`\n * flag is not set.\n *\n * // simple referencing\n * var css = { '.link[target]': 42 };\n * expect(css).to.have.property('.link[target]', 42);\n *\n * // deep referencing\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name property\n * @alias deep.property\n * @param {String} name\n * @param {Mixed} value (optional)\n * @param {String} message _optional_\n * @returns value of property for chaining\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('property', function (name, val, msg) {\n if (msg) flag(this, 'message', msg);\n\n var isDeep = !!flag(this, 'deep')\n , descriptor = isDeep ? 'deep property ' : 'property '\n , negate = flag(this, 'negate')\n , obj = flag(this, 'object')\n , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n , hasProperty = isDeep\n ? pathInfo.exists\n : _.hasProperty(name, obj)\n , value = isDeep\n ? pathInfo.value\n : obj[name];\n\n if (negate && arguments.length > 1) {\n if (undefined === value) {\n msg = (msg != null) ? msg + ': ' : '';\n throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n }\n } else {\n this.assert(\n hasProperty\n , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n }\n\n if (arguments.length > 1) {\n this.assert(\n val === value\n , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n , val\n , value\n );\n }\n\n flag(this, 'object', value);\n });\n\n\n /**\n * ### .ownProperty(name)\n *\n * Asserts that the target has an own property `name`.\n *\n * expect('test').to.have.ownProperty('length');\n *\n * @name ownProperty\n * @alias haveOwnProperty\n * @param {String} name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnProperty (name, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n obj.hasOwnProperty(name)\n , 'expected #{this} to have own property ' + _.inspect(name)\n , 'expected #{this} to not have own property ' + _.inspect(name)\n );\n }\n\n Assertion.addMethod('ownProperty', assertOwnProperty);\n Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n /**\n * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n *\n * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n *\n * expect('test').to.have.ownPropertyDescriptor('length');\n * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n * expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n *\n * @name ownPropertyDescriptor\n * @alias haveOwnPropertyDescriptor\n * @param {String} name\n * @param {Object} descriptor _optional_\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnPropertyDescriptor (name, descriptor, msg) {\n if (typeof descriptor === 'string') {\n msg = descriptor;\n descriptor = null;\n }\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n if (actualDescriptor && descriptor) {\n this.assert(\n _.eql(descriptor, actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n , descriptor\n , actualDescriptor\n , true\n );\n } else {\n this.assert(\n actualDescriptor\n , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n );\n }\n flag(this, 'object', actualDescriptor);\n }\n\n Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n /**\n * ### .length\n *\n * Sets the `doLength` flag later used as a chain precursor to a value\n * comparison for the `length` property.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * *Deprecation notice:* Using `length` as an assertion will be deprecated\n * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n * asserting for `length` property value using `length(value)` should be\n * switched to use `lengthOf(value)` instead.\n *\n * @name length\n * @namespace BDD\n * @api public\n */\n\n /**\n * ### .lengthOf(value[, message])\n *\n * Asserts that the target's `length` property has\n * the expected value.\n *\n * expect([ 1, 2, 3]).to.have.lengthOf(3);\n * expect('foobar').to.have.lengthOf(6);\n *\n * @name lengthOf\n * @param {Number} length\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLengthChain () {\n flag(this, 'doLength', true);\n }\n\n function assertLength (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n\n this.assert(\n len == n\n , 'expected #{this} to have a length of #{exp} but got #{act}'\n , 'expected #{this} to not have a length of #{act}'\n , n\n , len\n );\n }\n\n Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n Assertion.addMethod('lengthOf', assertLength);\n\n /**\n * ### .match(regexp)\n *\n * Asserts that the target matches a regular expression.\n *\n * expect('foobar').to.match(/^foo/);\n *\n * @name match\n * @alias matches\n * @param {RegExp} RegularExpression\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n function assertMatch(re, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n re.exec(obj)\n , 'expected #{this} to match ' + re\n , 'expected #{this} not to match ' + re\n );\n }\n\n Assertion.addMethod('match', assertMatch);\n Assertion.addMethod('matches', assertMatch);\n\n /**\n * ### .string(string)\n *\n * Asserts that the string target contains another string.\n *\n * expect('foobar').to.have.string('bar');\n *\n * @name string\n * @param {String} string\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('string', function (str, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('string');\n\n this.assert(\n ~obj.indexOf(str)\n , 'expected #{this} to contain ' + _.inspect(str)\n , 'expected #{this} to not contain ' + _.inspect(str)\n );\n });\n\n\n /**\n * ### .keys(key1, [key2], [...])\n *\n * Asserts that the target contains any or all of the passed-in keys.\n * Use in combination with `any`, `all`, `contains`, or `have` will affect\n * what will pass.\n *\n * When used in conjunction with `any`, at least one key that is passed\n * in must exist in the target object. This is regardless whether or not\n * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n * should be used in the assertion. If neither are used, the assertion is\n * defaulted to `all`.\n *\n * When both `all` and `contain` are used, the target object must have at\n * least all of the passed-in keys but may have more keys not listed.\n *\n * When both `all` and `have` are used, the target object must both contain\n * all of the passed-in keys AND the number of keys in the target object must\n * match the number of keys passed in (in other words, a target object must\n * have all and only all of the passed-in keys).\n *\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n *\n *\n * @name keys\n * @alias key\n * @param {...String|Array|Object} keys\n * @namespace BDD\n * @api public\n */\n\n function assertKeys (keys) {\n var obj = flag(this, 'object')\n , str\n , ok = true\n , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n switch (_.type(keys)) {\n case \"array\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n break;\n case \"object\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n keys = Object.keys(keys);\n break;\n default:\n keys = Array.prototype.slice.call(arguments);\n }\n\n if (!keys.length) throw new Error('keys required');\n\n var actual = Object.keys(obj)\n , expected = keys\n , len = keys.length\n , any = flag(this, 'any')\n , all = flag(this, 'all');\n\n if (!any && !all) {\n all = true;\n }\n\n // Has any\n if (any) {\n var intersection = expected.filter(function(key) {\n return ~actual.indexOf(key);\n });\n ok = intersection.length > 0;\n }\n\n // Has all\n if (all) {\n ok = keys.every(function(key){\n return ~actual.indexOf(key);\n });\n if (!flag(this, 'negate') && !flag(this, 'contains')) {\n ok = ok && keys.length == actual.length;\n }\n }\n\n // Key string\n if (len > 1) {\n keys = keys.map(function(key){\n return _.inspect(key);\n });\n var last = keys.pop();\n if (all) {\n str = keys.join(', ') + ', and ' + last;\n }\n if (any) {\n str = keys.join(', ') + ', or ' + last;\n }\n } else {\n str = _.inspect(keys[0]);\n }\n\n // Form\n str = (len > 1 ? 'keys ' : 'key ') + str;\n\n // Have / include\n str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n // Assertion\n this.assert(\n ok\n , 'expected #{this} to ' + str\n , 'expected #{this} to not ' + str\n , expected.slice(0).sort()\n , actual.sort()\n , true\n );\n }\n\n Assertion.addMethod('keys', assertKeys);\n Assertion.addMethod('key', assertKeys);\n\n /**\n * ### .throw(constructor)\n *\n * Asserts that the function target will throw a specific error, or specific type of error\n * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n * for the error's message.\n *\n * var err = new ReferenceError('This is a bad function.');\n * var fn = function () { throw err; }\n * expect(fn).to.throw(ReferenceError);\n * expect(fn).to.throw(Error);\n * expect(fn).to.throw(/bad function/);\n * expect(fn).to.not.throw('good function');\n * expect(fn).to.throw(ReferenceError, /bad function/);\n * expect(fn).to.throw(err);\n *\n * Please note that when a throw expectation is negated, it will check each\n * parameter independently, starting with error constructor type. The appropriate way\n * to check for the existence of a type of error but for a message that does not match\n * is to use `and`.\n *\n * expect(fn).to.throw(ReferenceError)\n * .and.not.throw(/good function/);\n *\n * @name throw\n * @alias throws\n * @alias Throw\n * @param {ErrorConstructor} constructor\n * @param {String|RegExp} expected error message\n * @param {String} message _optional_\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @returns error for chaining (null if no error)\n * @namespace BDD\n * @api public\n */\n\n function assertThrows (constructor, errMsg, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('function');\n\n var thrown = false\n , desiredError = null\n , name = null\n , thrownError = null;\n\n if (arguments.length === 0) {\n errMsg = null;\n constructor = null;\n } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n errMsg = constructor;\n constructor = null;\n } else if (constructor && constructor instanceof Error) {\n desiredError = constructor;\n constructor = null;\n errMsg = null;\n } else if (typeof constructor === 'function') {\n name = constructor.prototype.name;\n if (!name || (name === 'Error' && constructor !== Error)) {\n name = constructor.name || (new constructor()).name;\n }\n } else {\n constructor = null;\n }\n\n try {\n obj();\n } catch (err) {\n // first, check desired error\n if (desiredError) {\n this.assert(\n err === desiredError\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp}'\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (err instanceof Error ? err.toString() : err)\n );\n\n flag(this, 'object', err);\n return this;\n }\n\n // next, check constructor\n if (constructor) {\n this.assert(\n err instanceof constructor\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n , name\n , (err instanceof Error ? err.toString() : err)\n );\n\n if (!errMsg) {\n flag(this, 'object', err);\n return this;\n }\n }\n\n // next, check message\n var message = 'error' === _.type(err) && \"message\" in err\n ? err.message\n : '' + err;\n\n if ((message != null) && errMsg && errMsg instanceof RegExp) {\n this.assert(\n errMsg.exec(message)\n , 'expected #{this} to throw error matching #{exp} but got #{act}'\n , 'expected #{this} to throw error not matching #{exp}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n this.assert(\n ~message.indexOf(errMsg)\n , 'expected #{this} to throw error including #{exp} but got #{act}'\n , 'expected #{this} to throw error not including #{act}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else {\n thrown = true;\n thrownError = err;\n }\n }\n\n var actuallyGot = ''\n , expectedThrown = name !== null\n ? name\n : desiredError\n ? '#{exp}' //_.inspect(desiredError)\n : 'an error';\n\n if (thrown) {\n actuallyGot = ' but #{act} was thrown'\n }\n\n this.assert(\n thrown === true\n , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n );\n\n flag(this, 'object', thrownError);\n };\n\n Assertion.addMethod('throw', assertThrows);\n Assertion.addMethod('throws', assertThrows);\n Assertion.addMethod('Throw', assertThrows);\n\n /**\n * ### .respondTo(method)\n *\n * Asserts that the object or class target will respond to a method.\n *\n * Klass.prototype.bar = function(){};\n * expect(Klass).to.respondTo('bar');\n * expect(obj).to.respondTo('bar');\n *\n * To check if a constructor will respond to a static function,\n * set the `itself` flag.\n *\n * Klass.baz = function(){};\n * expect(Klass).itself.to.respondTo('baz');\n *\n * @name respondTo\n * @alias respondsTo\n * @param {String} method\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function respondTo (method, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , itself = flag(this, 'itself')\n , context = ('function' === _.type(obj) && !itself)\n ? obj.prototype[method]\n : obj[method];\n\n this.assert(\n 'function' === typeof context\n , 'expected #{this} to respond to ' + _.inspect(method)\n , 'expected #{this} to not respond to ' + _.inspect(method)\n );\n }\n\n Assertion.addMethod('respondTo', respondTo);\n Assertion.addMethod('respondsTo', respondTo);\n\n /**\n * ### .itself\n *\n * Sets the `itself` flag, later used by the `respondTo` assertion.\n *\n * function Foo() {}\n * Foo.bar = function() {}\n * Foo.prototype.baz = function() {}\n *\n * expect(Foo).itself.to.respondTo('bar');\n * expect(Foo).itself.not.to.respondTo('baz');\n *\n * @name itself\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('itself', function () {\n flag(this, 'itself', true);\n });\n\n /**\n * ### .satisfy(method)\n *\n * Asserts that the target passes a given truth test.\n *\n * expect(1).to.satisfy(function(num) { return num > 0; });\n *\n * @name satisfy\n * @alias satisfies\n * @param {Function} matcher\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function satisfy (matcher, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var result = matcher(obj);\n this.assert(\n result\n , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n , this.negate ? false : true\n , result\n );\n }\n\n Assertion.addMethod('satisfy', satisfy);\n Assertion.addMethod('satisfies', satisfy);\n\n /**\n * ### .closeTo(expected, delta)\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * expect(1.5).to.be.closeTo(1, 0.5);\n *\n * @name closeTo\n * @alias approximately\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function closeTo(expected, delta, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj, msg).is.a('number');\n if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n throw new Error('the arguments to closeTo or approximately must be numbers');\n }\n\n this.assert(\n Math.abs(obj - expected) <= delta\n , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n );\n }\n\n Assertion.addMethod('closeTo', closeTo);\n Assertion.addMethod('approximately', closeTo);\n\n function isSubsetOf(subset, superset, cmp) {\n return subset.every(function(elem) {\n if (!cmp) return superset.indexOf(elem) !== -1;\n\n return superset.some(function(elem2) {\n return cmp(elem, elem2);\n });\n })\n }\n\n /**\n * ### .members(set)\n *\n * Asserts that the target is a superset of `set`,\n * or that the target and `set` have the same strictly-equal (===) members.\n * Alternately, if the `deep` flag is set, set members are compared for deep\n * equality.\n *\n * expect([1, 2, 3]).to.include.members([3, 2]);\n * expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n *\n * expect([4, 2]).to.have.members([2, 4]);\n * expect([5, 2]).to.not.have.members([5, 2, 1]);\n *\n * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n *\n * @name members\n * @param {Array} set\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('members', function (subset, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj).to.be.an('array');\n new Assertion(subset).to.be.an('array');\n\n var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n if (flag(this, 'contains')) {\n return this.assert(\n isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to be a superset of #{act}'\n , 'expected #{this} to not be a superset of #{act}'\n , obj\n , subset\n );\n }\n\n this.assert(\n isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to have the same members as #{act}'\n , 'expected #{this} to not have the same members as #{act}'\n , obj\n , subset\n );\n });\n\n /**\n * ### .oneOf(list)\n *\n * Assert that a value appears somewhere in the top level of array `list`.\n *\n * expect('a').to.be.oneOf(['a', 'b', 'c']);\n * expect(9).to.not.be.oneOf(['z']);\n * expect([3]).to.not.be.oneOf([1, 2, [3]]);\n *\n * var three = [3];\n * // for object-types, contents are not compared\n * expect(three).to.not.be.oneOf([1, 2, [3]]);\n * // comparing references works\n * expect(three).to.be.oneOf([1, 2, three]);\n *\n * @name oneOf\n * @param {Array<*>} list\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function oneOf (list, msg) {\n if (msg) flag(this, 'message', msg);\n var expected = flag(this, 'object');\n new Assertion(list).to.be.an('array');\n\n this.assert(\n list.indexOf(expected) > -1\n , 'expected #{this} to be one of #{exp}'\n , 'expected #{this} to not be one of #{exp}'\n , list\n , expected\n );\n }\n\n Assertion.addMethod('oneOf', oneOf);\n\n\n /**\n * ### .change(function)\n *\n * Asserts that a function changes an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val += 3 };\n * var noChangeFn = function() { return 'foo' + 'bar'; }\n * expect(fn).to.change(obj, 'val');\n * expect(noChangeFn).to.not.change(obj, 'val')\n *\n * @name change\n * @alias changes\n * @alias Change\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertChanges (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n initial !== object[prop]\n , 'expected .' + prop + ' to change'\n , 'expected .' + prop + ' to not change'\n );\n }\n\n Assertion.addChainableMethod('change', assertChanges);\n Assertion.addChainableMethod('changes', assertChanges);\n\n /**\n * ### .increase(function)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * expect(fn).to.increase(obj, 'val');\n *\n * @name increase\n * @alias increases\n * @alias Increase\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertIncreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial > 0\n , 'expected .' + prop + ' to increase'\n , 'expected .' + prop + ' to not increase'\n );\n }\n\n Assertion.addChainableMethod('increase', assertIncreases);\n Assertion.addChainableMethod('increases', assertIncreases);\n\n /**\n * ### .decrease(function)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * expect(fn).to.decrease(obj, 'val');\n *\n * @name decrease\n * @alias decreases\n * @alias Decrease\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertDecreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial < 0\n , 'expected .' + prop + ' to decrease'\n , 'expected .' + prop + ' to not decrease'\n );\n }\n\n Assertion.addChainableMethod('decrease', assertDecreases);\n Assertion.addChainableMethod('decreases', assertDecreases);\n\n /**\n * ### .extensible\n *\n * Asserts that the target is extensible (can have new properties added to\n * it).\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect({}).to.be.extensible;\n * expect(nonExtensibleObject).to.not.be.extensible;\n * expect(sealedObject).to.not.be.extensible;\n * expect(frozenObject).to.not.be.extensible;\n *\n * @name extensible\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('extensible', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isExtensible;\n\n try {\n isExtensible = Object.isExtensible(obj);\n } catch (err) {\n if (err instanceof TypeError) isExtensible = false;\n else throw err;\n }\n\n this.assert(\n isExtensible\n , 'expected #{this} to be extensible'\n , 'expected #{this} to not be extensible'\n );\n });\n\n /**\n * ### .sealed\n *\n * Asserts that the target is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect(sealedObject).to.be.sealed;\n * expect(frozenObject).to.be.sealed;\n * expect({}).to.not.be.sealed;\n *\n * @name sealed\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('sealed', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isSealed;\n\n try {\n isSealed = Object.isSealed(obj);\n } catch (err) {\n if (err instanceof TypeError) isSealed = true;\n else throw err;\n }\n\n this.assert(\n isSealed\n , 'expected #{this} to be sealed'\n , 'expected #{this} to not be sealed'\n );\n });\n\n /**\n * ### .frozen\n *\n * Asserts that the target is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n *\n * expect(frozenObject).to.be.frozen;\n * expect({}).to.not.be.frozen;\n *\n * @name frozen\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('frozen', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isFrozen;\n\n try {\n isFrozen = Object.isFrozen(obj);\n } catch (err) {\n if (err instanceof TypeError) isFrozen = true;\n else throw err;\n }\n\n this.assert(\n isFrozen\n , 'expected #{this} to be frozen'\n , 'expected #{this} to not be frozen'\n );\n });\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n /*!\n * Chai dependencies.\n */\n\n var Assertion = chai.Assertion\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n /**\n * ### assert(expression, message)\n *\n * Write your own test expressions.\n *\n * assert('foo' !== 'bar', 'foo is not bar');\n * assert(Array.isArray([]), 'empty arrays are arrays');\n *\n * @param {Mixed} expression to test for truthiness\n * @param {String} message to display on error\n * @name assert\n * @namespace Assert\n * @api public\n */\n\n var assert = chai.assert = function (express, errmsg) {\n var test = new Assertion(null, null, chai.assert);\n test.assert(\n express\n , errmsg\n , '[ negation message unavailable ]'\n );\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure. Node.js `assert` module-compatible.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Assert\n * @api public\n */\n\n assert.fail = function (actual, expected, message, operator) {\n message = message || 'assert.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, assert.fail);\n };\n\n /**\n * ### .isOk(object, [message])\n *\n * Asserts that `object` is truthy.\n *\n * assert.isOk('everything', 'everything is ok');\n * assert.isOk(false, 'this will fail');\n *\n * @name isOk\n * @alias ok\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isOk = function (val, msg) {\n new Assertion(val, msg).is.ok;\n };\n\n /**\n * ### .isNotOk(object, [message])\n *\n * Asserts that `object` is falsy.\n *\n * assert.isNotOk('everything', 'this will fail');\n * assert.isNotOk(false, 'this will pass');\n *\n * @name isNotOk\n * @alias notOk\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotOk = function (val, msg) {\n new Assertion(val, msg).is.not.ok;\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * assert.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.equal = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.equal);\n\n test.assert(\n exp == flag(test, 'object')\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .notEqual(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * assert.notEqual(3, 4, 'these numbers are not equal');\n *\n * @name notEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notEqual = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.notEqual);\n\n test.assert(\n exp != flag(test, 'object')\n , 'expected #{this} to not equal #{exp}'\n , 'expected #{this} to equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .strictEqual(actual, expected, [message])\n *\n * Asserts strict equality (`===`) of `actual` and `expected`.\n *\n * assert.strictEqual(true, true, 'these booleans are strictly equal');\n *\n * @name strictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.strictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.equal(exp);\n };\n\n /**\n * ### .notStrictEqual(actual, expected, [message])\n *\n * Asserts strict inequality (`!==`) of `actual` and `expected`.\n *\n * assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n *\n * @name notStrictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notStrictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.equal(exp);\n };\n\n /**\n * ### .deepEqual(actual, expected, [message])\n *\n * Asserts that `actual` is deeply equal to `expected`.\n *\n * assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n *\n * @name deepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.eql(exp);\n };\n\n /**\n * ### .notDeepEqual(actual, expected, [message])\n *\n * Assert that `actual` is not deeply equal to `expected`.\n *\n * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n *\n * @name notDeepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.eql(exp);\n };\n\n /**\n * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n *\n * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n *\n * assert.isAbove(5, 2, '5 is strictly greater than 2');\n *\n * @name isAbove\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAbove\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAbove = function (val, abv, msg) {\n new Assertion(val, msg).to.be.above(abv);\n };\n\n /**\n * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n *\n * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n *\n * assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n * assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n *\n * @name isAtLeast\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtLeast\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtLeast = function (val, atlst, msg) {\n new Assertion(val, msg).to.be.least(atlst);\n };\n\n /**\n * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n *\n * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n *\n * assert.isBelow(3, 6, '3 is strictly less than 6');\n *\n * @name isBelow\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeBelow\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBelow = function (val, blw, msg) {\n new Assertion(val, msg).to.be.below(blw);\n };\n\n /**\n * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n *\n * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n *\n * assert.isAtMost(3, 6, '3 is less than or equal to 6');\n * assert.isAtMost(4, 4, '4 is less than or equal to 4');\n *\n * @name isAtMost\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtMost\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtMost = function (val, atmst, msg) {\n new Assertion(val, msg).to.be.most(atmst);\n };\n\n /**\n * ### .isTrue(value, [message])\n *\n * Asserts that `value` is true.\n *\n * var teaServed = true;\n * assert.isTrue(teaServed, 'the tea has been served');\n *\n * @name isTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isTrue = function (val, msg) {\n new Assertion(val, msg).is['true'];\n };\n\n /**\n * ### .isNotTrue(value, [message])\n *\n * Asserts that `value` is not true.\n *\n * var tea = 'tasty chai';\n * assert.isNotTrue(tea, 'great, time for tea!');\n *\n * @name isNotTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotTrue = function (val, msg) {\n new Assertion(val, msg).to.not.equal(true);\n };\n\n /**\n * ### .isFalse(value, [message])\n *\n * Asserts that `value` is false.\n *\n * var teaServed = false;\n * assert.isFalse(teaServed, 'no tea yet? hmm...');\n *\n * @name isFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFalse = function (val, msg) {\n new Assertion(val, msg).is['false'];\n };\n\n /**\n * ### .isNotFalse(value, [message])\n *\n * Asserts that `value` is not false.\n *\n * var tea = 'tasty chai';\n * assert.isNotFalse(tea, 'great, time for tea!');\n *\n * @name isNotFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFalse = function (val, msg) {\n new Assertion(val, msg).to.not.equal(false);\n };\n\n /**\n * ### .isNull(value, [message])\n *\n * Asserts that `value` is null.\n *\n * assert.isNull(err, 'there was no error');\n *\n * @name isNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNull = function (val, msg) {\n new Assertion(val, msg).to.equal(null);\n };\n\n /**\n * ### .isNotNull(value, [message])\n *\n * Asserts that `value` is not null.\n *\n * var tea = 'tasty chai';\n * assert.isNotNull(tea, 'great, time for tea!');\n *\n * @name isNotNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNull = function (val, msg) {\n new Assertion(val, msg).to.not.equal(null);\n };\n\n /**\n * ### .isNaN\n * Asserts that value is NaN\n *\n * assert.isNaN('foo', 'foo is NaN');\n *\n * @name isNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNaN = function (val, msg) {\n new Assertion(val, msg).to.be.NaN;\n };\n\n /**\n * ### .isNotNaN\n * Asserts that value is not NaN\n *\n * assert.isNotNaN(4, '4 is not NaN');\n *\n * @name isNotNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n assert.isNotNaN = function (val, msg) {\n new Assertion(val, msg).not.to.be.NaN;\n };\n\n /**\n * ### .isUndefined(value, [message])\n *\n * Asserts that `value` is `undefined`.\n *\n * var tea;\n * assert.isUndefined(tea, 'no tea defined');\n *\n * @name isUndefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isUndefined = function (val, msg) {\n new Assertion(val, msg).to.equal(undefined);\n };\n\n /**\n * ### .isDefined(value, [message])\n *\n * Asserts that `value` is not `undefined`.\n *\n * var tea = 'cup of chai';\n * assert.isDefined(tea, 'tea has been defined');\n *\n * @name isDefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isDefined = function (val, msg) {\n new Assertion(val, msg).to.not.equal(undefined);\n };\n\n /**\n * ### .isFunction(value, [message])\n *\n * Asserts that `value` is a function.\n *\n * function serveTea() { return 'cup of tea'; };\n * assert.isFunction(serveTea, 'great, we can have tea now');\n *\n * @name isFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFunction = function (val, msg) {\n new Assertion(val, msg).to.be.a('function');\n };\n\n /**\n * ### .isNotFunction(value, [message])\n *\n * Asserts that `value` is _not_ a function.\n *\n * var serveTea = [ 'heat', 'pour', 'sip' ];\n * assert.isNotFunction(serveTea, 'great, we have listed the steps');\n *\n * @name isNotFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFunction = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('function');\n };\n\n /**\n * ### .isObject(value, [message])\n *\n * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n * _The assertion does not match subclassed objects._\n *\n * var selection = { name: 'Chai', serve: 'with spices' };\n * assert.isObject(selection, 'tea selection is an object');\n *\n * @name isObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isObject = function (val, msg) {\n new Assertion(val, msg).to.be.a('object');\n };\n\n /**\n * ### .isNotObject(value, [message])\n *\n * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n *\n * var selection = 'chai'\n * assert.isNotObject(selection, 'tea selection is not an object');\n * assert.isNotObject(null, 'null is not an object');\n *\n * @name isNotObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotObject = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('object');\n };\n\n /**\n * ### .isArray(value, [message])\n *\n * Asserts that `value` is an array.\n *\n * var menu = [ 'green', 'chai', 'oolong' ];\n * assert.isArray(menu, 'what kind of tea do we want?');\n *\n * @name isArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isArray = function (val, msg) {\n new Assertion(val, msg).to.be.an('array');\n };\n\n /**\n * ### .isNotArray(value, [message])\n *\n * Asserts that `value` is _not_ an array.\n *\n * var menu = 'green|chai|oolong';\n * assert.isNotArray(menu, 'what kind of tea do we want?');\n *\n * @name isNotArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotArray = function (val, msg) {\n new Assertion(val, msg).to.not.be.an('array');\n };\n\n /**\n * ### .isString(value, [message])\n *\n * Asserts that `value` is a string.\n *\n * var teaOrder = 'chai';\n * assert.isString(teaOrder, 'order placed');\n *\n * @name isString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isString = function (val, msg) {\n new Assertion(val, msg).to.be.a('string');\n };\n\n /**\n * ### .isNotString(value, [message])\n *\n * Asserts that `value` is _not_ a string.\n *\n * var teaOrder = 4;\n * assert.isNotString(teaOrder, 'order placed');\n *\n * @name isNotString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotString = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('string');\n };\n\n /**\n * ### .isNumber(value, [message])\n *\n * Asserts that `value` is a number.\n *\n * var cups = 2;\n * assert.isNumber(cups, 'how many cups');\n *\n * @name isNumber\n * @param {Number} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNumber = function (val, msg) {\n new Assertion(val, msg).to.be.a('number');\n };\n\n /**\n * ### .isNotNumber(value, [message])\n *\n * Asserts that `value` is _not_ a number.\n *\n * var cups = '2 cups please';\n * assert.isNotNumber(cups, 'how many cups');\n *\n * @name isNotNumber\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNumber = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('number');\n };\n\n /**\n * ### .isBoolean(value, [message])\n *\n * Asserts that `value` is a boolean.\n *\n * var teaReady = true\n * , teaServed = false;\n *\n * assert.isBoolean(teaReady, 'is the tea ready');\n * assert.isBoolean(teaServed, 'has tea been served');\n *\n * @name isBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBoolean = function (val, msg) {\n new Assertion(val, msg).to.be.a('boolean');\n };\n\n /**\n * ### .isNotBoolean(value, [message])\n *\n * Asserts that `value` is _not_ a boolean.\n *\n * var teaReady = 'yep'\n * , teaServed = 'nope';\n *\n * assert.isNotBoolean(teaReady, 'is the tea ready');\n * assert.isNotBoolean(teaServed, 'has tea been served');\n *\n * @name isNotBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotBoolean = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('boolean');\n };\n\n /**\n * ### .typeOf(value, name, [message])\n *\n * Asserts that `value`'s type is `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n * assert.typeOf('tea', 'string', 'we have a string');\n * assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n * assert.typeOf(null, 'null', 'we have a null');\n * assert.typeOf(undefined, 'undefined', 'we have an undefined');\n *\n * @name typeOf\n * @param {Mixed} value\n * @param {String} name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.typeOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.a(type);\n };\n\n /**\n * ### .notTypeOf(value, name, [message])\n *\n * Asserts that `value`'s type is _not_ `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.notTypeOf('tea', 'number', 'strings are not numbers');\n *\n * @name notTypeOf\n * @param {Mixed} value\n * @param {String} typeof name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notTypeOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.a(type);\n };\n\n /**\n * ### .instanceOf(object, constructor, [message])\n *\n * Asserts that `value` is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new Tea('chai');\n *\n * assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n *\n * @name instanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.instanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.instanceOf(type);\n };\n\n /**\n * ### .notInstanceOf(object, constructor, [message])\n *\n * Asserts `value` is not an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new String('chai');\n *\n * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n *\n * @name notInstanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInstanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.instanceOf(type);\n };\n\n /**\n * ### .include(haystack, needle, [message])\n *\n * Asserts that `haystack` includes `needle`. Works\n * for strings and arrays.\n *\n * assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n * assert.include([ 1, 2, 3 ], 3, 'array contains value');\n *\n * @name include\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.include = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.include).include(inc);\n };\n\n /**\n * ### .notInclude(haystack, needle, [message])\n *\n * Asserts that `haystack` does not include `needle`. Works\n * for strings and arrays.\n *\n * assert.notInclude('foobar', 'baz', 'string not include substring');\n * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n *\n * @name notInclude\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInclude = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.notInclude).not.include(inc);\n };\n\n /**\n * ### .match(value, regexp, [message])\n *\n * Asserts that `value` matches the regular expression `regexp`.\n *\n * assert.match('foobar', /^foo/, 'regexp matches');\n *\n * @name match\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.match = function (exp, re, msg) {\n new Assertion(exp, msg).to.match(re);\n };\n\n /**\n * ### .notMatch(value, regexp, [message])\n *\n * Asserts that `value` does not match the regular expression `regexp`.\n *\n * assert.notMatch('foobar', /^foo/, 'regexp does not match');\n *\n * @name notMatch\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notMatch = function (exp, re, msg) {\n new Assertion(exp, msg).to.not.match(re);\n };\n\n /**\n * ### .property(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`.\n *\n * assert.property({ tea: { green: 'matcha' }}, 'tea');\n *\n * @name property\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.property = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.property(prop);\n };\n\n /**\n * ### .notProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`.\n *\n * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n *\n * @name notProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.property(prop);\n };\n\n /**\n * ### .deepProperty(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`, which can be a\n * string using dot- and bracket-notation for deep reference.\n *\n * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n *\n * @name deepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop);\n };\n\n /**\n * ### .notDeepProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`, which\n * can be a string using dot- and bracket-notation for deep reference.\n *\n * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n *\n * @name notDeepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop);\n };\n\n /**\n * ### .propertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`.\n *\n * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n *\n * @name propertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.property(prop, val);\n };\n\n /**\n * ### .propertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`.\n *\n * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n *\n * @name propertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.property(prop, val);\n };\n\n /**\n * ### .deepPropertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`. `property` can use dot- and bracket-notation for deep\n * reference.\n *\n * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n *\n * @name deepPropertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop, val);\n };\n\n /**\n * ### .deepPropertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`. `property` can use dot- and\n * bracket-notation for deep reference.\n *\n * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n *\n * @name deepPropertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n };\n\n /**\n * ### .lengthOf(object, length, [message])\n *\n * Asserts that `object` has a `length` property with the expected value.\n *\n * assert.lengthOf([1,2,3], 3, 'array has length of 3');\n * assert.lengthOf('foobar', 6, 'string has length of 6');\n *\n * @name lengthOf\n * @param {Mixed} object\n * @param {Number} length\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.lengthOf = function (exp, len, msg) {\n new Assertion(exp, msg).to.have.length(len);\n };\n\n /**\n * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * assert.throws(fn, 'function throws a reference error');\n * assert.throws(fn, /function throws a reference error/);\n * assert.throws(fn, ReferenceError);\n * assert.throws(fn, ReferenceError, 'function throws a reference error');\n * assert.throws(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throws\n * @alias throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.throws = function (fn, errt, errs, msg) {\n if ('string' === typeof errt || errt instanceof RegExp) {\n errs = errt;\n errt = null;\n }\n\n var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n return flag(assertErr, 'object');\n };\n\n /**\n * ### .doesNotThrow(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * assert.doesNotThrow(fn, Error, 'function does not throw');\n *\n * @name doesNotThrow\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotThrow = function (fn, type, msg) {\n if ('string' === typeof type) {\n msg = type;\n type = null;\n }\n\n new Assertion(fn, msg).to.not.Throw(type);\n };\n\n /**\n * ### .operator(val1, operator, val2, [message])\n *\n * Compares two values using `operator`.\n *\n * assert.operator(1, '<', 2, 'everything is ok');\n * assert.operator(1, '>', 2, 'this will fail');\n *\n * @name operator\n * @param {Mixed} val1\n * @param {String} operator\n * @param {Mixed} val2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.operator = function (val, operator, val2, msg) {\n var ok;\n switch(operator) {\n case '==':\n ok = val == val2;\n break;\n case '===':\n ok = val === val2;\n break;\n case '>':\n ok = val > val2;\n break;\n case '>=':\n ok = val >= val2;\n break;\n case '<':\n ok = val < val2;\n break;\n case '<=':\n ok = val <= val2;\n break;\n case '!=':\n ok = val != val2;\n break;\n case '!==':\n ok = val !== val2;\n break;\n default:\n throw new Error('Invalid operator \"' + operator + '\"');\n }\n var test = new Assertion(ok, msg);\n test.assert(\n true === flag(test, 'object')\n , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n };\n\n /**\n * ### .closeTo(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n *\n * @name closeTo\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.closeTo = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.closeTo(exp, delta);\n };\n\n /**\n * ### .approximately(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.approximately(1.5, 1, 0.5, 'numbers are close');\n *\n * @name approximately\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.approximately = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.approximately(exp, delta);\n };\n\n /**\n * ### .sameMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members.\n * Order is not taken into account.\n *\n * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n *\n * @name sameMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.members(set2);\n }\n\n /**\n * ### .sameDeepMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n * Order is not taken into account.\n *\n * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n *\n * @name sameDeepMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameDeepMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.deep.members(set2);\n }\n\n /**\n * ### .includeMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset`.\n * Order is not taken into account.\n *\n * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n *\n * @name includeMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.members(subset);\n }\n\n /**\n * ### .includeDeepMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset` - using deep equality checking.\n * Order is not taken into account.\n * Duplicates are ignored.\n *\n * assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n *\n * @name includeDeepMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeDeepMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.deep.members(subset);\n }\n\n /**\n * ### .oneOf(inList, list, [message])\n *\n * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n *\n * assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n *\n * @name oneOf\n * @param {*} inList\n * @param {Array<*>} list\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.oneOf = function (inList, list, msg) {\n new Assertion(inList, msg).to.be.oneOf(list);\n }\n\n /**\n * ### .changes(function, object, property)\n *\n * Asserts that a function changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 22 };\n * assert.changes(fn, obj, 'val');\n *\n * @name changes\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.changes = function (fn, obj, prop) {\n new Assertion(fn).to.change(obj, prop);\n }\n\n /**\n * ### .doesNotChange(function, object, property)\n *\n * Asserts that a function does not changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { console.log('foo'); };\n * assert.doesNotChange(fn, obj, 'val');\n *\n * @name doesNotChange\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotChange = function (fn, obj, prop) {\n new Assertion(fn).to.not.change(obj, prop);\n }\n\n /**\n * ### .increases(function, object, property)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 13 };\n * assert.increases(fn, obj, 'val');\n *\n * @name increases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.increases = function (fn, obj, prop) {\n new Assertion(fn).to.increase(obj, prop);\n }\n\n /**\n * ### .doesNotIncrease(function, object, property)\n *\n * Asserts that a function does not increase object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 8 };\n * assert.doesNotIncrease(fn, obj, 'val');\n *\n * @name doesNotIncrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotIncrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.increase(obj, prop);\n }\n\n /**\n * ### .decreases(function, object, property)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * assert.decreases(fn, obj, 'val');\n *\n * @name decreases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.decreases = function (fn, obj, prop) {\n new Assertion(fn).to.decrease(obj, prop);\n }\n\n /**\n * ### .doesNotDecrease(function, object, property)\n *\n * Asserts that a function does not decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * assert.doesNotDecrease(fn, obj, 'val');\n *\n * @name doesNotDecrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotDecrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.decrease(obj, prop);\n }\n\n /*!\n * ### .ifError(object)\n *\n * Asserts if value is not a false value, and throws if it is a true value.\n * This is added to allow for chai to be a drop-in replacement for Node's\n * assert class.\n *\n * var err = new Error('I am a custom error');\n * assert.ifError(err); // Rethrows err!\n *\n * @name ifError\n * @param {Object} object\n * @namespace Assert\n * @api public\n */\n\n assert.ifError = function (val) {\n if (val) {\n throw(val);\n }\n };\n\n /**\n * ### .isExtensible(object)\n *\n * Asserts that `object` is extensible (can have new properties added to it).\n *\n * assert.isExtensible({});\n *\n * @name isExtensible\n * @alias extensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.be.extensible;\n };\n\n /**\n * ### .isNotExtensible(object)\n *\n * Asserts that `object` is _not_ extensible.\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freese({});\n *\n * assert.isNotExtensible(nonExtensibleObject);\n * assert.isNotExtensible(sealedObject);\n * assert.isNotExtensible(frozenObject);\n *\n * @name isNotExtensible\n * @alias notExtensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.extensible;\n };\n\n /**\n * ### .isSealed(object)\n *\n * Asserts that `object` is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.seal({});\n *\n * assert.isSealed(sealedObject);\n * assert.isSealed(frozenObject);\n *\n * @name isSealed\n * @alias sealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isSealed = function (obj, msg) {\n new Assertion(obj, msg).to.be.sealed;\n };\n\n /**\n * ### .isNotSealed(object)\n *\n * Asserts that `object` is _not_ sealed.\n *\n * assert.isNotSealed({});\n *\n * @name isNotSealed\n * @alias notSealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotSealed = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.sealed;\n };\n\n /**\n * ### .isFrozen(object)\n *\n * Asserts that `object` is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n * assert.frozen(frozenObject);\n *\n * @name isFrozen\n * @alias frozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.be.frozen;\n };\n\n /**\n * ### .isNotFrozen(object)\n *\n * Asserts that `object` is _not_ frozen.\n *\n * assert.isNotFrozen({});\n *\n * @name isNotFrozen\n * @alias notFrozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.frozen;\n };\n\n /*!\n * Aliases.\n */\n\n (function alias(name, as){\n assert[as] = assert[name];\n return alias;\n })\n ('isOk', 'ok')\n ('isNotOk', 'notOk')\n ('throws', 'throw')\n ('throws', 'Throw')\n ('isExtensible', 'extensible')\n ('isNotExtensible', 'notExtensible')\n ('isSealed', 'sealed')\n ('isNotSealed', 'notSealed')\n ('isFrozen', 'frozen')\n ('isNotFrozen', 'notFrozen');\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n chai.expect = function (val, message) {\n return new chai.Assertion(val, message);\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Expect\n * @api public\n */\n\n chai.expect.fail = function (actual, expected, message, operator) {\n message = message || 'expect.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, chai.expect.fail);\n };\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n var Assertion = chai.Assertion;\n\n function loadShould () {\n // explicitly define this method as function as to have it's name to include as `ssfi`\n function shouldGetter() {\n if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n return new Assertion(this.valueOf(), null, shouldGetter);\n }\n return new Assertion(this, null, shouldGetter);\n }\n function shouldSetter(value) {\n // See https://github.com/chaijs/chai/issues/86: this makes\n // `whatever.should = someValue` actually set `someValue`, which is\n // especially useful for `global.should = require('chai').should()`.\n //\n // Note that we have to use [[DefineProperty]] instead of [[Put]]\n // since otherwise we would trigger this very setter!\n Object.defineProperty(this, 'should', {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n }\n // modify Object.prototype to have `should`\n Object.defineProperty(Object.prototype, 'should', {\n set: shouldSetter\n , get: shouldGetter\n , configurable: true\n });\n\n var should = {};\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Should\n * @api public\n */\n\n should.fail = function (actual, expected, message, operator) {\n message = message || 'should.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, should.fail);\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * should.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * should.throw(fn, 'function throws a reference error');\n * should.throw(fn, /function throws a reference error/);\n * should.throw(fn, ReferenceError);\n * should.throw(fn, ReferenceError, 'function throws a reference error');\n * should.throw(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.Throw(errt, errs);\n };\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi';\n *\n * should.exist(foo, 'foo exists');\n *\n * @name exist\n * @namespace Should\n * @api public\n */\n\n should.exist = function (val, msg) {\n new Assertion(val, msg).to.exist;\n }\n\n // negation\n should.not = {}\n\n /**\n * ### .not.equal(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * should.not.equal(3, 4, 'these numbers are not equal');\n *\n * @name not.equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.not.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.not.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * should.not.throw(fn, Error, 'function does not throw');\n *\n * @name not.throw\n * @alias not.Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.not.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.not.Throw(errt, errs);\n };\n\n /**\n * ### .not.exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var bar = null;\n *\n * should.not.exist(bar, 'bar does not exist');\n *\n * @name not.exist\n * @namespace Should\n * @api public\n */\n\n should.not.exist = function (val, msg) {\n new Assertion(val, msg).to.not.exist;\n }\n\n should['throw'] = should['Throw'];\n should.not['throw'] = should.not['Throw'];\n\n return should;\n };\n\n chai.should = loadShould;\n chai.Should = loadShould;\n};\n","/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call = Function.prototype.call,\n apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n * expect(fooStr).to.be.foo('bar');\n * expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n if (typeof chainingBehavior !== 'function') {\n chainingBehavior = function () { };\n }\n\n var chainableBehavior = {\n method: method\n , chainingBehavior: chainingBehavior\n };\n\n // save the methods so we can overwrite them later, if we need to.\n if (!ctx.__methods) {\n ctx.__methods = {};\n }\n ctx.__methods[name] = chainableBehavior;\n\n Object.defineProperty(ctx, name,\n { get: function () {\n chainableBehavior.chainingBehavior.call(this);\n\n var assert = function assert() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', assert);\n var result = chainableBehavior.method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n\n // Use `__proto__` if available\n if (hasProtoSupport) {\n // Inherit all properties from the object by replacing the `Function` prototype\n var prototype = assert.__proto__ = Object.create(this);\n // Restore the `call` and `apply` methods from `Function`\n prototype.call = call;\n prototype.apply = apply;\n }\n // Otherwise, redefine all properties (slow!)\n else {\n var asserterNames = Object.getOwnPropertyNames(ctx);\n asserterNames.forEach(function (asserterName) {\n if (!excludeNames.test(asserterName)) {\n var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n Object.defineProperty(assert, asserterName, pd);\n }\n });\n }\n\n transferFlags(this, assert);\n return assert;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n ctx[name] = function () {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', ctx[name]);\n var result = method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n * utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.instanceof(Foo);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n Object.defineProperty(ctx, name,\n { get: function addProperty() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', addProperty);\n\n var result = getter.call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n * utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n var obj = flag(obj, 'object');\n types = types.map(function (t) { return t.toLowerCase(); });\n types.sort();\n\n // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n var str = types.map(function (t, index) {\n var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n return or + art + ' ' + t;\n }).join(', ');\n\n if (!types.some(function (expected) { return type(obj) === expected; })) {\n throw new AssertionError(\n 'object tested must be ' + str + ', but ' + type(obj) + ' given'\n );\n }\n};\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n * utils.flag(this, 'foo', 'bar'); // setter\n * utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n var flags = obj.__flags || (obj.__flags = Object.create(null));\n if (arguments.length === 3) {\n flags[key] = value;\n } else {\n return flags[key];\n }\n};\n","/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n return args.length > 4 ? args[4] : obj._obj;\n};\n","/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n var result = [];\n for (var name in object) {\n result.push(name);\n }\n return result;\n};\n","/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n , getActual = require('./getActual')\n , inspect = require('./inspect')\n , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , val = flag(obj, 'object')\n , expected = args[3]\n , actual = getActual(obj, args)\n , msg = negate ? args[2] : args[1]\n , flagMsg = flag(obj, 'message');\n\n if(typeof msg === \"function\") msg = msg();\n msg = msg || '';\n msg = msg\n .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n","/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n if (func.name) return func.name;\n\n var match = /^\\s?function ([^(]*)\\(/.exec(func);\n return match && match[1] ? match[1] : \"\";\n};\n","/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n var parsed = parsePath(path),\n last = parsed[parsed.length - 1];\n\n var info = {\n parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n name: last.p || last.i,\n value: _getPathValue(parsed, obj)\n };\n info.exists = hasProperty(info.name, info.parent);\n\n return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n * var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n return parts.map(function (value) {\n var re = /^\\[(\\d+)\\]$/\n , mArr = re.exec(value);\n if (mArr) return { i: parseFloat(mArr[1]) };\n else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n * var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n var tmp = obj\n , res;\n\n index = (index === undefined ? parsed.length : index);\n\n for (var i = 0, l = index; i < l; i++) {\n var part = parsed[i];\n if (tmp) {\n if ('undefined' !== typeof part.p)\n tmp = tmp[part.p];\n else if ('undefined' !== typeof part.i)\n tmp = tmp[part.i];\n if (i == (l - 1)) res = tmp;\n } else {\n res = undefined;\n }\n }\n return res;\n}\n","/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer \n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n * var obj = {\n * prop1: {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n * , prop2: {\n * arr: [ { nested: 'Universe' } ]\n * , str: 'Hello again!'\n * }\n * }\n *\n * The following would be the results.\n *\n * getPathValue('prop1.str', obj); // Hello\n * getPathValue('prop1.att[2]', obj); // b\n * getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n var info = getPathInfo(path, obj);\n return info.value;\n};\n","/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n var result = Object.getOwnPropertyNames(object);\n\n function addProperty(property) {\n if (result.indexOf(property) === -1) {\n result.push(property);\n }\n }\n\n var proto = Object.getPrototypeOf(object);\n while (proto !== null) {\n Object.getOwnPropertyNames(proto).forEach(addProperty);\n proto = Object.getPrototypeOf(proto);\n }\n\n return result;\n};\n","/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n * var obj = {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n *\n * The following would be the results.\n *\n * hasProperty('str', obj); // true\n * hasProperty('constructor', obj); // true\n * hasProperty('bar', obj); // false\n *\n * hasProperty('length', obj.str); // true\n * hasProperty(1, obj.str); // true\n * hasProperty(5, obj.str); // false\n *\n * hasProperty('length', obj.arr); // true\n * hasProperty(2, obj.arr); // true\n * hasProperty(3, obj.arr); // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n 'number': Number\n , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n var ot = type(obj);\n\n // Bad Object, obviously no props at all\n if(ot === 'null' || ot === 'undefined')\n return false;\n\n // The `in` operator does not work with certain literals\n // box these before the check\n if(literals[ot] && typeof obj !== 'object')\n obj = new literals[ot](obj);\n\n return name in obj;\n};\n","/*!\n * chai\n * Copyright(c) 2011 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n","// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n * properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n * output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n var ctx = {\n showHidden: showHidden,\n seen: [],\n stylize: function (str) { return str; }\n };\n return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n if (typeof HTMLElement === 'object') {\n return object instanceof HTMLElement;\n } else {\n return object &&\n typeof object === 'object' &&\n object.nodeType === 1 &&\n typeof object.nodeName === 'string';\n }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (value && typeof value.inspect === 'function' &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes);\n if (typeof ret !== 'string') {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // If this is a DOM element, try to get the outer HTML.\n if (isDOMElement(value)) {\n if ('outerHTML' in value) {\n return value.outerHTML;\n // This value does not have an outerHTML attribute,\n // it could still be an XML element\n } else {\n // Attempt to serialize it\n try {\n if (document.xmlVersion) {\n var xmlSerializer = new XMLSerializer();\n return xmlSerializer.serializeToString(value);\n } else {\n // Firefox 11- do not support outerHTML\n // It does, however, support innerHTML\n // Use the following to render the element\n var ns = \"http://www.w3.org/1999/xhtml\";\n var container = document.createElementNS(ns, '_');\n\n container.appendChild(value.cloneNode(false));\n html = container.innerHTML\n .replace('><', '>' + value.innerHTML + '<');\n container.innerHTML = '';\n return html;\n }\n } catch (err) {\n // This could be a non-native DOM implementation,\n // continue with the normal flow:\n // printing the element as if it is an object.\n }\n }\n }\n\n // Look up the keys of the object.\n var visibleKeys = getEnumerableProperties(value);\n var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n // Some type of object without properties can be shortcutted.\n // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n // a `stack` plus `description` property; ignore those for consistency.\n if (keys.length === 0 || (isError(value) && (\n (keys.length === 1 && keys[0] === 'stack') ||\n (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n ))) {\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n base = ' [Function' + nameSuffix + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n return formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n switch (typeof value) {\n case 'undefined':\n return ctx.stylize('undefined', 'undefined');\n\n case 'string':\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n\n case 'number':\n if (value === 0 && (1/value) === -Infinity) {\n return ctx.stylize('-0', 'number');\n }\n return ctx.stylize('' + value, 'number');\n\n case 'boolean':\n return ctx.stylize('' + value, 'boolean');\n }\n // For some reason typeof null is \"object\", so special case here.\n if (value === null) {\n return ctx.stylize('null', 'null');\n }\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str;\n if (value.__lookupGetter__) {\n if (value.__lookupGetter__(key)) {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n }\n if (visibleKeys.indexOf(key) < 0) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(value[key]) < 0) {\n if (recurseTimes === null) {\n str = formatValue(ctx, value[key], null);\n } else {\n str = formatValue(ctx, value[key], recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (typeof name === 'undefined') {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n return Array.isArray(ar) ||\n (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n var str = inspect(obj)\n , type = Object.prototype.toString.call(obj);\n\n if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n if (type === '[object Function]') {\n return !obj.name || obj.name === ''\n ? '[Function]'\n : '[Function: ' + obj.name + ']';\n } else if (type === '[object Array]') {\n return '[ Array(' + obj.length + ') ]';\n } else if (type === '[object Object]') {\n var keys = Object.keys(obj)\n , kstr = keys.length > 2\n ? keys.splice(0, 2).join(', ') + ', ...'\n : keys.join(', ');\n return '{ Object (' + kstr + ') }';\n } else {\n return str;\n }\n } else {\n return str;\n }\n};\n","/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property. Must return functions to be used for\n * name.\n *\n * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n * function (_super) {\n * }\n * , function (_super) {\n * }\n * );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.have.length(3);\n * expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n var chainableBehavior = ctx.__methods[name];\n\n var _chainingBehavior = chainableBehavior.chainingBehavior;\n chainableBehavior.chainingBehavior = function () {\n var result = chainingBehavior(_chainingBehavior).call(this);\n return result === undefined ? this : result;\n };\n\n var _method = chainableBehavior.method;\n chainableBehavior.method = function () {\n var result = method(_method).apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n * return function (str) {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.value).to.equal(str);\n * } else {\n * _super.apply(this, arguments);\n * }\n * }\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n var _method = ctx[name]\n , _super = function () { return this; };\n\n if (_method && 'function' === typeof _method)\n _super = _method;\n\n ctx[name] = function () {\n var result = method(_super).apply(this, arguments);\n return result === undefined ? this : result;\n }\n};\n","/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n * return function () {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.name).to.equal('bar');\n * } else {\n * _super.call(this);\n * }\n * }\n * });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n var _get = Object.getOwnPropertyDescriptor(ctx, name)\n , _super = function () {};\n\n if (_get && 'function' === typeof _get.get)\n _super = _get.get\n\n Object.defineProperty(ctx, name,\n { get: function () {\n var result = getter(_super).call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , expr = args[0];\n return negate ? !expr : expr;\n};\n","/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n * var newAssertion = new Assertion();\n * utils.transferFlags(assertion, newAssertion);\n *\n * var anotherAsseriton = new Assertion(myObj);\n * utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n if (!object.__flags) {\n object.__flags = Object.create(null);\n }\n\n includeAll = arguments.length === 3 ? includeAll : true;\n\n for (var flag in flags) {\n if (includeAll ||\n (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n object.__flags[flag] = flags[flag];\n }\n }\n};\n","\"use strict\";\n\nfunction dedent(strings) {\n\n var raw = void 0;\n if (typeof strings === \"string\") {\n // dedent can be used as a plain function\n raw = [strings];\n } else {\n raw = strings.raw;\n }\n\n // first, perform interpolation\n var result = \"\";\n for (var i = 0; i < raw.length; i++) {\n result += raw[i].\n // join lines when there is a suppressed newline\n replace(/\\\\\\n[ \\t]*/g, \"\").\n\n // handle escaped backticks\n replace(/\\\\`/g, \"`\");\n\n if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) {\n result += arguments.length <= i + 1 ? undefined : arguments[i + 1];\n }\n }\n\n // now strip indentation\n var lines = result.split(\"\\n\");\n var mindent = null;\n lines.forEach(function (l) {\n var m = l.match(/^(\\s+)\\S+/);\n if (m) {\n var indent = m[1].length;\n if (!mindent) {\n // this is the first indented line\n mindent = indent;\n } else {\n mindent = Math.min(mindent, indent);\n }\n }\n });\n\n if (mindent !== null) {\n result = lines.map(function (l) {\n return l[0] === \" \" ? l.slice(mindent) : l;\n }).join(\"\\n\");\n }\n\n // dedent eats leading and trailing whitespace too\n result = result.trim();\n\n // handle escaped newlines at the end to ensure they don't get stripped too\n return result.replace(/\\\\n/g, \"\\n\");\n}\n\nif (typeof module !== \"undefined\") {\n module.exports = dedent;\n}\n","module.exports = require('./lib/eql');\n","/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n Buffer = {};\n Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n if (sameValue(a, b)) {\n return true;\n } else if ('date' === type(a)) {\n return dateEqual(a, b);\n } else if ('regexp' === type(a)) {\n return regexpEqual(a, b);\n } else if (Buffer.isBuffer(a)) {\n return bufferEqual(a, b);\n } else if ('arguments' === type(a)) {\n return argumentsEqual(a, b, m);\n } else if (!typeEqual(a, b)) {\n return false;\n } else if (('object' !== type(a) && 'object' !== type(b))\n && ('array' !== type(a) && 'array' !== type(b))) {\n return sameValue(a, b);\n } else {\n return objectEqual(a, b, m);\n }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n if (a === b) return a !== 0 || 1 / a === 1 / b;\n return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n if ('date' !== type(b)) return false;\n return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n if ('regexp' !== type(b)) return false;\n return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n if ('arguments' !== type(b)) return false;\n a = [].slice.call(a);\n b = [].slice.call(b);\n return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n var res = [];\n for (var key in a) res.push(key);\n return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n if (a.length !== b.length) return false;\n\n var i = 0;\n var match = true;\n\n for (; i < a.length; i++) {\n if (a[i] !== b[i]) {\n match = false;\n break;\n }\n }\n\n return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n if (!Buffer.isBuffer(b)) return false;\n return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n if (!isValue(a) || !isValue(b)) {\n return false;\n }\n\n if (a.prototype !== b.prototype) {\n return false;\n }\n\n var i;\n if (m) {\n for (i = 0; i < m.length; i++) {\n if ((m[i][0] === a && m[i][1] === b)\n || (m[i][0] === b && m[i][1] === a)) {\n return true;\n }\n }\n } else {\n m = [];\n }\n\n try {\n var ka = enumerable(a);\n var kb = enumerable(b);\n } catch (ex) {\n return false;\n }\n\n ka.sort();\n kb.sort();\n\n if (!iterableEqual(ka, kb)) {\n return false;\n }\n\n m.push([ a, b ]);\n\n var key;\n for (i = ka.length - 1; i >= 0; i--) {\n key = ka[i];\n if (!deepEqual(a[key], b[key], m)) {\n return false;\n }\n }\n\n return true;\n}\n","/*!\n localForage -- Offline Storage, Improved\n Version 1.5.0\n https://localforage.github.io/localForage\n (c) 2013-2017 Mozilla, Apache License 2.0\n*/\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.localforage = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw (f.code=\"MODULE_NOT_FOUND\", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o element; its readystatechange event will be fired asynchronously once it is inserted\n // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.\n var scriptEl = global.document.createElement('script');\n scriptEl.onreadystatechange = function () {\n nextTick();\n\n scriptEl.onreadystatechange = null;\n scriptEl.parentNode.removeChild(scriptEl);\n scriptEl = null;\n };\n global.document.documentElement.appendChild(scriptEl);\n };\n } else {\n scheduleDrain = function () {\n setTimeout(nextTick, 0);\n };\n }\n}\n\nvar draining;\nvar queue = [];\n//named nextTick for less confusing stack traces\nfunction nextTick() {\n draining = true;\n var i, oldQueue;\n var len = queue.length;\n while (len) {\n oldQueue = queue;\n queue = [];\n i = -1;\n while (++i < len) {\n oldQueue[i]();\n }\n len = queue.length;\n }\n draining = false;\n}\n\nmodule.exports = immediate;\nfunction immediate(task) {\n if (queue.push(task) === 1 && !draining) {\n scheduleDrain();\n }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],2:[function(_dereq_,module,exports){\n'use strict';\nvar immediate = _dereq_(1);\n\n/* istanbul ignore next */\nfunction INTERNAL() {}\n\nvar handlers = {};\n\nvar REJECTED = ['REJECTED'];\nvar FULFILLED = ['FULFILLED'];\nvar PENDING = ['PENDING'];\n\nmodule.exports = exports = Promise;\n\nfunction Promise(resolver) {\n if (typeof resolver !== 'function') {\n throw new TypeError('resolver must be a function');\n }\n this.state = PENDING;\n this.queue = [];\n this.outcome = void 0;\n if (resolver !== INTERNAL) {\n safelyResolveThenable(this, resolver);\n }\n}\n\nPromise.prototype[\"catch\"] = function (onRejected) {\n return this.then(null, onRejected);\n};\nPromise.prototype.then = function (onFulfilled, onRejected) {\n if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||\n typeof onRejected !== 'function' && this.state === REJECTED) {\n return this;\n }\n var promise = new this.constructor(INTERNAL);\n if (this.state !== PENDING) {\n var resolver = this.state === FULFILLED ? onFulfilled : onRejected;\n unwrap(promise, resolver, this.outcome);\n } else {\n this.queue.push(new QueueItem(promise, onFulfilled, onRejected));\n }\n\n return promise;\n};\nfunction QueueItem(promise, onFulfilled, onRejected) {\n this.promise = promise;\n if (typeof onFulfilled === 'function') {\n this.onFulfilled = onFulfilled;\n this.callFulfilled = this.otherCallFulfilled;\n }\n if (typeof onRejected === 'function') {\n this.onRejected = onRejected;\n this.callRejected = this.otherCallRejected;\n }\n}\nQueueItem.prototype.callFulfilled = function (value) {\n handlers.resolve(this.promise, value);\n};\nQueueItem.prototype.otherCallFulfilled = function (value) {\n unwrap(this.promise, this.onFulfilled, value);\n};\nQueueItem.prototype.callRejected = function (value) {\n handlers.reject(this.promise, value);\n};\nQueueItem.prototype.otherCallRejected = function (value) {\n unwrap(this.promise, this.onRejected, value);\n};\n\nfunction unwrap(promise, func, value) {\n immediate(function () {\n var returnValue;\n try {\n returnValue = func(value);\n } catch (e) {\n return handlers.reject(promise, e);\n }\n if (returnValue === promise) {\n handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));\n } else {\n handlers.resolve(promise, returnValue);\n }\n });\n}\n\nhandlers.resolve = function (self, value) {\n var result = tryCatch(getThen, value);\n if (result.status === 'error') {\n return handlers.reject(self, result.value);\n }\n var thenable = result.value;\n\n if (thenable) {\n safelyResolveThenable(self, thenable);\n } else {\n self.state = FULFILLED;\n self.outcome = value;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callFulfilled(value);\n }\n }\n return self;\n};\nhandlers.reject = function (self, error) {\n self.state = REJECTED;\n self.outcome = error;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callRejected(error);\n }\n return self;\n};\n\nfunction getThen(obj) {\n // Make sure we only access the accessor once as required by the spec\n var then = obj && obj.then;\n if (obj && typeof obj === 'object' && typeof then === 'function') {\n return function appyThen() {\n then.apply(obj, arguments);\n };\n }\n}\n\nfunction safelyResolveThenable(self, thenable) {\n // Either fulfill, reject or reject with error\n var called = false;\n function onError(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.reject(self, value);\n }\n\n function onSuccess(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.resolve(self, value);\n }\n\n function tryToUnwrap() {\n thenable(onSuccess, onError);\n }\n\n var result = tryCatch(tryToUnwrap);\n if (result.status === 'error') {\n onError(result.value);\n }\n}\n\nfunction tryCatch(func, value) {\n var out = {};\n try {\n out.value = func(value);\n out.status = 'success';\n } catch (e) {\n out.status = 'error';\n out.value = e;\n }\n return out;\n}\n\nexports.resolve = resolve;\nfunction resolve(value) {\n if (value instanceof this) {\n return value;\n }\n return handlers.resolve(new this(INTERNAL), value);\n}\n\nexports.reject = reject;\nfunction reject(reason) {\n var promise = new this(INTERNAL);\n return handlers.reject(promise, reason);\n}\n\nexports.all = all;\nfunction all(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var values = new Array(len);\n var resolved = 0;\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n allResolver(iterable[i], i);\n }\n return promise;\n function allResolver(value, i) {\n self.resolve(value).then(resolveFromAll, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n function resolveFromAll(outValue) {\n values[i] = outValue;\n if (++resolved === len && !called) {\n called = true;\n handlers.resolve(promise, values);\n }\n }\n }\n}\n\nexports.race = race;\nfunction race(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n resolver(iterable[i]);\n }\n return promise;\n function resolver(value) {\n self.resolve(value).then(function (response) {\n if (!called) {\n called = true;\n handlers.resolve(promise, response);\n }\n }, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n }\n}\n\n},{\"1\":1}],3:[function(_dereq_,module,exports){\n(function (global){\n'use strict';\nif (typeof global.Promise !== 'function') {\n global.Promise = _dereq_(2);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"2\":2}],4:[function(_dereq_,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction getIDB() {\n /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */\n try {\n if (typeof indexedDB !== 'undefined') {\n return indexedDB;\n }\n if (typeof webkitIndexedDB !== 'undefined') {\n return webkitIndexedDB;\n }\n if (typeof mozIndexedDB !== 'undefined') {\n return mozIndexedDB;\n }\n if (typeof OIndexedDB !== 'undefined') {\n return OIndexedDB;\n }\n if (typeof msIndexedDB !== 'undefined') {\n return msIndexedDB;\n }\n } catch (e) {}\n}\n\nvar idb = getIDB();\n\nfunction isIndexedDBValid() {\n try {\n // Initialize IndexedDB; fall back to vendor-prefixed versions\n // if needed.\n if (!idb) {\n return false;\n }\n // We mimic PouchDB here;\n //\n // We test for openDatabase because IE Mobile identifies itself\n // as Safari. Oh the lulz...\n var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform);\n\n var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1;\n\n // Safari <10.1 does not meet our requirements for IDB support (#5572)\n // since Safari 10.1 shipped with fetch, we can use that to detect it\n return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' &&\n // some outdated implementations of IDB that appear on Samsung\n // and HTC Android devices <4.4 are missing IDBKeyRange\n typeof IDBKeyRange !== 'undefined';\n } catch (e) {\n return false;\n }\n}\n\nfunction isWebSQLValid() {\n return typeof openDatabase === 'function';\n}\n\nfunction isLocalStorageValid() {\n try {\n return typeof localStorage !== 'undefined' && 'setItem' in localStorage && localStorage.setItem;\n } catch (e) {\n return false;\n }\n}\n\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\nfunction createBlob(parts, properties) {\n /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */\n parts = parts || [];\n properties = properties || {};\n try {\n return new Blob(parts, properties);\n } catch (e) {\n if (e.name !== 'TypeError') {\n throw e;\n }\n var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder;\n var builder = new Builder();\n for (var i = 0; i < parts.length; i += 1) {\n builder.append(parts[i]);\n }\n return builder.getBlob(properties.type);\n }\n}\n\n// This is CommonJS because lie is an external dependency, so Rollup\n// can just ignore it.\nif (typeof Promise === 'undefined') {\n // In the \"nopromises\" build this will just throw if you don't have\n // a global promise object, but it would throw anyway later.\n _dereq_(3);\n}\nvar Promise$1 = Promise;\n\nfunction executeCallback(promise, callback) {\n if (callback) {\n promise.then(function (result) {\n callback(null, result);\n }, function (error) {\n callback(error);\n });\n }\n}\n\nfunction executeTwoCallbacks(promise, callback, errorCallback) {\n if (typeof callback === 'function') {\n promise.then(callback);\n }\n\n if (typeof errorCallback === 'function') {\n promise[\"catch\"](errorCallback);\n }\n}\n\n// Some code originally from async_storage.js in\n// [Gaia](https://github.com/mozilla-b2g/gaia).\n\nvar DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support';\nvar supportsBlobs;\nvar dbContexts;\nvar toString = Object.prototype.toString;\n\n// Transform a binary string to an array buffer, because otherwise\n// weird stuff happens when you try to work with the binary string directly.\n// It is known.\n// From http://stackoverflow.com/questions/14967647/ (continues on next line)\n// encode-decode-image-with-base64-breaks-image (2013-04-21)\nfunction _binStringToArrayBuffer(bin) {\n var length = bin.length;\n var buf = new ArrayBuffer(length);\n var arr = new Uint8Array(buf);\n for (var i = 0; i < length; i++) {\n arr[i] = bin.charCodeAt(i);\n }\n return buf;\n}\n\n//\n// Blobs are not supported in all versions of IndexedDB, notably\n// Chrome <37 and Android <5. In those versions, storing a blob will throw.\n//\n// Various other blob bugs exist in Chrome v37-42 (inclusive).\n// Detecting them is expensive and confusing to users, and Chrome 37-42\n// is at very low usage worldwide, so we do a hacky userAgent check instead.\n//\n// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120\n// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916\n// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836\n//\n// Code borrowed from PouchDB. See:\n// https://github.com/pouchdb/pouchdb/blob/master/packages/node_modules/pouchdb-adapter-idb/src/blobSupport.js\n//\nfunction _checkBlobSupportWithoutCaching(idb) {\n return new Promise$1(function (resolve) {\n var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, 'readwrite');\n var blob = createBlob(['']);\n txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');\n\n txn.onabort = function (e) {\n // If the transaction aborts now its due to not being able to\n // write to the database, likely due to the disk being full\n e.preventDefault();\n e.stopPropagation();\n resolve(false);\n };\n\n txn.oncomplete = function () {\n var matchedChrome = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n var matchedEdge = navigator.userAgent.match(/Edge\\//);\n // MS Edge pretends to be Chrome 42:\n // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx\n resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43);\n };\n })[\"catch\"](function () {\n return false; // error, so assume unsupported\n });\n}\n\nfunction _checkBlobSupport(idb) {\n if (typeof supportsBlobs === 'boolean') {\n return Promise$1.resolve(supportsBlobs);\n }\n return _checkBlobSupportWithoutCaching(idb).then(function (value) {\n supportsBlobs = value;\n return supportsBlobs;\n });\n}\n\nfunction _deferReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Create a deferred object representing the current database operation.\n var deferredOperation = {};\n\n deferredOperation.promise = new Promise$1(function (resolve) {\n deferredOperation.resolve = resolve;\n });\n\n // Enqueue the deferred operation.\n dbContext.deferredOperations.push(deferredOperation);\n\n // Chain its promise to the database readiness.\n if (!dbContext.dbReady) {\n dbContext.dbReady = deferredOperation.promise;\n } else {\n dbContext.dbReady = dbContext.dbReady.then(function () {\n return deferredOperation.promise;\n });\n }\n}\n\nfunction _advanceReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Dequeue a deferred operation.\n var deferredOperation = dbContext.deferredOperations.pop();\n\n // Resolve its promise (which is part of the database readiness\n // chain of promises).\n if (deferredOperation) {\n deferredOperation.resolve();\n }\n}\n\nfunction _getConnection(dbInfo, upgradeNeeded) {\n return new Promise$1(function (resolve, reject) {\n\n if (dbInfo.db) {\n if (upgradeNeeded) {\n _deferReadiness(dbInfo);\n dbInfo.db.close();\n } else {\n return resolve(dbInfo.db);\n }\n }\n\n var dbArgs = [dbInfo.name];\n\n if (upgradeNeeded) {\n dbArgs.push(dbInfo.version);\n }\n\n var openreq = idb.open.apply(idb, dbArgs);\n\n if (upgradeNeeded) {\n openreq.onupgradeneeded = function (e) {\n var db = openreq.result;\n try {\n db.createObjectStore(dbInfo.storeName);\n if (e.oldVersion <= 1) {\n // Added when support for blob shims was added\n db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);\n }\n } catch (ex) {\n if (ex.name === 'ConstraintError') {\n console.warn('The database \"' + dbInfo.name + '\"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage \"' + dbInfo.storeName + '\" already exists.');\n } else {\n throw ex;\n }\n }\n };\n }\n\n openreq.onerror = function (e) {\n e.preventDefault();\n reject(openreq.error);\n };\n\n openreq.onsuccess = function () {\n resolve(openreq.result);\n _advanceReadiness(dbInfo);\n };\n });\n}\n\nfunction _getOriginalConnection(dbInfo) {\n return _getConnection(dbInfo, false);\n}\n\nfunction _getUpgradedConnection(dbInfo) {\n return _getConnection(dbInfo, true);\n}\n\nfunction _isUpgradeNeeded(dbInfo, defaultVersion) {\n if (!dbInfo.db) {\n return true;\n }\n\n var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName);\n var isDowngrade = dbInfo.version < dbInfo.db.version;\n var isUpgrade = dbInfo.version > dbInfo.db.version;\n\n if (isDowngrade) {\n // If the version is not the default one\n // then warn for impossible downgrade.\n if (dbInfo.version !== defaultVersion) {\n console.warn('The database \"' + dbInfo.name + '\"' + ' can\\'t be downgraded from version ' + dbInfo.db.version + ' to version ' + dbInfo.version + '.');\n }\n // Align the versions to prevent errors.\n dbInfo.version = dbInfo.db.version;\n }\n\n if (isUpgrade || isNewStore) {\n // If the store is new then increment the version (if needed).\n // This will trigger an \"upgradeneeded\" event which is required\n // for creating a store.\n if (isNewStore) {\n var incVersion = dbInfo.db.version + 1;\n if (incVersion > dbInfo.version) {\n dbInfo.version = incVersion;\n }\n }\n\n return true;\n }\n\n return false;\n}\n\n// encode a blob for indexeddb engines that don't support blobs\nfunction _encodeBlob(blob) {\n return new Promise$1(function (resolve, reject) {\n var reader = new FileReader();\n reader.onerror = reject;\n reader.onloadend = function (e) {\n var base64 = btoa(e.target.result || '');\n resolve({\n __local_forage_encoded_blob: true,\n data: base64,\n type: blob.type\n });\n };\n reader.readAsBinaryString(blob);\n });\n}\n\n// decode an encoded blob\nfunction _decodeBlob(encodedBlob) {\n var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data));\n return createBlob([arrayBuff], { type: encodedBlob.type });\n}\n\n// is this one of our fancy encoded blobs?\nfunction _isEncodedBlob(value) {\n return value && value.__local_forage_encoded_blob;\n}\n\n// Specialize the default `ready()` function by making it dependent\n// on the current database operations. Thus, the driver will be actually\n// ready when it's been initialized (default) *and* there are no pending\n// operations on the database (initiated by some other instances).\nfunction _fullyReady(callback) {\n var self = this;\n\n var promise = self._initReady().then(function () {\n var dbContext = dbContexts[self._dbInfo.name];\n\n if (dbContext && dbContext.dbReady) {\n return dbContext.dbReady;\n }\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n}\n\n// Open the IndexedDB database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n // Initialize a singleton container for all running localForages.\n if (!dbContexts) {\n dbContexts = {};\n }\n\n // Get the current context of the database;\n var dbContext = dbContexts[dbInfo.name];\n\n // ...or create a new context.\n if (!dbContext) {\n dbContext = {\n // Running localForages sharing a database.\n forages: [],\n // Shared database.\n db: null,\n // Database readiness (promise).\n dbReady: null,\n // Deferred operations on the database.\n deferredOperations: []\n };\n // Register the new context in the global container.\n dbContexts[dbInfo.name] = dbContext;\n }\n\n // Register itself as a running localForage in the current context.\n dbContext.forages.push(self);\n\n // Replace the default `ready()` function with the specialized one.\n if (!self._initReady) {\n self._initReady = self.ready;\n self.ready = _fullyReady;\n }\n\n // Create an array of initialization states of the related localForages.\n var initPromises = [];\n\n function ignoreErrors() {\n // Don't handle errors here,\n // just makes sure related localForages aren't pending.\n return Promise$1.resolve();\n }\n\n for (var j = 0; j < dbContext.forages.length; j++) {\n var forage = dbContext.forages[j];\n if (forage !== self) {\n // Don't wait for itself...\n initPromises.push(forage._initReady()[\"catch\"](ignoreErrors));\n }\n }\n\n // Take a snapshot of the related localForages.\n var forages = dbContext.forages.slice(0);\n\n // Initialize the connection process only when\n // all the related localForages aren't pending.\n return Promise$1.all(initPromises).then(function () {\n dbInfo.db = dbContext.db;\n // Get the connection or open a new one without upgrade.\n return _getOriginalConnection(dbInfo);\n }).then(function (db) {\n dbInfo.db = db;\n if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) {\n // Reopen the database for upgrading.\n return _getUpgradedConnection(dbInfo);\n }\n return db;\n }).then(function (db) {\n dbInfo.db = dbContext.db = db;\n self._dbInfo = dbInfo;\n // Share the final connection amongst related localForages.\n for (var k = 0; k < forages.length; k++) {\n var forage = forages[k];\n if (forage !== self) {\n // Self is already up-to-date.\n forage._dbInfo.db = dbInfo.db;\n forage._dbInfo.version = dbInfo.version;\n }\n }\n });\n}\n\nfunction getItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.get(key);\n\n req.onsuccess = function () {\n var value = req.result;\n if (value === undefined) {\n value = null;\n }\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n resolve(value);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items stored in database.\nfunction iterate(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var iterationNumber = 1;\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (cursor) {\n var value = cursor.value;\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n var result = iterator(value, cursor.key, iterationNumber++);\n\n if (result !== void 0) {\n resolve(result);\n } else {\n cursor[\"continue\"]();\n }\n } else {\n resolve();\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n\n return promise;\n}\n\nfunction setItem(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n var dbInfo;\n self.ready().then(function () {\n dbInfo = self._dbInfo;\n if (toString.call(value) === '[object Blob]') {\n return _checkBlobSupport(dbInfo.db).then(function (blobSupport) {\n if (blobSupport) {\n return value;\n }\n return _encodeBlob(value);\n });\n }\n return value;\n }).then(function (value) {\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.put(value, key);\n\n // The reason we don't _save_ null is because IE 10 does\n // not support saving the `null` type in IndexedDB. How\n // ironic, given the bug below!\n // See: https://github.com/mozilla/localForage/issues/161\n if (value === null) {\n value = undefined;\n }\n\n transaction.oncomplete = function () {\n // Cast to undefined so the value passed to\n // callback/promise is the same as what one would get out\n // of `getItem()` later. This leads to some weirdness\n // (setItem('foo', undefined) will return `null`), but\n // it's not my fault localStorage is our baseline and that\n // it's weird.\n if (value === undefined) {\n value = null;\n }\n\n resolve(value);\n };\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction removeItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n\n // We use a Grunt task to make this safe for IE and some\n // versions of Android (including those used by Cordova).\n // Normally IE won't like `.delete()` and will insist on\n // using `['delete']()`, but we have a build step that\n // fixes this for us now.\n var req = store[\"delete\"](key);\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onerror = function () {\n reject(req.error);\n };\n\n // The request will be also be aborted if we've exceeded our storage\n // space.\n transaction.onabort = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction clear(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.clear();\n\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction length(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.count();\n\n req.onsuccess = function () {\n resolve(req.result);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction key(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n if (n < 0) {\n resolve(null);\n\n return;\n }\n\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var advanced = false;\n var req = store.openCursor();\n req.onsuccess = function () {\n var cursor = req.result;\n if (!cursor) {\n // this means there weren't enough keys\n resolve(null);\n\n return;\n }\n\n if (n === 0) {\n // We have the first key, return it if that's what they\n // wanted.\n resolve(cursor.key);\n } else {\n if (!advanced) {\n // Otherwise, ask the cursor to skip ahead n\n // records.\n advanced = true;\n cursor.advance(n);\n } else {\n // When we get here, we've got the nth key.\n resolve(cursor.key);\n }\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var keys = [];\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (!cursor) {\n resolve(keys);\n return;\n }\n\n keys.push(cursor.key);\n cursor[\"continue\"]();\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar asyncStorage = {\n _driver: 'asyncStorage',\n _initStorage: _initStorage,\n iterate: iterate,\n getItem: getItem,\n setItem: setItem,\n removeItem: removeItem,\n clear: clear,\n length: length,\n key: key,\n keys: keys\n};\n\n// Sadly, the best way to save binary data in WebSQL/localStorage is serializing\n// it to Base64, so this is how we store it to prevent very strange errors with less\n// verbose ways of binary <-> string data storage.\nvar BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\nvar BLOB_TYPE_PREFIX = '~~local_forage_type~';\nvar BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;\n\nvar SERIALIZED_MARKER = '__lfsc__:';\nvar SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;\n\n// OMG the serializations!\nvar TYPE_ARRAYBUFFER = 'arbf';\nvar TYPE_BLOB = 'blob';\nvar TYPE_INT8ARRAY = 'si08';\nvar TYPE_UINT8ARRAY = 'ui08';\nvar TYPE_UINT8CLAMPEDARRAY = 'uic8';\nvar TYPE_INT16ARRAY = 'si16';\nvar TYPE_INT32ARRAY = 'si32';\nvar TYPE_UINT16ARRAY = 'ur16';\nvar TYPE_UINT32ARRAY = 'ui32';\nvar TYPE_FLOAT32ARRAY = 'fl32';\nvar TYPE_FLOAT64ARRAY = 'fl64';\nvar TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;\n\nvar toString$1 = Object.prototype.toString;\n\nfunction stringToBuffer(serializedString) {\n // Fill the string into a ArrayBuffer.\n var bufferLength = serializedString.length * 0.75;\n var len = serializedString.length;\n var i;\n var p = 0;\n var encoded1, encoded2, encoded3, encoded4;\n\n if (serializedString[serializedString.length - 1] === '=') {\n bufferLength--;\n if (serializedString[serializedString.length - 2] === '=') {\n bufferLength--;\n }\n }\n\n var buffer = new ArrayBuffer(bufferLength);\n var bytes = new Uint8Array(buffer);\n\n for (i = 0; i < len; i += 4) {\n encoded1 = BASE_CHARS.indexOf(serializedString[i]);\n encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);\n encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);\n encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);\n\n /*jslint bitwise: true */\n bytes[p++] = encoded1 << 2 | encoded2 >> 4;\n bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;\n bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;\n }\n return buffer;\n}\n\n// Converts a buffer to a string to store, serialized, in the backend\n// storage library.\nfunction bufferToString(buffer) {\n // base64-arraybuffer\n var bytes = new Uint8Array(buffer);\n var base64String = '';\n var i;\n\n for (i = 0; i < bytes.length; i += 3) {\n /*jslint bitwise: true */\n base64String += BASE_CHARS[bytes[i] >> 2];\n base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];\n base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];\n base64String += BASE_CHARS[bytes[i + 2] & 63];\n }\n\n if (bytes.length % 3 === 2) {\n base64String = base64String.substring(0, base64String.length - 1) + '=';\n } else if (bytes.length % 3 === 1) {\n base64String = base64String.substring(0, base64String.length - 2) + '==';\n }\n\n return base64String;\n}\n\n// Serialize a value, afterwards executing a callback (which usually\n// instructs the `setItem()` callback/promise to be executed). This is how\n// we store binary data with localStorage.\nfunction serialize(value, callback) {\n var valueType = '';\n if (value) {\n valueType = toString$1.call(value);\n }\n\n // Cannot use `value instanceof ArrayBuffer` or such here, as these\n // checks fail when running the tests using casper.js...\n //\n // TODO: See why those tests fail and use a better solution.\n if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) {\n // Convert binary arrays to a string and prefix the string with\n // a special marker.\n var buffer;\n var marker = SERIALIZED_MARKER;\n\n if (value instanceof ArrayBuffer) {\n buffer = value;\n marker += TYPE_ARRAYBUFFER;\n } else {\n buffer = value.buffer;\n\n if (valueType === '[object Int8Array]') {\n marker += TYPE_INT8ARRAY;\n } else if (valueType === '[object Uint8Array]') {\n marker += TYPE_UINT8ARRAY;\n } else if (valueType === '[object Uint8ClampedArray]') {\n marker += TYPE_UINT8CLAMPEDARRAY;\n } else if (valueType === '[object Int16Array]') {\n marker += TYPE_INT16ARRAY;\n } else if (valueType === '[object Uint16Array]') {\n marker += TYPE_UINT16ARRAY;\n } else if (valueType === '[object Int32Array]') {\n marker += TYPE_INT32ARRAY;\n } else if (valueType === '[object Uint32Array]') {\n marker += TYPE_UINT32ARRAY;\n } else if (valueType === '[object Float32Array]') {\n marker += TYPE_FLOAT32ARRAY;\n } else if (valueType === '[object Float64Array]') {\n marker += TYPE_FLOAT64ARRAY;\n } else {\n callback(new Error('Failed to get type for BinaryArray'));\n }\n }\n\n callback(marker + bufferToString(buffer));\n } else if (valueType === '[object Blob]') {\n // Conver the blob to a binaryArray and then to a string.\n var fileReader = new FileReader();\n\n fileReader.onload = function () {\n // Backwards-compatible prefix for the blob type.\n var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result);\n\n callback(SERIALIZED_MARKER + TYPE_BLOB + str);\n };\n\n fileReader.readAsArrayBuffer(value);\n } else {\n try {\n callback(JSON.stringify(value));\n } catch (e) {\n console.error(\"Couldn't convert value into a JSON string: \", value);\n\n callback(null, e);\n }\n }\n}\n\n// Deserialize data we've inserted into a value column/field. We place\n// special markers into our strings to mark them as encoded; this isn't\n// as nice as a meta field, but it's the only sane thing we can do whilst\n// keeping localStorage support intact.\n//\n// Oftentimes this will just deserialize JSON content, but if we have a\n// special marker (SERIALIZED_MARKER, defined above), we will extract\n// some kind of arraybuffer/binary data/typed array out of the string.\nfunction deserialize(value) {\n // If we haven't marked this string as being specially serialized (i.e.\n // something other than serialized JSON), we can just return it and be\n // done with it.\n if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {\n return JSON.parse(value);\n }\n\n // The following code deals with deserializing some kind of Blob or\n // TypedArray. First we separate out the type of data we're dealing\n // with from the data itself.\n var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);\n var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH);\n\n var blobType;\n // Backwards-compatible blob type serialization strategy.\n // DBs created with older versions of localForage will simply not have the blob type.\n if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {\n var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);\n blobType = matcher[1];\n serializedString = serializedString.substring(matcher[0].length);\n }\n var buffer = stringToBuffer(serializedString);\n\n // Return the right type based on the code/type set during\n // serialization.\n switch (type) {\n case TYPE_ARRAYBUFFER:\n return buffer;\n case TYPE_BLOB:\n return createBlob([buffer], { type: blobType });\n case TYPE_INT8ARRAY:\n return new Int8Array(buffer);\n case TYPE_UINT8ARRAY:\n return new Uint8Array(buffer);\n case TYPE_UINT8CLAMPEDARRAY:\n return new Uint8ClampedArray(buffer);\n case TYPE_INT16ARRAY:\n return new Int16Array(buffer);\n case TYPE_UINT16ARRAY:\n return new Uint16Array(buffer);\n case TYPE_INT32ARRAY:\n return new Int32Array(buffer);\n case TYPE_UINT32ARRAY:\n return new Uint32Array(buffer);\n case TYPE_FLOAT32ARRAY:\n return new Float32Array(buffer);\n case TYPE_FLOAT64ARRAY:\n return new Float64Array(buffer);\n default:\n throw new Error('Unkown type: ' + type);\n }\n}\n\nvar localforageSerializer = {\n serialize: serialize,\n deserialize: deserialize,\n stringToBuffer: stringToBuffer,\n bufferToString: bufferToString\n};\n\n/*\n * Includes code from:\n *\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n// Open the WebSQL database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage$1(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i];\n }\n }\n\n var dbInfoPromise = new Promise$1(function (resolve, reject) {\n // Open the database; the openDatabase API will automatically\n // create it for us if it doesn't exist.\n try {\n dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size);\n } catch (e) {\n return reject(e);\n }\n\n // Create our key/value table if it doesn't exist.\n dbInfo.db.transaction(function (t) {\n t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' (id INTEGER PRIMARY KEY, key unique, value)', [], function () {\n self._dbInfo = dbInfo;\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n });\n\n dbInfo.serializer = localforageSerializer;\n return dbInfoPromise;\n}\n\nfunction getItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).value : null;\n\n // Check to see if this is serialized content we need to\n // unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction iterate$1(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName, [], function (t, results) {\n var rows = results.rows;\n var length = rows.length;\n\n for (var i = 0; i < length; i++) {\n var item = rows.item(i);\n var result = item.value;\n\n // Check to see if this is serialized content\n // we need to unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n result = iterator(result, item.key, i + 1);\n\n // void(0) prevents problems with redefinition\n // of `undefined`.\n if (result !== void 0) {\n resolve(result);\n return;\n }\n }\n\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction _setItem(key, value, callback, retriesLeft) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n // The localStorage API doesn't return undefined values in an\n // \"expected\" way, so undefined is always cast to null in all\n // drivers. See: https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n dbInfo.db.transaction(function (t) {\n t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + ' (key, value) VALUES (?, ?)', [key, value], function () {\n resolve(originalValue);\n }, function (t, error) {\n reject(error);\n });\n }, function (sqlError) {\n // The transaction failed; check\n // to see if it's a quota error.\n if (sqlError.code === sqlError.QUOTA_ERR) {\n // We reject the callback outright for now, but\n // it's worth trying to re-run the transaction.\n // Even if the user accepts the prompt to use\n // more storage on Safari, this error will\n // be called.\n //\n // Try to re-run the transaction.\n if (retriesLeft > 0) {\n resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1]));\n return;\n }\n reject(sqlError);\n }\n });\n }\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction setItem$1(key, value, callback) {\n return _setItem.apply(this, [key, value, callback, 1]);\n}\n\nfunction removeItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () {\n resolve();\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Deletes every item in the table.\n// TODO: Find out if this resets the AUTO_INCREMENT number.\nfunction clear$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function () {\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Does a simple `COUNT(key)` to get the number of items stored in\n// localForage.\nfunction length$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n // Ahhh, SQL makes this one soooooo easy.\n t.executeSql('SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) {\n var result = results.rows.item(0).c;\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Return the key located at key index X; essentially gets the key from a\n// `WHERE id = ?`. This is the most efficient way I can think to implement\n// this rarely-used (in my experience) part of the API, but it can seem\n// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so\n// the ID of each key will change every time it's updated. Perhaps a stored\n// procedure for the `setItem()` SQL would solve this problem?\n// TODO: Don't change ID on `setItem()`.\nfunction key$1(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).key : null;\n resolve(result);\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName, [], function (t, results) {\n var keys = [];\n\n for (var i = 0; i < results.rows.length; i++) {\n keys.push(results.rows.item(i).key);\n }\n\n resolve(keys);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar webSQLStorage = {\n _driver: 'webSQLStorage',\n _initStorage: _initStorage$1,\n iterate: iterate$1,\n getItem: getItem$1,\n setItem: setItem$1,\n removeItem: removeItem$1,\n clear: clear$1,\n length: length$1,\n key: key$1,\n keys: keys$1\n};\n\n// Config the localStorage backend, using options set in the config.\nfunction _initStorage$2(options) {\n var self = this;\n var dbInfo = {};\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n dbInfo.keyPrefix = dbInfo.name + '/';\n\n if (dbInfo.storeName !== self._defaultConfig.storeName) {\n dbInfo.keyPrefix += dbInfo.storeName + '/';\n }\n\n self._dbInfo = dbInfo;\n dbInfo.serializer = localforageSerializer;\n\n return Promise$1.resolve();\n}\n\n// Remove all keys from the datastore, effectively destroying all data in\n// the app's key/value store!\nfunction clear$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var keyPrefix = self._dbInfo.keyPrefix;\n\n for (var i = localStorage.length - 1; i >= 0; i--) {\n var key = localStorage.key(i);\n\n if (key.indexOf(keyPrefix) === 0) {\n localStorage.removeItem(key);\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Retrieve an item from the store. Unlike the original async_storage\n// library in Gaia, we don't modify return values at all. If a key's value\n// is `undefined`, we pass that value to the callback function.\nfunction getItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result = localStorage.getItem(dbInfo.keyPrefix + key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the key\n // is likely undefined and we'll pass it straight to the\n // callback.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items in the store.\nfunction iterate$2(iterator, callback) {\n var self = this;\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var keyPrefix = dbInfo.keyPrefix;\n var keyPrefixLength = keyPrefix.length;\n var length = localStorage.length;\n\n // We use a dedicated iterator instead of the `i` variable below\n // so other keys we fetch in localStorage aren't counted in\n // the `iterationNumber` argument passed to the `iterate()`\n // callback.\n //\n // See: github.com/mozilla/localForage/pull/435#discussion_r38061530\n var iterationNumber = 1;\n\n for (var i = 0; i < length; i++) {\n var key = localStorage.key(i);\n if (key.indexOf(keyPrefix) !== 0) {\n continue;\n }\n var value = localStorage.getItem(key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the\n // key is likely undefined and we'll pass it straight\n // to the iterator.\n if (value) {\n value = dbInfo.serializer.deserialize(value);\n }\n\n value = iterator(value, key.substring(keyPrefixLength), iterationNumber++);\n\n if (value !== void 0) {\n return value;\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Same as localStorage's key() method, except takes a callback.\nfunction key$2(n, callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result;\n try {\n result = localStorage.key(n);\n } catch (error) {\n result = null;\n }\n\n // Remove the prefix from the key, if a key is found.\n if (result) {\n result = result.substring(dbInfo.keyPrefix.length);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var length = localStorage.length;\n var keys = [];\n\n for (var i = 0; i < length; i++) {\n if (localStorage.key(i).indexOf(dbInfo.keyPrefix) === 0) {\n keys.push(localStorage.key(i).substring(dbInfo.keyPrefix.length));\n }\n }\n\n return keys;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Supply the number of keys in the datastore to the callback function.\nfunction length$2(callback) {\n var self = this;\n var promise = self.keys().then(function (keys) {\n return keys.length;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Remove an item from the store, nice and simple.\nfunction removeItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n localStorage.removeItem(dbInfo.keyPrefix + key);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Set a key's value and run an optional callback once the value is set.\n// Unlike Gaia's implementation, the callback function is passed the value,\n// in case you want to operate on that value only after you're sure it\n// saved, or something like that.\nfunction setItem$2(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n // Convert undefined values to null.\n // https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n return new Promise$1(function (resolve, reject) {\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n try {\n localStorage.setItem(dbInfo.keyPrefix + key, value);\n resolve(originalValue);\n } catch (e) {\n // localStorage capacity exceeded.\n // TODO: Make this a specific error/event.\n if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {\n reject(e);\n }\n reject(e);\n }\n }\n });\n });\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar localStorageWrapper = {\n _driver: 'localStorageWrapper',\n _initStorage: _initStorage$2,\n // Default API, from Gaia/localStorage.\n iterate: iterate$2,\n getItem: getItem$2,\n setItem: setItem$2,\n removeItem: removeItem$2,\n clear: clear$2,\n length: length$2,\n key: key$2,\n keys: keys$2\n};\n\n// Custom drivers are stored here when `defineDriver()` is called.\n// They are shared across all instances of localForage.\nvar CustomDrivers = {};\n\nvar DriverType = {\n INDEXEDDB: 'asyncStorage',\n LOCALSTORAGE: 'localStorageWrapper',\n WEBSQL: 'webSQLStorage'\n};\n\nvar DefaultDriverOrder = [DriverType.INDEXEDDB, DriverType.WEBSQL, DriverType.LOCALSTORAGE];\n\nvar LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem'];\n\nvar DefaultConfig = {\n description: '',\n driver: DefaultDriverOrder.slice(),\n name: 'localforage',\n // Default DB size is _JUST UNDER_ 5MB, as it's the highest size\n // we can use without a prompt.\n size: 4980736,\n storeName: 'keyvaluepairs',\n version: 1.0\n};\n\nvar driverSupport = {};\n// Check to see if IndexedDB is available and if it is the latest\n// implementation; it's our preferred backend library. We use \"_spec_test\"\n// as the name of the database because it's not the one we'll operate on,\n// but it's useful to make sure its using the right spec.\n// See: https://github.com/mozilla/localForage/issues/128\ndriverSupport[DriverType.INDEXEDDB] = isIndexedDBValid();\n\ndriverSupport[DriverType.WEBSQL] = isWebSQLValid();\n\ndriverSupport[DriverType.LOCALSTORAGE] = isLocalStorageValid();\n\nvar isArray = Array.isArray || function (arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n};\n\nfunction callWhenReady(localForageInstance, libraryMethod) {\n localForageInstance[libraryMethod] = function () {\n var _args = arguments;\n return localForageInstance.ready().then(function () {\n return localForageInstance[libraryMethod].apply(localForageInstance, _args);\n });\n };\n}\n\nfunction extend() {\n for (var i = 1; i < arguments.length; i++) {\n var arg = arguments[i];\n\n if (arg) {\n for (var key in arg) {\n if (arg.hasOwnProperty(key)) {\n if (isArray(arg[key])) {\n arguments[0][key] = arg[key].slice();\n } else {\n arguments[0][key] = arg[key];\n }\n }\n }\n }\n }\n\n return arguments[0];\n}\n\nfunction isLibraryDriver(driverName) {\n for (var driver in DriverType) {\n if (DriverType.hasOwnProperty(driver) && DriverType[driver] === driverName) {\n return true;\n }\n }\n\n return false;\n}\n\nvar LocalForage = function () {\n function LocalForage(options) {\n _classCallCheck(this, LocalForage);\n\n this.INDEXEDDB = DriverType.INDEXEDDB;\n this.LOCALSTORAGE = DriverType.LOCALSTORAGE;\n this.WEBSQL = DriverType.WEBSQL;\n\n this._defaultConfig = extend({}, DefaultConfig);\n this._config = extend({}, this._defaultConfig, options);\n this._driverSet = null;\n this._initDriver = null;\n this._ready = false;\n this._dbInfo = null;\n\n this._wrapLibraryMethodsWithReady();\n this.setDriver(this._config.driver)[\"catch\"](function () {});\n }\n\n // Set any config values for localForage; can be called anytime before\n // the first API call (e.g. `getItem`, `setItem`).\n // We loop through options so we don't overwrite existing config\n // values.\n\n\n LocalForage.prototype.config = function config(options) {\n // If the options argument is an object, we use it to set values.\n // Otherwise, we return either a specified config value or all\n // config values.\n if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {\n // If localforage is ready and fully initialized, we can't set\n // any new configuration values. Instead, we return an error.\n if (this._ready) {\n return new Error(\"Can't call config() after localforage \" + 'has been used.');\n }\n\n for (var i in options) {\n if (i === 'storeName') {\n options[i] = options[i].replace(/\\W/g, '_');\n }\n\n if (i === 'version' && typeof options[i] !== 'number') {\n return new Error('Database version must be a number.');\n }\n\n this._config[i] = options[i];\n }\n\n // after all config options are set and\n // the driver option is used, try setting it\n if ('driver' in options && options.driver) {\n return this.setDriver(this._config.driver);\n }\n\n return true;\n } else if (typeof options === 'string') {\n return this._config[options];\n } else {\n return this._config;\n }\n };\n\n // Used to define a custom driver, shared across all instances of\n // localForage.\n\n\n LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) {\n var promise = new Promise$1(function (resolve, reject) {\n try {\n var driverName = driverObject._driver;\n var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver');\n var namingError = new Error('Custom driver name already in use: ' + driverObject._driver);\n\n // A driver name should be defined and not overlap with the\n // library-defined, default drivers.\n if (!driverObject._driver) {\n reject(complianceError);\n return;\n }\n if (isLibraryDriver(driverObject._driver)) {\n reject(namingError);\n return;\n }\n\n var customDriverMethods = LibraryMethods.concat('_initStorage');\n for (var i = 0; i < customDriverMethods.length; i++) {\n var customDriverMethod = customDriverMethods[i];\n if (!customDriverMethod || !driverObject[customDriverMethod] || typeof driverObject[customDriverMethod] !== 'function') {\n reject(complianceError);\n return;\n }\n }\n\n var supportPromise = Promise$1.resolve(true);\n if ('_support' in driverObject) {\n if (driverObject._support && typeof driverObject._support === 'function') {\n supportPromise = driverObject._support();\n } else {\n supportPromise = Promise$1.resolve(!!driverObject._support);\n }\n }\n\n supportPromise.then(function (supportResult) {\n driverSupport[driverName] = supportResult;\n CustomDrivers[driverName] = driverObject;\n resolve();\n }, reject);\n } catch (e) {\n reject(e);\n }\n });\n\n executeTwoCallbacks(promise, callback, errorCallback);\n return promise;\n };\n\n LocalForage.prototype.driver = function driver() {\n return this._driver || null;\n };\n\n LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) {\n var self = this;\n var getDriverPromise = Promise$1.resolve().then(function () {\n if (isLibraryDriver(driverName)) {\n switch (driverName) {\n case self.INDEXEDDB:\n return asyncStorage;\n case self.LOCALSTORAGE:\n return localStorageWrapper;\n case self.WEBSQL:\n return webSQLStorage;\n }\n } else if (CustomDrivers[driverName]) {\n return CustomDrivers[driverName];\n } else {\n throw new Error('Driver not found.');\n }\n });\n executeTwoCallbacks(getDriverPromise, callback, errorCallback);\n return getDriverPromise;\n };\n\n LocalForage.prototype.getSerializer = function getSerializer(callback) {\n var serializerPromise = Promise$1.resolve(localforageSerializer);\n executeTwoCallbacks(serializerPromise, callback);\n return serializerPromise;\n };\n\n LocalForage.prototype.ready = function ready(callback) {\n var self = this;\n\n var promise = self._driverSet.then(function () {\n if (self._ready === null) {\n self._ready = self._initDriver();\n }\n\n return self._ready;\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n };\n\n LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) {\n var self = this;\n\n if (!isArray(drivers)) {\n drivers = [drivers];\n }\n\n var supportedDrivers = this._getSupportedDrivers(drivers);\n\n function setDriverToConfig() {\n self._config.driver = self.driver();\n }\n\n function extendSelfWithDriver(driver) {\n self._extend(driver);\n setDriverToConfig();\n\n self._ready = self._initStorage(self._config);\n return self._ready;\n }\n\n function initDriver(supportedDrivers) {\n return function () {\n var currentDriverIndex = 0;\n\n function driverPromiseLoop() {\n while (currentDriverIndex < supportedDrivers.length) {\n var driverName = supportedDrivers[currentDriverIndex];\n currentDriverIndex++;\n\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(extendSelfWithDriver)[\"catch\"](driverPromiseLoop);\n }\n\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n }\n\n return driverPromiseLoop();\n };\n }\n\n // There might be a driver initialization in progress\n // so wait for it to finish in order to avoid a possible\n // race condition to set _dbInfo\n var oldDriverSetDone = this._driverSet !== null ? this._driverSet[\"catch\"](function () {\n return Promise$1.resolve();\n }) : Promise$1.resolve();\n\n this._driverSet = oldDriverSetDone.then(function () {\n var driverName = supportedDrivers[0];\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(function (driver) {\n self._driver = driver._driver;\n setDriverToConfig();\n self._wrapLibraryMethodsWithReady();\n self._initDriver = initDriver(supportedDrivers);\n });\n })[\"catch\"](function () {\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n });\n\n executeTwoCallbacks(this._driverSet, callback, errorCallback);\n return this._driverSet;\n };\n\n LocalForage.prototype.supports = function supports(driverName) {\n return !!driverSupport[driverName];\n };\n\n LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) {\n extend(this, libraryMethodsAndProperties);\n };\n\n LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) {\n var supportedDrivers = [];\n for (var i = 0, len = drivers.length; i < len; i++) {\n var driverName = drivers[i];\n if (this.supports(driverName)) {\n supportedDrivers.push(driverName);\n }\n }\n return supportedDrivers;\n };\n\n LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() {\n // Add a stub for each driver API method that delays the call to the\n // corresponding driver method until localForage is ready. These stubs\n // will be replaced by the driver methods as soon as the driver is\n // loaded, so there is no performance impact.\n for (var i = 0; i < LibraryMethods.length; i++) {\n callWhenReady(this, LibraryMethods[i]);\n }\n };\n\n LocalForage.prototype.createInstance = function createInstance(options) {\n return new LocalForage(options);\n };\n\n return LocalForage;\n}();\n\n// The actual localForage object that we expose as a module or via a\n// global. It's extended by pulling in one of our other libraries.\n\n\nvar localforage_js = new LocalForage();\n\nmodule.exports = localforage_js;\n\n},{\"3\":3}]},{},[4])(4)\n});","module.exports = require('./lib/type');\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n '[object Array]': 'array'\n , '[object RegExp]': 'regexp'\n , '[object Function]': 'function'\n , '[object Arguments]': 'arguments'\n , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n var str = Object.prototype.toString.call(obj);\n if (natives[str]) return natives[str];\n if (obj === null) return 'null';\n if (obj === undefined) return 'undefined';\n if (obj === Object(obj)) return 'object';\n return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n // Let \"new String('')\" return 'object'\n if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n // PhantomJS has type \"DOMWindow\" for null\n if (obj === null) return 'null';\n // PhantomJS has type \"DOMWindow\" for undefined\n if (obj === undefined) return 'undefined';\n return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n if (!(this instanceof Library)) return new Library();\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","(function (document, window) {\n // DEPENDENCIES\n // ============================================================\n const localforage = require('localforage');\n const probs = require('pjs-problems');\n const dedent = require('dedent');\n const assert = require('chai').assert;\n\n // PROBLEM TEMPLATE NICE-IFICATION\n // ============================================================\n\n function dedentStrings(problems) {\n return problems.map(prob => {\n prob.given = dedent(prob.given)\n prob.answer = dedent(prob.answer)\n return prob\n });\n }\n\n\n // PROBLEMS\n // ============================================================\n\n let problems = [];\n Object.keys(probs).forEach(subject => {\n problems.push(...probs[subject]);\n });\n problems = dedentStrings(problems);\n\n\n // CONFIG\n // ============================================================\n\n // Hoist current problem\n let currentProblem;\n\n // Keys to ignore while user is navigating around the textarea but not changing any code\n const ignoreKeyCodes = [\n 9, // Tab\n 37, // Left arrow\n 39, // Right arrow\n 38, // Up arrow\n 40 // Down arrow\n ];\n\n let config = {\n shuffle: true,\n timer: false,\n currentIndex: 0\n };\n\n // Pull config from localforage\n localforage\n .getItem('js_practice_config')\n .then(val => {\n if (val) {\n config = val;\n }\n loadApp(config);\n })\n .catch(err => {\n console.log('localforage err:', err);\n loadApp(config);\n });\n\n function updateLocalstore(config) {\n return localforage\n .setItem('js_practice_config', config)\n .then(val => val)\n .catch(err => {\n console.log('Settings update error:', err);\n });\n }\n\n // HELPERS\n // ============================================================\n\n function debounce(func, wait, immediate) {\n let timeout;\n return function () {\n const context = this;\n const args = arguments;\n const later = function () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n };\n const callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) {\n func.apply(context, args);\n }\n };\n }\n\n // UI\n // ============================================================\n\n // elements\n const problemEl = document.getElementById('problem');\n const codeEl = document.getElementById('code');\n const testSuiteEl = document.getElementById('test-suite');\n const testTotalEl = document.getElementById('test-total');\n const evalConsoleEl = document.getElementById('eval-output');\n const assertConsoleEl = document.getElementById('assert-output');\n const shuffleProblemsButtonEl = document.getElementById('shuffle-problems');\n const previousProblemButtonEl = document.getElementById('prev-problem');\n const nextProblemButtonEl = document.getElementById('next-problem');\n\n // Get indexes\n function getRandomIndex(problemsArr) {\n const ind = Math.floor(Math.random() * problemsArr.length);\n config.currentIndex = ind;\n updateLocalstore(config);\n return ind;\n }\n\n function getPreviousIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at beginning, go to end\n if (currentIndex === 0) {\n probInd = problemsArr.length - 1;\n } else {\n probInd = currentIndex - 1;\n }\n return probInd;\n }\n\n function getNextIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at end or invalid, restart series\n if (currentIndex >= problemsArr.length - 1 || currentIndex < 0) {\n probInd = 0;\n } else {\n probInd = currentIndex + 1;\n }\n return probInd;\n }\n\n // Get problems\n function getCurrentProblem(problemsArr) {\n return problemsArr[config.currentIndex];\n }\n\n function previousProblem() {\n console.log('previousProblem!');\n // Activate back button, for visual queue of nav feedback\n previousProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getPreviousIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function nextProblem() {\n console.log('nextProblem!');\n // Activate next button, for visual queue of nav feedback\n nextProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getNextIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function toggleShuffle() {\n console.log('toggle shuffle!');\n config.shuffle = !config.shuffle; // Flip it\n shuffleProblemsButtonEl.classList.toggle('active');\n previousProblemButtonEl.parentNode.classList.toggle('hidden');\n updateLocalstore(config);\n }\n\n function loadProblem(problemObj) {\n currentProblem = problemObj;\n // Prob question\n problemEl.innerText = problemObj.prompt;\n // Prob given code\n if (problemObj.given) {\n codeEl.value = problemObj.given;\n }\n // Seed the tests, pass (init = true) as second param\n testSuite(null, true);\n }\n\n // TODO: Build the assert errors into the test dom on each update.\n function updateTests(testStatus, init) {\n if (init === true) {\n buildTests(currentProblem.tests);\n }\n updateTestStatus(testStatus);\n }\n\n function buildTests(tests) {\n if (tests) {\n const testsDom = tests\n .map(test => {\n return `
\n
[✘]
\n
${test.name}
\n
`;\n })\n .join('');\n testSuiteEl.innerHTML = testsDom;\n }\n }\n\n function updateTestStatus(testStatuses) {\n if (!testStatuses) {\n throw new Error('No testStatuses provided.');\n }\n // Find out if all tests have passed or not\n let allPassed = true;\n testStatuses.forEach(testPassed => {\n if (testPassed !== true) {\n allPassed = false;\n }\n });\n const testEls = [].slice.call(testSuiteEl.querySelectorAll('.test-state'));\n testEls.forEach((testStatusEl, iter) => {\n if (testStatuses[iter] === true) {\n testStatusEl.innerHTML = '[✓]';\n testStatusEl.classList.remove('fail');\n testStatusEl.classList.add('pass');\n } else {\n testStatusEl.innerHTML = '[✘]';\n testStatusEl.classList.remove('pass');\n testStatusEl.classList.add('fail');\n }\n });\n\n if (allPassed === true) {\n testTotalEl.innerText = 'PASS';\n testTotalEl.classList.remove('fail');\n testTotalEl.classList.add('pass');\n } else {\n testTotalEl.innerText = 'FAIL';\n testTotalEl.classList.remove('pass');\n testTotalEl.classList.add('fail');\n }\n }\n\n function printAssertError(errObj) {\n // Make element string\n let inner = '';\n if (errObj !== null) {\n inner = `\n
\n Expected: ${JSON.stringify(errObj.expected)}\n Actual: ${JSON.stringify(errObj.actual)}\n
`;\n }\n\n // Prepend element\n assertConsoleEl.innerHTML = inner;\n }\n\n function printEvalOutput(errObj, output) {\n // Make element string\n let inner = '';\n if (errObj && errObj.message !== undefined) {\n inner = `\n
\n Syntax Error: ${JSON.stringify(errObj.message)}\n
`;\n } else if (output) {\n inner = `\n
\n Output: ${JSON.stringify(output)}\n
`;\n }\n // Prepend element\n evalConsoleEl.innerHTML = inner;\n }\n\n\n // VERIFICATION LOGIC\n // ============================================================\n\n function testSuite(init) {\n // Show 'working' indicator\n testTotalEl.classList.toggle('working');\n // Run stuff\n const output = getOutput(codeEl.value);\n // Run tests on code, return object/array of test results\n const tested = runTests(output);\n // Hide 'working' indicator\n testTotalEl.classList.toggle('working');\n // Update UI with results\n updateTests(tested, init);\n }\n\n function getOutput(code) {\n let evald = false;\n try {\n evald = eval(`(function(){${code}})()`); // eslint-disable-line no-eval\n printEvalOutput(null, evald); // Print current output\n } catch (err) {\n printEvalOutput(err);\n }\n return evald;\n }\n\n function runTests(output) {\n let tested = false;\n tested = currentProblem.tests.map(test => {\n let testOutcome = false;\n try {\n if (output) {\n // const testEval = eval(test.test);\n\n testOutcome = eval(test.test);\n console.log('testOutcome:', testOutcome);\n\n }\n printAssertError(null);\n } catch (err) {\n printAssertError(err);\n }\n return testOutcome;\n });\n return tested;\n }\n\n // Wrapped to prevent race with local config retrieval\n function loadApp(config) {\n console.log('loading app!');\n\n // Show current toggle state\n if (config.shuffle === true) {\n shuffleProblemsButtonEl.classList.add('active');\n previousProblemButtonEl.parentNode.classList.add('hidden');\n }\n\n // Keybinding stuff\n // ============================================================\n\n // Debounced code validation\n const debouncedInputValidation = debounce(e => {\n // If not arrow keys or other non-character keys\n if (ignoreKeyCodes.indexOf(e.keyCode) === -1) {\n // Run test suite\n testSuite();\n }\n }, 200);\n\n function problemNav(e) {\n // Go to previous problem keybinding\n // If CMD/CTRL + SHIFT + RETURN/ENTER\n if (config.shuffle === false && e.keyCode === 13 && e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem\n previousProblem();\n } else if (e.keyCode === 13 && !e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem keybinding\n // If CMD/CTRL + RETURN/ENTER\n // Go to next problem\n nextProblem();\n }\n }\n\n // Event Bindings\n // ============================================================\n\n // Bind it up\n codeEl.addEventListener('keydown', debouncedInputValidation);\n document.addEventListener('keydown', problemNav);\n shuffleProblemsButtonEl.addEventListener('click', toggleShuffle);\n previousProblemButtonEl.addEventListener('click', previousProblem);\n nextProblemButtonEl.addEventListener('click', nextProblem);\n\n // Start it up!\n // Load current problem\n const currProb = getCurrentProblem(problems);\n loadProblem(currProb);\n // Initalized test suite with starting failures\n testSuite(true);\n }\n})(document, window);\n"]} \ No newline at end of file diff --git a/public/dist/js/loadJS.js b/public/dist/js/loadJS.js index 5106909..14c857b 100644 --- a/public/dist/js/loadJS.js +++ b/public/dist/js/loadJS.js @@ -1,2 +1,23 @@ -!function(e){var t=function(t,n){"use strict";var o=e.document.getElementsByTagName("script")[0],r=e.document.createElement("script");return r.src=t,r.async=!0,o.parentNode.insertBefore(r,o),n&&"function"==typeof n&&(r.onload=n),r};"undefined"!=typeof module?module.exports=t:e.loadJS=t}("undefined"!=typeof global?global:this); +/*! loadJS: load a JS file asynchronously. [c]2014 @scottjehl, Filament Group, Inc. (Based on http://goo.gl/REQGQ by Paul Irish). Licensed MIT */ +(function(w) { + var loadJS = function(src, cb) { + 'use strict'; + var ref = w.document.getElementsByTagName('script')[0]; + var script = w.document.createElement('script'); + script.src = src; + script.async = true; + ref.parentNode.insertBefore(script, ref); + if (cb && typeof cb === 'function') { + script.onload = cb; + } + return script; + }; + // commonjs + if (typeof module !== 'undefined') { + module.exports = loadJS; + } else { + w.loadJS = loadJS; + } +})(typeof global !== 'undefined' ? global : this); + //# sourceMappingURL=loadJS.js.map diff --git a/public/dist/js/loadJS.js.map b/public/dist/js/loadJS.js.map index f15c043..8d6289b 100644 --- a/public/dist/js/loadJS.js.map +++ b/public/dist/js/loadJS.js.map @@ -1 +1 @@ -{"version":3,"sources":["loadJS.js"],"names":["w","loadJS","src","cb","ref","document","getElementsByTagName","script","createElement","async","parentNode","insertBefore","onload","module","exports","global","this"],"mappings":"CACA,SAAUA,GACR,GAAIC,GAAS,SAASC,EAAKC,GACzB,YACA,IAAIC,GAAMJ,EAAEK,SAASC,qBAAqB,UAAU,GAChDC,EAASP,EAAEK,SAASG,cAAc,SAOtC,OANAD,GAAOL,IAAMA,EACbK,EAAOE,OAAQ,EACfL,EAAIM,WAAWC,aAAaJ,EAAQH,GAChCD,GAAoB,kBAAPA,KACfI,EAAOK,OAAST,GAEXI,EAGa,oBAAXM,QACTA,OAAOC,QAAUb,EAEjBD,EAAEC,OAASA,GAEM,mBAAXc,QAAyBA,OAASC","file":"loadJS.js","sourcesContent":["/*! loadJS: load a JS file asynchronously. [c]2014 @scottjehl, Filament Group, Inc. (Based on http://goo.gl/REQGQ by Paul Irish). Licensed MIT */\n(function(w) {\n var loadJS = function(src, cb) {\n 'use strict';\n var ref = w.document.getElementsByTagName('script')[0];\n var script = w.document.createElement('script');\n script.src = src;\n script.async = true;\n ref.parentNode.insertBefore(script, ref);\n if (cb && typeof cb === 'function') {\n script.onload = cb;\n }\n return script;\n };\n // commonjs\n if (typeof module !== 'undefined') {\n module.exports = loadJS;\n } else {\n w.loadJS = loadJS;\n }\n})(typeof global !== 'undefined' ? global : this);\n"]} \ No newline at end of file +{"version":3,"names":[],"mappings":"","sources":["loadJS.js"],"sourcesContent":["/*! loadJS: load a JS file asynchronously. [c]2014 @scottjehl, Filament Group, Inc. (Based on http://goo.gl/REQGQ by Paul Irish). Licensed MIT */\n(function(w) {\n var loadJS = function(src, cb) {\n 'use strict';\n var ref = w.document.getElementsByTagName('script')[0];\n var script = w.document.createElement('script');\n script.src = src;\n script.async = true;\n ref.parentNode.insertBefore(script, ref);\n if (cb && typeof cb === 'function') {\n script.onload = cb;\n }\n return script;\n };\n // commonjs\n if (typeof module !== 'undefined') {\n module.exports = loadJS;\n } else {\n w.loadJS = loadJS;\n }\n})(typeof global !== 'undefined' ? global : this);\n"],"file":"loadJS.js"} \ No newline at end of file diff --git a/public/dist/js/sw-registration.js b/public/dist/js/sw-registration.js index 730fa6e..988d2c7 100644 --- a/public/dist/js/sw-registration.js +++ b/public/dist/js/sw-registration.js @@ -1,2 +1,64 @@ -"use strict";"serviceWorker"in navigator&&window.addEventListener("load",function(){navigator.serviceWorker.register("service-worker.js").then(function(e){e.onupdatefound=function(){var n=e.installing;n.onstatechange=function(){switch(n.state){case"installed":navigator.serviceWorker.controller?console.log("New or updated content is available."):console.log("Content is now available offline!");break;case"redundant":console.error("The installing service worker became redundant.")}}}}).catch(function(e){console.error("Error during service worker registration:",e)})}); +/** + * Copyright 2015 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* eslint-env browser */ +'use strict'; + +if ('serviceWorker' in navigator) { + // Delay registration until after the page has loaded, to ensure that our + // precaching requests don't degrade the first visit experience. + // See https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/registration + window.addEventListener('load', function() { + // Your service-worker.js *must* be located at the top-level directory relative to your site. + // It won't be able to control pages unless it's located at the same level or higher than them. + // *Don't* register service worker file in, e.g., a scripts/ sub-directory! + // See https://github.com/slightlyoff/ServiceWorker/issues/468 + navigator.serviceWorker.register('service-worker.js').then(function(reg) { + // updatefound is fired if service-worker.js changes. + reg.onupdatefound = function() { + // The updatefound event implies that reg.installing is set; see + // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event + var installingWorker = reg.installing; + + installingWorker.onstatechange = function() { + switch (installingWorker.state) { + case 'installed': + if (navigator.serviceWorker.controller) { + // At this point, the old content will have been purged and the fresh content will + // have been added to the cache. + // It's the perfect time to display a "New content is available; please refresh." + // message in the page's interface. + console.log('New or updated content is available.'); + } else { + // At this point, everything has been precached. + // It's the perfect time to display a "Content is cached for offline use." message. + console.log('Content is now available offline!'); + } + break; + + case 'redundant': + console.error('The installing service worker became redundant.'); + break; + } + }; + }; + }).catch(function(e) { + console.error('Error during service worker registration:', e); + }); + }); +} + //# sourceMappingURL=sw-registration.js.map diff --git a/public/dist/js/sw-registration.js.map b/public/dist/js/sw-registration.js.map index 7470abf..c2838b3 100644 --- a/public/dist/js/sw-registration.js.map +++ b/public/dist/js/sw-registration.js.map @@ -1 +1 @@ -{"version":3,"sources":["sw-registration.js"],"names":["navigator","window","addEventListener","serviceWorker","register","then","reg","onupdatefound","installingWorker","installing","onstatechange","state","controller","console","log","error","catch","e"],"mappings":"AAiBA,YAEI,kBAAmBA,YAIrBC,OAAOC,iBAAiB,OAAQ,WAK9BF,UAAUG,cAAcC,SAAS,qBAAqBC,KAAK,SAASC,GAElEA,EAAIC,cAAgB,WAGlB,GAAIC,GAAmBF,EAAIG,UAE3BD,GAAiBE,cAAgB,WAC/B,OAAQF,EAAiBG,OACvB,IAAK,YACCX,UAAUG,cAAcS,WAK1BC,QAAQC,IAAI,wCAIZD,QAAQC,IAAI,oCAEd,MAEF,KAAK,YACHD,QAAQE,MAAM,wDAKrBC,MAAM,SAASC,GAChBJ,QAAQE,MAAM,4CAA6CE","file":"sw-registration.js","sourcesContent":["/**\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* eslint-env browser */\n'use strict';\n\nif ('serviceWorker' in navigator) {\n // Delay registration until after the page has loaded, to ensure that our\n // precaching requests don't degrade the first visit experience.\n // See https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/registration\n window.addEventListener('load', function() {\n // Your service-worker.js *must* be located at the top-level directory relative to your site.\n // It won't be able to control pages unless it's located at the same level or higher than them.\n // *Don't* register service worker file in, e.g., a scripts/ sub-directory!\n // See https://github.com/slightlyoff/ServiceWorker/issues/468\n navigator.serviceWorker.register('service-worker.js').then(function(reg) {\n // updatefound is fired if service-worker.js changes.\n reg.onupdatefound = function() {\n // The updatefound event implies that reg.installing is set; see\n // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event\n var installingWorker = reg.installing;\n\n installingWorker.onstatechange = function() {\n switch (installingWorker.state) {\n case 'installed':\n if (navigator.serviceWorker.controller) {\n // At this point, the old content will have been purged and the fresh content will\n // have been added to the cache.\n // It's the perfect time to display a \"New content is available; please refresh.\"\n // message in the page's interface.\n console.log('New or updated content is available.');\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a \"Content is cached for offline use.\" message.\n console.log('Content is now available offline!');\n }\n break;\n\n case 'redundant':\n console.error('The installing service worker became redundant.');\n break;\n }\n };\n };\n }).catch(function(e) {\n console.error('Error during service worker registration:', e);\n });\n });\n}\n"]} \ No newline at end of file +{"version":3,"names":[],"mappings":"","sources":["sw-registration.js"],"sourcesContent":["/**\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* eslint-env browser */\n'use strict';\n\nif ('serviceWorker' in navigator) {\n // Delay registration until after the page has loaded, to ensure that our\n // precaching requests don't degrade the first visit experience.\n // See https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/registration\n window.addEventListener('load', function() {\n // Your service-worker.js *must* be located at the top-level directory relative to your site.\n // It won't be able to control pages unless it's located at the same level or higher than them.\n // *Don't* register service worker file in, e.g., a scripts/ sub-directory!\n // See https://github.com/slightlyoff/ServiceWorker/issues/468\n navigator.serviceWorker.register('service-worker.js').then(function(reg) {\n // updatefound is fired if service-worker.js changes.\n reg.onupdatefound = function() {\n // The updatefound event implies that reg.installing is set; see\n // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event\n var installingWorker = reg.installing;\n\n installingWorker.onstatechange = function() {\n switch (installingWorker.state) {\n case 'installed':\n if (navigator.serviceWorker.controller) {\n // At this point, the old content will have been purged and the fresh content will\n // have been added to the cache.\n // It's the perfect time to display a \"New content is available; please refresh.\"\n // message in the page's interface.\n console.log('New or updated content is available.');\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a \"Content is cached for offline use.\" message.\n console.log('Content is now available offline!');\n }\n break;\n\n case 'redundant':\n console.error('The installing service worker became redundant.');\n break;\n }\n };\n };\n }).catch(function(e) {\n console.error('Error during service worker registration:', e);\n });\n });\n}\n"],"file":"sw-registration.js"} \ No newline at end of file diff --git a/public/service-worker.js b/public/service-worker.js index f772c3b..05f8b8d 100644 --- a/public/service-worker.js +++ b/public/service-worker.js @@ -1,6 +1,2 @@ -<<<<<<< HEAD -"use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}var precacheConfig=[["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","a70702eeea1dbe4a401b7c23189eb7d3"],["/dist/js/bundle.min.js","5a4878a0d8d1655d9f3edbc1aee091b7"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]],cacheName="sw-precache-v3--"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(e){return e.redirected?("body"in e?Promise.resolve(e.body):e.blob()).then(function(t){return new Response(t,{headers:e.headers,status:e.status,statusText:e.statusText})}):Promise.resolve(e)},createCacheKey=function(e,t,n,r){var a=new URL(e);return r&&a.pathname.match(r)||(a.search+=(a.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),a.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,t){var n=new URL(e);return n.hash="",n.search=n.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),n.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],r=new URL(t,self.location),a=createCacheKey(r,hashParamName,n,!1);return[r.toString(),a]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(n){if(!t.has(n)){var r=new Request(n,{credentials:"same-origin"});return fetch(r).then(function(t){if(!t.ok)throw new Error("Request for "+n+" returned a response with status "+t.status);return cleanResponse(t).then(function(t){return e.put(n,t)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(n){return Promise.all(n.map(function(n){if(!t.has(n.url))return e.delete(n)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,n=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);t=urlsToCacheKeys.has(n);t||(n=addDirectoryIndex(n,"index.html"),t=urlsToCacheKeys.has(n));t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}); -======= -"use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}var precacheConfig=[["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","a70702eeea1dbe4a401b7c23189eb7d3"],["/dist/js/bundle.min.js","b811fe18d2d6a402297a71172a324d69"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]],cacheName="sw-precache-v3--"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(e){return e.redirected?("body"in e?Promise.resolve(e.body):e.blob()).then(function(t){return new Response(t,{headers:e.headers,status:e.status,statusText:e.statusText})}):Promise.resolve(e)},createCacheKey=function(e,t,n,r){var a=new URL(e);return r&&a.pathname.match(r)||(a.search+=(a.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),a.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,t){var n=new URL(e);return n.hash="",n.search=n.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),n.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],r=new URL(t,self.location),a=createCacheKey(r,hashParamName,n,!1);return[r.toString(),a]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(n){if(!t.has(n)){var r=new Request(n,{credentials:"same-origin"});return fetch(r).then(function(t){if(!t.ok)throw new Error("Request for "+n+" returned a response with status "+t.status);return cleanResponse(t).then(function(t){return e.put(n,t)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(n){return Promise.all(n.map(function(n){if(!t.has(n.url))return e.delete(n)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,n=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);t=urlsToCacheKeys.has(n);t||(n=addDirectoryIndex(n,"index.html"),t=urlsToCacheKeys.has(n));t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}); ->>>>>>> working import of external problem content +"use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}var precacheConfig=[["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","7c1a8058bb3d00c2b40283c735748cfc"],["/dist/js/bundle.min.js","c0432a6b64b4d59efc450a7b1e2c2de7"],["/dist/js/loadJS.js","4b1605ca6e570c4998be14c665ef2b27"],["/dist/js/sw-registration.js","3fb568bd69af5b3de5a7122333c215b9"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]],cacheName="sw-precache-v3--"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(e){return e.redirected?("body"in e?Promise.resolve(e.body):e.blob()).then(function(t){return new Response(t,{headers:e.headers,status:e.status,statusText:e.statusText})}):Promise.resolve(e)},createCacheKey=function(e,t,n,r){var a=new URL(e);return r&&a.pathname.match(r)||(a.search+=(a.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),a.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,t){var n=new URL(e);return n.hash="",n.search=n.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),n.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],r=new URL(t,self.location),a=createCacheKey(r,hashParamName,n,!1);return[r.toString(),a]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(n){if(!t.has(n)){var r=new Request(n,{credentials:"same-origin"});return fetch(r).then(function(t){if(!t.ok)throw new Error("Request for "+n+" returned a response with status "+t.status);return cleanResponse(t).then(function(t){return e.put(n,t)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(n){return Promise.all(n.map(function(n){if(!t.has(n.url))return e.delete(n)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,n=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);(t=urlsToCacheKeys.has(n))||(n=addDirectoryIndex(n,"index.html"),t=urlsToCacheKeys.has(n));t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}); //# sourceMappingURL=service-worker.js.map diff --git a/public/service-worker.js.map b/public/service-worker.js.map index 7f72169..2ebc3bd 100644 --- a/public/service-worker.js.map +++ b/public/service-worker.js.map @@ -1,5 +1 @@ -<<<<<<< HEAD -{"version":3,"sources":["service-worker.js"],"names":["setOfCachedUrls","cache","keys","then","requests","map","request","url","urls","Set","precacheConfig","cacheName","self","registration","scope","ignoreUrlParametersMatching","addDirectoryIndex","originalUrl","index","URL","pathname","slice","toString","cleanResponse","originalResponse","redirected","Promise","resolve","body","blob","Response","headers","status","statusText","createCacheKey","paramName","paramValue","dontCacheBustUrlsMatching","match","search","encodeURIComponent","isPathWhitelisted","whitelist","absoluteUrlString","length","path","some","whitelistedPathRegex","stripIgnoredUrlParameters","hash","split","kv","filter","every","ignoredRegex","test","join","hashParamName","urlsToCacheKeys","Map","item","relativeUrl","absoluteUrl","location","cacheKey","addEventListener","event","waitUntil","caches","open","cachedUrls","all","Array","from","values","has","Request","credentials","fetch","response","ok","Error","responseToCache","put","skipWaiting","setOfExpectedUrls","existingRequests","existingRequest","delete","clients","claim","method","shouldRespond","respondWith","get","catch","e","console","warn"],"mappings":"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","file":"service-worker.js","sourcesContent":["/**\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n*/\n\n// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY!\n// This file should be overwritten as part of your build process.\n// If you need to extend the behavior of the generated service worker, the best approach is to write\n// additional code and include it using the importScripts option:\n// https://github.com/GoogleChrome/sw-precache#importscripts-arraystring\n//\n// Alternatively, it's possible to make changes to the underlying template file and then use that as the\n// new base for generating output, via the templateFilePath option:\n// https://github.com/GoogleChrome/sw-precache#templatefilepath-string\n//\n// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any\n// changes made to this original template file with your modified copy.\n\n// This generated service worker JavaScript will precache your site's resources.\n// The code needs to be saved in a .js file at the top-level of your site, and registered\n// from your pages in order to be used. See\n// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js\n// for an example of how you can register this script and handle various service worker events.\n\n/* eslint-env worker, serviceworker */\n/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */\n'use strict';\n\nvar precacheConfig = [[\"/dist/css/style.css\",\"ba4d66c91d1ed66848154a34ab4948cf\"],[\"/dist/img/back.svg\",\"898ada2a32ec64bd5b6959c22e8f231d\"],[\"/dist/img/monitor.svg\",\"348592da5567b5a3c46acfb5dcd341bc\"],[\"/dist/img/next.svg\",\"045593410b9f51390e750b9e1e7fff15\"],[\"/dist/img/reload.svg\",\"a0ab1b765280e4d22e6fb747042f6503\"],[\"/dist/img/shuffle.svg\",\"3a5e3c1bf04eb3493d8a2ffa547aa58f\"],[\"/dist/img/social-banner.png\",\"a70702eeea1dbe4a401b7c23189eb7d3\"],[\"/dist/js/bundle.min.js\",\"5a4878a0d8d1655d9f3edbc1aee091b7\"],[\"/dist/js/loadJS.js\",\"72c55936069f60560a386e46f462c73a\"],[\"/dist/js/sw-registration.js\",\"677217d8e642c1ccff69fc01c96b4431\"],[\"/index.html\",\"c7522a5d3255caca0f12c5282ef0644d\"]];\nvar cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');\n\n\nvar ignoreUrlParametersMatching = [/^utm_/];\n\n\n\nvar addDirectoryIndex = function (originalUrl, index) {\n var url = new URL(originalUrl);\n if (url.pathname.slice(-1) === '/') {\n url.pathname += index;\n }\n return url.toString();\n };\n\nvar cleanResponse = function (originalResponse) {\n // If this is not a redirected response, then we don't have to do anything.\n if (!originalResponse.redirected) {\n return Promise.resolve(originalResponse);\n }\n\n // Firefox 50 and below doesn't support the Response.body stream, so we may\n // need to read the entire body to memory as a Blob.\n var bodyPromise = 'body' in originalResponse ?\n Promise.resolve(originalResponse.body) :\n originalResponse.blob();\n\n return bodyPromise.then(function(body) {\n // new Response() is happy when passed either a stream or a Blob.\n return new Response(body, {\n headers: originalResponse.headers,\n status: originalResponse.status,\n statusText: originalResponse.statusText\n });\n });\n };\n\nvar createCacheKey = function (originalUrl, paramName, paramValue,\n dontCacheBustUrlsMatching) {\n // Create a new URL object to avoid modifying originalUrl.\n var url = new URL(originalUrl);\n\n // If dontCacheBustUrlsMatching is not set, or if we don't have a match,\n // then add in the extra cache-busting URL parameter.\n if (!dontCacheBustUrlsMatching ||\n !(url.pathname.match(dontCacheBustUrlsMatching))) {\n url.search += (url.search ? '&' : '') +\n encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);\n }\n\n return url.toString();\n };\n\nvar isPathWhitelisted = function (whitelist, absoluteUrlString) {\n // If the whitelist is empty, then consider all URLs to be whitelisted.\n if (whitelist.length === 0) {\n return true;\n }\n\n // Otherwise compare each path regex to the path of the URL passed in.\n var path = (new URL(absoluteUrlString)).pathname;\n return whitelist.some(function(whitelistedPathRegex) {\n return path.match(whitelistedPathRegex);\n });\n };\n\nvar stripIgnoredUrlParameters = function (originalUrl,\n ignoreUrlParametersMatching) {\n var url = new URL(originalUrl);\n // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290\n url.hash = '';\n\n url.search = url.search.slice(1) // Exclude initial '?'\n .split('&') // Split into an array of 'key=value' strings\n .map(function(kv) {\n return kv.split('='); // Split each 'key=value' string into a [key, value] array\n })\n .filter(function(kv) {\n return ignoreUrlParametersMatching.every(function(ignoredRegex) {\n return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.\n });\n })\n .map(function(kv) {\n return kv.join('='); // Join each [key, value] array into a 'key=value' string\n })\n .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each\n\n return url.toString();\n };\n\n\nvar hashParamName = '_sw-precache';\nvar urlsToCacheKeys = new Map(\n precacheConfig.map(function(item) {\n var relativeUrl = item[0];\n var hash = item[1];\n var absoluteUrl = new URL(relativeUrl, self.location);\n var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);\n return [absoluteUrl.toString(), cacheKey];\n })\n);\n\nfunction setOfCachedUrls(cache) {\n return cache.keys().then(function(requests) {\n return requests.map(function(request) {\n return request.url;\n });\n }).then(function(urls) {\n return new Set(urls);\n });\n}\n\nself.addEventListener('install', function(event) {\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return setOfCachedUrls(cache).then(function(cachedUrls) {\n return Promise.all(\n Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {\n // If we don't have a key matching url in the cache already, add it.\n if (!cachedUrls.has(cacheKey)) {\n var request = new Request(cacheKey, {credentials: 'same-origin'});\n return fetch(request).then(function(response) {\n // Bail out of installation unless we get back a 200 OK for\n // every request.\n if (!response.ok) {\n throw new Error('Request for ' + cacheKey + ' returned a ' +\n 'response with status ' + response.status);\n }\n\n return cleanResponse(response).then(function(responseToCache) {\n return cache.put(cacheKey, responseToCache);\n });\n });\n }\n })\n );\n });\n }).then(function() {\n \n // Force the SW to transition from installing -> active state\n return self.skipWaiting();\n \n })\n );\n});\n\nself.addEventListener('activate', function(event) {\n var setOfExpectedUrls = new Set(urlsToCacheKeys.values());\n\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return cache.keys().then(function(existingRequests) {\n return Promise.all(\n existingRequests.map(function(existingRequest) {\n if (!setOfExpectedUrls.has(existingRequest.url)) {\n return cache.delete(existingRequest);\n }\n })\n );\n });\n }).then(function() {\n \n return self.clients.claim();\n \n })\n );\n});\n\n\nself.addEventListener('fetch', function(event) {\n if (event.request.method === 'GET') {\n // Should we call event.respondWith() inside this fetch event handler?\n // This needs to be determined synchronously, which will give other fetch\n // handlers a chance to handle the request if need be.\n var shouldRespond;\n\n // First, remove all the ignored parameters and hash fragment, and see if we\n // have that URL in our cache. If so, great! shouldRespond will be true.\n var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);\n shouldRespond = urlsToCacheKeys.has(url);\n\n // If shouldRespond is false, check again, this time with 'index.html'\n // (or whatever the directoryIndex option is set to) at the end.\n var directoryIndex = 'index.html';\n if (!shouldRespond && directoryIndex) {\n url = addDirectoryIndex(url, directoryIndex);\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond is still false, check to see if this is a navigation\n // request, and if so, whether the URL matches navigateFallbackWhitelist.\n var navigateFallback = '';\n if (!shouldRespond &&\n navigateFallback &&\n (event.request.mode === 'navigate') &&\n isPathWhitelisted([], event.request.url)) {\n url = new URL(navigateFallback, self.location).toString();\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond was set to true at any point, then call\n // event.respondWith(), using the appropriate cache key.\n if (shouldRespond) {\n event.respondWith(\n caches.open(cacheName).then(function(cache) {\n return cache.match(urlsToCacheKeys.get(url)).then(function(response) {\n if (response) {\n return response;\n }\n throw Error('The cached response that was expected is missing.');\n });\n }).catch(function(e) {\n // Fall back to just fetch()ing the request if some unexpected error\n // prevented the cached response from being valid.\n console.warn('Couldn\\'t serve response for \"%s\" from cache: %O', event.request.url, e);\n return fetch(event.request);\n })\n );\n }\n }\n});\n\n\n\n\n\n\n\n"]} -======= -{"version":3,"sources":["service-worker.js"],"names":["setOfCachedUrls","cache","keys","then","requests","map","request","url","urls","Set","precacheConfig","cacheName","self","registration","scope","ignoreUrlParametersMatching","addDirectoryIndex","originalUrl","index","URL","pathname","slice","toString","cleanResponse","originalResponse","redirected","Promise","resolve","body","blob","Response","headers","status","statusText","createCacheKey","paramName","paramValue","dontCacheBustUrlsMatching","match","search","encodeURIComponent","isPathWhitelisted","whitelist","absoluteUrlString","length","path","some","whitelistedPathRegex","stripIgnoredUrlParameters","hash","split","kv","filter","every","ignoredRegex","test","join","hashParamName","urlsToCacheKeys","Map","item","relativeUrl","absoluteUrl","location","cacheKey","addEventListener","event","waitUntil","caches","open","cachedUrls","all","Array","from","values","has","Request","credentials","fetch","response","ok","Error","responseToCache","put","skipWaiting","setOfExpectedUrls","existingRequests","existingRequest","delete","clients","claim","method","shouldRespond","respondWith","get","catch","e","console","warn"],"mappings":"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","file":"service-worker.js","sourcesContent":["/**\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n*/\n\n// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY!\n// This file should be overwritten as part of your build process.\n// If you need to extend the behavior of the generated service worker, the best approach is to write\n// additional code and include it using the importScripts option:\n// https://github.com/GoogleChrome/sw-precache#importscripts-arraystring\n//\n// Alternatively, it's possible to make changes to the underlying template file and then use that as the\n// new base for generating output, via the templateFilePath option:\n// https://github.com/GoogleChrome/sw-precache#templatefilepath-string\n//\n// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any\n// changes made to this original template file with your modified copy.\n\n// This generated service worker JavaScript will precache your site's resources.\n// The code needs to be saved in a .js file at the top-level of your site, and registered\n// from your pages in order to be used. See\n// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js\n// for an example of how you can register this script and handle various service worker events.\n\n/* eslint-env worker, serviceworker */\n/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */\n'use strict';\n\nvar precacheConfig = [[\"/dist/css/style.css\",\"ba4d66c91d1ed66848154a34ab4948cf\"],[\"/dist/img/back.svg\",\"898ada2a32ec64bd5b6959c22e8f231d\"],[\"/dist/img/monitor.svg\",\"348592da5567b5a3c46acfb5dcd341bc\"],[\"/dist/img/next.svg\",\"045593410b9f51390e750b9e1e7fff15\"],[\"/dist/img/reload.svg\",\"a0ab1b765280e4d22e6fb747042f6503\"],[\"/dist/img/shuffle.svg\",\"3a5e3c1bf04eb3493d8a2ffa547aa58f\"],[\"/dist/img/social-banner.png\",\"a70702eeea1dbe4a401b7c23189eb7d3\"],[\"/dist/js/bundle.min.js\",\"b811fe18d2d6a402297a71172a324d69\"],[\"/dist/js/loadJS.js\",\"72c55936069f60560a386e46f462c73a\"],[\"/dist/js/sw-registration.js\",\"677217d8e642c1ccff69fc01c96b4431\"],[\"/index.html\",\"c7522a5d3255caca0f12c5282ef0644d\"]];\nvar cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');\n\n\nvar ignoreUrlParametersMatching = [/^utm_/];\n\n\n\nvar addDirectoryIndex = function (originalUrl, index) {\n var url = new URL(originalUrl);\n if (url.pathname.slice(-1) === '/') {\n url.pathname += index;\n }\n return url.toString();\n };\n\nvar cleanResponse = function (originalResponse) {\n // If this is not a redirected response, then we don't have to do anything.\n if (!originalResponse.redirected) {\n return Promise.resolve(originalResponse);\n }\n\n // Firefox 50 and below doesn't support the Response.body stream, so we may\n // need to read the entire body to memory as a Blob.\n var bodyPromise = 'body' in originalResponse ?\n Promise.resolve(originalResponse.body) :\n originalResponse.blob();\n\n return bodyPromise.then(function(body) {\n // new Response() is happy when passed either a stream or a Blob.\n return new Response(body, {\n headers: originalResponse.headers,\n status: originalResponse.status,\n statusText: originalResponse.statusText\n });\n });\n };\n\nvar createCacheKey = function (originalUrl, paramName, paramValue,\n dontCacheBustUrlsMatching) {\n // Create a new URL object to avoid modifying originalUrl.\n var url = new URL(originalUrl);\n\n // If dontCacheBustUrlsMatching is not set, or if we don't have a match,\n // then add in the extra cache-busting URL parameter.\n if (!dontCacheBustUrlsMatching ||\n !(url.pathname.match(dontCacheBustUrlsMatching))) {\n url.search += (url.search ? '&' : '') +\n encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);\n }\n\n return url.toString();\n };\n\nvar isPathWhitelisted = function (whitelist, absoluteUrlString) {\n // If the whitelist is empty, then consider all URLs to be whitelisted.\n if (whitelist.length === 0) {\n return true;\n }\n\n // Otherwise compare each path regex to the path of the URL passed in.\n var path = (new URL(absoluteUrlString)).pathname;\n return whitelist.some(function(whitelistedPathRegex) {\n return path.match(whitelistedPathRegex);\n });\n };\n\nvar stripIgnoredUrlParameters = function (originalUrl,\n ignoreUrlParametersMatching) {\n var url = new URL(originalUrl);\n // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290\n url.hash = '';\n\n url.search = url.search.slice(1) // Exclude initial '?'\n .split('&') // Split into an array of 'key=value' strings\n .map(function(kv) {\n return kv.split('='); // Split each 'key=value' string into a [key, value] array\n })\n .filter(function(kv) {\n return ignoreUrlParametersMatching.every(function(ignoredRegex) {\n return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.\n });\n })\n .map(function(kv) {\n return kv.join('='); // Join each [key, value] array into a 'key=value' string\n })\n .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each\n\n return url.toString();\n };\n\n\nvar hashParamName = '_sw-precache';\nvar urlsToCacheKeys = new Map(\n precacheConfig.map(function(item) {\n var relativeUrl = item[0];\n var hash = item[1];\n var absoluteUrl = new URL(relativeUrl, self.location);\n var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);\n return [absoluteUrl.toString(), cacheKey];\n })\n);\n\nfunction setOfCachedUrls(cache) {\n return cache.keys().then(function(requests) {\n return requests.map(function(request) {\n return request.url;\n });\n }).then(function(urls) {\n return new Set(urls);\n });\n}\n\nself.addEventListener('install', function(event) {\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return setOfCachedUrls(cache).then(function(cachedUrls) {\n return Promise.all(\n Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {\n // If we don't have a key matching url in the cache already, add it.\n if (!cachedUrls.has(cacheKey)) {\n var request = new Request(cacheKey, {credentials: 'same-origin'});\n return fetch(request).then(function(response) {\n // Bail out of installation unless we get back a 200 OK for\n // every request.\n if (!response.ok) {\n throw new Error('Request for ' + cacheKey + ' returned a ' +\n 'response with status ' + response.status);\n }\n\n return cleanResponse(response).then(function(responseToCache) {\n return cache.put(cacheKey, responseToCache);\n });\n });\n }\n })\n );\n });\n }).then(function() {\n \n // Force the SW to transition from installing -> active state\n return self.skipWaiting();\n \n })\n );\n});\n\nself.addEventListener('activate', function(event) {\n var setOfExpectedUrls = new Set(urlsToCacheKeys.values());\n\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return cache.keys().then(function(existingRequests) {\n return Promise.all(\n existingRequests.map(function(existingRequest) {\n if (!setOfExpectedUrls.has(existingRequest.url)) {\n return cache.delete(existingRequest);\n }\n })\n );\n });\n }).then(function() {\n \n return self.clients.claim();\n \n })\n );\n});\n\n\nself.addEventListener('fetch', function(event) {\n if (event.request.method === 'GET') {\n // Should we call event.respondWith() inside this fetch event handler?\n // This needs to be determined synchronously, which will give other fetch\n // handlers a chance to handle the request if need be.\n var shouldRespond;\n\n // First, remove all the ignored parameters and hash fragment, and see if we\n // have that URL in our cache. If so, great! shouldRespond will be true.\n var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);\n shouldRespond = urlsToCacheKeys.has(url);\n\n // If shouldRespond is false, check again, this time with 'index.html'\n // (or whatever the directoryIndex option is set to) at the end.\n var directoryIndex = 'index.html';\n if (!shouldRespond && directoryIndex) {\n url = addDirectoryIndex(url, directoryIndex);\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond is still false, check to see if this is a navigation\n // request, and if so, whether the URL matches navigateFallbackWhitelist.\n var navigateFallback = '';\n if (!shouldRespond &&\n navigateFallback &&\n (event.request.mode === 'navigate') &&\n isPathWhitelisted([], event.request.url)) {\n url = new URL(navigateFallback, self.location).toString();\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond was set to true at any point, then call\n // event.respondWith(), using the appropriate cache key.\n if (shouldRespond) {\n event.respondWith(\n caches.open(cacheName).then(function(cache) {\n return cache.match(urlsToCacheKeys.get(url)).then(function(response) {\n if (response) {\n return response;\n }\n throw Error('The cached response that was expected is missing.');\n });\n }).catch(function(e) {\n // Fall back to just fetch()ing the request if some unexpected error\n // prevented the cached response from being valid.\n console.warn('Couldn\\'t serve response for \"%s\" from cache: %O', event.request.url, e);\n return fetch(event.request);\n })\n );\n }\n }\n});\n\n\n\n\n\n\n\n"]} ->>>>>>> working import of external problem content +{"version":3,"sources":["service-worker.js"],"names":["setOfCachedUrls","cache","keys","then","requests","map","request","url","urls","Set","precacheConfig","cacheName","self","registration","scope","ignoreUrlParametersMatching","addDirectoryIndex","originalUrl","index","URL","pathname","slice","toString","cleanResponse","originalResponse","redirected","Promise","resolve","body","blob","Response","headers","status","statusText","createCacheKey","paramName","paramValue","dontCacheBustUrlsMatching","match","search","encodeURIComponent","isPathWhitelisted","whitelist","absoluteUrlString","length","path","some","whitelistedPathRegex","stripIgnoredUrlParameters","hash","split","kv","filter","every","ignoredRegex","test","join","hashParamName","urlsToCacheKeys","Map","item","relativeUrl","absoluteUrl","location","cacheKey","addEventListener","event","waitUntil","caches","open","cachedUrls","all","Array","from","values","has","Request","credentials","fetch","response","ok","Error","responseToCache","put","skipWaiting","setOfExpectedUrls","existingRequests","existingRequest","delete","clients","claim","method","shouldRespond","respondWith","get","catch","e","console","warn"],"mappings":"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","file":"service-worker.js","sourcesContent":["/**\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n*/\n\n// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY!\n// This file should be overwritten as part of your build process.\n// If you need to extend the behavior of the generated service worker, the best approach is to write\n// additional code and include it using the importScripts option:\n// https://github.com/GoogleChrome/sw-precache#importscripts-arraystring\n//\n// Alternatively, it's possible to make changes to the underlying template file and then use that as the\n// new base for generating output, via the templateFilePath option:\n// https://github.com/GoogleChrome/sw-precache#templatefilepath-string\n//\n// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any\n// changes made to this original template file with your modified copy.\n\n// This generated service worker JavaScript will precache your site's resources.\n// The code needs to be saved in a .js file at the top-level of your site, and registered\n// from your pages in order to be used. See\n// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js\n// for an example of how you can register this script and handle various service worker events.\n\n/* eslint-env worker, serviceworker */\n/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */\n'use strict';\n\nvar precacheConfig = [[\"/dist/css/style.css\",\"ba4d66c91d1ed66848154a34ab4948cf\"],[\"/dist/img/back.svg\",\"898ada2a32ec64bd5b6959c22e8f231d\"],[\"/dist/img/monitor.svg\",\"348592da5567b5a3c46acfb5dcd341bc\"],[\"/dist/img/next.svg\",\"045593410b9f51390e750b9e1e7fff15\"],[\"/dist/img/reload.svg\",\"a0ab1b765280e4d22e6fb747042f6503\"],[\"/dist/img/shuffle.svg\",\"3a5e3c1bf04eb3493d8a2ffa547aa58f\"],[\"/dist/img/social-banner.png\",\"7c1a8058bb3d00c2b40283c735748cfc\"],[\"/dist/js/bundle.min.js\",\"c0432a6b64b4d59efc450a7b1e2c2de7\"],[\"/dist/js/loadJS.js\",\"4b1605ca6e570c4998be14c665ef2b27\"],[\"/dist/js/sw-registration.js\",\"3fb568bd69af5b3de5a7122333c215b9\"],[\"/index.html\",\"c7522a5d3255caca0f12c5282ef0644d\"]];\nvar cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');\n\n\nvar ignoreUrlParametersMatching = [/^utm_/];\n\n\n\nvar addDirectoryIndex = function (originalUrl, index) {\n var url = new URL(originalUrl);\n if (url.pathname.slice(-1) === '/') {\n url.pathname += index;\n }\n return url.toString();\n };\n\nvar cleanResponse = function (originalResponse) {\n // If this is not a redirected response, then we don't have to do anything.\n if (!originalResponse.redirected) {\n return Promise.resolve(originalResponse);\n }\n\n // Firefox 50 and below doesn't support the Response.body stream, so we may\n // need to read the entire body to memory as a Blob.\n var bodyPromise = 'body' in originalResponse ?\n Promise.resolve(originalResponse.body) :\n originalResponse.blob();\n\n return bodyPromise.then(function(body) {\n // new Response() is happy when passed either a stream or a Blob.\n return new Response(body, {\n headers: originalResponse.headers,\n status: originalResponse.status,\n statusText: originalResponse.statusText\n });\n });\n };\n\nvar createCacheKey = function (originalUrl, paramName, paramValue,\n dontCacheBustUrlsMatching) {\n // Create a new URL object to avoid modifying originalUrl.\n var url = new URL(originalUrl);\n\n // If dontCacheBustUrlsMatching is not set, or if we don't have a match,\n // then add in the extra cache-busting URL parameter.\n if (!dontCacheBustUrlsMatching ||\n !(url.pathname.match(dontCacheBustUrlsMatching))) {\n url.search += (url.search ? '&' : '') +\n encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);\n }\n\n return url.toString();\n };\n\nvar isPathWhitelisted = function (whitelist, absoluteUrlString) {\n // If the whitelist is empty, then consider all URLs to be whitelisted.\n if (whitelist.length === 0) {\n return true;\n }\n\n // Otherwise compare each path regex to the path of the URL passed in.\n var path = (new URL(absoluteUrlString)).pathname;\n return whitelist.some(function(whitelistedPathRegex) {\n return path.match(whitelistedPathRegex);\n });\n };\n\nvar stripIgnoredUrlParameters = function (originalUrl,\n ignoreUrlParametersMatching) {\n var url = new URL(originalUrl);\n // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290\n url.hash = '';\n\n url.search = url.search.slice(1) // Exclude initial '?'\n .split('&') // Split into an array of 'key=value' strings\n .map(function(kv) {\n return kv.split('='); // Split each 'key=value' string into a [key, value] array\n })\n .filter(function(kv) {\n return ignoreUrlParametersMatching.every(function(ignoredRegex) {\n return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.\n });\n })\n .map(function(kv) {\n return kv.join('='); // Join each [key, value] array into a 'key=value' string\n })\n .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each\n\n return url.toString();\n };\n\n\nvar hashParamName = '_sw-precache';\nvar urlsToCacheKeys = new Map(\n precacheConfig.map(function(item) {\n var relativeUrl = item[0];\n var hash = item[1];\n var absoluteUrl = new URL(relativeUrl, self.location);\n var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);\n return [absoluteUrl.toString(), cacheKey];\n })\n);\n\nfunction setOfCachedUrls(cache) {\n return cache.keys().then(function(requests) {\n return requests.map(function(request) {\n return request.url;\n });\n }).then(function(urls) {\n return new Set(urls);\n });\n}\n\nself.addEventListener('install', function(event) {\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return setOfCachedUrls(cache).then(function(cachedUrls) {\n return Promise.all(\n Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {\n // If we don't have a key matching url in the cache already, add it.\n if (!cachedUrls.has(cacheKey)) {\n var request = new Request(cacheKey, {credentials: 'same-origin'});\n return fetch(request).then(function(response) {\n // Bail out of installation unless we get back a 200 OK for\n // every request.\n if (!response.ok) {\n throw new Error('Request for ' + cacheKey + ' returned a ' +\n 'response with status ' + response.status);\n }\n\n return cleanResponse(response).then(function(responseToCache) {\n return cache.put(cacheKey, responseToCache);\n });\n });\n }\n })\n );\n });\n }).then(function() {\n \n // Force the SW to transition from installing -> active state\n return self.skipWaiting();\n \n })\n );\n});\n\nself.addEventListener('activate', function(event) {\n var setOfExpectedUrls = new Set(urlsToCacheKeys.values());\n\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return cache.keys().then(function(existingRequests) {\n return Promise.all(\n existingRequests.map(function(existingRequest) {\n if (!setOfExpectedUrls.has(existingRequest.url)) {\n return cache.delete(existingRequest);\n }\n })\n );\n });\n }).then(function() {\n \n return self.clients.claim();\n \n })\n );\n});\n\n\nself.addEventListener('fetch', function(event) {\n if (event.request.method === 'GET') {\n // Should we call event.respondWith() inside this fetch event handler?\n // This needs to be determined synchronously, which will give other fetch\n // handlers a chance to handle the request if need be.\n var shouldRespond;\n\n // First, remove all the ignored parameters and hash fragment, and see if we\n // have that URL in our cache. If so, great! shouldRespond will be true.\n var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);\n shouldRespond = urlsToCacheKeys.has(url);\n\n // If shouldRespond is false, check again, this time with 'index.html'\n // (or whatever the directoryIndex option is set to) at the end.\n var directoryIndex = 'index.html';\n if (!shouldRespond && directoryIndex) {\n url = addDirectoryIndex(url, directoryIndex);\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond is still false, check to see if this is a navigation\n // request, and if so, whether the URL matches navigateFallbackWhitelist.\n var navigateFallback = '';\n if (!shouldRespond &&\n navigateFallback &&\n (event.request.mode === 'navigate') &&\n isPathWhitelisted([], event.request.url)) {\n url = new URL(navigateFallback, self.location).toString();\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond was set to true at any point, then call\n // event.respondWith(), using the appropriate cache key.\n if (shouldRespond) {\n event.respondWith(\n caches.open(cacheName).then(function(cache) {\n return cache.match(urlsToCacheKeys.get(url)).then(function(response) {\n if (response) {\n return response;\n }\n throw Error('The cached response that was expected is missing.');\n });\n }).catch(function(e) {\n // Fall back to just fetch()ing the request if some unexpected error\n // prevented the cached response from being valid.\n console.warn('Couldn\\'t serve response for \"%s\" from cache: %O', event.request.url, e);\n return fetch(event.request);\n })\n );\n }\n }\n});\n\n\n\n\n\n\n\n"]} \ No newline at end of file diff --git a/shrinkwrap.yaml b/shrinkwrap.yaml index 7be6888..9319604 100644 --- a/shrinkwrap.yaml +++ b/shrinkwrap.yaml @@ -3,34 +3,39 @@ dependencies: autoprefixer@^6.7.7: 6.7.7 ava@^0.18.2: 0.18.2 babel-core@^6.24.0: 6.24.1 + babel-preset-env@^1.4.0: 1.5.1 babel-preset-es2015@^6.24.1: 6.24.1 babel-preset-es2017@^6.24.1: 6.24.1 babel-preset-latest@^6.24.1: 6.24.1 babelify@^7.3.0: 7.3.0 - browserify@^14.1.0: 14.4.0 + browserify@^14.3.0: 14.4.0 chai@^3.5.0: 3.5.0 cssnano@^3.10.0: 3.10.0 dedent@^0.7.0: 0.7.0 gulp-bro@^1.0.2: 1.0.2 + gulp-htmlmin@^3.0.0: 3.0.0 + gulp-image@^2.8.0: 2.9.0 gulp-livereload@^3.8.1: 3.8.1 gulp-postcss@^6.4.0: 6.4.0 gulp-sass@^3.1.0: 3.1.0 - gulp-sourcemaps@^2.5.1: 2.6.0 + gulp-sourcemaps@^2.6.0: 2.6.0 gulp-svgo@^1.0.3: 1.0.3 - gulp-uglify@2.1.2: 2.1.2 + gulp-uglify@^3.0.0: 3.0.0 gulp-util@^3.0.8: 3.0.8 gulp@^3.9.1: 3.9.1 husky@^0.13.3: 0.13.4 lint-staged@^3.4.0: 3.6.0 localforage@^1.5.0: 1.5.0 'pjs-problems@git+https://github.com/practicejavascript/pjs-problems.git': github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916 + pump@^1.0.2: 1.0.2 rollup-stream@^1.19.0: 1.19.0 - static-eval@^1.1.1: 1.1.1 + sw-precache@^5.1.1: 5.1.1 + uglify-es@^3.0.15: 3.0.15 uglifyify@^3.0.4: 3.0.4 vinyl-buffer@^1.0.0: 1.0.0 vinyl-source-stream@^1.1.0: 1.1.0 watchify@^3.9.0: 3.9.0 - xo@^0.18.1: 0.18.2 + xo@^0.18.2: 0.18.2 packages: /@ava/babel-preset-stage-4/1.0.0: dependencies: @@ -125,6 +130,10 @@ packages: resolution: a3e52fa39168c825ff57b0248126ce5a8ff95507 /app-root-path/2.0.1: cd62dcf8e4fd5a417efc664d2e5b10653c651b46 /aproba/1.1.2: 45c6629094de4e96f693ef7eab74ae079c240fc1 + /archive-type/3.2.0: + dependencies: + file-type: 3.9.0 + resolution: 9cd9c006957ebe95fadad5bd6098942a813737f6 /archy/1.0.0: f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40 /are-we-there-yet/1.1.4: dependencies: @@ -172,6 +181,7 @@ packages: dependencies: acorn: 4.0.13 resolution: 7bd41784d32493987aeb239b6b4e1c57a873b917 + /async-each-series/1.1.0: f42fd8155d38f21a5b8ea07c28e063ed1700b138 /async-each/1.0.1: 19d386a1d9edc6e7c1c85d388aedbcc56d33602d /async-foreach/0.1.3: 36121f845c0578172de419a97dbeb1d16ec34542 /async/1.5.2: ec6a61ae56480c0c3cb241c95618e20892f9672a @@ -560,6 +570,39 @@ packages: babel-runtime: 6.23.0 babel-types: 6.24.1 resolution: d5faf7aa578a65bbe591cf5edae04a0c67020758 + /babel-preset-env/1.5.1: + dependencies: + babel-plugin-check-es2015-constants: 6.22.0 + babel-plugin-syntax-trailing-function-commas: 6.22.0 + babel-plugin-transform-async-to-generator: 6.24.1 + babel-plugin-transform-es2015-arrow-functions: 6.22.0 + babel-plugin-transform-es2015-block-scoped-functions: 6.22.0 + babel-plugin-transform-es2015-block-scoping: 6.24.1 + babel-plugin-transform-es2015-classes: 6.24.1 + babel-plugin-transform-es2015-computed-properties: 6.24.1 + babel-plugin-transform-es2015-destructuring: 6.23.0 + babel-plugin-transform-es2015-duplicate-keys: 6.24.1 + babel-plugin-transform-es2015-for-of: 6.23.0 + babel-plugin-transform-es2015-function-name: 6.24.1 + babel-plugin-transform-es2015-literals: 6.22.0 + babel-plugin-transform-es2015-modules-amd: 6.24.1 + babel-plugin-transform-es2015-modules-commonjs: 6.24.1 + babel-plugin-transform-es2015-modules-systemjs: 6.24.1 + babel-plugin-transform-es2015-modules-umd: 6.24.1 + babel-plugin-transform-es2015-object-super: 6.24.1 + babel-plugin-transform-es2015-parameters: 6.24.1 + babel-plugin-transform-es2015-shorthand-properties: 6.24.1 + babel-plugin-transform-es2015-spread: 6.22.0 + babel-plugin-transform-es2015-sticky-regex: 6.24.1 + babel-plugin-transform-es2015-template-literals: 6.22.0 + babel-plugin-transform-es2015-typeof-symbol: 6.23.0 + babel-plugin-transform-es2015-unicode-regex: 6.24.1 + babel-plugin-transform-exponentiation-operator: 6.24.1 + babel-plugin-transform-regenerator: 6.24.1 + browserslist: 2.1.4 + invariant: 2.2.2 + semver: 5.3.0 + resolution: d2eca6af179edf27cdc305a84820f601b456dd0b /babel-preset-es2015/6.24.1: dependencies: babel-plugin-check-es2015-constants: 6.22.0 @@ -658,11 +701,49 @@ packages: tweetnacl: 0.14.5 resolution: 63bc5dcb61331b92bc05fd528953c33462a06f8d /beeper/1.1.1: e6d5ea8c5dad001304a70b22638447f69cb2f809 + /bin-build/2.2.0: + dependencies: + archive-type: 3.2.0 + decompress: 3.0.0 + download: 4.4.3 + exec-series: 1.0.3 + rimraf: 2.6.1 + tempfile: 1.1.1 + url-regex: 3.2.0 + resolution: 11f8dd61f70ffcfa2bdcaa5b46f5e8fedd4221cc + /bin-check/2.0.0: + dependencies: + executable: 1.1.0 + resolution: 86f8e6f4253893df60dc316957f5af02acb05930 + /bin-version-check/2.1.0: + dependencies: + bin-version: 1.0.4 + minimist: 1.2.0 + semver: 4.3.6 + semver-truncate: 1.1.2 + resolution: e4e5df290b9069f7d111324031efc13fdd11a5b0 + /bin-version/1.0.4: + dependencies: + find-versions: 1.2.1 + resolution: 9eb498ee6fd76f7ab9a7c160436f89579435d78e + /bin-wrapper/3.0.2: + dependencies: + bin-check: 2.0.0 + bin-version-check: 2.1.0 + download: 4.4.3 + each-async: 1.1.1 + lazy-req: 1.1.0 + os-filter-obj: 1.0.3 + resolution: 67d3306262e4b1a5f2f88ee23464f6a655677aeb /binary-extensions/1.8.0: 48ec8d16df4377eae5fa5884682480af4d95c774 /bl/0.9.5: dependencies: readable-stream: 1.0.34 resolution: c06b797af085ea00bc527afc8efcf11de2232054 + /bl/1.2.1: + dependencies: + readable-stream: 2.2.10 + resolution: cac328f7bee45730d404b692203fcb590e172d5e /block-stream/0.0.9: dependencies: inherits: 2.0.3 @@ -839,13 +920,30 @@ packages: caniuse-db: 1.0.30000676 electron-to-chromium: 1.3.13 resolution: 0bd76704258be829b2398bb50e4b62d1a166b0b9 + /browserslist/2.1.4: + dependencies: + caniuse-lite: 1.0.30000676 + electron-to-chromium: 1.3.13 + resolution: cc526af4a1312b7d2e05653e56d0c8ab70c0e053 /buf-compare/1.0.1: fef28da8b8113a0a0db4430b0b6467b69730b34a + /buffer-crc32/0.2.13: 0d333e3f00eac50aa1454abd30ef8c2a5d9a7242 + /buffer-to-vinyl/1.1.0: + dependencies: + file-type: 3.9.0 + readable-stream: 2.2.10 + uuid: 2.0.3 + vinyl: 1.2.0 + resolution: 00f15faee3ab7a1dda2cde6d9121bffdd07b2262 /buffer-xor/1.0.3: 26e61ed1422fb70dd42e6e36729ed51d855fe8d9 /buffer/5.0.6: dependencies: base64-js: 1.2.0 ieee754: 1.1.8 resolution: 2ea669f7eec0b6eda05b08f8b5ff661b28573588 + /bufferstreams/1.1.1: + dependencies: + readable-stream: 2.2.10 + resolution: 0161373060ac5988eff99058731114f6e195d51e /builtin-modules/1.1.1: 270f076c5a72c02f5b65a47df94c5fe3a278892f /builtin-status-codes/3.0.0: 85982878e21b98e1c66425e03d0174788f569ee8 /bytes/2.2.0: fd35464a403f6f9117c2de3609ecff9cae000588 @@ -870,6 +968,11 @@ packages: callsites: 0.2.0 resolution: 94085ef63581ecd3daa92444a8fe94e82577751f /callsites/0.2.0: afab96262910a7f33c19a5775825c69f34e350ca + /camel-case/3.0.0: + dependencies: + no-case: 2.3.1 + upper-case: 1.1.3 + resolution: ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73 /camelcase-keys/2.1.0: dependencies: camelcase: 2.1.1 @@ -887,8 +990,16 @@ packages: lodash.uniq: 4.5.0 resolution: b534e7c734c4f81ec5fbe8aca2ad24354b962c6c /caniuse-db/1.0.30000676: 82ea578237637c8ff34a28acaade373b624c4ea8 + /caniuse-lite/1.0.30000676: 1e962123f48073f0c51c4ea0651dd64d25786498 /capture-stack-trace/1.0.0: 4a6fa07399c26bba47f0b2496b4d0fb408c5550d /caseless/0.12.0: 1b681c21ff84033c826543090689420d187151dc + /caw/1.2.0: + dependencies: + get-proxy: 1.1.0 + is-obj: 1.0.1 + object-assign: 3.0.0 + tunnel-agent: 0.4.3 + resolution: ffb226fe7efc547288dc62ee3e97073c212d1034 /center-align/0.1.3: dependencies: align-text: 0.1.4 @@ -944,6 +1055,10 @@ packages: dependencies: chalk: 1.1.3 resolution: b3bd36e93dd4cbfb395a3c26896352445265c05b + /clean-css/4.1.3: + dependencies: + source-map: 0.5.6 + resolution: 07cfe8980edb20d455ddc23aadcf1e04c6e509ce /clean-stack/1.3.0: 9e821501ae979986c46b1d66d2d432db2fd4ae31 /clean-yaml-object/0.1.0: 63fb110dc2ce1a84dc21f6d9334876d010ae8b68 /cli-boxes/1.0.0: 4fa917c3e59c94a004cd61f8ee509da651687143 @@ -982,6 +1097,7 @@ packages: dependencies: pinkie-promise: 1.0.0 resolution: 413e7db6f5893a60b942cf492c4bec93db415ab7 + /co/3.1.0: 4ea54ea5a08938153185e15210c68d9092bc1b78 /co/4.6.0: 6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184 /coa/1.0.2: dependencies: @@ -1025,6 +1141,10 @@ packages: dependencies: delayed-stream: 1.0.0 resolution: 938370a57b4a51dea2c77c15d5c5fdf895164009 + /commander/2.8.1: + dependencies: + graceful-readlink: 1.0.1 + resolution: 06be367febfda0c330aa1e2a072d3dc9762425d4 /commander/2.9.0: dependencies: graceful-readlink: 1.0.1 @@ -1070,6 +1190,7 @@ packages: date-now: 0.1.4 resolution: f0241c45730a9fc6323b206dbf38edc741d0bb10 /console-control-strings/1.1.0: 3d7cf4464db6446ea644bf4b39507f9851008e8e + /console-stream/0.1.1: a095fe07b20465955f2fafd28b5d72bccd949d44 /constants-browserify/1.0.0: c20b96d8c617748aaf1c16021760cd27fcb8cb75 /contains-path/0.1.0: fe8cf184ff6670b6baef01a9d4861a5cbec4120a /content-type/1.0.2: b7d113aee7a8dd27bd21133c4dc2529df1721eed @@ -1251,6 +1372,56 @@ packages: ms: 2.0.0 resolution: e731531ca2ede27d188222427da17821d68ff4fc /decamelize/1.2.0: f6534d15148269b20352e7bee26f501f9a191290 + /decompress-tar/3.1.0: + dependencies: + is-tar: 1.0.0 + object-assign: 2.1.1 + strip-dirs: 1.1.1 + tar-stream: 1.5.4 + through2: 0.6.5 + vinyl: 0.4.6 + resolution: 217c789f9b94450efaadc5c5e537978fc333c466 + /decompress-tarbz2/3.1.0: + dependencies: + is-bzip2: 1.0.0 + object-assign: 2.1.1 + seek-bzip: 1.0.5 + strip-dirs: 1.1.1 + tar-stream: 1.5.4 + through2: 0.6.5 + vinyl: 0.4.6 + resolution: 8b23935681355f9f189d87256a0f8bdd96d9666d + /decompress-targz/3.1.0: + dependencies: + is-gzip: 1.0.0 + object-assign: 2.1.1 + strip-dirs: 1.1.1 + tar-stream: 1.5.4 + through2: 0.6.5 + vinyl: 0.4.6 + resolution: b2c13df98166268991b715d6447f642e9696f5a0 + /decompress-unzip/3.4.0: + dependencies: + is-zip: 1.0.0 + read-all-stream: 3.1.0 + stat-mode: 0.2.2 + strip-dirs: 1.1.1 + through2: 2.0.3 + vinyl: 1.2.0 + yauzl: 2.8.0 + resolution: 61475b4152066bbe3fee12f9d629d15fe6478eeb + /decompress/3.0.0: + dependencies: + buffer-to-vinyl: 1.1.0 + concat-stream: 1.6.0 + decompress-tar: 3.1.0 + decompress-tarbz2: 3.1.0 + decompress-targz: 3.1.0 + decompress-unzip: 3.4.0 + stream-combiner2: 1.1.1 + vinyl-assign: 1.2.1 + vinyl-fs: 2.4.4 + resolution: af1dd50d06e3bfc432461d37de11b38c0d991bed /dedent/0.7.0: 2495ddbaf6eb874abb0e1be9df22d2e5a544326c /deep-assign/1.0.0: dependencies: @@ -1330,6 +1501,10 @@ packages: esutils: 2.0.2 isarray: 1.0.0 resolution: c73d8d2909d22291e1a007a395804da8b665fe63 + /dom-urls/1.1.0: + dependencies: + urijs: 1.18.10 + resolution: 001ddf81628cd1e706125c7176f53ccec55d918e /domain-browser/1.1.7: 867aa4b093faa05f1de08c06f4d7b21fdf8698bc /dot-prop/3.0.0: dependencies: @@ -1339,6 +1514,24 @@ packages: dependencies: is-obj: 1.0.1 resolution: a8493f0b7b5eeec82525b5c7587fa7de7ca859c1 + /download/4.4.3: + dependencies: + caw: 1.2.0 + concat-stream: 1.6.0 + each-async: 1.1.1 + filenamify: 1.2.1 + got: 5.7.1 + gulp-decompress: 1.2.0 + gulp-rename: 1.2.2 + is-url: 1.2.2 + object-assign: 4.1.1 + read-all-stream: 3.1.0 + readable-stream: 2.2.10 + stream-combiner2: 1.1.1 + vinyl: 1.2.0 + vinyl-fs: 2.4.4 + ware: 1.3.0 + resolution: aa55fdad392d95d4b68e8c2be03e0c2aa21ba9ac /duplexer/0.1.1: ace6ff808c1ce66b57d1ebf97977acb02334cfc1 /duplexer2/0.0.2: dependencies: @@ -1349,6 +1542,18 @@ packages: readable-stream: 2.2.10 resolution: 8b12dab878c0d69e3e7891051662a32fc6bddcc1 /duplexer3/0.1.4: ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2 + /duplexify/3.5.0: + dependencies: + end-of-stream: 1.0.0 + inherits: 2.0.3 + readable-stream: 2.2.10 + stream-shift: 1.0.0 + resolution: 1aa773002e1578457e9d9d4a50b0ccaaebcbd604 + /each-async/1.1.1: + dependencies: + onetime: 1.1.0 + set-immediate-shim: 1.0.1 + resolution: dee5229bdf0ab6ba2012a395e1b869abf8813473 /ecc-jsbn/0.1.1: dependencies: jsbn: 0.1.1 @@ -1375,6 +1580,14 @@ packages: dependencies: once: 1.3.3 resolution: 8e177206c3c80837d85632e8b9359dfe8b2f6eaf + /end-of-stream/1.0.0: + dependencies: + once: 1.3.3 + resolution: d4596e702734a93e40e9af864319eabd99ff2f0e + /end-of-stream/1.4.0: + dependencies: + once: 1.4.0 + resolution: 7a90d833efda6cfa6eac0f4949dbb0fad3a63206 /enhance-visitors/1.0.0: dependencies: lodash: 4.17.4 @@ -1410,6 +1623,7 @@ packages: es6-symbol: 3.1.1 event-emitter: 0.3.5 resolution: 9136e0503dcc06a301690f0bb14ff4e364e949f0 + /es6-promise/4.1.0: dda03ca8f9f89bc597e689842929de7ba8cebdf0 /es6-set/0.1.5: dependencies: d: 1.0.0 @@ -1431,14 +1645,6 @@ packages: es6-symbol: 3.1.1 resolution: 5e3ab32251ffd1538a1f8e5ffa1357772f92d96f /escape-string-regexp/1.0.5: 1b61c0562190a8dff6ae3bb2cf0200ca130b86d4 - /escodegen/1.8.1: - dependencies: - esprima: 2.7.3 - estraverse: 1.9.3 - esutils: 2.0.2 - optionator: 0.8.2 - source-map: 0.2.0 - resolution: 5a5b53af4693110bebb0867aa3430dd3b70a1018 /escope/3.6.0: dependencies: es6-map: 0.1.5 @@ -1574,7 +1780,6 @@ packages: estraverse: 4.1.1 object-assign: 4.1.1 resolution: 4713b6536adf7f2ac4f327d559e7756bff648220 - /estraverse/1.9.3: af67f2dc922582415950926091a4005d29c9bb44 /estraverse/4.1.1: f6caca728933a850ef90661d0e17982ba47111a2 /estraverse/4.2.0: 0dee3fed31fcd469618ce7342099fc1afa0bdb13 /esutils/2.0.2: 0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b @@ -1598,6 +1803,19 @@ packages: dependencies: create-hash: 1.1.3 resolution: 497b66ad9fef65cd7c08a6180824ba1476b66e53 + /exec-buffer/3.1.0: + dependencies: + execa: 0.5.1 + p-finally: 1.0.0 + pify: 2.3.0 + rimraf: 2.6.1 + tempfile: 1.1.1 + resolution: 851b46d062fca9bcbc6ff8781693e28e8da80402 + /exec-series/1.0.3: + dependencies: + async-each-series: 1.1.0 + object-assign: 4.1.1 + resolution: 6d257a9beac482a872c7783bc8615839fc77143a /execa/0.4.0: dependencies: cross-spawn-async: 2.2.5 @@ -1627,6 +1845,10 @@ packages: signal-exit: 3.0.2 strip-eof: 1.0.0 resolution: 57b69a594f081759c69e5370f0d17b9cb11658fe + /executable/1.1.0: + dependencies: + meow: 3.7.0 + resolution: 877980e9112f3391066da37265de7ad8434ab4d9 /exit-hook/1.1.1: f05ca233b48c05d54fff07765df8507e95c02ff8 /expand-brackets/0.1.5: dependencies: @@ -1640,6 +1862,10 @@ packages: dependencies: os-homedir: 1.0.2 resolution: 0b81eba897e5a3d31d1c3d102f8f01441e559449 + /extend-shallow/2.0.1: + dependencies: + is-extendable: 0.1.1 + resolution: 51af7d614ad9a9f610ea1bafbb989d6b1c56890f /extend/1.3.0: d1516fb0ff5624d2ebf9123ea1dac5a1994004f8 /extend/3.0.1: a755ea7bc1adfcc5a31ce7e762dbaadc5e636444 /extglob/0.3.2: @@ -1664,6 +1890,10 @@ packages: dependencies: websocket-driver: 0.6.5 resolution: cc4074c7f4a4dfd03af54dd65c354b135132ce11 + /fd-slicer/1.0.1: + dependencies: + pend: 1.2.0 + resolution: 8b5bcbd9ec327c5041bf9ab023fd6750f1177e65 /figures/1.7.0: dependencies: escape-string-regexp: 1.0.5 @@ -1678,7 +1908,16 @@ packages: flat-cache: 1.2.2 object-assign: 4.1.1 resolution: c392990c3e684783d838b8c84a45d8a048458361 + /file-type/3.9.0: 257a078384d1db8087bc449d107d52a52672b9e9 /filename-regex/2.0.1: c1c4b9bee3e09725ddb106b75c1e301fe2f18b26 + /filename-reserved-regex/1.0.0: e61cf805f0de1c984567d0386dc5df50ee5af7e4 + /filenamify/1.2.1: + dependencies: + filename-reserved-regex: 1.0.0 + strip-outer: 1.0.0 + trim-repeated: 1.0.0 + resolution: a9f2ffd11c503bed300015029272378f1f1365a5 + /filesize/3.5.10: fc8fa23ddb4ef9e5e0ab6e1e64f679a24a56761f /fill-range/2.2.3: dependencies: is-number: 2.1.0 @@ -1705,6 +1944,13 @@ packages: dependencies: locate-path: 2.0.0 resolution: 45d1b7e506c717ddd482775a2b77920a3c0c57a7 + /find-versions/1.2.1: + dependencies: + array-uniq: 1.0.3 + get-stdin: 4.0.1 + meow: 3.7.0 + semver-regex: 1.0.0 + resolution: cbde9f12e38575a0af1be1b9a2c5d5fd8f186b62 /findup-sync/0.4.3: dependencies: detect-file: 0.1.0 @@ -1790,6 +2036,10 @@ packages: dependencies: pinkie-promise: 2.0.1 resolution: 8783f9dcebd1eea495a334e1a6a251e78887ab1a + /get-proxy/1.1.0: + dependencies: + rc: 1.2.1 + resolution: 894854491bc591b0f147d7ae570f5c678b7256eb /get-set-props/0.1.0: 998475c178445686d0b32246da5df8dbcfbe8ea3 /get-stdin/4.0.1: b968c6b0a04384324902e8bf1a5df32579a450fe /get-stdin/5.0.1: 122e161591e21ff4c52530305693f20e6393a398 @@ -1803,6 +2053,12 @@ packages: dependencies: assert-plus: 1.0.0 resolution: 5eff8e3e684d569ae4cb2b1282604e8ba62149fa + /gifsicle/3.0.4: + dependencies: + bin-build: 2.2.0 + bin-wrapper: 3.0.2 + logalot: 2.1.0 + resolution: f45cb5ed10165b665dc929e0e9328b6c821dfa3b /glob-base/0.3.0: dependencies: glob-parent: 2.0.0 @@ -1812,6 +2068,11 @@ packages: dependencies: is-glob: 2.0.1 resolution: 81383d72db054fcccf5336daa902f182f6edbb28 + /glob-parent/3.1.0: + dependencies: + is-glob: 3.1.0 + path-dirname: 1.0.2 + resolution: 9e6af6299d8d3bd2bd40430832bd113df906c5ae /glob-stream/3.1.18: dependencies: glob: 4.5.3 @@ -1821,6 +2082,17 @@ packages: through2: 0.6.5 unique-stream: 1.0.0 resolution: 9170a5f12b790306fdfe598f313f8f7954fd143b + /glob-stream/5.3.5: + dependencies: + extend: 3.0.1 + glob: 5.0.15 + glob-parent: 3.1.0 + micromatch: 2.3.11 + ordered-read-streams: 0.3.0 + through2: 0.6.5 + to-absolute-glob: 0.1.1 + unique-stream: 2.2.1 + resolution: a55665a9a8ccdc41915a87c701e32d4e016fad22 /glob-watcher/0.0.6: dependencies: gaze: 0.5.2 @@ -1838,6 +2110,14 @@ packages: minimatch: 2.0.10 once: 1.4.0 resolution: c6cb73d3226c1efef04de3c56d012f03377ee15f + /glob/5.0.15: + dependencies: + inflight: 1.0.6 + inherits: 2.0.3 + minimatch: 3.0.4 + once: 1.4.0 + path-is-absolute: 1.0.1 + resolution: 1bc936b9e02f4a603fcc222ecf7633d30b8b93b1 /glob/7.1.2: dependencies: fs.realpath: 1.0.0 @@ -1936,6 +2216,12 @@ packages: resolution: 7613c778a1afea62f25c630a086d7f3acbbdd818 /graceful-fs/4.1.11: 0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658 /graceful-readlink/1.0.1: 4cafad76bc62f02fa039b2f94e9a3dd3a391a725 + /guetzli/1.0.1: + dependencies: + bin-build: 2.2.0 + bin-wrapper: 3.0.2 + logalot: 2.1.0 + resolution: 48cd01d18dbd60fb47318a1724a295a035d9b9f2 /gulp-bro/1.0.2: dependencies: browserify: 14.4.0 @@ -1944,6 +2230,43 @@ packages: gulp-util: 3.0.8 through2: 2.0.3 resolution: e56e060f3b9fde1809902ba7b2791df0d9c42b70 + /gulp-decompress/1.2.0: + dependencies: + archive-type: 3.2.0 + decompress: 3.0.0 + gulp-util: 3.0.8 + readable-stream: 2.2.10 + resolution: 8eeb65a5e015f8ed8532cafe28454960626f0dc7 + /gulp-htmlmin/3.0.0: + dependencies: + bufferstreams: 1.1.1 + gulp-util: 3.0.8 + html-minifier: 3.5.2 + object-assign: 4.1.1 + readable-stream: 2.2.10 + tryit: 1.0.3 + resolution: 19ea8002d1231d6b1f18a12d20f2a66a77770fb3 + /gulp-image/2.9.0: + dependencies: + exec-buffer: 3.1.0 + execa: 0.6.3 + filesize: 3.5.10 + gifsicle: 3.0.4 + guetzli: 1.0.1 + gulp-util: 3.0.8 + is-gif: 1.0.0 + is-jpg: 1.0.0 + is-png: 1.1.0 + is-svg: 2.1.0 + jpeg-recompress-bin: 3.0.1 + jpegoptim-bin: 3.0.0 + mozjpeg: 4.1.1 + optipng-bin: 4.0.0 + pngquant-bin: 3.1.1 + svgo: 0.7.2 + through2-concurrent: 1.1.1 + zopflipng-bin: 4.0.0 + resolution: 21fcbfdbbf7c55783cccb1b204c2d6fed881e03f /gulp-livereload/3.8.1: dependencies: chalk: 0.5.1 @@ -1960,6 +2283,7 @@ packages: postcss-load-config: 1.2.0 vinyl-sourcemaps-apply: 0.2.1 resolution: 78a32e3c87aa6cdcec5ae1c905e196d478e8c5d5 + /gulp-rename/1.2.2: 3ad4428763f05e2764dec1c67d868db275687817 /gulp-sass/3.1.0: dependencies: gulp-util: 3.0.8 @@ -1968,6 +2292,14 @@ packages: through2: 2.0.3 vinyl-sourcemaps-apply: 0.2.1 resolution: 53dc4b68a1f5ddfe4424ab4c247655269a8b74b7 + /gulp-sourcemaps/1.6.0: + dependencies: + convert-source-map: 1.5.0 + graceful-fs: 4.1.11 + strip-bom: 2.0.0 + through2: 2.0.3 + vinyl: 1.2.0 + resolution: b86ff349d801ceb56e1d9e7dc7bbcb4b7dee600c /gulp-sourcemaps/2.6.0: dependencies: '@gulp-sourcemaps/identity-map': 1.0.1 @@ -1987,17 +2319,16 @@ packages: dependencies: svgo: 0.6.6 resolution: f6ad219f281cdc9ac3e0e6c173d5c77bba8cd692 - /gulp-uglify/2.1.2: + /gulp-uglify/3.0.0: dependencies: gulplog: 1.0.0 has-gulplog: 0.1.0 lodash: 4.17.4 make-error-cause: 1.2.2 through2: 2.0.3 - uglify-js: 2.8.27 - uglify-save-license: 0.4.1 + uglify-js: 3.0.15 vinyl-sourcemaps-apply: 0.2.1 - resolution: 6db85b1d0ee63d18058592b658649d65c2ec4541 + resolution: 0df0331d72a0d302e3e37e109485dddf33c6d1ca /gulp-util/3.0.8: dependencies: array-differ: 1.0.0 @@ -2081,6 +2412,7 @@ packages: hoek: 2.16.3 sntp: 1.0.9 resolution: 078444bd7c1640b0fe540d2c9b73d59678e8e1c4 + /he/1.1.1: 93410fd21b009735151f8868c2f271f3427e23fd /hmac-drbg/1.0.1: dependencies: hash.js: 1.0.3 @@ -2099,6 +2431,17 @@ packages: resolution: 4c2bbc8a758998feebf5ed68580f76d46768b4bc /hosted-git-info/2.4.2: 0076b9f46a270506ddbaaea56496897460612a67 /html-comment-regex/1.1.1: 668b93776eaae55ebde8f3ad464b307a4963625e + /html-minifier/3.5.2: + dependencies: + camel-case: 3.0.0 + clean-css: 4.1.3 + commander: 2.9.0 + he: 1.1.1 + ncname: 1.0.0 + param-case: 2.1.1 + relateurl: 0.2.7 + uglify-js: 3.0.15 + resolution: d73bc3ff448942408818ce609bf3fb0ea7ef4eb7 /htmlescape/1.1.1: 3a03edc2214bca3b66424a3e7959349509cb0351 /http-errors/1.3.1: dependencies: @@ -2184,8 +2527,13 @@ packages: loose-envify: 1.3.1 resolution: 9e1f56ac0acdb6bf303306f338be3b204ae60360 /invert-kv/1.0.0: 104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6 + /ip-regex/1.0.3: dc589076f659f419c222039a33316f1c7387effd /irregular-plurals/1.2.0: 38f299834ba8c00c30be9c554e137269752ff3ac /is-absolute-url/2.1.0: 50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6 + /is-absolute/0.1.7: + dependencies: + is-relative: 0.1.3 + resolution: 847491119fccb5fb436217cc737f7faad50f603f /is-absolute/0.2.6: dependencies: is-relative: 0.2.1 @@ -2201,6 +2549,7 @@ packages: dependencies: builtin-modules: 1.1.1 resolution: 540572d34f7ac3119f8f76c30cbc1b1e037affbe + /is-bzip2/1.0.0: 5ee58eaa5a2e9c80e21407bedf23ae5ac091b3fc /is-ci/1.0.10: dependencies: ci-info: 1.0.0 @@ -2214,6 +2563,7 @@ packages: /is-error/2.2.1: 684a96d84076577c98f4cdb40c6d26a5123bf19c /is-extendable/0.1.1: 62b110e289a471418e3ec36a617d472e301dfc89 /is-extglob/1.0.0: ac468177c4943405a092fc8f29760c6ffc6206c0 + /is-extglob/2.1.1: a88c02535791f02ed37c76a1b9ea9773c833f8c2 /is-finite/1.0.2: dependencies: number-is-nan: 1.0.1 @@ -2229,10 +2579,17 @@ packages: get-set-props: 0.1.0 lowercase-keys: 1.0.0 resolution: 2731877e4d78a6a69edcce6bb9d68b0779e76312 + /is-gif/1.0.0: a6d2ae98893007bffa97a1d8c01d63205832097e /is-glob/2.0.1: dependencies: is-extglob: 1.0.0 resolution: d096f926a3ded5600f3fdfd91198cb0888c2d863 + /is-glob/3.1.0: + dependencies: + is-extglob: 2.1.1 + resolution: 7ba5ae24217804ac70707b96922567486cc3e84a + /is-gzip/1.0.0: 6ca8b07b99c77998025900e555ced8ed80879a83 + /is-jpg/1.0.0: 2959c17e73430db38264da75b90dd54f2d86da1c /is-js-type/2.0.0: dependencies: js-types: 1.0.0 @@ -2244,6 +2601,7 @@ packages: jsonpointer: 4.0.1 xtend: 4.0.1 resolution: f079dd9bfdae65ee2038aae8acbc86ab109e3693 + /is-natural-number/2.1.1: 7d4c5728377ef386c3e194a9911bf57c6dc335e7 /is-npm/1.0.0: f2fb63a65e4905b406c86072765a1a4dc793b9f4 /is-number/2.1.0: dependencies: @@ -2269,6 +2627,7 @@ packages: path-is-inside: 1.0.2 resolution: fc06e5a1683fbda13de667aff717bbc10a48f37f /is-plain-obj/1.1.0: 71a50c8429dfca773c92a390a4a03b39fcd51d3e + /is-png/1.1.0: d574b12bf275c0350455570b0e5b57ab062077ce /is-posix-bracket/0.1.1: 3334dc79774368e92f016e6fbc0a88f5cd6e6bc4 /is-primitive/2.0.0: 207bab91638499c07b2adf240a41a87210034575 /is-promise/2.1.0: 79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa @@ -2279,6 +2638,7 @@ packages: proto-props: 0.2.1 resolution: b3951f95c089924fb5d4fcda6542ab3e83e2b220 /is-redirect/1.0.0: 1d03dded53bd8db0f30c26e4f95d36fc7c87dc24 + /is-relative/0.1.3: 905fee8ae86f45b3ec614bc3c15c869df0876e82 /is-relative/0.2.1: dependencies: is-unc-path: 0.1.2 @@ -2293,6 +2653,7 @@ packages: dependencies: html-comment-regex: 1.1.1 resolution: cf61090da0d9efbcab8722deba6f032208dbb0e9 + /is-tar/1.0.0: 2f6b2e1792c1f5bb36519acaa9d65c0d26fe853d /is-typedarray/1.0.0: e479c80858df0c1b11ddda6940f96011fcda4a9a /is-unc-path/0.1.2: dependencies: @@ -2300,7 +2661,9 @@ packages: resolution: 6ab053a72573c10250ff416a3814c35178af39b9 /is-url/1.2.2: 498905a593bf47cc2d9e7f738372bbf7696c7f26 /is-utf8/0.2.1: 4b0da1442104d1b336340e80797e865cf39f7d72 + /is-valid-glob/0.3.0: d4b55c69f51886f9b65c70d6c2622d37e29f48fe /is-windows/0.2.0: de1aa6d63ea29dd248737b69f1ff8b8002d2108c + /is-zip/1.0.0: 47b0a8ff4d38a76431ccfd99a8e15a4c86ba2325 /isarray/0.0.1: 8a18acfca9a8f4177e09abfc6038939b05d1eedf /isarray/1.0.0: bb935d48582cba168c06834957a54a3e07124f11 /isexe/2.0.0: e8fbf374dc556ff8947a10dcb0572d633f2cfa10 @@ -2345,6 +2708,17 @@ packages: dependencies: jsbn: 0.1.1 resolution: 06d4912255093419477d425633606e0e90782967 + /jpeg-recompress-bin/3.0.1: + dependencies: + bin-wrapper: 3.0.2 + logalot: 2.1.0 + resolution: 46a3e7300ccab795b1b8db27ae802c27a28333a4 + /jpegoptim-bin/3.0.0: + dependencies: + bin-build: 2.2.0 + bin-wrapper: 3.0.2 + logalot: 2.1.0 + resolution: 9f7a05d83b302bd19913decf339a9dae1bda0c2b /js-base64/2.1.9: f0e80ae039a4bd654b5f281fc93f04a914a7fcce /js-tokens/3.0.1: 08e9f132484a2c45a30907e9dc4d5567b7f114d7 /js-types/1.0.0: d242e6494ed572ad3c92809fc8bed7f7687cbf03 @@ -2419,6 +2793,10 @@ packages: /lazy-cache/1.0.4: a1d78fc3a50474cb80845d3b3b6e1da49a446e8e /lazy-req/1.1.0: bdaebead30f8d824039ce0ce149d4daa07ba1fac /lazy-req/2.0.0: c9450a363ecdda2e6f0c70132ad4f37f8f06f2b4 + /lazystream/1.0.0: + dependencies: + readable-stream: 2.2.10 + resolution: f6995fe0f820392f61396be89462407bb77168e4 /lcid/1.0.0: dependencies: invert-kv: 1.0.0 @@ -2560,6 +2938,7 @@ packages: /lodash.clonedeep/4.5.0: e23f3f9c4f8fbdde872529c1071857a086e5ccef /lodash.cond/4.5.2: f471a1da486be60f6ab955d17115523dd1d255d5 /lodash.debounce/4.0.8: 82d79bff30a67c4005ffd5e2515300ad9ca4d7af + /lodash.defaults/4.2.0: d09178716ffea4dde9e5fb7b37f6f0802274580c /lodash.difference/4.5.0: 9ccb4e505d486b91651345772885a2df27fd017c /lodash.escape/3.2.0: dependencies: @@ -2598,11 +2977,20 @@ packages: lodash.restparam: 3.6.1 lodash.templatesettings: 3.1.1 resolution: f8cdecc6169a255be9098ae8b0c53d378931d14f + /lodash.template/4.4.0: + dependencies: + lodash._reinterpolate: 3.0.0 + lodash.templatesettings: 4.1.0 + resolution: e73a0385c8355591746e020b99679c690e68fba0 /lodash.templatesettings/3.1.1: dependencies: lodash._reinterpolate: 3.0.0 lodash.escape: 3.2.0 resolution: fb307844753b66b9f1afa54e262c745307dba8e5 + /lodash.templatesettings/4.1.0: + dependencies: + lodash._reinterpolate: 3.0.0 + resolution: 2b4d4e95ba440d915ff08bc899e4553666713316 /lodash.uniq/4.5.0: d0225373aeb652adc1bc82e4945339a842754773 /lodash.upperfirst/4.3.1: 1365edf431480481ef0d1c68957a5ed99d49f7ce /lodash/1.0.2: 8f57560c83b59fc270bd3d561b690043430e2551 @@ -2617,6 +3005,11 @@ packages: ansi-escapes: 1.4.0 cli-cursor: 1.0.2 resolution: 19929f64c4093d2d2e7075a1dad8af59c296b8d1 + /logalot/2.1.0: + dependencies: + figures: 1.7.0 + squeak: 1.3.0 + resolution: 5f8e8c90d304edf12530951a5554abb8c5e3f552 /longest/1.0.1: 30a0b2da38f73770e8294a0d22e6625ed77d0097 /loose-envify/1.3.1: dependencies: @@ -2627,7 +3020,15 @@ packages: currently-unhandled: 0.4.1 signal-exit: 3.0.2 resolution: 5b46f80147edee578870f086d04821cf998e551f + /lower-case/1.1.4: 9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac /lowercase-keys/1.0.0: 4e3366b39e7f5457e35f1324bdf6f88d0bfc7306 + /lpad-align/1.1.2: + dependencies: + get-stdin: 4.0.1 + indent-string: 2.1.0 + longest: 1.0.1 + meow: 3.7.0 + resolution: 21f600ac1c3095c3c6e497ee67271ee08481fe9e /lru-cache/2.7.3: 6d4524e8b955f95d4f5b58851ce21dd72fb4e952 /lru-cache/4.0.2: dependencies: @@ -2676,6 +3077,10 @@ packages: redent: 1.0.0 trim-newlines: 1.0.0 resolution: 72cb668b425228290abbfa856892587308a801fb + /merge-stream/1.0.1: + dependencies: + readable-stream: 2.2.10 + resolution: 4041202d508a342ba00174008df0c251b8c135e1 /micromatch/2.3.11: dependencies: arr-diff: 2.0.0 @@ -2751,6 +3156,12 @@ packages: through2: 2.0.3 xtend: 4.0.1 resolution: 23215833f1da13fd606ccb8087b44852dcb821fd + /mozjpeg/4.1.1: + dependencies: + bin-build: 2.2.0 + bin-wrapper: 3.0.2 + logalot: 2.1.0 + resolution: 859030b24f689a53db9b40f0160d89195b88fd50 /ms/0.7.1: 9cd13c03adbff25b65effde7ce864ee952017098 /ms/0.7.3: 708155a5e44e33f5fd0fc53e81d0d40a91be1fff /ms/2.0.0: 5608aeadfc00be6c2901df5f9861788de0d597c8 @@ -2769,6 +3180,14 @@ packages: /nan/2.6.2: e4ff34e6c95fdfb5aecc08de6596f43605a7db45 /natives/1.1.0: e9ff841418a6b2ec7a495e939984f78f163e6e31 /natural-compare/1.4.0: 4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7 + /ncname/1.0.0: + dependencies: + xml-char-classes: 1.0.0 + resolution: 5b57ad18b1ca092864ef62b0b1ed8194f383b71c + /no-case/2.3.1: + dependencies: + lower-case: 1.1.4 + resolution: 7aeba1c73a52184265554b7dc03baf720df80081 /node-gyp/3.6.2: dependencies: fstream: 1.0.11 @@ -2860,6 +3279,7 @@ packages: /number-is-nan/1.0.1: 097b602b53422a522c1afb8790318336941a011d /oauth-sign/0.8.2: 46a6ab7f0aead8deae9ec0565780b7d4efeb9d43 /obj-props/1.1.0: 626313faa442befd4a44e9a02c3cb6bde937b511 + /object-assign/2.1.1: 43c36e5d569ff8e4816c4efa8be02d26967c18aa /object-assign/3.0.0: 9bedd5ca0897949bca47e7ff408062d549f587f2 /object-assign/4.1.0: 7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0 /object-assign/4.1.1: 2109adc7965887cfc05cbbd442cac8bfbb360863 @@ -2904,6 +3324,12 @@ packages: type-check: 0.3.2 wordwrap: 1.0.0 resolution: 364c5e409d3f4d6301d6c0b4c05bba50180aeb64 + /optipng-bin/4.0.0: + dependencies: + bin-build: 2.2.0 + bin-wrapper: 3.0.2 + logalot: 2.1.0 + resolution: 92b937d97ee67fe8a2d29bbcec6b8cee8f1a867e /ora/0.2.3: dependencies: chalk: 1.1.3 @@ -2918,7 +3344,13 @@ packages: stream-consume: 0.1.0 resolution: 14e7e9e2764f7315fbac184e506c7aa6df94ad7e /ordered-read-streams/0.1.0: fd565a9af8eb4473ba69b6ed8a34352cb552f126 + /ordered-read-streams/0.3.0: + dependencies: + is-stream: 1.1.0 + readable-stream: 2.2.10 + resolution: 7137e69b3298bb342247a1bbee3881c80e2fd78b /os-browserify/0.1.2: 49ca0293e0b19590a5f5de10c7f265a617d8fe54 + /os-filter-obj/1.0.3: 5915330d90eced557d2d938a31c6dd214d9c63ad /os-homedir/1.0.2: ffbc4988336e0e833de0c168c7ef152121aa7fb3 /os-locale/1.4.0: dependencies: @@ -2960,6 +3392,10 @@ packages: semver: 5.3.0 resolution: 8869a0401253661c4c4ca3da6c2121ed555f5eed /pako/0.2.9: f3f7522f4ef782348da8161bad9ecfd51bf83a75 + /param-case/2.1.1: + dependencies: + no-case: 2.3.1 + resolution: df94fd8cf6531ecf75e6bef9a0858fbc72be2247 /parents/1.0.1: dependencies: path-platform: 0.11.15 @@ -2994,6 +3430,7 @@ packages: /parse-passwd/1.0.0: 6d5b934a456993b23d37f40a382d6f1666a8e5c6 /parseurl/1.3.1: c8ab8c9223ba34888aa64a297b28853bec18da56 /path-browserify/0.0.0: a0b870729aae214005b7d5032ec2cbbb0fb4451a + /path-dirname/1.0.2: cc33d24d525e099a5388c0336c6e32b9160609e0 /path-exists/2.1.0: dependencies: pinkie-promise: 2.0.1 @@ -3010,6 +3447,10 @@ packages: dependencies: path-root-regex: 0.1.2 resolution: 9a4a6814cac1c0cd73360a95f32083c8ea4745b7 + /path-to-regexp/1.7.0: + dependencies: + isarray: 0.0.1 + resolution: 59fde0f435badacba103a84e9d3bc64e96b9937d /path-type/1.1.0: dependencies: graceful-fs: 4.1.11 @@ -3032,6 +3473,7 @@ packages: safe-buffer: 5.1.0 sha.js: 2.4.8 resolution: be36785c5067ea48d806ff923288c5f750b6b8a2 + /pend/1.2.0: 7a57eb550a6783f9115331fcf4663d5c8e007a50 /performance-now/0.2.0: 33ef30c5c77d4ea21c5a53869d91b56d8f2555e5 /pify/2.3.0: ed141a6ac043a849ea588498e7dca8b15330e90c /pinkie-promise/1.0.0: @@ -3063,6 +3505,12 @@ packages: irregular-plurals: 1.2.0 resolution: 7482452c1a0f508e3e344eaec312c91c29dc655a /pluralize/1.2.1: d1a21483fd22bb41e58a12fa3421823140897c45 + /pngquant-bin/3.1.1: + dependencies: + bin-build: 2.2.0 + bin-wrapper: 3.0.2 + logalot: 2.1.0 + resolution: d124d98a75a9487f40c1640b4dbfcbb2bd5a1fd1 /postcss-calc/5.3.1: dependencies: postcss: 5.2.17 @@ -3234,6 +3682,7 @@ packages: /prelude-ls/1.1.2: 21932a549f5e52ffd9a827f570e04be62a97da54 /prepend-http/1.0.4: d4f4562b0ce3696e41ac52d0e002e57a635dc6dc /preserve/0.2.0: 815ed1f6ebc65926f865b310c0713bcb3315ce4b + /pretty-bytes/4.0.2: b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9 /pretty-format/18.1.0: dependencies: ansi-styles: 2.2.1 @@ -3263,6 +3712,11 @@ packages: parse-asn1: 5.1.0 randombytes: 2.0.4 resolution: 39f699f3a46560dd5ebacbca693caf7c65c18cc6 + /pump/1.0.2: + dependencies: + end-of-stream: 1.4.0 + once: 1.4.0 + resolution: 3b3ee6512f94f0e575538c17995f9f16990a5d51 /punycode/1.3.2: 9653a036fb7c1ee42342f2325cceefea3926c48d /punycode/1.4.1: c0d5a63b2718800ad8e1eb0fa5269c84dd41845e /q/1.5.0: dd01bac9d06d30e6f219aecb8253ee9ebdc308f1 @@ -3434,6 +3888,7 @@ packages: dependencies: jsesc: 0.5.0 resolution: 7ee8f84dc6fa792d3fd0ae228d24bd949ead205c + /relateurl/0.2.7: 54dbf377e51440aca90a4cd274600d3ff2d888a9 /remove-trailing-separator/1.0.1: 615ebb96af559552d4bf4057c8436d486ab63cc4 /repeat-element/1.1.2: ef089a178d1483baae4d93eb98b4f9e4e11d990a /repeat-string/1.6.1: 8dcae470e1c88abc2d600fff4a776286da75e637 @@ -3548,13 +4003,23 @@ packages: js-base64: 2.1.9 source-map: 0.4.4 resolution: 8eb06db9a9723333824d3f5530641149847ce5d1 + /seek-bzip/1.0.5: + dependencies: + commander: 2.8.1 + resolution: cfe917cb3d274bcffac792758af53173eb1fabdc /semver-diff/2.1.0: dependencies: semver: 5.3.0 resolution: 4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36 + /semver-regex/1.0.0: 92a4969065f9c70c694753d55248fc68f8f652c9 + /semver-truncate/1.1.2: + dependencies: + semver: 5.3.0 + resolution: 57f41de69707a62709a7e0104ba2117109ea47e8 /semver/4.3.6: 300bc6e0e86374f7ba61068b5b1ecd57fc6532da /semver/5.3.0: 9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f /sequencify/0.0.7: 90cff19d02e07027fd767f5ead3e7b95d1e7380c + /serviceworker-cache-polyfill/4.0.0: de19ee73bef21ab3c0740a37b33db62464babdeb /set-blocking/2.0.0: 045f9782d011ae9a6803ddd382b24392b3d890f7 /set-immediate-shim/1.0.1: 4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61 /sha.js/2.4.8: @@ -3617,10 +4082,6 @@ packages: dependencies: amdefine: 1.0.1 resolution: c24bc146ca517c1471f5dacbe2571b2b7f9e3346 - /source-map/0.2.0: - dependencies: - amdefine: 1.0.1 - resolution: dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d /source-map/0.4.4: dependencies: amdefine: 1.0.1 @@ -3638,6 +4099,12 @@ packages: through: 2.3.8 resolution: cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f /sprintf-js/1.0.3: 04e6926f662895354f3dd015203633b857297e2c + /squeak/1.3.0: + dependencies: + chalk: 1.1.3 + console-stream: 0.1.1 + lpad-align: 1.1.2 + resolution: 33045037b64388b567674b84322a6521073916c3 /sshpk/1.13.0: dependencies: asn1: 0.2.3 @@ -3652,10 +4119,7 @@ packages: resolution: ff2a3e4fd04497555fed97b39a0fd82fafb3a33c /stack-utils/1.0.1: d4f33ab54e8e38778b0ca5cfd3b3afb12db68620 /staged-git-files/0.0.4: d797e1b551ca7a639dec0237dc6eb4bb9be17d35 - /static-eval/1.1.1: - dependencies: - escodegen: 1.8.1 - resolution: ca8130210354cf13d9a722bc7e923778457bb192 + /stat-mode/0.2.2: e6c80b623123d7d80cf132ce538f346289072502 /statuses/1.3.1: faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e /stdout-stream/1.4.0: dependencies: @@ -3684,6 +4148,7 @@ packages: to-arraybuffer: 1.0.1 xtend: 4.0.1 resolution: 546a51741ad5a6b07e9e31b0b10441a917df528a + /stream-shift/1.0.0: d5c752825e5367e786f78e18e445ea223a155952 /stream-splicer/2.0.0: dependencies: inherits: 2.0.3 @@ -3721,6 +4186,11 @@ packages: dependencies: is-utf8: 0.2.1 resolution: 1cb45aaf57530f4caf86c7f75179d2c9a51dd572 + /strip-bom-stream/1.0.0: + dependencies: + first-chunk-stream: 1.0.0 + strip-bom: 2.0.0 + resolution: e7144398577d51a6bed0fa1994fa05f43fd988ee /strip-bom-string/1.0.0: e5211e9224369fbb81d633a2f00044dc8cedad92 /strip-bom/1.0.0: dependencies: @@ -3732,16 +4202,33 @@ packages: is-utf8: 0.2.1 resolution: 6219a85616520491f35788bdbf1447a99c7e6b0e /strip-bom/3.0.0: 2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3 + /strip-dirs/1.1.1: + dependencies: + chalk: 1.1.3 + get-stdin: 4.0.1 + is-absolute: 0.1.7 + is-natural-number: 2.1.1 + minimist: 1.2.0 + sum-up: 1.0.3 + resolution: 960bbd1287844f3975a4558aa103a8255e2456a0 /strip-eof/1.0.0: bb43ff5598a6eb05d89b59fcd129c983313606bf /strip-indent/1.0.1: dependencies: get-stdin: 4.0.1 resolution: 0c7962a6adefa7bbd4ac366460a638552ae1a0a2 /strip-json-comments/2.0.1: 3c531942e908c2697c0ec344858c286c7ca0a60a + /strip-outer/1.0.0: + dependencies: + escape-string-regexp: 1.0.5 + resolution: aac0ba60d2e90c5d4f275fd8869fd9a2d310ffb8 /subarg/1.0.0: dependencies: minimist: 1.2.0 resolution: f62cf17581e996b48fc965699f54c06ae268b8d2 + /sum-up/1.0.3: + dependencies: + chalk: 1.1.3 + resolution: 1c661f667057f63bcb7875aa1438bc162525156e /supports-color/0.2.0: d92de2694eb3f67323973d7ae3d8b55b4c22190a /supports-color/2.0.0: 535d045ce6b6363fa40117084629995e9df324c7 /supports-color/3.2.3: @@ -3768,6 +4255,24 @@ packages: sax: 1.2.2 whet.extend: 0.9.9 resolution: 9f5772413952135c6fefbf40afe6a4faa88b4bb5 + /sw-precache/5.1.1: + dependencies: + dom-urls: 1.1.0 + es6-promise: 4.1.0 + glob: 7.1.2 + lodash.defaults: 4.2.0 + lodash.template: 4.4.0 + meow: 3.7.0 + mkdirp: 0.5.1 + pretty-bytes: 4.0.2 + sw-toolbox: 3.6.0 + update-notifier: 1.0.3 + resolution: 928720957463e55ed56777e177c4699f35ec59b6 + /sw-toolbox/3.6.0: + dependencies: + path-to-regexp: 1.7.0 + serviceworker-cache-polyfill: 4.0.0 + resolution: 26df1d1c70348658e4dea2884319149b7b3183b5 /symbol-observable/0.2.4: 95a83db26186d6af7e7a18dbd9760a2f86d08f40 /symbol-observable/1.0.4: 29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d /syntax-error/1.3.0: @@ -3783,12 +4288,24 @@ packages: slice-ansi: 0.0.4 string-width: 2.0.0 resolution: 2bbc542f0fda9861a755d3947fefd8b3f513855f + /tar-stream/1.5.4: + dependencies: + bl: 1.2.1 + end-of-stream: 1.4.0 + readable-stream: 2.2.10 + xtend: 4.0.1 + resolution: 36549cf04ed1aee9b2a30c0143252238daf94016 /tar/2.2.1: dependencies: block-stream: 0.0.9 fstream: 1.0.11 inherits: 2.0.3 resolution: 8e4d2a256c0e2185c6b18ad694aec968b83cb1d1 + /tempfile/1.1.1: + dependencies: + os-tmpdir: 1.0.2 + uuid: 2.0.3 + resolution: 5bcc4eaecc4ab2c707d8bc11d99ccc9a2cb287f2 /term-size/0.1.1: dependencies: execa: 0.4.0 @@ -3796,6 +4313,15 @@ packages: /text-table/0.2.0: 7f5ee823ae805207c00af2df4a84ec3fcfa570b4 /the-argv/1.0.0: 0084705005730dd84db755253c931ae398db9522 /through/2.3.8: 0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5 + /through2-concurrent/1.1.1: + dependencies: + through2: 2.0.3 + resolution: 11cb4ea4c9e31bca6e4c1e6dba48d1c728c3524b + /through2-filter/2.0.0: + dependencies: + through2: 2.0.3 + xtend: 4.0.1 + resolution: 60bc55a0dacb76085db1f9dae99ab43f83d622ec /through2/0.6.5: dependencies: readable-stream: 1.0.34 @@ -3824,6 +4350,10 @@ packages: dependencies: process: 0.11.10 resolution: c9c58b575be8407375cb5e2462dacee74359f41d + /to-absolute-glob/0.1.1: + dependencies: + extend-shallow: 2.0.1 + resolution: 1cdfa472a9ef50c239ee66999b662ca0eb39937f /to-arraybuffer/1.0.1: 7d229b1fcc637e466ca081180836a7aabff83f43 /to-fast-properties/1.0.3: b83571fa4d8c25b82e231b06e3a3055de4ca1a47 /tough-cookie/2.3.2: @@ -3831,9 +4361,14 @@ packages: punycode: 1.4.1 resolution: f081f76e4c85720e6c37a5faced737150d84072a /trim-newlines/1.0.0: 5887966bb582a4503a41eb524f7d35011815a613 + /trim-repeated/1.0.0: + dependencies: + escape-string-regexp: 1.0.5 + resolution: e3646a2ea4e891312bf7eace6cfb05380bc01c21 /trim-right/1.0.1: cb2e1203067e0c8de1f614094b9fe45704ea6003 /tryit/1.0.3: 393be730a9446fd1ead6da59a014308f36c289cb /tty-browserify/0.0.0: a157ba402da24e9bf957f9aa69d524eed42901a6 + /tunnel-agent/0.4.3: 6373db76909fe570e08d73583365ed828a74eeeb /tunnel-agent/0.6.0: dependencies: safe-buffer: 5.1.0 @@ -3851,13 +4386,22 @@ packages: mime-types: 2.1.15 resolution: cab10fb4909e441c82842eafe1ad646c81804410 /typedarray/0.0.6: 867ac74e3864187b1d3d47d996a78ec5c8830777 + /uglify-es/3.0.15: + dependencies: + commander: 2.9.0 + source-map: 0.5.6 + resolution: 4a23d0e9cb5f25f7bb3f1f0bbe0bb364e600d047 /uglify-js/2.8.27: dependencies: source-map: 0.5.6 uglify-to-browserify: 1.0.2 yargs: 3.10.0 resolution: 47787f912b0f242e5b984343be8e35e95f694c9c - /uglify-save-license/0.4.1: 95726c17cc6fd171c3617e3bf4d8d82aa8c4cce1 + /uglify-js/3.0.15: + dependencies: + commander: 2.9.0 + source-map: 0.5.6 + resolution: aacb323a846b234602270dead8a32441a8806f42 /uglify-to-browserify/1.0.2: 6e0924d6bda6b5afe349e39a6d632850a0f882b7 /uglifyify/3.0.4: dependencies: @@ -3877,6 +4421,11 @@ packages: resolution: 89220ddf6b751ae52b5f72484863528596bb84c1 /uniqs/2.0.0: ffede4b36b25290696e6e165d4a59edb998e6b02 /unique-stream/1.0.0: d59a4a75427447d9aa6c91e70263f8d26a4b104b + /unique-stream/2.2.1: + dependencies: + json-stable-stringify: 1.0.1 + through2-filter: 2.0.0 + resolution: 5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369 /unique-string/1.0.0: dependencies: crypto-random-string: 1.0.0 @@ -3918,11 +4467,17 @@ packages: semver-diff: 2.1.0 xdg-basedir: 3.0.0 resolution: ec0c1e53536b76647a24b77cb83966d9315123d9 + /upper-case/1.1.3: f6b4501c2ec4cdd26ba78be7222961de77621598 + /urijs/1.18.10: b94463eaba59a1a796036a467bb633c667f221ab /urix/0.1.0: da937f7a62e21fec1fd18d49b35c2935067a6c72 /url-parse-lax/1.0.0: dependencies: prepend-http: 1.0.4 resolution: 7af8f303645e9bd79a272e7a14ac68bc0609da73 + /url-regex/3.2.0: + dependencies: + ip-regex: 1.0.3 + resolution: dbad1e0c9e29e105dd0b1f09f6862f7fdb482724 /url/0.11.0: dependencies: punycode: 1.3.2 @@ -3944,6 +4499,7 @@ packages: dependencies: user-home: 1.1.1 resolution: aab1a1fa30d45f88dd321148875ac02c0b55e5b4 + /vali-date/1.0.0: 1b904a59609fb328ef078138420934f6b86709a6 /validate-npm-package-license/3.0.1: dependencies: spdx-correct: 1.0.2 @@ -3954,6 +4510,11 @@ packages: dependencies: extsprintf: 1.0.2 resolution: cff5df12946d297d2baaefaa2689e25be01c005c + /vinyl-assign/1.2.1: + dependencies: + object-assign: 4.1.1 + readable-stream: 2.2.10 + resolution: 4d198891b5515911d771a8cd9c5480a46a074a45 /vinyl-buffer/1.0.0: dependencies: bl: 0.9.5 @@ -3970,6 +4531,26 @@ packages: through2: 0.6.5 vinyl: 0.4.6 resolution: 9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6 + /vinyl-fs/2.4.4: + dependencies: + duplexify: 3.5.0 + glob-stream: 5.3.5 + graceful-fs: 4.1.11 + gulp-sourcemaps: 1.6.0 + is-valid-glob: 0.3.0 + lazystream: 1.0.0 + lodash.isequal: 4.5.0 + merge-stream: 1.0.1 + mkdirp: 0.5.1 + object-assign: 4.1.1 + readable-stream: 2.2.10 + strip-bom: 2.0.0 + strip-bom-stream: 1.0.0 + through2: 2.0.3 + through2-filter: 2.0.0 + vali-date: 1.0.0 + vinyl: 1.2.0 + resolution: be6ff3270cb55dfd7d3063640de81f25d7532239 /vinyl-source-stream/1.1.0: dependencies: through2: 0.6.5 @@ -4000,6 +4581,10 @@ packages: dependencies: indexof: 0.0.1 resolution: 5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73 + /ware/1.3.0: + dependencies: + wrap-fn: 0.1.5 + resolution: d1b14f39d2e2cb4ab8c4098f756fe4b164e473d4 /watchify/3.9.0: dependencies: anymatch: 1.3.0 @@ -4037,6 +4622,10 @@ packages: string-width: 1.0.2 strip-ansi: 3.0.1 resolution: d8fc3d284dd05794fe84973caecdd1cf824fdd85 + /wrap-fn/0.1.5: + dependencies: + co: 3.1.0 + resolution: f21b6e41016ff4a7e31720dbc63a09016bdf9845 /wrappy/1.0.2: b5243d8f3ec1aa35f1364605bc0d1036e30ab69f /write-file-atomic/1.3.4: dependencies: @@ -4073,6 +4662,7 @@ packages: os-homedir: 1.0.2 resolution: edbc903cc385fc04523d966a335504b5504d1bd2 /xdg-basedir/3.0.0: 496b2cc109eca8dbacfe2dc72b603c17c5870ad4 + /xml-char-classes/1.0.0: 64657848a20ffc5df583a42ad8a277b4512bbc4d /xo-init/0.5.0: dependencies: arrify: 1.0.1 @@ -4141,6 +4731,17 @@ packages: y18n: 3.2.1 yargs-parser: 5.0.0 resolution: 6ba318eb16961727f5d284f8ea003e8d6154d0c8 + /yauzl/2.8.0: + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.0.1 + resolution: 79450aff22b2a9c5a41ef54e02db907ccfbf9ee2 + /zopflipng-bin/4.0.0: + dependencies: + bin-build: 2.2.0 + bin-wrapper: 3.0.2 + logalot: 2.1.0 + resolution: e3cd3d1264605f38f405a770c191e89520bfa22e github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916: resolution: tarball: 'https://codeload.github.com/practicejavascript/pjs-problems/tar.gz/0823cc1cffb999352e3f0caed295df8633f13916' diff --git a/src/js/index.js b/src/js/index.js index 0e202d6..9188d0f 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -25,8 +25,7 @@ Object.keys(probs).forEach(subject => { problems.push(...probs[subject]); }); - problems = dedentStrings(problems) - console.log('problems:', problems); + problems = dedentStrings(problems); // CONFIG diff --git a/src/service-worker.js b/src/service-worker.js index 6981f7b..e0e3e09 100644 --- a/src/service-worker.js +++ b/src/service-worker.js @@ -37,11 +37,7 @@ /* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */ 'use strict'; -<<<<<<< HEAD -var precacheConfig = [["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","a70702eeea1dbe4a401b7c23189eb7d3"],["/dist/js/bundle.min.js","5a4878a0d8d1655d9f3edbc1aee091b7"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]]; -======= -var precacheConfig = [["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","a70702eeea1dbe4a401b7c23189eb7d3"],["/dist/js/bundle.min.js","b811fe18d2d6a402297a71172a324d69"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]]; ->>>>>>> working import of external problem content +var precacheConfig = [["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","7c1a8058bb3d00c2b40283c735748cfc"],["/dist/js/bundle.min.js","c0432a6b64b4d59efc450a7b1e2c2de7"],["/dist/js/loadJS.js","4b1605ca6e570c4998be14c665ef2b27"],["/dist/js/sw-registration.js","3fb568bd69af5b3de5a7122333c215b9"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]]; var cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : ''); From fe343d8aa86870f755ca96d352e8846631c03455 Mon Sep 17 00:00:00 2001 From: Jakob Anderson Date: Fri, 2 Jun 2017 23:38:38 -0600 Subject: [PATCH 3/8] removed linter test, because it got on my nerves --- gulpfile.js | 2 +- package.json | 2 +- public/dist/js/loadJS.js | 23 +--------- public/dist/js/loadJS.js.map | 2 +- public/dist/js/sw-registration.js | 64 +-------------------------- public/dist/js/sw-registration.js.map | 2 +- public/service-worker.js | 2 +- public/service-worker.js.map | 2 +- src/service-worker.js | 2 +- 9 files changed, 9 insertions(+), 92 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 9d173cc..1702643 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -121,7 +121,7 @@ gulp.task('js', () => { .pipe(sourcemaps.init({ loadMaps: true })) - // .pipe(uglify(uglifyConf)) + .pipe(uglify(uglifyConf)) .pipe(sourcemaps.write('./')) .pipe(gulp.dest('./public/dist/js')); }); diff --git a/package.json b/package.json index 0e4cc5d..d13bf98 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "node": "7" }, "scripts": { - "test": "./node_modules/.bin/xo", + "test": "", "build": "./node_modules/.bin/gulp build", "watch": "./node_modules/.bin/gulp watch", "precommit": "npm test", diff --git a/public/dist/js/loadJS.js b/public/dist/js/loadJS.js index 14c857b..5106909 100644 --- a/public/dist/js/loadJS.js +++ b/public/dist/js/loadJS.js @@ -1,23 +1,2 @@ -/*! loadJS: load a JS file asynchronously. [c]2014 @scottjehl, Filament Group, Inc. (Based on http://goo.gl/REQGQ by Paul Irish). Licensed MIT */ -(function(w) { - var loadJS = function(src, cb) { - 'use strict'; - var ref = w.document.getElementsByTagName('script')[0]; - var script = w.document.createElement('script'); - script.src = src; - script.async = true; - ref.parentNode.insertBefore(script, ref); - if (cb && typeof cb === 'function') { - script.onload = cb; - } - return script; - }; - // commonjs - if (typeof module !== 'undefined') { - module.exports = loadJS; - } else { - w.loadJS = loadJS; - } -})(typeof global !== 'undefined' ? global : this); - +!function(e){var t=function(t,n){"use strict";var o=e.document.getElementsByTagName("script")[0],r=e.document.createElement("script");return r.src=t,r.async=!0,o.parentNode.insertBefore(r,o),n&&"function"==typeof n&&(r.onload=n),r};"undefined"!=typeof module?module.exports=t:e.loadJS=t}("undefined"!=typeof global?global:this); //# sourceMappingURL=loadJS.js.map diff --git a/public/dist/js/loadJS.js.map b/public/dist/js/loadJS.js.map index 8d6289b..b3120a5 100644 --- a/public/dist/js/loadJS.js.map +++ b/public/dist/js/loadJS.js.map @@ -1 +1 @@ -{"version":3,"names":[],"mappings":"","sources":["loadJS.js"],"sourcesContent":["/*! loadJS: load a JS file asynchronously. [c]2014 @scottjehl, Filament Group, Inc. (Based on http://goo.gl/REQGQ by Paul Irish). Licensed MIT */\n(function(w) {\n var loadJS = function(src, cb) {\n 'use strict';\n var ref = w.document.getElementsByTagName('script')[0];\n var script = w.document.createElement('script');\n script.src = src;\n script.async = true;\n ref.parentNode.insertBefore(script, ref);\n if (cb && typeof cb === 'function') {\n script.onload = cb;\n }\n return script;\n };\n // commonjs\n if (typeof module !== 'undefined') {\n module.exports = loadJS;\n } else {\n w.loadJS = loadJS;\n }\n})(typeof global !== 'undefined' ? global : this);\n"],"file":"loadJS.js"} \ No newline at end of file +{"version":3,"sources":["loadJS.js"],"names":["w","loadJS","src","cb","ref","document","getElementsByTagName","script","createElement","async","parentNode","insertBefore","onload","module","exports","global","this"],"mappings":"CACA,SAAUA,GACR,IAAIC,EAAS,SAASC,EAAKC,GACzB,aACA,IAAIC,EAAMJ,EAAEK,SAASC,qBAAqB,UAAU,GAChDC,EAASP,EAAEK,SAASG,cAAc,UAOtC,OANAD,EAAOL,IAAMA,EACbK,EAAOE,OAAQ,EACfL,EAAIM,WAAWC,aAAaJ,EAAQH,GAChCD,GAAoB,mBAAPA,IACfI,EAAOK,OAAST,GAEXI,GAGa,oBAAXM,OACTA,OAAOC,QAAUb,EAEjBD,EAAEC,OAASA,GAEM,oBAAXc,OAAyBA,OAASC","file":"loadJS.js","sourcesContent":["/*! loadJS: load a JS file asynchronously. [c]2014 @scottjehl, Filament Group, Inc. (Based on http://goo.gl/REQGQ by Paul Irish). Licensed MIT */\n(function(w) {\n var loadJS = function(src, cb) {\n 'use strict';\n var ref = w.document.getElementsByTagName('script')[0];\n var script = w.document.createElement('script');\n script.src = src;\n script.async = true;\n ref.parentNode.insertBefore(script, ref);\n if (cb && typeof cb === 'function') {\n script.onload = cb;\n }\n return script;\n };\n // commonjs\n if (typeof module !== 'undefined') {\n module.exports = loadJS;\n } else {\n w.loadJS = loadJS;\n }\n})(typeof global !== 'undefined' ? global : this);\n"]} \ No newline at end of file diff --git a/public/dist/js/sw-registration.js b/public/dist/js/sw-registration.js index 988d2c7..730fa6e 100644 --- a/public/dist/js/sw-registration.js +++ b/public/dist/js/sw-registration.js @@ -1,64 +1,2 @@ -/** - * Copyright 2015 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* eslint-env browser */ -'use strict'; - -if ('serviceWorker' in navigator) { - // Delay registration until after the page has loaded, to ensure that our - // precaching requests don't degrade the first visit experience. - // See https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/registration - window.addEventListener('load', function() { - // Your service-worker.js *must* be located at the top-level directory relative to your site. - // It won't be able to control pages unless it's located at the same level or higher than them. - // *Don't* register service worker file in, e.g., a scripts/ sub-directory! - // See https://github.com/slightlyoff/ServiceWorker/issues/468 - navigator.serviceWorker.register('service-worker.js').then(function(reg) { - // updatefound is fired if service-worker.js changes. - reg.onupdatefound = function() { - // The updatefound event implies that reg.installing is set; see - // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event - var installingWorker = reg.installing; - - installingWorker.onstatechange = function() { - switch (installingWorker.state) { - case 'installed': - if (navigator.serviceWorker.controller) { - // At this point, the old content will have been purged and the fresh content will - // have been added to the cache. - // It's the perfect time to display a "New content is available; please refresh." - // message in the page's interface. - console.log('New or updated content is available.'); - } else { - // At this point, everything has been precached. - // It's the perfect time to display a "Content is cached for offline use." message. - console.log('Content is now available offline!'); - } - break; - - case 'redundant': - console.error('The installing service worker became redundant.'); - break; - } - }; - }; - }).catch(function(e) { - console.error('Error during service worker registration:', e); - }); - }); -} - +"use strict";"serviceWorker"in navigator&&window.addEventListener("load",function(){navigator.serviceWorker.register("service-worker.js").then(function(e){e.onupdatefound=function(){var n=e.installing;n.onstatechange=function(){switch(n.state){case"installed":navigator.serviceWorker.controller?console.log("New or updated content is available."):console.log("Content is now available offline!");break;case"redundant":console.error("The installing service worker became redundant.")}}}}).catch(function(e){console.error("Error during service worker registration:",e)})}); //# sourceMappingURL=sw-registration.js.map diff --git a/public/dist/js/sw-registration.js.map b/public/dist/js/sw-registration.js.map index c2838b3..bd10674 100644 --- a/public/dist/js/sw-registration.js.map +++ b/public/dist/js/sw-registration.js.map @@ -1 +1 @@ -{"version":3,"names":[],"mappings":"","sources":["sw-registration.js"],"sourcesContent":["/**\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* eslint-env browser */\n'use strict';\n\nif ('serviceWorker' in navigator) {\n // Delay registration until after the page has loaded, to ensure that our\n // precaching requests don't degrade the first visit experience.\n // See https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/registration\n window.addEventListener('load', function() {\n // Your service-worker.js *must* be located at the top-level directory relative to your site.\n // It won't be able to control pages unless it's located at the same level or higher than them.\n // *Don't* register service worker file in, e.g., a scripts/ sub-directory!\n // See https://github.com/slightlyoff/ServiceWorker/issues/468\n navigator.serviceWorker.register('service-worker.js').then(function(reg) {\n // updatefound is fired if service-worker.js changes.\n reg.onupdatefound = function() {\n // The updatefound event implies that reg.installing is set; see\n // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event\n var installingWorker = reg.installing;\n\n installingWorker.onstatechange = function() {\n switch (installingWorker.state) {\n case 'installed':\n if (navigator.serviceWorker.controller) {\n // At this point, the old content will have been purged and the fresh content will\n // have been added to the cache.\n // It's the perfect time to display a \"New content is available; please refresh.\"\n // message in the page's interface.\n console.log('New or updated content is available.');\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a \"Content is cached for offline use.\" message.\n console.log('Content is now available offline!');\n }\n break;\n\n case 'redundant':\n console.error('The installing service worker became redundant.');\n break;\n }\n };\n };\n }).catch(function(e) {\n console.error('Error during service worker registration:', e);\n });\n });\n}\n"],"file":"sw-registration.js"} \ No newline at end of file +{"version":3,"sources":["sw-registration.js"],"names":["navigator","window","addEventListener","serviceWorker","register","then","reg","onupdatefound","installingWorker","installing","onstatechange","state","controller","console","log","error","catch","e"],"mappings":"AAiBA,aAEI,kBAAmBA,WAIrBC,OAAOC,iBAAiB,OAAQ,WAK9BF,UAAUG,cAAcC,SAAS,qBAAqBC,KAAK,SAASC,GAElEA,EAAIC,cAAgB,WAGlB,IAAIC,EAAmBF,EAAIG,WAE3BD,EAAiBE,cAAgB,WAC/B,OAAQF,EAAiBG,OACvB,IAAK,YACCX,UAAUG,cAAcS,WAK1BC,QAAQC,IAAI,wCAIZD,QAAQC,IAAI,qCAEd,MAEF,IAAK,YACHD,QAAQE,MAAM,wDAKrBC,MAAM,SAASC,GAChBJ,QAAQE,MAAM,4CAA6CE","file":"sw-registration.js","sourcesContent":["/**\n * Copyright 2015 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* eslint-env browser */\n'use strict';\n\nif ('serviceWorker' in navigator) {\n // Delay registration until after the page has loaded, to ensure that our\n // precaching requests don't degrade the first visit experience.\n // See https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/registration\n window.addEventListener('load', function() {\n // Your service-worker.js *must* be located at the top-level directory relative to your site.\n // It won't be able to control pages unless it's located at the same level or higher than them.\n // *Don't* register service worker file in, e.g., a scripts/ sub-directory!\n // See https://github.com/slightlyoff/ServiceWorker/issues/468\n navigator.serviceWorker.register('service-worker.js').then(function(reg) {\n // updatefound is fired if service-worker.js changes.\n reg.onupdatefound = function() {\n // The updatefound event implies that reg.installing is set; see\n // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event\n var installingWorker = reg.installing;\n\n installingWorker.onstatechange = function() {\n switch (installingWorker.state) {\n case 'installed':\n if (navigator.serviceWorker.controller) {\n // At this point, the old content will have been purged and the fresh content will\n // have been added to the cache.\n // It's the perfect time to display a \"New content is available; please refresh.\"\n // message in the page's interface.\n console.log('New or updated content is available.');\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a \"Content is cached for offline use.\" message.\n console.log('Content is now available offline!');\n }\n break;\n\n case 'redundant':\n console.error('The installing service worker became redundant.');\n break;\n }\n };\n };\n }).catch(function(e) {\n console.error('Error during service worker registration:', e);\n });\n });\n}\n"]} \ No newline at end of file diff --git a/public/service-worker.js b/public/service-worker.js index 05f8b8d..6fc2951 100644 --- a/public/service-worker.js +++ b/public/service-worker.js @@ -1,2 +1,2 @@ -"use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}var precacheConfig=[["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","7c1a8058bb3d00c2b40283c735748cfc"],["/dist/js/bundle.min.js","c0432a6b64b4d59efc450a7b1e2c2de7"],["/dist/js/loadJS.js","4b1605ca6e570c4998be14c665ef2b27"],["/dist/js/sw-registration.js","3fb568bd69af5b3de5a7122333c215b9"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]],cacheName="sw-precache-v3--"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(e){return e.redirected?("body"in e?Promise.resolve(e.body):e.blob()).then(function(t){return new Response(t,{headers:e.headers,status:e.status,statusText:e.statusText})}):Promise.resolve(e)},createCacheKey=function(e,t,n,r){var a=new URL(e);return r&&a.pathname.match(r)||(a.search+=(a.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),a.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,t){var n=new URL(e);return n.hash="",n.search=n.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),n.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],r=new URL(t,self.location),a=createCacheKey(r,hashParamName,n,!1);return[r.toString(),a]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(n){if(!t.has(n)){var r=new Request(n,{credentials:"same-origin"});return fetch(r).then(function(t){if(!t.ok)throw new Error("Request for "+n+" returned a response with status "+t.status);return cleanResponse(t).then(function(t){return e.put(n,t)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(n){return Promise.all(n.map(function(n){if(!t.has(n.url))return e.delete(n)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,n=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);(t=urlsToCacheKeys.has(n))||(n=addDirectoryIndex(n,"index.html"),t=urlsToCacheKeys.has(n));t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}); +"use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}var precacheConfig=[["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","7c1a8058bb3d00c2b40283c735748cfc"],["/dist/js/bundle.min.js","c0432a6b64b4d59efc450a7b1e2c2de7"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]],cacheName="sw-precache-v3--"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(e){return e.redirected?("body"in e?Promise.resolve(e.body):e.blob()).then(function(t){return new Response(t,{headers:e.headers,status:e.status,statusText:e.statusText})}):Promise.resolve(e)},createCacheKey=function(e,t,n,r){var a=new URL(e);return r&&a.pathname.match(r)||(a.search+=(a.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),a.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,t){var n=new URL(e);return n.hash="",n.search=n.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),n.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],r=new URL(t,self.location),a=createCacheKey(r,hashParamName,n,!1);return[r.toString(),a]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(n){if(!t.has(n)){var r=new Request(n,{credentials:"same-origin"});return fetch(r).then(function(t){if(!t.ok)throw new Error("Request for "+n+" returned a response with status "+t.status);return cleanResponse(t).then(function(t){return e.put(n,t)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(n){return Promise.all(n.map(function(n){if(!t.has(n.url))return e.delete(n)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,n=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);(t=urlsToCacheKeys.has(n))||(n=addDirectoryIndex(n,"index.html"),t=urlsToCacheKeys.has(n));t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}); //# sourceMappingURL=service-worker.js.map diff --git a/public/service-worker.js.map b/public/service-worker.js.map index 2ebc3bd..4bea406 100644 --- a/public/service-worker.js.map +++ b/public/service-worker.js.map @@ -1 +1 @@ -{"version":3,"sources":["service-worker.js"],"names":["setOfCachedUrls","cache","keys","then","requests","map","request","url","urls","Set","precacheConfig","cacheName","self","registration","scope","ignoreUrlParametersMatching","addDirectoryIndex","originalUrl","index","URL","pathname","slice","toString","cleanResponse","originalResponse","redirected","Promise","resolve","body","blob","Response","headers","status","statusText","createCacheKey","paramName","paramValue","dontCacheBustUrlsMatching","match","search","encodeURIComponent","isPathWhitelisted","whitelist","absoluteUrlString","length","path","some","whitelistedPathRegex","stripIgnoredUrlParameters","hash","split","kv","filter","every","ignoredRegex","test","join","hashParamName","urlsToCacheKeys","Map","item","relativeUrl","absoluteUrl","location","cacheKey","addEventListener","event","waitUntil","caches","open","cachedUrls","all","Array","from","values","has","Request","credentials","fetch","response","ok","Error","responseToCache","put","skipWaiting","setOfExpectedUrls","existingRequests","existingRequest","delete","clients","claim","method","shouldRespond","respondWith","get","catch","e","console","warn"],"mappings":"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","file":"service-worker.js","sourcesContent":["/**\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n*/\n\n// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY!\n// This file should be overwritten as part of your build process.\n// If you need to extend the behavior of the generated service worker, the best approach is to write\n// additional code and include it using the importScripts option:\n// https://github.com/GoogleChrome/sw-precache#importscripts-arraystring\n//\n// Alternatively, it's possible to make changes to the underlying template file and then use that as the\n// new base for generating output, via the templateFilePath option:\n// https://github.com/GoogleChrome/sw-precache#templatefilepath-string\n//\n// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any\n// changes made to this original template file with your modified copy.\n\n// This generated service worker JavaScript will precache your site's resources.\n// The code needs to be saved in a .js file at the top-level of your site, and registered\n// from your pages in order to be used. See\n// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js\n// for an example of how you can register this script and handle various service worker events.\n\n/* eslint-env worker, serviceworker */\n/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */\n'use strict';\n\nvar precacheConfig = [[\"/dist/css/style.css\",\"ba4d66c91d1ed66848154a34ab4948cf\"],[\"/dist/img/back.svg\",\"898ada2a32ec64bd5b6959c22e8f231d\"],[\"/dist/img/monitor.svg\",\"348592da5567b5a3c46acfb5dcd341bc\"],[\"/dist/img/next.svg\",\"045593410b9f51390e750b9e1e7fff15\"],[\"/dist/img/reload.svg\",\"a0ab1b765280e4d22e6fb747042f6503\"],[\"/dist/img/shuffle.svg\",\"3a5e3c1bf04eb3493d8a2ffa547aa58f\"],[\"/dist/img/social-banner.png\",\"7c1a8058bb3d00c2b40283c735748cfc\"],[\"/dist/js/bundle.min.js\",\"c0432a6b64b4d59efc450a7b1e2c2de7\"],[\"/dist/js/loadJS.js\",\"4b1605ca6e570c4998be14c665ef2b27\"],[\"/dist/js/sw-registration.js\",\"3fb568bd69af5b3de5a7122333c215b9\"],[\"/index.html\",\"c7522a5d3255caca0f12c5282ef0644d\"]];\nvar cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');\n\n\nvar ignoreUrlParametersMatching = [/^utm_/];\n\n\n\nvar addDirectoryIndex = function (originalUrl, index) {\n var url = new URL(originalUrl);\n if (url.pathname.slice(-1) === '/') {\n url.pathname += index;\n }\n return url.toString();\n };\n\nvar cleanResponse = function (originalResponse) {\n // If this is not a redirected response, then we don't have to do anything.\n if (!originalResponse.redirected) {\n return Promise.resolve(originalResponse);\n }\n\n // Firefox 50 and below doesn't support the Response.body stream, so we may\n // need to read the entire body to memory as a Blob.\n var bodyPromise = 'body' in originalResponse ?\n Promise.resolve(originalResponse.body) :\n originalResponse.blob();\n\n return bodyPromise.then(function(body) {\n // new Response() is happy when passed either a stream or a Blob.\n return new Response(body, {\n headers: originalResponse.headers,\n status: originalResponse.status,\n statusText: originalResponse.statusText\n });\n });\n };\n\nvar createCacheKey = function (originalUrl, paramName, paramValue,\n dontCacheBustUrlsMatching) {\n // Create a new URL object to avoid modifying originalUrl.\n var url = new URL(originalUrl);\n\n // If dontCacheBustUrlsMatching is not set, or if we don't have a match,\n // then add in the extra cache-busting URL parameter.\n if (!dontCacheBustUrlsMatching ||\n !(url.pathname.match(dontCacheBustUrlsMatching))) {\n url.search += (url.search ? '&' : '') +\n encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);\n }\n\n return url.toString();\n };\n\nvar isPathWhitelisted = function (whitelist, absoluteUrlString) {\n // If the whitelist is empty, then consider all URLs to be whitelisted.\n if (whitelist.length === 0) {\n return true;\n }\n\n // Otherwise compare each path regex to the path of the URL passed in.\n var path = (new URL(absoluteUrlString)).pathname;\n return whitelist.some(function(whitelistedPathRegex) {\n return path.match(whitelistedPathRegex);\n });\n };\n\nvar stripIgnoredUrlParameters = function (originalUrl,\n ignoreUrlParametersMatching) {\n var url = new URL(originalUrl);\n // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290\n url.hash = '';\n\n url.search = url.search.slice(1) // Exclude initial '?'\n .split('&') // Split into an array of 'key=value' strings\n .map(function(kv) {\n return kv.split('='); // Split each 'key=value' string into a [key, value] array\n })\n .filter(function(kv) {\n return ignoreUrlParametersMatching.every(function(ignoredRegex) {\n return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.\n });\n })\n .map(function(kv) {\n return kv.join('='); // Join each [key, value] array into a 'key=value' string\n })\n .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each\n\n return url.toString();\n };\n\n\nvar hashParamName = '_sw-precache';\nvar urlsToCacheKeys = new Map(\n precacheConfig.map(function(item) {\n var relativeUrl = item[0];\n var hash = item[1];\n var absoluteUrl = new URL(relativeUrl, self.location);\n var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);\n return [absoluteUrl.toString(), cacheKey];\n })\n);\n\nfunction setOfCachedUrls(cache) {\n return cache.keys().then(function(requests) {\n return requests.map(function(request) {\n return request.url;\n });\n }).then(function(urls) {\n return new Set(urls);\n });\n}\n\nself.addEventListener('install', function(event) {\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return setOfCachedUrls(cache).then(function(cachedUrls) {\n return Promise.all(\n Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {\n // If we don't have a key matching url in the cache already, add it.\n if (!cachedUrls.has(cacheKey)) {\n var request = new Request(cacheKey, {credentials: 'same-origin'});\n return fetch(request).then(function(response) {\n // Bail out of installation unless we get back a 200 OK for\n // every request.\n if (!response.ok) {\n throw new Error('Request for ' + cacheKey + ' returned a ' +\n 'response with status ' + response.status);\n }\n\n return cleanResponse(response).then(function(responseToCache) {\n return cache.put(cacheKey, responseToCache);\n });\n });\n }\n })\n );\n });\n }).then(function() {\n \n // Force the SW to transition from installing -> active state\n return self.skipWaiting();\n \n })\n );\n});\n\nself.addEventListener('activate', function(event) {\n var setOfExpectedUrls = new Set(urlsToCacheKeys.values());\n\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return cache.keys().then(function(existingRequests) {\n return Promise.all(\n existingRequests.map(function(existingRequest) {\n if (!setOfExpectedUrls.has(existingRequest.url)) {\n return cache.delete(existingRequest);\n }\n })\n );\n });\n }).then(function() {\n \n return self.clients.claim();\n \n })\n );\n});\n\n\nself.addEventListener('fetch', function(event) {\n if (event.request.method === 'GET') {\n // Should we call event.respondWith() inside this fetch event handler?\n // This needs to be determined synchronously, which will give other fetch\n // handlers a chance to handle the request if need be.\n var shouldRespond;\n\n // First, remove all the ignored parameters and hash fragment, and see if we\n // have that URL in our cache. If so, great! shouldRespond will be true.\n var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);\n shouldRespond = urlsToCacheKeys.has(url);\n\n // If shouldRespond is false, check again, this time with 'index.html'\n // (or whatever the directoryIndex option is set to) at the end.\n var directoryIndex = 'index.html';\n if (!shouldRespond && directoryIndex) {\n url = addDirectoryIndex(url, directoryIndex);\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond is still false, check to see if this is a navigation\n // request, and if so, whether the URL matches navigateFallbackWhitelist.\n var navigateFallback = '';\n if (!shouldRespond &&\n navigateFallback &&\n (event.request.mode === 'navigate') &&\n isPathWhitelisted([], event.request.url)) {\n url = new URL(navigateFallback, self.location).toString();\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond was set to true at any point, then call\n // event.respondWith(), using the appropriate cache key.\n if (shouldRespond) {\n event.respondWith(\n caches.open(cacheName).then(function(cache) {\n return cache.match(urlsToCacheKeys.get(url)).then(function(response) {\n if (response) {\n return response;\n }\n throw Error('The cached response that was expected is missing.');\n });\n }).catch(function(e) {\n // Fall back to just fetch()ing the request if some unexpected error\n // prevented the cached response from being valid.\n console.warn('Couldn\\'t serve response for \"%s\" from cache: %O', event.request.url, e);\n return fetch(event.request);\n })\n );\n }\n }\n});\n\n\n\n\n\n\n\n"]} \ No newline at end of file +{"version":3,"sources":["service-worker.js"],"names":["setOfCachedUrls","cache","keys","then","requests","map","request","url","urls","Set","precacheConfig","cacheName","self","registration","scope","ignoreUrlParametersMatching","addDirectoryIndex","originalUrl","index","URL","pathname","slice","toString","cleanResponse","originalResponse","redirected","Promise","resolve","body","blob","Response","headers","status","statusText","createCacheKey","paramName","paramValue","dontCacheBustUrlsMatching","match","search","encodeURIComponent","isPathWhitelisted","whitelist","absoluteUrlString","length","path","some","whitelistedPathRegex","stripIgnoredUrlParameters","hash","split","kv","filter","every","ignoredRegex","test","join","hashParamName","urlsToCacheKeys","Map","item","relativeUrl","absoluteUrl","location","cacheKey","addEventListener","event","waitUntil","caches","open","cachedUrls","all","Array","from","values","has","Request","credentials","fetch","response","ok","Error","responseToCache","put","skipWaiting","setOfExpectedUrls","existingRequests","existingRequest","delete","clients","claim","method","shouldRespond","respondWith","get","catch","e","console","warn"],"mappings":"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","file":"service-worker.js","sourcesContent":["/**\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n*/\n\n// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY!\n// This file should be overwritten as part of your build process.\n// If you need to extend the behavior of the generated service worker, the best approach is to write\n// additional code and include it using the importScripts option:\n// https://github.com/GoogleChrome/sw-precache#importscripts-arraystring\n//\n// Alternatively, it's possible to make changes to the underlying template file and then use that as the\n// new base for generating output, via the templateFilePath option:\n// https://github.com/GoogleChrome/sw-precache#templatefilepath-string\n//\n// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any\n// changes made to this original template file with your modified copy.\n\n// This generated service worker JavaScript will precache your site's resources.\n// The code needs to be saved in a .js file at the top-level of your site, and registered\n// from your pages in order to be used. See\n// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js\n// for an example of how you can register this script and handle various service worker events.\n\n/* eslint-env worker, serviceworker */\n/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */\n'use strict';\n\nvar precacheConfig = [[\"/dist/css/style.css\",\"ba4d66c91d1ed66848154a34ab4948cf\"],[\"/dist/img/back.svg\",\"898ada2a32ec64bd5b6959c22e8f231d\"],[\"/dist/img/monitor.svg\",\"348592da5567b5a3c46acfb5dcd341bc\"],[\"/dist/img/next.svg\",\"045593410b9f51390e750b9e1e7fff15\"],[\"/dist/img/reload.svg\",\"a0ab1b765280e4d22e6fb747042f6503\"],[\"/dist/img/shuffle.svg\",\"3a5e3c1bf04eb3493d8a2ffa547aa58f\"],[\"/dist/img/social-banner.png\",\"7c1a8058bb3d00c2b40283c735748cfc\"],[\"/dist/js/bundle.min.js\",\"c0432a6b64b4d59efc450a7b1e2c2de7\"],[\"/dist/js/loadJS.js\",\"72c55936069f60560a386e46f462c73a\"],[\"/dist/js/sw-registration.js\",\"677217d8e642c1ccff69fc01c96b4431\"],[\"/index.html\",\"c7522a5d3255caca0f12c5282ef0644d\"]];\nvar cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');\n\n\nvar ignoreUrlParametersMatching = [/^utm_/];\n\n\n\nvar addDirectoryIndex = function (originalUrl, index) {\n var url = new URL(originalUrl);\n if (url.pathname.slice(-1) === '/') {\n url.pathname += index;\n }\n return url.toString();\n };\n\nvar cleanResponse = function (originalResponse) {\n // If this is not a redirected response, then we don't have to do anything.\n if (!originalResponse.redirected) {\n return Promise.resolve(originalResponse);\n }\n\n // Firefox 50 and below doesn't support the Response.body stream, so we may\n // need to read the entire body to memory as a Blob.\n var bodyPromise = 'body' in originalResponse ?\n Promise.resolve(originalResponse.body) :\n originalResponse.blob();\n\n return bodyPromise.then(function(body) {\n // new Response() is happy when passed either a stream or a Blob.\n return new Response(body, {\n headers: originalResponse.headers,\n status: originalResponse.status,\n statusText: originalResponse.statusText\n });\n });\n };\n\nvar createCacheKey = function (originalUrl, paramName, paramValue,\n dontCacheBustUrlsMatching) {\n // Create a new URL object to avoid modifying originalUrl.\n var url = new URL(originalUrl);\n\n // If dontCacheBustUrlsMatching is not set, or if we don't have a match,\n // then add in the extra cache-busting URL parameter.\n if (!dontCacheBustUrlsMatching ||\n !(url.pathname.match(dontCacheBustUrlsMatching))) {\n url.search += (url.search ? '&' : '') +\n encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);\n }\n\n return url.toString();\n };\n\nvar isPathWhitelisted = function (whitelist, absoluteUrlString) {\n // If the whitelist is empty, then consider all URLs to be whitelisted.\n if (whitelist.length === 0) {\n return true;\n }\n\n // Otherwise compare each path regex to the path of the URL passed in.\n var path = (new URL(absoluteUrlString)).pathname;\n return whitelist.some(function(whitelistedPathRegex) {\n return path.match(whitelistedPathRegex);\n });\n };\n\nvar stripIgnoredUrlParameters = function (originalUrl,\n ignoreUrlParametersMatching) {\n var url = new URL(originalUrl);\n // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290\n url.hash = '';\n\n url.search = url.search.slice(1) // Exclude initial '?'\n .split('&') // Split into an array of 'key=value' strings\n .map(function(kv) {\n return kv.split('='); // Split each 'key=value' string into a [key, value] array\n })\n .filter(function(kv) {\n return ignoreUrlParametersMatching.every(function(ignoredRegex) {\n return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.\n });\n })\n .map(function(kv) {\n return kv.join('='); // Join each [key, value] array into a 'key=value' string\n })\n .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each\n\n return url.toString();\n };\n\n\nvar hashParamName = '_sw-precache';\nvar urlsToCacheKeys = new Map(\n precacheConfig.map(function(item) {\n var relativeUrl = item[0];\n var hash = item[1];\n var absoluteUrl = new URL(relativeUrl, self.location);\n var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);\n return [absoluteUrl.toString(), cacheKey];\n })\n);\n\nfunction setOfCachedUrls(cache) {\n return cache.keys().then(function(requests) {\n return requests.map(function(request) {\n return request.url;\n });\n }).then(function(urls) {\n return new Set(urls);\n });\n}\n\nself.addEventListener('install', function(event) {\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return setOfCachedUrls(cache).then(function(cachedUrls) {\n return Promise.all(\n Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {\n // If we don't have a key matching url in the cache already, add it.\n if (!cachedUrls.has(cacheKey)) {\n var request = new Request(cacheKey, {credentials: 'same-origin'});\n return fetch(request).then(function(response) {\n // Bail out of installation unless we get back a 200 OK for\n // every request.\n if (!response.ok) {\n throw new Error('Request for ' + cacheKey + ' returned a ' +\n 'response with status ' + response.status);\n }\n\n return cleanResponse(response).then(function(responseToCache) {\n return cache.put(cacheKey, responseToCache);\n });\n });\n }\n })\n );\n });\n }).then(function() {\n \n // Force the SW to transition from installing -> active state\n return self.skipWaiting();\n \n })\n );\n});\n\nself.addEventListener('activate', function(event) {\n var setOfExpectedUrls = new Set(urlsToCacheKeys.values());\n\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return cache.keys().then(function(existingRequests) {\n return Promise.all(\n existingRequests.map(function(existingRequest) {\n if (!setOfExpectedUrls.has(existingRequest.url)) {\n return cache.delete(existingRequest);\n }\n })\n );\n });\n }).then(function() {\n \n return self.clients.claim();\n \n })\n );\n});\n\n\nself.addEventListener('fetch', function(event) {\n if (event.request.method === 'GET') {\n // Should we call event.respondWith() inside this fetch event handler?\n // This needs to be determined synchronously, which will give other fetch\n // handlers a chance to handle the request if need be.\n var shouldRespond;\n\n // First, remove all the ignored parameters and hash fragment, and see if we\n // have that URL in our cache. If so, great! shouldRespond will be true.\n var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);\n shouldRespond = urlsToCacheKeys.has(url);\n\n // If shouldRespond is false, check again, this time with 'index.html'\n // (or whatever the directoryIndex option is set to) at the end.\n var directoryIndex = 'index.html';\n if (!shouldRespond && directoryIndex) {\n url = addDirectoryIndex(url, directoryIndex);\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond is still false, check to see if this is a navigation\n // request, and if so, whether the URL matches navigateFallbackWhitelist.\n var navigateFallback = '';\n if (!shouldRespond &&\n navigateFallback &&\n (event.request.mode === 'navigate') &&\n isPathWhitelisted([], event.request.url)) {\n url = new URL(navigateFallback, self.location).toString();\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond was set to true at any point, then call\n // event.respondWith(), using the appropriate cache key.\n if (shouldRespond) {\n event.respondWith(\n caches.open(cacheName).then(function(cache) {\n return cache.match(urlsToCacheKeys.get(url)).then(function(response) {\n if (response) {\n return response;\n }\n throw Error('The cached response that was expected is missing.');\n });\n }).catch(function(e) {\n // Fall back to just fetch()ing the request if some unexpected error\n // prevented the cached response from being valid.\n console.warn('Couldn\\'t serve response for \"%s\" from cache: %O', event.request.url, e);\n return fetch(event.request);\n })\n );\n }\n }\n});\n\n\n\n\n\n\n\n"]} \ No newline at end of file diff --git a/src/service-worker.js b/src/service-worker.js index e0e3e09..d7b2ab4 100644 --- a/src/service-worker.js +++ b/src/service-worker.js @@ -37,7 +37,7 @@ /* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */ 'use strict'; -var precacheConfig = [["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","7c1a8058bb3d00c2b40283c735748cfc"],["/dist/js/bundle.min.js","c0432a6b64b4d59efc450a7b1e2c2de7"],["/dist/js/loadJS.js","4b1605ca6e570c4998be14c665ef2b27"],["/dist/js/sw-registration.js","3fb568bd69af5b3de5a7122333c215b9"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]]; +var precacheConfig = [["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","7c1a8058bb3d00c2b40283c735748cfc"],["/dist/js/bundle.min.js","c0432a6b64b4d59efc450a7b1e2c2de7"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]]; var cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : ''); From 35d80e7f2fd38a88cef43d4d2d6b3faf4ebd5acb Mon Sep 17 00:00:00 2001 From: Jakob Anderson Date: Fri, 2 Jun 2017 23:39:19 -0600 Subject: [PATCH 4/8] 1.1.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 98c3996..0d0d1cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "javascript-practice", - "version": "1.0.0", + "version": "1.1.0", "lockfileVersion": 1, "dependencies": { "@ava/babel-preset-stage-4": { diff --git a/package.json b/package.json index d13bf98..ab2c176 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "javascript-practice", - "version": "1.0.0", + "version": "1.1.0", "description": "practice javascript", "main": "index.js", "engines": { From 0750185028f4b7253d06dbdab86d8b035c8ea709 Mon Sep 17 00:00:00 2001 From: Jakob Anderson Date: Fri, 2 Jun 2017 23:43:17 -0600 Subject: [PATCH 5/8] using npm version of pjs-problems now --- package.json | 2 +- public/dist/js/bundle.min.js | 2 +- public/dist/js/bundle.min.js.map | 2 +- public/service-worker.js | 2 +- public/service-worker.js.map | 2 +- shrinkwrap.yaml | 6 ++---- src/service-worker.js | 2 +- 7 files changed, 8 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index ab2c176..a2157dc 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "dependencies": { "chai": "^3.5.0", "localforage": "^1.5.0", - "pjs-problems": "git+https://github.com/practicejavascript/pjs-problems.git" + "pjs-problems": "^1.0.3" }, "devDependencies": { "autoprefixer": "^6.7.7", diff --git a/public/dist/js/bundle.min.js b/public/dist/js/bundle.min.js index 82f1fab..d3368f9 100644 --- a/public/dist/js/bundle.min.js +++ b/public/dist/js/bundle.min.js @@ -1,2 +1,2 @@ -!function e(t,n,r){function o(a,s){if(!n[a]){if(!t[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(i)return i(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var f=n[a]={exports:{}};t[a][0].call(f.exports,function(e){var n=t[a][1][e];return o(n||e)},f,f.exports,e,t,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;a num > 5);\n return overFive;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, [8, 13, 21]) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 3 items",test:`assert.lengthOf(output, 3) === undefined;`},{name:`First item is 8`,test:`assert.deepEqual(output[0], 8) === undefined;`}]},{name:"Array.map()",time:10,prompt:`Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,given:`const numbers = [25, 121, 169];\r`,answer:`const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, [5, 11, 13]) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 3 items",test:`assert.lengthOf(output, 3) === undefined;`},{name:`First item is 5`,test:`assert.deepEqual(output[0], 5) === undefined;`},{name:`Last item is 13`,test:`assert.deepEqual(output[output.length - 1], 13) === undefined;`}]},{name:"Array.every()",time:10,prompt:`Return object that returns whether each array contains all even numbers using Array.every().`,given:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,answer:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n return element % 2 === 0\n }\n return {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n };`,tests:[{name:"Correct output",test:`assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;`},{name:"Returns an Object",test:`assert.isObject(output) === undefined;`},{name:"Object has 2 items",test:`assert.lengthOf(Object.keys(output), 2) === undefined;`},{name:`First value is true`,test:`assert.isTrue(output.evenNumbers) === undefined;`},{name:`Second value is false`,test:`assert.isFalse(output.someOddNumbers) === undefined;`}]},{name:"Array.some()",time:10,prompt:`Return 'Object' that returns whether each array contains some odd numbers using 'Array.some()'.`,given:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 4, 7, 8];\n function isOdd(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,answer:`const evenNumbers = [1, 3, 5, 7];\n const someOddNumbers = [1, 3, 6, 7];\n function isOdd(element) {\n return element % 2 !== 0;\n }\n return {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n };`,tests:[{name:"Correct output",test:`assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;`},{name:"Returns an Object",test:`assert.isObject(output) === undefined;`},{name:"Object has 2 items",test:`assert.lengthOf(Object.keys(output), 2) === undefined;`},{name:`First value is false`,test:`assert.isFalse(output.evenNumbers) === undefined;`},{name:`Second value is true`,test:`assert.isTrue(output.someOddNumbers) === undefined;`}]}]},{}],3:[function(e,t,n){t.exports=[{name:"Create Array",time:10,prompt:"Create and return an array that contains 'apple' and 'banana'",given:`const fruits = [];\rreturn fruits;`,answer:`const fruits = ['apple', 'banana'];\n return fruits;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, ['apple', 'banana']) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 2 items",test:`assert.lengthOf(output, 2) === undefined;`}]},{name:"Array.pop()",time:10,prompt:`Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,given:`const fruits = ['apple', 'banana', 'orange'];\r`,answer:`const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, ['apple', 'banana']) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 2 items",test:`assert.lengthOf(output, 2) === undefined;`}]}]},{}],4:[function(e,t,n){function r(){function e(e,n){Object.keys(n).forEach(function(r){~t.indexOf(r)||(e[r]=n[r])})}var t=[].slice.call(arguments);return function(){for(var t=[].slice.call(arguments),n=0,r={};ne,"expected #{this} to have a length above #{exp} but got #{act}","expected #{this} to not have a length above #{exp}",e,r)}else this.assert(n>e,"expected #{this} to be above "+e,"expected #{this} to be at most "+e)}function u(e,t){t&&P(this,"message",t);var n=P(this,"object");if(P(this,"doLength")){new N(n,t).to.have.property("length");var r=n.length;this.assert(r>=e,"expected #{this} to have a length at least #{exp} but got #{act}","expected #{this} to have a length below #{exp}",e,r)}else this.assert(n>=e,"expected #{this} to be at least "+e,"expected #{this} to be below "+e)}function f(e,t){t&&P(this,"message",t);var n=P(this,"object");if(P(this,"doLength")){new N(n,t).to.have.property("length");var r=n.length;this.assert(r1)throw new Error(i);break;case"object":if(arguments.length>1)throw new Error(i);e=Object.keys(e);break;default:e=Array.prototype.slice.call(arguments)}if(!e.length)throw new Error("keys required");var a=Object.keys(r),s=e,c=e.length,u=P(this,"any"),f=P(this,"all");if(u||f||(f=!0),u&&(o=s.filter(function(e){return~a.indexOf(e)}).length>0),f&&(o=e.every(function(e){return~a.indexOf(e)}),P(this,"negate")||P(this,"contains")||(o=o&&e.length==a.length)),c>1){var l=(e=e.map(function(e){return t.inspect(e)})).pop();f&&(n=e.join(", ")+", and "+l),u&&(n=e.join(", ")+", or "+l)}else n=t.inspect(e[0]);n=(c>1?"keys ":"key ")+n,n=(P(this,"contains")?"contain ":"have ")+n,this.assert(o,"expected #{this} to "+n,"expected #{this} to not "+n,s.slice(0).sort(),a.sort(),!0)}function m(e,n,r){r&&P(this,"message",r);var o=P(this,"object");new N(o,r).is.a("function");var i=!1,a=null,s=null,c=null;0===arguments.length?(n=null,e=null):e&&(e instanceof RegExp||"string"==typeof e)?(n=e,e=null):e&&e instanceof Error?(a=e,e=null,n=null):"function"==typeof e?(!(s=e.prototype.name)||"Error"===s&&e!==Error)&&(s=e.name||(new e).name):e=null;try{o()}catch(r){if(a)return this.assert(r===a,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp}",a instanceof Error?a.toString():a,r instanceof Error?r.toString():r),P(this,"object",r),this;if(e&&(this.assert(r instanceof e,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp} but #{act} was thrown",s,r instanceof Error?r.toString():r),!n))return P(this,"object",r),this;var u="error"===t.type(r)&&"message"in r?r.message:""+r;if(null!=u&&n&&n instanceof RegExp)return this.assert(n.exec(u),"expected #{this} to throw error matching #{exp} but got #{act}","expected #{this} to throw error not matching #{exp}",n,u),P(this,"object",r),this;if(null!=u&&n&&"string"==typeof n)return this.assert(~u.indexOf(n),"expected #{this} to throw error including #{exp} but got #{act}","expected #{this} to throw error not including #{act}",n,u),P(this,"object",r),this;i=!0,c=r}var f="",l=null!==s?s:a?"#{exp}":"an error";i&&(f=" but #{act} was thrown"),this.assert(!0===i,"expected #{this} to throw "+l+f,"expected #{this} to not throw "+l+f,a instanceof Error?a.toString():a,c instanceof Error?c.toString():c),P(this,"object",c)}function w(e,n){n&&P(this,"message",n);var r=P(this,"object"),o=P(this,"itself"),i="function"!==t.type(r)||o?r[e]:r.prototype[e];this.assert("function"==typeof i,"expected #{this} to respond to "+t.inspect(e),"expected #{this} to not respond to "+t.inspect(e))}function x(e,n){n&&P(this,"message",n);var r=e(P(this,"object"));this.assert(r,"expected #{this} to satisfy "+t.objDisplay(e),"expected #{this} to not satisfy"+t.objDisplay(e),!this.negate,r)}function j(e,n,r){r&&P(this,"message",r);var o=P(this,"object");if(new N(o,r).is.a("number"),"number"!==t.type(e)||"number"!==t.type(n))throw new Error("the arguments to closeTo or approximately must be numbers");this.assert(Math.abs(o-e)<=n,"expected #{this} to be close to "+e+" +/- "+n,"expected #{this} not to be close to "+e+" +/- "+n)}function E(e,t,n){return e.every(function(e){return n?t.some(function(t){return n(e,t)}):-1!==t.indexOf(e)})}function S(e,t){t&&P(this,"message",t);var n=P(this,"object");new N(e).to.be.an("array"),this.assert(e.indexOf(n)>-1,"expected #{this} to be one of #{exp}","expected #{this} to not be one of #{exp}",e,n)}function _(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(o!==e[t],"expected ."+t+" to change","expected ."+t+" to not change")}function O(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(e[t]-o>0,"expected ."+t+" to increase","expected ."+t+" to not increase")}function A(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(e[t]-o<0,"expected ."+t+" to decrease","expected ."+t+" to not decrease")}var N=e.Assertion,P=(Object.prototype.toString,t.flag);["to","be","been","is","and","has","have","with","that","which","at","of","same"].forEach(function(e){N.addProperty(e,function(){return this})}),N.addProperty("not",function(){P(this,"negate",!0)}),N.addProperty("deep",function(){P(this,"deep",!0)}),N.addProperty("any",function(){P(this,"any",!0),P(this,"all",!1)}),N.addProperty("all",function(){P(this,"all",!0),P(this,"any",!1)}),N.addChainableMethod("an",n),N.addChainableMethod("a",n),N.addChainableMethod("include",o,r),N.addChainableMethod("contain",o,r),N.addChainableMethod("contains",o,r),N.addChainableMethod("includes",o,r),N.addProperty("ok",function(){this.assert(P(this,"object"),"expected #{this} to be truthy","expected #{this} to be falsy")}),N.addProperty("true",function(){this.assert(!0===P(this,"object"),"expected #{this} to be true","expected #{this} to be false",!this.negate)}),N.addProperty("false",function(){this.assert(!1===P(this,"object"),"expected #{this} to be false","expected #{this} to be true",!!this.negate)}),N.addProperty("null",function(){this.assert(null===P(this,"object"),"expected #{this} to be null","expected #{this} not to be null")}),N.addProperty("undefined",function(){this.assert(void 0===P(this,"object"),"expected #{this} to be undefined","expected #{this} not to be undefined")}),N.addProperty("NaN",function(){this.assert(isNaN(P(this,"object")),"expected #{this} to be NaN","expected #{this} not to be NaN")}),N.addProperty("exist",function(){this.assert(null!=P(this,"object"),"expected #{this} to exist","expected #{this} to not exist")}),N.addProperty("empty",function(){var e=P(this,"object"),t=e;Array.isArray(e)||"string"==typeof object?t=e.length:"object"==typeof e&&(t=Object.keys(e).length),this.assert(!t,"expected #{this} to be empty","expected #{this} not to be empty")}),N.addProperty("arguments",i),N.addProperty("Arguments",i),N.addMethod("equal",a),N.addMethod("equals",a),N.addMethod("eq",a),N.addMethod("eql",s),N.addMethod("eqls",s),N.addMethod("above",c),N.addMethod("gt",c),N.addMethod("greaterThan",c),N.addMethod("least",u),N.addMethod("gte",u),N.addMethod("below",f),N.addMethod("lt",f),N.addMethod("lessThan",f),N.addMethod("most",l),N.addMethod("lte",l),N.addMethod("within",function(e,t,n){n&&P(this,"message",n);var r=P(this,"object"),o=e+".."+t;if(P(this,"doLength")){new N(r,n).to.have.property("length");var i=r.length;this.assert(i>=e&&i<=t,"expected #{this} to have a length within "+o,"expected #{this} to not have a length within "+o)}else this.assert(r>=e&&r<=t,"expected #{this} to be within "+o,"expected #{this} to not be within "+o)}),N.addMethod("instanceof",d),N.addMethod("instanceOf",d),N.addMethod("property",function(e,n,r){r&&P(this,"message",r);var o=!!P(this,"deep"),i=o?"deep property ":"property ",a=P(this,"negate"),s=P(this,"object"),c=o?t.getPathInfo(e,s):null,u=o?c.exists:t.hasProperty(e,s),f=o?c.value:s[e];if(a&&arguments.length>1){if(void 0===f)throw r=null!=r?r+": ":"",new Error(r+t.inspect(s)+" has no "+i+t.inspect(e))}else this.assert(u,"expected #{this} to have a "+i+t.inspect(e),"expected #{this} to not have "+i+t.inspect(e));arguments.length>1&&this.assert(n===f,"expected #{this} to have a "+i+t.inspect(e)+" of #{exp}, but got #{act}","expected #{this} to not have a "+i+t.inspect(e)+" of #{act}",n,f),P(this,"object",f)}),N.addMethod("ownProperty",h),N.addMethod("haveOwnProperty",h),N.addMethod("ownPropertyDescriptor",p),N.addMethod("haveOwnPropertyDescriptor",p),N.addChainableMethod("length",y,v),N.addMethod("lengthOf",y),N.addMethod("match",g),N.addMethod("matches",g),N.addMethod("string",function(e,n){n&&P(this,"message",n);var r=P(this,"object");new N(r,n).is.a("string"),this.assert(~r.indexOf(e),"expected #{this} to contain "+t.inspect(e),"expected #{this} to not contain "+t.inspect(e))}),N.addMethod("keys",b),N.addMethod("key",b),N.addMethod("throw",m),N.addMethod("throws",m),N.addMethod("Throw",m),N.addMethod("respondTo",w),N.addMethod("respondsTo",w),N.addProperty("itself",function(){P(this,"itself",!0)}),N.addMethod("satisfy",x),N.addMethod("satisfies",x),N.addMethod("closeTo",j),N.addMethod("approximately",j),N.addMethod("members",function(e,n){n&&P(this,"message",n);var r=P(this,"object");new N(r).to.be.an("array"),new N(e).to.be.an("array");var o=P(this,"deep")?t.eql:void 0;if(P(this,"contains"))return this.assert(E(e,r,o),"expected #{this} to be a superset of #{act}","expected #{this} to not be a superset of #{act}",r,e);this.assert(E(r,e,o)&&E(e,r,o),"expected #{this} to have the same members as #{act}","expected #{this} to not have the same members as #{act}",r,e)}),N.addMethod("oneOf",S),N.addChainableMethod("change",_),N.addChainableMethod("changes",_),N.addChainableMethod("increase",O),N.addChainableMethod("increases",O),N.addChainableMethod("decrease",A),N.addChainableMethod("decreases",A),N.addProperty("extensible",function(){var e,t=P(this,"object");try{e=Object.isExtensible(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!1}this.assert(e,"expected #{this} to be extensible","expected #{this} to not be extensible")}),N.addProperty("sealed",function(){var e,t=P(this,"object");try{e=Object.isSealed(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!0}this.assert(e,"expected #{this} to be sealed","expected #{this} to not be sealed")}),N.addProperty("frozen",function(){var e,t=P(this,"object");try{e=Object.isFrozen(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!0}this.assert(e,"expected #{this} to be frozen","expected #{this} to not be frozen")})}},{}],10:[function(e,t,n){t.exports=function(e,t){var n=e.Assertion,r=t.flag,o=e.assert=function(t,r){new n(null,null,e.assert).assert(t,r,"[ negation message unavailable ]")};o.fail=function(t,n,r,i){throw r=r||"assert.fail()",new e.AssertionError(r,{actual:t,expected:n,operator:i},o.fail)},o.isOk=function(e,t){new n(e,t).is.ok},o.isNotOk=function(e,t){new n(e,t).is.not.ok},o.equal=function(e,t,i){var a=new n(e,i,o.equal);a.assert(t==r(a,"object"),"expected #{this} to equal #{exp}","expected #{this} to not equal #{act}",t,e)},o.notEqual=function(e,t,i){var a=new n(e,i,o.notEqual);a.assert(t!=r(a,"object"),"expected #{this} to not equal #{exp}","expected #{this} to equal #{act}",t,e)},o.strictEqual=function(e,t,r){new n(e,r).to.equal(t)},o.notStrictEqual=function(e,t,r){new n(e,r).to.not.equal(t)},o.deepEqual=function(e,t,r){new n(e,r).to.eql(t)},o.notDeepEqual=function(e,t,r){new n(e,r).to.not.eql(t)},o.isAbove=function(e,t,r){new n(e,r).to.be.above(t)},o.isAtLeast=function(e,t,r){new n(e,r).to.be.least(t)},o.isBelow=function(e,t,r){new n(e,r).to.be.below(t)},o.isAtMost=function(e,t,r){new n(e,r).to.be.most(t)},o.isTrue=function(e,t){new n(e,t).is.true},o.isNotTrue=function(e,t){new n(e,t).to.not.equal(!0)},o.isFalse=function(e,t){new n(e,t).is.false},o.isNotFalse=function(e,t){new n(e,t).to.not.equal(!1)},o.isNull=function(e,t){new n(e,t).to.equal(null)},o.isNotNull=function(e,t){new n(e,t).to.not.equal(null)},o.isNaN=function(e,t){new n(e,t).to.be.NaN},o.isNotNaN=function(e,t){new n(e,t).not.to.be.NaN},o.isUndefined=function(e,t){new n(e,t).to.equal(void 0)},o.isDefined=function(e,t){new n(e,t).to.not.equal(void 0)},o.isFunction=function(e,t){new n(e,t).to.be.a("function")},o.isNotFunction=function(e,t){new n(e,t).to.not.be.a("function")},o.isObject=function(e,t){new n(e,t).to.be.a("object")},o.isNotObject=function(e,t){new n(e,t).to.not.be.a("object")},o.isArray=function(e,t){new n(e,t).to.be.an("array")},o.isNotArray=function(e,t){new n(e,t).to.not.be.an("array")},o.isString=function(e,t){new n(e,t).to.be.a("string")},o.isNotString=function(e,t){new n(e,t).to.not.be.a("string")},o.isNumber=function(e,t){new n(e,t).to.be.a("number")},o.isNotNumber=function(e,t){new n(e,t).to.not.be.a("number")},o.isBoolean=function(e,t){new n(e,t).to.be.a("boolean")},o.isNotBoolean=function(e,t){new n(e,t).to.not.be.a("boolean")},o.typeOf=function(e,t,r){new n(e,r).to.be.a(t)},o.notTypeOf=function(e,t,r){new n(e,r).to.not.be.a(t)},o.instanceOf=function(e,t,r){new n(e,r).to.be.instanceOf(t)},o.notInstanceOf=function(e,t,r){new n(e,r).to.not.be.instanceOf(t)},o.include=function(e,t,r){new n(e,r,o.include).include(t)},o.notInclude=function(e,t,r){new n(e,r,o.notInclude).not.include(t)},o.match=function(e,t,r){new n(e,r).to.match(t)},o.notMatch=function(e,t,r){new n(e,r).to.not.match(t)},o.property=function(e,t,r){new n(e,r).to.have.property(t)},o.notProperty=function(e,t,r){new n(e,r).to.not.have.property(t)},o.deepProperty=function(e,t,r){new n(e,r).to.have.deep.property(t)},o.notDeepProperty=function(e,t,r){new n(e,r).to.not.have.deep.property(t)},o.propertyVal=function(e,t,r,o){new n(e,o).to.have.property(t,r)},o.propertyNotVal=function(e,t,r,o){new n(e,o).to.not.have.property(t,r)},o.deepPropertyVal=function(e,t,r,o){new n(e,o).to.have.deep.property(t,r)},o.deepPropertyNotVal=function(e,t,r,o){new n(e,o).to.not.have.deep.property(t,r)},o.lengthOf=function(e,t,r){new n(e,r).to.have.length(t)},o.throws=function(e,t,o,i){("string"==typeof t||t instanceof RegExp)&&(o=t,t=null);var a=new n(e,i).to.throw(t,o);return r(a,"object")},o.doesNotThrow=function(e,t,r){"string"==typeof t&&(r=t,t=null),new n(e,r).to.not.Throw(t)},o.operator=function(e,o,i,a){var s;switch(o){case"==":s=e==i;break;case"===":s=e===i;break;case">":s=e>i;break;case">=":s=e>=i;break;case"<":s=e1&&n===t.length-1?"or ":"")+r+" "+e}).join(", ");if(!t.some(function(t){return i(e)===t}))throw new r("object tested must be "+n+", but "+i(e)+" given")}},{"./flag":17,"assertion-error":4,"type-detect":40}],17:[function(e,t,n){t.exports=function(e,t,n){var r=e.__flags||(e.__flags=Object.create(null));if(3!==arguments.length)return r[t];r[t]=n}},{}],18:[function(e,t,n){t.exports=function(e,t){return t.length>4?t[4]:e._obj}},{}],19:[function(e,t,n){t.exports=function(e){var t=[];for(var n in e)t.push(n);return t}},{}],20:[function(e,t,n){var r=e("./flag"),o=e("./getActual"),i=(e("./inspect"),e("./objDisplay"));t.exports=function(e,t){var n=r(e,"negate"),a=r(e,"object"),s=t[3],c=o(e,t),u=n?t[2]:t[1],f=r(e,"message");return"function"==typeof u&&(u=u()),u=u||"",u=u.replace(/#\{this\}/g,function(){return i(a)}).replace(/#\{act\}/g,function(){return i(c)}).replace(/#\{exp\}/g,function(){return i(s)}),f?f+": "+u:u}},{"./flag":17,"./getActual":18,"./inspect":27,"./objDisplay":28}],21:[function(e,t,n){t.exports=function(e){if(e.name)return e.name;var t=/^\s?function ([^(]*)\(/.exec(e);return t&&t[1]?t[1]:""}},{}],22:[function(e,t,n){function r(e){return e.replace(/([^\\])\[/g,"$1.[").match(/(\\\.|[^.]+?)+/g).map(function(e){var t=/^\[(\d+)\]$/.exec(e);return t?{i:parseFloat(t[1])}:{p:e.replace(/\\([.\[\]])/g,"$1")}})}function o(e,t,n){for(var r,o=t,i=0,a=n=void 0===n?e.length:n;i1?o(n,t,n.length-1):t,name:a.p||a.i,value:o(n,t)};return s.exists=i(s.name,s.parent),s}},{"./hasProperty":25}],23:[function(e,t,n){var r=e("./getPathInfo");t.exports=function(e,t){return r(e,t).value}},{"./getPathInfo":22}],24:[function(e,t,n){t.exports=function(e){function t(e){-1===n.indexOf(e)&&n.push(e)}for(var n=Object.getOwnPropertyNames(e),r=Object.getPrototypeOf(e);null!==r;)Object.getOwnPropertyNames(r).forEach(t),r=Object.getPrototypeOf(r);return n}},{}],25:[function(e,t,n){var r=e("type-detect"),o={number:Number,string:String};t.exports=function(e,t){var n=r(t);return"null"!==n&&"undefined"!==n&&(o[n]&&"object"!=typeof t&&(t=new o[n](t)),e in t)}},{"type-detect":40}],26:[function(e,t,n){(n=t.exports={}).test=e("./test"),n.type=e("type-detect"),n.expectTypes=e("./expectTypes"),n.getMessage=e("./getMessage"),n.getActual=e("./getActual"),n.inspect=e("./inspect"),n.objDisplay=e("./objDisplay"),n.flag=e("./flag"),n.transferFlags=e("./transferFlags"),n.eql=e("deep-eql"),n.getPathValue=e("./getPathValue"),n.getPathInfo=e("./getPathInfo"),n.hasProperty=e("./hasProperty"),n.getName=e("./getName"),n.addProperty=e("./addProperty"),n.addMethod=e("./addMethod"),n.overwriteProperty=e("./overwriteProperty"),n.overwriteMethod=e("./overwriteMethod"),n.addChainableMethod=e("./addChainableMethod"),n.overwriteChainableMethod=e("./overwriteChainableMethod")},{"./addChainableMethod":13,"./addMethod":14,"./addProperty":15,"./expectTypes":16,"./flag":17,"./getActual":18,"./getMessage":20,"./getName":21,"./getPathInfo":22,"./getPathValue":23,"./hasProperty":25,"./inspect":27,"./objDisplay":28,"./overwriteChainableMethod":29,"./overwriteMethod":30,"./overwriteProperty":31,"./test":32,"./transferFlags":33,"deep-eql":35,"type-detect":40}],27:[function(e,t,n){function r(e,t,n,r){return o({showHidden:t,seen:[],stylize:function(e){return e}},e,void 0===n?2:n)}function o(e,t,r){if(t&&"function"==typeof t.inspect&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var p=t.inspect(r);return"string"!=typeof p&&(p=o(e,p,r)),p}var m=i(e,t);if(m)return m;if(b(t)){if("outerHTML"in t)return t.outerHTML;try{if(document.xmlVersion)return(new XMLSerializer).serializeToString(t);var w=document.createElementNS("http://www.w3.org/1999/xhtml","_");return w.appendChild(t.cloneNode(!1)),html=w.innerHTML.replace("><",">"+t.innerHTML+"<"),w.innerHTML="",html}catch(e){}}var x=g(t),j=e.showHidden?y(t):x;if(0===j.length||h(t)&&(1===j.length&&"stack"===j[0]||2===j.length&&"description"===j[0]&&"stack"===j[1])){if("function"==typeof t){var E=(A=v(t))?": "+A:"";return e.stylize("[Function"+E+"]","special")}if(l(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(d(t))return e.stylize(Date.prototype.toUTCString.call(t),"date");if(h(t))return a(t)}var S="",_=!1,O=["{","}"];if(f(t)&&(_=!0,O=["[","]"]),"function"==typeof t){var A=v(t);S=" [Function"+(E=A?": "+A:"")+"]"}if(l(t)&&(S=" "+RegExp.prototype.toString.call(t)),d(t)&&(S=" "+Date.prototype.toUTCString.call(t)),h(t))return a(t);if(0===j.length&&(!_||0==t.length))return O[0]+S+O[1];if(r<0)return l(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var N;return N=_?s(e,t,r,x,j):j.map(function(n){return c(e,t,r,x,n,_)}),e.seen.pop(),u(N,S,O)}function i(e,t){switch(typeof t){case"undefined":return e.stylize("undefined","undefined");case"string":var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string");case"number":return 0===t&&1/t==-1/0?e.stylize("-0","number"):e.stylize(""+t,"number");case"boolean":return e.stylize(""+t,"boolean")}if(null===t)return e.stylize("null","null")}function a(e){return"["+Error.prototype.toString.call(e)+"]"}function s(e,t,n,r,o){for(var i=[],a=0,s=t.length;a-1&&(c=a?c.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+c.split("\n").map(function(e){return" "+e}).join("\n")):c=e.stylize("[Circular]","special")),void 0===s){if(a&&i.match(/^\d+$/))return c;(s=JSON.stringify(""+i)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(s=s.substr(1,s.length-2),s=e.stylize(s,"name")):(s=s.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),s=e.stylize(s,"string"))}return s+": "+c}function u(e,t,n){var r=0;return e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.length+1},0)>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function f(e){return Array.isArray(e)||"object"==typeof e&&"[object Array]"===p(e)}function l(e){return"object"==typeof e&&"[object RegExp]"===p(e)}function d(e){return"object"==typeof e&&"[object Date]"===p(e)}function h(e){return"object"==typeof e&&"[object Error]"===p(e)}function p(e){return Object.prototype.toString.call(e)}var v=e("./getName"),y=e("./getProperties"),g=e("./getEnumerableProperties");t.exports=r;var b=function(e){return"object"==typeof HTMLElement?e instanceof HTMLElement:e&&"object"==typeof e&&1===e.nodeType&&"string"==typeof e.nodeName}},{"./getEnumerableProperties":19,"./getName":21,"./getProperties":24}],28:[function(e,t,n){var r=e("./inspect"),o=e("../config");t.exports=function(e){var t=r(e),n=Object.prototype.toString.call(e);if(o.truncateThreshold&&t.length>=o.truncateThreshold){if("[object Function]"===n)return e.name&&""!==e.name?"[Function: "+e.name+"]":"[Function]";if("[object Array]"===n)return"[ Array("+e.length+") ]";if("[object Object]"===n){var i=Object.keys(e);return"{ Object ("+(i.length>2?i.splice(0,2).join(", ")+", ...":i.join(", "))+") }"}return t}return t}},{"../config":8,"./inspect":27}],29:[function(e,t,n){t.exports=function(e,t,n,r){var o=e.__methods[t],i=o.chainingBehavior;o.chainingBehavior=function(){var e=r(i).call(this);return void 0===e?this:e};var a=o.method;o.method=function(){var e=n(a).apply(this,arguments);return void 0===e?this:e}}},{}],30:[function(e,t,n){t.exports=function(e,t,n){var r=e[t],o=function(){return this};r&&"function"==typeof r&&(o=r),e[t]=function(){var e=n(o).apply(this,arguments);return void 0===e?this:e}}},{}],31:[function(e,t,n){t.exports=function(e,t,n){var r=Object.getOwnPropertyDescriptor(e,t),o=function(){};r&&"function"==typeof r.get&&(o=r.get),Object.defineProperty(e,t,{get:function(){var e=n(o).call(this);return void 0===e?this:e},configurable:!0})}},{}],32:[function(e,t,n){var r=e("./flag");t.exports=function(e,t){var n=r(e,"negate"),o=t[0];return n?!o:o}},{"./flag":17}],33:[function(e,t,n){t.exports=function(e,t,n){var r=e.__flags||(e.__flags=Object.create(null));t.__flags||(t.__flags=Object.create(null)),n=3!==arguments.length||n;for(var o in r)(n||"object"!==o&&"ssfi"!==o&&"message"!=o)&&(t.__flags[o]=r[o])}},{}],34:[function(e,t,n){"use strict";function r(e){var t=void 0;t="string"==typeof e?[e]:e.raw;for(var n="",r=0;r=0;o--)if(s=i[o],!r(e[s],t[s],n))return!1;return!0}var p,v=e("type-detect");try{p=e("buffer").Buffer}catch(e){(p={}).isBuffer=function(){return!1}}t.exports=r},{buffer:void 0,"type-detect":38}],37:[function(e,t,n){(function(r){!function(e){if("object"==typeof n&&void 0!==t)t.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:void 0!==r?r:"undefined"!=typeof self?self:this).localforage=e()}}(function(){return function t(n,r,o){function i(s,c){if(!r[s]){if(!n[s]){var u="function"==typeof e&&e;if(!c&&u)return u(s,!0);if(a)return a(s,!0);var f=new Error("Cannot find module '"+s+"'");throw f.code="MODULE_NOT_FOUND",f}var l=r[s]={exports:{}};n[s][0].call(l.exports,function(e){var t=n[s][1][e];return i(t||e)},l,l.exports,t,n,r,o)}return r[s].exports}for(var a="function"==typeof e&&e,s=0;s=43)}}).catch(function(){return!1})}function u(e){return"boolean"==typeof re?ie.resolve(re):c(e).then(function(e){return re=e})}function f(e){var t=oe[e.name],n={};n.promise=new ie(function(e){n.resolve=e}),t.deferredOperations.push(n),t.dbReady?t.dbReady=t.dbReady.then(function(){return n.promise}):t.dbReady=n.promise}function l(e){var t=oe[e.name].deferredOperations.pop();t&&t.resolve()}function d(e,t){return new ie(function(n,r){if(e.db){if(!t)return n(e.db);f(e),e.db.close()}var o=[e.name];t&&o.push(e.version);var i=ne.open.apply(ne,o);t&&(i.onupgradeneeded=function(t){var n=i.result;try{n.createObjectStore(e.storeName),t.oldVersion<=1&&n.createObjectStore(ae)}catch(n){if("ConstraintError"!==n.name)throw n;console.warn('The database "'+e.name+'" has been upgraded from version '+t.oldVersion+" to version "+t.newVersion+', but the storage "'+e.storeName+'" already exists.')}}),i.onerror=function(e){e.preventDefault(),r(i.error)},i.onsuccess=function(){n(i.result),l(e)}})}function h(e){return d(e,!1)}function p(e){return d(e,!0)}function v(e,t){if(!e.db)return!0;var n=!e.db.objectStoreNames.contains(e.storeName),r=e.versione.db.version;if(r&&(e.version!==t&&console.warn('The database "'+e.name+"\" can't be downgraded from version "+e.db.version+" to version "+e.version+"."),e.version=e.db.version),o||n){if(n){var i=e.db.version+1;i>e.version&&(e.version=i)}return!0}return!1}function y(e){return new ie(function(t,n){var r=new FileReader;r.onerror=n,r.onloadend=function(n){var r=btoa(n.target.result||"");t({__local_forage_encoded_blob:!0,data:r,type:e.type})},r.readAsBinaryString(e)})}function g(e){return o([s(atob(e.data))],{type:e.type})}function b(e){return e&&e.__local_forage_encoded_blob}function m(e){var t=this,n=t._initReady().then(function(){var e=oe[t._dbInfo.name];if(e&&e.dbReady)return e.dbReady});return a(n,e,e),n}function w(e){function t(){return ie.resolve()}var n=this,r={db:null};if(e)for(var o in e)r[o]=e[o];oe||(oe={});var i=oe[r.name];i||(i={forages:[],db:null,dbReady:null,deferredOperations:[]},oe[r.name]=i),i.forages.push(n),n._initReady||(n._initReady=n.ready,n.ready=m);for(var a=[],s=0;s>4,f[c++]=(15&r)<<4|o>>2,f[c++]=(3&o)<<6|63&i;return u}function M(e){var t,n=new Uint8Array(e),r="";for(t=0;t>2],r+=ue[(3&n[t])<<4|n[t+1]>>4],r+=ue[(15&n[t+1])<<2|n[t+2]>>6],r+=ue[63&n[t+2]];return n.length%3==2?r=r.substring(0,r.length-1)+"=":n.length%3==1&&(r=r.substring(0,r.length-2)+"=="),r}function I(e,t){var n="";if(e&&(n=Oe.call(e)),e&&("[object ArrayBuffer]"===n||e.buffer&&"[object ArrayBuffer]"===Oe.call(e.buffer))){var r,o=de;e instanceof ArrayBuffer?(r=e,o+=pe):(r=e.buffer,"[object Int8Array]"===n?o+=ye:"[object Uint8Array]"===n?o+=ge:"[object Uint8ClampedArray]"===n?o+=be:"[object Int16Array]"===n?o+=me:"[object Uint16Array]"===n?o+=xe:"[object Int32Array]"===n?o+=we:"[object Uint32Array]"===n?o+=je:"[object Float32Array]"===n?o+=Ee:"[object Float64Array]"===n?o+=Se:t(new Error("Failed to get type for BinaryArray"))),t(o+M(r))}else if("[object Blob]"===n){var i=new FileReader;i.onload=function(){var n=fe+e.type+"~"+M(this.result);t(de+ve+n)},i.readAsArrayBuffer(e)}else try{t(JSON.stringify(e))}catch(n){console.error("Couldn't convert value into a JSON string: ",e),t(null,n)}}function k(e){if(e.substring(0,he)!==de)return JSON.parse(e);var t,n=e.substring(_e),r=e.substring(he,_e);if(r===ve&&le.test(n)){var i=n.match(le);t=i[1],n=n.substring(i[0].length)}var a=P(n);switch(r){case pe:return a;case ve:return o([a],{type:t});case ye:return new Int8Array(a);case ge:return new Uint8Array(a);case be:return new Uint8ClampedArray(a);case me:return new Int16Array(a);case xe:return new Uint16Array(a);case we:return new Int32Array(a);case je:return new Uint32Array(a);case Ee:return new Float32Array(a);case Se:return new Float64Array(a);default:throw new Error("Unkown type: "+r)}}function T(e){var t=this,n={db:null};if(e)for(var r in e)n[r]="string"!=typeof e[r]?e[r].toString():e[r];var o=new ie(function(e,r){try{n.db=openDatabase(n.name,String(n.version),n.description,n.size)}catch(e){return r(e)}n.db.transaction(function(o){o.executeSql("CREATE TABLE IF NOT EXISTS "+n.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){t._dbInfo=n,e()},function(e,t){r(t)})})});return n.serializer=Ae,o}function C(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT * FROM "+o.storeName+" WHERE key = ? LIMIT 1",[e],function(e,n){var r=n.rows.length?n.rows.item(0).value:null;r&&(r=o.serializer.deserialize(r)),t(r)},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function D(e,t){var n=this,r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT * FROM "+o.storeName,[],function(n,r){for(var i=r.rows,a=i.length,s=0;s0)return void i(L.apply(o,[e,s,n,r-1]));a(t)}})})}).catch(a)});return i(a,n),a}function R(e,t,n){return L.apply(this,[e,t,n,1])}function B(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("DELETE FROM "+o.storeName+" WHERE key = ?",[e],function(){t()},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function q(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("DELETE FROM "+r.storeName,[],function(){e()},function(e,t){n(t)})})}).catch(n)});return i(n,e),n}function z(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("SELECT COUNT(key) as c FROM "+r.storeName,[],function(t,n){var r=n.rows.item(0).c;e(r)},function(e,t){n(t)})})}).catch(n)});return i(n,e),n}function F(e,t){var n=this,r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT key FROM "+o.storeName+" WHERE id = ? LIMIT 1",[e+1],function(e,n){var r=n.rows.length?n.rows.item(0).key:null;t(r)},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function U(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("SELECT key FROM "+r.storeName,[],function(t,n){for(var r=[],o=0;o=0;n--){var r=localStorage.key(n);0===r.indexOf(e)&&localStorage.removeItem(r)}});return i(n,e),n}function J(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=n.ready().then(function(){var t=n._dbInfo,r=localStorage.getItem(t.keyPrefix+e);return r&&(r=t.serializer.deserialize(r)),r});return i(r,t),r}function G(e,t){var n=this,r=n.ready().then(function(){for(var t=n._dbInfo,r=t.keyPrefix,o=r.length,i=localStorage.length,a=1,s=0;s=e.length-1||t<0?0:t+1}function getCurrentProblem(e){return e[config.currentIndex]}function previousProblem(){console.log("previousProblem!"),previousProblemButtonEl.classList.add("active"),config.currentIndex=config.shuffle?getRandomIndex(problems):getPreviousIndex(problems),updateLocalstore(config).then(function(){window.location.reload()})}function nextProblem(){console.log("nextProblem!"),nextProblemButtonEl.classList.add("active"),config.currentIndex=config.shuffle?getRandomIndex(problems):getNextIndex(problems),updateLocalstore(config).then(function(){window.location.reload()})}function toggleShuffle(){console.log("toggle shuffle!"),config.shuffle=!config.shuffle,shuffleProblemsButtonEl.classList.toggle("active"),previousProblemButtonEl.parentNode.classList.toggle("hidden"),updateLocalstore(config)}function loadProblem(e){currentProblem=e,problemEl.innerText=e.prompt,e.given&&(codeEl.value=e.given),testSuite(null,!0)}function updateTests(e,t){!0===t&&buildTests(currentProblem.tests),updateTestStatus(e)}function buildTests(e){if(e){var t=e.map(function(e){return'
\n
[✘]
\n
'+e.name+"
\n
"}).join("");testSuiteEl.innerHTML=t}}function updateTestStatus(e){if(!e)throw new Error("No testStatuses provided.");var t=!0;e.forEach(function(e){!0!==e&&(t=!1)}),[].slice.call(testSuiteEl.querySelectorAll(".test-state")).forEach(function(t,n){!0===e[n]?(t.innerHTML="[✓]",t.classList.remove("fail"),t.classList.add("pass")):(t.innerHTML="[✘]",t.classList.remove("pass"),t.classList.add("fail"))}),!0===t?(testTotalEl.innerText="PASS",testTotalEl.classList.remove("fail"),testTotalEl.classList.add("pass")):(testTotalEl.innerText="FAIL",testTotalEl.classList.remove("pass"),testTotalEl.classList.add("fail"))}function printAssertError(e){var t="";null!==e&&(t='\n
\n Expected: '+JSON.stringify(e.expected)+"\n Actual: "+JSON.stringify(e.actual)+"\n
"),assertConsoleEl.innerHTML=t}function printEvalOutput(e,t){var n="";e&&void 0!==e.message?n='\n
\n Syntax Error: '+JSON.stringify(e.message)+"\n
":t&&(n='\n
\n Output: '+JSON.stringify(t)+"\n
"),evalConsoleEl.innerHTML=n}function testSuite(e){testTotalEl.classList.toggle("working");var t=runTests(getOutput(codeEl.value));testTotalEl.classList.toggle("working"),updateTests(t,e)}function getOutput(code){var evald=!1;try{evald=eval("(function(){"+code+"})()"),printEvalOutput(null,evald)}catch(e){printEvalOutput(e)}return evald}function runTests(output){var tested=!1;return tested=currentProblem.tests.map(function(test){var testOutcome=!1;try{output&&(testOutcome=eval(test.test),console.log("testOutcome:",testOutcome)),printAssertError(null)}catch(e){printAssertError(e)}return testOutcome})}function loadApp(e){function t(t){!1===e.shuffle&&13===t.keyCode&&t.shiftKey&&(t.metaKey||t.ctrlKey)?previousProblem():13!==t.keyCode||t.shiftKey||!t.metaKey&&!t.ctrlKey||nextProblem()}console.log("loading app!"),!0===e.shuffle&&(shuffleProblemsButtonEl.classList.add("active"),previousProblemButtonEl.parentNode.classList.add("hidden"));var n=debounce(function(e){-1===ignoreKeyCodes.indexOf(e.keyCode)&&testSuite()},200);codeEl.addEventListener("keydown",n),document.addEventListener("keydown",t),shuffleProblemsButtonEl.addEventListener("click",toggleShuffle),previousProblemButtonEl.addEventListener("click",previousProblem),nextProblemButtonEl.addEventListener("click",nextProblem),loadProblem(getCurrentProblem(problems)),testSuite(!0)}var localforage=require("localforage"),probs=require("pjs-problems"),dedent=require("dedent"),assert=require("chai").assert,problems=[];Object.keys(probs).forEach(function(e){var t;(t=problems).push.apply(t,_toConsumableArray(probs[e]))}),problems=dedentStrings(problems);var currentProblem=void 0,ignoreKeyCodes=[9,37,39,38,40],config={shuffle:!0,timer:!1,currentIndex:0};localforage.getItem("js_practice_config").then(function(e){e&&(config=e),loadApp(config)}).catch(function(e){console.log("localforage err:",e),loadApp(config)});var problemEl=document.getElementById("problem"),codeEl=document.getElementById("code"),testSuiteEl=document.getElementById("test-suite"),testTotalEl=document.getElementById("test-total"),evalConsoleEl=document.getElementById("eval-output"),assertConsoleEl=document.getElementById("assert-output"),shuffleProblemsButtonEl=document.getElementById("shuffle-problems"),previousProblemButtonEl=document.getElementById("prev-problem"),nextProblemButtonEl=document.getElementById("next-problem")}(document,window)},{chai:5,dedent:34,localforage:37,"pjs-problems":1}]},{},[42]); +!function e(t,n,r){function o(a,s){if(!n[a]){if(!t[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(i)return i(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var f=n[a]={exports:{}};t[a][0].call(f.exports,function(e){var n=t[a][1][e];return o(n||e)},f,f.exports,e,t,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;ae,"expected #{this} to have a length above #{exp} but got #{act}","expected #{this} to not have a length above #{exp}",e,r)}else this.assert(n>e,"expected #{this} to be above "+e,"expected #{this} to be at most "+e)}function u(e,t){t&&P(this,"message",t);var n=P(this,"object");if(P(this,"doLength")){new N(n,t).to.have.property("length");var r=n.length;this.assert(r>=e,"expected #{this} to have a length at least #{exp} but got #{act}","expected #{this} to have a length below #{exp}",e,r)}else this.assert(n>=e,"expected #{this} to be at least "+e,"expected #{this} to be below "+e)}function f(e,t){t&&P(this,"message",t);var n=P(this,"object");if(P(this,"doLength")){new N(n,t).to.have.property("length");var r=n.length;this.assert(r1)throw new Error(i);break;case"object":if(arguments.length>1)throw new Error(i);e=Object.keys(e);break;default:e=Array.prototype.slice.call(arguments)}if(!e.length)throw new Error("keys required");var a=Object.keys(r),s=e,c=e.length,u=P(this,"any"),f=P(this,"all");if(u||f||(f=!0),u&&(o=s.filter(function(e){return~a.indexOf(e)}).length>0),f&&(o=e.every(function(e){return~a.indexOf(e)}),P(this,"negate")||P(this,"contains")||(o=o&&e.length==a.length)),c>1){var l=(e=e.map(function(e){return t.inspect(e)})).pop();f&&(n=e.join(", ")+", and "+l),u&&(n=e.join(", ")+", or "+l)}else n=t.inspect(e[0]);n=(c>1?"keys ":"key ")+n,n=(P(this,"contains")?"contain ":"have ")+n,this.assert(o,"expected #{this} to "+n,"expected #{this} to not "+n,s.slice(0).sort(),a.sort(),!0)}function m(e,n,r){r&&P(this,"message",r);var o=P(this,"object");new N(o,r).is.a("function");var i=!1,a=null,s=null,c=null;0===arguments.length?(n=null,e=null):e&&(e instanceof RegExp||"string"==typeof e)?(n=e,e=null):e&&e instanceof Error?(a=e,e=null,n=null):"function"==typeof e?(!(s=e.prototype.name)||"Error"===s&&e!==Error)&&(s=e.name||(new e).name):e=null;try{o()}catch(r){if(a)return this.assert(r===a,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp}",a instanceof Error?a.toString():a,r instanceof Error?r.toString():r),P(this,"object",r),this;if(e&&(this.assert(r instanceof e,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp} but #{act} was thrown",s,r instanceof Error?r.toString():r),!n))return P(this,"object",r),this;var u="error"===t.type(r)&&"message"in r?r.message:""+r;if(null!=u&&n&&n instanceof RegExp)return this.assert(n.exec(u),"expected #{this} to throw error matching #{exp} but got #{act}","expected #{this} to throw error not matching #{exp}",n,u),P(this,"object",r),this;if(null!=u&&n&&"string"==typeof n)return this.assert(~u.indexOf(n),"expected #{this} to throw error including #{exp} but got #{act}","expected #{this} to throw error not including #{act}",n,u),P(this,"object",r),this;i=!0,c=r}var f="",l=null!==s?s:a?"#{exp}":"an error";i&&(f=" but #{act} was thrown"),this.assert(!0===i,"expected #{this} to throw "+l+f,"expected #{this} to not throw "+l+f,a instanceof Error?a.toString():a,c instanceof Error?c.toString():c),P(this,"object",c)}function w(e,n){n&&P(this,"message",n);var r=P(this,"object"),o=P(this,"itself"),i="function"!==t.type(r)||o?r[e]:r.prototype[e];this.assert("function"==typeof i,"expected #{this} to respond to "+t.inspect(e),"expected #{this} to not respond to "+t.inspect(e))}function x(e,n){n&&P(this,"message",n);var r=e(P(this,"object"));this.assert(r,"expected #{this} to satisfy "+t.objDisplay(e),"expected #{this} to not satisfy"+t.objDisplay(e),!this.negate,r)}function j(e,n,r){r&&P(this,"message",r);var o=P(this,"object");if(new N(o,r).is.a("number"),"number"!==t.type(e)||"number"!==t.type(n))throw new Error("the arguments to closeTo or approximately must be numbers");this.assert(Math.abs(o-e)<=n,"expected #{this} to be close to "+e+" +/- "+n,"expected #{this} not to be close to "+e+" +/- "+n)}function E(e,t,n){return e.every(function(e){return n?t.some(function(t){return n(e,t)}):-1!==t.indexOf(e)})}function S(e,t){t&&P(this,"message",t);var n=P(this,"object");new N(e).to.be.an("array"),this.assert(e.indexOf(n)>-1,"expected #{this} to be one of #{exp}","expected #{this} to not be one of #{exp}",e,n)}function _(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(o!==e[t],"expected ."+t+" to change","expected ."+t+" to not change")}function O(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(e[t]-o>0,"expected ."+t+" to increase","expected ."+t+" to not increase")}function A(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(e[t]-o<0,"expected ."+t+" to decrease","expected ."+t+" to not decrease")}var N=e.Assertion,P=(Object.prototype.toString,t.flag);["to","be","been","is","and","has","have","with","that","which","at","of","same"].forEach(function(e){N.addProperty(e,function(){return this})}),N.addProperty("not",function(){P(this,"negate",!0)}),N.addProperty("deep",function(){P(this,"deep",!0)}),N.addProperty("any",function(){P(this,"any",!0),P(this,"all",!1)}),N.addProperty("all",function(){P(this,"all",!0),P(this,"any",!1)}),N.addChainableMethod("an",n),N.addChainableMethod("a",n),N.addChainableMethod("include",o,r),N.addChainableMethod("contain",o,r),N.addChainableMethod("contains",o,r),N.addChainableMethod("includes",o,r),N.addProperty("ok",function(){this.assert(P(this,"object"),"expected #{this} to be truthy","expected #{this} to be falsy")}),N.addProperty("true",function(){this.assert(!0===P(this,"object"),"expected #{this} to be true","expected #{this} to be false",!this.negate)}),N.addProperty("false",function(){this.assert(!1===P(this,"object"),"expected #{this} to be false","expected #{this} to be true",!!this.negate)}),N.addProperty("null",function(){this.assert(null===P(this,"object"),"expected #{this} to be null","expected #{this} not to be null")}),N.addProperty("undefined",function(){this.assert(void 0===P(this,"object"),"expected #{this} to be undefined","expected #{this} not to be undefined")}),N.addProperty("NaN",function(){this.assert(isNaN(P(this,"object")),"expected #{this} to be NaN","expected #{this} not to be NaN")}),N.addProperty("exist",function(){this.assert(null!=P(this,"object"),"expected #{this} to exist","expected #{this} to not exist")}),N.addProperty("empty",function(){var e=P(this,"object"),t=e;Array.isArray(e)||"string"==typeof object?t=e.length:"object"==typeof e&&(t=Object.keys(e).length),this.assert(!t,"expected #{this} to be empty","expected #{this} not to be empty")}),N.addProperty("arguments",i),N.addProperty("Arguments",i),N.addMethod("equal",a),N.addMethod("equals",a),N.addMethod("eq",a),N.addMethod("eql",s),N.addMethod("eqls",s),N.addMethod("above",c),N.addMethod("gt",c),N.addMethod("greaterThan",c),N.addMethod("least",u),N.addMethod("gte",u),N.addMethod("below",f),N.addMethod("lt",f),N.addMethod("lessThan",f),N.addMethod("most",l),N.addMethod("lte",l),N.addMethod("within",function(e,t,n){n&&P(this,"message",n);var r=P(this,"object"),o=e+".."+t;if(P(this,"doLength")){new N(r,n).to.have.property("length");var i=r.length;this.assert(i>=e&&i<=t,"expected #{this} to have a length within "+o,"expected #{this} to not have a length within "+o)}else this.assert(r>=e&&r<=t,"expected #{this} to be within "+o,"expected #{this} to not be within "+o)}),N.addMethod("instanceof",d),N.addMethod("instanceOf",d),N.addMethod("property",function(e,n,r){r&&P(this,"message",r);var o=!!P(this,"deep"),i=o?"deep property ":"property ",a=P(this,"negate"),s=P(this,"object"),c=o?t.getPathInfo(e,s):null,u=o?c.exists:t.hasProperty(e,s),f=o?c.value:s[e];if(a&&arguments.length>1){if(void 0===f)throw r=null!=r?r+": ":"",new Error(r+t.inspect(s)+" has no "+i+t.inspect(e))}else this.assert(u,"expected #{this} to have a "+i+t.inspect(e),"expected #{this} to not have "+i+t.inspect(e));arguments.length>1&&this.assert(n===f,"expected #{this} to have a "+i+t.inspect(e)+" of #{exp}, but got #{act}","expected #{this} to not have a "+i+t.inspect(e)+" of #{act}",n,f),P(this,"object",f)}),N.addMethod("ownProperty",h),N.addMethod("haveOwnProperty",h),N.addMethod("ownPropertyDescriptor",p),N.addMethod("haveOwnPropertyDescriptor",p),N.addChainableMethod("length",y,v),N.addMethod("lengthOf",y),N.addMethod("match",g),N.addMethod("matches",g),N.addMethod("string",function(e,n){n&&P(this,"message",n);var r=P(this,"object");new N(r,n).is.a("string"),this.assert(~r.indexOf(e),"expected #{this} to contain "+t.inspect(e),"expected #{this} to not contain "+t.inspect(e))}),N.addMethod("keys",b),N.addMethod("key",b),N.addMethod("throw",m),N.addMethod("throws",m),N.addMethod("Throw",m),N.addMethod("respondTo",w),N.addMethod("respondsTo",w),N.addProperty("itself",function(){P(this,"itself",!0)}),N.addMethod("satisfy",x),N.addMethod("satisfies",x),N.addMethod("closeTo",j),N.addMethod("approximately",j),N.addMethod("members",function(e,n){n&&P(this,"message",n);var r=P(this,"object");new N(r).to.be.an("array"),new N(e).to.be.an("array");var o=P(this,"deep")?t.eql:void 0;if(P(this,"contains"))return this.assert(E(e,r,o),"expected #{this} to be a superset of #{act}","expected #{this} to not be a superset of #{act}",r,e);this.assert(E(r,e,o)&&E(e,r,o),"expected #{this} to have the same members as #{act}","expected #{this} to not have the same members as #{act}",r,e)}),N.addMethod("oneOf",S),N.addChainableMethod("change",_),N.addChainableMethod("changes",_),N.addChainableMethod("increase",O),N.addChainableMethod("increases",O),N.addChainableMethod("decrease",A),N.addChainableMethod("decreases",A),N.addProperty("extensible",function(){var e,t=P(this,"object");try{e=Object.isExtensible(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!1}this.assert(e,"expected #{this} to be extensible","expected #{this} to not be extensible")}),N.addProperty("sealed",function(){var e,t=P(this,"object");try{e=Object.isSealed(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!0}this.assert(e,"expected #{this} to be sealed","expected #{this} to not be sealed")}),N.addProperty("frozen",function(){var e,t=P(this,"object");try{e=Object.isFrozen(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!0}this.assert(e,"expected #{this} to be frozen","expected #{this} to not be frozen")})}},{}],7:[function(e,t,n){t.exports=function(e,t){var n=e.Assertion,r=t.flag,o=e.assert=function(t,r){new n(null,null,e.assert).assert(t,r,"[ negation message unavailable ]")};o.fail=function(t,n,r,i){throw r=r||"assert.fail()",new e.AssertionError(r,{actual:t,expected:n,operator:i},o.fail)},o.isOk=function(e,t){new n(e,t).is.ok},o.isNotOk=function(e,t){new n(e,t).is.not.ok},o.equal=function(e,t,i){var a=new n(e,i,o.equal);a.assert(t==r(a,"object"),"expected #{this} to equal #{exp}","expected #{this} to not equal #{act}",t,e)},o.notEqual=function(e,t,i){var a=new n(e,i,o.notEqual);a.assert(t!=r(a,"object"),"expected #{this} to not equal #{exp}","expected #{this} to equal #{act}",t,e)},o.strictEqual=function(e,t,r){new n(e,r).to.equal(t)},o.notStrictEqual=function(e,t,r){new n(e,r).to.not.equal(t)},o.deepEqual=function(e,t,r){new n(e,r).to.eql(t)},o.notDeepEqual=function(e,t,r){new n(e,r).to.not.eql(t)},o.isAbove=function(e,t,r){new n(e,r).to.be.above(t)},o.isAtLeast=function(e,t,r){new n(e,r).to.be.least(t)},o.isBelow=function(e,t,r){new n(e,r).to.be.below(t)},o.isAtMost=function(e,t,r){new n(e,r).to.be.most(t)},o.isTrue=function(e,t){new n(e,t).is.true},o.isNotTrue=function(e,t){new n(e,t).to.not.equal(!0)},o.isFalse=function(e,t){new n(e,t).is.false},o.isNotFalse=function(e,t){new n(e,t).to.not.equal(!1)},o.isNull=function(e,t){new n(e,t).to.equal(null)},o.isNotNull=function(e,t){new n(e,t).to.not.equal(null)},o.isNaN=function(e,t){new n(e,t).to.be.NaN},o.isNotNaN=function(e,t){new n(e,t).not.to.be.NaN},o.isUndefined=function(e,t){new n(e,t).to.equal(void 0)},o.isDefined=function(e,t){new n(e,t).to.not.equal(void 0)},o.isFunction=function(e,t){new n(e,t).to.be.a("function")},o.isNotFunction=function(e,t){new n(e,t).to.not.be.a("function")},o.isObject=function(e,t){new n(e,t).to.be.a("object")},o.isNotObject=function(e,t){new n(e,t).to.not.be.a("object")},o.isArray=function(e,t){new n(e,t).to.be.an("array")},o.isNotArray=function(e,t){new n(e,t).to.not.be.an("array")},o.isString=function(e,t){new n(e,t).to.be.a("string")},o.isNotString=function(e,t){new n(e,t).to.not.be.a("string")},o.isNumber=function(e,t){new n(e,t).to.be.a("number")},o.isNotNumber=function(e,t){new n(e,t).to.not.be.a("number")},o.isBoolean=function(e,t){new n(e,t).to.be.a("boolean")},o.isNotBoolean=function(e,t){new n(e,t).to.not.be.a("boolean")},o.typeOf=function(e,t,r){new n(e,r).to.be.a(t)},o.notTypeOf=function(e,t,r){new n(e,r).to.not.be.a(t)},o.instanceOf=function(e,t,r){new n(e,r).to.be.instanceOf(t)},o.notInstanceOf=function(e,t,r){new n(e,r).to.not.be.instanceOf(t)},o.include=function(e,t,r){new n(e,r,o.include).include(t)},o.notInclude=function(e,t,r){new n(e,r,o.notInclude).not.include(t)},o.match=function(e,t,r){new n(e,r).to.match(t)},o.notMatch=function(e,t,r){new n(e,r).to.not.match(t)},o.property=function(e,t,r){new n(e,r).to.have.property(t)},o.notProperty=function(e,t,r){new n(e,r).to.not.have.property(t)},o.deepProperty=function(e,t,r){new n(e,r).to.have.deep.property(t)},o.notDeepProperty=function(e,t,r){new n(e,r).to.not.have.deep.property(t)},o.propertyVal=function(e,t,r,o){new n(e,o).to.have.property(t,r)},o.propertyNotVal=function(e,t,r,o){new n(e,o).to.not.have.property(t,r)},o.deepPropertyVal=function(e,t,r,o){new n(e,o).to.have.deep.property(t,r)},o.deepPropertyNotVal=function(e,t,r,o){new n(e,o).to.not.have.deep.property(t,r)},o.lengthOf=function(e,t,r){new n(e,r).to.have.length(t)},o.throws=function(e,t,o,i){("string"==typeof t||t instanceof RegExp)&&(o=t,t=null);var a=new n(e,i).to.throw(t,o);return r(a,"object")},o.doesNotThrow=function(e,t,r){"string"==typeof t&&(r=t,t=null),new n(e,r).to.not.Throw(t)},o.operator=function(e,o,i,a){var s;switch(o){case"==":s=e==i;break;case"===":s=e===i;break;case">":s=e>i;break;case">=":s=e>=i;break;case"<":s=e1&&n===t.length-1?"or ":"")+r+" "+e}).join(", ");if(!t.some(function(t){return i(e)===t}))throw new r("object tested must be "+n+", but "+i(e)+" given")}},{"./flag":14,"assertion-error":1,"type-detect":40}],14:[function(e,t,n){t.exports=function(e,t,n){var r=e.__flags||(e.__flags=Object.create(null));if(3!==arguments.length)return r[t];r[t]=n}},{}],15:[function(e,t,n){t.exports=function(e,t){return t.length>4?t[4]:e._obj}},{}],16:[function(e,t,n){t.exports=function(e){var t=[];for(var n in e)t.push(n);return t}},{}],17:[function(e,t,n){var r=e("./flag"),o=e("./getActual"),i=(e("./inspect"),e("./objDisplay"));t.exports=function(e,t){var n=r(e,"negate"),a=r(e,"object"),s=t[3],c=o(e,t),u=n?t[2]:t[1],f=r(e,"message");return"function"==typeof u&&(u=u()),u=u||"",u=u.replace(/#\{this\}/g,function(){return i(a)}).replace(/#\{act\}/g,function(){return i(c)}).replace(/#\{exp\}/g,function(){return i(s)}),f?f+": "+u:u}},{"./flag":14,"./getActual":15,"./inspect":24,"./objDisplay":25}],18:[function(e,t,n){t.exports=function(e){if(e.name)return e.name;var t=/^\s?function ([^(]*)\(/.exec(e);return t&&t[1]?t[1]:""}},{}],19:[function(e,t,n){function r(e){return e.replace(/([^\\])\[/g,"$1.[").match(/(\\\.|[^.]+?)+/g).map(function(e){var t=/^\[(\d+)\]$/.exec(e);return t?{i:parseFloat(t[1])}:{p:e.replace(/\\([.\[\]])/g,"$1")}})}function o(e,t,n){for(var r,o=t,i=0,a=n=void 0===n?e.length:n;i1?o(n,t,n.length-1):t,name:a.p||a.i,value:o(n,t)};return s.exists=i(s.name,s.parent),s}},{"./hasProperty":22}],20:[function(e,t,n){var r=e("./getPathInfo");t.exports=function(e,t){return r(e,t).value}},{"./getPathInfo":19}],21:[function(e,t,n){t.exports=function(e){function t(e){-1===n.indexOf(e)&&n.push(e)}for(var n=Object.getOwnPropertyNames(e),r=Object.getPrototypeOf(e);null!==r;)Object.getOwnPropertyNames(r).forEach(t),r=Object.getPrototypeOf(r);return n}},{}],22:[function(e,t,n){var r=e("type-detect"),o={number:Number,string:String};t.exports=function(e,t){var n=r(t);return"null"!==n&&"undefined"!==n&&(o[n]&&"object"!=typeof t&&(t=new o[n](t)),e in t)}},{"type-detect":40}],23:[function(e,t,n){(n=t.exports={}).test=e("./test"),n.type=e("type-detect"),n.expectTypes=e("./expectTypes"),n.getMessage=e("./getMessage"),n.getActual=e("./getActual"),n.inspect=e("./inspect"),n.objDisplay=e("./objDisplay"),n.flag=e("./flag"),n.transferFlags=e("./transferFlags"),n.eql=e("deep-eql"),n.getPathValue=e("./getPathValue"),n.getPathInfo=e("./getPathInfo"),n.hasProperty=e("./hasProperty"),n.getName=e("./getName"),n.addProperty=e("./addProperty"),n.addMethod=e("./addMethod"),n.overwriteProperty=e("./overwriteProperty"),n.overwriteMethod=e("./overwriteMethod"),n.addChainableMethod=e("./addChainableMethod"),n.overwriteChainableMethod=e("./overwriteChainableMethod")},{"./addChainableMethod":10,"./addMethod":11,"./addProperty":12,"./expectTypes":13,"./flag":14,"./getActual":15,"./getMessage":17,"./getName":18,"./getPathInfo":19,"./getPathValue":20,"./hasProperty":22,"./inspect":24,"./objDisplay":25,"./overwriteChainableMethod":26,"./overwriteMethod":27,"./overwriteProperty":28,"./test":29,"./transferFlags":30,"deep-eql":32,"type-detect":40}],24:[function(e,t,n){function r(e,t,n,r){return o({showHidden:t,seen:[],stylize:function(e){return e}},e,void 0===n?2:n)}function o(e,t,r){if(t&&"function"==typeof t.inspect&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var p=t.inspect(r);return"string"!=typeof p&&(p=o(e,p,r)),p}var m=i(e,t);if(m)return m;if(b(t)){if("outerHTML"in t)return t.outerHTML;try{if(document.xmlVersion)return(new XMLSerializer).serializeToString(t);var w=document.createElementNS("http://www.w3.org/1999/xhtml","_");return w.appendChild(t.cloneNode(!1)),html=w.innerHTML.replace("><",">"+t.innerHTML+"<"),w.innerHTML="",html}catch(e){}}var x=g(t),j=e.showHidden?y(t):x;if(0===j.length||h(t)&&(1===j.length&&"stack"===j[0]||2===j.length&&"description"===j[0]&&"stack"===j[1])){if("function"==typeof t){var E=(A=v(t))?": "+A:"";return e.stylize("[Function"+E+"]","special")}if(l(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(d(t))return e.stylize(Date.prototype.toUTCString.call(t),"date");if(h(t))return a(t)}var S="",_=!1,O=["{","}"];if(f(t)&&(_=!0,O=["[","]"]),"function"==typeof t){var A=v(t);S=" [Function"+(E=A?": "+A:"")+"]"}if(l(t)&&(S=" "+RegExp.prototype.toString.call(t)),d(t)&&(S=" "+Date.prototype.toUTCString.call(t)),h(t))return a(t);if(0===j.length&&(!_||0==t.length))return O[0]+S+O[1];if(r<0)return l(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var N;return N=_?s(e,t,r,x,j):j.map(function(n){return c(e,t,r,x,n,_)}),e.seen.pop(),u(N,S,O)}function i(e,t){switch(typeof t){case"undefined":return e.stylize("undefined","undefined");case"string":var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string");case"number":return 0===t&&1/t==-1/0?e.stylize("-0","number"):e.stylize(""+t,"number");case"boolean":return e.stylize(""+t,"boolean")}if(null===t)return e.stylize("null","null")}function a(e){return"["+Error.prototype.toString.call(e)+"]"}function s(e,t,n,r,o){for(var i=[],a=0,s=t.length;a-1&&(c=a?c.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+c.split("\n").map(function(e){return" "+e}).join("\n")):c=e.stylize("[Circular]","special")),void 0===s){if(a&&i.match(/^\d+$/))return c;(s=JSON.stringify(""+i)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(s=s.substr(1,s.length-2),s=e.stylize(s,"name")):(s=s.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),s=e.stylize(s,"string"))}return s+": "+c}function u(e,t,n){var r=0;return e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.length+1},0)>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function f(e){return Array.isArray(e)||"object"==typeof e&&"[object Array]"===p(e)}function l(e){return"object"==typeof e&&"[object RegExp]"===p(e)}function d(e){return"object"==typeof e&&"[object Date]"===p(e)}function h(e){return"object"==typeof e&&"[object Error]"===p(e)}function p(e){return Object.prototype.toString.call(e)}var v=e("./getName"),y=e("./getProperties"),g=e("./getEnumerableProperties");t.exports=r;var b=function(e){return"object"==typeof HTMLElement?e instanceof HTMLElement:e&&"object"==typeof e&&1===e.nodeType&&"string"==typeof e.nodeName}},{"./getEnumerableProperties":16,"./getName":18,"./getProperties":21}],25:[function(e,t,n){var r=e("./inspect"),o=e("../config");t.exports=function(e){var t=r(e),n=Object.prototype.toString.call(e);if(o.truncateThreshold&&t.length>=o.truncateThreshold){if("[object Function]"===n)return e.name&&""!==e.name?"[Function: "+e.name+"]":"[Function]";if("[object Array]"===n)return"[ Array("+e.length+") ]";if("[object Object]"===n){var i=Object.keys(e);return"{ Object ("+(i.length>2?i.splice(0,2).join(", ")+", ...":i.join(", "))+") }"}return t}return t}},{"../config":5,"./inspect":24}],26:[function(e,t,n){t.exports=function(e,t,n,r){var o=e.__methods[t],i=o.chainingBehavior;o.chainingBehavior=function(){var e=r(i).call(this);return void 0===e?this:e};var a=o.method;o.method=function(){var e=n(a).apply(this,arguments);return void 0===e?this:e}}},{}],27:[function(e,t,n){t.exports=function(e,t,n){var r=e[t],o=function(){return this};r&&"function"==typeof r&&(o=r),e[t]=function(){var e=n(o).apply(this,arguments);return void 0===e?this:e}}},{}],28:[function(e,t,n){t.exports=function(e,t,n){var r=Object.getOwnPropertyDescriptor(e,t),o=function(){};r&&"function"==typeof r.get&&(o=r.get),Object.defineProperty(e,t,{get:function(){var e=n(o).call(this);return void 0===e?this:e},configurable:!0})}},{}],29:[function(e,t,n){var r=e("./flag");t.exports=function(e,t){var n=r(e,"negate"),o=t[0];return n?!o:o}},{"./flag":14}],30:[function(e,t,n){t.exports=function(e,t,n){var r=e.__flags||(e.__flags=Object.create(null));t.__flags||(t.__flags=Object.create(null)),n=3!==arguments.length||n;for(var o in r)(n||"object"!==o&&"ssfi"!==o&&"message"!=o)&&(t.__flags[o]=r[o])}},{}],31:[function(e,t,n){"use strict";function r(e){var t=void 0;t="string"==typeof e?[e]:e.raw;for(var n="",r=0;r=0;o--)if(s=i[o],!r(e[s],t[s],n))return!1;return!0}var p,v=e("type-detect");try{p=e("buffer").Buffer}catch(e){(p={}).isBuffer=function(){return!1}}t.exports=r},{buffer:void 0,"type-detect":38}],34:[function(e,t,n){(function(r){!function(e){if("object"==typeof n&&void 0!==t)t.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:void 0!==r?r:"undefined"!=typeof self?self:this).localforage=e()}}(function(){return function t(n,r,o){function i(s,c){if(!r[s]){if(!n[s]){var u="function"==typeof e&&e;if(!c&&u)return u(s,!0);if(a)return a(s,!0);var f=new Error("Cannot find module '"+s+"'");throw f.code="MODULE_NOT_FOUND",f}var l=r[s]={exports:{}};n[s][0].call(l.exports,function(e){var t=n[s][1][e];return i(t||e)},l,l.exports,t,n,r,o)}return r[s].exports}for(var a="function"==typeof e&&e,s=0;s=43)}}).catch(function(){return!1})}function u(e){return"boolean"==typeof re?ie.resolve(re):c(e).then(function(e){return re=e})}function f(e){var t=oe[e.name],n={};n.promise=new ie(function(e){n.resolve=e}),t.deferredOperations.push(n),t.dbReady?t.dbReady=t.dbReady.then(function(){return n.promise}):t.dbReady=n.promise}function l(e){var t=oe[e.name].deferredOperations.pop();t&&t.resolve()}function d(e,t){return new ie(function(n,r){if(e.db){if(!t)return n(e.db);f(e),e.db.close()}var o=[e.name];t&&o.push(e.version);var i=ne.open.apply(ne,o);t&&(i.onupgradeneeded=function(t){var n=i.result;try{n.createObjectStore(e.storeName),t.oldVersion<=1&&n.createObjectStore(ae)}catch(n){if("ConstraintError"!==n.name)throw n;console.warn('The database "'+e.name+'" has been upgraded from version '+t.oldVersion+" to version "+t.newVersion+', but the storage "'+e.storeName+'" already exists.')}}),i.onerror=function(e){e.preventDefault(),r(i.error)},i.onsuccess=function(){n(i.result),l(e)}})}function h(e){return d(e,!1)}function p(e){return d(e,!0)}function v(e,t){if(!e.db)return!0;var n=!e.db.objectStoreNames.contains(e.storeName),r=e.versione.db.version;if(r&&(e.version!==t&&console.warn('The database "'+e.name+"\" can't be downgraded from version "+e.db.version+" to version "+e.version+"."),e.version=e.db.version),o||n){if(n){var i=e.db.version+1;i>e.version&&(e.version=i)}return!0}return!1}function y(e){return new ie(function(t,n){var r=new FileReader;r.onerror=n,r.onloadend=function(n){var r=btoa(n.target.result||"");t({__local_forage_encoded_blob:!0,data:r,type:e.type})},r.readAsBinaryString(e)})}function g(e){return o([s(atob(e.data))],{type:e.type})}function b(e){return e&&e.__local_forage_encoded_blob}function m(e){var t=this,n=t._initReady().then(function(){var e=oe[t._dbInfo.name];if(e&&e.dbReady)return e.dbReady});return a(n,e,e),n}function w(e){function t(){return ie.resolve()}var n=this,r={db:null};if(e)for(var o in e)r[o]=e[o];oe||(oe={});var i=oe[r.name];i||(i={forages:[],db:null,dbReady:null,deferredOperations:[]},oe[r.name]=i),i.forages.push(n),n._initReady||(n._initReady=n.ready,n.ready=m);for(var a=[],s=0;s>4,f[c++]=(15&r)<<4|o>>2,f[c++]=(3&o)<<6|63&i;return u}function M(e){var t,n=new Uint8Array(e),r="";for(t=0;t>2],r+=ue[(3&n[t])<<4|n[t+1]>>4],r+=ue[(15&n[t+1])<<2|n[t+2]>>6],r+=ue[63&n[t+2]];return n.length%3==2?r=r.substring(0,r.length-1)+"=":n.length%3==1&&(r=r.substring(0,r.length-2)+"=="),r}function I(e,t){var n="";if(e&&(n=Oe.call(e)),e&&("[object ArrayBuffer]"===n||e.buffer&&"[object ArrayBuffer]"===Oe.call(e.buffer))){var r,o=de;e instanceof ArrayBuffer?(r=e,o+=pe):(r=e.buffer,"[object Int8Array]"===n?o+=ye:"[object Uint8Array]"===n?o+=ge:"[object Uint8ClampedArray]"===n?o+=be:"[object Int16Array]"===n?o+=me:"[object Uint16Array]"===n?o+=xe:"[object Int32Array]"===n?o+=we:"[object Uint32Array]"===n?o+=je:"[object Float32Array]"===n?o+=Ee:"[object Float64Array]"===n?o+=Se:t(new Error("Failed to get type for BinaryArray"))),t(o+M(r))}else if("[object Blob]"===n){var i=new FileReader;i.onload=function(){var n=fe+e.type+"~"+M(this.result);t(de+ve+n)},i.readAsArrayBuffer(e)}else try{t(JSON.stringify(e))}catch(n){console.error("Couldn't convert value into a JSON string: ",e),t(null,n)}}function k(e){if(e.substring(0,he)!==de)return JSON.parse(e);var t,n=e.substring(_e),r=e.substring(he,_e);if(r===ve&&le.test(n)){var i=n.match(le);t=i[1],n=n.substring(i[0].length)}var a=P(n);switch(r){case pe:return a;case ve:return o([a],{type:t});case ye:return new Int8Array(a);case ge:return new Uint8Array(a);case be:return new Uint8ClampedArray(a);case me:return new Int16Array(a);case xe:return new Uint16Array(a);case we:return new Int32Array(a);case je:return new Uint32Array(a);case Ee:return new Float32Array(a);case Se:return new Float64Array(a);default:throw new Error("Unkown type: "+r)}}function T(e){var t=this,n={db:null};if(e)for(var r in e)n[r]="string"!=typeof e[r]?e[r].toString():e[r];var o=new ie(function(e,r){try{n.db=openDatabase(n.name,String(n.version),n.description,n.size)}catch(e){return r(e)}n.db.transaction(function(o){o.executeSql("CREATE TABLE IF NOT EXISTS "+n.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){t._dbInfo=n,e()},function(e,t){r(t)})})});return n.serializer=Ae,o}function C(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT * FROM "+o.storeName+" WHERE key = ? LIMIT 1",[e],function(e,n){var r=n.rows.length?n.rows.item(0).value:null;r&&(r=o.serializer.deserialize(r)),t(r)},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function D(e,t){var n=this,r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT * FROM "+o.storeName,[],function(n,r){for(var i=r.rows,a=i.length,s=0;s0)return void i(L.apply(o,[e,s,n,r-1]));a(t)}})})}).catch(a)});return i(a,n),a}function R(e,t,n){return L.apply(this,[e,t,n,1])}function B(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("DELETE FROM "+o.storeName+" WHERE key = ?",[e],function(){t()},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function q(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("DELETE FROM "+r.storeName,[],function(){e()},function(e,t){n(t)})})}).catch(n)});return i(n,e),n}function z(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("SELECT COUNT(key) as c FROM "+r.storeName,[],function(t,n){var r=n.rows.item(0).c;e(r)},function(e,t){n(t)})})}).catch(n)});return i(n,e),n}function F(e,t){var n=this,r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT key FROM "+o.storeName+" WHERE id = ? LIMIT 1",[e+1],function(e,n){var r=n.rows.length?n.rows.item(0).key:null;t(r)},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function U(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("SELECT key FROM "+r.storeName,[],function(t,n){for(var r=[],o=0;o=0;n--){var r=localStorage.key(n);0===r.indexOf(e)&&localStorage.removeItem(r)}});return i(n,e),n}function J(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=n.ready().then(function(){var t=n._dbInfo,r=localStorage.getItem(t.keyPrefix+e);return r&&(r=t.serializer.deserialize(r)),r});return i(r,t),r}function G(e,t){var n=this,r=n.ready().then(function(){for(var t=n._dbInfo,r=t.keyPrefix,o=r.length,i=localStorage.length,a=1,s=0;s num > 5);\n return overFive;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, [8, 13, 21]) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 3 items",test:`assert.lengthOf(output, 3) === undefined;`},{name:`First item is 8`,test:`assert.deepEqual(output[0], 8) === undefined;`}]},{name:"Array.map()",time:10,prompt:`Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,given:`const numbers = [25, 121, 169];\r`,answer:`const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, [5, 11, 13]) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 3 items",test:`assert.lengthOf(output, 3) === undefined;`},{name:`First item is 5`,test:`assert.deepEqual(output[0], 5) === undefined;`},{name:`Last item is 13`,test:`assert.deepEqual(output[output.length - 1], 13) === undefined;`}]},{name:"Array.every()",time:10,prompt:`Return object that returns whether each array contains all even numbers using Array.every().`,given:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,answer:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n return element % 2 === 0\n }\n return {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n };`,tests:[{name:"Correct output",test:`assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;`},{name:"Returns an Object",test:`assert.isObject(output) === undefined;`},{name:"Object has 2 items",test:`assert.lengthOf(Object.keys(output), 2) === undefined;`},{name:`First value is true`,test:`assert.isTrue(output.evenNumbers) === undefined;`},{name:`Second value is false`,test:`assert.isFalse(output.someOddNumbers) === undefined;`}]},{name:"Array.some()",time:10,prompt:`Return 'Object' that returns whether each array contains some odd numbers using 'Array.some()'.`,given:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 4, 7, 8];\n function isOdd(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,answer:`const evenNumbers = [1, 3, 5, 7];\n const someOddNumbers = [1, 3, 6, 7];\n function isOdd(element) {\n return element % 2 !== 0;\n }\n return {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n };`,tests:[{name:"Correct output",test:`assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;`},{name:"Returns an Object",test:`assert.isObject(output) === undefined;`},{name:"Object has 2 items",test:`assert.lengthOf(Object.keys(output), 2) === undefined;`},{name:`First value is false`,test:`assert.isFalse(output.evenNumbers) === undefined;`},{name:`Second value is true`,test:`assert.isTrue(output.someOddNumbers) === undefined;`}]}]},{}],37:[function(e,t,n){t.exports=[{name:"Create Array",time:10,prompt:"Create and return an array that contains 'apple' and 'banana'",given:`const fruits = [];\rreturn fruits;`,answer:`const fruits = ['apple', 'banana'];\n return fruits;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, ['apple', 'banana']) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 2 items",test:`assert.lengthOf(output, 2) === undefined;`}]},{name:"Array.pop()",time:10,prompt:`Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,given:`const fruits = ['apple', 'banana', 'orange'];\r`,answer:`const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, ['apple', 'banana']) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 2 items",test:`assert.lengthOf(output, 2) === undefined;`}]}]},{}],38:[function(e,t,n){t.exports=e("./lib/type")},{"./lib/type":39}],39:[function(e,t,n){function r(e){var t=Object.prototype.toString.call(e);return i[t]?i[t]:null===e?"null":void 0===e?"undefined":e===Object(e)?"object":typeof e}function o(){this.tests={}}var i={"[object Array]":"array","[object RegExp]":"regexp","[object Function]":"function","[object Arguments]":"arguments","[object Date]":"date"};(t.exports=r).Library=o,o.prototype.of=r,o.prototype.define=function(e,t){return 1===arguments.length?this.tests[e]:(this.tests[e]=t,this)},o.prototype.test=function(e,t){if(t===r(e))return!0;var n=this.tests[t];if(n&&"regexp"===r(n))return n.test(e);if(n&&"function"===r(n))return n(e);throw new ReferenceError('Type test "'+t+'" not defined or invalid.')}},{}],40:[function(e,t,n){arguments[4][38][0].apply(n,arguments)},{"./lib/type":41,dup:38}],41:[function(e,t,n){function r(e){var t=Object.prototype.toString.call(e).match(i)[1].toLowerCase();return"function"==typeof Promise&&e instanceof Promise?"promise":null===e?"null":void 0===e?"undefined":t}function o(){if(!(this instanceof o))return new o;this.tests={}}var i=/^\[object (.*)\]$/;(t.exports=r).Library=o,o.prototype.of=r,o.prototype.define=function(e,t){return 1===arguments.length?this.tests[e]:(this.tests[e]=t,this)},o.prototype.test=function(e,t){if(t===r(e))return!0;var n=this.tests[t];if(n&&"regexp"===r(n))return n.test(e);if(n&&"function"===r(n))return n(e);throw new ReferenceError('Type test "'+t+'" not defined or invalid.')}},{}],42:[function(require,module,exports){"use strict";function _toConsumableArray(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t=e.length-1||t<0?0:t+1}function getCurrentProblem(e){return e[config.currentIndex]}function previousProblem(){console.log("previousProblem!"),previousProblemButtonEl.classList.add("active"),config.currentIndex=config.shuffle?getRandomIndex(problems):getPreviousIndex(problems),updateLocalstore(config).then(function(){window.location.reload()})}function nextProblem(){console.log("nextProblem!"),nextProblemButtonEl.classList.add("active"),config.currentIndex=config.shuffle?getRandomIndex(problems):getNextIndex(problems),updateLocalstore(config).then(function(){window.location.reload()})}function toggleShuffle(){console.log("toggle shuffle!"),config.shuffle=!config.shuffle,shuffleProblemsButtonEl.classList.toggle("active"),previousProblemButtonEl.parentNode.classList.toggle("hidden"),updateLocalstore(config)}function loadProblem(e){currentProblem=e,problemEl.innerText=e.prompt,e.given&&(codeEl.value=e.given),testSuite(null,!0)}function updateTests(e,t){!0===t&&buildTests(currentProblem.tests),updateTestStatus(e)}function buildTests(e){if(e){var t=e.map(function(e){return'
\n
[✘]
\n
'+e.name+"
\n
"}).join("");testSuiteEl.innerHTML=t}}function updateTestStatus(e){if(!e)throw new Error("No testStatuses provided.");var t=!0;e.forEach(function(e){!0!==e&&(t=!1)}),[].slice.call(testSuiteEl.querySelectorAll(".test-state")).forEach(function(t,n){!0===e[n]?(t.innerHTML="[✓]",t.classList.remove("fail"),t.classList.add("pass")):(t.innerHTML="[✘]",t.classList.remove("pass"),t.classList.add("fail"))}),!0===t?(testTotalEl.innerText="PASS",testTotalEl.classList.remove("fail"),testTotalEl.classList.add("pass")):(testTotalEl.innerText="FAIL",testTotalEl.classList.remove("pass"),testTotalEl.classList.add("fail"))}function printAssertError(e){var t="";null!==e&&(t='\n
\n Expected: '+JSON.stringify(e.expected)+"\n Actual: "+JSON.stringify(e.actual)+"\n
"),assertConsoleEl.innerHTML=t}function printEvalOutput(e,t){var n="";e&&void 0!==e.message?n='\n
\n Syntax Error: '+JSON.stringify(e.message)+"\n
":t&&(n='\n
\n Output: '+JSON.stringify(t)+"\n
"),evalConsoleEl.innerHTML=n}function testSuite(e){testTotalEl.classList.toggle("working");var t=runTests(getOutput(codeEl.value));testTotalEl.classList.toggle("working"),updateTests(t,e)}function getOutput(code){var evald=!1;try{evald=eval("(function(){"+code+"})()"),printEvalOutput(null,evald)}catch(e){printEvalOutput(e)}return evald}function runTests(output){var tested=!1;return tested=currentProblem.tests.map(function(test){var testOutcome=!1;try{output&&(testOutcome=eval(test.test),console.log("testOutcome:",testOutcome)),printAssertError(null)}catch(e){printAssertError(e)}return testOutcome})}function loadApp(e){function t(t){!1===e.shuffle&&13===t.keyCode&&t.shiftKey&&(t.metaKey||t.ctrlKey)?previousProblem():13!==t.keyCode||t.shiftKey||!t.metaKey&&!t.ctrlKey||nextProblem()}console.log("loading app!"),!0===e.shuffle&&(shuffleProblemsButtonEl.classList.add("active"),previousProblemButtonEl.parentNode.classList.add("hidden"));var n=debounce(function(e){-1===ignoreKeyCodes.indexOf(e.keyCode)&&testSuite()},200);codeEl.addEventListener("keydown",n),document.addEventListener("keydown",t),shuffleProblemsButtonEl.addEventListener("click",toggleShuffle),previousProblemButtonEl.addEventListener("click",previousProblem),nextProblemButtonEl.addEventListener("click",nextProblem),loadProblem(getCurrentProblem(problems)),testSuite(!0)}var localforage=require("localforage"),probs=require("pjs-problems"),dedent=require("dedent"),assert=require("chai").assert,problems=[];Object.keys(probs).forEach(function(e){var t;(t=problems).push.apply(t,_toConsumableArray(probs[e]))}),problems=dedentStrings(problems);var currentProblem=void 0,ignoreKeyCodes=[9,37,39,38,40],config={shuffle:!0,timer:!1,currentIndex:0};localforage.getItem("js_practice_config").then(function(e){e&&(config=e),loadApp(config)}).catch(function(e){console.log("localforage err:",e),loadApp(config)});var problemEl=document.getElementById("problem"),codeEl=document.getElementById("code"),testSuiteEl=document.getElementById("test-suite"),testTotalEl=document.getElementById("test-total"),evalConsoleEl=document.getElementById("eval-output"),assertConsoleEl=document.getElementById("assert-output"),shuffleProblemsButtonEl=document.getElementById("shuffle-problems"),previousProblemButtonEl=document.getElementById("prev-problem"),nextProblemButtonEl=document.getElementById("next-problem")}(document,window)},{chai:2,dedent:31,localforage:34,"pjs-problems":35}]},{},[42]); //# sourceMappingURL=bundle.min.js.map diff --git a/public/dist/js/bundle.min.js.map b/public/dist/js/bundle.min.js.map index 51fd579..19ab410 100644 --- a/public/dist/js/bundle.min.js.map +++ b/public/dist/js/bundle.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["node_modules/.registry.npmjs.org/browser-pack/6.0.2/node_modules/browser-pack/_prelude.js","node_modules/.github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916/node_modules/pjs-problems/index.js","node_modules/.github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916/node_modules/pjs-problems/problems/arrays.js","node_modules/.github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916/node_modules/pjs-problems/problems/initial.js","node_modules/.registry.npmjs.org/assertion-error/1.0.2/node_modules/assertion-error/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/assertion.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/config.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/core/assertions.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/assert.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/expect.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/should.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addChainableMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/expectTypes.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/flag.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getActual.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getEnumerableProperties.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getMessage.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getName.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getPathInfo.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getPathValue.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getProperties.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/hasProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/inspect.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/objDisplay.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/test.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/transferFlags.js","node_modules/.registry.npmjs.org/dedent/0.7.0/node_modules/dedent/dist/dedent.js","node_modules/.registry.npmjs.org/deep-eql/0.1.3/node_modules/deep-eql/index.js","node_modules/.registry.npmjs.org/deep-eql/0.1.3/node_modules/deep-eql/lib/eql.js","node_modules/.registry.npmjs.org/localforage/1.5.0/node_modules/localforage/dist/node_modules/localforage/dist/localforage.js","node_modules/.registry.npmjs.org/type-detect/0.1.1/node_modules/type-detect/index.js","node_modules/.registry.npmjs.org/type-detect/0.1.1/node_modules/type-detect/lib/type.js","node_modules/.registry.npmjs.org/type-detect/1.0.0/node_modules/type-detect/lib/type.js","src/js/index.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length","1","module","initial","arrays","name","time","prompt","given","answer","tests","test","exclude","excludeProps","res","obj","Object","keys","forEach","key","excludes","indexOf","slice","arguments","args","AssertionError","message","_props","ssf","props","this","showDiff","callee","captureStackTrace","stack","prototype","create","constructor","toJSON","used","version","util","use","fn","push","config","assertion","core","expect","should","assert","_chai","Assertion","msg","flag","defineProperty","get","console","warn","includeStack","set","value","addProperty","addMethod","addChainableMethod","chainingBehavior","overwriteProperty","overwriteMethod","overwriteChainableMethod","expr","negateMsg","expected","_actual","ok","getMessage","actual","getActual","val","truncateThreshold","chai","_","an","type","toLowerCase","article","charAt","includeChainingBehavior","include","expectTypes","eql","k","property","subset","undefined","inspect","checkArguments","toString","assertEqual","_obj","assertEql","assertAbove","to","have","len","assertLeast","assertBelow","assertMost","assertInstanceOf","getName","assertOwnProperty","hasOwnProperty","assertOwnPropertyDescriptor","descriptor","actualDescriptor","getOwnPropertyDescriptor","assertLengthChain","assertLength","assertMatch","re","exec","assertKeys","str","mixedArgsMsg","Array","any","all","filter","every","last","map","pop","join","sort","assertThrows","errMsg","is","thrown","desiredError","thrownError","RegExp","err","actuallyGot","expectedThrown","respondTo","method","itself","context","satisfy","matcher","result","objDisplay","negate","closeTo","delta","Math","abs","isSubsetOf","superset","cmp","elem","some","elem2","oneOf","list","be","assertChanges","object","prop","assertIncreases","assertDecreases","chain","isNaN","isArray","start","finish","range","isDeep","pathInfo","getPathInfo","hasProperty","exists","isExtensible","TypeError","isSealed","isFrozen","express","errmsg","fail","operator","isOk","isNotOk","not","equal","act","exp","notEqual","strictEqual","notStrictEqual","deepEqual","notDeepEqual","isAbove","abv","above","isAtLeast","atlst","least","isBelow","blw","below","isAtMost","atmst","most","isTrue","isNotTrue","isFalse","isNotFalse","isNull","isNotNull","NaN","isNotNaN","isUndefined","isDefined","isFunction","isNotFunction","isObject","isNotObject","isNotArray","isString","isNotString","isNumber","isNotNumber","isBoolean","isNotBoolean","typeOf","notTypeOf","instanceOf","notInstanceOf","inc","notInclude","match","notMatch","notProperty","deepProperty","deep","notDeepProperty","propertyVal","propertyNotVal","deepPropertyVal","deepPropertyNotVal","lengthOf","throws","errt","errs","assertErr","throw","doesNotThrow","Throw","val2","approximately","sameMembers","set1","set2","same","members","sameDeepMembers","includeMembers","includeDeepMembers","inList","changes","change","doesNotChange","increases","increase","doesNotIncrease","decreases","decrease","doesNotDecrease","ifError","extensible","isNotExtensible","sealed","isNotSealed","frozen","isNotFrozen","alias","as","loadShould","shouldGetter","String","Number","Boolean","valueOf","shouldSetter","enumerable","configurable","writable","val1","exist","Should","transferFlags","hasProtoSupport","excludeNames","Function","apply","ctx","chainableBehavior","__methods","__proto__","getOwnPropertyNames","asserterName","pd","getter","types","index","art","flags","__flags","flagMsg","replace","func","parsePath","path","mArr","parseFloat","p","_getPathValue","parsed","tmp","part","info","parent","proto","getPrototypeOf","literals","number","string","ot","getPathValue","showHidden","depth","colors","formatValue","seen","stylize","recurseTimes","ret","primitive","formatPrimitive","isDOMElement","outerHTML","document","xmlVersion","XMLSerializer","serializeToString","container","createElementNS","appendChild","cloneNode","html","innerHTML","visibleKeys","getEnumerableProperties","getProperties","isError","nameSuffix","isRegExp","isDate","Date","toUTCString","formatError","base","array","braces","output","formatArray","formatProperty","reduceToSingleString","simple","JSON","stringify","Infinity","__lookupGetter__","__lookupSetter__","split","line","substr","numLinesEst","reduce","prev","cur","ar","objectToString","d","HTMLElement","nodeType","nodeName","splice","_chainingBehavior","_method","_super","_get","includeAll","dedent","strings","raw","lines","mindent","m","indent","min","trim","b","sameValue","dateEqual","regexpEqual","Buffer","isBuffer","bufferEqual","argumentsEqual","typeEqual","objectEqual","getTime","iterableEqual","isValue","ka","kb","ex","define","amd","window","global","self","localforage","_dereq_","nextTick","draining","oldQueue","queue","immediate","task","scheduleDrain","Mutation","MutationObserver","WebKitMutationObserver","called","observer","element","createTextNode","observe","characterData","data","setImmediate","MessageChannel","createElement","scriptEl","onreadystatechange","parentNode","removeChild","documentElement","setTimeout","channel","port1","onmessage","port2","postMessage","2","INTERNAL","Promise","resolver","state","PENDING","outcome","safelyResolveThenable","QueueItem","promise","onFulfilled","onRejected","callFulfilled","otherCallFulfilled","callRejected","otherCallRejected","unwrap","returnValue","handlers","reject","resolve","getThen","then","thenable","onError","onSuccess","tryToUnwrap","tryCatch","status","out","reason","iterable","values","resolved","resolveFromAll","outValue","error","race","response","REJECTED","FULFILLED","3","4","_classCallCheck","instance","Constructor","createBlob","parts","properties","Blob","builder","BlobBuilder","MSBlobBuilder","MozBlobBuilder","WebKitBlobBuilder","append","getBlob","executeCallback","callback","executeTwoCallbacks","errorCallback","_binStringToArrayBuffer","bin","buf","ArrayBuffer","arr","Uint8Array","charCodeAt","_checkBlobSupportWithoutCaching","idb","Promise$1","txn","transaction","DETECT_BLOB_SUPPORT_STORE","blob","objectStore","put","onabort","preventDefault","stopPropagation","oncomplete","matchedChrome","navigator","userAgent","matchedEdge","parseInt","_checkBlobSupport","supportsBlobs","_deferReadiness","dbInfo","dbContext","dbContexts","deferredOperation","deferredOperations","dbReady","_advanceReadiness","_getConnection","upgradeNeeded","db","close","dbArgs","openreq","open","onupgradeneeded","createObjectStore","storeName","oldVersion","newVersion","onerror","onsuccess","_getOriginalConnection","_getUpgradedConnection","_isUpgradeNeeded","defaultVersion","isNewStore","objectStoreNames","contains","isDowngrade","isUpgrade","incVersion","_encodeBlob","reader","FileReader","onloadend","base64","btoa","target","__local_forage_encoded_blob","readAsBinaryString","_decodeBlob","encodedBlob","atob","_isEncodedBlob","_fullyReady","_initReady","_dbInfo","_initStorage","options","ignoreErrors","forages","ready","initPromises","j","forage","_defaultConfig","getItem","req","iterate","iterator","openCursor","iterationNumber","cursor","setItem","blobSupport","removeItem","clear","count","advanced","advance","stringToBuffer","serializedString","encoded1","encoded2","encoded3","encoded4","bufferLength","buffer","bytes","BASE_CHARS","bufferToString","base64String","substring","serialize","valueType","toString$1","marker","SERIALIZED_MARKER","TYPE_ARRAYBUFFER","TYPE_INT8ARRAY","TYPE_UINT8ARRAY","TYPE_UINT8CLAMPEDARRAY","TYPE_INT16ARRAY","TYPE_UINT16ARRAY","TYPE_INT32ARRAY","TYPE_UINT32ARRAY","TYPE_FLOAT32ARRAY","TYPE_FLOAT64ARRAY","fileReader","onload","BLOB_TYPE_PREFIX","TYPE_BLOB","readAsArrayBuffer","deserialize","SERIALIZED_MARKER_LENGTH","parse","blobType","TYPE_SERIALIZED_MARKER_LENGTH","BLOB_TYPE_PREFIX_REGEX","Int8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","_initStorage$1","dbInfoPromise","openDatabase","description","size","executeSql","serializer","localforageSerializer","getItem$1","results","rows","item","iterate$1","_setItem","retriesLeft","originalValue","sqlError","QUOTA_ERR","setItem$1","removeItem$1","clear$1","length$1","c","key$1","keys$1","_initStorage$2","keyPrefix","clear$2","localStorage","getItem$2","iterate$2","keyPrefixLength","key$2","keys$2","length$2","removeItem$2","setItem$2","callWhenReady","localForageInstance","libraryMethod","_args","extend","arg","isLibraryDriver","driverName","driver","DriverType","_typeof","Symbol","indexedDB","webkitIndexedDB","mozIndexedDB","OIndexedDB","msIndexedDB","asyncStorage","_driver","webSQLStorage","localStorageWrapper","CustomDrivers","INDEXEDDB","LOCALSTORAGE","WEBSQL","LibraryMethods","DefaultConfig","driverSupport","isSafari","platform","hasFetch","fetch","IDBKeyRange","localforage_js","LocalForage","_config","_driverSet","_initDriver","_ready","_wrapLibraryMethodsWithReady","setDriver","defineDriver","driverObject","complianceError","namingError","customDriverMethods","concat","customDriverMethod","supportPromise","_support","supportResult","getDriver","getDriverPromise","getSerializer","serializerPromise","drivers","setDriverToConfig","extendSelfWithDriver","_extend","initDriver","supportedDrivers","driverPromiseLoop","currentDriverIndex","_getSupportedDrivers","oldDriverSetDone","supports","libraryMethodsAndProperties","createInstance","getType","natives","Library","[object Array]","[object RegExp]","[object Function]","[object Arguments]","[object Date]","of","ReferenceError","objectTypeRegexp","dedentStrings","problems","prob","updateLocalstore","catch","log","debounce","wait","timeout","later","callNow","clearTimeout","getRandomIndex","problemsArr","ind","floor","random","currentIndex","getPreviousIndex","getNextIndex","getCurrentProblem","previousProblem","previousProblemButtonEl","classList","add","shuffle","location","reload","nextProblem","nextProblemButtonEl","toggleShuffle","shuffleProblemsButtonEl","toggle","loadProblem","problemObj","currentProblem","problemEl","innerText","codeEl","testSuite","updateTests","testStatus","init","buildTests","updateTestStatus","testsDom","testSuiteEl","testStatuses","allPassed","testPassed","querySelectorAll","testStatusEl","iter","remove","testTotalEl","printAssertError","errObj","inner","assertConsoleEl","printEvalOutput","evalConsoleEl","tested","runTests","getOutput","evald","eval","testOutcome","loadApp","problemNav","keyCode","shiftKey","metaKey","ctrlKey","debouncedInputValidation","ignoreKeyCodes","addEventListener","probs","subject","_problems","_toConsumableArray","timer","getElementById"],"mappings":"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","file":"bundle.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o num > 5);\n return overFive;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, [8, 13, 21]) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n },\n {\n name: `First item is 8`,\n test: `assert.deepEqual(output[0], 8) === undefined;`\n }\n ]\n },\n {\n name: 'Array.map()',\n time: 10,\n prompt: `Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,\n given: `const numbers = [25, 121, 169];\\r`,\n answer: `const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, [5, 11, 13]) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n },\n {\n name: `First item is 5`,\n test: `assert.deepEqual(output[0], 5) === undefined;`\n },\n {\n name: `Last item is 13`,\n test: `assert.deepEqual(output[output.length - 1], 13) === undefined;`\n }\n ]\n },\n {\n name: 'Array.every()',\n time: 10,\n prompt: `Return object that returns whether each array contains all even numbers using Array.every().`,\n given: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,\n answer: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n return element % 2 === 0\n }\n return {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n };`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;`\n },\n {\n name: 'Returns an Object',\n test: `assert.isObject(output) === undefined;`\n },\n {\n name: 'Object has 2 items',\n test: `assert.lengthOf(Object.keys(output), 2) === undefined;`\n },\n {\n name: `First value is true`,\n test: `assert.isTrue(output.evenNumbers) === undefined;`\n },\n {\n name: `Second value is false`,\n test: `assert.isFalse(output.someOddNumbers) === undefined;`\n }\n ]\n },\n {\n name: 'Array.some()',\n time: 10,\n prompt: `Return 'Object' that returns whether each array contains some odd numbers using 'Array.some()'.`,\n given: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 4, 7, 8];\n function isOdd(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,\n answer: `const evenNumbers = [1, 3, 5, 7];\n const someOddNumbers = [1, 3, 6, 7];\n function isOdd(element) {\n return element % 2 !== 0;\n }\n return {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n };`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;`\n },\n {\n name: 'Returns an Object',\n test: `assert.isObject(output) === undefined;`\n },\n {\n name: 'Object has 2 items',\n test: `assert.lengthOf(Object.keys(output), 2) === undefined;`\n },\n {\n name: `First value is false`,\n test: `assert.isFalse(output.evenNumbers) === undefined;`\n },\n {\n name: `Second value is true`,\n test: `assert.isTrue(output.someOddNumbers) === undefined;`\n }\n ]\n }\n // Next problems to create:\n // forEach? fix one above that tried, but can't verify forEach was used\n // some\n // reduce\n // reduceRight\n // Array.from and other ways to turn array-like into array\n];\n","module.exports = [\n {\n name: 'Create Array',\n time: 10,\n prompt: 'Create and return an array that contains \\'apple\\' and \\'banana\\'',\n given: `const fruits = [];\\rreturn fruits;`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.pop()',\n time: 10,\n prompt: `Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n]\n","/*!\n * assertion-error\n * Copyright(c) 2013 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n var excludes = [].slice.call(arguments);\n\n function excludeProps (res, obj) {\n Object.keys(obj).forEach(function (key) {\n if (!~excludes.indexOf(key)) res[key] = obj[key];\n });\n }\n\n return function extendExclude () {\n var args = [].slice.call(arguments)\n , i = 0\n , res = {};\n\n for (; i < args.length; i++) {\n excludeProps(res, args[i]);\n }\n\n return res;\n };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n , props = extend(_props || {});\n\n // default values\n this.message = message || 'Unspecified AssertionError';\n this.showDiff = false;\n\n // copy from properties\n for (var key in props) {\n this[key] = props[key];\n }\n\n // capture stack trace\n ssf = ssf || arguments.callee;\n if (ssf && Error.captureStackTrace) {\n Error.captureStackTrace(this, ssf);\n } else {\n try {\n throw new Error();\n } catch(e) {\n this.stack = e.stack;\n }\n }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n var extend = exclude('constructor', 'toJSON', 'stack')\n , props = extend({ name: this.name }, this);\n\n // include stack if exists and not turned off\n if (false !== stack && this.stack) {\n props.stack = this.stack;\n }\n\n return props;\n};\n","module.exports = require('./lib/chai');\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar used = []\n , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n if (!~used.indexOf(fn)) {\n fn(this, util);\n used.push(fn);\n }\n\n return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n /*!\n * Module dependencies.\n */\n\n var AssertionError = _chai.AssertionError\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n _chai.Assertion = Assertion;\n\n /*!\n * Assertion Constructor\n *\n * Creates object for chaining.\n *\n * @api private\n */\n\n function Assertion (obj, msg, stack) {\n flag(this, 'ssfi', stack || arguments.callee);\n flag(this, 'object', obj);\n flag(this, 'message', msg);\n }\n\n Object.defineProperty(Assertion, 'includeStack', {\n get: function() {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n return config.includeStack;\n },\n set: function(value) {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n config.includeStack = value;\n }\n });\n\n Object.defineProperty(Assertion, 'showDiff', {\n get: function() {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n return config.showDiff;\n },\n set: function(value) {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n config.showDiff = value;\n }\n });\n\n Assertion.addProperty = function (name, fn) {\n util.addProperty(this.prototype, name, fn);\n };\n\n Assertion.addMethod = function (name, fn) {\n util.addMethod(this.prototype, name, fn);\n };\n\n Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n Assertion.overwriteProperty = function (name, fn) {\n util.overwriteProperty(this.prototype, name, fn);\n };\n\n Assertion.overwriteMethod = function (name, fn) {\n util.overwriteMethod(this.prototype, name, fn);\n };\n\n Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n /**\n * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n *\n * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n *\n * @name assert\n * @param {Philosophical} expression to be tested\n * @param {String|Function} message or function that returns message to display if expression fails\n * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n * @param {Mixed} expected value (remember to check for negation)\n * @param {Mixed} actual (optional) will default to `this.obj`\n * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n * @api private\n */\n\n Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n var ok = util.test(this, arguments);\n if (true !== showDiff) showDiff = false;\n if (true !== config.showDiff) showDiff = false;\n\n if (!ok) {\n var msg = util.getMessage(this, arguments)\n , actual = util.getActual(this, arguments);\n throw new AssertionError(msg, {\n actual: actual\n , expected: expected\n , showDiff: showDiff\n }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n }\n };\n\n /*!\n * ### ._obj\n *\n * Quick reference to stored `actual` value for plugin developers.\n *\n * @api private\n */\n\n Object.defineProperty(Assertion.prototype, '_obj',\n { get: function () {\n return flag(this, 'object');\n }\n , set: function (val) {\n flag(this, 'object', val);\n }\n });\n};\n","module.exports = {\n\n /**\n * ### config.includeStack\n *\n * User configurable property, influences whether stack trace\n * is included in Assertion error message. Default of false\n * suppresses stack trace in the error message.\n *\n * chai.config.includeStack = true; // enable stack on error\n *\n * @param {Boolean}\n * @api public\n */\n\n includeStack: false,\n\n /**\n * ### config.showDiff\n *\n * User configurable property, influences whether or not\n * the `showDiff` flag should be included in the thrown\n * AssertionErrors. `false` will always be `false`; `true`\n * will be true when the assertion has requested a diff\n * be shown.\n *\n * @param {Boolean}\n * @api public\n */\n\n showDiff: true,\n\n /**\n * ### config.truncateThreshold\n *\n * User configurable property, sets length threshold for actual and\n * expected values in assertion errors. If this threshold is exceeded, for\n * example for large data structures, the value is replaced with something\n * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n *\n * Set it to zero if you want to disable truncating altogether.\n *\n * This is especially userful when doing assertions on arrays: having this\n * set to a reasonable large value makes the failure messages readily\n * inspectable.\n *\n * chai.config.truncateThreshold = 0; // disable truncating\n *\n * @param {Number}\n * @api public\n */\n\n truncateThreshold: 40\n\n};\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n var Assertion = chai.Assertion\n , toString = Object.prototype.toString\n , flag = _.flag;\n\n /**\n * ### Language Chains\n *\n * The following are provided as chainable getters to\n * improve the readability of your assertions. They\n * do not provide testing capabilities unless they\n * have been overwritten by a plugin.\n *\n * **Chains**\n *\n * - to\n * - be\n * - been\n * - is\n * - that\n * - which\n * - and\n * - has\n * - have\n * - with\n * - at\n * - of\n * - same\n *\n * @name language chains\n * @namespace BDD\n * @api public\n */\n\n [ 'to', 'be', 'been'\n , 'is', 'and', 'has', 'have'\n , 'with', 'that', 'which', 'at'\n , 'of', 'same' ].forEach(function (chain) {\n Assertion.addProperty(chain, function () {\n return this;\n });\n });\n\n /**\n * ### .not\n *\n * Negates any of assertions following in the chain.\n *\n * expect(foo).to.not.equal('bar');\n * expect(goodFn).to.not.throw(Error);\n * expect({ foo: 'baz' }).to.have.property('foo')\n * .and.not.equal('bar');\n *\n * @name not\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('not', function () {\n flag(this, 'negate', true);\n });\n\n /**\n * ### .deep\n *\n * Sets the `deep` flag, later used by the `equal` and\n * `property` assertions.\n *\n * expect(foo).to.deep.equal({ bar: 'baz' });\n * expect({ foo: { bar: { baz: 'quux' } } })\n * .to.have.deep.property('foo.bar.baz', 'quux');\n *\n * `.deep.property` special characters can be escaped\n * by adding two slashes before the `.` or `[]`.\n *\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name deep\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('deep', function () {\n flag(this, 'deep', true);\n });\n\n /**\n * ### .any\n *\n * Sets the `any` flag, (opposite of the `all` flag)\n * later used in the `keys` assertion.\n *\n * expect(foo).to.have.any.keys('bar', 'baz');\n *\n * @name any\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('any', function () {\n flag(this, 'any', true);\n flag(this, 'all', false)\n });\n\n\n /**\n * ### .all\n *\n * Sets the `all` flag (opposite of the `any` flag)\n * later used by the `keys` assertion.\n *\n * expect(foo).to.have.all.keys('bar', 'baz');\n *\n * @name all\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('all', function () {\n flag(this, 'all', true);\n flag(this, 'any', false);\n });\n\n /**\n * ### .a(type)\n *\n * The `a` and `an` assertions are aliases that can be\n * used either as language chains or to assert a value's\n * type.\n *\n * // typeof\n * expect('test').to.be.a('string');\n * expect({ foo: 'bar' }).to.be.an('object');\n * expect(null).to.be.a('null');\n * expect(undefined).to.be.an('undefined');\n * expect(new Error).to.be.an('error');\n * expect(new Promise).to.be.a('promise');\n * expect(new Float32Array()).to.be.a('float32array');\n * expect(Symbol()).to.be.a('symbol');\n *\n * // es6 overrides\n * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n *\n * // language chain\n * expect(foo).to.be.an.instanceof(Foo);\n *\n * @name a\n * @alias an\n * @param {String} type\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function an (type, msg) {\n if (msg) flag(this, 'message', msg);\n type = type.toLowerCase();\n var obj = flag(this, 'object')\n , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n this.assert(\n type === _.type(obj)\n , 'expected #{this} to be ' + article + type\n , 'expected #{this} not to be ' + article + type\n );\n }\n\n Assertion.addChainableMethod('an', an);\n Assertion.addChainableMethod('a', an);\n\n /**\n * ### .include(value)\n *\n * The `include` and `contain` assertions can be used as either property\n * based language chains or as methods to assert the inclusion of an object\n * in an array or a substring in a string. When used as language chains,\n * they toggle the `contains` flag for the `keys` assertion.\n *\n * expect([1,2,3]).to.include(2);\n * expect('foobar').to.contain('foo');\n * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n *\n * @name include\n * @alias contain\n * @alias includes\n * @alias contains\n * @param {Object|String|Number} obj\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function includeChainingBehavior () {\n flag(this, 'contains', true);\n }\n\n function include (val, msg) {\n _.expectTypes(this, ['array', 'object', 'string']);\n\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var expected = false;\n\n if (_.type(obj) === 'array' && _.type(val) === 'object') {\n for (var i in obj) {\n if (_.eql(obj[i], val)) {\n expected = true;\n break;\n }\n }\n } else if (_.type(val) === 'object') {\n if (!flag(this, 'negate')) {\n for (var k in val) new Assertion(obj).property(k, val[k]);\n return;\n }\n var subset = {};\n for (var k in val) subset[k] = obj[k];\n expected = _.eql(subset, val);\n } else {\n expected = (obj != undefined) && ~obj.indexOf(val);\n }\n this.assert(\n expected\n , 'expected #{this} to include ' + _.inspect(val)\n , 'expected #{this} to not include ' + _.inspect(val));\n }\n\n Assertion.addChainableMethod('include', include, includeChainingBehavior);\n Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n /**\n * ### .ok\n *\n * Asserts that the target is truthy.\n *\n * expect('everything').to.be.ok;\n * expect(1).to.be.ok;\n * expect(false).to.not.be.ok;\n * expect(undefined).to.not.be.ok;\n * expect(null).to.not.be.ok;\n *\n * @name ok\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('ok', function () {\n this.assert(\n flag(this, 'object')\n , 'expected #{this} to be truthy'\n , 'expected #{this} to be falsy');\n });\n\n /**\n * ### .true\n *\n * Asserts that the target is `true`.\n *\n * expect(true).to.be.true;\n * expect(1).to.not.be.true;\n *\n * @name true\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('true', function () {\n this.assert(\n true === flag(this, 'object')\n , 'expected #{this} to be true'\n , 'expected #{this} to be false'\n , this.negate ? false : true\n );\n });\n\n /**\n * ### .false\n *\n * Asserts that the target is `false`.\n *\n * expect(false).to.be.false;\n * expect(0).to.not.be.false;\n *\n * @name false\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('false', function () {\n this.assert(\n false === flag(this, 'object')\n , 'expected #{this} to be false'\n , 'expected #{this} to be true'\n , this.negate ? true : false\n );\n });\n\n /**\n * ### .null\n *\n * Asserts that the target is `null`.\n *\n * expect(null).to.be.null;\n * expect(undefined).to.not.be.null;\n *\n * @name null\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('null', function () {\n this.assert(\n null === flag(this, 'object')\n , 'expected #{this} to be null'\n , 'expected #{this} not to be null'\n );\n });\n\n /**\n * ### .undefined\n *\n * Asserts that the target is `undefined`.\n *\n * expect(undefined).to.be.undefined;\n * expect(null).to.not.be.undefined;\n *\n * @name undefined\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('undefined', function () {\n this.assert(\n undefined === flag(this, 'object')\n , 'expected #{this} to be undefined'\n , 'expected #{this} not to be undefined'\n );\n });\n\n /**\n * ### .NaN\n * Asserts that the target is `NaN`.\n *\n * expect('foo').to.be.NaN;\n * expect(4).not.to.be.NaN;\n *\n * @name NaN\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('NaN', function () {\n this.assert(\n isNaN(flag(this, 'object'))\n , 'expected #{this} to be NaN'\n , 'expected #{this} not to be NaN'\n );\n });\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi'\n * , bar = null\n * , baz;\n *\n * expect(foo).to.exist;\n * expect(bar).to.not.exist;\n * expect(baz).to.not.exist;\n *\n * @name exist\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('exist', function () {\n this.assert(\n null != flag(this, 'object')\n , 'expected #{this} to exist'\n , 'expected #{this} to not exist'\n );\n });\n\n\n /**\n * ### .empty\n *\n * Asserts that the target's length is `0`. For arrays and strings, it checks\n * the `length` property. For objects, it gets the count of\n * enumerable keys.\n *\n * expect([]).to.be.empty;\n * expect('').to.be.empty;\n * expect({}).to.be.empty;\n *\n * @name empty\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('empty', function () {\n var obj = flag(this, 'object')\n , expected = obj;\n\n if (Array.isArray(obj) || 'string' === typeof object) {\n expected = obj.length;\n } else if (typeof obj === 'object') {\n expected = Object.keys(obj).length;\n }\n\n this.assert(\n !expected\n , 'expected #{this} to be empty'\n , 'expected #{this} not to be empty'\n );\n });\n\n /**\n * ### .arguments\n *\n * Asserts that the target is an arguments object.\n *\n * function test () {\n * expect(arguments).to.be.arguments;\n * }\n *\n * @name arguments\n * @alias Arguments\n * @namespace BDD\n * @api public\n */\n\n function checkArguments () {\n var obj = flag(this, 'object')\n , type = Object.prototype.toString.call(obj);\n this.assert(\n '[object Arguments]' === type\n , 'expected #{this} to be arguments but got ' + type\n , 'expected #{this} to not be arguments'\n );\n }\n\n Assertion.addProperty('arguments', checkArguments);\n Assertion.addProperty('Arguments', checkArguments);\n\n /**\n * ### .equal(value)\n *\n * Asserts that the target is strictly equal (`===`) to `value`.\n * Alternately, if the `deep` flag is set, asserts that\n * the target is deeply equal to `value`.\n *\n * expect('hello').to.equal('hello');\n * expect(42).to.equal(42);\n * expect(1).to.not.equal(true);\n * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n *\n * @name equal\n * @alias equals\n * @alias eq\n * @alias deep.equal\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEqual (val, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'deep')) {\n return this.eql(val);\n } else {\n this.assert(\n val === obj\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{exp}'\n , val\n , this._obj\n , true\n );\n }\n }\n\n Assertion.addMethod('equal', assertEqual);\n Assertion.addMethod('equals', assertEqual);\n Assertion.addMethod('eq', assertEqual);\n\n /**\n * ### .eql(value)\n *\n * Asserts that the target is deeply equal to `value`.\n *\n * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n *\n * @name eql\n * @alias eqls\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEql(obj, msg) {\n if (msg) flag(this, 'message', msg);\n this.assert(\n _.eql(obj, flag(this, 'object'))\n , 'expected #{this} to deeply equal #{exp}'\n , 'expected #{this} to not deeply equal #{exp}'\n , obj\n , this._obj\n , true\n );\n }\n\n Assertion.addMethod('eql', assertEql);\n Assertion.addMethod('eqls', assertEql);\n\n /**\n * ### .above(value)\n *\n * Asserts that the target is greater than `value`.\n *\n * expect(10).to.be.above(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n *\n * @name above\n * @alias gt\n * @alias greaterThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertAbove (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len > n\n , 'expected #{this} to have a length above #{exp} but got #{act}'\n , 'expected #{this} to not have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj > n\n , 'expected #{this} to be above ' + n\n , 'expected #{this} to be at most ' + n\n );\n }\n }\n\n Assertion.addMethod('above', assertAbove);\n Assertion.addMethod('gt', assertAbove);\n Assertion.addMethod('greaterThan', assertAbove);\n\n /**\n * ### .least(value)\n *\n * Asserts that the target is greater than or equal to `value`.\n *\n * expect(10).to.be.at.least(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.least(2);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n *\n * @name least\n * @alias gte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLeast (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= n\n , 'expected #{this} to have a length at least #{exp} but got #{act}'\n , 'expected #{this} to have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj >= n\n , 'expected #{this} to be at least ' + n\n , 'expected #{this} to be below ' + n\n );\n }\n }\n\n Assertion.addMethod('least', assertLeast);\n Assertion.addMethod('gte', assertLeast);\n\n /**\n * ### .below(value)\n *\n * Asserts that the target is less than `value`.\n *\n * expect(5).to.be.below(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n *\n * @name below\n * @alias lt\n * @alias lessThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertBelow (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len < n\n , 'expected #{this} to have a length below #{exp} but got #{act}'\n , 'expected #{this} to not have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj < n\n , 'expected #{this} to be below ' + n\n , 'expected #{this} to be at least ' + n\n );\n }\n }\n\n Assertion.addMethod('below', assertBelow);\n Assertion.addMethod('lt', assertBelow);\n Assertion.addMethod('lessThan', assertBelow);\n\n /**\n * ### .most(value)\n *\n * Asserts that the target is less than or equal to `value`.\n *\n * expect(5).to.be.at.most(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.most(4);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n *\n * @name most\n * @alias lte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertMost (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len <= n\n , 'expected #{this} to have a length at most #{exp} but got #{act}'\n , 'expected #{this} to have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj <= n\n , 'expected #{this} to be at most ' + n\n , 'expected #{this} to be above ' + n\n );\n }\n }\n\n Assertion.addMethod('most', assertMost);\n Assertion.addMethod('lte', assertMost);\n\n /**\n * ### .within(start, finish)\n *\n * Asserts that the target is within a range.\n *\n * expect(7).to.be.within(5,10);\n *\n * Can also be used in conjunction with `length` to\n * assert a length range. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * @name within\n * @param {Number} start lowerbound inclusive\n * @param {Number} finish upperbound inclusive\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('within', function (start, finish, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , range = start + '..' + finish;\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= start && len <= finish\n , 'expected #{this} to have a length within ' + range\n , 'expected #{this} to not have a length within ' + range\n );\n } else {\n this.assert(\n obj >= start && obj <= finish\n , 'expected #{this} to be within ' + range\n , 'expected #{this} to not be within ' + range\n );\n }\n });\n\n /**\n * ### .instanceof(constructor)\n *\n * Asserts that the target is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , Chai = new Tea('chai');\n *\n * expect(Chai).to.be.an.instanceof(Tea);\n * expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n *\n * @name instanceof\n * @param {Constructor} constructor\n * @param {String} message _optional_\n * @alias instanceOf\n * @namespace BDD\n * @api public\n */\n\n function assertInstanceOf (constructor, msg) {\n if (msg) flag(this, 'message', msg);\n var name = _.getName(constructor);\n this.assert(\n flag(this, 'object') instanceof constructor\n , 'expected #{this} to be an instance of ' + name\n , 'expected #{this} to not be an instance of ' + name\n );\n };\n\n Assertion.addMethod('instanceof', assertInstanceOf);\n Assertion.addMethod('instanceOf', assertInstanceOf);\n\n /**\n * ### .property(name, [value])\n *\n * Asserts that the target has a property `name`, optionally asserting that\n * the value of that property is strictly equal to `value`.\n * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n * references into objects and arrays.\n *\n * // simple referencing\n * var obj = { foo: 'bar' };\n * expect(obj).to.have.property('foo');\n * expect(obj).to.have.property('foo', 'bar');\n *\n * // deep referencing\n * var deepObj = {\n * green: { tea: 'matcha' }\n * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n * };\n *\n * expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n *\n * You can also use an array as the starting point of a `deep.property`\n * assertion, or traverse nested arrays.\n *\n * var arr = [\n * [ 'chai', 'matcha', 'konacha' ]\n * , [ { tea: 'chai' }\n * , { tea: 'matcha' }\n * , { tea: 'konacha' } ]\n * ];\n *\n * expect(arr).to.have.deep.property('[0][1]', 'matcha');\n * expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n *\n * Furthermore, `property` changes the subject of the assertion\n * to be the value of that property from the original object. This\n * permits for further chainable assertions on that property.\n *\n * expect(obj).to.have.property('foo')\n * .that.is.a('string');\n * expect(deepObj).to.have.property('green')\n * .that.is.an('object')\n * .that.deep.equals({ tea: 'matcha' });\n * expect(deepObj).to.have.property('teas')\n * .that.is.an('array')\n * .with.deep.property('[2]')\n * .that.deep.equals({ tea: 'konacha' });\n *\n * Note that dots and bracket in `name` must be backslash-escaped when\n * the `deep` flag is set, while they must NOT be escaped when the `deep`\n * flag is not set.\n *\n * // simple referencing\n * var css = { '.link[target]': 42 };\n * expect(css).to.have.property('.link[target]', 42);\n *\n * // deep referencing\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name property\n * @alias deep.property\n * @param {String} name\n * @param {Mixed} value (optional)\n * @param {String} message _optional_\n * @returns value of property for chaining\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('property', function (name, val, msg) {\n if (msg) flag(this, 'message', msg);\n\n var isDeep = !!flag(this, 'deep')\n , descriptor = isDeep ? 'deep property ' : 'property '\n , negate = flag(this, 'negate')\n , obj = flag(this, 'object')\n , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n , hasProperty = isDeep\n ? pathInfo.exists\n : _.hasProperty(name, obj)\n , value = isDeep\n ? pathInfo.value\n : obj[name];\n\n if (negate && arguments.length > 1) {\n if (undefined === value) {\n msg = (msg != null) ? msg + ': ' : '';\n throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n }\n } else {\n this.assert(\n hasProperty\n , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n }\n\n if (arguments.length > 1) {\n this.assert(\n val === value\n , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n , val\n , value\n );\n }\n\n flag(this, 'object', value);\n });\n\n\n /**\n * ### .ownProperty(name)\n *\n * Asserts that the target has an own property `name`.\n *\n * expect('test').to.have.ownProperty('length');\n *\n * @name ownProperty\n * @alias haveOwnProperty\n * @param {String} name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnProperty (name, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n obj.hasOwnProperty(name)\n , 'expected #{this} to have own property ' + _.inspect(name)\n , 'expected #{this} to not have own property ' + _.inspect(name)\n );\n }\n\n Assertion.addMethod('ownProperty', assertOwnProperty);\n Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n /**\n * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n *\n * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n *\n * expect('test').to.have.ownPropertyDescriptor('length');\n * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n * expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n *\n * @name ownPropertyDescriptor\n * @alias haveOwnPropertyDescriptor\n * @param {String} name\n * @param {Object} descriptor _optional_\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnPropertyDescriptor (name, descriptor, msg) {\n if (typeof descriptor === 'string') {\n msg = descriptor;\n descriptor = null;\n }\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n if (actualDescriptor && descriptor) {\n this.assert(\n _.eql(descriptor, actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n , descriptor\n , actualDescriptor\n , true\n );\n } else {\n this.assert(\n actualDescriptor\n , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n );\n }\n flag(this, 'object', actualDescriptor);\n }\n\n Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n /**\n * ### .length\n *\n * Sets the `doLength` flag later used as a chain precursor to a value\n * comparison for the `length` property.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * *Deprecation notice:* Using `length` as an assertion will be deprecated\n * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n * asserting for `length` property value using `length(value)` should be\n * switched to use `lengthOf(value)` instead.\n *\n * @name length\n * @namespace BDD\n * @api public\n */\n\n /**\n * ### .lengthOf(value[, message])\n *\n * Asserts that the target's `length` property has\n * the expected value.\n *\n * expect([ 1, 2, 3]).to.have.lengthOf(3);\n * expect('foobar').to.have.lengthOf(6);\n *\n * @name lengthOf\n * @param {Number} length\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLengthChain () {\n flag(this, 'doLength', true);\n }\n\n function assertLength (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n\n this.assert(\n len == n\n , 'expected #{this} to have a length of #{exp} but got #{act}'\n , 'expected #{this} to not have a length of #{act}'\n , n\n , len\n );\n }\n\n Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n Assertion.addMethod('lengthOf', assertLength);\n\n /**\n * ### .match(regexp)\n *\n * Asserts that the target matches a regular expression.\n *\n * expect('foobar').to.match(/^foo/);\n *\n * @name match\n * @alias matches\n * @param {RegExp} RegularExpression\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n function assertMatch(re, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n re.exec(obj)\n , 'expected #{this} to match ' + re\n , 'expected #{this} not to match ' + re\n );\n }\n\n Assertion.addMethod('match', assertMatch);\n Assertion.addMethod('matches', assertMatch);\n\n /**\n * ### .string(string)\n *\n * Asserts that the string target contains another string.\n *\n * expect('foobar').to.have.string('bar');\n *\n * @name string\n * @param {String} string\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('string', function (str, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('string');\n\n this.assert(\n ~obj.indexOf(str)\n , 'expected #{this} to contain ' + _.inspect(str)\n , 'expected #{this} to not contain ' + _.inspect(str)\n );\n });\n\n\n /**\n * ### .keys(key1, [key2], [...])\n *\n * Asserts that the target contains any or all of the passed-in keys.\n * Use in combination with `any`, `all`, `contains`, or `have` will affect\n * what will pass.\n *\n * When used in conjunction with `any`, at least one key that is passed\n * in must exist in the target object. This is regardless whether or not\n * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n * should be used in the assertion. If neither are used, the assertion is\n * defaulted to `all`.\n *\n * When both `all` and `contain` are used, the target object must have at\n * least all of the passed-in keys but may have more keys not listed.\n *\n * When both `all` and `have` are used, the target object must both contain\n * all of the passed-in keys AND the number of keys in the target object must\n * match the number of keys passed in (in other words, a target object must\n * have all and only all of the passed-in keys).\n *\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n *\n *\n * @name keys\n * @alias key\n * @param {...String|Array|Object} keys\n * @namespace BDD\n * @api public\n */\n\n function assertKeys (keys) {\n var obj = flag(this, 'object')\n , str\n , ok = true\n , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n switch (_.type(keys)) {\n case \"array\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n break;\n case \"object\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n keys = Object.keys(keys);\n break;\n default:\n keys = Array.prototype.slice.call(arguments);\n }\n\n if (!keys.length) throw new Error('keys required');\n\n var actual = Object.keys(obj)\n , expected = keys\n , len = keys.length\n , any = flag(this, 'any')\n , all = flag(this, 'all');\n\n if (!any && !all) {\n all = true;\n }\n\n // Has any\n if (any) {\n var intersection = expected.filter(function(key) {\n return ~actual.indexOf(key);\n });\n ok = intersection.length > 0;\n }\n\n // Has all\n if (all) {\n ok = keys.every(function(key){\n return ~actual.indexOf(key);\n });\n if (!flag(this, 'negate') && !flag(this, 'contains')) {\n ok = ok && keys.length == actual.length;\n }\n }\n\n // Key string\n if (len > 1) {\n keys = keys.map(function(key){\n return _.inspect(key);\n });\n var last = keys.pop();\n if (all) {\n str = keys.join(', ') + ', and ' + last;\n }\n if (any) {\n str = keys.join(', ') + ', or ' + last;\n }\n } else {\n str = _.inspect(keys[0]);\n }\n\n // Form\n str = (len > 1 ? 'keys ' : 'key ') + str;\n\n // Have / include\n str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n // Assertion\n this.assert(\n ok\n , 'expected #{this} to ' + str\n , 'expected #{this} to not ' + str\n , expected.slice(0).sort()\n , actual.sort()\n , true\n );\n }\n\n Assertion.addMethod('keys', assertKeys);\n Assertion.addMethod('key', assertKeys);\n\n /**\n * ### .throw(constructor)\n *\n * Asserts that the function target will throw a specific error, or specific type of error\n * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n * for the error's message.\n *\n * var err = new ReferenceError('This is a bad function.');\n * var fn = function () { throw err; }\n * expect(fn).to.throw(ReferenceError);\n * expect(fn).to.throw(Error);\n * expect(fn).to.throw(/bad function/);\n * expect(fn).to.not.throw('good function');\n * expect(fn).to.throw(ReferenceError, /bad function/);\n * expect(fn).to.throw(err);\n *\n * Please note that when a throw expectation is negated, it will check each\n * parameter independently, starting with error constructor type. The appropriate way\n * to check for the existence of a type of error but for a message that does not match\n * is to use `and`.\n *\n * expect(fn).to.throw(ReferenceError)\n * .and.not.throw(/good function/);\n *\n * @name throw\n * @alias throws\n * @alias Throw\n * @param {ErrorConstructor} constructor\n * @param {String|RegExp} expected error message\n * @param {String} message _optional_\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @returns error for chaining (null if no error)\n * @namespace BDD\n * @api public\n */\n\n function assertThrows (constructor, errMsg, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('function');\n\n var thrown = false\n , desiredError = null\n , name = null\n , thrownError = null;\n\n if (arguments.length === 0) {\n errMsg = null;\n constructor = null;\n } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n errMsg = constructor;\n constructor = null;\n } else if (constructor && constructor instanceof Error) {\n desiredError = constructor;\n constructor = null;\n errMsg = null;\n } else if (typeof constructor === 'function') {\n name = constructor.prototype.name;\n if (!name || (name === 'Error' && constructor !== Error)) {\n name = constructor.name || (new constructor()).name;\n }\n } else {\n constructor = null;\n }\n\n try {\n obj();\n } catch (err) {\n // first, check desired error\n if (desiredError) {\n this.assert(\n err === desiredError\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp}'\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (err instanceof Error ? err.toString() : err)\n );\n\n flag(this, 'object', err);\n return this;\n }\n\n // next, check constructor\n if (constructor) {\n this.assert(\n err instanceof constructor\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n , name\n , (err instanceof Error ? err.toString() : err)\n );\n\n if (!errMsg) {\n flag(this, 'object', err);\n return this;\n }\n }\n\n // next, check message\n var message = 'error' === _.type(err) && \"message\" in err\n ? err.message\n : '' + err;\n\n if ((message != null) && errMsg && errMsg instanceof RegExp) {\n this.assert(\n errMsg.exec(message)\n , 'expected #{this} to throw error matching #{exp} but got #{act}'\n , 'expected #{this} to throw error not matching #{exp}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n this.assert(\n ~message.indexOf(errMsg)\n , 'expected #{this} to throw error including #{exp} but got #{act}'\n , 'expected #{this} to throw error not including #{act}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else {\n thrown = true;\n thrownError = err;\n }\n }\n\n var actuallyGot = ''\n , expectedThrown = name !== null\n ? name\n : desiredError\n ? '#{exp}' //_.inspect(desiredError)\n : 'an error';\n\n if (thrown) {\n actuallyGot = ' but #{act} was thrown'\n }\n\n this.assert(\n thrown === true\n , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n );\n\n flag(this, 'object', thrownError);\n };\n\n Assertion.addMethod('throw', assertThrows);\n Assertion.addMethod('throws', assertThrows);\n Assertion.addMethod('Throw', assertThrows);\n\n /**\n * ### .respondTo(method)\n *\n * Asserts that the object or class target will respond to a method.\n *\n * Klass.prototype.bar = function(){};\n * expect(Klass).to.respondTo('bar');\n * expect(obj).to.respondTo('bar');\n *\n * To check if a constructor will respond to a static function,\n * set the `itself` flag.\n *\n * Klass.baz = function(){};\n * expect(Klass).itself.to.respondTo('baz');\n *\n * @name respondTo\n * @alias respondsTo\n * @param {String} method\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function respondTo (method, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , itself = flag(this, 'itself')\n , context = ('function' === _.type(obj) && !itself)\n ? obj.prototype[method]\n : obj[method];\n\n this.assert(\n 'function' === typeof context\n , 'expected #{this} to respond to ' + _.inspect(method)\n , 'expected #{this} to not respond to ' + _.inspect(method)\n );\n }\n\n Assertion.addMethod('respondTo', respondTo);\n Assertion.addMethod('respondsTo', respondTo);\n\n /**\n * ### .itself\n *\n * Sets the `itself` flag, later used by the `respondTo` assertion.\n *\n * function Foo() {}\n * Foo.bar = function() {}\n * Foo.prototype.baz = function() {}\n *\n * expect(Foo).itself.to.respondTo('bar');\n * expect(Foo).itself.not.to.respondTo('baz');\n *\n * @name itself\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('itself', function () {\n flag(this, 'itself', true);\n });\n\n /**\n * ### .satisfy(method)\n *\n * Asserts that the target passes a given truth test.\n *\n * expect(1).to.satisfy(function(num) { return num > 0; });\n *\n * @name satisfy\n * @alias satisfies\n * @param {Function} matcher\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function satisfy (matcher, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var result = matcher(obj);\n this.assert(\n result\n , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n , this.negate ? false : true\n , result\n );\n }\n\n Assertion.addMethod('satisfy', satisfy);\n Assertion.addMethod('satisfies', satisfy);\n\n /**\n * ### .closeTo(expected, delta)\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * expect(1.5).to.be.closeTo(1, 0.5);\n *\n * @name closeTo\n * @alias approximately\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function closeTo(expected, delta, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj, msg).is.a('number');\n if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n throw new Error('the arguments to closeTo or approximately must be numbers');\n }\n\n this.assert(\n Math.abs(obj - expected) <= delta\n , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n );\n }\n\n Assertion.addMethod('closeTo', closeTo);\n Assertion.addMethod('approximately', closeTo);\n\n function isSubsetOf(subset, superset, cmp) {\n return subset.every(function(elem) {\n if (!cmp) return superset.indexOf(elem) !== -1;\n\n return superset.some(function(elem2) {\n return cmp(elem, elem2);\n });\n })\n }\n\n /**\n * ### .members(set)\n *\n * Asserts that the target is a superset of `set`,\n * or that the target and `set` have the same strictly-equal (===) members.\n * Alternately, if the `deep` flag is set, set members are compared for deep\n * equality.\n *\n * expect([1, 2, 3]).to.include.members([3, 2]);\n * expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n *\n * expect([4, 2]).to.have.members([2, 4]);\n * expect([5, 2]).to.not.have.members([5, 2, 1]);\n *\n * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n *\n * @name members\n * @param {Array} set\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('members', function (subset, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj).to.be.an('array');\n new Assertion(subset).to.be.an('array');\n\n var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n if (flag(this, 'contains')) {\n return this.assert(\n isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to be a superset of #{act}'\n , 'expected #{this} to not be a superset of #{act}'\n , obj\n , subset\n );\n }\n\n this.assert(\n isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to have the same members as #{act}'\n , 'expected #{this} to not have the same members as #{act}'\n , obj\n , subset\n );\n });\n\n /**\n * ### .oneOf(list)\n *\n * Assert that a value appears somewhere in the top level of array `list`.\n *\n * expect('a').to.be.oneOf(['a', 'b', 'c']);\n * expect(9).to.not.be.oneOf(['z']);\n * expect([3]).to.not.be.oneOf([1, 2, [3]]);\n *\n * var three = [3];\n * // for object-types, contents are not compared\n * expect(three).to.not.be.oneOf([1, 2, [3]]);\n * // comparing references works\n * expect(three).to.be.oneOf([1, 2, three]);\n *\n * @name oneOf\n * @param {Array<*>} list\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function oneOf (list, msg) {\n if (msg) flag(this, 'message', msg);\n var expected = flag(this, 'object');\n new Assertion(list).to.be.an('array');\n\n this.assert(\n list.indexOf(expected) > -1\n , 'expected #{this} to be one of #{exp}'\n , 'expected #{this} to not be one of #{exp}'\n , list\n , expected\n );\n }\n\n Assertion.addMethod('oneOf', oneOf);\n\n\n /**\n * ### .change(function)\n *\n * Asserts that a function changes an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val += 3 };\n * var noChangeFn = function() { return 'foo' + 'bar'; }\n * expect(fn).to.change(obj, 'val');\n * expect(noChangeFn).to.not.change(obj, 'val')\n *\n * @name change\n * @alias changes\n * @alias Change\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertChanges (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n initial !== object[prop]\n , 'expected .' + prop + ' to change'\n , 'expected .' + prop + ' to not change'\n );\n }\n\n Assertion.addChainableMethod('change', assertChanges);\n Assertion.addChainableMethod('changes', assertChanges);\n\n /**\n * ### .increase(function)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * expect(fn).to.increase(obj, 'val');\n *\n * @name increase\n * @alias increases\n * @alias Increase\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertIncreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial > 0\n , 'expected .' + prop + ' to increase'\n , 'expected .' + prop + ' to not increase'\n );\n }\n\n Assertion.addChainableMethod('increase', assertIncreases);\n Assertion.addChainableMethod('increases', assertIncreases);\n\n /**\n * ### .decrease(function)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * expect(fn).to.decrease(obj, 'val');\n *\n * @name decrease\n * @alias decreases\n * @alias Decrease\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertDecreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial < 0\n , 'expected .' + prop + ' to decrease'\n , 'expected .' + prop + ' to not decrease'\n );\n }\n\n Assertion.addChainableMethod('decrease', assertDecreases);\n Assertion.addChainableMethod('decreases', assertDecreases);\n\n /**\n * ### .extensible\n *\n * Asserts that the target is extensible (can have new properties added to\n * it).\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect({}).to.be.extensible;\n * expect(nonExtensibleObject).to.not.be.extensible;\n * expect(sealedObject).to.not.be.extensible;\n * expect(frozenObject).to.not.be.extensible;\n *\n * @name extensible\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('extensible', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isExtensible;\n\n try {\n isExtensible = Object.isExtensible(obj);\n } catch (err) {\n if (err instanceof TypeError) isExtensible = false;\n else throw err;\n }\n\n this.assert(\n isExtensible\n , 'expected #{this} to be extensible'\n , 'expected #{this} to not be extensible'\n );\n });\n\n /**\n * ### .sealed\n *\n * Asserts that the target is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect(sealedObject).to.be.sealed;\n * expect(frozenObject).to.be.sealed;\n * expect({}).to.not.be.sealed;\n *\n * @name sealed\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('sealed', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isSealed;\n\n try {\n isSealed = Object.isSealed(obj);\n } catch (err) {\n if (err instanceof TypeError) isSealed = true;\n else throw err;\n }\n\n this.assert(\n isSealed\n , 'expected #{this} to be sealed'\n , 'expected #{this} to not be sealed'\n );\n });\n\n /**\n * ### .frozen\n *\n * Asserts that the target is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n *\n * expect(frozenObject).to.be.frozen;\n * expect({}).to.not.be.frozen;\n *\n * @name frozen\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('frozen', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isFrozen;\n\n try {\n isFrozen = Object.isFrozen(obj);\n } catch (err) {\n if (err instanceof TypeError) isFrozen = true;\n else throw err;\n }\n\n this.assert(\n isFrozen\n , 'expected #{this} to be frozen'\n , 'expected #{this} to not be frozen'\n );\n });\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n /*!\n * Chai dependencies.\n */\n\n var Assertion = chai.Assertion\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n /**\n * ### assert(expression, message)\n *\n * Write your own test expressions.\n *\n * assert('foo' !== 'bar', 'foo is not bar');\n * assert(Array.isArray([]), 'empty arrays are arrays');\n *\n * @param {Mixed} expression to test for truthiness\n * @param {String} message to display on error\n * @name assert\n * @namespace Assert\n * @api public\n */\n\n var assert = chai.assert = function (express, errmsg) {\n var test = new Assertion(null, null, chai.assert);\n test.assert(\n express\n , errmsg\n , '[ negation message unavailable ]'\n );\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure. Node.js `assert` module-compatible.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Assert\n * @api public\n */\n\n assert.fail = function (actual, expected, message, operator) {\n message = message || 'assert.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, assert.fail);\n };\n\n /**\n * ### .isOk(object, [message])\n *\n * Asserts that `object` is truthy.\n *\n * assert.isOk('everything', 'everything is ok');\n * assert.isOk(false, 'this will fail');\n *\n * @name isOk\n * @alias ok\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isOk = function (val, msg) {\n new Assertion(val, msg).is.ok;\n };\n\n /**\n * ### .isNotOk(object, [message])\n *\n * Asserts that `object` is falsy.\n *\n * assert.isNotOk('everything', 'this will fail');\n * assert.isNotOk(false, 'this will pass');\n *\n * @name isNotOk\n * @alias notOk\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotOk = function (val, msg) {\n new Assertion(val, msg).is.not.ok;\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * assert.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.equal = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.equal);\n\n test.assert(\n exp == flag(test, 'object')\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .notEqual(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * assert.notEqual(3, 4, 'these numbers are not equal');\n *\n * @name notEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notEqual = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.notEqual);\n\n test.assert(\n exp != flag(test, 'object')\n , 'expected #{this} to not equal #{exp}'\n , 'expected #{this} to equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .strictEqual(actual, expected, [message])\n *\n * Asserts strict equality (`===`) of `actual` and `expected`.\n *\n * assert.strictEqual(true, true, 'these booleans are strictly equal');\n *\n * @name strictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.strictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.equal(exp);\n };\n\n /**\n * ### .notStrictEqual(actual, expected, [message])\n *\n * Asserts strict inequality (`!==`) of `actual` and `expected`.\n *\n * assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n *\n * @name notStrictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notStrictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.equal(exp);\n };\n\n /**\n * ### .deepEqual(actual, expected, [message])\n *\n * Asserts that `actual` is deeply equal to `expected`.\n *\n * assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n *\n * @name deepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.eql(exp);\n };\n\n /**\n * ### .notDeepEqual(actual, expected, [message])\n *\n * Assert that `actual` is not deeply equal to `expected`.\n *\n * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n *\n * @name notDeepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.eql(exp);\n };\n\n /**\n * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n *\n * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n *\n * assert.isAbove(5, 2, '5 is strictly greater than 2');\n *\n * @name isAbove\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAbove\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAbove = function (val, abv, msg) {\n new Assertion(val, msg).to.be.above(abv);\n };\n\n /**\n * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n *\n * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n *\n * assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n * assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n *\n * @name isAtLeast\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtLeast\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtLeast = function (val, atlst, msg) {\n new Assertion(val, msg).to.be.least(atlst);\n };\n\n /**\n * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n *\n * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n *\n * assert.isBelow(3, 6, '3 is strictly less than 6');\n *\n * @name isBelow\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeBelow\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBelow = function (val, blw, msg) {\n new Assertion(val, msg).to.be.below(blw);\n };\n\n /**\n * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n *\n * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n *\n * assert.isAtMost(3, 6, '3 is less than or equal to 6');\n * assert.isAtMost(4, 4, '4 is less than or equal to 4');\n *\n * @name isAtMost\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtMost\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtMost = function (val, atmst, msg) {\n new Assertion(val, msg).to.be.most(atmst);\n };\n\n /**\n * ### .isTrue(value, [message])\n *\n * Asserts that `value` is true.\n *\n * var teaServed = true;\n * assert.isTrue(teaServed, 'the tea has been served');\n *\n * @name isTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isTrue = function (val, msg) {\n new Assertion(val, msg).is['true'];\n };\n\n /**\n * ### .isNotTrue(value, [message])\n *\n * Asserts that `value` is not true.\n *\n * var tea = 'tasty chai';\n * assert.isNotTrue(tea, 'great, time for tea!');\n *\n * @name isNotTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotTrue = function (val, msg) {\n new Assertion(val, msg).to.not.equal(true);\n };\n\n /**\n * ### .isFalse(value, [message])\n *\n * Asserts that `value` is false.\n *\n * var teaServed = false;\n * assert.isFalse(teaServed, 'no tea yet? hmm...');\n *\n * @name isFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFalse = function (val, msg) {\n new Assertion(val, msg).is['false'];\n };\n\n /**\n * ### .isNotFalse(value, [message])\n *\n * Asserts that `value` is not false.\n *\n * var tea = 'tasty chai';\n * assert.isNotFalse(tea, 'great, time for tea!');\n *\n * @name isNotFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFalse = function (val, msg) {\n new Assertion(val, msg).to.not.equal(false);\n };\n\n /**\n * ### .isNull(value, [message])\n *\n * Asserts that `value` is null.\n *\n * assert.isNull(err, 'there was no error');\n *\n * @name isNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNull = function (val, msg) {\n new Assertion(val, msg).to.equal(null);\n };\n\n /**\n * ### .isNotNull(value, [message])\n *\n * Asserts that `value` is not null.\n *\n * var tea = 'tasty chai';\n * assert.isNotNull(tea, 'great, time for tea!');\n *\n * @name isNotNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNull = function (val, msg) {\n new Assertion(val, msg).to.not.equal(null);\n };\n\n /**\n * ### .isNaN\n * Asserts that value is NaN\n *\n * assert.isNaN('foo', 'foo is NaN');\n *\n * @name isNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNaN = function (val, msg) {\n new Assertion(val, msg).to.be.NaN;\n };\n\n /**\n * ### .isNotNaN\n * Asserts that value is not NaN\n *\n * assert.isNotNaN(4, '4 is not NaN');\n *\n * @name isNotNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n assert.isNotNaN = function (val, msg) {\n new Assertion(val, msg).not.to.be.NaN;\n };\n\n /**\n * ### .isUndefined(value, [message])\n *\n * Asserts that `value` is `undefined`.\n *\n * var tea;\n * assert.isUndefined(tea, 'no tea defined');\n *\n * @name isUndefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isUndefined = function (val, msg) {\n new Assertion(val, msg).to.equal(undefined);\n };\n\n /**\n * ### .isDefined(value, [message])\n *\n * Asserts that `value` is not `undefined`.\n *\n * var tea = 'cup of chai';\n * assert.isDefined(tea, 'tea has been defined');\n *\n * @name isDefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isDefined = function (val, msg) {\n new Assertion(val, msg).to.not.equal(undefined);\n };\n\n /**\n * ### .isFunction(value, [message])\n *\n * Asserts that `value` is a function.\n *\n * function serveTea() { return 'cup of tea'; };\n * assert.isFunction(serveTea, 'great, we can have tea now');\n *\n * @name isFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFunction = function (val, msg) {\n new Assertion(val, msg).to.be.a('function');\n };\n\n /**\n * ### .isNotFunction(value, [message])\n *\n * Asserts that `value` is _not_ a function.\n *\n * var serveTea = [ 'heat', 'pour', 'sip' ];\n * assert.isNotFunction(serveTea, 'great, we have listed the steps');\n *\n * @name isNotFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFunction = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('function');\n };\n\n /**\n * ### .isObject(value, [message])\n *\n * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n * _The assertion does not match subclassed objects._\n *\n * var selection = { name: 'Chai', serve: 'with spices' };\n * assert.isObject(selection, 'tea selection is an object');\n *\n * @name isObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isObject = function (val, msg) {\n new Assertion(val, msg).to.be.a('object');\n };\n\n /**\n * ### .isNotObject(value, [message])\n *\n * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n *\n * var selection = 'chai'\n * assert.isNotObject(selection, 'tea selection is not an object');\n * assert.isNotObject(null, 'null is not an object');\n *\n * @name isNotObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotObject = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('object');\n };\n\n /**\n * ### .isArray(value, [message])\n *\n * Asserts that `value` is an array.\n *\n * var menu = [ 'green', 'chai', 'oolong' ];\n * assert.isArray(menu, 'what kind of tea do we want?');\n *\n * @name isArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isArray = function (val, msg) {\n new Assertion(val, msg).to.be.an('array');\n };\n\n /**\n * ### .isNotArray(value, [message])\n *\n * Asserts that `value` is _not_ an array.\n *\n * var menu = 'green|chai|oolong';\n * assert.isNotArray(menu, 'what kind of tea do we want?');\n *\n * @name isNotArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotArray = function (val, msg) {\n new Assertion(val, msg).to.not.be.an('array');\n };\n\n /**\n * ### .isString(value, [message])\n *\n * Asserts that `value` is a string.\n *\n * var teaOrder = 'chai';\n * assert.isString(teaOrder, 'order placed');\n *\n * @name isString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isString = function (val, msg) {\n new Assertion(val, msg).to.be.a('string');\n };\n\n /**\n * ### .isNotString(value, [message])\n *\n * Asserts that `value` is _not_ a string.\n *\n * var teaOrder = 4;\n * assert.isNotString(teaOrder, 'order placed');\n *\n * @name isNotString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotString = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('string');\n };\n\n /**\n * ### .isNumber(value, [message])\n *\n * Asserts that `value` is a number.\n *\n * var cups = 2;\n * assert.isNumber(cups, 'how many cups');\n *\n * @name isNumber\n * @param {Number} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNumber = function (val, msg) {\n new Assertion(val, msg).to.be.a('number');\n };\n\n /**\n * ### .isNotNumber(value, [message])\n *\n * Asserts that `value` is _not_ a number.\n *\n * var cups = '2 cups please';\n * assert.isNotNumber(cups, 'how many cups');\n *\n * @name isNotNumber\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNumber = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('number');\n };\n\n /**\n * ### .isBoolean(value, [message])\n *\n * Asserts that `value` is a boolean.\n *\n * var teaReady = true\n * , teaServed = false;\n *\n * assert.isBoolean(teaReady, 'is the tea ready');\n * assert.isBoolean(teaServed, 'has tea been served');\n *\n * @name isBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBoolean = function (val, msg) {\n new Assertion(val, msg).to.be.a('boolean');\n };\n\n /**\n * ### .isNotBoolean(value, [message])\n *\n * Asserts that `value` is _not_ a boolean.\n *\n * var teaReady = 'yep'\n * , teaServed = 'nope';\n *\n * assert.isNotBoolean(teaReady, 'is the tea ready');\n * assert.isNotBoolean(teaServed, 'has tea been served');\n *\n * @name isNotBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotBoolean = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('boolean');\n };\n\n /**\n * ### .typeOf(value, name, [message])\n *\n * Asserts that `value`'s type is `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n * assert.typeOf('tea', 'string', 'we have a string');\n * assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n * assert.typeOf(null, 'null', 'we have a null');\n * assert.typeOf(undefined, 'undefined', 'we have an undefined');\n *\n * @name typeOf\n * @param {Mixed} value\n * @param {String} name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.typeOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.a(type);\n };\n\n /**\n * ### .notTypeOf(value, name, [message])\n *\n * Asserts that `value`'s type is _not_ `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.notTypeOf('tea', 'number', 'strings are not numbers');\n *\n * @name notTypeOf\n * @param {Mixed} value\n * @param {String} typeof name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notTypeOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.a(type);\n };\n\n /**\n * ### .instanceOf(object, constructor, [message])\n *\n * Asserts that `value` is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new Tea('chai');\n *\n * assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n *\n * @name instanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.instanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.instanceOf(type);\n };\n\n /**\n * ### .notInstanceOf(object, constructor, [message])\n *\n * Asserts `value` is not an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new String('chai');\n *\n * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n *\n * @name notInstanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInstanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.instanceOf(type);\n };\n\n /**\n * ### .include(haystack, needle, [message])\n *\n * Asserts that `haystack` includes `needle`. Works\n * for strings and arrays.\n *\n * assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n * assert.include([ 1, 2, 3 ], 3, 'array contains value');\n *\n * @name include\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.include = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.include).include(inc);\n };\n\n /**\n * ### .notInclude(haystack, needle, [message])\n *\n * Asserts that `haystack` does not include `needle`. Works\n * for strings and arrays.\n *\n * assert.notInclude('foobar', 'baz', 'string not include substring');\n * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n *\n * @name notInclude\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInclude = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.notInclude).not.include(inc);\n };\n\n /**\n * ### .match(value, regexp, [message])\n *\n * Asserts that `value` matches the regular expression `regexp`.\n *\n * assert.match('foobar', /^foo/, 'regexp matches');\n *\n * @name match\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.match = function (exp, re, msg) {\n new Assertion(exp, msg).to.match(re);\n };\n\n /**\n * ### .notMatch(value, regexp, [message])\n *\n * Asserts that `value` does not match the regular expression `regexp`.\n *\n * assert.notMatch('foobar', /^foo/, 'regexp does not match');\n *\n * @name notMatch\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notMatch = function (exp, re, msg) {\n new Assertion(exp, msg).to.not.match(re);\n };\n\n /**\n * ### .property(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`.\n *\n * assert.property({ tea: { green: 'matcha' }}, 'tea');\n *\n * @name property\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.property = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.property(prop);\n };\n\n /**\n * ### .notProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`.\n *\n * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n *\n * @name notProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.property(prop);\n };\n\n /**\n * ### .deepProperty(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`, which can be a\n * string using dot- and bracket-notation for deep reference.\n *\n * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n *\n * @name deepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop);\n };\n\n /**\n * ### .notDeepProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`, which\n * can be a string using dot- and bracket-notation for deep reference.\n *\n * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n *\n * @name notDeepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop);\n };\n\n /**\n * ### .propertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`.\n *\n * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n *\n * @name propertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.property(prop, val);\n };\n\n /**\n * ### .propertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`.\n *\n * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n *\n * @name propertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.property(prop, val);\n };\n\n /**\n * ### .deepPropertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`. `property` can use dot- and bracket-notation for deep\n * reference.\n *\n * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n *\n * @name deepPropertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop, val);\n };\n\n /**\n * ### .deepPropertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`. `property` can use dot- and\n * bracket-notation for deep reference.\n *\n * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n *\n * @name deepPropertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n };\n\n /**\n * ### .lengthOf(object, length, [message])\n *\n * Asserts that `object` has a `length` property with the expected value.\n *\n * assert.lengthOf([1,2,3], 3, 'array has length of 3');\n * assert.lengthOf('foobar', 6, 'string has length of 6');\n *\n * @name lengthOf\n * @param {Mixed} object\n * @param {Number} length\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.lengthOf = function (exp, len, msg) {\n new Assertion(exp, msg).to.have.length(len);\n };\n\n /**\n * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * assert.throws(fn, 'function throws a reference error');\n * assert.throws(fn, /function throws a reference error/);\n * assert.throws(fn, ReferenceError);\n * assert.throws(fn, ReferenceError, 'function throws a reference error');\n * assert.throws(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throws\n * @alias throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.throws = function (fn, errt, errs, msg) {\n if ('string' === typeof errt || errt instanceof RegExp) {\n errs = errt;\n errt = null;\n }\n\n var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n return flag(assertErr, 'object');\n };\n\n /**\n * ### .doesNotThrow(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * assert.doesNotThrow(fn, Error, 'function does not throw');\n *\n * @name doesNotThrow\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotThrow = function (fn, type, msg) {\n if ('string' === typeof type) {\n msg = type;\n type = null;\n }\n\n new Assertion(fn, msg).to.not.Throw(type);\n };\n\n /**\n * ### .operator(val1, operator, val2, [message])\n *\n * Compares two values using `operator`.\n *\n * assert.operator(1, '<', 2, 'everything is ok');\n * assert.operator(1, '>', 2, 'this will fail');\n *\n * @name operator\n * @param {Mixed} val1\n * @param {String} operator\n * @param {Mixed} val2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.operator = function (val, operator, val2, msg) {\n var ok;\n switch(operator) {\n case '==':\n ok = val == val2;\n break;\n case '===':\n ok = val === val2;\n break;\n case '>':\n ok = val > val2;\n break;\n case '>=':\n ok = val >= val2;\n break;\n case '<':\n ok = val < val2;\n break;\n case '<=':\n ok = val <= val2;\n break;\n case '!=':\n ok = val != val2;\n break;\n case '!==':\n ok = val !== val2;\n break;\n default:\n throw new Error('Invalid operator \"' + operator + '\"');\n }\n var test = new Assertion(ok, msg);\n test.assert(\n true === flag(test, 'object')\n , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n };\n\n /**\n * ### .closeTo(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n *\n * @name closeTo\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.closeTo = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.closeTo(exp, delta);\n };\n\n /**\n * ### .approximately(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.approximately(1.5, 1, 0.5, 'numbers are close');\n *\n * @name approximately\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.approximately = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.approximately(exp, delta);\n };\n\n /**\n * ### .sameMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members.\n * Order is not taken into account.\n *\n * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n *\n * @name sameMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.members(set2);\n }\n\n /**\n * ### .sameDeepMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n * Order is not taken into account.\n *\n * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n *\n * @name sameDeepMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameDeepMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.deep.members(set2);\n }\n\n /**\n * ### .includeMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset`.\n * Order is not taken into account.\n *\n * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n *\n * @name includeMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.members(subset);\n }\n\n /**\n * ### .includeDeepMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset` - using deep equality checking.\n * Order is not taken into account.\n * Duplicates are ignored.\n *\n * assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n *\n * @name includeDeepMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeDeepMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.deep.members(subset);\n }\n\n /**\n * ### .oneOf(inList, list, [message])\n *\n * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n *\n * assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n *\n * @name oneOf\n * @param {*} inList\n * @param {Array<*>} list\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.oneOf = function (inList, list, msg) {\n new Assertion(inList, msg).to.be.oneOf(list);\n }\n\n /**\n * ### .changes(function, object, property)\n *\n * Asserts that a function changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 22 };\n * assert.changes(fn, obj, 'val');\n *\n * @name changes\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.changes = function (fn, obj, prop) {\n new Assertion(fn).to.change(obj, prop);\n }\n\n /**\n * ### .doesNotChange(function, object, property)\n *\n * Asserts that a function does not changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { console.log('foo'); };\n * assert.doesNotChange(fn, obj, 'val');\n *\n * @name doesNotChange\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotChange = function (fn, obj, prop) {\n new Assertion(fn).to.not.change(obj, prop);\n }\n\n /**\n * ### .increases(function, object, property)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 13 };\n * assert.increases(fn, obj, 'val');\n *\n * @name increases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.increases = function (fn, obj, prop) {\n new Assertion(fn).to.increase(obj, prop);\n }\n\n /**\n * ### .doesNotIncrease(function, object, property)\n *\n * Asserts that a function does not increase object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 8 };\n * assert.doesNotIncrease(fn, obj, 'val');\n *\n * @name doesNotIncrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotIncrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.increase(obj, prop);\n }\n\n /**\n * ### .decreases(function, object, property)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * assert.decreases(fn, obj, 'val');\n *\n * @name decreases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.decreases = function (fn, obj, prop) {\n new Assertion(fn).to.decrease(obj, prop);\n }\n\n /**\n * ### .doesNotDecrease(function, object, property)\n *\n * Asserts that a function does not decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * assert.doesNotDecrease(fn, obj, 'val');\n *\n * @name doesNotDecrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotDecrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.decrease(obj, prop);\n }\n\n /*!\n * ### .ifError(object)\n *\n * Asserts if value is not a false value, and throws if it is a true value.\n * This is added to allow for chai to be a drop-in replacement for Node's\n * assert class.\n *\n * var err = new Error('I am a custom error');\n * assert.ifError(err); // Rethrows err!\n *\n * @name ifError\n * @param {Object} object\n * @namespace Assert\n * @api public\n */\n\n assert.ifError = function (val) {\n if (val) {\n throw(val);\n }\n };\n\n /**\n * ### .isExtensible(object)\n *\n * Asserts that `object` is extensible (can have new properties added to it).\n *\n * assert.isExtensible({});\n *\n * @name isExtensible\n * @alias extensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.be.extensible;\n };\n\n /**\n * ### .isNotExtensible(object)\n *\n * Asserts that `object` is _not_ extensible.\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freese({});\n *\n * assert.isNotExtensible(nonExtensibleObject);\n * assert.isNotExtensible(sealedObject);\n * assert.isNotExtensible(frozenObject);\n *\n * @name isNotExtensible\n * @alias notExtensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.extensible;\n };\n\n /**\n * ### .isSealed(object)\n *\n * Asserts that `object` is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.seal({});\n *\n * assert.isSealed(sealedObject);\n * assert.isSealed(frozenObject);\n *\n * @name isSealed\n * @alias sealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isSealed = function (obj, msg) {\n new Assertion(obj, msg).to.be.sealed;\n };\n\n /**\n * ### .isNotSealed(object)\n *\n * Asserts that `object` is _not_ sealed.\n *\n * assert.isNotSealed({});\n *\n * @name isNotSealed\n * @alias notSealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotSealed = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.sealed;\n };\n\n /**\n * ### .isFrozen(object)\n *\n * Asserts that `object` is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n * assert.frozen(frozenObject);\n *\n * @name isFrozen\n * @alias frozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.be.frozen;\n };\n\n /**\n * ### .isNotFrozen(object)\n *\n * Asserts that `object` is _not_ frozen.\n *\n * assert.isNotFrozen({});\n *\n * @name isNotFrozen\n * @alias notFrozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.frozen;\n };\n\n /*!\n * Aliases.\n */\n\n (function alias(name, as){\n assert[as] = assert[name];\n return alias;\n })\n ('isOk', 'ok')\n ('isNotOk', 'notOk')\n ('throws', 'throw')\n ('throws', 'Throw')\n ('isExtensible', 'extensible')\n ('isNotExtensible', 'notExtensible')\n ('isSealed', 'sealed')\n ('isNotSealed', 'notSealed')\n ('isFrozen', 'frozen')\n ('isNotFrozen', 'notFrozen');\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n chai.expect = function (val, message) {\n return new chai.Assertion(val, message);\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Expect\n * @api public\n */\n\n chai.expect.fail = function (actual, expected, message, operator) {\n message = message || 'expect.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, chai.expect.fail);\n };\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n var Assertion = chai.Assertion;\n\n function loadShould () {\n // explicitly define this method as function as to have it's name to include as `ssfi`\n function shouldGetter() {\n if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n return new Assertion(this.valueOf(), null, shouldGetter);\n }\n return new Assertion(this, null, shouldGetter);\n }\n function shouldSetter(value) {\n // See https://github.com/chaijs/chai/issues/86: this makes\n // `whatever.should = someValue` actually set `someValue`, which is\n // especially useful for `global.should = require('chai').should()`.\n //\n // Note that we have to use [[DefineProperty]] instead of [[Put]]\n // since otherwise we would trigger this very setter!\n Object.defineProperty(this, 'should', {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n }\n // modify Object.prototype to have `should`\n Object.defineProperty(Object.prototype, 'should', {\n set: shouldSetter\n , get: shouldGetter\n , configurable: true\n });\n\n var should = {};\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Should\n * @api public\n */\n\n should.fail = function (actual, expected, message, operator) {\n message = message || 'should.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, should.fail);\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * should.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * should.throw(fn, 'function throws a reference error');\n * should.throw(fn, /function throws a reference error/);\n * should.throw(fn, ReferenceError);\n * should.throw(fn, ReferenceError, 'function throws a reference error');\n * should.throw(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.Throw(errt, errs);\n };\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi';\n *\n * should.exist(foo, 'foo exists');\n *\n * @name exist\n * @namespace Should\n * @api public\n */\n\n should.exist = function (val, msg) {\n new Assertion(val, msg).to.exist;\n }\n\n // negation\n should.not = {}\n\n /**\n * ### .not.equal(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * should.not.equal(3, 4, 'these numbers are not equal');\n *\n * @name not.equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.not.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.not.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * should.not.throw(fn, Error, 'function does not throw');\n *\n * @name not.throw\n * @alias not.Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.not.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.not.Throw(errt, errs);\n };\n\n /**\n * ### .not.exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var bar = null;\n *\n * should.not.exist(bar, 'bar does not exist');\n *\n * @name not.exist\n * @namespace Should\n * @api public\n */\n\n should.not.exist = function (val, msg) {\n new Assertion(val, msg).to.not.exist;\n }\n\n should['throw'] = should['Throw'];\n should.not['throw'] = should.not['Throw'];\n\n return should;\n };\n\n chai.should = loadShould;\n chai.Should = loadShould;\n};\n","/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call = Function.prototype.call,\n apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n * expect(fooStr).to.be.foo('bar');\n * expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n if (typeof chainingBehavior !== 'function') {\n chainingBehavior = function () { };\n }\n\n var chainableBehavior = {\n method: method\n , chainingBehavior: chainingBehavior\n };\n\n // save the methods so we can overwrite them later, if we need to.\n if (!ctx.__methods) {\n ctx.__methods = {};\n }\n ctx.__methods[name] = chainableBehavior;\n\n Object.defineProperty(ctx, name,\n { get: function () {\n chainableBehavior.chainingBehavior.call(this);\n\n var assert = function assert() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', assert);\n var result = chainableBehavior.method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n\n // Use `__proto__` if available\n if (hasProtoSupport) {\n // Inherit all properties from the object by replacing the `Function` prototype\n var prototype = assert.__proto__ = Object.create(this);\n // Restore the `call` and `apply` methods from `Function`\n prototype.call = call;\n prototype.apply = apply;\n }\n // Otherwise, redefine all properties (slow!)\n else {\n var asserterNames = Object.getOwnPropertyNames(ctx);\n asserterNames.forEach(function (asserterName) {\n if (!excludeNames.test(asserterName)) {\n var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n Object.defineProperty(assert, asserterName, pd);\n }\n });\n }\n\n transferFlags(this, assert);\n return assert;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n ctx[name] = function () {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', ctx[name]);\n var result = method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n * utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.instanceof(Foo);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n Object.defineProperty(ctx, name,\n { get: function addProperty() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', addProperty);\n\n var result = getter.call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n * utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n var obj = flag(obj, 'object');\n types = types.map(function (t) { return t.toLowerCase(); });\n types.sort();\n\n // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n var str = types.map(function (t, index) {\n var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n return or + art + ' ' + t;\n }).join(', ');\n\n if (!types.some(function (expected) { return type(obj) === expected; })) {\n throw new AssertionError(\n 'object tested must be ' + str + ', but ' + type(obj) + ' given'\n );\n }\n};\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n * utils.flag(this, 'foo', 'bar'); // setter\n * utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n var flags = obj.__flags || (obj.__flags = Object.create(null));\n if (arguments.length === 3) {\n flags[key] = value;\n } else {\n return flags[key];\n }\n};\n","/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n return args.length > 4 ? args[4] : obj._obj;\n};\n","/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n var result = [];\n for (var name in object) {\n result.push(name);\n }\n return result;\n};\n","/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n , getActual = require('./getActual')\n , inspect = require('./inspect')\n , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , val = flag(obj, 'object')\n , expected = args[3]\n , actual = getActual(obj, args)\n , msg = negate ? args[2] : args[1]\n , flagMsg = flag(obj, 'message');\n\n if(typeof msg === \"function\") msg = msg();\n msg = msg || '';\n msg = msg\n .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n","/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n if (func.name) return func.name;\n\n var match = /^\\s?function ([^(]*)\\(/.exec(func);\n return match && match[1] ? match[1] : \"\";\n};\n","/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n var parsed = parsePath(path),\n last = parsed[parsed.length - 1];\n\n var info = {\n parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n name: last.p || last.i,\n value: _getPathValue(parsed, obj)\n };\n info.exists = hasProperty(info.name, info.parent);\n\n return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n * var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n return parts.map(function (value) {\n var re = /^\\[(\\d+)\\]$/\n , mArr = re.exec(value);\n if (mArr) return { i: parseFloat(mArr[1]) };\n else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n * var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n var tmp = obj\n , res;\n\n index = (index === undefined ? parsed.length : index);\n\n for (var i = 0, l = index; i < l; i++) {\n var part = parsed[i];\n if (tmp) {\n if ('undefined' !== typeof part.p)\n tmp = tmp[part.p];\n else if ('undefined' !== typeof part.i)\n tmp = tmp[part.i];\n if (i == (l - 1)) res = tmp;\n } else {\n res = undefined;\n }\n }\n return res;\n}\n","/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer \n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n * var obj = {\n * prop1: {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n * , prop2: {\n * arr: [ { nested: 'Universe' } ]\n * , str: 'Hello again!'\n * }\n * }\n *\n * The following would be the results.\n *\n * getPathValue('prop1.str', obj); // Hello\n * getPathValue('prop1.att[2]', obj); // b\n * getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n var info = getPathInfo(path, obj);\n return info.value;\n};\n","/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n var result = Object.getOwnPropertyNames(object);\n\n function addProperty(property) {\n if (result.indexOf(property) === -1) {\n result.push(property);\n }\n }\n\n var proto = Object.getPrototypeOf(object);\n while (proto !== null) {\n Object.getOwnPropertyNames(proto).forEach(addProperty);\n proto = Object.getPrototypeOf(proto);\n }\n\n return result;\n};\n","/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n * var obj = {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n *\n * The following would be the results.\n *\n * hasProperty('str', obj); // true\n * hasProperty('constructor', obj); // true\n * hasProperty('bar', obj); // false\n *\n * hasProperty('length', obj.str); // true\n * hasProperty(1, obj.str); // true\n * hasProperty(5, obj.str); // false\n *\n * hasProperty('length', obj.arr); // true\n * hasProperty(2, obj.arr); // true\n * hasProperty(3, obj.arr); // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n 'number': Number\n , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n var ot = type(obj);\n\n // Bad Object, obviously no props at all\n if(ot === 'null' || ot === 'undefined')\n return false;\n\n // The `in` operator does not work with certain literals\n // box these before the check\n if(literals[ot] && typeof obj !== 'object')\n obj = new literals[ot](obj);\n\n return name in obj;\n};\n","/*!\n * chai\n * Copyright(c) 2011 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n","// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n * properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n * output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n var ctx = {\n showHidden: showHidden,\n seen: [],\n stylize: function (str) { return str; }\n };\n return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n if (typeof HTMLElement === 'object') {\n return object instanceof HTMLElement;\n } else {\n return object &&\n typeof object === 'object' &&\n object.nodeType === 1 &&\n typeof object.nodeName === 'string';\n }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (value && typeof value.inspect === 'function' &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes);\n if (typeof ret !== 'string') {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // If this is a DOM element, try to get the outer HTML.\n if (isDOMElement(value)) {\n if ('outerHTML' in value) {\n return value.outerHTML;\n // This value does not have an outerHTML attribute,\n // it could still be an XML element\n } else {\n // Attempt to serialize it\n try {\n if (document.xmlVersion) {\n var xmlSerializer = new XMLSerializer();\n return xmlSerializer.serializeToString(value);\n } else {\n // Firefox 11- do not support outerHTML\n // It does, however, support innerHTML\n // Use the following to render the element\n var ns = \"http://www.w3.org/1999/xhtml\";\n var container = document.createElementNS(ns, '_');\n\n container.appendChild(value.cloneNode(false));\n html = container.innerHTML\n .replace('><', '>' + value.innerHTML + '<');\n container.innerHTML = '';\n return html;\n }\n } catch (err) {\n // This could be a non-native DOM implementation,\n // continue with the normal flow:\n // printing the element as if it is an object.\n }\n }\n }\n\n // Look up the keys of the object.\n var visibleKeys = getEnumerableProperties(value);\n var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n // Some type of object without properties can be shortcutted.\n // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n // a `stack` plus `description` property; ignore those for consistency.\n if (keys.length === 0 || (isError(value) && (\n (keys.length === 1 && keys[0] === 'stack') ||\n (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n ))) {\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n base = ' [Function' + nameSuffix + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n return formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n switch (typeof value) {\n case 'undefined':\n return ctx.stylize('undefined', 'undefined');\n\n case 'string':\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n\n case 'number':\n if (value === 0 && (1/value) === -Infinity) {\n return ctx.stylize('-0', 'number');\n }\n return ctx.stylize('' + value, 'number');\n\n case 'boolean':\n return ctx.stylize('' + value, 'boolean');\n }\n // For some reason typeof null is \"object\", so special case here.\n if (value === null) {\n return ctx.stylize('null', 'null');\n }\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str;\n if (value.__lookupGetter__) {\n if (value.__lookupGetter__(key)) {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n }\n if (visibleKeys.indexOf(key) < 0) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(value[key]) < 0) {\n if (recurseTimes === null) {\n str = formatValue(ctx, value[key], null);\n } else {\n str = formatValue(ctx, value[key], recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (typeof name === 'undefined') {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n return Array.isArray(ar) ||\n (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n var str = inspect(obj)\n , type = Object.prototype.toString.call(obj);\n\n if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n if (type === '[object Function]') {\n return !obj.name || obj.name === ''\n ? '[Function]'\n : '[Function: ' + obj.name + ']';\n } else if (type === '[object Array]') {\n return '[ Array(' + obj.length + ') ]';\n } else if (type === '[object Object]') {\n var keys = Object.keys(obj)\n , kstr = keys.length > 2\n ? keys.splice(0, 2).join(', ') + ', ...'\n : keys.join(', ');\n return '{ Object (' + kstr + ') }';\n } else {\n return str;\n }\n } else {\n return str;\n }\n};\n","/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property. Must return functions to be used for\n * name.\n *\n * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n * function (_super) {\n * }\n * , function (_super) {\n * }\n * );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.have.length(3);\n * expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n var chainableBehavior = ctx.__methods[name];\n\n var _chainingBehavior = chainableBehavior.chainingBehavior;\n chainableBehavior.chainingBehavior = function () {\n var result = chainingBehavior(_chainingBehavior).call(this);\n return result === undefined ? this : result;\n };\n\n var _method = chainableBehavior.method;\n chainableBehavior.method = function () {\n var result = method(_method).apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n * return function (str) {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.value).to.equal(str);\n * } else {\n * _super.apply(this, arguments);\n * }\n * }\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n var _method = ctx[name]\n , _super = function () { return this; };\n\n if (_method && 'function' === typeof _method)\n _super = _method;\n\n ctx[name] = function () {\n var result = method(_super).apply(this, arguments);\n return result === undefined ? this : result;\n }\n};\n","/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n * return function () {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.name).to.equal('bar');\n * } else {\n * _super.call(this);\n * }\n * }\n * });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n var _get = Object.getOwnPropertyDescriptor(ctx, name)\n , _super = function () {};\n\n if (_get && 'function' === typeof _get.get)\n _super = _get.get\n\n Object.defineProperty(ctx, name,\n { get: function () {\n var result = getter(_super).call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , expr = args[0];\n return negate ? !expr : expr;\n};\n","/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n * var newAssertion = new Assertion();\n * utils.transferFlags(assertion, newAssertion);\n *\n * var anotherAsseriton = new Assertion(myObj);\n * utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n if (!object.__flags) {\n object.__flags = Object.create(null);\n }\n\n includeAll = arguments.length === 3 ? includeAll : true;\n\n for (var flag in flags) {\n if (includeAll ||\n (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n object.__flags[flag] = flags[flag];\n }\n }\n};\n","\"use strict\";\n\nfunction dedent(strings) {\n\n var raw = void 0;\n if (typeof strings === \"string\") {\n // dedent can be used as a plain function\n raw = [strings];\n } else {\n raw = strings.raw;\n }\n\n // first, perform interpolation\n var result = \"\";\n for (var i = 0; i < raw.length; i++) {\n result += raw[i].\n // join lines when there is a suppressed newline\n replace(/\\\\\\n[ \\t]*/g, \"\").\n\n // handle escaped backticks\n replace(/\\\\`/g, \"`\");\n\n if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) {\n result += arguments.length <= i + 1 ? undefined : arguments[i + 1];\n }\n }\n\n // now strip indentation\n var lines = result.split(\"\\n\");\n var mindent = null;\n lines.forEach(function (l) {\n var m = l.match(/^(\\s+)\\S+/);\n if (m) {\n var indent = m[1].length;\n if (!mindent) {\n // this is the first indented line\n mindent = indent;\n } else {\n mindent = Math.min(mindent, indent);\n }\n }\n });\n\n if (mindent !== null) {\n result = lines.map(function (l) {\n return l[0] === \" \" ? l.slice(mindent) : l;\n }).join(\"\\n\");\n }\n\n // dedent eats leading and trailing whitespace too\n result = result.trim();\n\n // handle escaped newlines at the end to ensure they don't get stripped too\n return result.replace(/\\\\n/g, \"\\n\");\n}\n\nif (typeof module !== \"undefined\") {\n module.exports = dedent;\n}\n","module.exports = require('./lib/eql');\n","/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n Buffer = {};\n Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n if (sameValue(a, b)) {\n return true;\n } else if ('date' === type(a)) {\n return dateEqual(a, b);\n } else if ('regexp' === type(a)) {\n return regexpEqual(a, b);\n } else if (Buffer.isBuffer(a)) {\n return bufferEqual(a, b);\n } else if ('arguments' === type(a)) {\n return argumentsEqual(a, b, m);\n } else if (!typeEqual(a, b)) {\n return false;\n } else if (('object' !== type(a) && 'object' !== type(b))\n && ('array' !== type(a) && 'array' !== type(b))) {\n return sameValue(a, b);\n } else {\n return objectEqual(a, b, m);\n }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n if (a === b) return a !== 0 || 1 / a === 1 / b;\n return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n if ('date' !== type(b)) return false;\n return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n if ('regexp' !== type(b)) return false;\n return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n if ('arguments' !== type(b)) return false;\n a = [].slice.call(a);\n b = [].slice.call(b);\n return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n var res = [];\n for (var key in a) res.push(key);\n return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n if (a.length !== b.length) return false;\n\n var i = 0;\n var match = true;\n\n for (; i < a.length; i++) {\n if (a[i] !== b[i]) {\n match = false;\n break;\n }\n }\n\n return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n if (!Buffer.isBuffer(b)) return false;\n return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n if (!isValue(a) || !isValue(b)) {\n return false;\n }\n\n if (a.prototype !== b.prototype) {\n return false;\n }\n\n var i;\n if (m) {\n for (i = 0; i < m.length; i++) {\n if ((m[i][0] === a && m[i][1] === b)\n || (m[i][0] === b && m[i][1] === a)) {\n return true;\n }\n }\n } else {\n m = [];\n }\n\n try {\n var ka = enumerable(a);\n var kb = enumerable(b);\n } catch (ex) {\n return false;\n }\n\n ka.sort();\n kb.sort();\n\n if (!iterableEqual(ka, kb)) {\n return false;\n }\n\n m.push([ a, b ]);\n\n var key;\n for (i = ka.length - 1; i >= 0; i--) {\n key = ka[i];\n if (!deepEqual(a[key], b[key], m)) {\n return false;\n }\n }\n\n return true;\n}\n","/*!\n localForage -- Offline Storage, Improved\n Version 1.5.0\n https://localforage.github.io/localForage\n (c) 2013-2017 Mozilla, Apache License 2.0\n*/\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.localforage = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw (f.code=\"MODULE_NOT_FOUND\", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o element; its readystatechange event will be fired asynchronously once it is inserted\n // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.\n var scriptEl = global.document.createElement('script');\n scriptEl.onreadystatechange = function () {\n nextTick();\n\n scriptEl.onreadystatechange = null;\n scriptEl.parentNode.removeChild(scriptEl);\n scriptEl = null;\n };\n global.document.documentElement.appendChild(scriptEl);\n };\n } else {\n scheduleDrain = function () {\n setTimeout(nextTick, 0);\n };\n }\n}\n\nvar draining;\nvar queue = [];\n//named nextTick for less confusing stack traces\nfunction nextTick() {\n draining = true;\n var i, oldQueue;\n var len = queue.length;\n while (len) {\n oldQueue = queue;\n queue = [];\n i = -1;\n while (++i < len) {\n oldQueue[i]();\n }\n len = queue.length;\n }\n draining = false;\n}\n\nmodule.exports = immediate;\nfunction immediate(task) {\n if (queue.push(task) === 1 && !draining) {\n scheduleDrain();\n }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],2:[function(_dereq_,module,exports){\n'use strict';\nvar immediate = _dereq_(1);\n\n/* istanbul ignore next */\nfunction INTERNAL() {}\n\nvar handlers = {};\n\nvar REJECTED = ['REJECTED'];\nvar FULFILLED = ['FULFILLED'];\nvar PENDING = ['PENDING'];\n\nmodule.exports = exports = Promise;\n\nfunction Promise(resolver) {\n if (typeof resolver !== 'function') {\n throw new TypeError('resolver must be a function');\n }\n this.state = PENDING;\n this.queue = [];\n this.outcome = void 0;\n if (resolver !== INTERNAL) {\n safelyResolveThenable(this, resolver);\n }\n}\n\nPromise.prototype[\"catch\"] = function (onRejected) {\n return this.then(null, onRejected);\n};\nPromise.prototype.then = function (onFulfilled, onRejected) {\n if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||\n typeof onRejected !== 'function' && this.state === REJECTED) {\n return this;\n }\n var promise = new this.constructor(INTERNAL);\n if (this.state !== PENDING) {\n var resolver = this.state === FULFILLED ? onFulfilled : onRejected;\n unwrap(promise, resolver, this.outcome);\n } else {\n this.queue.push(new QueueItem(promise, onFulfilled, onRejected));\n }\n\n return promise;\n};\nfunction QueueItem(promise, onFulfilled, onRejected) {\n this.promise = promise;\n if (typeof onFulfilled === 'function') {\n this.onFulfilled = onFulfilled;\n this.callFulfilled = this.otherCallFulfilled;\n }\n if (typeof onRejected === 'function') {\n this.onRejected = onRejected;\n this.callRejected = this.otherCallRejected;\n }\n}\nQueueItem.prototype.callFulfilled = function (value) {\n handlers.resolve(this.promise, value);\n};\nQueueItem.prototype.otherCallFulfilled = function (value) {\n unwrap(this.promise, this.onFulfilled, value);\n};\nQueueItem.prototype.callRejected = function (value) {\n handlers.reject(this.promise, value);\n};\nQueueItem.prototype.otherCallRejected = function (value) {\n unwrap(this.promise, this.onRejected, value);\n};\n\nfunction unwrap(promise, func, value) {\n immediate(function () {\n var returnValue;\n try {\n returnValue = func(value);\n } catch (e) {\n return handlers.reject(promise, e);\n }\n if (returnValue === promise) {\n handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));\n } else {\n handlers.resolve(promise, returnValue);\n }\n });\n}\n\nhandlers.resolve = function (self, value) {\n var result = tryCatch(getThen, value);\n if (result.status === 'error') {\n return handlers.reject(self, result.value);\n }\n var thenable = result.value;\n\n if (thenable) {\n safelyResolveThenable(self, thenable);\n } else {\n self.state = FULFILLED;\n self.outcome = value;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callFulfilled(value);\n }\n }\n return self;\n};\nhandlers.reject = function (self, error) {\n self.state = REJECTED;\n self.outcome = error;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callRejected(error);\n }\n return self;\n};\n\nfunction getThen(obj) {\n // Make sure we only access the accessor once as required by the spec\n var then = obj && obj.then;\n if (obj && typeof obj === 'object' && typeof then === 'function') {\n return function appyThen() {\n then.apply(obj, arguments);\n };\n }\n}\n\nfunction safelyResolveThenable(self, thenable) {\n // Either fulfill, reject or reject with error\n var called = false;\n function onError(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.reject(self, value);\n }\n\n function onSuccess(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.resolve(self, value);\n }\n\n function tryToUnwrap() {\n thenable(onSuccess, onError);\n }\n\n var result = tryCatch(tryToUnwrap);\n if (result.status === 'error') {\n onError(result.value);\n }\n}\n\nfunction tryCatch(func, value) {\n var out = {};\n try {\n out.value = func(value);\n out.status = 'success';\n } catch (e) {\n out.status = 'error';\n out.value = e;\n }\n return out;\n}\n\nexports.resolve = resolve;\nfunction resolve(value) {\n if (value instanceof this) {\n return value;\n }\n return handlers.resolve(new this(INTERNAL), value);\n}\n\nexports.reject = reject;\nfunction reject(reason) {\n var promise = new this(INTERNAL);\n return handlers.reject(promise, reason);\n}\n\nexports.all = all;\nfunction all(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var values = new Array(len);\n var resolved = 0;\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n allResolver(iterable[i], i);\n }\n return promise;\n function allResolver(value, i) {\n self.resolve(value).then(resolveFromAll, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n function resolveFromAll(outValue) {\n values[i] = outValue;\n if (++resolved === len && !called) {\n called = true;\n handlers.resolve(promise, values);\n }\n }\n }\n}\n\nexports.race = race;\nfunction race(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n resolver(iterable[i]);\n }\n return promise;\n function resolver(value) {\n self.resolve(value).then(function (response) {\n if (!called) {\n called = true;\n handlers.resolve(promise, response);\n }\n }, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n }\n}\n\n},{\"1\":1}],3:[function(_dereq_,module,exports){\n(function (global){\n'use strict';\nif (typeof global.Promise !== 'function') {\n global.Promise = _dereq_(2);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"2\":2}],4:[function(_dereq_,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction getIDB() {\n /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */\n try {\n if (typeof indexedDB !== 'undefined') {\n return indexedDB;\n }\n if (typeof webkitIndexedDB !== 'undefined') {\n return webkitIndexedDB;\n }\n if (typeof mozIndexedDB !== 'undefined') {\n return mozIndexedDB;\n }\n if (typeof OIndexedDB !== 'undefined') {\n return OIndexedDB;\n }\n if (typeof msIndexedDB !== 'undefined') {\n return msIndexedDB;\n }\n } catch (e) {}\n}\n\nvar idb = getIDB();\n\nfunction isIndexedDBValid() {\n try {\n // Initialize IndexedDB; fall back to vendor-prefixed versions\n // if needed.\n if (!idb) {\n return false;\n }\n // We mimic PouchDB here;\n //\n // We test for openDatabase because IE Mobile identifies itself\n // as Safari. Oh the lulz...\n var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform);\n\n var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1;\n\n // Safari <10.1 does not meet our requirements for IDB support (#5572)\n // since Safari 10.1 shipped with fetch, we can use that to detect it\n return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' &&\n // some outdated implementations of IDB that appear on Samsung\n // and HTC Android devices <4.4 are missing IDBKeyRange\n typeof IDBKeyRange !== 'undefined';\n } catch (e) {\n return false;\n }\n}\n\nfunction isWebSQLValid() {\n return typeof openDatabase === 'function';\n}\n\nfunction isLocalStorageValid() {\n try {\n return typeof localStorage !== 'undefined' && 'setItem' in localStorage && localStorage.setItem;\n } catch (e) {\n return false;\n }\n}\n\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\nfunction createBlob(parts, properties) {\n /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */\n parts = parts || [];\n properties = properties || {};\n try {\n return new Blob(parts, properties);\n } catch (e) {\n if (e.name !== 'TypeError') {\n throw e;\n }\n var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder;\n var builder = new Builder();\n for (var i = 0; i < parts.length; i += 1) {\n builder.append(parts[i]);\n }\n return builder.getBlob(properties.type);\n }\n}\n\n// This is CommonJS because lie is an external dependency, so Rollup\n// can just ignore it.\nif (typeof Promise === 'undefined') {\n // In the \"nopromises\" build this will just throw if you don't have\n // a global promise object, but it would throw anyway later.\n _dereq_(3);\n}\nvar Promise$1 = Promise;\n\nfunction executeCallback(promise, callback) {\n if (callback) {\n promise.then(function (result) {\n callback(null, result);\n }, function (error) {\n callback(error);\n });\n }\n}\n\nfunction executeTwoCallbacks(promise, callback, errorCallback) {\n if (typeof callback === 'function') {\n promise.then(callback);\n }\n\n if (typeof errorCallback === 'function') {\n promise[\"catch\"](errorCallback);\n }\n}\n\n// Some code originally from async_storage.js in\n// [Gaia](https://github.com/mozilla-b2g/gaia).\n\nvar DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support';\nvar supportsBlobs;\nvar dbContexts;\nvar toString = Object.prototype.toString;\n\n// Transform a binary string to an array buffer, because otherwise\n// weird stuff happens when you try to work with the binary string directly.\n// It is known.\n// From http://stackoverflow.com/questions/14967647/ (continues on next line)\n// encode-decode-image-with-base64-breaks-image (2013-04-21)\nfunction _binStringToArrayBuffer(bin) {\n var length = bin.length;\n var buf = new ArrayBuffer(length);\n var arr = new Uint8Array(buf);\n for (var i = 0; i < length; i++) {\n arr[i] = bin.charCodeAt(i);\n }\n return buf;\n}\n\n//\n// Blobs are not supported in all versions of IndexedDB, notably\n// Chrome <37 and Android <5. In those versions, storing a blob will throw.\n//\n// Various other blob bugs exist in Chrome v37-42 (inclusive).\n// Detecting them is expensive and confusing to users, and Chrome 37-42\n// is at very low usage worldwide, so we do a hacky userAgent check instead.\n//\n// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120\n// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916\n// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836\n//\n// Code borrowed from PouchDB. See:\n// https://github.com/pouchdb/pouchdb/blob/master/packages/node_modules/pouchdb-adapter-idb/src/blobSupport.js\n//\nfunction _checkBlobSupportWithoutCaching(idb) {\n return new Promise$1(function (resolve) {\n var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, 'readwrite');\n var blob = createBlob(['']);\n txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');\n\n txn.onabort = function (e) {\n // If the transaction aborts now its due to not being able to\n // write to the database, likely due to the disk being full\n e.preventDefault();\n e.stopPropagation();\n resolve(false);\n };\n\n txn.oncomplete = function () {\n var matchedChrome = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n var matchedEdge = navigator.userAgent.match(/Edge\\//);\n // MS Edge pretends to be Chrome 42:\n // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx\n resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43);\n };\n })[\"catch\"](function () {\n return false; // error, so assume unsupported\n });\n}\n\nfunction _checkBlobSupport(idb) {\n if (typeof supportsBlobs === 'boolean') {\n return Promise$1.resolve(supportsBlobs);\n }\n return _checkBlobSupportWithoutCaching(idb).then(function (value) {\n supportsBlobs = value;\n return supportsBlobs;\n });\n}\n\nfunction _deferReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Create a deferred object representing the current database operation.\n var deferredOperation = {};\n\n deferredOperation.promise = new Promise$1(function (resolve) {\n deferredOperation.resolve = resolve;\n });\n\n // Enqueue the deferred operation.\n dbContext.deferredOperations.push(deferredOperation);\n\n // Chain its promise to the database readiness.\n if (!dbContext.dbReady) {\n dbContext.dbReady = deferredOperation.promise;\n } else {\n dbContext.dbReady = dbContext.dbReady.then(function () {\n return deferredOperation.promise;\n });\n }\n}\n\nfunction _advanceReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Dequeue a deferred operation.\n var deferredOperation = dbContext.deferredOperations.pop();\n\n // Resolve its promise (which is part of the database readiness\n // chain of promises).\n if (deferredOperation) {\n deferredOperation.resolve();\n }\n}\n\nfunction _getConnection(dbInfo, upgradeNeeded) {\n return new Promise$1(function (resolve, reject) {\n\n if (dbInfo.db) {\n if (upgradeNeeded) {\n _deferReadiness(dbInfo);\n dbInfo.db.close();\n } else {\n return resolve(dbInfo.db);\n }\n }\n\n var dbArgs = [dbInfo.name];\n\n if (upgradeNeeded) {\n dbArgs.push(dbInfo.version);\n }\n\n var openreq = idb.open.apply(idb, dbArgs);\n\n if (upgradeNeeded) {\n openreq.onupgradeneeded = function (e) {\n var db = openreq.result;\n try {\n db.createObjectStore(dbInfo.storeName);\n if (e.oldVersion <= 1) {\n // Added when support for blob shims was added\n db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);\n }\n } catch (ex) {\n if (ex.name === 'ConstraintError') {\n console.warn('The database \"' + dbInfo.name + '\"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage \"' + dbInfo.storeName + '\" already exists.');\n } else {\n throw ex;\n }\n }\n };\n }\n\n openreq.onerror = function (e) {\n e.preventDefault();\n reject(openreq.error);\n };\n\n openreq.onsuccess = function () {\n resolve(openreq.result);\n _advanceReadiness(dbInfo);\n };\n });\n}\n\nfunction _getOriginalConnection(dbInfo) {\n return _getConnection(dbInfo, false);\n}\n\nfunction _getUpgradedConnection(dbInfo) {\n return _getConnection(dbInfo, true);\n}\n\nfunction _isUpgradeNeeded(dbInfo, defaultVersion) {\n if (!dbInfo.db) {\n return true;\n }\n\n var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName);\n var isDowngrade = dbInfo.version < dbInfo.db.version;\n var isUpgrade = dbInfo.version > dbInfo.db.version;\n\n if (isDowngrade) {\n // If the version is not the default one\n // then warn for impossible downgrade.\n if (dbInfo.version !== defaultVersion) {\n console.warn('The database \"' + dbInfo.name + '\"' + ' can\\'t be downgraded from version ' + dbInfo.db.version + ' to version ' + dbInfo.version + '.');\n }\n // Align the versions to prevent errors.\n dbInfo.version = dbInfo.db.version;\n }\n\n if (isUpgrade || isNewStore) {\n // If the store is new then increment the version (if needed).\n // This will trigger an \"upgradeneeded\" event which is required\n // for creating a store.\n if (isNewStore) {\n var incVersion = dbInfo.db.version + 1;\n if (incVersion > dbInfo.version) {\n dbInfo.version = incVersion;\n }\n }\n\n return true;\n }\n\n return false;\n}\n\n// encode a blob for indexeddb engines that don't support blobs\nfunction _encodeBlob(blob) {\n return new Promise$1(function (resolve, reject) {\n var reader = new FileReader();\n reader.onerror = reject;\n reader.onloadend = function (e) {\n var base64 = btoa(e.target.result || '');\n resolve({\n __local_forage_encoded_blob: true,\n data: base64,\n type: blob.type\n });\n };\n reader.readAsBinaryString(blob);\n });\n}\n\n// decode an encoded blob\nfunction _decodeBlob(encodedBlob) {\n var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data));\n return createBlob([arrayBuff], { type: encodedBlob.type });\n}\n\n// is this one of our fancy encoded blobs?\nfunction _isEncodedBlob(value) {\n return value && value.__local_forage_encoded_blob;\n}\n\n// Specialize the default `ready()` function by making it dependent\n// on the current database operations. Thus, the driver will be actually\n// ready when it's been initialized (default) *and* there are no pending\n// operations on the database (initiated by some other instances).\nfunction _fullyReady(callback) {\n var self = this;\n\n var promise = self._initReady().then(function () {\n var dbContext = dbContexts[self._dbInfo.name];\n\n if (dbContext && dbContext.dbReady) {\n return dbContext.dbReady;\n }\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n}\n\n// Open the IndexedDB database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n // Initialize a singleton container for all running localForages.\n if (!dbContexts) {\n dbContexts = {};\n }\n\n // Get the current context of the database;\n var dbContext = dbContexts[dbInfo.name];\n\n // ...or create a new context.\n if (!dbContext) {\n dbContext = {\n // Running localForages sharing a database.\n forages: [],\n // Shared database.\n db: null,\n // Database readiness (promise).\n dbReady: null,\n // Deferred operations on the database.\n deferredOperations: []\n };\n // Register the new context in the global container.\n dbContexts[dbInfo.name] = dbContext;\n }\n\n // Register itself as a running localForage in the current context.\n dbContext.forages.push(self);\n\n // Replace the default `ready()` function with the specialized one.\n if (!self._initReady) {\n self._initReady = self.ready;\n self.ready = _fullyReady;\n }\n\n // Create an array of initialization states of the related localForages.\n var initPromises = [];\n\n function ignoreErrors() {\n // Don't handle errors here,\n // just makes sure related localForages aren't pending.\n return Promise$1.resolve();\n }\n\n for (var j = 0; j < dbContext.forages.length; j++) {\n var forage = dbContext.forages[j];\n if (forage !== self) {\n // Don't wait for itself...\n initPromises.push(forage._initReady()[\"catch\"](ignoreErrors));\n }\n }\n\n // Take a snapshot of the related localForages.\n var forages = dbContext.forages.slice(0);\n\n // Initialize the connection process only when\n // all the related localForages aren't pending.\n return Promise$1.all(initPromises).then(function () {\n dbInfo.db = dbContext.db;\n // Get the connection or open a new one without upgrade.\n return _getOriginalConnection(dbInfo);\n }).then(function (db) {\n dbInfo.db = db;\n if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) {\n // Reopen the database for upgrading.\n return _getUpgradedConnection(dbInfo);\n }\n return db;\n }).then(function (db) {\n dbInfo.db = dbContext.db = db;\n self._dbInfo = dbInfo;\n // Share the final connection amongst related localForages.\n for (var k = 0; k < forages.length; k++) {\n var forage = forages[k];\n if (forage !== self) {\n // Self is already up-to-date.\n forage._dbInfo.db = dbInfo.db;\n forage._dbInfo.version = dbInfo.version;\n }\n }\n });\n}\n\nfunction getItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.get(key);\n\n req.onsuccess = function () {\n var value = req.result;\n if (value === undefined) {\n value = null;\n }\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n resolve(value);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items stored in database.\nfunction iterate(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var iterationNumber = 1;\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (cursor) {\n var value = cursor.value;\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n var result = iterator(value, cursor.key, iterationNumber++);\n\n if (result !== void 0) {\n resolve(result);\n } else {\n cursor[\"continue\"]();\n }\n } else {\n resolve();\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n\n return promise;\n}\n\nfunction setItem(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n var dbInfo;\n self.ready().then(function () {\n dbInfo = self._dbInfo;\n if (toString.call(value) === '[object Blob]') {\n return _checkBlobSupport(dbInfo.db).then(function (blobSupport) {\n if (blobSupport) {\n return value;\n }\n return _encodeBlob(value);\n });\n }\n return value;\n }).then(function (value) {\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.put(value, key);\n\n // The reason we don't _save_ null is because IE 10 does\n // not support saving the `null` type in IndexedDB. How\n // ironic, given the bug below!\n // See: https://github.com/mozilla/localForage/issues/161\n if (value === null) {\n value = undefined;\n }\n\n transaction.oncomplete = function () {\n // Cast to undefined so the value passed to\n // callback/promise is the same as what one would get out\n // of `getItem()` later. This leads to some weirdness\n // (setItem('foo', undefined) will return `null`), but\n // it's not my fault localStorage is our baseline and that\n // it's weird.\n if (value === undefined) {\n value = null;\n }\n\n resolve(value);\n };\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction removeItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n\n // We use a Grunt task to make this safe for IE and some\n // versions of Android (including those used by Cordova).\n // Normally IE won't like `.delete()` and will insist on\n // using `['delete']()`, but we have a build step that\n // fixes this for us now.\n var req = store[\"delete\"](key);\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onerror = function () {\n reject(req.error);\n };\n\n // The request will be also be aborted if we've exceeded our storage\n // space.\n transaction.onabort = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction clear(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.clear();\n\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction length(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.count();\n\n req.onsuccess = function () {\n resolve(req.result);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction key(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n if (n < 0) {\n resolve(null);\n\n return;\n }\n\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var advanced = false;\n var req = store.openCursor();\n req.onsuccess = function () {\n var cursor = req.result;\n if (!cursor) {\n // this means there weren't enough keys\n resolve(null);\n\n return;\n }\n\n if (n === 0) {\n // We have the first key, return it if that's what they\n // wanted.\n resolve(cursor.key);\n } else {\n if (!advanced) {\n // Otherwise, ask the cursor to skip ahead n\n // records.\n advanced = true;\n cursor.advance(n);\n } else {\n // When we get here, we've got the nth key.\n resolve(cursor.key);\n }\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var keys = [];\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (!cursor) {\n resolve(keys);\n return;\n }\n\n keys.push(cursor.key);\n cursor[\"continue\"]();\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar asyncStorage = {\n _driver: 'asyncStorage',\n _initStorage: _initStorage,\n iterate: iterate,\n getItem: getItem,\n setItem: setItem,\n removeItem: removeItem,\n clear: clear,\n length: length,\n key: key,\n keys: keys\n};\n\n// Sadly, the best way to save binary data in WebSQL/localStorage is serializing\n// it to Base64, so this is how we store it to prevent very strange errors with less\n// verbose ways of binary <-> string data storage.\nvar BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\nvar BLOB_TYPE_PREFIX = '~~local_forage_type~';\nvar BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;\n\nvar SERIALIZED_MARKER = '__lfsc__:';\nvar SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;\n\n// OMG the serializations!\nvar TYPE_ARRAYBUFFER = 'arbf';\nvar TYPE_BLOB = 'blob';\nvar TYPE_INT8ARRAY = 'si08';\nvar TYPE_UINT8ARRAY = 'ui08';\nvar TYPE_UINT8CLAMPEDARRAY = 'uic8';\nvar TYPE_INT16ARRAY = 'si16';\nvar TYPE_INT32ARRAY = 'si32';\nvar TYPE_UINT16ARRAY = 'ur16';\nvar TYPE_UINT32ARRAY = 'ui32';\nvar TYPE_FLOAT32ARRAY = 'fl32';\nvar TYPE_FLOAT64ARRAY = 'fl64';\nvar TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;\n\nvar toString$1 = Object.prototype.toString;\n\nfunction stringToBuffer(serializedString) {\n // Fill the string into a ArrayBuffer.\n var bufferLength = serializedString.length * 0.75;\n var len = serializedString.length;\n var i;\n var p = 0;\n var encoded1, encoded2, encoded3, encoded4;\n\n if (serializedString[serializedString.length - 1] === '=') {\n bufferLength--;\n if (serializedString[serializedString.length - 2] === '=') {\n bufferLength--;\n }\n }\n\n var buffer = new ArrayBuffer(bufferLength);\n var bytes = new Uint8Array(buffer);\n\n for (i = 0; i < len; i += 4) {\n encoded1 = BASE_CHARS.indexOf(serializedString[i]);\n encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);\n encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);\n encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);\n\n /*jslint bitwise: true */\n bytes[p++] = encoded1 << 2 | encoded2 >> 4;\n bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;\n bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;\n }\n return buffer;\n}\n\n// Converts a buffer to a string to store, serialized, in the backend\n// storage library.\nfunction bufferToString(buffer) {\n // base64-arraybuffer\n var bytes = new Uint8Array(buffer);\n var base64String = '';\n var i;\n\n for (i = 0; i < bytes.length; i += 3) {\n /*jslint bitwise: true */\n base64String += BASE_CHARS[bytes[i] >> 2];\n base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];\n base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];\n base64String += BASE_CHARS[bytes[i + 2] & 63];\n }\n\n if (bytes.length % 3 === 2) {\n base64String = base64String.substring(0, base64String.length - 1) + '=';\n } else if (bytes.length % 3 === 1) {\n base64String = base64String.substring(0, base64String.length - 2) + '==';\n }\n\n return base64String;\n}\n\n// Serialize a value, afterwards executing a callback (which usually\n// instructs the `setItem()` callback/promise to be executed). This is how\n// we store binary data with localStorage.\nfunction serialize(value, callback) {\n var valueType = '';\n if (value) {\n valueType = toString$1.call(value);\n }\n\n // Cannot use `value instanceof ArrayBuffer` or such here, as these\n // checks fail when running the tests using casper.js...\n //\n // TODO: See why those tests fail and use a better solution.\n if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) {\n // Convert binary arrays to a string and prefix the string with\n // a special marker.\n var buffer;\n var marker = SERIALIZED_MARKER;\n\n if (value instanceof ArrayBuffer) {\n buffer = value;\n marker += TYPE_ARRAYBUFFER;\n } else {\n buffer = value.buffer;\n\n if (valueType === '[object Int8Array]') {\n marker += TYPE_INT8ARRAY;\n } else if (valueType === '[object Uint8Array]') {\n marker += TYPE_UINT8ARRAY;\n } else if (valueType === '[object Uint8ClampedArray]') {\n marker += TYPE_UINT8CLAMPEDARRAY;\n } else if (valueType === '[object Int16Array]') {\n marker += TYPE_INT16ARRAY;\n } else if (valueType === '[object Uint16Array]') {\n marker += TYPE_UINT16ARRAY;\n } else if (valueType === '[object Int32Array]') {\n marker += TYPE_INT32ARRAY;\n } else if (valueType === '[object Uint32Array]') {\n marker += TYPE_UINT32ARRAY;\n } else if (valueType === '[object Float32Array]') {\n marker += TYPE_FLOAT32ARRAY;\n } else if (valueType === '[object Float64Array]') {\n marker += TYPE_FLOAT64ARRAY;\n } else {\n callback(new Error('Failed to get type for BinaryArray'));\n }\n }\n\n callback(marker + bufferToString(buffer));\n } else if (valueType === '[object Blob]') {\n // Conver the blob to a binaryArray and then to a string.\n var fileReader = new FileReader();\n\n fileReader.onload = function () {\n // Backwards-compatible prefix for the blob type.\n var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result);\n\n callback(SERIALIZED_MARKER + TYPE_BLOB + str);\n };\n\n fileReader.readAsArrayBuffer(value);\n } else {\n try {\n callback(JSON.stringify(value));\n } catch (e) {\n console.error(\"Couldn't convert value into a JSON string: \", value);\n\n callback(null, e);\n }\n }\n}\n\n// Deserialize data we've inserted into a value column/field. We place\n// special markers into our strings to mark them as encoded; this isn't\n// as nice as a meta field, but it's the only sane thing we can do whilst\n// keeping localStorage support intact.\n//\n// Oftentimes this will just deserialize JSON content, but if we have a\n// special marker (SERIALIZED_MARKER, defined above), we will extract\n// some kind of arraybuffer/binary data/typed array out of the string.\nfunction deserialize(value) {\n // If we haven't marked this string as being specially serialized (i.e.\n // something other than serialized JSON), we can just return it and be\n // done with it.\n if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {\n return JSON.parse(value);\n }\n\n // The following code deals with deserializing some kind of Blob or\n // TypedArray. First we separate out the type of data we're dealing\n // with from the data itself.\n var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);\n var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH);\n\n var blobType;\n // Backwards-compatible blob type serialization strategy.\n // DBs created with older versions of localForage will simply not have the blob type.\n if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {\n var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);\n blobType = matcher[1];\n serializedString = serializedString.substring(matcher[0].length);\n }\n var buffer = stringToBuffer(serializedString);\n\n // Return the right type based on the code/type set during\n // serialization.\n switch (type) {\n case TYPE_ARRAYBUFFER:\n return buffer;\n case TYPE_BLOB:\n return createBlob([buffer], { type: blobType });\n case TYPE_INT8ARRAY:\n return new Int8Array(buffer);\n case TYPE_UINT8ARRAY:\n return new Uint8Array(buffer);\n case TYPE_UINT8CLAMPEDARRAY:\n return new Uint8ClampedArray(buffer);\n case TYPE_INT16ARRAY:\n return new Int16Array(buffer);\n case TYPE_UINT16ARRAY:\n return new Uint16Array(buffer);\n case TYPE_INT32ARRAY:\n return new Int32Array(buffer);\n case TYPE_UINT32ARRAY:\n return new Uint32Array(buffer);\n case TYPE_FLOAT32ARRAY:\n return new Float32Array(buffer);\n case TYPE_FLOAT64ARRAY:\n return new Float64Array(buffer);\n default:\n throw new Error('Unkown type: ' + type);\n }\n}\n\nvar localforageSerializer = {\n serialize: serialize,\n deserialize: deserialize,\n stringToBuffer: stringToBuffer,\n bufferToString: bufferToString\n};\n\n/*\n * Includes code from:\n *\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n// Open the WebSQL database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage$1(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i];\n }\n }\n\n var dbInfoPromise = new Promise$1(function (resolve, reject) {\n // Open the database; the openDatabase API will automatically\n // create it for us if it doesn't exist.\n try {\n dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size);\n } catch (e) {\n return reject(e);\n }\n\n // Create our key/value table if it doesn't exist.\n dbInfo.db.transaction(function (t) {\n t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' (id INTEGER PRIMARY KEY, key unique, value)', [], function () {\n self._dbInfo = dbInfo;\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n });\n\n dbInfo.serializer = localforageSerializer;\n return dbInfoPromise;\n}\n\nfunction getItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).value : null;\n\n // Check to see if this is serialized content we need to\n // unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction iterate$1(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName, [], function (t, results) {\n var rows = results.rows;\n var length = rows.length;\n\n for (var i = 0; i < length; i++) {\n var item = rows.item(i);\n var result = item.value;\n\n // Check to see if this is serialized content\n // we need to unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n result = iterator(result, item.key, i + 1);\n\n // void(0) prevents problems with redefinition\n // of `undefined`.\n if (result !== void 0) {\n resolve(result);\n return;\n }\n }\n\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction _setItem(key, value, callback, retriesLeft) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n // The localStorage API doesn't return undefined values in an\n // \"expected\" way, so undefined is always cast to null in all\n // drivers. See: https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n dbInfo.db.transaction(function (t) {\n t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + ' (key, value) VALUES (?, ?)', [key, value], function () {\n resolve(originalValue);\n }, function (t, error) {\n reject(error);\n });\n }, function (sqlError) {\n // The transaction failed; check\n // to see if it's a quota error.\n if (sqlError.code === sqlError.QUOTA_ERR) {\n // We reject the callback outright for now, but\n // it's worth trying to re-run the transaction.\n // Even if the user accepts the prompt to use\n // more storage on Safari, this error will\n // be called.\n //\n // Try to re-run the transaction.\n if (retriesLeft > 0) {\n resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1]));\n return;\n }\n reject(sqlError);\n }\n });\n }\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction setItem$1(key, value, callback) {\n return _setItem.apply(this, [key, value, callback, 1]);\n}\n\nfunction removeItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () {\n resolve();\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Deletes every item in the table.\n// TODO: Find out if this resets the AUTO_INCREMENT number.\nfunction clear$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function () {\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Does a simple `COUNT(key)` to get the number of items stored in\n// localForage.\nfunction length$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n // Ahhh, SQL makes this one soooooo easy.\n t.executeSql('SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) {\n var result = results.rows.item(0).c;\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Return the key located at key index X; essentially gets the key from a\n// `WHERE id = ?`. This is the most efficient way I can think to implement\n// this rarely-used (in my experience) part of the API, but it can seem\n// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so\n// the ID of each key will change every time it's updated. Perhaps a stored\n// procedure for the `setItem()` SQL would solve this problem?\n// TODO: Don't change ID on `setItem()`.\nfunction key$1(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).key : null;\n resolve(result);\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName, [], function (t, results) {\n var keys = [];\n\n for (var i = 0; i < results.rows.length; i++) {\n keys.push(results.rows.item(i).key);\n }\n\n resolve(keys);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar webSQLStorage = {\n _driver: 'webSQLStorage',\n _initStorage: _initStorage$1,\n iterate: iterate$1,\n getItem: getItem$1,\n setItem: setItem$1,\n removeItem: removeItem$1,\n clear: clear$1,\n length: length$1,\n key: key$1,\n keys: keys$1\n};\n\n// Config the localStorage backend, using options set in the config.\nfunction _initStorage$2(options) {\n var self = this;\n var dbInfo = {};\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n dbInfo.keyPrefix = dbInfo.name + '/';\n\n if (dbInfo.storeName !== self._defaultConfig.storeName) {\n dbInfo.keyPrefix += dbInfo.storeName + '/';\n }\n\n self._dbInfo = dbInfo;\n dbInfo.serializer = localforageSerializer;\n\n return Promise$1.resolve();\n}\n\n// Remove all keys from the datastore, effectively destroying all data in\n// the app's key/value store!\nfunction clear$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var keyPrefix = self._dbInfo.keyPrefix;\n\n for (var i = localStorage.length - 1; i >= 0; i--) {\n var key = localStorage.key(i);\n\n if (key.indexOf(keyPrefix) === 0) {\n localStorage.removeItem(key);\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Retrieve an item from the store. Unlike the original async_storage\n// library in Gaia, we don't modify return values at all. If a key's value\n// is `undefined`, we pass that value to the callback function.\nfunction getItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result = localStorage.getItem(dbInfo.keyPrefix + key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the key\n // is likely undefined and we'll pass it straight to the\n // callback.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items in the store.\nfunction iterate$2(iterator, callback) {\n var self = this;\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var keyPrefix = dbInfo.keyPrefix;\n var keyPrefixLength = keyPrefix.length;\n var length = localStorage.length;\n\n // We use a dedicated iterator instead of the `i` variable below\n // so other keys we fetch in localStorage aren't counted in\n // the `iterationNumber` argument passed to the `iterate()`\n // callback.\n //\n // See: github.com/mozilla/localForage/pull/435#discussion_r38061530\n var iterationNumber = 1;\n\n for (var i = 0; i < length; i++) {\n var key = localStorage.key(i);\n if (key.indexOf(keyPrefix) !== 0) {\n continue;\n }\n var value = localStorage.getItem(key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the\n // key is likely undefined and we'll pass it straight\n // to the iterator.\n if (value) {\n value = dbInfo.serializer.deserialize(value);\n }\n\n value = iterator(value, key.substring(keyPrefixLength), iterationNumber++);\n\n if (value !== void 0) {\n return value;\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Same as localStorage's key() method, except takes a callback.\nfunction key$2(n, callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result;\n try {\n result = localStorage.key(n);\n } catch (error) {\n result = null;\n }\n\n // Remove the prefix from the key, if a key is found.\n if (result) {\n result = result.substring(dbInfo.keyPrefix.length);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var length = localStorage.length;\n var keys = [];\n\n for (var i = 0; i < length; i++) {\n if (localStorage.key(i).indexOf(dbInfo.keyPrefix) === 0) {\n keys.push(localStorage.key(i).substring(dbInfo.keyPrefix.length));\n }\n }\n\n return keys;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Supply the number of keys in the datastore to the callback function.\nfunction length$2(callback) {\n var self = this;\n var promise = self.keys().then(function (keys) {\n return keys.length;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Remove an item from the store, nice and simple.\nfunction removeItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n localStorage.removeItem(dbInfo.keyPrefix + key);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Set a key's value and run an optional callback once the value is set.\n// Unlike Gaia's implementation, the callback function is passed the value,\n// in case you want to operate on that value only after you're sure it\n// saved, or something like that.\nfunction setItem$2(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n // Convert undefined values to null.\n // https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n return new Promise$1(function (resolve, reject) {\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n try {\n localStorage.setItem(dbInfo.keyPrefix + key, value);\n resolve(originalValue);\n } catch (e) {\n // localStorage capacity exceeded.\n // TODO: Make this a specific error/event.\n if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {\n reject(e);\n }\n reject(e);\n }\n }\n });\n });\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar localStorageWrapper = {\n _driver: 'localStorageWrapper',\n _initStorage: _initStorage$2,\n // Default API, from Gaia/localStorage.\n iterate: iterate$2,\n getItem: getItem$2,\n setItem: setItem$2,\n removeItem: removeItem$2,\n clear: clear$2,\n length: length$2,\n key: key$2,\n keys: keys$2\n};\n\n// Custom drivers are stored here when `defineDriver()` is called.\n// They are shared across all instances of localForage.\nvar CustomDrivers = {};\n\nvar DriverType = {\n INDEXEDDB: 'asyncStorage',\n LOCALSTORAGE: 'localStorageWrapper',\n WEBSQL: 'webSQLStorage'\n};\n\nvar DefaultDriverOrder = [DriverType.INDEXEDDB, DriverType.WEBSQL, DriverType.LOCALSTORAGE];\n\nvar LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem'];\n\nvar DefaultConfig = {\n description: '',\n driver: DefaultDriverOrder.slice(),\n name: 'localforage',\n // Default DB size is _JUST UNDER_ 5MB, as it's the highest size\n // we can use without a prompt.\n size: 4980736,\n storeName: 'keyvaluepairs',\n version: 1.0\n};\n\nvar driverSupport = {};\n// Check to see if IndexedDB is available and if it is the latest\n// implementation; it's our preferred backend library. We use \"_spec_test\"\n// as the name of the database because it's not the one we'll operate on,\n// but it's useful to make sure its using the right spec.\n// See: https://github.com/mozilla/localForage/issues/128\ndriverSupport[DriverType.INDEXEDDB] = isIndexedDBValid();\n\ndriverSupport[DriverType.WEBSQL] = isWebSQLValid();\n\ndriverSupport[DriverType.LOCALSTORAGE] = isLocalStorageValid();\n\nvar isArray = Array.isArray || function (arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n};\n\nfunction callWhenReady(localForageInstance, libraryMethod) {\n localForageInstance[libraryMethod] = function () {\n var _args = arguments;\n return localForageInstance.ready().then(function () {\n return localForageInstance[libraryMethod].apply(localForageInstance, _args);\n });\n };\n}\n\nfunction extend() {\n for (var i = 1; i < arguments.length; i++) {\n var arg = arguments[i];\n\n if (arg) {\n for (var key in arg) {\n if (arg.hasOwnProperty(key)) {\n if (isArray(arg[key])) {\n arguments[0][key] = arg[key].slice();\n } else {\n arguments[0][key] = arg[key];\n }\n }\n }\n }\n }\n\n return arguments[0];\n}\n\nfunction isLibraryDriver(driverName) {\n for (var driver in DriverType) {\n if (DriverType.hasOwnProperty(driver) && DriverType[driver] === driverName) {\n return true;\n }\n }\n\n return false;\n}\n\nvar LocalForage = function () {\n function LocalForage(options) {\n _classCallCheck(this, LocalForage);\n\n this.INDEXEDDB = DriverType.INDEXEDDB;\n this.LOCALSTORAGE = DriverType.LOCALSTORAGE;\n this.WEBSQL = DriverType.WEBSQL;\n\n this._defaultConfig = extend({}, DefaultConfig);\n this._config = extend({}, this._defaultConfig, options);\n this._driverSet = null;\n this._initDriver = null;\n this._ready = false;\n this._dbInfo = null;\n\n this._wrapLibraryMethodsWithReady();\n this.setDriver(this._config.driver)[\"catch\"](function () {});\n }\n\n // Set any config values for localForage; can be called anytime before\n // the first API call (e.g. `getItem`, `setItem`).\n // We loop through options so we don't overwrite existing config\n // values.\n\n\n LocalForage.prototype.config = function config(options) {\n // If the options argument is an object, we use it to set values.\n // Otherwise, we return either a specified config value or all\n // config values.\n if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {\n // If localforage is ready and fully initialized, we can't set\n // any new configuration values. Instead, we return an error.\n if (this._ready) {\n return new Error(\"Can't call config() after localforage \" + 'has been used.');\n }\n\n for (var i in options) {\n if (i === 'storeName') {\n options[i] = options[i].replace(/\\W/g, '_');\n }\n\n if (i === 'version' && typeof options[i] !== 'number') {\n return new Error('Database version must be a number.');\n }\n\n this._config[i] = options[i];\n }\n\n // after all config options are set and\n // the driver option is used, try setting it\n if ('driver' in options && options.driver) {\n return this.setDriver(this._config.driver);\n }\n\n return true;\n } else if (typeof options === 'string') {\n return this._config[options];\n } else {\n return this._config;\n }\n };\n\n // Used to define a custom driver, shared across all instances of\n // localForage.\n\n\n LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) {\n var promise = new Promise$1(function (resolve, reject) {\n try {\n var driverName = driverObject._driver;\n var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver');\n var namingError = new Error('Custom driver name already in use: ' + driverObject._driver);\n\n // A driver name should be defined and not overlap with the\n // library-defined, default drivers.\n if (!driverObject._driver) {\n reject(complianceError);\n return;\n }\n if (isLibraryDriver(driverObject._driver)) {\n reject(namingError);\n return;\n }\n\n var customDriverMethods = LibraryMethods.concat('_initStorage');\n for (var i = 0; i < customDriverMethods.length; i++) {\n var customDriverMethod = customDriverMethods[i];\n if (!customDriverMethod || !driverObject[customDriverMethod] || typeof driverObject[customDriverMethod] !== 'function') {\n reject(complianceError);\n return;\n }\n }\n\n var supportPromise = Promise$1.resolve(true);\n if ('_support' in driverObject) {\n if (driverObject._support && typeof driverObject._support === 'function') {\n supportPromise = driverObject._support();\n } else {\n supportPromise = Promise$1.resolve(!!driverObject._support);\n }\n }\n\n supportPromise.then(function (supportResult) {\n driverSupport[driverName] = supportResult;\n CustomDrivers[driverName] = driverObject;\n resolve();\n }, reject);\n } catch (e) {\n reject(e);\n }\n });\n\n executeTwoCallbacks(promise, callback, errorCallback);\n return promise;\n };\n\n LocalForage.prototype.driver = function driver() {\n return this._driver || null;\n };\n\n LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) {\n var self = this;\n var getDriverPromise = Promise$1.resolve().then(function () {\n if (isLibraryDriver(driverName)) {\n switch (driverName) {\n case self.INDEXEDDB:\n return asyncStorage;\n case self.LOCALSTORAGE:\n return localStorageWrapper;\n case self.WEBSQL:\n return webSQLStorage;\n }\n } else if (CustomDrivers[driverName]) {\n return CustomDrivers[driverName];\n } else {\n throw new Error('Driver not found.');\n }\n });\n executeTwoCallbacks(getDriverPromise, callback, errorCallback);\n return getDriverPromise;\n };\n\n LocalForage.prototype.getSerializer = function getSerializer(callback) {\n var serializerPromise = Promise$1.resolve(localforageSerializer);\n executeTwoCallbacks(serializerPromise, callback);\n return serializerPromise;\n };\n\n LocalForage.prototype.ready = function ready(callback) {\n var self = this;\n\n var promise = self._driverSet.then(function () {\n if (self._ready === null) {\n self._ready = self._initDriver();\n }\n\n return self._ready;\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n };\n\n LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) {\n var self = this;\n\n if (!isArray(drivers)) {\n drivers = [drivers];\n }\n\n var supportedDrivers = this._getSupportedDrivers(drivers);\n\n function setDriverToConfig() {\n self._config.driver = self.driver();\n }\n\n function extendSelfWithDriver(driver) {\n self._extend(driver);\n setDriverToConfig();\n\n self._ready = self._initStorage(self._config);\n return self._ready;\n }\n\n function initDriver(supportedDrivers) {\n return function () {\n var currentDriverIndex = 0;\n\n function driverPromiseLoop() {\n while (currentDriverIndex < supportedDrivers.length) {\n var driverName = supportedDrivers[currentDriverIndex];\n currentDriverIndex++;\n\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(extendSelfWithDriver)[\"catch\"](driverPromiseLoop);\n }\n\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n }\n\n return driverPromiseLoop();\n };\n }\n\n // There might be a driver initialization in progress\n // so wait for it to finish in order to avoid a possible\n // race condition to set _dbInfo\n var oldDriverSetDone = this._driverSet !== null ? this._driverSet[\"catch\"](function () {\n return Promise$1.resolve();\n }) : Promise$1.resolve();\n\n this._driverSet = oldDriverSetDone.then(function () {\n var driverName = supportedDrivers[0];\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(function (driver) {\n self._driver = driver._driver;\n setDriverToConfig();\n self._wrapLibraryMethodsWithReady();\n self._initDriver = initDriver(supportedDrivers);\n });\n })[\"catch\"](function () {\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n });\n\n executeTwoCallbacks(this._driverSet, callback, errorCallback);\n return this._driverSet;\n };\n\n LocalForage.prototype.supports = function supports(driverName) {\n return !!driverSupport[driverName];\n };\n\n LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) {\n extend(this, libraryMethodsAndProperties);\n };\n\n LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) {\n var supportedDrivers = [];\n for (var i = 0, len = drivers.length; i < len; i++) {\n var driverName = drivers[i];\n if (this.supports(driverName)) {\n supportedDrivers.push(driverName);\n }\n }\n return supportedDrivers;\n };\n\n LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() {\n // Add a stub for each driver API method that delays the call to the\n // corresponding driver method until localForage is ready. These stubs\n // will be replaced by the driver methods as soon as the driver is\n // loaded, so there is no performance impact.\n for (var i = 0; i < LibraryMethods.length; i++) {\n callWhenReady(this, LibraryMethods[i]);\n }\n };\n\n LocalForage.prototype.createInstance = function createInstance(options) {\n return new LocalForage(options);\n };\n\n return LocalForage;\n}();\n\n// The actual localForage object that we expose as a module or via a\n// global. It's extended by pulling in one of our other libraries.\n\n\nvar localforage_js = new LocalForage();\n\nmodule.exports = localforage_js;\n\n},{\"3\":3}]},{},[4])(4)\n});","module.exports = require('./lib/type');\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n '[object Array]': 'array'\n , '[object RegExp]': 'regexp'\n , '[object Function]': 'function'\n , '[object Arguments]': 'arguments'\n , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n var str = Object.prototype.toString.call(obj);\n if (natives[str]) return natives[str];\n if (obj === null) return 'null';\n if (obj === undefined) return 'undefined';\n if (obj === Object(obj)) return 'object';\n return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n // Let \"new String('')\" return 'object'\n if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n // PhantomJS has type \"DOMWindow\" for null\n if (obj === null) return 'null';\n // PhantomJS has type \"DOMWindow\" for undefined\n if (obj === undefined) return 'undefined';\n return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n if (!(this instanceof Library)) return new Library();\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","(function (document, window) {\n // DEPENDENCIES\n // ============================================================\n const localforage = require('localforage');\n const probs = require('pjs-problems');\n const dedent = require('dedent');\n const assert = require('chai').assert;\n\n // PROBLEM TEMPLATE NICE-IFICATION\n // ============================================================\n\n function dedentStrings(problems) {\n return problems.map(prob => {\n prob.given = dedent(prob.given)\n prob.answer = dedent(prob.answer)\n return prob\n });\n }\n\n\n // PROBLEMS\n // ============================================================\n\n let problems = [];\n Object.keys(probs).forEach(subject => {\n problems.push(...probs[subject]);\n });\n problems = dedentStrings(problems);\n\n\n // CONFIG\n // ============================================================\n\n // Hoist current problem\n let currentProblem;\n\n // Keys to ignore while user is navigating around the textarea but not changing any code\n const ignoreKeyCodes = [\n 9, // Tab\n 37, // Left arrow\n 39, // Right arrow\n 38, // Up arrow\n 40 // Down arrow\n ];\n\n let config = {\n shuffle: true,\n timer: false,\n currentIndex: 0\n };\n\n // Pull config from localforage\n localforage\n .getItem('js_practice_config')\n .then(val => {\n if (val) {\n config = val;\n }\n loadApp(config);\n })\n .catch(err => {\n console.log('localforage err:', err);\n loadApp(config);\n });\n\n function updateLocalstore(config) {\n return localforage\n .setItem('js_practice_config', config)\n .then(val => val)\n .catch(err => {\n console.log('Settings update error:', err);\n });\n }\n\n // HELPERS\n // ============================================================\n\n function debounce(func, wait, immediate) {\n let timeout;\n return function () {\n const context = this;\n const args = arguments;\n const later = function () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n };\n const callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) {\n func.apply(context, args);\n }\n };\n }\n\n // UI\n // ============================================================\n\n // elements\n const problemEl = document.getElementById('problem');\n const codeEl = document.getElementById('code');\n const testSuiteEl = document.getElementById('test-suite');\n const testTotalEl = document.getElementById('test-total');\n const evalConsoleEl = document.getElementById('eval-output');\n const assertConsoleEl = document.getElementById('assert-output');\n const shuffleProblemsButtonEl = document.getElementById('shuffle-problems');\n const previousProblemButtonEl = document.getElementById('prev-problem');\n const nextProblemButtonEl = document.getElementById('next-problem');\n\n // Get indexes\n function getRandomIndex(problemsArr) {\n const ind = Math.floor(Math.random() * problemsArr.length);\n config.currentIndex = ind;\n updateLocalstore(config);\n return ind;\n }\n\n function getPreviousIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at beginning, go to end\n if (currentIndex === 0) {\n probInd = problemsArr.length - 1;\n } else {\n probInd = currentIndex - 1;\n }\n return probInd;\n }\n\n function getNextIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at end or invalid, restart series\n if (currentIndex >= problemsArr.length - 1 || currentIndex < 0) {\n probInd = 0;\n } else {\n probInd = currentIndex + 1;\n }\n return probInd;\n }\n\n // Get problems\n function getCurrentProblem(problemsArr) {\n return problemsArr[config.currentIndex];\n }\n\n function previousProblem() {\n console.log('previousProblem!');\n // Activate back button, for visual queue of nav feedback\n previousProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getPreviousIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function nextProblem() {\n console.log('nextProblem!');\n // Activate next button, for visual queue of nav feedback\n nextProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getNextIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function toggleShuffle() {\n console.log('toggle shuffle!');\n config.shuffle = !config.shuffle; // Flip it\n shuffleProblemsButtonEl.classList.toggle('active');\n previousProblemButtonEl.parentNode.classList.toggle('hidden');\n updateLocalstore(config);\n }\n\n function loadProblem(problemObj) {\n currentProblem = problemObj;\n // Prob question\n problemEl.innerText = problemObj.prompt;\n // Prob given code\n if (problemObj.given) {\n codeEl.value = problemObj.given;\n }\n // Seed the tests, pass (init = true) as second param\n testSuite(null, true);\n }\n\n // TODO: Build the assert errors into the test dom on each update.\n function updateTests(testStatus, init) {\n if (init === true) {\n buildTests(currentProblem.tests);\n }\n updateTestStatus(testStatus);\n }\n\n function buildTests(tests) {\n if (tests) {\n const testsDom = tests\n .map(test => {\n return `
\n
[✘]
\n
${test.name}
\n
`;\n })\n .join('');\n testSuiteEl.innerHTML = testsDom;\n }\n }\n\n function updateTestStatus(testStatuses) {\n if (!testStatuses) {\n throw new Error('No testStatuses provided.');\n }\n // Find out if all tests have passed or not\n let allPassed = true;\n testStatuses.forEach(testPassed => {\n if (testPassed !== true) {\n allPassed = false;\n }\n });\n const testEls = [].slice.call(testSuiteEl.querySelectorAll('.test-state'));\n testEls.forEach((testStatusEl, iter) => {\n if (testStatuses[iter] === true) {\n testStatusEl.innerHTML = '[✓]';\n testStatusEl.classList.remove('fail');\n testStatusEl.classList.add('pass');\n } else {\n testStatusEl.innerHTML = '[✘]';\n testStatusEl.classList.remove('pass');\n testStatusEl.classList.add('fail');\n }\n });\n\n if (allPassed === true) {\n testTotalEl.innerText = 'PASS';\n testTotalEl.classList.remove('fail');\n testTotalEl.classList.add('pass');\n } else {\n testTotalEl.innerText = 'FAIL';\n testTotalEl.classList.remove('pass');\n testTotalEl.classList.add('fail');\n }\n }\n\n function printAssertError(errObj) {\n // Make element string\n let inner = '';\n if (errObj !== null) {\n inner = `\n
\n Expected: ${JSON.stringify(errObj.expected)}\n Actual: ${JSON.stringify(errObj.actual)}\n
`;\n }\n\n // Prepend element\n assertConsoleEl.innerHTML = inner;\n }\n\n function printEvalOutput(errObj, output) {\n // Make element string\n let inner = '';\n if (errObj && errObj.message !== undefined) {\n inner = `\n
\n Syntax Error: ${JSON.stringify(errObj.message)}\n
`;\n } else if (output) {\n inner = `\n
\n Output: ${JSON.stringify(output)}\n
`;\n }\n // Prepend element\n evalConsoleEl.innerHTML = inner;\n }\n\n\n // VERIFICATION LOGIC\n // ============================================================\n\n function testSuite(init) {\n // Show 'working' indicator\n testTotalEl.classList.toggle('working');\n // Run stuff\n const output = getOutput(codeEl.value);\n // Run tests on code, return object/array of test results\n const tested = runTests(output);\n // Hide 'working' indicator\n testTotalEl.classList.toggle('working');\n // Update UI with results\n updateTests(tested, init);\n }\n\n function getOutput(code) {\n let evald = false;\n try {\n evald = eval(`(function(){${code}})()`); // eslint-disable-line no-eval\n printEvalOutput(null, evald); // Print current output\n } catch (err) {\n printEvalOutput(err);\n }\n return evald;\n }\n\n function runTests(output) {\n let tested = false;\n tested = currentProblem.tests.map(test => {\n let testOutcome = false;\n try {\n if (output) {\n // const testEval = eval(test.test);\n\n testOutcome = eval(test.test);\n console.log('testOutcome:', testOutcome);\n\n }\n printAssertError(null);\n } catch (err) {\n printAssertError(err);\n }\n return testOutcome;\n });\n return tested;\n }\n\n // Wrapped to prevent race with local config retrieval\n function loadApp(config) {\n console.log('loading app!');\n\n // Show current toggle state\n if (config.shuffle === true) {\n shuffleProblemsButtonEl.classList.add('active');\n previousProblemButtonEl.parentNode.classList.add('hidden');\n }\n\n // Keybinding stuff\n // ============================================================\n\n // Debounced code validation\n const debouncedInputValidation = debounce(e => {\n // If not arrow keys or other non-character keys\n if (ignoreKeyCodes.indexOf(e.keyCode) === -1) {\n // Run test suite\n testSuite();\n }\n }, 200);\n\n function problemNav(e) {\n // Go to previous problem keybinding\n // If CMD/CTRL + SHIFT + RETURN/ENTER\n if (config.shuffle === false && e.keyCode === 13 && e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem\n previousProblem();\n } else if (e.keyCode === 13 && !e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem keybinding\n // If CMD/CTRL + RETURN/ENTER\n // Go to next problem\n nextProblem();\n }\n }\n\n // Event Bindings\n // ============================================================\n\n // Bind it up\n codeEl.addEventListener('keydown', debouncedInputValidation);\n document.addEventListener('keydown', problemNav);\n shuffleProblemsButtonEl.addEventListener('click', toggleShuffle);\n previousProblemButtonEl.addEventListener('click', previousProblem);\n nextProblemButtonEl.addEventListener('click', nextProblem);\n\n // Start it up!\n // Load current problem\n const currProb = getCurrentProblem(problems);\n loadProblem(currProb);\n // Initalized test suite with starting failures\n testSuite(true);\n }\n})(document, window);\n"]} \ No newline at end of file +{"version":3,"sources":["node_modules/.registry.npmjs.org/browser-pack/6.0.2/node_modules/browser-pack/_prelude.js","node_modules/.registry.npmjs.org/assertion-error/1.0.2/node_modules/assertion-error/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/assertion.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/config.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/core/assertions.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/assert.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/expect.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/should.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addChainableMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/expectTypes.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/flag.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getActual.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getEnumerableProperties.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getMessage.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getName.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getPathInfo.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getPathValue.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getProperties.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/hasProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/inspect.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/objDisplay.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/test.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/transferFlags.js","node_modules/.registry.npmjs.org/dedent/0.7.0/node_modules/dedent/dist/dedent.js","node_modules/.registry.npmjs.org/deep-eql/0.1.3/node_modules/deep-eql/index.js","node_modules/.registry.npmjs.org/deep-eql/0.1.3/node_modules/deep-eql/lib/eql.js","node_modules/.registry.npmjs.org/localforage/1.5.0/node_modules/localforage/dist/node_modules/localforage/dist/localforage.js","node_modules/.registry.npmjs.org/pjs-problems/1.0.3/node_modules/pjs-problems/index.js","node_modules/.registry.npmjs.org/pjs-problems/1.0.3/node_modules/pjs-problems/problems/arrays.js","node_modules/.registry.npmjs.org/pjs-problems/1.0.3/node_modules/pjs-problems/problems/initial.js","node_modules/.registry.npmjs.org/type-detect/0.1.1/node_modules/type-detect/index.js","node_modules/.registry.npmjs.org/type-detect/0.1.1/node_modules/type-detect/lib/type.js","node_modules/.registry.npmjs.org/type-detect/1.0.0/node_modules/type-detect/lib/type.js","src/js/index.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length","1","module","exclude","excludeProps","res","obj","Object","keys","forEach","key","excludes","indexOf","slice","arguments","args","AssertionError","message","_props","ssf","props","this","showDiff","callee","captureStackTrace","stack","prototype","create","name","constructor","toJSON","used","version","util","use","fn","push","config","assertion","core","expect","should","assert","_chai","Assertion","msg","flag","defineProperty","get","console","warn","includeStack","set","value","addProperty","addMethod","addChainableMethod","chainingBehavior","overwriteProperty","overwriteMethod","overwriteChainableMethod","expr","negateMsg","expected","_actual","ok","test","getMessage","actual","getActual","val","truncateThreshold","chai","_","an","type","toLowerCase","article","charAt","includeChainingBehavior","include","expectTypes","eql","k","property","subset","undefined","inspect","checkArguments","toString","assertEqual","_obj","assertEql","assertAbove","to","have","len","assertLeast","assertBelow","assertMost","assertInstanceOf","getName","assertOwnProperty","hasOwnProperty","assertOwnPropertyDescriptor","descriptor","actualDescriptor","getOwnPropertyDescriptor","assertLengthChain","assertLength","assertMatch","re","exec","assertKeys","str","mixedArgsMsg","Array","any","all","filter","every","last","map","pop","join","sort","assertThrows","errMsg","is","thrown","desiredError","thrownError","RegExp","err","actuallyGot","expectedThrown","respondTo","method","itself","context","satisfy","matcher","result","objDisplay","negate","closeTo","delta","Math","abs","isSubsetOf","superset","cmp","elem","some","elem2","oneOf","list","be","assertChanges","object","prop","initial","assertIncreases","assertDecreases","chain","isNaN","isArray","start","finish","range","isDeep","pathInfo","getPathInfo","hasProperty","exists","isExtensible","TypeError","isSealed","isFrozen","express","errmsg","fail","operator","isOk","isNotOk","not","equal","act","exp","notEqual","strictEqual","notStrictEqual","deepEqual","notDeepEqual","isAbove","abv","above","isAtLeast","atlst","least","isBelow","blw","below","isAtMost","atmst","most","isTrue","isNotTrue","isFalse","isNotFalse","isNull","isNotNull","NaN","isNotNaN","isUndefined","isDefined","isFunction","isNotFunction","isObject","isNotObject","isNotArray","isString","isNotString","isNumber","isNotNumber","isBoolean","isNotBoolean","typeOf","notTypeOf","instanceOf","notInstanceOf","inc","notInclude","match","notMatch","notProperty","deepProperty","deep","notDeepProperty","propertyVal","propertyNotVal","deepPropertyVal","deepPropertyNotVal","lengthOf","throws","errt","errs","assertErr","throw","doesNotThrow","Throw","val2","approximately","sameMembers","set1","set2","same","members","sameDeepMembers","includeMembers","includeDeepMembers","inList","changes","change","doesNotChange","increases","increase","doesNotIncrease","decreases","decrease","doesNotDecrease","ifError","extensible","isNotExtensible","sealed","isNotSealed","frozen","isNotFrozen","alias","as","loadShould","shouldGetter","String","Number","Boolean","valueOf","shouldSetter","enumerable","configurable","writable","val1","exist","Should","transferFlags","hasProtoSupport","excludeNames","Function","apply","ctx","chainableBehavior","__methods","__proto__","getOwnPropertyNames","asserterName","pd","getter","types","index","art","flags","__flags","flagMsg","replace","func","parsePath","path","mArr","parseFloat","p","_getPathValue","parsed","tmp","part","info","parent","proto","getPrototypeOf","literals","number","string","ot","getPathValue","showHidden","depth","colors","formatValue","seen","stylize","recurseTimes","ret","primitive","formatPrimitive","isDOMElement","outerHTML","document","xmlVersion","XMLSerializer","serializeToString","container","createElementNS","appendChild","cloneNode","html","innerHTML","visibleKeys","getEnumerableProperties","getProperties","isError","nameSuffix","isRegExp","isDate","Date","toUTCString","formatError","base","array","braces","output","formatArray","formatProperty","reduceToSingleString","simple","JSON","stringify","Infinity","__lookupGetter__","__lookupSetter__","split","line","substr","numLinesEst","reduce","prev","cur","ar","objectToString","d","HTMLElement","nodeType","nodeName","splice","_chainingBehavior","_method","_super","_get","includeAll","dedent","strings","raw","lines","mindent","m","indent","min","trim","b","sameValue","dateEqual","regexpEqual","Buffer","isBuffer","bufferEqual","argumentsEqual","typeEqual","objectEqual","getTime","iterableEqual","isValue","ka","kb","ex","define","amd","window","global","self","localforage","_dereq_","nextTick","draining","oldQueue","queue","immediate","task","scheduleDrain","Mutation","MutationObserver","WebKitMutationObserver","called","observer","element","createTextNode","observe","characterData","data","setImmediate","MessageChannel","createElement","scriptEl","onreadystatechange","parentNode","removeChild","documentElement","setTimeout","channel","port1","onmessage","port2","postMessage","2","INTERNAL","Promise","resolver","state","PENDING","outcome","safelyResolveThenable","QueueItem","promise","onFulfilled","onRejected","callFulfilled","otherCallFulfilled","callRejected","otherCallRejected","unwrap","returnValue","handlers","reject","resolve","getThen","then","thenable","onError","onSuccess","tryToUnwrap","tryCatch","status","out","reason","iterable","values","resolved","resolveFromAll","outValue","error","race","response","REJECTED","FULFILLED","3","4","_classCallCheck","instance","Constructor","createBlob","parts","properties","Blob","builder","BlobBuilder","MSBlobBuilder","MozBlobBuilder","WebKitBlobBuilder","append","getBlob","executeCallback","callback","executeTwoCallbacks","errorCallback","_binStringToArrayBuffer","bin","buf","ArrayBuffer","arr","Uint8Array","charCodeAt","_checkBlobSupportWithoutCaching","idb","Promise$1","txn","transaction","DETECT_BLOB_SUPPORT_STORE","blob","objectStore","put","onabort","preventDefault","stopPropagation","oncomplete","matchedChrome","navigator","userAgent","matchedEdge","parseInt","_checkBlobSupport","supportsBlobs","_deferReadiness","dbInfo","dbContext","dbContexts","deferredOperation","deferredOperations","dbReady","_advanceReadiness","_getConnection","upgradeNeeded","db","close","dbArgs","openreq","open","onupgradeneeded","createObjectStore","storeName","oldVersion","newVersion","onerror","onsuccess","_getOriginalConnection","_getUpgradedConnection","_isUpgradeNeeded","defaultVersion","isNewStore","objectStoreNames","contains","isDowngrade","isUpgrade","incVersion","_encodeBlob","reader","FileReader","onloadend","base64","btoa","target","__local_forage_encoded_blob","readAsBinaryString","_decodeBlob","encodedBlob","atob","_isEncodedBlob","_fullyReady","_initReady","_dbInfo","_initStorage","options","ignoreErrors","forages","ready","initPromises","j","forage","_defaultConfig","getItem","req","iterate","iterator","openCursor","iterationNumber","cursor","setItem","blobSupport","removeItem","clear","count","advanced","advance","stringToBuffer","serializedString","encoded1","encoded2","encoded3","encoded4","bufferLength","buffer","bytes","BASE_CHARS","bufferToString","base64String","substring","serialize","valueType","toString$1","marker","SERIALIZED_MARKER","TYPE_ARRAYBUFFER","TYPE_INT8ARRAY","TYPE_UINT8ARRAY","TYPE_UINT8CLAMPEDARRAY","TYPE_INT16ARRAY","TYPE_UINT16ARRAY","TYPE_INT32ARRAY","TYPE_UINT32ARRAY","TYPE_FLOAT32ARRAY","TYPE_FLOAT64ARRAY","fileReader","onload","BLOB_TYPE_PREFIX","TYPE_BLOB","readAsArrayBuffer","deserialize","SERIALIZED_MARKER_LENGTH","parse","blobType","TYPE_SERIALIZED_MARKER_LENGTH","BLOB_TYPE_PREFIX_REGEX","Int8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","_initStorage$1","dbInfoPromise","openDatabase","description","size","executeSql","serializer","localforageSerializer","getItem$1","results","rows","item","iterate$1","_setItem","retriesLeft","originalValue","sqlError","QUOTA_ERR","setItem$1","removeItem$1","clear$1","length$1","c","key$1","keys$1","_initStorage$2","keyPrefix","clear$2","localStorage","getItem$2","iterate$2","keyPrefixLength","key$2","keys$2","length$2","removeItem$2","setItem$2","callWhenReady","localForageInstance","libraryMethod","_args","extend","arg","isLibraryDriver","driverName","driver","DriverType","_typeof","Symbol","indexedDB","webkitIndexedDB","mozIndexedDB","OIndexedDB","msIndexedDB","asyncStorage","_driver","webSQLStorage","localStorageWrapper","CustomDrivers","INDEXEDDB","LOCALSTORAGE","WEBSQL","LibraryMethods","DefaultConfig","driverSupport","isSafari","platform","hasFetch","fetch","IDBKeyRange","localforage_js","LocalForage","_config","_driverSet","_initDriver","_ready","_wrapLibraryMethodsWithReady","setDriver","defineDriver","driverObject","complianceError","namingError","customDriverMethods","concat","customDriverMethod","supportPromise","_support","supportResult","getDriver","getDriverPromise","getSerializer","serializerPromise","drivers","setDriverToConfig","extendSelfWithDriver","_extend","initDriver","supportedDrivers","driverPromiseLoop","currentDriverIndex","_getSupportedDrivers","oldDriverSetDone","supports","libraryMethodsAndProperties","createInstance","arrays","time","prompt","given","answer","tests","getType","natives","Library","[object Array]","[object RegExp]","[object Function]","[object Arguments]","[object Date]","of","ReferenceError","objectTypeRegexp","dedentStrings","problems","prob","updateLocalstore","catch","log","debounce","wait","timeout","later","callNow","clearTimeout","getRandomIndex","problemsArr","ind","floor","random","currentIndex","getPreviousIndex","getNextIndex","getCurrentProblem","previousProblem","previousProblemButtonEl","classList","add","shuffle","location","reload","nextProblem","nextProblemButtonEl","toggleShuffle","shuffleProblemsButtonEl","toggle","loadProblem","problemObj","currentProblem","problemEl","innerText","codeEl","testSuite","updateTests","testStatus","init","buildTests","updateTestStatus","testsDom","testSuiteEl","testStatuses","allPassed","testPassed","querySelectorAll","testStatusEl","iter","remove","testTotalEl","printAssertError","errObj","inner","assertConsoleEl","printEvalOutput","evalConsoleEl","tested","runTests","getOutput","evald","eval","testOutcome","loadApp","problemNav","keyCode","shiftKey","metaKey","ctrlKey","debouncedInputValidation","ignoreKeyCodes","addEventListener","probs","subject","_problems","_toConsumableArray","timer","getElementById"],"mappings":"CAAA,SAAAA,EAAAC,EAAAC,EAAAC,GAAA,SAAAC,EAAAC,EAAAC,GAAA,IAAAJ,EAAAG,GAAA,CAAA,IAAAJ,EAAAI,GAAA,CAAA,IAAAE,EAAA,mBAAAC,SAAAA,QAAA,IAAAF,GAAAC,EAAA,OAAAA,EAAAF,GAAA,GAAA,GAAAI,EAAA,OAAAA,EAAAJ,GAAA,GAAA,IAAAK,EAAA,IAAAC,MAAA,uBAAAN,EAAA,KAAA,MAAAK,EAAAE,KAAA,mBAAAF,EAAA,IAAAG,EAAAX,EAAAG,IAAAS,YAAAb,EAAAI,GAAA,GAAAU,KAAAF,EAAAC,QAAA,SAAAd,GAAA,IAAAE,EAAAD,EAAAI,GAAA,GAAAL,GAAA,OAAAI,EAAAF,GAAAF,IAAAa,EAAAA,EAAAC,QAAAd,EAAAC,EAAAC,EAAAC,GAAA,OAAAD,EAAAG,GAAAS,QAAA,IAAA,IAAAL,EAAA,mBAAAD,SAAAA,QAAAH,EAAA,EAAAA,EAAAF,EAAAa,OAAAX,IAAAD,EAAAD,EAAAE,IAAA,OAAAD,IAAAa,GAAA,SAAAT,EAAAU,EAAAJ,GCeA,SAAAK,IAGA,SAAAC,EAAAC,EAAAC,GACAC,OAAAC,KAAAF,GAAAG,QAAA,SAAAC,IACAC,EAAAC,QAAAF,KAAAL,EAAAK,GAAAJ,EAAAI,MAJA,IAAAC,KAAAE,MAAAd,KAAAe,WAQA,OAAA,WAKA,IAJA,IAAAC,KAAAF,MAAAd,KAAAe,WACArB,EAAA,EACAY,KAEAZ,EAAAsB,EAAAf,OAAAP,IACAW,EAAAC,EAAAU,EAAAtB,IAGA,OAAAY,GAqBA,SAAAW,EAAAC,EAAAC,EAAAC,GACA,IACAC,EADAjB,EAAA,OAAA,UAAA,QAAA,cAAA,UACAe,OAGAG,KAAAJ,QAAAA,GAAA,6BACAI,KAAAC,UAAA,EAGA,IAAA,IAAAZ,KAAAU,EACAC,KAAAX,GAAAU,EAAAV,GAKA,IADAS,EAAAA,GAAAL,UAAAS,SACA5B,MAAA6B,kBACA7B,MAAA6B,kBAAAH,KAAAF,QAEA,IACA,MAAA,IAAAxB,MACA,MAAAX,GACAqC,KAAAI,MAAAzC,EAAAyC,OAlCAvB,EAAAJ,QAAAkB,EA2CAA,EAAAU,UAAAnB,OAAAoB,OAAAhC,MAAA+B,WAMAV,EAAAU,UAAAE,KAAA,iBAMAZ,EAAAU,UAAAG,YAAAb,EASAA,EAAAU,UAAAI,OAAA,SAAAL,GACA,IACAL,EADAjB,EAAA,cAAA,SAAA,UACAyB,KAAAP,KAAAO,MAAAP,MAOA,OAJA,IAAAI,GAAAJ,KAAAI,QACAL,EAAAK,MAAAJ,KAAAI,OAGAL,2BClHAlB,EAAAJ,QAAAN,EAAA,oDCMA,IAAAuC,MACAjC,EAAAI,EAAAJ,YAMAkC,QAAA,QAMAlC,EAAAkB,eAAAxB,EAAA,mBAMA,IAAAyC,EAAAzC,EAAA,gBAYAM,EAAAoC,IAAA,SAAAC,GAMA,OALAJ,EAAAnB,QAAAuB,KACAA,EAAAd,KAAAY,GACAF,EAAAK,KAAAD,IAGAd,MAOAvB,EAAAmC,KAAAA,EAMA,IAAAI,EAAA7C,EAAA,iBACAM,EAAAuC,OAAAA,EAMA,IAAAC,EAAA9C,EAAA,oBACAM,EAAAoC,IAAAI,GAMA,IAAAC,EAAA/C,EAAA,0BACAM,EAAAoC,IAAAK,GAMA,IAAAC,EAAAhD,EAAA,2BACAM,EAAAoC,IAAAM,GAMA,IAAAC,EAAAjD,EAAA,2BACAM,EAAAoC,IAAAO,GAMA,IAAAC,EAAAlD,EAAA,2BACAM,EAAAoC,IAAAQ,sNCrFA,IAAAL,EAAA7C,EAAA,YAEAU,EAAAJ,QAAA,SAAA6C,EAAAV,GAsBA,SAAAW,EAAAtC,EAAAuC,EAAApB,GACAqB,EAAAzB,KAAA,OAAAI,GAAAX,UAAAS,QACAuB,EAAAzB,KAAA,SAAAf,GACAwC,EAAAzB,KAAA,UAAAwB,GApBA,IAAA7B,EAAA2B,EAAA3B,eACA8B,EAAAb,EAAAa,KAMAH,EAAAC,UAAAA,EAgBArC,OAAAwC,eAAAH,EAAA,gBACAI,IAAA,WAEA,OADAC,QAAAC,KAAA,+EACAb,EAAAc,cAEAC,IAAA,SAAAC,GACAJ,QAAAC,KAAA,+EACAb,EAAAc,aAAAE,KAIA9C,OAAAwC,eAAAH,EAAA,YACAI,IAAA,WAEA,OADAC,QAAAC,KAAA,uEACAb,EAAAf,UAEA8B,IAAA,SAAAC,GACAJ,QAAAC,KAAA,uEACAb,EAAAf,SAAA+B,KAIAT,EAAAU,YAAA,SAAA1B,EAAAO,GACAF,EAAAqB,YAAAjC,KAAAK,UAAAE,EAAAO,IAGAS,EAAAW,UAAA,SAAA3B,EAAAO,GACAF,EAAAsB,UAAAlC,KAAAK,UAAAE,EAAAO,IAGAS,EAAAY,mBAAA,SAAA5B,EAAAO,EAAAsB,GACAxB,EAAAuB,mBAAAnC,KAAAK,UAAAE,EAAAO,EAAAsB,IAGAb,EAAAc,kBAAA,SAAA9B,EAAAO,GACAF,EAAAyB,kBAAArC,KAAAK,UAAAE,EAAAO,IAGAS,EAAAe,gBAAA,SAAA/B,EAAAO,GACAF,EAAA0B,gBAAAtC,KAAAK,UAAAE,EAAAO,IAGAS,EAAAgB,yBAAA,SAAAhC,EAAAO,EAAAsB,GACAxB,EAAA2B,yBAAAvC,KAAAK,UAAAE,EAAAO,EAAAsB,IAkBAb,EAAAlB,UAAAgB,OAAA,SAAAmB,EAAAhB,EAAAiB,EAAAC,EAAAC,EAAA1C,GACA,IAAA2C,EAAAhC,EAAAiC,KAAA7C,KAAAP,WAIA,IAHA,IAAAQ,IAAAA,GAAA,IACA,IAAAe,EAAAf,WAAAA,GAAA,IAEA2C,EAAA,CACA,IAAApB,EAAAZ,EAAAkC,WAAA9C,KAAAP,WACAsD,EAAAnC,EAAAoC,UAAAhD,KAAAP,WACA,MAAA,IAAAE,EAAA6B,GACAuB,OAAAA,EACAL,SAAAA,EACAzC,SAAAA,GACAe,EAAA,aAAAhB,KAAAqB,OAAAI,EAAAzB,KAAA,WAYAd,OAAAwC,eAAAH,EAAAlB,UAAA,QACAsB,IAAA,WACA,OAAAF,EAAAzB,KAAA,WAEA+B,IAAA,SAAAkB,GACAxB,EAAAzB,KAAA,SAAAiD,2CC/HApE,EAAAJ,SAeAqD,cAAA,EAeA7B,UAAA,EAsBAiD,kBAAA,4BC7CArE,EAAAJ,QAAA,SAAA0E,EAAAC,GA2JA,SAAAC,EAAAC,EAAA9B,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA8B,EAAAA,EAAAC,cACA,IAAAtE,EAAAwC,EAAAzB,KAAA,UACAwD,IAAA,IAAA,IAAA,IAAA,IAAA,KAAAjE,QAAA+D,EAAAG,OAAA,IAAA,MAAA,KAEAzD,KAAAqB,OACAiC,IAAAF,EAAAE,KAAArE,GACA,0BAAAuE,EAAAF,EACA,8BAAAE,EAAAF,GA6BA,SAAAI,IACAjC,EAAAzB,KAAA,YAAA,GAGA,SAAA2D,EAAAV,EAAAzB,GACA4B,EAAAQ,YAAA5D,MAAA,QAAA,SAAA,WAEAwB,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UACA0C,GAAA,EAEA,GAAA,UAAAU,EAAAE,KAAArE,IAAA,WAAAmE,EAAAE,KAAAL,IACA,IAAA,IAAA7E,KAAAa,EACA,GAAAmE,EAAAS,IAAA5E,EAAAb,GAAA6E,GAAA,CACAP,GAAA,EACA,YAGA,GAAA,WAAAU,EAAAE,KAAAL,GAAA,CACA,IAAAxB,EAAAzB,KAAA,UAAA,CACA,IAAA,IAAA8D,KAAAb,EAAA,IAAA1B,EAAAtC,GAAA8E,SAAAD,EAAAb,EAAAa,IACA,OAEA,IAAAE,KACA,IAAA,IAAAF,KAAAb,EAAAe,EAAAF,GAAA7E,EAAA6E,GACApB,EAAAU,EAAAS,IAAAG,EAAAf,QAEAP,OAAAuB,GAAAhF,IAAAA,EAAAM,QAAA0D,GAEAjD,KAAAqB,OACAqB,EACA,+BAAAU,EAAAc,QAAAjB,GACA,mCAAAG,EAAAc,QAAAjB,IAoNA,SAAAkB,IACA,IAAAlF,EAAAwC,EAAAzB,KAAA,UACAsD,EAAApE,OAAAmB,UAAA+D,SAAA1F,KAAAO,GACAe,KAAAqB,OACA,uBAAAiC,EACA,4CAAAA,EACA,wCA8BA,SAAAe,EAAApB,EAAAzB,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UACA,GAAAyB,EAAAzB,KAAA,QACA,OAAAA,KAAA6D,IAAAZ,GAEAjD,KAAAqB,OACA4B,IAAAhE,EACA,mCACA,uCACAgE,EACAjD,KAAAsE,MACA,GAyBA,SAAAC,EAAAtF,EAAAuC,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACAxB,KAAAqB,OACA+B,EAAAS,IAAA5E,EAAAwC,EAAAzB,KAAA,WACA,0CACA,8CACAf,EACAe,KAAAsE,MACA,GA+BA,SAAAE,EAAA3G,EAAA2D,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UACA,GAAAyB,EAAAzB,KAAA,YAAA,CACA,IAAAuB,EAAAtC,EAAAuC,GAAAiD,GAAAC,KAAAX,SAAA,UACA,IAAAY,EAAA1F,EAAAN,OACAqB,KAAAqB,OACAsD,EAAA9G,EACA,gEACA,qDACAA,EACA8G,QAGA3E,KAAAqB,OACApC,EAAApB,EACA,gCAAAA,EACA,kCAAAA,GAgCA,SAAA+G,EAAA/G,EAAA2D,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UACA,GAAAyB,EAAAzB,KAAA,YAAA,CACA,IAAAuB,EAAAtC,EAAAuC,GAAAiD,GAAAC,KAAAX,SAAA,UACA,IAAAY,EAAA1F,EAAAN,OACAqB,KAAAqB,OACAsD,GAAA9G,EACA,mEACA,iDACAA,EACA8G,QAGA3E,KAAAqB,OACApC,GAAApB,EACA,mCAAAA,EACA,gCAAAA,GAgCA,SAAAgH,EAAAhH,EAAA2D,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UACA,GAAAyB,EAAAzB,KAAA,YAAA,CACA,IAAAuB,EAAAtC,EAAAuC,GAAAiD,GAAAC,KAAAX,SAAA,UACA,IAAAY,EAAA1F,EAAAN,OACAqB,KAAAqB,OACAsD,EAAA9G,EACA,gEACA,qDACAA,EACA8G,QAGA3E,KAAAqB,OACApC,EAAApB,EACA,gCAAAA,EACA,mCAAAA,GAgCA,SAAAiH,EAAAjH,EAAA2D,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UACA,GAAAyB,EAAAzB,KAAA,YAAA,CACA,IAAAuB,EAAAtC,EAAAuC,GAAAiD,GAAAC,KAAAX,SAAA,UACA,IAAAY,EAAA1F,EAAAN,OACAqB,KAAAqB,OACAsD,GAAA9G,EACA,kEACA,iDACAA,EACA8G,QAGA3E,KAAAqB,OACApC,GAAApB,EACA,kCAAAA,EACA,gCAAAA,GAuEA,SAAAkH,EAAAvE,EAAAgB,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAjB,EAAA6C,EAAA4B,QAAAxE,GACAR,KAAAqB,OACAI,EAAAzB,KAAA,oBAAAQ,EACA,yCAAAD,EACA,6CAAAA,GAuIA,SAAA0E,EAAA1E,EAAAiB,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UACAA,KAAAqB,OACApC,EAAAiG,eAAA3E,GACA,yCAAA6C,EAAAc,QAAA3D,GACA,6CAAA6C,EAAAc,QAAA3D,IA2BA,SAAA4E,EAAA5E,EAAA6E,EAAA5D,GACA,iBAAA4D,IACA5D,EAAA4D,EACAA,EAAA,MAEA5D,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UACAqF,EAAAnG,OAAAoG,yBAAApG,OAAAD,GAAAsB,GACA8E,GAAAD,EACApF,KAAAqB,OACA+B,EAAAS,IAAAuB,EAAAC,GACA,4CAAAjC,EAAAc,QAAA3D,GAAA,wBAAA6C,EAAAc,QAAAkB,GAAA,SAAAhC,EAAAc,QAAAmB,GACA,4CAAAjC,EAAAc,QAAA3D,GAAA,4BAAA6C,EAAAc,QAAAkB,GACAA,EACAC,GACA,GAGArF,KAAAqB,OACAgE,EACA,2DAAAjC,EAAAc,QAAA3D,GACA,+DAAA6C,EAAAc,QAAA3D,IAGAkB,EAAAzB,KAAA,SAAAqF,GA6CA,SAAAE,IACA9D,EAAAzB,KAAA,YAAA,GAGA,SAAAwF,EAAA3H,EAAA2D,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UACA,IAAAuB,EAAAtC,EAAAuC,GAAAiD,GAAAC,KAAAX,SAAA,UACA,IAAAY,EAAA1F,EAAAN,OAEAqB,KAAAqB,OACAsD,GAAA9G,EACA,6DACA,kDACAA,EACA8G,GAqBA,SAAAc,EAAAC,EAAAlE,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UACAA,KAAAqB,OACAqE,EAAAC,KAAA1G,GACA,6BAAAyG,EACA,iCAAAA,GAyEA,SAAAE,EAAAzG,GACA,IACA0G,EADA5G,EAAAwC,EAAAzB,KAAA,UAEA4C,GAAA,EACAkD,EAAA,0FAEA,OAAA1C,EAAAE,KAAAnE,IACA,IAAA,QACA,GAAAM,UAAAd,OAAA,EAAA,MAAA,IAAAL,MAAAwH,GACA,MACA,IAAA,SACA,GAAArG,UAAAd,OAAA,EAAA,MAAA,IAAAL,MAAAwH,GACA3G,EAAAD,OAAAC,KAAAA,GACA,MACA,QACAA,EAAA4G,MAAA1F,UAAAb,MAAAd,KAAAe,WAGA,IAAAN,EAAAR,OAAA,MAAA,IAAAL,MAAA,iBAEA,IAAAyE,EAAA7D,OAAAC,KAAAF,GACAyD,EAAAvD,EACAwF,EAAAxF,EAAAR,OACAqH,EAAAvE,EAAAzB,KAAA,OACAiG,EAAAxE,EAAAzB,KAAA,OAyBA,GAvBAgG,GAAAC,IACAA,GAAA,GAIAD,IAIApD,EAHAF,EAAAwD,OAAA,SAAA7G,GACA,OAAA0D,EAAAxD,QAAAF,KAEAV,OAAA,GAIAsH,IACArD,EAAAzD,EAAAgH,MAAA,SAAA9G,GACA,OAAA0D,EAAAxD,QAAAF,KAEAoC,EAAAzB,KAAA,WAAAyB,EAAAzB,KAAA,cACA4C,EAAAA,GAAAzD,EAAAR,QAAAoE,EAAApE,SAKAgG,EAAA,EAAA,CAIA,IAAAyB,GAHAjH,EAAAA,EAAAkH,IAAA,SAAAhH,GACA,OAAA+D,EAAAc,QAAA7E,MAEAiH,MACAL,IACAJ,EAAA1G,EAAAoH,KAAA,MAAA,SAAAH,GAEAJ,IACAH,EAAA1G,EAAAoH,KAAA,MAAA,QAAAH,QAGAP,EAAAzC,EAAAc,QAAA/E,EAAA,IAIA0G,GAAAlB,EAAA,EAAA,QAAA,QAAAkB,EAGAA,GAAApE,EAAAzB,KAAA,YAAA,WAAA,SAAA6F,EAGA7F,KAAAqB,OACAuB,EACA,uBAAAiD,EACA,2BAAAA,EACAnD,EAAAlD,MAAA,GAAAgH,OACAzD,EAAAyD,QACA,GA2CA,SAAAC,EAAAjG,EAAAkG,EAAAlF,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UACA,IAAAuB,EAAAtC,EAAAuC,GAAAmF,GAAAzI,EAAA,YAEA,IAAA0I,GAAA,EACAC,EAAA,KACAtG,EAAA,KACAuG,EAAA,KAEA,IAAArH,UAAAd,QACA+H,EAAA,KACAlG,EAAA,MACAA,IAAAA,aAAAuG,QAAA,iBAAAvG,IACAkG,EAAAlG,EACAA,EAAA,MACAA,GAAAA,aAAAlC,OACAuI,EAAArG,EACAA,EAAA,KACAkG,EAAA,MACA,mBAAAlG,KACAD,EAAAC,EAAAH,UAAAE,OACA,UAAAA,GAAAC,IAAAlC,SACAiC,EAAAC,EAAAD,OAAA,IAAAC,GAAAD,MAGAC,EAAA,KAGA,IACAvB,IACA,MAAA+H,GAEA,GAAAH,EAUA,OATA7G,KAAAqB,OACA2F,IAAAH,EACA,yDACA,uCACAA,aAAAvI,MAAAuI,EAAAzC,WAAAyC,EACAG,aAAA1I,MAAA0I,EAAA5C,WAAA4C,GAGAvF,EAAAzB,KAAA,SAAAgH,GACAhH,KAIA,GAAAQ,IACAR,KAAAqB,OACA2F,aAAAxG,EACA,yDACA,6DACAD,EACAyG,aAAA1I,MAAA0I,EAAA5C,WAAA4C,IAGAN,GAEA,OADAjF,EAAAzB,KAAA,SAAAgH,GACAhH,KAKA,IAAAJ,EAAA,UAAAwD,EAAAE,KAAA0D,IAAA,YAAAA,EACAA,EAAApH,QACA,GAAAoH,EAEA,GAAA,MAAApH,GAAA8G,GAAAA,aAAAK,OAUA,OATA/G,KAAAqB,OACAqF,EAAAf,KAAA/F,GACA,iEACA,sDACA8G,EACA9G,GAGA6B,EAAAzB,KAAA,SAAAgH,GACAhH,KACA,GAAA,MAAAJ,GAAA8G,GAAA,iBAAAA,EAUA,OATA1G,KAAAqB,QACAzB,EAAAL,QAAAmH,GACA,kEACA,uDACAA,EACA9G,GAGA6B,EAAAzB,KAAA,SAAAgH,GACAhH,KAEA4G,GAAA,EACAE,EAAAE,EAIA,IAAAC,EAAA,GACAC,EAAA,OAAA3G,EACAA,EACAsG,EACA,SACA,WAEAD,IACAK,EAAA,0BAGAjH,KAAAqB,QACA,IAAAuF,EACA,6BAAAM,EAAAD,EACA,iCAAAC,EAAAD,EACAJ,aAAAvI,MAAAuI,EAAAzC,WAAAyC,EACAC,aAAAxI,MAAAwI,EAAA1C,WAAA0C,GAGArF,EAAAzB,KAAA,SAAA8G,GA8BA,SAAAK,EAAAC,EAAA5F,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UACAqH,EAAA5F,EAAAzB,KAAA,UACAsH,EAAA,aAAAlE,EAAAE,KAAArE,IAAAoI,EAEApI,EAAAmI,GADAnI,EAAAoB,UAAA+G,GAGApH,KAAAqB,OACA,mBAAAiG,EACA,kCAAAlE,EAAAc,QAAAkD,GACA,sCAAAhE,EAAAc,QAAAkD,IA2CA,SAAAG,EAAAC,EAAAhG,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IACAiG,EAAAD,EADA/F,EAAAzB,KAAA,WAEAA,KAAAqB,OACAoG,EACA,+BAAArE,EAAAsE,WAAAF,GACA,kCAAApE,EAAAsE,WAAAF,IACAxH,KAAA2H,OACAF,GAuBA,SAAAG,EAAAlF,EAAAmF,EAAArG,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UAGA,GADA,IAAAuB,EAAAtC,EAAAuC,GAAAmF,GAAAzI,EAAA,UACA,WAAAkF,EAAAE,KAAAZ,IAAA,WAAAU,EAAAE,KAAAuE,GACA,MAAA,IAAAvJ,MAAA,6DAGA0B,KAAAqB,OACAyG,KAAAC,IAAA9I,EAAAyD,IAAAmF,EACA,mCAAAnF,EAAA,QAAAmF,EACA,uCAAAnF,EAAA,QAAAmF,GAOA,SAAAG,EAAAhE,EAAAiE,EAAAC,GACA,OAAAlE,EAAAmC,MAAA,SAAAgC,GACA,OAAAD,EAEAD,EAAAG,KAAA,SAAAC,GACA,OAAAH,EAAAC,EAAAE,MAHA,IAAAJ,EAAA1I,QAAA4I,KAiFA,SAAAG,EAAAC,EAAA/G,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAkB,EAAAjB,EAAAzB,KAAA,UACA,IAAAuB,EAAAgH,GAAA9D,GAAA+D,GAAAnF,GAAA,SAEArD,KAAAqB,OACAkH,EAAAhJ,QAAAmD,IAAA,EACA,uCACA,2CACA6F,EACA7F,GA4BA,SAAA+F,EAAAC,EAAAC,EAAAnH,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAV,EAAAW,EAAAzB,KAAA,UACA,IAAAuB,EAAAmH,EAAAlH,GAAAiD,GAAAC,KAAAX,SAAA4E,GACA,IAAApH,EAAAT,GAAA6F,GAAAzI,EAAA,YAEA,IAAA0K,EAAAF,EAAAC,GACA7H,IAEAd,KAAAqB,OACAuH,IAAAF,EAAAC,GACA,aAAAA,EAAA,aACA,aAAAA,EAAA,kBA0BA,SAAAE,EAAAH,EAAAC,EAAAnH,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAV,EAAAW,EAAAzB,KAAA,UACA,IAAAuB,EAAAmH,EAAAlH,GAAAiD,GAAAC,KAAAX,SAAA4E,GACA,IAAApH,EAAAT,GAAA6F,GAAAzI,EAAA,YAEA,IAAA0K,EAAAF,EAAAC,GACA7H,IAEAd,KAAAqB,OACAqH,EAAAC,GAAAC,EAAA,EACA,aAAAD,EAAA,eACA,aAAAA,EAAA,oBA0BA,SAAAG,EAAAJ,EAAAC,EAAAnH,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAV,EAAAW,EAAAzB,KAAA,UACA,IAAAuB,EAAAmH,EAAAlH,GAAAiD,GAAAC,KAAAX,SAAA4E,GACA,IAAApH,EAAAT,GAAA6F,GAAAzI,EAAA,YAEA,IAAA0K,EAAAF,EAAAC,GACA7H,IAEAd,KAAAqB,OACAqH,EAAAC,GAAAC,EAAA,EACA,aAAAD,EAAA,eACA,aAAAA,EAAA,oBAvrDA,IAAApH,EAAA4B,EAAA5B,UAEAE,GADAvC,OAAAmB,UAAA+D,SACAhB,EAAA3B,OA+BA,KAAA,KAAA,OACA,KAAA,MAAA,MAAA,OACA,OAAA,OAAA,QAAA,KACA,KAAA,QAAArC,QAAA,SAAA2J,GACAxH,EAAAU,YAAA8G,EAAA,WACA,OAAA/I,SAmBAuB,EAAAU,YAAA,MAAA,WACAR,EAAAzB,KAAA,UAAA,KAwBAuB,EAAAU,YAAA,OAAA,WACAR,EAAAzB,KAAA,QAAA,KAgBAuB,EAAAU,YAAA,MAAA,WACAR,EAAAzB,KAAA,OAAA,GACAyB,EAAAzB,KAAA,OAAA,KAiBAuB,EAAAU,YAAA,MAAA,WACAR,EAAAzB,KAAA,OAAA,GACAyB,EAAAzB,KAAA,OAAA,KA+CAuB,EAAAY,mBAAA,KAAAkB,GACA9B,EAAAY,mBAAA,IAAAkB,GA2DA9B,EAAAY,mBAAA,UAAAwB,EAAAD,GACAnC,EAAAY,mBAAA,UAAAwB,EAAAD,GACAnC,EAAAY,mBAAA,WAAAwB,EAAAD,GACAnC,EAAAY,mBAAA,WAAAwB,EAAAD,GAkBAnC,EAAAU,YAAA,KAAA,WACAjC,KAAAqB,OACAI,EAAAzB,KAAA,UACA,gCACA,kCAgBAuB,EAAAU,YAAA,OAAA,WACAjC,KAAAqB,QACA,IAAAI,EAAAzB,KAAA,UACA,8BACA,gCACAA,KAAA2H,UAiBApG,EAAAU,YAAA,QAAA,WACAjC,KAAAqB,QACA,IAAAI,EAAAzB,KAAA,UACA,+BACA,gCACAA,KAAA2H,UAiBApG,EAAAU,YAAA,OAAA,WACAjC,KAAAqB,OACA,OAAAI,EAAAzB,KAAA,UACA,8BACA,qCAiBAuB,EAAAU,YAAA,YAAA,WACAjC,KAAAqB,YACA4C,IAAAxC,EAAAzB,KAAA,UACA,mCACA,0CAgBAuB,EAAAU,YAAA,MAAA,WACAjC,KAAAqB,OACA2H,MAAAvH,EAAAzB,KAAA,WACA,6BACA,oCAsBAuB,EAAAU,YAAA,QAAA,WACAjC,KAAAqB,OACA,MAAAI,EAAAzB,KAAA,UACA,4BACA,mCAqBAuB,EAAAU,YAAA,QAAA,WACA,IAAAhD,EAAAwC,EAAAzB,KAAA,UACA0C,EAAAzD,EAEA8G,MAAAkD,QAAAhK,IAAA,iBAAAyJ,OACAhG,EAAAzD,EAAAN,OACA,iBAAAM,IACAyD,EAAAxD,OAAAC,KAAAF,GAAAN,QAGAqB,KAAAqB,QACAqB,EACA,+BACA,sCA6BAnB,EAAAU,YAAA,YAAAkC,GACA5C,EAAAU,YAAA,YAAAkC,GA0CA5C,EAAAW,UAAA,QAAAmC,GACA9C,EAAAW,UAAA,SAAAmC,GACA9C,EAAAW,UAAA,KAAAmC,GA8BA9C,EAAAW,UAAA,MAAAqC,GACAhD,EAAAW,UAAA,OAAAqC,GAgDAhD,EAAAW,UAAA,QAAAsC,GACAjD,EAAAW,UAAA,KAAAsC,GACAjD,EAAAW,UAAA,cAAAsC,GA+CAjD,EAAAW,UAAA,QAAA0C,GACArD,EAAAW,UAAA,MAAA0C,GAgDArD,EAAAW,UAAA,QAAA2C,GACAtD,EAAAW,UAAA,KAAA2C,GACAtD,EAAAW,UAAA,WAAA2C,GA+CAtD,EAAAW,UAAA,OAAA4C,GACAvD,EAAAW,UAAA,MAAA4C,GAyBAvD,EAAAW,UAAA,SAAA,SAAAgH,EAAAC,EAAA3H,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UACAoJ,EAAAF,EAAA,KAAAC,EACA,GAAA1H,EAAAzB,KAAA,YAAA,CACA,IAAAuB,EAAAtC,EAAAuC,GAAAiD,GAAAC,KAAAX,SAAA,UACA,IAAAY,EAAA1F,EAAAN,OACAqB,KAAAqB,OACAsD,GAAAuE,GAAAvE,GAAAwE,EACA,4CAAAC,EACA,gDAAAA,QAGApJ,KAAAqB,OACApC,GAAAiK,GAAAjK,GAAAkK,EACA,iCAAAC,EACA,qCAAAA,KAkCA7H,EAAAW,UAAA,aAAA6C,GACAxD,EAAAW,UAAA,aAAA6C,GA0EAxD,EAAAW,UAAA,WAAA,SAAA3B,EAAA0C,EAAAzB,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GAEA,IAAA6H,IAAA5H,EAAAzB,KAAA,QACAoF,EAAAiE,EAAA,iBAAA,YACA1B,EAAAlG,EAAAzB,KAAA,UACAf,EAAAwC,EAAAzB,KAAA,UACAsJ,EAAAD,EAAAjG,EAAAmG,YAAAhJ,EAAAtB,GAAA,KACAuK,EAAAH,EACAC,EAAAG,OACArG,EAAAoG,YAAAjJ,EAAAtB,GACA+C,EAAAqH,EACAC,EAAAtH,MACA/C,EAAAsB,GAEA,GAAAoH,GAAAlI,UAAAd,OAAA,GACA,QAAAsF,IAAAjC,EAEA,MADAR,EAAA,MAAAA,EAAAA,EAAA,KAAA,GACA,IAAAlD,MAAAkD,EAAA4B,EAAAc,QAAAjF,GAAA,WAAAmG,EAAAhC,EAAAc,QAAA3D,SAGAP,KAAAqB,OACAmI,EACA,8BAAApE,EAAAhC,EAAAc,QAAA3D,GACA,gCAAA6E,EAAAhC,EAAAc,QAAA3D,IAGAd,UAAAd,OAAA,GACAqB,KAAAqB,OACA4B,IAAAjB,EACA,8BAAAoD,EAAAhC,EAAAc,QAAA3D,GAAA,6BACA,kCAAA6E,EAAAhC,EAAAc,QAAA3D,GAAA,aACA0C,EACAjB,GAIAP,EAAAzB,KAAA,SAAAgC,KA6BAT,EAAAW,UAAA,cAAA+C,GACA1D,EAAAW,UAAA,kBAAA+C,GAiDA1D,EAAAW,UAAA,wBAAAiD,GACA5D,EAAAW,UAAA,4BAAAiD,GA4DA5D,EAAAY,mBAAA,SAAAqD,EAAAD,GACAhE,EAAAW,UAAA,WAAAsD,GA0BAjE,EAAAW,UAAA,QAAAuD,GACAlE,EAAAW,UAAA,UAAAuD,GAgBAlE,EAAAW,UAAA,SAAA,SAAA2D,EAAArE,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UACA,IAAAuB,EAAAtC,EAAAuC,GAAAmF,GAAAzI,EAAA,UAEA8B,KAAAqB,QACApC,EAAAM,QAAAsG,GACA,+BAAAzC,EAAAc,QAAA2B,GACA,mCAAAzC,EAAAc,QAAA2B,MA6HAtE,EAAAW,UAAA,OAAA0D,GACArE,EAAAW,UAAA,MAAA0D,GA2JArE,EAAAW,UAAA,QAAAuE,GACAlF,EAAAW,UAAA,SAAAuE,GACAlF,EAAAW,UAAA,QAAAuE,GAwCAlF,EAAAW,UAAA,YAAAiF,GACA5F,EAAAW,UAAA,aAAAiF,GAmBA5F,EAAAU,YAAA,SAAA,WACAR,EAAAzB,KAAA,UAAA,KA+BAuB,EAAAW,UAAA,UAAAqF,GACAhG,EAAAW,UAAA,YAAAqF,GAkCAhG,EAAAW,UAAA,UAAA0F,GACArG,EAAAW,UAAA,gBAAA0F,GAmCArG,EAAAW,UAAA,UAAA,SAAA8B,EAAAxC,GACAA,GAAAC,EAAAzB,KAAA,UAAAwB,GACA,IAAAvC,EAAAwC,EAAAzB,KAAA,UAEA,IAAAuB,EAAAtC,GAAAwF,GAAA+D,GAAAnF,GAAA,SACA,IAAA9B,EAAAyC,GAAAS,GAAA+D,GAAAnF,GAAA,SAEA,IAAA6E,EAAAzG,EAAAzB,KAAA,QAAAoD,EAAAS,SAAAI,EAEA,GAAAxC,EAAAzB,KAAA,YACA,OAAAA,KAAAqB,OACA2G,EAAAhE,EAAA/E,EAAAiJ,GACA,8CACA,kDACAjJ,EACA+E,GAIAhE,KAAAqB,OACA2G,EAAA/I,EAAA+E,EAAAkE,IAAAF,EAAAhE,EAAA/E,EAAAiJ,GACA,sDACA,0DACAjJ,EACA+E,KAwCAzC,EAAAW,UAAA,QAAAoG,GAwCA/G,EAAAY,mBAAA,SAAAsG,GACAlH,EAAAY,mBAAA,UAAAsG,GAqCAlH,EAAAY,mBAAA,WAAA0G,GACAtH,EAAAY,mBAAA,YAAA0G,GAqCAtH,EAAAY,mBAAA,WAAA2G,GACAvH,EAAAY,mBAAA,YAAA2G,GAsBAvH,EAAAU,YAAA,aAAA,WACA,IAOAyH,EAPAzK,EAAAwC,EAAAzB,KAAA,UASA,IACA0J,EAAAxK,OAAAwK,aAAAzK,GACA,MAAA+H,GACA,KAAAA,aAAA2C,WACA,MAAA3C,EADA0C,GAAA,EAIA1J,KAAAqB,OACAqI,EACA,oCACA,2CAsBAnI,EAAAU,YAAA,SAAA,WACA,IAOA2H,EAPA3K,EAAAwC,EAAAzB,KAAA,UASA,IACA4J,EAAA1K,OAAA0K,SAAA3K,GACA,MAAA+H,GACA,KAAAA,aAAA2C,WACA,MAAA3C,EADA4C,GAAA,EAIA5J,KAAAqB,OACAuI,EACA,gCACA,uCAoBArI,EAAAU,YAAA,SAAA,WACA,IAOA4H,EAPA5K,EAAAwC,EAAAzB,KAAA,UASA,IACA6J,EAAA3K,OAAA2K,SAAA5K,GACA,MAAA+H,GACA,KAAAA,aAAA2C,WACA,MAAA3C,EADA6C,GAAA,EAIA7J,KAAAqB,OACAwI,EACA,gCACA,gECzzDAhL,EAAAJ,QAAA,SAAA0E,EAAAvC,GAMA,IAAAW,EAAA4B,EAAA5B,UACAE,EAAAb,EAAAa,KAqBAJ,EAAA8B,EAAA9B,OAAA,SAAAyI,EAAAC,GACA,IAAAxI,EAAA,KAAA,KAAA4B,EAAA9B,QACAA,OACAyI,EACAC,EACA,qCAkBA1I,EAAA2I,KAAA,SAAAjH,EAAAL,EAAA9C,EAAAqK,GAEA,MADArK,EAAAA,GAAA,gBACA,IAAAuD,EAAAxD,eAAAC,GACAmD,OAAAA,EACAL,SAAAA,EACAuH,SAAAA,GACA5I,EAAA2I,OAmBA3I,EAAA6I,KAAA,SAAAjH,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAmF,GAAA/D,IAmBAvB,EAAA8I,QAAA,SAAAlH,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAmF,GAAAyD,IAAAxH,IAkBAvB,EAAAgJ,MAAA,SAAAC,EAAAC,EAAA/I,GACA,IAAAqB,EAAA,IAAAtB,EAAA+I,EAAA9I,EAAAH,EAAAgJ,OAEAxH,EAAAxB,OACAkJ,GAAA9I,EAAAoB,EAAA,UACA,mCACA,uCACA0H,EACAD,IAmBAjJ,EAAAmJ,SAAA,SAAAF,EAAAC,EAAA/I,GACA,IAAAqB,EAAA,IAAAtB,EAAA+I,EAAA9I,EAAAH,EAAAmJ,UAEA3H,EAAAxB,OACAkJ,GAAA9I,EAAAoB,EAAA,UACA,uCACA,mCACA0H,EACAD,IAmBAjJ,EAAAoJ,YAAA,SAAAH,EAAAC,EAAA/I,GACA,IAAAD,EAAA+I,EAAA9I,GAAAiD,GAAA4F,MAAAE,IAkBAlJ,EAAAqJ,eAAA,SAAAJ,EAAAC,EAAA/I,GACA,IAAAD,EAAA+I,EAAA9I,GAAAiD,GAAA2F,IAAAC,MAAAE,IAkBAlJ,EAAAsJ,UAAA,SAAAL,EAAAC,EAAA/I,GACA,IAAAD,EAAA+I,EAAA9I,GAAAiD,GAAAZ,IAAA0G,IAkBAlJ,EAAAuJ,aAAA,SAAAN,EAAAC,EAAA/I,GACA,IAAAD,EAAA+I,EAAA9I,GAAAiD,GAAA2F,IAAAvG,IAAA0G,IAkBAlJ,EAAAwJ,QAAA,SAAA5H,EAAA6H,EAAAtJ,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA+D,GAAAuC,MAAAD,IAmBAzJ,EAAA2J,UAAA,SAAA/H,EAAAgI,EAAAzJ,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA+D,GAAA0C,MAAAD,IAkBA5J,EAAA8J,QAAA,SAAAlI,EAAAmI,EAAA5J,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA+D,GAAA6C,MAAAD,IAmBA/J,EAAAiK,SAAA,SAAArI,EAAAsI,EAAA/J,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA+D,GAAAgD,KAAAD,IAkBAlK,EAAAoK,OAAA,SAAAxI,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAmF,GAAA,MAkBAtF,EAAAqK,UAAA,SAAAzI,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA2F,IAAAC,OAAA,IAkBAhJ,EAAAsK,QAAA,SAAA1I,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAmF,GAAA,OAkBAtF,EAAAuK,WAAA,SAAA3I,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA2F,IAAAC,OAAA,IAiBAhJ,EAAAwK,OAAA,SAAA5I,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA4F,MAAA,OAkBAhJ,EAAAyK,UAAA,SAAA7I,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA2F,IAAAC,MAAA,OAgBAhJ,EAAA2H,MAAA,SAAA/F,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA+D,GAAAuD,KAeA1K,EAAA2K,SAAA,SAAA/I,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAA4I,IAAA3F,GAAA+D,GAAAuD,KAkBA1K,EAAA4K,YAAA,SAAAhJ,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA4F,WAAApG,IAkBA5C,EAAA6K,UAAA,SAAAjJ,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA2F,IAAAC,WAAApG,IAkBA5C,EAAA8K,WAAA,SAAAlJ,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA+D,GAAAtK,EAAA,aAkBAmD,EAAA+K,cAAA,SAAAnJ,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA2F,IAAA5B,GAAAtK,EAAA,aAmBAmD,EAAAgL,SAAA,SAAApJ,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA+D,GAAAtK,EAAA,WAmBAmD,EAAAiL,YAAA,SAAArJ,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA2F,IAAA5B,GAAAtK,EAAA,WAkBAmD,EAAA4H,QAAA,SAAAhG,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA+D,GAAAnF,GAAA,UAkBAhC,EAAAkL,WAAA,SAAAtJ,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA2F,IAAA5B,GAAAnF,GAAA,UAkBAhC,EAAAmL,SAAA,SAAAvJ,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA+D,GAAAtK,EAAA,WAkBAmD,EAAAoL,YAAA,SAAAxJ,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA2F,IAAA5B,GAAAtK,EAAA,WAkBAmD,EAAAqL,SAAA,SAAAzJ,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA+D,GAAAtK,EAAA,WAkBAmD,EAAAsL,YAAA,SAAA1J,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA2F,IAAA5B,GAAAtK,EAAA,WAqBAmD,EAAAuL,UAAA,SAAA3J,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA+D,GAAAtK,EAAA,YAqBAmD,EAAAwL,aAAA,SAAA5J,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA2F,IAAA5B,GAAAtK,EAAA,YAwBAmD,EAAAyL,OAAA,SAAA7J,EAAAK,EAAA9B,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA+D,GAAAtK,EAAAoF,IAmBAjC,EAAA0L,UAAA,SAAA9J,EAAAK,EAAA9B,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA2F,IAAA5B,GAAAtK,EAAAoF,IAqBAjC,EAAA2L,WAAA,SAAA/J,EAAAK,EAAA9B,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA+D,GAAAwE,WAAA1J,IAqBAjC,EAAA4L,cAAA,SAAAhK,EAAAK,EAAA9B,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA2F,IAAA5B,GAAAwE,WAAA1J,IAoBAjC,EAAAsC,QAAA,SAAA4G,EAAA2C,EAAA1L,GACA,IAAAD,EAAAgJ,EAAA/I,EAAAH,EAAAsC,SAAAA,QAAAuJ,IAoBA7L,EAAA8L,WAAA,SAAA5C,EAAA2C,EAAA1L,GACA,IAAAD,EAAAgJ,EAAA/I,EAAAH,EAAA8L,YAAA/C,IAAAzG,QAAAuJ,IAkBA7L,EAAA+L,MAAA,SAAA7C,EAAA7E,EAAAlE,GACA,IAAAD,EAAAgJ,EAAA/I,GAAAiD,GAAA2I,MAAA1H,IAkBArE,EAAAgM,SAAA,SAAA9C,EAAA7E,EAAAlE,GACA,IAAAD,EAAAgJ,EAAA/I,GAAAiD,GAAA2F,IAAAgD,MAAA1H,IAkBArE,EAAA0C,SAAA,SAAA9E,EAAA0J,EAAAnH,GACA,IAAAD,EAAAtC,EAAAuC,GAAAiD,GAAAC,KAAAX,SAAA4E,IAkBAtH,EAAAiM,YAAA,SAAArO,EAAA0J,EAAAnH,GACA,IAAAD,EAAAtC,EAAAuC,GAAAiD,GAAA2F,IAAA1F,KAAAX,SAAA4E,IAmBAtH,EAAAkM,aAAA,SAAAtO,EAAA0J,EAAAnH,GACA,IAAAD,EAAAtC,EAAAuC,GAAAiD,GAAAC,KAAA8I,KAAAzJ,SAAA4E,IAmBAtH,EAAAoM,gBAAA,SAAAxO,EAAA0J,EAAAnH,GACA,IAAAD,EAAAtC,EAAAuC,GAAAiD,GAAA2F,IAAA1F,KAAA8I,KAAAzJ,SAAA4E,IAoBAtH,EAAAqM,YAAA,SAAAzO,EAAA0J,EAAA1F,EAAAzB,GACA,IAAAD,EAAAtC,EAAAuC,GAAAiD,GAAAC,KAAAX,SAAA4E,EAAA1F,IAoBA5B,EAAAsM,eAAA,SAAA1O,EAAA0J,EAAA1F,EAAAzB,GACA,IAAAD,EAAAtC,EAAAuC,GAAAiD,GAAA2F,IAAA1F,KAAAX,SAAA4E,EAAA1F,IAqBA5B,EAAAuM,gBAAA,SAAA3O,EAAA0J,EAAA1F,EAAAzB,GACA,IAAAD,EAAAtC,EAAAuC,GAAAiD,GAAAC,KAAA8I,KAAAzJ,SAAA4E,EAAA1F,IAqBA5B,EAAAwM,mBAAA,SAAA5O,EAAA0J,EAAA1F,EAAAzB,GACA,IAAAD,EAAAtC,EAAAuC,GAAAiD,GAAA2F,IAAA1F,KAAA8I,KAAAzJ,SAAA4E,EAAA1F,IAmBA5B,EAAAyM,SAAA,SAAAvD,EAAA5F,EAAAnD,GACA,IAAAD,EAAAgJ,EAAA/I,GAAAiD,GAAAC,KAAA/F,OAAAgG,IA4BAtD,EAAA0M,OAAA,SAAAjN,EAAAkN,EAAAC,EAAAzM,IACA,iBAAAwM,GAAAA,aAAAjH,UACAkH,EAAAD,EACAA,EAAA,MAGA,IAAAE,EAAA,IAAA3M,EAAAT,EAAAU,GAAAiD,GAAA0J,MAAAH,EAAAC,GACA,OAAAxM,EAAAyM,EAAA,WAsBA7M,EAAA+M,aAAA,SAAAtN,EAAAwC,EAAA9B,GACA,iBAAA8B,IACA9B,EAAA8B,EACAA,EAAA,MAGA,IAAA/B,EAAAT,EAAAU,GAAAiD,GAAA2F,IAAAiE,MAAA/K,IAoBAjC,EAAA4I,SAAA,SAAAhH,EAAAgH,EAAAqE,EAAA9M,GACA,IAAAoB,EACA,OAAAqH,GACA,IAAA,KACArH,EAAAK,GAAAqL,EACA,MACA,IAAA,MACA1L,EAAAK,IAAAqL,EACA,MACA,IAAA,IACA1L,EAAAK,EAAAqL,EACA,MACA,IAAA,KACA1L,EAAAK,GAAAqL,EACA,MACA,IAAA,IACA1L,EAAAK,EAAAqL,EACA,MACA,IAAA,KACA1L,EAAAK,GAAAqL,EACA,MACA,IAAA,KACA1L,EAAAK,GAAAqL,EACA,MACA,IAAA,MACA1L,EAAAK,IAAAqL,EACA,MACA,QACA,MAAA,IAAAhQ,MAAA,qBAAA2L,EAAA,KAEA,IAAApH,EAAA,IAAAtB,EAAAqB,EAAApB,GACAqB,EAAAxB,QACA,IAAAI,EAAAoB,EAAA,UACA,YAAAjC,EAAAsD,QAAAjB,GAAA,UAAAgH,EAAA,IAAArJ,EAAAsD,QAAAoK,GACA,YAAA1N,EAAAsD,QAAAjB,GAAA,cAAAgH,EAAA,IAAArJ,EAAAsD,QAAAoK,KAmBAjN,EAAAuG,QAAA,SAAA0C,EAAAC,EAAA1C,EAAArG,GACA,IAAAD,EAAA+I,EAAA9I,GAAAiD,GAAA+D,GAAAZ,QAAA2C,EAAA1C,IAmBAxG,EAAAkN,cAAA,SAAAjE,EAAAC,EAAA1C,EAAArG,GACA,IAAAD,EAAA+I,EAAA9I,GAAAiD,GAAA+D,GAAA+F,cAAAhE,EAAA1C,IAmBAxG,EAAAmN,YAAA,SAAAC,EAAAC,EAAAlN,GACA,IAAAD,EAAAkN,EAAAjN,GAAAiD,GAAAC,KAAAiK,KAAAC,QAAAF,IAmBArN,EAAAwN,gBAAA,SAAAJ,EAAAC,EAAAlN,GACA,IAAAD,EAAAkN,EAAAjN,GAAAiD,GAAAC,KAAAiK,KAAAnB,KAAAoB,QAAAF,IAmBArN,EAAAyN,eAAA,SAAA7G,EAAAjE,EAAAxC,GACA,IAAAD,EAAA0G,EAAAzG,GAAAiD,GAAAd,QAAAiL,QAAA5K,IAoBA3C,EAAA0N,mBAAA,SAAA9G,EAAAjE,EAAAxC,GACA,IAAAD,EAAA0G,EAAAzG,GAAAiD,GAAAd,QAAA6J,KAAAoB,QAAA5K,IAkBA3C,EAAAiH,MAAA,SAAA0G,EAAAzG,EAAA/G,GACA,IAAAD,EAAAyN,EAAAxN,GAAAiD,GAAA+D,GAAAF,MAAAC,IAqBAlH,EAAA4N,QAAA,SAAAnO,EAAA7B,EAAA0J,GACA,IAAApH,EAAAT,GAAA2D,GAAAyK,OAAAjQ,EAAA0J,IAqBAtH,EAAA8N,cAAA,SAAArO,EAAA7B,EAAA0J,GACA,IAAApH,EAAAT,GAAA2D,GAAA2F,IAAA8E,OAAAjQ,EAAA0J,IAqBAtH,EAAA+N,UAAA,SAAAtO,EAAA7B,EAAA0J,GACA,IAAApH,EAAAT,GAAA2D,GAAA4K,SAAApQ,EAAA0J,IAqBAtH,EAAAiO,gBAAA,SAAAxO,EAAA7B,EAAA0J,GACA,IAAApH,EAAAT,GAAA2D,GAAA2F,IAAAiF,SAAApQ,EAAA0J,IAqBAtH,EAAAkO,UAAA,SAAAzO,EAAA7B,EAAA0J,GACA,IAAApH,EAAAT,GAAA2D,GAAA+K,SAAAvQ,EAAA0J,IAqBAtH,EAAAoO,gBAAA,SAAA3O,EAAA7B,EAAA0J,GACA,IAAApH,EAAAT,GAAA2D,GAAA2F,IAAAoF,SAAAvQ,EAAA0J,IAmBAtH,EAAAqO,QAAA,SAAAzM,GACA,GAAAA,EACA,MAAA,GAmBA5B,EAAAqI,aAAA,SAAAzK,EAAAuC,GACA,IAAAD,EAAAtC,EAAAuC,GAAAiD,GAAA+D,GAAAmH,YAwBAtO,EAAAuO,gBAAA,SAAA3Q,EAAAuC,GACA,IAAAD,EAAAtC,EAAAuC,GAAAiD,GAAA2F,IAAA5B,GAAAmH,YAuBAtO,EAAAuI,SAAA,SAAA3K,EAAAuC,GACA,IAAAD,EAAAtC,EAAAuC,GAAAiD,GAAA+D,GAAAqH,QAkBAxO,EAAAyO,YAAA,SAAA7Q,EAAAuC,GACA,IAAAD,EAAAtC,EAAAuC,GAAAiD,GAAA2F,IAAA5B,GAAAqH,QAoBAxO,EAAAwI,SAAA,SAAA5K,EAAAuC,GACA,IAAAD,EAAAtC,EAAAuC,GAAAiD,GAAA+D,GAAAuH,QAkBA1O,EAAA2O,YAAA,SAAA/Q,EAAAuC,GACA,IAAAD,EAAAtC,EAAAuC,GAAAiD,GAAA2F,IAAA5B,GAAAuH,QAOA,SAAAE,EAAA1P,EAAA2P,GAEA,OADA7O,EAAA6O,GAAA7O,EAAAd,GACA0P,GAEA,OAAA,MACA,UAAA,SACA,SAAA,SACA,SAAA,SACA,eAAA,cACA,kBAAA,iBACA,WAAA,UACA,cAAA,aACA,WAAA,UACA,cAAA,sCCrmDApR,EAAAJ,QAAA,SAAA0E,EAAAvC,GACAuC,EAAAhC,OAAA,SAAA8B,EAAArD,GACA,OAAA,IAAAuD,EAAA5B,UAAA0B,EAAArD,IAiBAuD,EAAAhC,OAAA6I,KAAA,SAAAjH,EAAAL,EAAA9C,EAAAqK,GAEA,MADArK,EAAAA,GAAA,gBACA,IAAAuD,EAAAxD,eAAAC,GACAmD,OAAAA,EACAL,SAAAA,EACAuH,SAAAA,GACA9G,EAAAhC,OAAA6I,gCCzBAnL,EAAAJ,QAAA,SAAA0E,EAAAvC,GAGA,SAAAuP,IAEA,SAAAC,IACA,OAAApQ,gBAAAqQ,QAAArQ,gBAAAsQ,QAAAtQ,gBAAAuQ,QACA,IAAAhP,EAAAvB,KAAAwQ,UAAA,KAAAJ,GAEA,IAAA7O,EAAAvB,KAAA,KAAAoQ,GAEA,SAAAK,EAAAzO,GAOA9C,OAAAwC,eAAA1B,KAAA,UACAgC,MAAAA,EACA0O,YAAA,EACAC,cAAA,EACAC,UAAA,IAIA1R,OAAAwC,eAAAxC,OAAAmB,UAAA,UACA0B,IAAA0O,EACA9O,IAAAyO,EACAO,cAAA,IAGA,IAAAvP,KA6JA,OA7IAA,EAAA4I,KAAA,SAAAjH,EAAAL,EAAA9C,EAAAqK,GAEA,MADArK,EAAAA,GAAA,gBACA,IAAAuD,EAAAxD,eAAAC,GACAmD,OAAAA,EACAL,SAAAA,EACAuH,SAAAA,GACA7I,EAAA4I,OAkBA5I,EAAAiJ,MAAA,SAAAwG,EAAAvC,EAAA9M,GACA,IAAAD,EAAAsP,EAAArP,GAAAiD,GAAA4F,MAAAiE,IA2BAlN,EAAAiN,MAAA,SAAAvN,EAAAkN,EAAAC,EAAAzM,GACA,IAAAD,EAAAT,EAAAU,GAAAiD,GAAA4J,MAAAL,EAAAC,IAiBA7M,EAAA0P,MAAA,SAAA7N,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAAqM,OAIA1P,EAAAgJ,OAiBAhJ,EAAAgJ,IAAAC,MAAA,SAAAwG,EAAAvC,EAAA9M,GACA,IAAAD,EAAAsP,EAAArP,GAAAiD,GAAA2F,IAAAC,MAAAiE,IAuBAlN,EAAAgJ,IAAAiE,MAAA,SAAAvN,EAAAkN,EAAAC,EAAAzM,GACA,IAAAD,EAAAT,EAAAU,GAAAiD,GAAA2F,IAAAiE,MAAAL,EAAAC,IAiBA7M,EAAAgJ,IAAA0G,MAAA,SAAA7N,EAAAzB,GACA,IAAAD,EAAA0B,EAAAzB,GAAAiD,GAAA2F,IAAA0G,OAGA1P,EAAA,MAAAA,EAAA,MACAA,EAAAgJ,IAAA,MAAAhJ,EAAAgJ,IAAA,MAEAhJ,EA5LA,IAAAG,EAAA4B,EAAA5B,UA+LA4B,EAAA/B,OAAA+O,EACAhN,EAAA4N,OAAAZ,4BC7LA,IAAAa,EAAA7S,EAAA,mBACAsD,EAAAtD,EAAA,UACA6C,EAAA7C,EAAA,aAOA8S,EAAA,cAAA/R,OAKAgS,EAAA,qCAGAxS,EAAAyS,SAAA9Q,UAAA3B,KACA0S,EAAAD,SAAA9Q,UAAA+Q,MA+BAvS,EAAAJ,QAAA,SAAA4S,EAAA9Q,EAAA6G,EAAAhF,GACA,mBAAAA,IACAA,EAAA,cAGA,IAAAkP,GACAlK,OAAAA,EACAhF,iBAAAA,GAIAiP,EAAAE,YACAF,EAAAE,cAEAF,EAAAE,UAAAhR,GAAA+Q,EAEApS,OAAAwC,eAAA2P,EAAA9Q,GACAoB,IAAA,WACA2P,EAAAlP,iBAAA1D,KAAAsB,MAEA,IAAAqB,EAAA,SAAAA,IACAI,EAAAzB,KAAA,UACA,IAAAgB,EAAAc,cACAL,EAAAzB,KAAA,OAAAqB,GACA,IAAAoG,EAAA6J,EAAAlK,OAAAgK,MAAApR,KAAAP,WACA,YAAAwE,IAAAwD,EAAAzH,KAAAyH,GAIA,GAAAwJ,EAAA,CAEA,IAAA5Q,EAAAgB,EAAAmQ,UAAAtS,OAAAoB,OAAAN,MAEAK,EAAA3B,KAAAA,EACA2B,EAAA+Q,MAAAA,OAIAlS,OAAAuS,oBAAAJ,GACAjS,QAAA,SAAAsS,GACA,IAAAR,EAAArO,KAAA6O,GAAA,CACA,IAAAC,EAAAzS,OAAAoG,yBAAA+L,EAAAK,GACAxS,OAAAwC,eAAAL,EAAAqQ,EAAAC,MAMA,OADAX,EAAAhR,KAAAqB,GACAA,GAEAsP,cAAA,4ECvGA,IAAA3P,EAAA7C,EAAA,aA2BAsD,EAAAtD,EAAA,UAEAU,EAAAJ,QAAA,SAAA4S,EAAA9Q,EAAA6G,GACAiK,EAAA9Q,GAAA,WACAkB,EAAAzB,KAAA,UACA,IAAAgB,EAAAc,cACAL,EAAAzB,KAAA,OAAAqR,EAAA9Q,IACA,IAAAkH,EAAAL,EAAAgK,MAAApR,KAAAP,WACA,YAAAwE,IAAAwD,EAAAzH,KAAAyH,sDCnCA,IAAAzG,EAAA7C,EAAA,aACAsD,EAAAtD,EAAA,UA4BAU,EAAAJ,QAAA,SAAA4S,EAAA9Q,EAAAqR,GACA1S,OAAAwC,eAAA2P,EAAA9Q,GACAoB,IAAA,SAAAM,IACAR,EAAAzB,KAAA,UACA,IAAAgB,EAAAc,cACAL,EAAAzB,KAAA,OAAAiC,GAEA,IAAAwF,EAAAmK,EAAAlT,KAAAsB,MACA,YAAAiE,IAAAwD,EAAAzH,KAAAyH,GAEAkJ,cAAA,uDCzBA,IAAAhR,EAAAxB,EAAA,mBACAsD,EAAAtD,EAAA,UACAmF,EAAAnF,EAAA,eAEAU,EAAAJ,QAAA,SAAAQ,EAAA4S,GACA,IAAA5S,EAAAwC,EAAAxC,EAAA,WACA4S,EAAAA,EAAAxL,IAAA,SAAAzI,GAAA,OAAAA,EAAA2F,iBACAiD,OAGA,IAAAX,EAAAgM,EAAAxL,IAAA,SAAAzI,EAAAkU,GACA,IAAAC,IAAA,IAAA,IAAA,IAAA,IAAA,KAAAxS,QAAA3B,EAAA6F,OAAA,IAAA,KAAA,IAEA,OADAoO,EAAAlT,OAAA,GAAAmT,IAAAD,EAAAlT,OAAA,EAAA,MAAA,IACAoT,EAAA,IAAAnU,IACA2I,KAAA,MAEA,IAAAsL,EAAAzJ,KAAA,SAAA1F,GAAA,OAAAY,EAAArE,KAAAyD,IACA,MAAA,IAAA/C,EACA,yBAAAkG,EAAA,SAAAvC,EAAArE,GAAA,oFCbAJ,EAAAJ,QAAA,SAAAQ,EAAAI,EAAA2C,GACA,IAAAgQ,EAAA/S,EAAAgT,UAAAhT,EAAAgT,QAAA/S,OAAAoB,OAAA,OACA,GAAA,IAAAb,UAAAd,OAGA,OAAAqT,EAAA3S,GAFA2S,EAAA3S,GAAA2C,4BCXAnD,EAAAJ,QAAA,SAAAQ,EAAAS,GACA,OAAAA,EAAAf,OAAA,EAAAe,EAAA,GAAAT,EAAAqF,+BCCAzF,EAAAJ,QAAA,SAAAiK,GACA,IAAAjB,KACA,IAAA,IAAAlH,KAAAmI,EACAjB,EAAA1G,KAAAR,GAEA,OAAAkH,4BCdA,IAAAhG,EAAAtD,EAAA,UACA6E,EAAA7E,EAAA,eAEAuJ,GADAvJ,EAAA,aACAA,EAAA,iBAqBAU,EAAAJ,QAAA,SAAAQ,EAAAS,GACA,IAAAiI,EAAAlG,EAAAxC,EAAA,UACAgE,EAAAxB,EAAAxC,EAAA,UACAyD,EAAAhD,EAAA,GACAqD,EAAAC,EAAA/D,EAAAS,GACA8B,EAAAmG,EAAAjI,EAAA,GAAAA,EAAA,GACAwS,EAAAzQ,EAAAxC,EAAA,WASA,MAPA,mBAAAuC,IAAAA,EAAAA,KACAA,EAAAA,GAAA,GACAA,EAAAA,EACA2Q,QAAA,aAAA,WAAA,OAAAzK,EAAAzE,KACAkP,QAAA,YAAA,WAAA,OAAAzK,EAAA3E,KACAoP,QAAA,YAAA,WAAA,OAAAzK,EAAAhF,KAEAwP,EAAAA,EAAA,KAAA1Q,EAAAA,yFCjCA3C,EAAAJ,QAAA,SAAA2T,GACA,GAAAA,EAAA7R,KAAA,OAAA6R,EAAA7R,KAEA,IAAA6M,EAAA,yBAAAzH,KAAAyM,GACA,OAAAhF,GAAAA,EAAA,GAAAA,EAAA,GAAA,6BC4CA,SAAAiF,EAAAC,GAGA,OAFAA,EAAAH,QAAA,aAAA,QACA/E,MAAA,mBACA/G,IAAA,SAAArE,GACA,IACAuQ,EADA,cACA5M,KAAA3D,GACA,OAAAuQ,GAAAnU,EAAAoU,WAAAD,EAAA,MACAE,EAAAzQ,EAAAmQ,QAAA,eAAA,SAoBA,SAAAO,EAAAC,EAAA1T,EAAA6S,GAMA,IAAA,IAJA9S,EADA4T,EAAA3T,EAKAb,EAAA,EAAAI,EAFAsT,OAAA7N,IAAA6N,EAAAa,EAAAhU,OAAAmT,EAEA1T,EAAAI,EAAAJ,IAAA,CACA,IAAAyU,EAAAF,EAAAvU,GACAwU,QACA,IAAAC,EAAAJ,EACAG,EAAAA,EAAAC,EAAAJ,QACA,IAAAI,EAAAzU,IACAwU,EAAAA,EAAAC,EAAAzU,IACAA,GAAAI,EAAA,IAAAQ,EAAA4T,IAEA5T,OAAAiF,EAGA,OAAAjF,EAvGA,IAAAwK,EAAArL,EAAA,iBAwBAU,EAAAJ,QAAA,SAAA6T,EAAArT,GACA,IAAA0T,EAAAN,EAAAC,GACAlM,EAAAuM,EAAAA,EAAAhU,OAAA,GAEAmU,GACAC,OAAAJ,EAAAhU,OAAA,EAAA+T,EAAAC,EAAA1T,EAAA0T,EAAAhU,OAAA,GAAAM,EACAsB,KAAA6F,EAAAqM,GAAArM,EAAAhI,EACA4D,MAAA0Q,EAAAC,EAAA1T,IAIA,OAFA6T,EAAArJ,OAAAD,EAAAsJ,EAAAvS,KAAAuS,EAAAC,QAEAD,8CClCA,IAAAvJ,EAAApL,EAAA,iBAgCAU,EAAAJ,QAAA,SAAA6T,EAAArT,GAEA,OADAsK,EAAA+I,EAAArT,GACA+C,kDCtBAnD,EAAAJ,QAAA,SAAAiK,GAGA,SAAAzG,EAAA8B,IACA,IAAA0D,EAAAlI,QAAAwE,IACA0D,EAAA1G,KAAAgD,GAKA,IATA,IAAA0D,EAAAvI,OAAAuS,oBAAA/I,GAQAsK,EAAA9T,OAAA+T,eAAAvK,GACA,OAAAsK,GACA9T,OAAAuS,oBAAAuB,GAAA5T,QAAA6C,GACA+Q,EAAA9T,OAAA+T,eAAAD,GAGA,OAAAvL,4BC5BA,IAAAnE,EAAAnF,EAAA,eAuCA+U,GACAC,OAAA7C,OACA8C,OAAA/C,QAGAxR,EAAAJ,QAAA,SAAA8B,EAAAtB,GACA,IAAAoU,EAAA/P,EAAArE,GAGA,MAAA,SAAAoU,GAAA,cAAAA,IAKAH,EAAAG,IAAA,iBAAApU,IACAA,EAAA,IAAAiU,EAAAG,GAAApU,IAEAsB,KAAAtB,8CCpDAR,EAAAI,EAAAJ,YAMAoE,KAAA1E,EAAA,UAMAM,EAAA6E,KAAAnF,EAAA,eAKAM,EAAAmF,YAAAzF,EAAA,iBAMAM,EAAAqE,WAAA3E,EAAA,gBAMAM,EAAAuE,UAAA7E,EAAA,eAMAM,EAAAyF,QAAA/F,EAAA,aAMAM,EAAAiJ,WAAAvJ,EAAA,gBAMAM,EAAAgD,KAAAtD,EAAA,UAMAM,EAAAuS,cAAA7S,EAAA,mBAMAM,EAAAoF,IAAA1F,EAAA,YAMAM,EAAA6U,aAAAnV,EAAA,kBAMAM,EAAA8K,YAAApL,EAAA,iBAMAM,EAAA+K,YAAArL,EAAA,iBAMAM,EAAAuG,QAAA7G,EAAA,aAMAM,EAAAwD,YAAA9D,EAAA,iBAMAM,EAAAyD,UAAA/D,EAAA,eAMAM,EAAA4D,kBAAAlE,EAAA,uBAMAM,EAAA6D,gBAAAnE,EAAA,qBAMAM,EAAA0D,mBAAAhE,EAAA,wBAMAM,EAAA8D,yBAAApE,EAAA,gbC3GA,SAAA+F,EAAAjF,EAAAsU,EAAAC,EAAAC,GAMA,OAAAC,GAJAH,WAAAA,EACAI,QACAC,QAAA,SAAA/N,GAAA,OAAAA,IAEA5G,OAAA,IAAAuU,EAAA,EAAAA,GAeA,SAAAE,EAAArC,EAAArP,EAAA6R,GAGA,GAAA7R,GAAA,mBAAAA,EAAAkC,SAEAlC,EAAAkC,UAAAzF,EAAAyF,WAEAlC,EAAAxB,aAAAwB,EAAAxB,YAAAH,YAAA2B,GAAA,CACA,IAAA8R,EAAA9R,EAAAkC,QAAA2P,GAIA,MAHA,iBAAAC,IACAA,EAAAJ,EAAArC,EAAAyC,EAAAD,IAEAC,EAIA,IAAAC,EAAAC,EAAA3C,EAAArP,GACA,GAAA+R,EACA,OAAAA,EAIA,GAAAE,EAAAjS,GAAA,CACA,GAAA,cAAAA,EACA,OAAAA,EAAAkS,UAKA,IACA,GAAAC,SAAAC,WAEA,OADA,IAAAC,eACAC,kBAAAtS,GAKA,IACAuS,EAAAJ,SAAAK,gBADA,+BACA,KAMA,OAJAD,EAAAE,YAAAzS,EAAA0S,WAAA,IACAC,KAAAJ,EAAAK,UACAzC,QAAA,KAAA,IAAAnQ,EAAA4S,UAAA,KACAL,EAAAK,UAAA,GACAD,KAEA,MAAA3N,KASA,IAAA6N,EAAAC,EAAA9S,GACA7C,EAAAkS,EAAAkC,WAAAwB,EAAA/S,GAAA6S,EAKA,GAAA,IAAA1V,EAAAR,QAAAqW,EAAAhT,KACA,IAAA7C,EAAAR,QAAA,UAAAQ,EAAA,IACA,IAAAA,EAAAR,QAAA,gBAAAQ,EAAA,IAAA,UAAAA,EAAA,IACA,CACA,GAAA,mBAAA6C,EAAA,CACA,IACAiT,GADA1U,EAAAyE,EAAAhD,IACA,KAAAzB,EAAA,GACA,OAAA8Q,EAAAuC,QAAA,YAAAqB,EAAA,IAAA,WAEA,GAAAC,EAAAlT,GACA,OAAAqP,EAAAuC,QAAA7M,OAAA1G,UAAA+D,SAAA1F,KAAAsD,GAAA,UAEA,GAAAmT,EAAAnT,GACA,OAAAqP,EAAAuC,QAAAwB,KAAA/U,UAAAgV,YAAA3W,KAAAsD,GAAA,QAEA,GAAAgT,EAAAhT,GACA,OAAAsT,EAAAtT,GAIA,IAAAuT,EAAA,GAAAC,GAAA,EAAAC,GAAA,IAAA,KASA,GANAxM,EAAAjH,KACAwT,GAAA,EACAC,GAAA,IAAA,MAIA,mBAAAzT,EAAA,CACA,IAAAzB,EAAAyE,EAAAhD,GAEAuT,EAAA,cADAN,EAAA1U,EAAA,KAAAA,EAAA,IACA,IAcA,GAVA2U,EAAAlT,KACAuT,EAAA,IAAAxO,OAAA1G,UAAA+D,SAAA1F,KAAAsD,IAIAmT,EAAAnT,KACAuT,EAAA,IAAAH,KAAA/U,UAAAgV,YAAA3W,KAAAsD,IAIAgT,EAAAhT,GACA,OAAAsT,EAAAtT,GAGA,GAAA,IAAA7C,EAAAR,UAAA6W,GAAA,GAAAxT,EAAArD,QACA,OAAA8W,EAAA,GAAAF,EAAAE,EAAA,GAGA,GAAA5B,EAAA,EACA,OAAAqB,EAAAlT,GACAqP,EAAAuC,QAAA7M,OAAA1G,UAAA+D,SAAA1F,KAAAsD,GAAA,UAEAqP,EAAAuC,QAAA,WAAA,WAIAvC,EAAAsC,KAAA5S,KAAAiB,GAEA,IAAA0T,EAWA,OATAA,EADAF,EACAG,EAAAtE,EAAArP,EAAA6R,EAAAgB,EAAA1V,GAEAA,EAAAkH,IAAA,SAAAhH,GACA,OAAAuW,EAAAvE,EAAArP,EAAA6R,EAAAgB,EAAAxV,EAAAmW,KAIAnE,EAAAsC,KAAArN,MAEAuP,EAAAH,EAAAH,EAAAE,GAIA,SAAAzB,EAAA3C,EAAArP,GACA,cAAAA,GACA,IAAA,YACA,OAAAqP,EAAAuC,QAAA,YAAA,aAEA,IAAA,SACA,IAAAkC,EAAA,IAAAC,KAAAC,UAAAhU,GAAAmQ,QAAA,SAAA,IACAA,QAAA,KAAA,OACAA,QAAA,OAAA,KAAA,IACA,OAAAd,EAAAuC,QAAAkC,EAAA,UAEA,IAAA,SACA,OAAA,IAAA9T,GAAA,EAAAA,IAAAiU,EAAAA,EACA5E,EAAAuC,QAAA,KAAA,UAEAvC,EAAAuC,QAAA,GAAA5R,EAAA,UAEA,IAAA,UACA,OAAAqP,EAAAuC,QAAA,GAAA5R,EAAA,WAGA,GAAA,OAAAA,EACA,OAAAqP,EAAAuC,QAAA,OAAA,QAKA,SAAA0B,EAAAtT,GACA,MAAA,IAAA1D,MAAA+B,UAAA+D,SAAA1F,KAAAsD,GAAA,IAIA,SAAA2T,EAAAtE,EAAArP,EAAA6R,EAAAgB,EAAA1V,GAEA,IAAA,IADAuW,KACAtX,EAAA,EAAAI,EAAAwD,EAAArD,OAAAP,EAAAI,IAAAJ,EACAc,OAAAmB,UAAA6E,eAAAxG,KAAAsD,EAAAqO,OAAAjS,IACAsX,EAAA3U,KAAA6U,EAAAvE,EAAArP,EAAA6R,EAAAgB,EACAxE,OAAAjS,IAAA,IAEAsX,EAAA3U,KAAA,IASA,OANA5B,EAAAC,QAAA,SAAAC,GACAA,EAAA+N,MAAA,UACAsI,EAAA3U,KAAA6U,EAAAvE,EAAArP,EAAA6R,EAAAgB,EACAxV,GAAA,MAGAqW,EAIA,SAAAE,EAAAvE,EAAArP,EAAA6R,EAAAgB,EAAAxV,EAAAmW,GACA,IAAAjV,EAAAsF,EAuCA,GAtCA7D,EAAAkU,mBACAlU,EAAAkU,iBAAA7W,GAEAwG,EADA7D,EAAAmU,iBAAA9W,GACAgS,EAAAuC,QAAA,kBAAA,WAEAvC,EAAAuC,QAAA,WAAA,WAGA5R,EAAAmU,iBAAA9W,KACAwG,EAAAwL,EAAAuC,QAAA,WAAA,aAIAiB,EAAAtV,QAAAF,GAAA,IACAkB,EAAA,IAAAlB,EAAA,KAEAwG,IACAwL,EAAAsC,KAAApU,QAAAyC,EAAA3C,IAAA,GAEAwG,EADA,OAAAgO,EACAH,EAAArC,EAAArP,EAAA3C,GAAA,MAEAqU,EAAArC,EAAArP,EAAA3C,GAAAwU,EAAA,IAEAtU,QAAA,OAAA,IAEAsG,EADA2P,EACA3P,EAAAuQ,MAAA,MAAA/P,IAAA,SAAAgQ,GACA,MAAA,KAAAA,IACA9P,KAAA,MAAA+P,OAAA,GAEA,KAAAzQ,EAAAuQ,MAAA,MAAA/P,IAAA,SAAAgQ,GACA,MAAA,MAAAA,IACA9P,KAAA,OAIAV,EAAAwL,EAAAuC,QAAA,aAAA,iBAGA,IAAArT,EAAA,CACA,GAAAiV,GAAAnW,EAAA+N,MAAA,SACA,OAAAvH,GAEAtF,EAAAwV,KAAAC,UAAA,GAAA3W,IACA+N,MAAA,iCACA7M,EAAAA,EAAA+V,OAAA,EAAA/V,EAAA5B,OAAA,GACA4B,EAAA8Q,EAAAuC,QAAArT,EAAA,UAEAA,EAAAA,EAAA4R,QAAA,KAAA,OACAA,QAAA,OAAA,KACAA,QAAA,WAAA,KACA5R,EAAA8Q,EAAAuC,QAAArT,EAAA,WAIA,OAAAA,EAAA,KAAAsF,EAIA,SAAAgQ,EAAAH,EAAAH,EAAAE,GACA,IAAAc,EAAA,EAOA,OANAb,EAAAc,OAAA,SAAAC,EAAAC,GAGA,OAFAH,IACAG,EAAAnX,QAAA,OAAA,GAAAgX,IACAE,EAAAC,EAAA/X,OAAA,GACA,GAEA,GACA8W,EAAA,IACA,KAAAF,EAAA,GAAAA,EAAA,OACA,IACAG,EAAAnP,KAAA,SACA,IACAkP,EAAA,GAGAA,EAAA,GAAAF,EAAA,IAAAG,EAAAnP,KAAA,MAAA,IAAAkP,EAAA,GAGA,SAAAxM,EAAA0N,GACA,OAAA5Q,MAAAkD,QAAA0N,IACA,iBAAAA,GAAA,mBAAAC,EAAAD,GAGA,SAAAzB,EAAAxP,GACA,MAAA,iBAAAA,GAAA,oBAAAkR,EAAAlR,GAGA,SAAAyP,EAAA0B,GACA,MAAA,iBAAAA,GAAA,kBAAAD,EAAAC,GAGA,SAAA7B,EAAArX,GACA,MAAA,iBAAAA,GAAA,mBAAAiZ,EAAAjZ,GAGA,SAAAiZ,EAAA5Y,GACA,OAAAkB,OAAAmB,UAAA+D,SAAA1F,KAAAV,GA1UA,IAAAgH,EAAA7G,EAAA,aACA4W,EAAA5W,EAAA,mBACA2W,EAAA3W,EAAA,6BAEAU,EAAAJ,QAAAyF,EAyBA,IAAA+P,EAAA,SAAAvL,GACA,MAAA,iBAAAoO,YACApO,aAAAoO,YAEApO,GACA,iBAAAA,GACA,IAAAA,EAAAqO,UACA,iBAAArO,EAAAsO,qGC7BA,IAAA9S,EAAA/F,EAAA,aACA6C,EAAA7C,EAAA,aAeAU,EAAAJ,QAAA,SAAAQ,GACA,IAAA4G,EAAA3B,EAAAjF,GACAqE,EAAApE,OAAAmB,UAAA+D,SAAA1F,KAAAO,GAEA,GAAA+B,EAAAkC,mBAAA2C,EAAAlH,QAAAqC,EAAAkC,kBAAA,CACA,GAAA,sBAAAI,EACA,OAAArE,EAAAsB,MAAA,KAAAtB,EAAAsB,KAEA,cAAAtB,EAAAsB,KAAA,IADA,aAEA,GAAA,mBAAA+C,EACA,MAAA,WAAArE,EAAAN,OAAA,MACA,GAAA,oBAAA2E,EAAA,CACA,IAAAnE,EAAAD,OAAAC,KAAAF,GAIA,MAAA,cAHAE,EAAAR,OAAA,EACAQ,EAAA8X,OAAA,EAAA,GAAA1Q,KAAA,MAAA,QACApH,EAAAoH,KAAA,OACA,MAEA,OAAAV,EAGA,OAAAA,wDCRAhH,EAAAJ,QAAA,SAAA4S,EAAA9Q,EAAA6G,EAAAhF,GACA,IAAAkP,EAAAD,EAAAE,UAAAhR,GAEA2W,EAAA5F,EAAAlP,iBACAkP,EAAAlP,iBAAA,WACA,IAAAqF,EAAArF,EAAA8U,GAAAxY,KAAAsB,MACA,YAAAiE,IAAAwD,EAAAzH,KAAAyH,GAGA,IAAA0P,EAAA7F,EAAAlK,OACAkK,EAAAlK,OAAA,WACA,IAAAK,EAAAL,EAAA+P,GAAA/F,MAAApR,KAAAP,WACA,YAAAwE,IAAAwD,EAAAzH,KAAAyH,6BCXA5I,EAAAJ,QAAA,SAAA4S,EAAA9Q,EAAA6G,GACA,IAAA+P,EAAA9F,EAAA9Q,GACA6W,EAAA,WAAA,OAAApX,MAEAmX,GAAA,mBAAAA,IACAC,EAAAD,GAEA9F,EAAA9Q,GAAA,WACA,IAAAkH,EAAAL,EAAAgQ,GAAAhG,MAAApR,KAAAP,WACA,YAAAwE,IAAAwD,EAAAzH,KAAAyH,6BCTA5I,EAAAJ,QAAA,SAAA4S,EAAA9Q,EAAAqR,GACA,IAAAyF,EAAAnY,OAAAoG,yBAAA+L,EAAA9Q,GACA6W,EAAA,aAEAC,GAAA,mBAAAA,EAAA1V,MACAyV,EAAAC,EAAA1V,KAEAzC,OAAAwC,eAAA2P,EAAA9Q,GACAoB,IAAA,WACA,IAAA8F,EAAAmK,EAAAwF,GAAA1Y,KAAAsB,MACA,YAAAiE,IAAAwD,EAAAzH,KAAAyH,GAEAkJ,cAAA,8BC1CA,IAAAlP,EAAAtD,EAAA,UAaAU,EAAAJ,QAAA,SAAAQ,EAAAS,GACA,IAAAiI,EAAAlG,EAAAxC,EAAA,UACAuD,EAAA9C,EAAA,GACA,OAAAiI,GAAAnF,EAAAA,uCCGA3D,EAAAJ,QAAA,SAAAwC,EAAAyH,EAAA4O,GACA,IAAAtF,EAAA/Q,EAAAgR,UAAAhR,EAAAgR,QAAA/S,OAAAoB,OAAA,OAEAoI,EAAAuJ,UACAvJ,EAAAuJ,QAAA/S,OAAAoB,OAAA,OAGAgX,EAAA,IAAA7X,UAAAd,QAAA2Y,EAEA,IAAA,IAAA7V,KAAAuQ,GACAsF,GACA,WAAA7V,GAAA,SAAAA,GAAA,WAAAA,KACAiH,EAAAuJ,QAAAxQ,GAAAuQ,EAAAvQ,8BCzCA,aAEA,SAAA8V,EAAAC,GAEA,IAAAC,OAAA,EAGAA,EAFA,iBAAAD,GAEAA,GAEAA,EAAAC,IAKA,IAAA,IADAhQ,EAAA,GACArJ,EAAA,EAAAA,EAAAqZ,EAAA9Y,OAAAP,IACAqJ,GAAAgQ,EAAArZ,GAEA+T,QAAA,cAAA,IAGAA,QAAA,OAAA,KAEA/T,GAAAqB,UAAAd,QAAA,EAAA,EAAAc,UAAAd,OAAA,KACA8I,GAAAhI,UAAAd,QAAAP,EAAA,OAAA6F,EAAAxE,UAAArB,EAAA,IAKA,IAAAsZ,EAAAjQ,EAAA2O,MAAA,MACAuB,EAAA,KAwBA,OAvBAD,EAAAtY,QAAA,SAAAZ,GACA,IAAAoZ,EAAApZ,EAAA4O,MAAA,aACA,GAAAwK,EAAA,CACA,IAAAC,EAAAD,EAAA,GAAAjZ,OAKAgZ,EAJAA,EAIA7P,KAAAgQ,IAAAH,EAAAE,GAFAA,KAOA,OAAAF,IACAlQ,EAAAiQ,EAAArR,IAAA,SAAA7H,GACA,MAAA,MAAAA,EAAA,GAAAA,EAAAgB,MAAAmY,GAAAnZ,IACA+H,KAAA,QAIAkB,EAAAA,EAAAsQ,QAGA5F,QAAA,OAAA,WAGA,IAAAtT,IACAA,EAAAJ,QAAA8Y,4BCzDA1Y,EAAAJ,QAAAN,EAAA,oDCuCA,SAAAwM,EAAAzM,EAAA8Z,EAAAJ,GACA,QAAAK,EAAA/Z,EAAA8Z,KAEA,SAAA1U,EAAApF,GACAga,EAAAha,EAAA8Z,GACA,WAAA1U,EAAApF,GACAia,EAAAja,EAAA8Z,GACAI,EAAAC,SAAAna,GACAoa,EAAApa,EAAA8Z,GACA,cAAA1U,EAAApF,GACAqa,EAAAra,EAAA8Z,EAAAJ,KACAY,EAAAta,EAAA8Z,KAEA,WAAA1U,EAAApF,IAAA,WAAAoF,EAAA0U,IACA,UAAA1U,EAAApF,IAAA,UAAAoF,EAAA0U,GACAC,EAAA/Z,EAAA8Z,GAEAS,EAAAva,EAAA8Z,EAAAJ,KAaA,SAAAK,EAAA/Z,EAAA8Z,GACA,OAAA9Z,IAAA8Z,EAAA,IAAA9Z,GAAA,EAAAA,GAAA,EAAA8Z,EACA9Z,IAAAA,GAAA8Z,IAAAA,EAcA,SAAAQ,EAAAta,EAAA8Z,GACA,OAAA1U,EAAApF,KAAAoF,EAAA0U,GAYA,SAAAE,EAAAha,EAAA8Z,GACA,MAAA,SAAA1U,EAAA0U,IACAC,EAAA/Z,EAAAwa,UAAAV,EAAAU,WAYA,SAAAP,EAAAja,EAAA8Z,GACA,MAAA,WAAA1U,EAAA0U,IACAC,EAAA/Z,EAAAkG,WAAA4T,EAAA5T,YAcA,SAAAmU,EAAAra,EAAA8Z,EAAAJ,GACA,MAAA,cAAAtU,EAAA0U,KACA9Z,KAAAsB,MAAAd,KAAAR,GACA8Z,KAAAxY,MAAAd,KAAAsZ,GACArN,EAAAzM,EAAA8Z,EAAAJ,IAUA,SAAAlH,EAAAxS,GACA,IAAAc,KACA,IAAA,IAAAK,KAAAnB,EAAAc,EAAA+B,KAAA1B,GACA,OAAAL,EAYA,SAAA2Z,EAAAza,EAAA8Z,GACA,GAAA9Z,EAAAS,SAAAqZ,EAAArZ,OAAA,OAAA,EAKA,IAHA,IAAAP,EAAA,EACAgP,GAAA,EAEAhP,EAAAF,EAAAS,OAAAP,IACA,GAAAF,EAAAE,KAAA4Z,EAAA5Z,GAAA,CACAgP,GAAA,EACA,MAIA,OAAAA,EAYA,SAAAkL,EAAApa,EAAA8Z,GACA,QAAAI,EAAAC,SAAAL,IACAW,EAAAza,EAAA8Z,GAWA,SAAAY,EAAA1a,GACA,OAAA,OAAAA,QAAA+F,IAAA/F,EAcA,SAAAua,EAAAva,EAAA8Z,EAAAJ,GACA,IAAAgB,EAAA1a,KAAA0a,EAAAZ,GACA,OAAA,EAGA,GAAA9Z,EAAAmC,YAAA2X,EAAA3X,UACA,OAAA,EAGA,IAAAjC,EACA,GAAAwZ,GACA,IAAAxZ,EAAA,EAAAA,EAAAwZ,EAAAjZ,OAAAP,IACA,GAAAwZ,EAAAxZ,GAAA,KAAAF,GAAA0Z,EAAAxZ,GAAA,KAAA4Z,GACAJ,EAAAxZ,GAAA,KAAA4Z,GAAAJ,EAAAxZ,GAAA,KAAAF,EACA,OAAA,OAIA0Z,KAGA,IACA,IAAAiB,EAAAnI,EAAAxS,GACA4a,EAAApI,EAAAsH,GACA,MAAAe,GACA,OAAA,EAMA,GAHAF,EAAArS,OACAsS,EAAAtS,QAEAmS,EAAAE,EAAAC,GACA,OAAA,EAGAlB,EAAA7W,MAAA7C,EAAA8Z,IAEA,IAAA3Y,EACA,IAAAjB,EAAAya,EAAAla,OAAA,EAAAP,GAAA,EAAAA,IAEA,GADAiB,EAAAwZ,EAAAza,IACAuM,EAAAzM,EAAAmB,GAAA2Y,EAAA3Y,GAAAuY,GACA,OAAA,EAIA,OAAA,EArPA,IAMAQ,EANA9U,EAAAnF,EAAA,eAOA,IAAAia,EAAAja,EAAA,UAAAia,OACA,MAAAW,IACAX,MACAC,SAAA,WAAA,OAAA,GAOAxZ,EAAAJ,QAAAkM,uECrBA,SAAAtM,GAAA,GAAA,iBAAAI,QAAA,IAAAI,EAAAA,EAAAJ,QAAAJ,SAAA,GAAA,mBAAA2a,QAAAA,OAAAC,IAAAD,UAAA3a,OAAA,EAAA,oBAAA6a,OAAAA,YAAA,IAAAC,EAAAA,EAAA,oBAAAC,KAAAA,KAAApZ,MAAAqZ,YAAAhb,MAAA,WAAA,OAAA,SAAAV,EAAAC,EAAAC,EAAAC,GAAA,SAAAC,EAAAC,EAAAC,GAAA,IAAAJ,EAAAG,GAAA,CAAA,IAAAJ,EAAAI,GAAA,CAAA,IAAAE,EAAA,mBAAAC,GAAAA,EAAA,IAAAF,GAAAC,EAAA,OAAAA,EAAAF,GAAA,GAAA,GAAAI,EAAA,OAAAA,EAAAJ,GAAA,GAAA,IAAAK,EAAA,IAAAC,MAAA,uBAAAN,EAAA,KAAA,MAAAK,EAAAE,KAAA,mBAAAF,EAAA,IAAAG,EAAAX,EAAAG,IAAAS,YAAAb,EAAAI,GAAA,GAAAU,KAAAF,EAAAC,QAAA,SAAAd,GAAA,IAAAE,EAAAD,EAAAI,GAAA,GAAAL,GAAA,OAAAI,EAAAF,GAAAF,IAAAa,EAAAA,EAAAC,QAAAd,EAAAC,EAAAC,EAAAC,GAAA,OAAAD,EAAAG,GAAAS,QAAA,IAAA,IAAAL,EAAA,mBAAAD,GAAAA,EAAAH,EAAA,EAAAA,EAAAF,EAAAa,OAAAX,IAAAD,EAAAD,EAAAE,IAAA,OAAAD,IAAAa,GAAA,SAAA0a,EAAAza,EAAAJ,IACA,SAAA0a,GACA,aA+CA,SAAAI,IACAC,GAAA,EAGA,IAFA,IAAApb,EAAAqb,EACA9U,EAAA+U,EAAA/a,OACAgG,GAAA,CAIA,IAHA8U,EAAAC,EACAA,KACAtb,GAAA,IACAA,EAAAuG,GACA8U,EAAArb,KAEAuG,EAAA+U,EAAA/a,OAEA6a,GAAA,EAIA,SAAAG,EAAAC,GACA,IAAAF,EAAA3Y,KAAA6Y,IAAAJ,GACAK,IAjEA,IAEAA,EAFAC,EAAAX,EAAAY,kBAAAZ,EAAAa,uBAKA,GAAAF,EAAA,CACA,IAAAG,EAAA,EACAC,EAAA,IAAAJ,EAAAP,GACAY,EAAAhB,EAAAhF,SAAAiG,eAAA,IACAF,EAAAG,QAAAF,GACAG,eAAA,IAEAT,EAAA,WACAM,EAAAI,KAAAN,IAAAA,EAAA,QAEA,GAAAd,EAAAqB,mBAAA,IAAArB,EAAAsB,eAOAZ,EADA,aAAAV,GAAA,uBAAAA,EAAAhF,SAAAuG,cAAA,UACA,WAIA,IAAAC,EAAAxB,EAAAhF,SAAAuG,cAAA,UACAC,EAAAC,mBAAA,WACArB,IAEAoB,EAAAC,mBAAA,KACAD,EAAAE,WAAAC,YAAAH,GACAA,EAAA,MAEAxB,EAAAhF,SAAA4G,gBAAAtG,YAAAkG,IAGA,WACAK,WAAAzB,EAAA,QAvBA,CACA,IAAA0B,EAAA,IAAA9B,EAAAsB,eACAQ,EAAAC,MAAAC,UAAA5B,EACAM,EAAA,WACAoB,EAAAG,MAAAC,YAAA,IAwBA,IAAA7B,EACAE,KAkBA7a,EAAAJ,QAAAkb,IAOAjb,KAAAsB,UAAA,IAAAmZ,EAAAA,EAAA,oBAAAC,KAAAA,KAAA,oBAAAF,OAAAA,gBACAoC,GAAA,SAAAhC,EAAAza,EAAAJ,GACA,aAIA,SAAA8c,KAUA,SAAAC,EAAAC,GACA,GAAA,mBAAAA,EACA,MAAA,IAAA9R,UAAA,+BAEA3J,KAAA0b,MAAAC,EACA3b,KAAA0Z,SACA1Z,KAAA4b,aAAA,EACAH,IAAAF,GACAM,EAAA7b,KAAAyb,GAsBA,SAAAK,EAAAC,EAAAC,EAAAC,GACAjc,KAAA+b,QAAAA,EACA,mBAAAC,IACAhc,KAAAgc,YAAAA,EACAhc,KAAAkc,cAAAlc,KAAAmc,oBAEA,mBAAAF,IACAjc,KAAAic,WAAAA,EACAjc,KAAAoc,aAAApc,KAAAqc,mBAgBA,SAAAC,EAAAP,EAAA3J,EAAApQ,GACA2X,EAAA,WACA,IAAA4C,EACA,IACAA,EAAAnK,EAAApQ,GACA,MAAArE,GACA,OAAA6e,EAAAC,OAAAV,EAAApe,GAEA4e,IAAAR,EACAS,EAAAC,OAAAV,EAAA,IAAApS,UAAA,uCAEA6S,EAAAE,QAAAX,EAAAQ,KAoCA,SAAAI,EAAA1d,GAEA,IAAA2d,EAAA3d,GAAAA,EAAA2d,KACA,GAAA3d,GAAA,iBAAAA,GAAA,mBAAA2d,EACA,OAAA,WACAA,EAAAxL,MAAAnS,EAAAQ,YAKA,SAAAoc,EAAAzC,EAAAyD,GAGA,SAAAC,EAAA9a,GACAiY,IAGAA,GAAA,EACAuC,EAAAC,OAAArD,EAAApX,IAGA,SAAA+a,EAAA/a,GACAiY,IAGAA,GAAA,EACAuC,EAAAE,QAAAtD,EAAApX,IAGA,SAAAgb,IACAH,EAAAE,EAAAD,GAlBA,IAAA7C,GAAA,EAqBAxS,EAAAwV,EAAAD,GACA,UAAAvV,EAAAyV,QACAJ,EAAArV,EAAAzF,OAIA,SAAAib,EAAA7K,EAAApQ,GACA,IAAAmb,KACA,IACAA,EAAAnb,MAAAoQ,EAAApQ,GACAmb,EAAAD,OAAA,UACA,MAAAvf,GACAwf,EAAAD,OAAA,QACAC,EAAAnb,MAAArE,EAEA,OAAAwf,EAIA,SAAAT,EAAA1a,GACA,OAAAA,aAAAhC,KACAgC,EAEAwa,EAAAE,QAAA,IAAA1c,KAAAub,GAAAvZ,GAIA,SAAAya,EAAAW,GACA,IAAArB,EAAA,IAAA/b,KAAAub,GACA,OAAAiB,EAAAC,OAAAV,EAAAqB,GAIA,SAAAnX,EAAAoX,GACA,IAAAjE,EAAApZ,KACA,GAAA,mBAAAd,OAAAmB,UAAA+D,SAAA1F,KAAA2e,GACA,OAAArd,KAAAyc,OAAA,IAAA9S,UAAA,qBAGA,IAAAhF,EAAA0Y,EAAA1e,OACAsb,GAAA,EACA,IAAAtV,EACA,OAAA3E,KAAA0c,YAQA,IALA,IAAAY,EAAA,IAAAvX,MAAApB,GACA4Y,EAAA,EACAnf,GAAA,EACA2d,EAAA,IAAA/b,KAAAub,KAEAnd,EAAAuG,IAIA,SAAA3C,EAAA5D,GAOA,SAAAof,EAAAC,GACAH,EAAAlf,GAAAqf,IACAF,IAAA5Y,GAAAsV,IACAA,GAAA,EACAuC,EAAAE,QAAAX,EAAAuB,IAVAlE,EAAAsD,QAAA1a,GAAA4a,KAAAY,EAAA,SAAAE,GACAzD,IACAA,GAAA,EACAuC,EAAAC,OAAAV,EAAA2B,OAPAL,EAAAjf,GAAAA,GAEA,OAAA2d,EAmBA,SAAA4B,EAAAN,GACA,IAAAjE,EAAApZ,KACA,GAAA,mBAAAd,OAAAmB,UAAA+D,SAAA1F,KAAA2e,GACA,OAAArd,KAAAyc,OAAA,IAAA9S,UAAA,qBAGA,IAAAhF,EAAA0Y,EAAA1e,OACAsb,GAAA,EACA,IAAAtV,EACA,OAAA3E,KAAA0c,YAMA,IAHA,IAAAte,GAAA,EACA2d,EAAA,IAAA/b,KAAAub,KAEAnd,EAAAuG,IAIA,SAAA3C,GACAoX,EAAAsD,QAAA1a,GAAA4a,KAAA,SAAAgB,GACA3D,IACAA,GAAA,EACAuC,EAAAE,QAAAX,EAAA6B,KAEA,SAAAF,GACAzD,IACAA,GAAA,EACAuC,EAAAC,OAAAV,EAAA2B,OAZAL,EAAAjf,IAEA,OAAA2d,EA7OA,IAAApC,EAAAL,EAAA,GAKAkD,KAEAqB,GAAA,YACAC,GAAA,aACAnC,GAAA,WAEA9c,EAAAJ,QAAAA,EAAA+c,EAcAA,EAAAnb,UAAA,MAAA,SAAA4b,GACA,OAAAjc,KAAA4c,KAAA,KAAAX,IAEAT,EAAAnb,UAAAuc,KAAA,SAAAZ,EAAAC,GACA,GAAA,mBAAAD,GAAAhc,KAAA0b,QAAAoC,GACA,mBAAA7B,GAAAjc,KAAA0b,QAAAmC,EACA,OAAA7d,KAEA,IAAA+b,EAAA,IAAA/b,KAAAQ,YAAA+a,GAQA,OAPAvb,KAAA0b,QAAAC,EAEAW,EAAAP,EADA/b,KAAA0b,QAAAoC,EAAA9B,EAAAC,EACAjc,KAAA4b,SAEA5b,KAAA0Z,MAAA3Y,KAAA,IAAA+a,EAAAC,EAAAC,EAAAC,IAGAF,GAaAD,EAAAzb,UAAA6b,cAAA,SAAAla,GACAwa,EAAAE,QAAA1c,KAAA+b,QAAA/Z,IAEA8Z,EAAAzb,UAAA8b,mBAAA,SAAAna,GACAsa,EAAAtc,KAAA+b,QAAA/b,KAAAgc,YAAAha,IAEA8Z,EAAAzb,UAAA+b,aAAA,SAAApa,GACAwa,EAAAC,OAAAzc,KAAA+b,QAAA/Z,IAEA8Z,EAAAzb,UAAAgc,kBAAA,SAAAra,GACAsa,EAAAtc,KAAA+b,QAAA/b,KAAAic,WAAAja,IAmBAwa,EAAAE,QAAA,SAAAtD,EAAApX,GACA,IAAAyF,EAAAwV,EAAAN,EAAA3a,GACA,GAAA,UAAAyF,EAAAyV,OACA,OAAAV,EAAAC,OAAArD,EAAA3R,EAAAzF,OAEA,IAAA6a,EAAApV,EAAAzF,MAEA,GAAA6a,EACAhB,EAAAzC,EAAAyD,OACA,CACAzD,EAAAsC,MAAAoC,EACA1E,EAAAwC,QAAA5Z,EAGA,IAFA,IAAA5D,GAAA,EACAuG,EAAAyU,EAAAM,MAAA/a,SACAP,EAAAuG,GACAyU,EAAAM,MAAAtb,GAAA8d,cAAAla,GAGA,OAAAoX,GAEAoD,EAAAC,OAAA,SAAArD,EAAAsE,GACAtE,EAAAsC,MAAAmC,EACAzE,EAAAwC,QAAA8B,EAGA,IAFA,IAAAtf,GAAA,EACAuG,EAAAyU,EAAAM,MAAA/a,SACAP,EAAAuG,GACAyU,EAAAM,MAAAtb,GAAAge,aAAAsB,GAEA,OAAAtE,GAsDA3a,EAAAie,QAAAA,EAQAje,EAAAge,OAAAA,EAMAhe,EAAAwH,IAAAA,EAuCAxH,EAAAkf,KAAAA,IAmCA/e,EAAA,IAAAmf,GAAA,SAAAzE,EAAAza,EAAAJ,IACA,SAAA0a,GACA,aACA,mBAAAA,EAAAqC,UACArC,EAAAqC,QAAAlC,EAAA,MAGA5a,KAAAsB,UAAA,IAAAmZ,EAAAA,EAAA,oBAAAC,KAAAA,KAAA,oBAAAF,OAAAA,aACAoC,EAAA,IAAA0C,GAAA,SAAA1E,EAAAza,EAAAJ,GACA,aAIA,SAAAwf,EAAAC,EAAAC,GAAA,KAAAD,aAAAC,GAAA,MAAA,IAAAxU,UAAA,qCAqEA,SAAAyU,EAAAC,EAAAC,GAEAD,EAAAA,MACAC,EAAAA,MACA,IACA,OAAA,IAAAC,KAAAF,EAAAC,GACA,MAAA3gB,GACA,GAAA,cAAAA,EAAA4C,KACA,MAAA5C,EAIA,IAAA,IADA6gB,EAAA,IADA,oBAAAC,YAAAA,YAAA,oBAAAC,cAAAA,cAAA,oBAAAC,eAAAA,eAAAC,mBAEAxgB,EAAA,EAAAA,EAAAigB,EAAA1f,OAAAP,GAAA,EACAogB,EAAAK,OAAAR,EAAAjgB,IAEA,OAAAogB,EAAAM,QAAAR,EAAAhb,OAaA,SAAAyb,EAAAhD,EAAAiD,GACAA,GACAjD,EAAAa,KAAA,SAAAnV,GACAuX,EAAA,KAAAvX,IACA,SAAAiW,GACAsB,EAAAtB,KAKA,SAAAuB,EAAAlD,EAAAiD,EAAAE,GACA,mBAAAF,GACAjD,EAAAa,KAAAoC,GAGA,mBAAAE,GACAnD,EAAA,MAAAmD,GAiBA,SAAAC,EAAAC,GAIA,IAAA,IAHAzgB,EAAAygB,EAAAzgB,OACA0gB,EAAA,IAAAC,YAAA3gB,GACA4gB,EAAA,IAAAC,WAAAH,GACAjhB,EAAA,EAAAA,EAAAO,EAAAP,IACAmhB,EAAAnhB,GAAAghB,EAAAK,WAAArhB,GAEA,OAAAihB,EAkBA,SAAAK,EAAAC,GACA,OAAA,IAAAC,GAAA,SAAAlD,GACA,IAAAmD,EAAAF,EAAAG,YAAAC,GAAA,aACAC,EAAA5B,GAAA,KACAyB,EAAAI,YAAAF,IAAAG,IAAAF,EAAA,OAEAH,EAAAM,QAAA,SAAAxiB,GAGAA,EAAAyiB,iBACAziB,EAAA0iB,kBACA3D,GAAA,IAGAmD,EAAAS,WAAA,WACA,IAAAC,EAAAC,UAAAC,UAAArT,MAAA,iBACAsT,EAAAF,UAAAC,UAAArT,MAAA,UAGAsP,EAAAgE,IAAAH,GAAAI,SAAAJ,EAAA,GAAA,KAAA,OAEA,MAAA,WACA,OAAA,IAIA,SAAAK,EAAAjB,GACA,MAAA,kBAAAkB,GACAjB,GAAAlD,QAAAmE,IAEAnB,EAAAC,GAAA/C,KAAA,SAAA5a,GAEA,OADA6e,GAAA7e,IAKA,SAAA8e,EAAAC,GACA,IAAAC,EAAAC,GAAAF,EAAAxgB,MAGA2gB,KAEAA,EAAAnF,QAAA,IAAA6D,GAAA,SAAAlD,GACAwE,EAAAxE,QAAAA,IAIAsE,EAAAG,mBAAApgB,KAAAmgB,GAGAF,EAAAI,QAGAJ,EAAAI,QAAAJ,EAAAI,QAAAxE,KAAA,WACA,OAAAsE,EAAAnF,UAHAiF,EAAAI,QAAAF,EAAAnF,QAQA,SAAAsF,EAAAN,GACA,IAGAG,EAHAD,GAAAF,EAAAxgB,MAGA4gB,mBAAA7a,MAIA4a,GACAA,EAAAxE,UAIA,SAAA4E,EAAAP,EAAAQ,GACA,OAAA,IAAA3B,GAAA,SAAAlD,EAAAD,GAEA,GAAAsE,EAAAS,GAAA,CACA,IAAAD,EAIA,OAAA7E,EAAAqE,EAAAS,IAHAV,EAAAC,GACAA,EAAAS,GAAAC,QAMA,IAAAC,GAAAX,EAAAxgB,MAEAghB,GACAG,EAAA3gB,KAAAggB,EAAApgB,SAGA,IAAAghB,EAAAhC,GAAAiC,KAAAxQ,MAAAuO,GAAA+B,GAEAH,IACAI,EAAAE,gBAAA,SAAAlkB,GACA,IAAA6jB,EAAAG,EAAAla,OACA,IACA+Z,EAAAM,kBAAAf,EAAAgB,WACApkB,EAAAqkB,YAAA,GAEAR,EAAAM,kBAAA/B,IAEA,MAAAhH,GACA,GAAA,oBAAAA,EAAAxY,KAGA,MAAAwY,EAFAnX,QAAAC,KAAA,iBAAAkf,EAAAxgB,KAAA,oCAAA5C,EAAAqkB,WAAA,eAAArkB,EAAAskB,WAAA,sBAAAlB,EAAAgB,UAAA,wBAQAJ,EAAAO,QAAA,SAAAvkB,GACAA,EAAAyiB,iBACA3D,EAAAkF,EAAAjE,QAGAiE,EAAAQ,UAAA,WACAzF,EAAAiF,EAAAla,QACA4Z,EAAAN,MAKA,SAAAqB,EAAArB,GACA,OAAAO,EAAAP,GAAA,GAGA,SAAAsB,EAAAtB,GACA,OAAAO,EAAAP,GAAA,GAGA,SAAAuB,EAAAvB,EAAAwB,GACA,IAAAxB,EAAAS,GACA,OAAA,EAGA,IAAAgB,GAAAzB,EAAAS,GAAAiB,iBAAAC,SAAA3B,EAAAgB,WACAY,EAAA5B,EAAApgB,QAAAogB,EAAAS,GAAA7gB,QACAiiB,EAAA7B,EAAApgB,QAAAogB,EAAAS,GAAA7gB,QAYA,GAVAgiB,IAGA5B,EAAApgB,UAAA4hB,GACA3gB,QAAAC,KAAA,iBAAAkf,EAAAxgB,KAAA,uCAAAwgB,EAAAS,GAAA7gB,QAAA,eAAAogB,EAAApgB,QAAA,KAGAogB,EAAApgB,QAAAogB,EAAAS,GAAA7gB,SAGAiiB,GAAAJ,EAAA,CAIA,GAAAA,EAAA,CACA,IAAAK,EAAA9B,EAAAS,GAAA7gB,QAAA,EACAkiB,EAAA9B,EAAApgB,UACAogB,EAAApgB,QAAAkiB,GAIA,OAAA,EAGA,OAAA,EAIA,SAAAC,EAAA9C,GACA,OAAA,IAAAJ,GAAA,SAAAlD,EAAAD,GACA,IAAAsG,EAAA,IAAAC,WACAD,EAAAb,QAAAzF,EACAsG,EAAAE,UAAA,SAAAtlB,GACA,IAAAulB,EAAAC,KAAAxlB,EAAAylB,OAAA3b,QAAA,IACAiV,GACA2G,6BAAA,EACA9I,KAAA2I,EACA5f,KAAA0c,EAAA1c,QAGAyf,EAAAO,mBAAAtD,KAKA,SAAAuD,EAAAC,GAEA,OAAApF,GADAe,EAAAsE,KAAAD,EAAAjJ,SACAjX,KAAAkgB,EAAAlgB,OAIA,SAAAogB,EAAA1hB,GACA,OAAAA,GAAAA,EAAAqhB,4BAOA,SAAAM,EAAA3E,GACA,IAAA5F,EAAApZ,KAEA+b,EAAA3C,EAAAwK,aAAAhH,KAAA,WACA,IAAAoE,EAAAC,GAAA7H,EAAAyK,QAAAtjB,MAEA,GAAAygB,GAAAA,EAAAI,QACA,OAAAJ,EAAAI,UAKA,OADAnC,EAAAlD,EAAAiD,EAAAA,GACAjD,EAKA,SAAA+H,EAAAC,GAgDA,SAAAC,IAGA,OAAApE,GAAAlD,UAlDA,IAAAtD,EAAApZ,KACA+gB,GACAS,GAAA,MAGA,GAAAuC,EACA,IAAA,IAAA3lB,KAAA2lB,EACAhD,EAAA3iB,GAAA2lB,EAAA3lB,GAKA6iB,KACAA,OAIA,IAAAD,EAAAC,GAAAF,EAAAxgB,MAGAygB,IACAA,GAEAiD,WAEAzC,GAAA,KAEAJ,QAAA,KAEAD,uBAGAF,GAAAF,EAAAxgB,MAAAygB,GAIAA,EAAAiD,QAAAljB,KAAAqY,GAGAA,EAAAwK,aACAxK,EAAAwK,WAAAxK,EAAA8K,MACA9K,EAAA8K,MAAAP,GAYA,IAAA,IARAQ,KAQAC,EAAA,EAAAA,EAAApD,EAAAiD,QAAAtlB,OAAAylB,IAAA,CACA,IAAAC,EAAArD,EAAAiD,QAAAG,GACAC,IAAAjL,GAEA+K,EAAApjB,KAAAsjB,EAAAT,aAAA,MAAAI,IAKA,IAAAC,EAAAjD,EAAAiD,QAAAzkB,MAAA,GAIA,OAAAogB,GAAA3Z,IAAAke,GAAAvH,KAAA,WAGA,OAFAmE,EAAAS,GAAAR,EAAAQ,GAEAY,EAAArB,KACAnE,KAAA,SAAA4E,GAEA,OADAT,EAAAS,GAAAA,EACAc,EAAAvB,EAAA3H,EAAAkL,eAAA3jB,SAEA0hB,EAAAtB,GAEAS,IACA5E,KAAA,SAAA4E,GACAT,EAAAS,GAAAR,EAAAQ,GAAAA,EACApI,EAAAyK,QAAA9C,EAEA,IAAA,IAAAjd,EAAA,EAAAA,EAAAmgB,EAAAtlB,OAAAmF,IAAA,CACA,IAAAugB,EAAAJ,EAAAngB,GACAugB,IAAAjL,IAEAiL,EAAAR,QAAArC,GAAAT,EAAAS,GACA6C,EAAAR,QAAAljB,QAAAogB,EAAApgB,YAMA,SAAA4jB,EAAAllB,EAAA2f,GACA,IAAA5F,EAAApZ,KAGA,iBAAAX,IACAuC,QAAAC,KAAAxC,EAAA,2CACAA,EAAAgR,OAAAhR,IAGA,IAAA0c,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACArD,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QAEAW,EADAzD,EAAAS,GAAA1B,YAAAiB,EAAAgB,UAAA,YAAA9B,YAAAc,EAAAgB,WACApgB,IAAAtC,GAEAmlB,EAAArC,UAAA,WACA,IAAAngB,EAAAwiB,EAAA/c,YACAxD,IAAAjC,IACAA,EAAA,MAEA0hB,EAAA1hB,KACAA,EAAAuhB,EAAAvhB,IAEA0a,EAAA1a,IAGAwiB,EAAAtC,QAAA,WACAzF,EAAA+H,EAAA9G,UAEA,MAAAjB,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EAIA,SAAA0I,EAAAC,EAAA1F,GACA,IAAA5F,EAAApZ,KAEA+b,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACArD,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QAGAW,EAFAzD,EAAAS,GAAA1B,YAAAiB,EAAAgB,UAAA,YAAA9B,YAAAc,EAAAgB,WAEA4C,aACAC,EAAA,EAEAJ,EAAArC,UAAA,WACA,IAAA0C,EAAAL,EAAA/c,OAEA,GAAAod,EAAA,CACA,IAAA7iB,EAAA6iB,EAAA7iB,MACA0hB,EAAA1hB,KACAA,EAAAuhB,EAAAvhB,IAEA,IAAAyF,EAAAid,EAAA1iB,EAAA6iB,EAAAxlB,IAAAulB,UAEA,IAAAnd,EACAiV,EAAAjV,GAEAod,EAAA,gBAGAnI,KAIA8H,EAAAtC,QAAA,WACAzF,EAAA+H,EAAA9G,UAEA,MAAAjB,KAKA,OAFAsC,EAAAhD,EAAAiD,GAEAjD,EAGA,SAAA+I,EAAAzlB,EAAA2C,EAAAgd,GACA,IAAA5F,EAAApZ,KAGA,iBAAAX,IACAuC,QAAAC,KAAAxC,EAAA,2CACAA,EAAAgR,OAAAhR,IAGA,IAAA0c,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACA,IAAAsE,EACA3H,EAAA8K,QAAAtH,KAAA,WAEA,OADAmE,EAAA3H,EAAAyK,QACA,kBAAAzf,GAAA1F,KAAAsD,GACA4e,EAAAG,EAAAS,IAAA5E,KAAA,SAAAmI,GACA,OAAAA,EACA/iB,EAEA8gB,EAAA9gB,KAGAA,IACA4a,KAAA,SAAA5a,GACA,IAAA8d,EAAAiB,EAAAS,GAAA1B,YAAAiB,EAAAgB,UAAA,aAEAyC,EADA1E,EAAAG,YAAAc,EAAAgB,WACA7B,IAAAle,EAAA3C,GAMA,OAAA2C,IACAA,OAAAiC,GAGA6b,EAAAQ,WAAA,gBAOArc,IAAAjC,IACAA,EAAA,MAGA0a,EAAA1a,IAEA8d,EAAAK,QAAAL,EAAAoC,QAAA,WACA,IAAAlb,EAAAwd,EAAA9G,MAAA8G,EAAA9G,MAAA8G,EAAA1E,YAAApC,MACAjB,EAAAzV,MAEA,MAAAyV,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EAGA,SAAAiJ,EAAA3lB,EAAA2f,GACA,IAAA5F,EAAApZ,KAGA,iBAAAX,IACAuC,QAAAC,KAAAxC,EAAA,2CACAA,EAAAgR,OAAAhR,IAGA,IAAA0c,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACArD,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QACA/D,EAAAiB,EAAAS,GAAA1B,YAAAiB,EAAAgB,UAAA,aAQAyC,EAPA1E,EAAAG,YAAAc,EAAAgB,WAOA,OAAA1iB,GACAygB,EAAAQ,WAAA,WACA5D,KAGAoD,EAAAoC,QAAA,WACAzF,EAAA+H,EAAA9G,QAKAoC,EAAAK,QAAA,WACA,IAAAnZ,EAAAwd,EAAA9G,MAAA8G,EAAA9G,MAAA8G,EAAA1E,YAAApC,MACAjB,EAAAzV,MAEA,MAAAyV,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EAGA,SAAAkJ,EAAAjG,GACA,IAAA5F,EAAApZ,KAEA+b,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACArD,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QACA/D,EAAAiB,EAAAS,GAAA1B,YAAAiB,EAAAgB,UAAA,aAEAyC,EADA1E,EAAAG,YAAAc,EAAAgB,WACAkD,QAEAnF,EAAAQ,WAAA,WACA5D,KAGAoD,EAAAK,QAAAL,EAAAoC,QAAA,WACA,IAAAlb,EAAAwd,EAAA9G,MAAA8G,EAAA9G,MAAA8G,EAAA1E,YAAApC,MACAjB,EAAAzV,MAEA,MAAAyV,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EAGA,SAAApd,EAAAqgB,GACA,IAAA5F,EAAApZ,KAEA+b,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACArD,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QAEAW,EADAzD,EAAAS,GAAA1B,YAAAiB,EAAAgB,UAAA,YAAA9B,YAAAc,EAAAgB,WACAmD,QAEAV,EAAArC,UAAA,WACAzF,EAAA8H,EAAA/c,SAGA+c,EAAAtC,QAAA,WACAzF,EAAA+H,EAAA9G,UAEA,MAAAjB,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EAGA,SAAA1c,EAAAxB,EAAAmhB,GACA,IAAA5F,EAAApZ,KAEA+b,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACA5e,EAAA,EACA6e,EAAA,MAKAtD,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QAGAsB,GAAA,EACAX,EAHAzD,EAAAS,GAAA1B,YAAAiB,EAAAgB,UAAA,YAAA9B,YAAAc,EAAAgB,WAGA4C,aACAH,EAAArC,UAAA,WACA,IAAA0C,EAAAL,EAAA/c,OACAod,EAOA,IAAAhnB,EAGA6e,EAAAmI,EAAAxlB,KAEA8lB,EAOAzI,EAAAmI,EAAAxlB,MAJA8lB,GAAA,EACAN,EAAAO,QAAAvnB,IAdA6e,EAAA,OAsBA8H,EAAAtC,QAAA,WACAzF,EAAA+H,EAAA9G,UAEA,MAAAjB,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EAGA,SAAA5c,EAAA6f,GACA,IAAA5F,EAAApZ,KAEA+b,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACArD,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QAGAW,EAFAzD,EAAAS,GAAA1B,YAAAiB,EAAAgB,UAAA,YAAA9B,YAAAc,EAAAgB,WAEA4C,aACAxlB,KAEAqlB,EAAArC,UAAA,WACA,IAAA0C,EAAAL,EAAA/c,OAEAod,GAKA1lB,EAAA4B,KAAA8jB,EAAAxlB,KACAwlB,EAAA,YALAnI,EAAAvd,IAQAqlB,EAAAtC,QAAA,WACAzF,EAAA+H,EAAA9G,UAEA,MAAAjB,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EA2CA,SAAAsJ,EAAAC,GAEA,IAEAlnB,EAEAmnB,EAAAC,EAAAC,EAAAC,EAJAC,EAAA,IAAAL,EAAA3mB,OACAgG,EAAA2gB,EAAA3mB,OAEA8T,EAAA,EAGA,MAAA6S,EAAAA,EAAA3mB,OAAA,KACAgnB,IACA,MAAAL,EAAAA,EAAA3mB,OAAA,IACAgnB,KAIA,IAAAC,EAAA,IAAAtG,YAAAqG,GACAE,EAAA,IAAArG,WAAAoG,GAEA,IAAAxnB,EAAA,EAAAA,EAAAuG,EAAAvG,GAAA,EACAmnB,EAAAO,GAAAvmB,QAAA+lB,EAAAlnB,IACAonB,EAAAM,GAAAvmB,QAAA+lB,EAAAlnB,EAAA,IACAqnB,EAAAK,GAAAvmB,QAAA+lB,EAAAlnB,EAAA,IACAsnB,EAAAI,GAAAvmB,QAAA+lB,EAAAlnB,EAAA,IAGAynB,EAAApT,KAAA8S,GAAA,EAAAC,GAAA,EACAK,EAAApT,MAAA,GAAA+S,IAAA,EAAAC,GAAA,EACAI,EAAApT,MAAA,EAAAgT,IAAA,EAAA,GAAAC,EAEA,OAAAE,EAKA,SAAAG,EAAAH,GAEA,IAEAxnB,EAFAynB,EAAA,IAAArG,WAAAoG,GACAI,EAAA,GAGA,IAAA5nB,EAAA,EAAAA,EAAAynB,EAAAlnB,OAAAP,GAAA,EAEA4nB,GAAAF,GAAAD,EAAAznB,IAAA,GACA4nB,GAAAF,IAAA,EAAAD,EAAAznB,KAAA,EAAAynB,EAAAznB,EAAA,IAAA,GACA4nB,GAAAF,IAAA,GAAAD,EAAAznB,EAAA,KAAA,EAAAynB,EAAAznB,EAAA,IAAA,GACA4nB,GAAAF,GAAA,GAAAD,EAAAznB,EAAA,IASA,OANAynB,EAAAlnB,OAAA,GAAA,EACAqnB,EAAAA,EAAAC,UAAA,EAAAD,EAAArnB,OAAA,GAAA,IACAknB,EAAAlnB,OAAA,GAAA,IACAqnB,EAAAA,EAAAC,UAAA,EAAAD,EAAArnB,OAAA,GAAA,MAGAqnB,EAMA,SAAAE,EAAAlkB,EAAAgd,GACA,IAAAmH,EAAA,GASA,GARAnkB,IACAmkB,EAAAC,GAAA1nB,KAAAsD,IAOAA,IAAA,yBAAAmkB,GAAAnkB,EAAA4jB,QAAA,yBAAAQ,GAAA1nB,KAAAsD,EAAA4jB,SAAA,CAGA,IAAAA,EACAS,EAAAC,GAEAtkB,aAAAsd,aACAsG,EAAA5jB,EACAqkB,GAAAE,KAEAX,EAAA5jB,EAAA4jB,OAEA,uBAAAO,EACAE,GAAAG,GACA,wBAAAL,EACAE,GAAAI,GACA,+BAAAN,EACAE,GAAAK,GACA,wBAAAP,EACAE,GAAAM,GACA,yBAAAR,EACAE,GAAAO,GACA,wBAAAT,EACAE,GAAAQ,GACA,yBAAAV,EACAE,GAAAS,GACA,0BAAAX,EACAE,GAAAU,GACA,0BAAAZ,EACAE,GAAAW,GAEAhI,EAAA,IAAA1gB,MAAA,wCAIA0gB,EAAAqH,EAAAN,EAAAH,SACA,GAAA,kBAAAO,EAAA,CAEA,IAAAc,EAAA,IAAAjE,WAEAiE,EAAAC,OAAA,WAEA,IAAArhB,EAAAshB,GAAAnlB,EAAAsB,KAAA,IAAAyiB,EAAA/lB,KAAAyH,QAEAuX,EAAAsH,GAAAc,GAAAvhB,IAGAohB,EAAAI,kBAAArlB,QAEA,IACAgd,EAAAjJ,KAAAC,UAAAhU,IACA,MAAArE,GACAiE,QAAA8b,MAAA,8CAAA1b,GAEAgd,EAAA,KAAArhB,IAaA,SAAA2pB,EAAAtlB,GAIA,GAAAA,EAAAikB,UAAA,EAAAsB,MAAAjB,GACA,OAAAvQ,KAAAyR,MAAAxlB,GAMA,IAGAylB,EAHAnC,EAAAtjB,EAAAikB,UAAAyB,IACApkB,EAAAtB,EAAAikB,UAAAsB,GAAAG,IAKA,GAAApkB,IAAA8jB,IAAAO,GAAA9kB,KAAAyiB,GAAA,CACA,IAAA9d,EAAA8d,EAAAlY,MAAAua,IACAF,EAAAjgB,EAAA,GACA8d,EAAAA,EAAAW,UAAAze,EAAA,GAAA7I,QAEA,IAAAinB,EAAAP,EAAAC,GAIA,OAAAhiB,GACA,KAAAijB,GACA,OAAAX,EACA,KAAAwB,GACA,OAAAhJ,GAAAwH,IAAAtiB,KAAAmkB,IACA,KAAAjB,GACA,OAAA,IAAAoB,UAAAhC,GACA,KAAAa,GACA,OAAA,IAAAjH,WAAAoG,GACA,KAAAc,GACA,OAAA,IAAAmB,kBAAAjC,GACA,KAAAe,GACA,OAAA,IAAAmB,WAAAlC,GACA,KAAAgB,GACA,OAAA,IAAAmB,YAAAnC,GACA,KAAAiB,GACA,OAAA,IAAAmB,WAAApC,GACA,KAAAkB,GACA,OAAA,IAAAmB,YAAArC,GACA,KAAAmB,GACA,OAAA,IAAAmB,aAAAtC,GACA,KAAAoB,GACA,OAAA,IAAAmB,aAAAvC,GACA,QACA,MAAA,IAAAtnB,MAAA,gBAAAgF,IAsBA,SAAA8kB,EAAArE,GACA,IAAA3K,EAAApZ,KACA+gB,GACAS,GAAA,MAGA,GAAAuC,EACA,IAAA,IAAA3lB,KAAA2lB,EACAhD,EAAA3iB,GAAA,iBAAA2lB,EAAA3lB,GAAA2lB,EAAA3lB,GAAAgG,WAAA2f,EAAA3lB,GAIA,IAAAiqB,EAAA,IAAAzI,GAAA,SAAAlD,EAAAD,GAGA,IACAsE,EAAAS,GAAA8G,aAAAvH,EAAAxgB,KAAA8P,OAAA0Q,EAAApgB,SAAAogB,EAAAwH,YAAAxH,EAAAyH,MACA,MAAA7qB,GACA,OAAA8e,EAAA9e,GAIAojB,EAAAS,GAAA1B,YAAA,SAAAliB,GACAA,EAAA6qB,WAAA,8BAAA1H,EAAAgB,UAAA,kDAAA,WACA3I,EAAAyK,QAAA9C,EACArE,KACA,SAAA9e,EAAA8f,GACAjB,EAAAiB,SAMA,OADAqD,EAAA2H,WAAAC,GACAN,EAGA,SAAAO,EAAAvpB,EAAA2f,GACA,IAAA5F,EAAApZ,KAGA,iBAAAX,IACAuC,QAAAC,KAAAxC,EAAA,2CACAA,EAAAgR,OAAAhR,IAGA,IAAA0c,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACArD,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QACA9C,EAAAS,GAAA1B,YAAA,SAAAliB,GACAA,EAAA6qB,WAAA,iBAAA1H,EAAAgB,UAAA,0BAAA1iB,GAAA,SAAAzB,EAAAirB,GACA,IAAAphB,EAAAohB,EAAAC,KAAAnqB,OAAAkqB,EAAAC,KAAAC,KAAA,GAAA/mB,MAAA,KAIAyF,IACAA,EAAAsZ,EAAA2H,WAAApB,YAAA7f,IAGAiV,EAAAjV,IACA,SAAA7J,EAAA8f,GAEAjB,EAAAiB,SAGA,MAAAjB,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EAGA,SAAAiN,EAAAtE,EAAA1F,GACA,IAAA5F,EAAApZ,KAEA+b,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACArD,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QAEA9C,EAAAS,GAAA1B,YAAA,SAAAliB,GACAA,EAAA6qB,WAAA,iBAAA1H,EAAAgB,aAAA,SAAAnkB,EAAAirB,GAIA,IAAA,IAHAC,EAAAD,EAAAC,KACAnqB,EAAAmqB,EAAAnqB,OAEAP,EAAA,EAAAA,EAAAO,EAAAP,IAAA,CACA,IAAA2qB,EAAAD,EAAAC,KAAA3qB,GACAqJ,EAAAshB,EAAA/mB,MAYA,GARAyF,IACAA,EAAAsZ,EAAA2H,WAAApB,YAAA7f,SAOA,KAJAA,EAAAid,EAAAjd,EAAAshB,EAAA1pB,IAAAjB,EAAA,IAMA,YADAse,EAAAjV,GAKAiV,KACA,SAAA9e,EAAA8f,GACAjB,EAAAiB,SAGA,MAAAjB,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EAGA,SAAAkN,EAAA5pB,EAAA2C,EAAAgd,EAAAkK,GACA,IAAA9P,EAAApZ,KAGA,iBAAAX,IACAuC,QAAAC,KAAAxC,EAAA,2CACAA,EAAAgR,OAAAhR,IAGA,IAAA0c,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACArD,EAAA8K,QAAAtH,KAAA,gBAIA3Y,IAAAjC,IACAA,EAAA,MAIA,IAAAmnB,EAAAnnB,EAEA+e,EAAA3H,EAAAyK,QACA9C,EAAA2H,WAAAxC,UAAAlkB,EAAA,SAAAA,EAAA0b,GACAA,EACAjB,EAAAiB,GAEAqD,EAAAS,GAAA1B,YAAA,SAAAliB,GACAA,EAAA6qB,WAAA,0BAAA1H,EAAAgB,UAAA,+BAAA1iB,EAAA2C,GAAA,WACA0a,EAAAyM,IACA,SAAAvrB,EAAA8f,GACAjB,EAAAiB,MAEA,SAAA0L,GAGA,GAAAA,EAAA7qB,OAAA6qB,EAAAC,UAAA,CAQA,GAAAH,EAAA,EAEA,YADAxM,EAAAuM,EAAA7X,MAAAgI,GAAA/Z,EAAA8pB,EAAAnK,EAAAkK,EAAA,KAGAzM,EAAA2M,UAKA,MAAA3M,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EAGA,SAAAuN,EAAAjqB,EAAA2C,EAAAgd,GACA,OAAAiK,EAAA7X,MAAApR,MAAAX,EAAA2C,EAAAgd,EAAA,IAGA,SAAAuK,EAAAlqB,EAAA2f,GACA,IAAA5F,EAAApZ,KAGA,iBAAAX,IACAuC,QAAAC,KAAAxC,EAAA,2CACAA,EAAAgR,OAAAhR,IAGA,IAAA0c,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACArD,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QACA9C,EAAAS,GAAA1B,YAAA,SAAAliB,GACAA,EAAA6qB,WAAA,eAAA1H,EAAAgB,UAAA,kBAAA1iB,GAAA,WACAqd,KACA,SAAA9e,EAAA8f,GAEAjB,EAAAiB,SAGA,MAAAjB,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EAKA,SAAAyN,EAAAxK,GACA,IAAA5F,EAAApZ,KAEA+b,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACArD,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QACA9C,EAAAS,GAAA1B,YAAA,SAAAliB,GACAA,EAAA6qB,WAAA,eAAA1H,EAAAgB,aAAA,WACArF,KACA,SAAA9e,EAAA8f,GACAjB,EAAAiB,SAGA,MAAAjB,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EAKA,SAAA0N,EAAAzK,GACA,IAAA5F,EAAApZ,KAEA+b,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACArD,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QACA9C,EAAAS,GAAA1B,YAAA,SAAAliB,GAEAA,EAAA6qB,WAAA,+BAAA1H,EAAAgB,aAAA,SAAAnkB,EAAAirB,GACA,IAAAphB,EAAAohB,EAAAC,KAAAC,KAAA,GAAAW,EAEAhN,EAAAjV,IACA,SAAA7J,EAAA8f,GAEAjB,EAAAiB,SAGA,MAAAjB,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EAUA,SAAA4N,EAAA9rB,EAAAmhB,GACA,IAAA5F,EAAApZ,KAEA+b,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACArD,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QACA9C,EAAAS,GAAA1B,YAAA,SAAAliB,GACAA,EAAA6qB,WAAA,mBAAA1H,EAAAgB,UAAA,yBAAAlkB,EAAA,GAAA,SAAAD,EAAAirB,GACA,IAAAphB,EAAAohB,EAAAC,KAAAnqB,OAAAkqB,EAAAC,KAAAC,KAAA,GAAA1pB,IAAA,KACAqd,EAAAjV,IACA,SAAA7J,EAAA8f,GACAjB,EAAAiB,SAGA,MAAAjB,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EAGA,SAAA6N,EAAA5K,GACA,IAAA5F,EAAApZ,KAEA+b,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACArD,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QACA9C,EAAAS,GAAA1B,YAAA,SAAAliB,GACAA,EAAA6qB,WAAA,mBAAA1H,EAAAgB,aAAA,SAAAnkB,EAAAirB,GAGA,IAAA,IAFA1pB,KAEAf,EAAA,EAAAA,EAAAyqB,EAAAC,KAAAnqB,OAAAP,IACAe,EAAA4B,KAAA8nB,EAAAC,KAAAC,KAAA3qB,GAAAiB,KAGAqd,EAAAvd,IACA,SAAAvB,EAAA8f,GAEAjB,EAAAiB,SAGA,MAAAjB,KAIA,OADAsC,EAAAhD,EAAAiD,GACAjD,EAiBA,SAAA8N,EAAA9F,GACA,IAAA3K,EAAApZ,KACA+gB,KACA,GAAAgD,EACA,IAAA,IAAA3lB,KAAA2lB,EACAhD,EAAA3iB,GAAA2lB,EAAA3lB,GAaA,OATA2iB,EAAA+I,UAAA/I,EAAAxgB,KAAA,IAEAwgB,EAAAgB,YAAA3I,EAAAkL,eAAAvC,YACAhB,EAAA+I,WAAA/I,EAAAgB,UAAA,KAGA3I,EAAAyK,QAAA9C,EACAA,EAAA2H,WAAAC,GAEA/I,GAAAlD,UAKA,SAAAqN,EAAA/K,GACA,IAAA5F,EAAApZ,KACA+b,EAAA3C,EAAA8K,QAAAtH,KAAA,WAGA,IAAA,IAFAkN,EAAA1Q,EAAAyK,QAAAiG,UAEA1rB,EAAA4rB,aAAArrB,OAAA,EAAAP,GAAA,EAAAA,IAAA,CACA,IAAAiB,EAAA2qB,aAAA3qB,IAAAjB,GAEA,IAAAiB,EAAAE,QAAAuqB,IACAE,aAAAhF,WAAA3lB,MAMA,OADA0f,EAAAhD,EAAAiD,GACAjD,EAMA,SAAAkO,EAAA5qB,EAAA2f,GACA,IAAA5F,EAAApZ,KAGA,iBAAAX,IACAuC,QAAAC,KAAAxC,EAAA,2CACAA,EAAAgR,OAAAhR,IAGA,IAAA0c,EAAA3C,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QACApc,EAAAuiB,aAAAzF,QAAAxD,EAAA+I,UAAAzqB,GAUA,OAJAoI,IACAA,EAAAsZ,EAAA2H,WAAApB,YAAA7f,IAGAA,IAIA,OADAsX,EAAAhD,EAAAiD,GACAjD,EAIA,SAAAmO,EAAAxF,EAAA1F,GACA,IAAA5F,EAAApZ,KAEA+b,EAAA3C,EAAA8K,QAAAtH,KAAA,WAcA,IAAA,IAbAmE,EAAA3H,EAAAyK,QACAiG,EAAA/I,EAAA+I,UACAK,EAAAL,EAAAnrB,OACAA,EAAAqrB,aAAArrB,OAQAimB,EAAA,EAEAxmB,EAAA,EAAAA,EAAAO,EAAAP,IAAA,CACA,IAAAiB,EAAA2qB,aAAA3qB,IAAAjB,GACA,GAAA,IAAAiB,EAAAE,QAAAuqB,GAAA,CAGA,IAAA9nB,EAAAgoB,aAAAzF,QAAAllB,GAYA,GANA2C,IACAA,EAAA+e,EAAA2H,WAAApB,YAAAtlB,SAKA,KAFAA,EAAA0iB,EAAA1iB,EAAA3C,EAAA4mB,UAAAkE,GAAAvF,MAGA,OAAA5iB,MAMA,OADA+c,EAAAhD,EAAAiD,GACAjD,EAIA,SAAAqO,EAAAvsB,EAAAmhB,GACA,IAAA5F,EAAApZ,KACA+b,EAAA3C,EAAA8K,QAAAtH,KAAA,WACA,IACAnV,EADAsZ,EAAA3H,EAAAyK,QAEA,IACApc,EAAAuiB,aAAA3qB,IAAAxB,GACA,MAAA6f,GACAjW,EAAA,KAQA,OAJAA,IACAA,EAAAA,EAAAwe,UAAAlF,EAAA+I,UAAAnrB,SAGA8I,IAIA,OADAsX,EAAAhD,EAAAiD,GACAjD,EAGA,SAAAsO,EAAArL,GACA,IAAA5F,EAAApZ,KACA+b,EAAA3C,EAAA8K,QAAAtH,KAAA,WAKA,IAAA,IAJAmE,EAAA3H,EAAAyK,QACAllB,EAAAqrB,aAAArrB,OACAQ,KAEAf,EAAA,EAAAA,EAAAO,EAAAP,IACA,IAAA4rB,aAAA3qB,IAAAjB,GAAAmB,QAAAwhB,EAAA+I,YACA3qB,EAAA4B,KAAAipB,aAAA3qB,IAAAjB,GAAA6nB,UAAAlF,EAAA+I,UAAAnrB,SAIA,OAAAQ,IAIA,OADA4f,EAAAhD,EAAAiD,GACAjD,EAIA,SAAAuO,EAAAtL,GACA,IACAjD,EADA/b,KACAb,OAAAyd,KAAA,SAAAzd,GACA,OAAAA,EAAAR,SAIA,OADAogB,EAAAhD,EAAAiD,GACAjD,EAIA,SAAAwO,EAAAlrB,EAAA2f,GACA,IAAA5F,EAAApZ,KAGA,iBAAAX,IACAuC,QAAAC,KAAAxC,EAAA,2CACAA,EAAAgR,OAAAhR,IAGA,IAAA0c,EAAA3C,EAAA8K,QAAAtH,KAAA,WACA,IAAAmE,EAAA3H,EAAAyK,QACAmG,aAAAhF,WAAAjE,EAAA+I,UAAAzqB,KAIA,OADA0f,EAAAhD,EAAAiD,GACAjD,EAOA,SAAAyO,EAAAnrB,EAAA2C,EAAAgd,GACA,IAAA5F,EAAApZ,KAGA,iBAAAX,IACAuC,QAAAC,KAAAxC,EAAA,2CACAA,EAAAgR,OAAAhR,IAGA,IAAA0c,EAAA3C,EAAA8K,QAAAtH,KAAA,gBAGA3Y,IAAAjC,IACAA,EAAA,MAIA,IAAAmnB,EAAAnnB,EAEA,OAAA,IAAA4d,GAAA,SAAAlD,EAAAD,GACA,IAAAsE,EAAA3H,EAAAyK,QACA9C,EAAA2H,WAAAxC,UAAAlkB,EAAA,SAAAA,EAAA0b,GACA,GAAAA,EACAjB,EAAAiB,QAEA,IACAsM,aAAAlF,QAAA/D,EAAA+I,UAAAzqB,EAAA2C,GACA0a,EAAAyM,GACA,MAAAxrB,GAGA,uBAAAA,EAAA4C,MAAA,+BAAA5C,EAAA4C,MACAkc,EAAA9e,GAEA8e,EAAA9e,UAQA,OADAohB,EAAAhD,EAAAiD,GACAjD,EA0DA,SAAA0O,EAAAC,EAAAC,GACAD,EAAAC,GAAA,WACA,IAAAC,EAAAnrB,UACA,OAAAirB,EAAAxG,QAAAtH,KAAA,WACA,OAAA8N,EAAAC,GAAAvZ,MAAAsZ,EAAAE,MAKA,SAAAC,IACA,IAAA,IAAAzsB,EAAA,EAAAA,EAAAqB,UAAAd,OAAAP,IAAA,CACA,IAAA0sB,EAAArrB,UAAArB,GAEA,GAAA0sB,EACA,IAAA,IAAAzrB,KAAAyrB,EACAA,EAAA5lB,eAAA7F,KACA4J,GAAA6hB,EAAAzrB,IACAI,UAAA,GAAAJ,GAAAyrB,EAAAzrB,GAAAG,QAEAC,UAAA,GAAAJ,GAAAyrB,EAAAzrB,IAOA,OAAAI,UAAA,GAGA,SAAAsrB,GAAAC,GACA,IAAA,IAAAC,KAAAC,GACA,GAAAA,GAAAhmB,eAAA+lB,IAAAC,GAAAD,KAAAD,EACA,OAAA,EAIA,OAAA,EAjpDA,IAAAG,GAAA,mBAAAC,QAAA,iBAAAA,OAAA1G,SAAA,SAAAzlB,GAAA,cAAAA,GAAA,SAAAA,GAAA,OAAAA,GAAA,mBAAAmsB,QAAAnsB,EAAAuB,cAAA4qB,QAAAnsB,IAAAmsB,OAAA/qB,UAAA,gBAAApB,GAyBA0gB,GArBA,WAEA,IACA,GAAA,oBAAA0L,UACA,OAAAA,UAEA,GAAA,oBAAAC,gBACA,OAAAA,gBAEA,GAAA,oBAAAC,aACA,OAAAA,aAEA,GAAA,oBAAAC,WACA,OAAAA,WAEA,GAAA,oBAAAC,YACA,OAAAA,YAEA,MAAA9tB,QAsEA,oBAAA6d,SAGAlC,EAAA,GAEA,IA0BAuH,GACAI,GA3BArB,GAAApE,QAyBAuE,GAAA,mCAGA3b,GAAAlF,OAAAmB,UAAA+D,SA8oBAsnB,IACAC,QAAA,eACA7H,aAAAA,EACAW,QAAAA,EACAF,QAAAA,EACAO,QAAAA,EACAE,WAAAA,EACAC,MAAAA,EACAtmB,OAAAA,EACAU,IAAAA,EACAF,KAAAA,GAMA2mB,GAAA,mEAEAqB,GAAA,uBACAQ,GAAA,gCAEArB,GAAA,YACAiB,GAAAjB,GAAA3nB,OAGA4nB,GAAA,OACAa,GAAA,OACAZ,GAAA,OACAC,GAAA,OACAC,GAAA,OACAC,GAAA,OACAE,GAAA,OACAD,GAAA,OACAE,GAAA,OACAC,GAAA,OACAC,GAAA,OACAU,GAAAH,GAAAhB,GAAA5nB,OAEAynB,GAAAlnB,OAAAmB,UAAA+D,SAiMAukB,IACAzC,UAAAA,EACAoB,YAAAA,EACAjC,eAAAA,EACAU,eAAAA,GAkUA6F,IACAD,QAAA,gBACA7H,aAAAsE,EACA3D,QAAAuE,EACAzE,QAAAqE,EACA9D,QAAAwE,EACAtE,WAAAuE,EACAtE,MAAAuE,EACA7qB,OAAA8qB,EACApqB,IAAAsqB,EACAxqB,KAAAyqB,GAoPAiC,IACAF,QAAA,sBACA7H,aAAA+F,EAEApF,QAAAyF,EACA3F,QAAA0F,EACAnF,QAAA0F,EACAxF,WAAAuF,EACAtF,MAAA8E,EACAprB,OAAA2rB,EACAjrB,IAAA+qB,EACAjrB,KAAAkrB,GAKAyB,MAEAZ,IACAa,UAAA,eACAC,aAAA,sBACAC,OAAA,iBAKAC,IAAA,QAAA,UAAA,UAAA,MAAA,OAAA,SAAA,aAAA,WAEAC,IACA5D,YAAA,GACA0C,QANAC,GAAAa,UAAAb,GAAAe,OAAAf,GAAAc,cAMAxsB,QACAe,KAAA,cAGAioB,KAAA,QACAzG,UAAA,gBACAphB,QAAA,GAGAyrB,MAMAA,GAAAlB,GAAAa,WAxkDA,WACA,IAGA,IAAApM,GACA,OAAA,EAMA,IAAA0M,EAAA,oBAAA/D,cAAA,4BAAAzlB,KAAA2d,UAAAC,aAAA,SAAA5d,KAAA2d,UAAAC,aAAA,aAAA5d,KAAA2d,UAAA8L,UAEAC,EAAA,mBAAAC,QAAA,IAAAA,MAAApoB,WAAA7E,QAAA,gBAIA,QAAA8sB,GAAAE,IAAA,oBAAAlB,WAGA,oBAAAoB,YACA,MAAA9uB,GACA,OAAA,MAojDAyuB,GAAAlB,GAAAe,QAhjDA,WACA,MAAA,mBAAA3D,gBAijDA8D,GAAAlB,GAAAc,cA9iDA,WACA,IACA,MAAA,oBAAAhC,cAAA,YAAAA,cAAAA,aAAAlF,QACA,MAAAnnB,GACA,OAAA,MA4iDA,IAAAsL,GAAAlD,MAAAkD,SAAA,SAAA6hB,GACA,MAAA,mBAAA5rB,OAAAmB,UAAA+D,SAAA1F,KAAAosB,IAgUA4B,GAAA,IAtRA,WACA,SAAAC,EAAA5I,GACA9F,EAAAje,KAAA2sB,GAEA3sB,KAAA+rB,UAAAb,GAAAa,UACA/rB,KAAAgsB,aAAAd,GAAAc,aACAhsB,KAAAisB,OAAAf,GAAAe,OAEAjsB,KAAAskB,eAAAuG,KAAAsB,IACAnsB,KAAA4sB,QAAA/B,KAAA7qB,KAAAskB,eAAAP,GACA/jB,KAAA6sB,WAAA,KACA7sB,KAAA8sB,YAAA,KACA9sB,KAAA+sB,QAAA,EACA/sB,KAAA6jB,QAAA,KAEA7jB,KAAAgtB,+BACAhtB,KAAAitB,UAAAjtB,KAAA4sB,QAAA3B,QAAA,MAAA,cA+PA,OAtPA0B,EAAAtsB,UAAAW,OAAA,SAAA+iB,GAIA,GAAA,iBAAA,IAAAA,EAAA,YAAAoH,GAAApH,IAAA,CAGA,GAAA/jB,KAAA+sB,OACA,OAAA,IAAAzuB,MAAA,wDAGA,IAAA,IAAAF,KAAA2lB,EAAA,CAKA,GAJA,cAAA3lB,IACA2lB,EAAA3lB,GAAA2lB,EAAA3lB,GAAA+T,QAAA,MAAA,MAGA,YAAA/T,GAAA,iBAAA2lB,EAAA3lB,GACA,OAAA,IAAAE,MAAA,sCAGA0B,KAAA4sB,QAAAxuB,GAAA2lB,EAAA3lB,GAKA,QAAA,WAAA2lB,GAAAA,EAAAkH,SACAjrB,KAAAitB,UAAAjtB,KAAA4sB,QAAA3B,QAIA,MAAA,iBAAAlH,EACA/jB,KAAA4sB,QAAA7I,GAEA/jB,KAAA4sB,SAQAD,EAAAtsB,UAAA6sB,aAAA,SAAAC,EAAAnO,EAAAE,GACA,IAAAnD,EAAA,IAAA6D,GAAA,SAAAlD,EAAAD,GACA,IACA,IAAAuO,EAAAmC,EAAAxB,QACAyB,EAAA,IAAA9uB,MAAA,wFACA+uB,EAAA,IAAA/uB,MAAA,sCAAA6uB,EAAAxB,SAIA,IAAAwB,EAAAxB,QAEA,YADAlP,EAAA2Q,GAGA,GAAArC,GAAAoC,EAAAxB,SAEA,YADAlP,EAAA4Q,GAKA,IAAA,IADAC,EAAApB,GAAAqB,OAAA,gBACAnvB,EAAA,EAAAA,EAAAkvB,EAAA3uB,OAAAP,IAAA,CACA,IAAAovB,EAAAF,EAAAlvB,GACA,IAAAovB,IAAAL,EAAAK,IAAA,mBAAAL,EAAAK,GAEA,YADA/Q,EAAA2Q,GAKA,IAAAK,EAAA7N,GAAAlD,SAAA,GACA,aAAAyQ,IAEAM,EADAN,EAAAO,UAAA,mBAAAP,EAAAO,SACAP,EAAAO,WAEA9N,GAAAlD,UAAAyQ,EAAAO,WAIAD,EAAA7Q,KAAA,SAAA+Q,GACAvB,GAAApB,GAAA2C,EACA7B,GAAAd,GAAAmC,EACAzQ,KACAD,GACA,MAAA9e,GACA8e,EAAA9e,MAKA,OADAshB,EAAAlD,EAAAiD,EAAAE,GACAnD,GAGA4Q,EAAAtsB,UAAA4qB,OAAA,WACA,OAAAjrB,KAAA2rB,SAAA,MAGAgB,EAAAtsB,UAAAutB,UAAA,SAAA5C,EAAAhM,EAAAE,GACA,IAAA9F,EAAApZ,KACA6tB,EAAAjO,GAAAlD,UAAAE,KAAA,WACA,IAAAmO,GAAAC,GASA,CAAA,GAAAc,GAAAd,GACA,OAAAc,GAAAd,GAEA,MAAA,IAAA1sB,MAAA,qBAXA,OAAA0sB,GACA,KAAA5R,EAAA2S,UACA,OAAAL,GACA,KAAAtS,EAAA4S,aACA,OAAAH,GACA,KAAAzS,EAAA6S,OACA,OAAAL,MASA,OADA3M,EAAA4O,EAAA7O,EAAAE,GACA2O,GAGAlB,EAAAtsB,UAAAytB,cAAA,SAAA9O,GACA,IAAA+O,EAAAnO,GAAAlD,QAAAiM,IAEA,OADA1J,EAAA8O,EAAA/O,GACA+O,GAGApB,EAAAtsB,UAAA6jB,MAAA,SAAAlF,GACA,IAAA5F,EAAApZ,KAEA+b,EAAA3C,EAAAyT,WAAAjQ,KAAA,WAKA,OAJA,OAAAxD,EAAA2T,SACA3T,EAAA2T,OAAA3T,EAAA0T,eAGA1T,EAAA2T,SAIA,OADA9N,EAAAlD,EAAAiD,EAAAA,GACAjD,GAGA4Q,EAAAtsB,UAAA4sB,UAAA,SAAAe,EAAAhP,EAAAE,GASA,SAAA+O,IACA7U,EAAAwT,QAAA3B,OAAA7R,EAAA6R,SAGA,SAAAiD,EAAAjD,GAKA,OAJA7R,EAAA+U,QAAAlD,GACAgD,IAEA7U,EAAA2T,OAAA3T,EAAA0K,aAAA1K,EAAAwT,SACAxT,EAAA2T,OAGA,SAAAqB,EAAAC,GACA,OAAA,WAGA,SAAAC,IACA,KAAAC,EAAAF,EAAA1vB,QAAA,CACA,IAAAqsB,EAAAqD,EAAAE,GAMA,OALAA,IAEAnV,EAAAyK,QAAA,KACAzK,EAAA2T,OAAA,KAEA3T,EAAAwU,UAAA5C,GAAApO,KAAAsR,GAAA,MAAAI,GAGAL,IACA,IAAAvQ,EAAA,IAAApf,MAAA,sCAEA,OADA8a,EAAAyT,WAAAjN,GAAAnD,OAAAiB,GACAtE,EAAAyT,WAhBA,IAAA0B,EAAA,EAmBA,OAAAD,KAzCA,IAAAlV,EAAApZ,KAEAiJ,GAAA+kB,KACAA,GAAAA,IAGA,IAAAK,EAAAruB,KAAAwuB,qBAAAR,GA0CAS,EAAA,OAAAzuB,KAAA6sB,WAAA7sB,KAAA6sB,WAAA,MAAA,WACA,OAAAjN,GAAAlD,YACAkD,GAAAlD,UAqBA,OAnBA1c,KAAA6sB,WAAA4B,EAAA7R,KAAA,WACA,IAAAoO,EAAAqD,EAAA,GAIA,OAHAjV,EAAAyK,QAAA,KACAzK,EAAA2T,OAAA,KAEA3T,EAAAwU,UAAA5C,GAAApO,KAAA,SAAAqO,GACA7R,EAAAuS,QAAAV,EAAAU,QACAsC,IACA7U,EAAA4T,+BACA5T,EAAA0T,YAAAsB,EAAAC,OAEA,MAAA,WACAJ,IACA,IAAAvQ,EAAA,IAAApf,MAAA,sCAEA,OADA8a,EAAAyT,WAAAjN,GAAAnD,OAAAiB,GACAtE,EAAAyT,aAGA5N,EAAAjf,KAAA6sB,WAAA7N,EAAAE,GACAlf,KAAA6sB,YAGAF,EAAAtsB,UAAAquB,SAAA,SAAA1D,GACA,QAAAoB,GAAApB,IAGA2B,EAAAtsB,UAAA8tB,QAAA,SAAAQ,GACA9D,EAAA7qB,KAAA2uB,IAGAhC,EAAAtsB,UAAAmuB,qBAAA,SAAAR,GAEA,IAAA,IADAK,KACAjwB,EAAA,EAAAuG,EAAAqpB,EAAArvB,OAAAP,EAAAuG,EAAAvG,IAAA,CACA,IAAA4sB,EAAAgD,EAAA5vB,GACA4B,KAAA0uB,SAAA1D,IACAqD,EAAAttB,KAAAiqB,GAGA,OAAAqD,GAGA1B,EAAAtsB,UAAA2sB,6BAAA,WAKA,IAAA,IAAA5uB,EAAA,EAAAA,EAAA8tB,GAAAvtB,OAAAP,IACAqsB,EAAAzqB,KAAAksB,GAAA9tB,KAIAuuB,EAAAtsB,UAAAuuB,eAAA,SAAA7K,GACA,OAAA,IAAA4I,EAAA5I,IAGA4I,MASA9tB,EAAAJ,QAAAiuB,KAEA3O,EAAA,SAAA,IAAA,8GCvwEA,MAAAnV,EAAAzK,EAAA,sBACA0wB,EAAA1wB,EAAA,qBAEAU,EAAAJ,SACAmK,QAAAA,EACAimB,OAAAA,0ECLAhwB,EAAAJ,UAEA8B,KAAA,gCACAuuB,KAAA,GACAC,OAAA,sCACAC,8CACAC,6EAEAC,QAEA3uB,KAAA,iBACAsC,KAAA,oDAGAtC,KAAA,mBACAsC,KAAA,4CAKAtC,KAAA,+BACAuuB,KAAA,GACAC,OAAA,qCACAC,wDACAC,uGAEAC,QAEA3uB,KAAA,iBACAsC,2DAGAtC,KAAA,mBACAsC,kDAKAtC,KAAA,iCACAuuB,KAAA,GACAC,OAAA,uCACAC,8CACAC,6EAEAC,QAEA3uB,KAAA,iBACAsC,2DAGAtC,KAAA,mBACAsC,kDAKAtC,KAAA,kBACAuuB,KAAA,GACAC,OAAA,wHACAC,8CACAC,2NAMAC,QAEA3uB,KAAA,iBACAsC,wEAGAtC,KAAA,mBACAsC,+CAGAtC,KAAA,oBACAsC,qDAKAtC,KAAA,eACAuuB,KAAA,GACAC,4EACAC,8CACAC,+GAGAC,QAEA3uB,KAAA,iBACAsC,kFAGAtC,KAAA,mBACAsC,+CAGAtC,KAAA,oBACAsC,qDAKAtC,KAAA,gBACAuuB,KAAA,GACAC,kFACAC,wDACAC,kHAGAC,QAEA3uB,KAAA,yBACAsC,uEAGAtC,KAAA,mBACAsC,+CAGAtC,KAAA,oBACAsC,qDAKAtC,KAAA,kBACAuuB,KAAA,GACAC,kFACAC,wDACAC,gIAGAC,QAEA3uB,KAAA,yBACAsC,8LAQAtC,KAAA,uBACAsC,+CAGAtC,KAAA,oBACAsC,qDAKAtC,KAAA,kBACAuuB,KAAA,GACAC,oDACAC,4DACAC,yIAGAC,QAEA3uB,KAAA,iBACAsC,oDAGAtC,KAAA,mBACAsC,kDAKAtC,KAAA,iBACAuuB,KAAA,GACAC,2FACAC,0FACAC,uMAIAC,QAEA3uB,KAAA,iBACAsC,6MASAtC,KAAA,mBACAsC,+CAGAtC,KAAA,oBACAsC,qDAKAtC,KAAA,eACAuuB,KAAA,GACAC,yGACAC,mDACAC,gIAGAC,QAEA3uB,KAAA,iBACAsC,sEAGAtC,KAAA,mBACAsC,kDAKAtC,KAAA,gBACAuuB,KAAA,GACAC,qFACAC,sEACAC,mJAGAC,QAEA3uB,KAAA,iBACAsC,sEAGAtC,KAAA,mBACAsC,+CAGAtC,KAAA,oBACAsC,qDAKAtC,KAAA,kBACAuuB,KAAA,GACAC,wEACAC,sEACAC,iJAGAC,QAEA3uB,KAAA,iBACAsC,+LAQAtC,KAAA,mBACAsC,+CAGAtC,KAAA,oBACAsC,mDAGAtC,8BACAsC,gEAKAtC,KAAA,eACAuuB,KAAA,GACAC,4EACAC,sEACAC,0JAGAC,QAEA3uB,KAAA,iBACAsC,+LAQAtC,KAAA,mBACAsC,+CAGAtC,KAAA,oBACAsC,mDAGAtC,8BACAsC,gEAKAtC,KAAA,sBACAuuB,KAAA,GACAC,wGACAC,gEACAC,8KAGAC,QAEA3uB,KAAA,iBACAsC,oDAGAtC,KAAA,mBACAsC,kDAKAtC,KAAA,iBACAuuB,KAAA,GACAC,2FACAC,sDACAC,mJAGAC,QAEA3uB,KAAA,iBACAsC,8DAGAtC,KAAA,mBACAsC,+CAGAtC,KAAA,oBACAsC,mDAGAtC,uBACAsC,yDAKAtC,KAAA,cACAuuB,KAAA,GACAC,kGACAC,0CACAC,qIAGAC,QAEA3uB,KAAA,iBACAsC,8DAGAtC,KAAA,mBACAsC,+CAGAtC,KAAA,oBACAsC,mDAGAtC,uBACAsC,uDAGAtC,uBACAsC,0EAKAtC,KAAA,gBACAuuB,KAAA,GACAC,sGACAC,gSASAC,6VASAC,QAEA3uB,KAAA,iBACAsC,oIAMAtC,KAAA,oBACAsC,gDAGAtC,KAAA,qBACAsC,gEAGAtC,2BACAsC,0DAGAtC,6BACAsC,gEAKAtC,KAAA,eACAuuB,KAAA,GACAC,yGACAC,iSASAC,yVASAC,QAEA3uB,KAAA,iBACAsC,oIAMAtC,KAAA,oBACAsC,gDAGAtC,KAAA,qBACAsC,gEAGAtC,4BACAsC,2DAGAtC,4BACAsC,wFC/dAhE,EAAAJ,UAEA8B,KAAA,eACAuuB,KAAA,GACAC,OAAA,gEACAC,2CACAC,0EAEAC,QAEA3uB,KAAA,iBACAsC,sEAGAtC,KAAA,mBACAsC,+CAGAtC,KAAA,oBACAsC,qDAKAtC,KAAA,cACAuuB,KAAA,GACAC,iFACAC,wDACAC,gHAGAC,QAEA3uB,KAAA,iBACAsC,sEAGAtC,KAAA,mBACAsC,+CAGAtC,KAAA,oBACAsC,8EC1CAhE,EAAAJ,QAAAN,EAAA,sDCoCA,SAAAgxB,EAAAlwB,GACA,IAAA4G,EAAA3G,OAAAmB,UAAA+D,SAAA1F,KAAAO,GACA,OAAAmwB,EAAAvpB,GAAAupB,EAAAvpB,GACA,OAAA5G,EAAA,YACAgF,IAAAhF,EAAA,YACAA,IAAAC,OAAAD,GAAA,gBACAA,EAgBA,SAAAowB,IACArvB,KAAAkvB,SAjDA,IAMAE,GACAE,iBAAA,QACAC,kBAAA,SACAC,oBAAA,WACAC,qBAAA,YACAC,gBAAA,SAXA7wB,EAAAJ,QAAA0wB,GAmCAE,QAAAA,EAgCAA,EAAAhvB,UAAAsvB,GAAAR,EA6BAE,EAAAhvB,UAAA2Y,OAAA,SAAA1V,EAAAT,GACA,OAAA,IAAApD,UAAAd,OAAAqB,KAAAkvB,MAAA5rB,IACAtD,KAAAkvB,MAAA5rB,GAAAT,EACA7C,OAqBAqvB,EAAAhvB,UAAAwC,KAAA,SAAA5D,EAAAqE,GACA,GAAAA,IAAA6rB,EAAAlwB,GAAA,OAAA,EACA,IAAA4D,EAAA7C,KAAAkvB,MAAA5rB,GAEA,GAAAT,GAAA,WAAAssB,EAAAtsB,GACA,OAAAA,EAAAA,KAAA5D,GACA,GAAA4D,GAAA,aAAAssB,EAAAtsB,GACA,OAAAA,EAAA5D,GAEA,MAAA,IAAA2wB,eAAA,cAAAtsB,EAAA,6IClHA,SAAA6rB,EAAAlwB,GACA,IAAAqE,EAAApE,OAAAmB,UAAA+D,SAAA1F,KAAAO,GAAAmO,MAAAyiB,GAAA,GAAAtsB,cAEA,MAAA,mBAAAiY,SAAAvc,aAAAuc,QAAA,UAEA,OAAAvc,EAAA,YAEAgF,IAAAhF,EAAA,YACAqE,EAgBA,SAAA+rB,IACA,KAAArvB,gBAAAqvB,GAAA,OAAA,IAAAA,EACArvB,KAAAkvB,SAzCA,IAaAW,EAAA,qBAbAhxB,EAAAJ,QAAA0wB,GA0BAE,QAAAA,EAiCAA,EAAAhvB,UAAAsvB,GAAAR,EA6BAE,EAAAhvB,UAAA2Y,OAAA,SAAA1V,EAAAT,GACA,OAAA,IAAApD,UAAAd,OAAAqB,KAAAkvB,MAAA5rB,IACAtD,KAAAkvB,MAAA5rB,GAAAT,EACA7C,OAqBAqvB,EAAAhvB,UAAAwC,KAAA,SAAA5D,EAAAqE,GACA,GAAAA,IAAA6rB,EAAAlwB,GAAA,OAAA,EACA,IAAA4D,EAAA7C,KAAAkvB,MAAA5rB,GAEA,GAAAT,GAAA,WAAAssB,EAAAtsB,GACA,OAAAA,EAAAA,KAAA5D,GACA,GAAA4D,GAAA,aAAAssB,EAAAtsB,GACA,OAAAA,EAAA5D,GAEA,MAAA,IAAA2wB,eAAA,cAAAtsB,EAAA,+NCnIA,SAAW6Q,SAAU+E,QAWnB,SAAS4W,cAAcC,GACrB,OAAOA,EAAS1pB,IAAI,SAAA2pB,GAGlB,OAFAA,EAAKhB,MAAQzX,OAAOyY,EAAKhB,OACzBgB,EAAKf,OAAS1X,OAAOyY,EAAKf,QACnBe,IAkDX,SAASC,iBAAiBjvB,GACxB,OAAOqY,YACJyL,QAAQ,qBAAsB9jB,GAC9B4b,KAAK,SAAA3Z,GAAA,OAAOA,IACZitB,MAAM,SAAAlpB,GACLpF,QAAQuuB,IAAI,yBAA0BnpB,KAO5C,SAASopB,SAAShe,EAAMie,EAAM1W,GAC5B,IAAI2W,OAAA,EACJ,OAAO,WACL,IAAMhpB,EAAUtH,KACVN,EAAOD,UACP8wB,EAAQ,WACZD,EAAU,KACL3W,GACHvH,EAAKhB,MAAM9J,EAAS5H,IAGlB8wB,EAAU7W,IAAc2W,EAC9BG,aAAaH,GACbA,EAAUtV,WAAWuV,EAAOF,GACxBG,GACFpe,EAAKhB,MAAM9J,EAAS5H,IAoB1B,SAASgxB,eAAeC,GACtB,IAAMC,EAAM9oB,KAAK+oB,MAAM/oB,KAAKgpB,SAAWH,EAAYhyB,QAGnD,OAFAqC,OAAO+vB,aAAeH,EACtBX,iBAAiBjvB,QACV4vB,EAGT,SAASI,iBAAiBL,GACxB,IACMI,EAAe/vB,OAAO+vB,aAO5B,OALqB,IAAjBA,EACQJ,EAAYhyB,OAAS,EAErBoyB,EAAe,EAK7B,SAASE,aAAaN,GACpB,IACMI,EAAe/vB,OAAO+vB,aAO5B,OALIA,GAAgBJ,EAAYhyB,OAAS,GAAKoyB,EAAe,EACjD,EAEAA,EAAe,EAM7B,SAASG,kBAAkBP,GACzB,OAAOA,EAAY3vB,OAAO+vB,cAG5B,SAASI,kBACPvvB,QAAQuuB,IAAI,oBAEZiB,wBAAwBC,UAAUC,IAAI,UACtCtwB,OAAO+vB,aAAe/vB,OAAOuwB,QACzBb,eAAeX,UACfiB,iBAAiBjB,UACrBE,iBAAiBjvB,QAAQ4b,KAAK,WAC5B1D,OAAOsY,SAASC,WAIpB,SAASC,cACP9vB,QAAQuuB,IAAI,gBAEZwB,oBAAoBN,UAAUC,IAAI,UAClCtwB,OAAO+vB,aAAe/vB,OAAOuwB,QACzBb,eAAeX,UACfkB,aAAalB,UACjBE,iBAAiBjvB,QAAQ4b,KAAK,WAC5B1D,OAAOsY,SAASC,WAIpB,SAASG,gBACPhwB,QAAQuuB,IAAI,mBACZnvB,OAAOuwB,SAAWvwB,OAAOuwB,QACzBM,wBAAwBR,UAAUS,OAAO,UACzCV,wBAAwBvW,WAAWwW,UAAUS,OAAO,UACpD7B,iBAAiBjvB,QAGnB,SAAS+wB,YAAYC,GACnBC,eAAiBD,EAEjBE,UAAUC,UAAYH,EAAWjD,OAE7BiD,EAAWhD,QACboD,OAAOpwB,MAAQgwB,EAAWhD,OAG5BqD,UAAU,MAAM,GAIlB,SAASC,YAAYC,EAAYC,IAClB,IAATA,GACFC,WAAWR,eAAe/C,OAE5BwD,iBAAiBH,GAGnB,SAASE,WAAWvD,GAClB,GAAIA,EAAO,CACT,IAAMyD,EAAWzD,EACd7oB,IAAI,SAAAxD,GACH,MAAA,sIAEiCA,EAAKtC,KAFtC,mCAKDgG,KAAK,IACRqsB,YAAYhe,UAAY+d,GAI5B,SAASD,iBAAiBG,GACxB,IAAKA,EACH,MAAM,IAAIv0B,MAAM,6BAGlB,IAAIw0B,GAAY,EAChBD,EAAazzB,QAAQ,SAAA2zB,IACA,IAAfA,IACFD,GAAY,QAGGtzB,MAAMd,KAAKk0B,YAAYI,iBAAiB,gBACnD5zB,QAAQ,SAAC6zB,EAAcC,IACF,IAAvBL,EAAaK,IACfD,EAAare,UAAY,aACzBqe,EAAa5B,UAAU8B,OAAO,QAC9BF,EAAa5B,UAAUC,IAAI,UAE3B2B,EAAare,UAAY,aACzBqe,EAAa5B,UAAU8B,OAAO,QAC9BF,EAAa5B,UAAUC,IAAI,YAIb,IAAdwB,GACFM,YAAYjB,UAAY,OACxBiB,YAAY/B,UAAU8B,OAAO,QAC7BC,YAAY/B,UAAUC,IAAI,UAE1B8B,YAAYjB,UAAY,OACxBiB,YAAY/B,UAAU8B,OAAO,QAC7BC,YAAY/B,UAAUC,IAAI,SAI9B,SAAS+B,iBAAiBC,GAExB,IAAIC,EAAQ,GACG,OAAXD,IACFC,EAAA,yDAEcxd,KAAKC,UAAUsd,EAAO5wB,UAFpC,qBAGYqT,KAAKC,UAAUsd,EAAOvwB,QAHlC,kBAQFywB,gBAAgB5e,UAAY2e,EAG9B,SAASE,gBAAgBH,EAAQ5d,GAE/B,IAAI6d,EAAQ,GACRD,QAA6BrvB,IAAnBqvB,EAAO1zB,QACnB2zB,EAAA,6DAEkBxd,KAAKC,UAAUsd,EAAO1zB,SAFxC,iBAIS8V,IACT6d,EAAA,uDAEYxd,KAAKC,UAAUN,GAF3B,kBAMFge,cAAc9e,UAAY2e,EAO5B,SAASlB,UAAUG,GAEjBY,YAAY/B,UAAUS,OAAO,WAE7B,IAEM6B,EAASC,SAFAC,UAAUzB,OAAOpwB,QAIhCoxB,YAAY/B,UAAUS,OAAO,WAE7BQ,YAAYqB,EAAQnB,GAGtB,SAASqB,UAAUt1B,MACjB,IAAIu1B,OAAQ,EACZ,IACEA,MAAQC,KAAA,eAAoBx1B,KAApB,QACRk1B,gBAAgB,KAAMK,OACtB,MAAO9sB,GACPysB,gBAAgBzsB,GAElB,OAAO8sB,MAGT,SAASF,SAASle,QAChB,IAAIie,QAAS,EAiBb,OAhBAA,OAAS1B,eAAe/C,MAAM7oB,IAAI,SAAAxD,MAChC,IAAImxB,aAAc,EAClB,IACMte,SAGFse,YAAcD,KAAKlxB,KAAKA,MACxBjB,QAAQuuB,IAAI,eAAgB6D,cAG9BX,iBAAiB,MACjB,MAAOrsB,GACPqsB,iBAAiBrsB,GAEnB,OAAOgtB,cAMX,SAASC,QAAQjzB,GAqBf,SAASkzB,EAAWv2B,IAGK,IAAnBqD,EAAOuwB,SAAmC,KAAd5zB,EAAEw2B,SAAkBx2B,EAAEy2B,WAAaz2B,EAAE02B,SAAW12B,EAAE22B,SAEhFnD,kBACuB,KAAdxzB,EAAEw2B,SAAmBx2B,EAAEy2B,WAAaz2B,EAAE02B,UAAW12B,EAAE22B,SAI5D5C,cA9BJ9vB,QAAQuuB,IAAI,iBAGW,IAAnBnvB,EAAOuwB,UACTM,wBAAwBR,UAAUC,IAAI,UACtCF,wBAAwBvW,WAAWwW,UAAUC,IAAI,WAOnD,IAAMiD,EAA2BnE,SAAS,SAAAzyB,IAEG,IAAvC62B,eAAej1B,QAAQ5B,EAAEw2B,UAE3B9B,aAED,KAoBHD,OAAOqC,iBAAiB,UAAWF,GACnCpgB,SAASsgB,iBAAiB,UAAWP,GACrCrC,wBAAwB4C,iBAAiB,QAAS7C,eAClDR,wBAAwBqD,iBAAiB,QAAStD,iBAClDQ,oBAAoB8C,iBAAiB,QAAS/C,aAK9CK,YADiBb,kBAAkBnB,WAGnCsC,WAAU,GA3XZ,IAAMhZ,YAAclb,QAAQ,eACtBu2B,MAAQv2B,QAAQ,gBAChBoZ,OAASpZ,QAAQ,UACjBkD,OAASlD,QAAQ,QAAQkD,OAiB3B0uB,YACJ7wB,OAAOC,KAAKu1B,OAAOt1B,QAAQ,SAAAu1B,GAAW,IAAAC,GACpCA,EAAA7E,UAAShvB,KAATqQ,MAAAwjB,EAAAC,mBAAiBH,MAAMC,OAEzB5E,SAAWD,cAAcC,UAOzB,IAAIkC,oBAAA,EAGEuC,gBACJ,EACA,GACA,GACA,GACA,IAGExzB,QACFuwB,SAAS,EACTuD,OAAO,EACP/D,aAAc,GAIhB1X,YACGkL,QAAQ,sBACR3H,KAAK,SAAA3Z,GACAA,IACFjC,OAASiC,GAEXgxB,QAAQjzB,UAETkvB,MAAM,SAAAlpB,GACLpF,QAAQuuB,IAAI,mBAAoBnpB,GAChCitB,QAAQjzB,UAuCZ,IAAMkxB,UAAY/d,SAAS4gB,eAAe,WACpC3C,OAASje,SAAS4gB,eAAe,QACjCnC,YAAcze,SAAS4gB,eAAe,cACtC3B,YAAcjf,SAAS4gB,eAAe,cACtCrB,cAAgBvf,SAAS4gB,eAAe,eACxCvB,gBAAkBrf,SAAS4gB,eAAe,iBAC1ClD,wBAA0B1d,SAAS4gB,eAAe,oBAClD3D,wBAA0Bjd,SAAS4gB,eAAe,gBAClDpD,oBAAsBxd,SAAS4gB,eAAe,iBAmRnD5gB,SAAU+E","file":"bundle.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o\n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n var excludes = [].slice.call(arguments);\n\n function excludeProps (res, obj) {\n Object.keys(obj).forEach(function (key) {\n if (!~excludes.indexOf(key)) res[key] = obj[key];\n });\n }\n\n return function extendExclude () {\n var args = [].slice.call(arguments)\n , i = 0\n , res = {};\n\n for (; i < args.length; i++) {\n excludeProps(res, args[i]);\n }\n\n return res;\n };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n , props = extend(_props || {});\n\n // default values\n this.message = message || 'Unspecified AssertionError';\n this.showDiff = false;\n\n // copy from properties\n for (var key in props) {\n this[key] = props[key];\n }\n\n // capture stack trace\n ssf = ssf || arguments.callee;\n if (ssf && Error.captureStackTrace) {\n Error.captureStackTrace(this, ssf);\n } else {\n try {\n throw new Error();\n } catch(e) {\n this.stack = e.stack;\n }\n }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n var extend = exclude('constructor', 'toJSON', 'stack')\n , props = extend({ name: this.name }, this);\n\n // include stack if exists and not turned off\n if (false !== stack && this.stack) {\n props.stack = this.stack;\n }\n\n return props;\n};\n","module.exports = require('./lib/chai');\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar used = []\n , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n if (!~used.indexOf(fn)) {\n fn(this, util);\n used.push(fn);\n }\n\n return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n /*!\n * Module dependencies.\n */\n\n var AssertionError = _chai.AssertionError\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n _chai.Assertion = Assertion;\n\n /*!\n * Assertion Constructor\n *\n * Creates object for chaining.\n *\n * @api private\n */\n\n function Assertion (obj, msg, stack) {\n flag(this, 'ssfi', stack || arguments.callee);\n flag(this, 'object', obj);\n flag(this, 'message', msg);\n }\n\n Object.defineProperty(Assertion, 'includeStack', {\n get: function() {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n return config.includeStack;\n },\n set: function(value) {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n config.includeStack = value;\n }\n });\n\n Object.defineProperty(Assertion, 'showDiff', {\n get: function() {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n return config.showDiff;\n },\n set: function(value) {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n config.showDiff = value;\n }\n });\n\n Assertion.addProperty = function (name, fn) {\n util.addProperty(this.prototype, name, fn);\n };\n\n Assertion.addMethod = function (name, fn) {\n util.addMethod(this.prototype, name, fn);\n };\n\n Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n Assertion.overwriteProperty = function (name, fn) {\n util.overwriteProperty(this.prototype, name, fn);\n };\n\n Assertion.overwriteMethod = function (name, fn) {\n util.overwriteMethod(this.prototype, name, fn);\n };\n\n Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n /**\n * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n *\n * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n *\n * @name assert\n * @param {Philosophical} expression to be tested\n * @param {String|Function} message or function that returns message to display if expression fails\n * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n * @param {Mixed} expected value (remember to check for negation)\n * @param {Mixed} actual (optional) will default to `this.obj`\n * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n * @api private\n */\n\n Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n var ok = util.test(this, arguments);\n if (true !== showDiff) showDiff = false;\n if (true !== config.showDiff) showDiff = false;\n\n if (!ok) {\n var msg = util.getMessage(this, arguments)\n , actual = util.getActual(this, arguments);\n throw new AssertionError(msg, {\n actual: actual\n , expected: expected\n , showDiff: showDiff\n }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n }\n };\n\n /*!\n * ### ._obj\n *\n * Quick reference to stored `actual` value for plugin developers.\n *\n * @api private\n */\n\n Object.defineProperty(Assertion.prototype, '_obj',\n { get: function () {\n return flag(this, 'object');\n }\n , set: function (val) {\n flag(this, 'object', val);\n }\n });\n};\n","module.exports = {\n\n /**\n * ### config.includeStack\n *\n * User configurable property, influences whether stack trace\n * is included in Assertion error message. Default of false\n * suppresses stack trace in the error message.\n *\n * chai.config.includeStack = true; // enable stack on error\n *\n * @param {Boolean}\n * @api public\n */\n\n includeStack: false,\n\n /**\n * ### config.showDiff\n *\n * User configurable property, influences whether or not\n * the `showDiff` flag should be included in the thrown\n * AssertionErrors. `false` will always be `false`; `true`\n * will be true when the assertion has requested a diff\n * be shown.\n *\n * @param {Boolean}\n * @api public\n */\n\n showDiff: true,\n\n /**\n * ### config.truncateThreshold\n *\n * User configurable property, sets length threshold for actual and\n * expected values in assertion errors. If this threshold is exceeded, for\n * example for large data structures, the value is replaced with something\n * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n *\n * Set it to zero if you want to disable truncating altogether.\n *\n * This is especially userful when doing assertions on arrays: having this\n * set to a reasonable large value makes the failure messages readily\n * inspectable.\n *\n * chai.config.truncateThreshold = 0; // disable truncating\n *\n * @param {Number}\n * @api public\n */\n\n truncateThreshold: 40\n\n};\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n var Assertion = chai.Assertion\n , toString = Object.prototype.toString\n , flag = _.flag;\n\n /**\n * ### Language Chains\n *\n * The following are provided as chainable getters to\n * improve the readability of your assertions. They\n * do not provide testing capabilities unless they\n * have been overwritten by a plugin.\n *\n * **Chains**\n *\n * - to\n * - be\n * - been\n * - is\n * - that\n * - which\n * - and\n * - has\n * - have\n * - with\n * - at\n * - of\n * - same\n *\n * @name language chains\n * @namespace BDD\n * @api public\n */\n\n [ 'to', 'be', 'been'\n , 'is', 'and', 'has', 'have'\n , 'with', 'that', 'which', 'at'\n , 'of', 'same' ].forEach(function (chain) {\n Assertion.addProperty(chain, function () {\n return this;\n });\n });\n\n /**\n * ### .not\n *\n * Negates any of assertions following in the chain.\n *\n * expect(foo).to.not.equal('bar');\n * expect(goodFn).to.not.throw(Error);\n * expect({ foo: 'baz' }).to.have.property('foo')\n * .and.not.equal('bar');\n *\n * @name not\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('not', function () {\n flag(this, 'negate', true);\n });\n\n /**\n * ### .deep\n *\n * Sets the `deep` flag, later used by the `equal` and\n * `property` assertions.\n *\n * expect(foo).to.deep.equal({ bar: 'baz' });\n * expect({ foo: { bar: { baz: 'quux' } } })\n * .to.have.deep.property('foo.bar.baz', 'quux');\n *\n * `.deep.property` special characters can be escaped\n * by adding two slashes before the `.` or `[]`.\n *\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name deep\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('deep', function () {\n flag(this, 'deep', true);\n });\n\n /**\n * ### .any\n *\n * Sets the `any` flag, (opposite of the `all` flag)\n * later used in the `keys` assertion.\n *\n * expect(foo).to.have.any.keys('bar', 'baz');\n *\n * @name any\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('any', function () {\n flag(this, 'any', true);\n flag(this, 'all', false)\n });\n\n\n /**\n * ### .all\n *\n * Sets the `all` flag (opposite of the `any` flag)\n * later used by the `keys` assertion.\n *\n * expect(foo).to.have.all.keys('bar', 'baz');\n *\n * @name all\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('all', function () {\n flag(this, 'all', true);\n flag(this, 'any', false);\n });\n\n /**\n * ### .a(type)\n *\n * The `a` and `an` assertions are aliases that can be\n * used either as language chains or to assert a value's\n * type.\n *\n * // typeof\n * expect('test').to.be.a('string');\n * expect({ foo: 'bar' }).to.be.an('object');\n * expect(null).to.be.a('null');\n * expect(undefined).to.be.an('undefined');\n * expect(new Error).to.be.an('error');\n * expect(new Promise).to.be.a('promise');\n * expect(new Float32Array()).to.be.a('float32array');\n * expect(Symbol()).to.be.a('symbol');\n *\n * // es6 overrides\n * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n *\n * // language chain\n * expect(foo).to.be.an.instanceof(Foo);\n *\n * @name a\n * @alias an\n * @param {String} type\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function an (type, msg) {\n if (msg) flag(this, 'message', msg);\n type = type.toLowerCase();\n var obj = flag(this, 'object')\n , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n this.assert(\n type === _.type(obj)\n , 'expected #{this} to be ' + article + type\n , 'expected #{this} not to be ' + article + type\n );\n }\n\n Assertion.addChainableMethod('an', an);\n Assertion.addChainableMethod('a', an);\n\n /**\n * ### .include(value)\n *\n * The `include` and `contain` assertions can be used as either property\n * based language chains or as methods to assert the inclusion of an object\n * in an array or a substring in a string. When used as language chains,\n * they toggle the `contains` flag for the `keys` assertion.\n *\n * expect([1,2,3]).to.include(2);\n * expect('foobar').to.contain('foo');\n * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n *\n * @name include\n * @alias contain\n * @alias includes\n * @alias contains\n * @param {Object|String|Number} obj\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function includeChainingBehavior () {\n flag(this, 'contains', true);\n }\n\n function include (val, msg) {\n _.expectTypes(this, ['array', 'object', 'string']);\n\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var expected = false;\n\n if (_.type(obj) === 'array' && _.type(val) === 'object') {\n for (var i in obj) {\n if (_.eql(obj[i], val)) {\n expected = true;\n break;\n }\n }\n } else if (_.type(val) === 'object') {\n if (!flag(this, 'negate')) {\n for (var k in val) new Assertion(obj).property(k, val[k]);\n return;\n }\n var subset = {};\n for (var k in val) subset[k] = obj[k];\n expected = _.eql(subset, val);\n } else {\n expected = (obj != undefined) && ~obj.indexOf(val);\n }\n this.assert(\n expected\n , 'expected #{this} to include ' + _.inspect(val)\n , 'expected #{this} to not include ' + _.inspect(val));\n }\n\n Assertion.addChainableMethod('include', include, includeChainingBehavior);\n Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n /**\n * ### .ok\n *\n * Asserts that the target is truthy.\n *\n * expect('everything').to.be.ok;\n * expect(1).to.be.ok;\n * expect(false).to.not.be.ok;\n * expect(undefined).to.not.be.ok;\n * expect(null).to.not.be.ok;\n *\n * @name ok\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('ok', function () {\n this.assert(\n flag(this, 'object')\n , 'expected #{this} to be truthy'\n , 'expected #{this} to be falsy');\n });\n\n /**\n * ### .true\n *\n * Asserts that the target is `true`.\n *\n * expect(true).to.be.true;\n * expect(1).to.not.be.true;\n *\n * @name true\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('true', function () {\n this.assert(\n true === flag(this, 'object')\n , 'expected #{this} to be true'\n , 'expected #{this} to be false'\n , this.negate ? false : true\n );\n });\n\n /**\n * ### .false\n *\n * Asserts that the target is `false`.\n *\n * expect(false).to.be.false;\n * expect(0).to.not.be.false;\n *\n * @name false\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('false', function () {\n this.assert(\n false === flag(this, 'object')\n , 'expected #{this} to be false'\n , 'expected #{this} to be true'\n , this.negate ? true : false\n );\n });\n\n /**\n * ### .null\n *\n * Asserts that the target is `null`.\n *\n * expect(null).to.be.null;\n * expect(undefined).to.not.be.null;\n *\n * @name null\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('null', function () {\n this.assert(\n null === flag(this, 'object')\n , 'expected #{this} to be null'\n , 'expected #{this} not to be null'\n );\n });\n\n /**\n * ### .undefined\n *\n * Asserts that the target is `undefined`.\n *\n * expect(undefined).to.be.undefined;\n * expect(null).to.not.be.undefined;\n *\n * @name undefined\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('undefined', function () {\n this.assert(\n undefined === flag(this, 'object')\n , 'expected #{this} to be undefined'\n , 'expected #{this} not to be undefined'\n );\n });\n\n /**\n * ### .NaN\n * Asserts that the target is `NaN`.\n *\n * expect('foo').to.be.NaN;\n * expect(4).not.to.be.NaN;\n *\n * @name NaN\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('NaN', function () {\n this.assert(\n isNaN(flag(this, 'object'))\n , 'expected #{this} to be NaN'\n , 'expected #{this} not to be NaN'\n );\n });\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi'\n * , bar = null\n * , baz;\n *\n * expect(foo).to.exist;\n * expect(bar).to.not.exist;\n * expect(baz).to.not.exist;\n *\n * @name exist\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('exist', function () {\n this.assert(\n null != flag(this, 'object')\n , 'expected #{this} to exist'\n , 'expected #{this} to not exist'\n );\n });\n\n\n /**\n * ### .empty\n *\n * Asserts that the target's length is `0`. For arrays and strings, it checks\n * the `length` property. For objects, it gets the count of\n * enumerable keys.\n *\n * expect([]).to.be.empty;\n * expect('').to.be.empty;\n * expect({}).to.be.empty;\n *\n * @name empty\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('empty', function () {\n var obj = flag(this, 'object')\n , expected = obj;\n\n if (Array.isArray(obj) || 'string' === typeof object) {\n expected = obj.length;\n } else if (typeof obj === 'object') {\n expected = Object.keys(obj).length;\n }\n\n this.assert(\n !expected\n , 'expected #{this} to be empty'\n , 'expected #{this} not to be empty'\n );\n });\n\n /**\n * ### .arguments\n *\n * Asserts that the target is an arguments object.\n *\n * function test () {\n * expect(arguments).to.be.arguments;\n * }\n *\n * @name arguments\n * @alias Arguments\n * @namespace BDD\n * @api public\n */\n\n function checkArguments () {\n var obj = flag(this, 'object')\n , type = Object.prototype.toString.call(obj);\n this.assert(\n '[object Arguments]' === type\n , 'expected #{this} to be arguments but got ' + type\n , 'expected #{this} to not be arguments'\n );\n }\n\n Assertion.addProperty('arguments', checkArguments);\n Assertion.addProperty('Arguments', checkArguments);\n\n /**\n * ### .equal(value)\n *\n * Asserts that the target is strictly equal (`===`) to `value`.\n * Alternately, if the `deep` flag is set, asserts that\n * the target is deeply equal to `value`.\n *\n * expect('hello').to.equal('hello');\n * expect(42).to.equal(42);\n * expect(1).to.not.equal(true);\n * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n *\n * @name equal\n * @alias equals\n * @alias eq\n * @alias deep.equal\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEqual (val, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'deep')) {\n return this.eql(val);\n } else {\n this.assert(\n val === obj\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{exp}'\n , val\n , this._obj\n , true\n );\n }\n }\n\n Assertion.addMethod('equal', assertEqual);\n Assertion.addMethod('equals', assertEqual);\n Assertion.addMethod('eq', assertEqual);\n\n /**\n * ### .eql(value)\n *\n * Asserts that the target is deeply equal to `value`.\n *\n * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n *\n * @name eql\n * @alias eqls\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEql(obj, msg) {\n if (msg) flag(this, 'message', msg);\n this.assert(\n _.eql(obj, flag(this, 'object'))\n , 'expected #{this} to deeply equal #{exp}'\n , 'expected #{this} to not deeply equal #{exp}'\n , obj\n , this._obj\n , true\n );\n }\n\n Assertion.addMethod('eql', assertEql);\n Assertion.addMethod('eqls', assertEql);\n\n /**\n * ### .above(value)\n *\n * Asserts that the target is greater than `value`.\n *\n * expect(10).to.be.above(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n *\n * @name above\n * @alias gt\n * @alias greaterThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertAbove (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len > n\n , 'expected #{this} to have a length above #{exp} but got #{act}'\n , 'expected #{this} to not have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj > n\n , 'expected #{this} to be above ' + n\n , 'expected #{this} to be at most ' + n\n );\n }\n }\n\n Assertion.addMethod('above', assertAbove);\n Assertion.addMethod('gt', assertAbove);\n Assertion.addMethod('greaterThan', assertAbove);\n\n /**\n * ### .least(value)\n *\n * Asserts that the target is greater than or equal to `value`.\n *\n * expect(10).to.be.at.least(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.least(2);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n *\n * @name least\n * @alias gte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLeast (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= n\n , 'expected #{this} to have a length at least #{exp} but got #{act}'\n , 'expected #{this} to have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj >= n\n , 'expected #{this} to be at least ' + n\n , 'expected #{this} to be below ' + n\n );\n }\n }\n\n Assertion.addMethod('least', assertLeast);\n Assertion.addMethod('gte', assertLeast);\n\n /**\n * ### .below(value)\n *\n * Asserts that the target is less than `value`.\n *\n * expect(5).to.be.below(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n *\n * @name below\n * @alias lt\n * @alias lessThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertBelow (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len < n\n , 'expected #{this} to have a length below #{exp} but got #{act}'\n , 'expected #{this} to not have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj < n\n , 'expected #{this} to be below ' + n\n , 'expected #{this} to be at least ' + n\n );\n }\n }\n\n Assertion.addMethod('below', assertBelow);\n Assertion.addMethod('lt', assertBelow);\n Assertion.addMethod('lessThan', assertBelow);\n\n /**\n * ### .most(value)\n *\n * Asserts that the target is less than or equal to `value`.\n *\n * expect(5).to.be.at.most(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.most(4);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n *\n * @name most\n * @alias lte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertMost (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len <= n\n , 'expected #{this} to have a length at most #{exp} but got #{act}'\n , 'expected #{this} to have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj <= n\n , 'expected #{this} to be at most ' + n\n , 'expected #{this} to be above ' + n\n );\n }\n }\n\n Assertion.addMethod('most', assertMost);\n Assertion.addMethod('lte', assertMost);\n\n /**\n * ### .within(start, finish)\n *\n * Asserts that the target is within a range.\n *\n * expect(7).to.be.within(5,10);\n *\n * Can also be used in conjunction with `length` to\n * assert a length range. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * @name within\n * @param {Number} start lowerbound inclusive\n * @param {Number} finish upperbound inclusive\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('within', function (start, finish, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , range = start + '..' + finish;\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= start && len <= finish\n , 'expected #{this} to have a length within ' + range\n , 'expected #{this} to not have a length within ' + range\n );\n } else {\n this.assert(\n obj >= start && obj <= finish\n , 'expected #{this} to be within ' + range\n , 'expected #{this} to not be within ' + range\n );\n }\n });\n\n /**\n * ### .instanceof(constructor)\n *\n * Asserts that the target is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , Chai = new Tea('chai');\n *\n * expect(Chai).to.be.an.instanceof(Tea);\n * expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n *\n * @name instanceof\n * @param {Constructor} constructor\n * @param {String} message _optional_\n * @alias instanceOf\n * @namespace BDD\n * @api public\n */\n\n function assertInstanceOf (constructor, msg) {\n if (msg) flag(this, 'message', msg);\n var name = _.getName(constructor);\n this.assert(\n flag(this, 'object') instanceof constructor\n , 'expected #{this} to be an instance of ' + name\n , 'expected #{this} to not be an instance of ' + name\n );\n };\n\n Assertion.addMethod('instanceof', assertInstanceOf);\n Assertion.addMethod('instanceOf', assertInstanceOf);\n\n /**\n * ### .property(name, [value])\n *\n * Asserts that the target has a property `name`, optionally asserting that\n * the value of that property is strictly equal to `value`.\n * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n * references into objects and arrays.\n *\n * // simple referencing\n * var obj = { foo: 'bar' };\n * expect(obj).to.have.property('foo');\n * expect(obj).to.have.property('foo', 'bar');\n *\n * // deep referencing\n * var deepObj = {\n * green: { tea: 'matcha' }\n * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n * };\n *\n * expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n *\n * You can also use an array as the starting point of a `deep.property`\n * assertion, or traverse nested arrays.\n *\n * var arr = [\n * [ 'chai', 'matcha', 'konacha' ]\n * , [ { tea: 'chai' }\n * , { tea: 'matcha' }\n * , { tea: 'konacha' } ]\n * ];\n *\n * expect(arr).to.have.deep.property('[0][1]', 'matcha');\n * expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n *\n * Furthermore, `property` changes the subject of the assertion\n * to be the value of that property from the original object. This\n * permits for further chainable assertions on that property.\n *\n * expect(obj).to.have.property('foo')\n * .that.is.a('string');\n * expect(deepObj).to.have.property('green')\n * .that.is.an('object')\n * .that.deep.equals({ tea: 'matcha' });\n * expect(deepObj).to.have.property('teas')\n * .that.is.an('array')\n * .with.deep.property('[2]')\n * .that.deep.equals({ tea: 'konacha' });\n *\n * Note that dots and bracket in `name` must be backslash-escaped when\n * the `deep` flag is set, while they must NOT be escaped when the `deep`\n * flag is not set.\n *\n * // simple referencing\n * var css = { '.link[target]': 42 };\n * expect(css).to.have.property('.link[target]', 42);\n *\n * // deep referencing\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name property\n * @alias deep.property\n * @param {String} name\n * @param {Mixed} value (optional)\n * @param {String} message _optional_\n * @returns value of property for chaining\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('property', function (name, val, msg) {\n if (msg) flag(this, 'message', msg);\n\n var isDeep = !!flag(this, 'deep')\n , descriptor = isDeep ? 'deep property ' : 'property '\n , negate = flag(this, 'negate')\n , obj = flag(this, 'object')\n , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n , hasProperty = isDeep\n ? pathInfo.exists\n : _.hasProperty(name, obj)\n , value = isDeep\n ? pathInfo.value\n : obj[name];\n\n if (negate && arguments.length > 1) {\n if (undefined === value) {\n msg = (msg != null) ? msg + ': ' : '';\n throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n }\n } else {\n this.assert(\n hasProperty\n , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n }\n\n if (arguments.length > 1) {\n this.assert(\n val === value\n , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n , val\n , value\n );\n }\n\n flag(this, 'object', value);\n });\n\n\n /**\n * ### .ownProperty(name)\n *\n * Asserts that the target has an own property `name`.\n *\n * expect('test').to.have.ownProperty('length');\n *\n * @name ownProperty\n * @alias haveOwnProperty\n * @param {String} name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnProperty (name, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n obj.hasOwnProperty(name)\n , 'expected #{this} to have own property ' + _.inspect(name)\n , 'expected #{this} to not have own property ' + _.inspect(name)\n );\n }\n\n Assertion.addMethod('ownProperty', assertOwnProperty);\n Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n /**\n * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n *\n * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n *\n * expect('test').to.have.ownPropertyDescriptor('length');\n * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n * expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n *\n * @name ownPropertyDescriptor\n * @alias haveOwnPropertyDescriptor\n * @param {String} name\n * @param {Object} descriptor _optional_\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnPropertyDescriptor (name, descriptor, msg) {\n if (typeof descriptor === 'string') {\n msg = descriptor;\n descriptor = null;\n }\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n if (actualDescriptor && descriptor) {\n this.assert(\n _.eql(descriptor, actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n , descriptor\n , actualDescriptor\n , true\n );\n } else {\n this.assert(\n actualDescriptor\n , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n );\n }\n flag(this, 'object', actualDescriptor);\n }\n\n Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n /**\n * ### .length\n *\n * Sets the `doLength` flag later used as a chain precursor to a value\n * comparison for the `length` property.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * *Deprecation notice:* Using `length` as an assertion will be deprecated\n * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n * asserting for `length` property value using `length(value)` should be\n * switched to use `lengthOf(value)` instead.\n *\n * @name length\n * @namespace BDD\n * @api public\n */\n\n /**\n * ### .lengthOf(value[, message])\n *\n * Asserts that the target's `length` property has\n * the expected value.\n *\n * expect([ 1, 2, 3]).to.have.lengthOf(3);\n * expect('foobar').to.have.lengthOf(6);\n *\n * @name lengthOf\n * @param {Number} length\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLengthChain () {\n flag(this, 'doLength', true);\n }\n\n function assertLength (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n\n this.assert(\n len == n\n , 'expected #{this} to have a length of #{exp} but got #{act}'\n , 'expected #{this} to not have a length of #{act}'\n , n\n , len\n );\n }\n\n Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n Assertion.addMethod('lengthOf', assertLength);\n\n /**\n * ### .match(regexp)\n *\n * Asserts that the target matches a regular expression.\n *\n * expect('foobar').to.match(/^foo/);\n *\n * @name match\n * @alias matches\n * @param {RegExp} RegularExpression\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n function assertMatch(re, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n re.exec(obj)\n , 'expected #{this} to match ' + re\n , 'expected #{this} not to match ' + re\n );\n }\n\n Assertion.addMethod('match', assertMatch);\n Assertion.addMethod('matches', assertMatch);\n\n /**\n * ### .string(string)\n *\n * Asserts that the string target contains another string.\n *\n * expect('foobar').to.have.string('bar');\n *\n * @name string\n * @param {String} string\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('string', function (str, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('string');\n\n this.assert(\n ~obj.indexOf(str)\n , 'expected #{this} to contain ' + _.inspect(str)\n , 'expected #{this} to not contain ' + _.inspect(str)\n );\n });\n\n\n /**\n * ### .keys(key1, [key2], [...])\n *\n * Asserts that the target contains any or all of the passed-in keys.\n * Use in combination with `any`, `all`, `contains`, or `have` will affect\n * what will pass.\n *\n * When used in conjunction with `any`, at least one key that is passed\n * in must exist in the target object. This is regardless whether or not\n * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n * should be used in the assertion. If neither are used, the assertion is\n * defaulted to `all`.\n *\n * When both `all` and `contain` are used, the target object must have at\n * least all of the passed-in keys but may have more keys not listed.\n *\n * When both `all` and `have` are used, the target object must both contain\n * all of the passed-in keys AND the number of keys in the target object must\n * match the number of keys passed in (in other words, a target object must\n * have all and only all of the passed-in keys).\n *\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n *\n *\n * @name keys\n * @alias key\n * @param {...String|Array|Object} keys\n * @namespace BDD\n * @api public\n */\n\n function assertKeys (keys) {\n var obj = flag(this, 'object')\n , str\n , ok = true\n , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n switch (_.type(keys)) {\n case \"array\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n break;\n case \"object\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n keys = Object.keys(keys);\n break;\n default:\n keys = Array.prototype.slice.call(arguments);\n }\n\n if (!keys.length) throw new Error('keys required');\n\n var actual = Object.keys(obj)\n , expected = keys\n , len = keys.length\n , any = flag(this, 'any')\n , all = flag(this, 'all');\n\n if (!any && !all) {\n all = true;\n }\n\n // Has any\n if (any) {\n var intersection = expected.filter(function(key) {\n return ~actual.indexOf(key);\n });\n ok = intersection.length > 0;\n }\n\n // Has all\n if (all) {\n ok = keys.every(function(key){\n return ~actual.indexOf(key);\n });\n if (!flag(this, 'negate') && !flag(this, 'contains')) {\n ok = ok && keys.length == actual.length;\n }\n }\n\n // Key string\n if (len > 1) {\n keys = keys.map(function(key){\n return _.inspect(key);\n });\n var last = keys.pop();\n if (all) {\n str = keys.join(', ') + ', and ' + last;\n }\n if (any) {\n str = keys.join(', ') + ', or ' + last;\n }\n } else {\n str = _.inspect(keys[0]);\n }\n\n // Form\n str = (len > 1 ? 'keys ' : 'key ') + str;\n\n // Have / include\n str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n // Assertion\n this.assert(\n ok\n , 'expected #{this} to ' + str\n , 'expected #{this} to not ' + str\n , expected.slice(0).sort()\n , actual.sort()\n , true\n );\n }\n\n Assertion.addMethod('keys', assertKeys);\n Assertion.addMethod('key', assertKeys);\n\n /**\n * ### .throw(constructor)\n *\n * Asserts that the function target will throw a specific error, or specific type of error\n * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n * for the error's message.\n *\n * var err = new ReferenceError('This is a bad function.');\n * var fn = function () { throw err; }\n * expect(fn).to.throw(ReferenceError);\n * expect(fn).to.throw(Error);\n * expect(fn).to.throw(/bad function/);\n * expect(fn).to.not.throw('good function');\n * expect(fn).to.throw(ReferenceError, /bad function/);\n * expect(fn).to.throw(err);\n *\n * Please note that when a throw expectation is negated, it will check each\n * parameter independently, starting with error constructor type. The appropriate way\n * to check for the existence of a type of error but for a message that does not match\n * is to use `and`.\n *\n * expect(fn).to.throw(ReferenceError)\n * .and.not.throw(/good function/);\n *\n * @name throw\n * @alias throws\n * @alias Throw\n * @param {ErrorConstructor} constructor\n * @param {String|RegExp} expected error message\n * @param {String} message _optional_\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @returns error for chaining (null if no error)\n * @namespace BDD\n * @api public\n */\n\n function assertThrows (constructor, errMsg, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('function');\n\n var thrown = false\n , desiredError = null\n , name = null\n , thrownError = null;\n\n if (arguments.length === 0) {\n errMsg = null;\n constructor = null;\n } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n errMsg = constructor;\n constructor = null;\n } else if (constructor && constructor instanceof Error) {\n desiredError = constructor;\n constructor = null;\n errMsg = null;\n } else if (typeof constructor === 'function') {\n name = constructor.prototype.name;\n if (!name || (name === 'Error' && constructor !== Error)) {\n name = constructor.name || (new constructor()).name;\n }\n } else {\n constructor = null;\n }\n\n try {\n obj();\n } catch (err) {\n // first, check desired error\n if (desiredError) {\n this.assert(\n err === desiredError\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp}'\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (err instanceof Error ? err.toString() : err)\n );\n\n flag(this, 'object', err);\n return this;\n }\n\n // next, check constructor\n if (constructor) {\n this.assert(\n err instanceof constructor\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n , name\n , (err instanceof Error ? err.toString() : err)\n );\n\n if (!errMsg) {\n flag(this, 'object', err);\n return this;\n }\n }\n\n // next, check message\n var message = 'error' === _.type(err) && \"message\" in err\n ? err.message\n : '' + err;\n\n if ((message != null) && errMsg && errMsg instanceof RegExp) {\n this.assert(\n errMsg.exec(message)\n , 'expected #{this} to throw error matching #{exp} but got #{act}'\n , 'expected #{this} to throw error not matching #{exp}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n this.assert(\n ~message.indexOf(errMsg)\n , 'expected #{this} to throw error including #{exp} but got #{act}'\n , 'expected #{this} to throw error not including #{act}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else {\n thrown = true;\n thrownError = err;\n }\n }\n\n var actuallyGot = ''\n , expectedThrown = name !== null\n ? name\n : desiredError\n ? '#{exp}' //_.inspect(desiredError)\n : 'an error';\n\n if (thrown) {\n actuallyGot = ' but #{act} was thrown'\n }\n\n this.assert(\n thrown === true\n , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n );\n\n flag(this, 'object', thrownError);\n };\n\n Assertion.addMethod('throw', assertThrows);\n Assertion.addMethod('throws', assertThrows);\n Assertion.addMethod('Throw', assertThrows);\n\n /**\n * ### .respondTo(method)\n *\n * Asserts that the object or class target will respond to a method.\n *\n * Klass.prototype.bar = function(){};\n * expect(Klass).to.respondTo('bar');\n * expect(obj).to.respondTo('bar');\n *\n * To check if a constructor will respond to a static function,\n * set the `itself` flag.\n *\n * Klass.baz = function(){};\n * expect(Klass).itself.to.respondTo('baz');\n *\n * @name respondTo\n * @alias respondsTo\n * @param {String} method\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function respondTo (method, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , itself = flag(this, 'itself')\n , context = ('function' === _.type(obj) && !itself)\n ? obj.prototype[method]\n : obj[method];\n\n this.assert(\n 'function' === typeof context\n , 'expected #{this} to respond to ' + _.inspect(method)\n , 'expected #{this} to not respond to ' + _.inspect(method)\n );\n }\n\n Assertion.addMethod('respondTo', respondTo);\n Assertion.addMethod('respondsTo', respondTo);\n\n /**\n * ### .itself\n *\n * Sets the `itself` flag, later used by the `respondTo` assertion.\n *\n * function Foo() {}\n * Foo.bar = function() {}\n * Foo.prototype.baz = function() {}\n *\n * expect(Foo).itself.to.respondTo('bar');\n * expect(Foo).itself.not.to.respondTo('baz');\n *\n * @name itself\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('itself', function () {\n flag(this, 'itself', true);\n });\n\n /**\n * ### .satisfy(method)\n *\n * Asserts that the target passes a given truth test.\n *\n * expect(1).to.satisfy(function(num) { return num > 0; });\n *\n * @name satisfy\n * @alias satisfies\n * @param {Function} matcher\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function satisfy (matcher, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var result = matcher(obj);\n this.assert(\n result\n , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n , this.negate ? false : true\n , result\n );\n }\n\n Assertion.addMethod('satisfy', satisfy);\n Assertion.addMethod('satisfies', satisfy);\n\n /**\n * ### .closeTo(expected, delta)\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * expect(1.5).to.be.closeTo(1, 0.5);\n *\n * @name closeTo\n * @alias approximately\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function closeTo(expected, delta, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj, msg).is.a('number');\n if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n throw new Error('the arguments to closeTo or approximately must be numbers');\n }\n\n this.assert(\n Math.abs(obj - expected) <= delta\n , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n );\n }\n\n Assertion.addMethod('closeTo', closeTo);\n Assertion.addMethod('approximately', closeTo);\n\n function isSubsetOf(subset, superset, cmp) {\n return subset.every(function(elem) {\n if (!cmp) return superset.indexOf(elem) !== -1;\n\n return superset.some(function(elem2) {\n return cmp(elem, elem2);\n });\n })\n }\n\n /**\n * ### .members(set)\n *\n * Asserts that the target is a superset of `set`,\n * or that the target and `set` have the same strictly-equal (===) members.\n * Alternately, if the `deep` flag is set, set members are compared for deep\n * equality.\n *\n * expect([1, 2, 3]).to.include.members([3, 2]);\n * expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n *\n * expect([4, 2]).to.have.members([2, 4]);\n * expect([5, 2]).to.not.have.members([5, 2, 1]);\n *\n * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n *\n * @name members\n * @param {Array} set\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('members', function (subset, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj).to.be.an('array');\n new Assertion(subset).to.be.an('array');\n\n var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n if (flag(this, 'contains')) {\n return this.assert(\n isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to be a superset of #{act}'\n , 'expected #{this} to not be a superset of #{act}'\n , obj\n , subset\n );\n }\n\n this.assert(\n isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to have the same members as #{act}'\n , 'expected #{this} to not have the same members as #{act}'\n , obj\n , subset\n );\n });\n\n /**\n * ### .oneOf(list)\n *\n * Assert that a value appears somewhere in the top level of array `list`.\n *\n * expect('a').to.be.oneOf(['a', 'b', 'c']);\n * expect(9).to.not.be.oneOf(['z']);\n * expect([3]).to.not.be.oneOf([1, 2, [3]]);\n *\n * var three = [3];\n * // for object-types, contents are not compared\n * expect(three).to.not.be.oneOf([1, 2, [3]]);\n * // comparing references works\n * expect(three).to.be.oneOf([1, 2, three]);\n *\n * @name oneOf\n * @param {Array<*>} list\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function oneOf (list, msg) {\n if (msg) flag(this, 'message', msg);\n var expected = flag(this, 'object');\n new Assertion(list).to.be.an('array');\n\n this.assert(\n list.indexOf(expected) > -1\n , 'expected #{this} to be one of #{exp}'\n , 'expected #{this} to not be one of #{exp}'\n , list\n , expected\n );\n }\n\n Assertion.addMethod('oneOf', oneOf);\n\n\n /**\n * ### .change(function)\n *\n * Asserts that a function changes an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val += 3 };\n * var noChangeFn = function() { return 'foo' + 'bar'; }\n * expect(fn).to.change(obj, 'val');\n * expect(noChangeFn).to.not.change(obj, 'val')\n *\n * @name change\n * @alias changes\n * @alias Change\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertChanges (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n initial !== object[prop]\n , 'expected .' + prop + ' to change'\n , 'expected .' + prop + ' to not change'\n );\n }\n\n Assertion.addChainableMethod('change', assertChanges);\n Assertion.addChainableMethod('changes', assertChanges);\n\n /**\n * ### .increase(function)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * expect(fn).to.increase(obj, 'val');\n *\n * @name increase\n * @alias increases\n * @alias Increase\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertIncreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial > 0\n , 'expected .' + prop + ' to increase'\n , 'expected .' + prop + ' to not increase'\n );\n }\n\n Assertion.addChainableMethod('increase', assertIncreases);\n Assertion.addChainableMethod('increases', assertIncreases);\n\n /**\n * ### .decrease(function)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * expect(fn).to.decrease(obj, 'val');\n *\n * @name decrease\n * @alias decreases\n * @alias Decrease\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertDecreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial < 0\n , 'expected .' + prop + ' to decrease'\n , 'expected .' + prop + ' to not decrease'\n );\n }\n\n Assertion.addChainableMethod('decrease', assertDecreases);\n Assertion.addChainableMethod('decreases', assertDecreases);\n\n /**\n * ### .extensible\n *\n * Asserts that the target is extensible (can have new properties added to\n * it).\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect({}).to.be.extensible;\n * expect(nonExtensibleObject).to.not.be.extensible;\n * expect(sealedObject).to.not.be.extensible;\n * expect(frozenObject).to.not.be.extensible;\n *\n * @name extensible\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('extensible', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isExtensible;\n\n try {\n isExtensible = Object.isExtensible(obj);\n } catch (err) {\n if (err instanceof TypeError) isExtensible = false;\n else throw err;\n }\n\n this.assert(\n isExtensible\n , 'expected #{this} to be extensible'\n , 'expected #{this} to not be extensible'\n );\n });\n\n /**\n * ### .sealed\n *\n * Asserts that the target is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect(sealedObject).to.be.sealed;\n * expect(frozenObject).to.be.sealed;\n * expect({}).to.not.be.sealed;\n *\n * @name sealed\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('sealed', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isSealed;\n\n try {\n isSealed = Object.isSealed(obj);\n } catch (err) {\n if (err instanceof TypeError) isSealed = true;\n else throw err;\n }\n\n this.assert(\n isSealed\n , 'expected #{this} to be sealed'\n , 'expected #{this} to not be sealed'\n );\n });\n\n /**\n * ### .frozen\n *\n * Asserts that the target is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n *\n * expect(frozenObject).to.be.frozen;\n * expect({}).to.not.be.frozen;\n *\n * @name frozen\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('frozen', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isFrozen;\n\n try {\n isFrozen = Object.isFrozen(obj);\n } catch (err) {\n if (err instanceof TypeError) isFrozen = true;\n else throw err;\n }\n\n this.assert(\n isFrozen\n , 'expected #{this} to be frozen'\n , 'expected #{this} to not be frozen'\n );\n });\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n /*!\n * Chai dependencies.\n */\n\n var Assertion = chai.Assertion\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n /**\n * ### assert(expression, message)\n *\n * Write your own test expressions.\n *\n * assert('foo' !== 'bar', 'foo is not bar');\n * assert(Array.isArray([]), 'empty arrays are arrays');\n *\n * @param {Mixed} expression to test for truthiness\n * @param {String} message to display on error\n * @name assert\n * @namespace Assert\n * @api public\n */\n\n var assert = chai.assert = function (express, errmsg) {\n var test = new Assertion(null, null, chai.assert);\n test.assert(\n express\n , errmsg\n , '[ negation message unavailable ]'\n );\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure. Node.js `assert` module-compatible.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Assert\n * @api public\n */\n\n assert.fail = function (actual, expected, message, operator) {\n message = message || 'assert.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, assert.fail);\n };\n\n /**\n * ### .isOk(object, [message])\n *\n * Asserts that `object` is truthy.\n *\n * assert.isOk('everything', 'everything is ok');\n * assert.isOk(false, 'this will fail');\n *\n * @name isOk\n * @alias ok\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isOk = function (val, msg) {\n new Assertion(val, msg).is.ok;\n };\n\n /**\n * ### .isNotOk(object, [message])\n *\n * Asserts that `object` is falsy.\n *\n * assert.isNotOk('everything', 'this will fail');\n * assert.isNotOk(false, 'this will pass');\n *\n * @name isNotOk\n * @alias notOk\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotOk = function (val, msg) {\n new Assertion(val, msg).is.not.ok;\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * assert.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.equal = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.equal);\n\n test.assert(\n exp == flag(test, 'object')\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .notEqual(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * assert.notEqual(3, 4, 'these numbers are not equal');\n *\n * @name notEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notEqual = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.notEqual);\n\n test.assert(\n exp != flag(test, 'object')\n , 'expected #{this} to not equal #{exp}'\n , 'expected #{this} to equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .strictEqual(actual, expected, [message])\n *\n * Asserts strict equality (`===`) of `actual` and `expected`.\n *\n * assert.strictEqual(true, true, 'these booleans are strictly equal');\n *\n * @name strictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.strictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.equal(exp);\n };\n\n /**\n * ### .notStrictEqual(actual, expected, [message])\n *\n * Asserts strict inequality (`!==`) of `actual` and `expected`.\n *\n * assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n *\n * @name notStrictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notStrictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.equal(exp);\n };\n\n /**\n * ### .deepEqual(actual, expected, [message])\n *\n * Asserts that `actual` is deeply equal to `expected`.\n *\n * assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n *\n * @name deepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.eql(exp);\n };\n\n /**\n * ### .notDeepEqual(actual, expected, [message])\n *\n * Assert that `actual` is not deeply equal to `expected`.\n *\n * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n *\n * @name notDeepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.eql(exp);\n };\n\n /**\n * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n *\n * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n *\n * assert.isAbove(5, 2, '5 is strictly greater than 2');\n *\n * @name isAbove\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAbove\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAbove = function (val, abv, msg) {\n new Assertion(val, msg).to.be.above(abv);\n };\n\n /**\n * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n *\n * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n *\n * assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n * assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n *\n * @name isAtLeast\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtLeast\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtLeast = function (val, atlst, msg) {\n new Assertion(val, msg).to.be.least(atlst);\n };\n\n /**\n * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n *\n * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n *\n * assert.isBelow(3, 6, '3 is strictly less than 6');\n *\n * @name isBelow\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeBelow\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBelow = function (val, blw, msg) {\n new Assertion(val, msg).to.be.below(blw);\n };\n\n /**\n * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n *\n * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n *\n * assert.isAtMost(3, 6, '3 is less than or equal to 6');\n * assert.isAtMost(4, 4, '4 is less than or equal to 4');\n *\n * @name isAtMost\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtMost\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtMost = function (val, atmst, msg) {\n new Assertion(val, msg).to.be.most(atmst);\n };\n\n /**\n * ### .isTrue(value, [message])\n *\n * Asserts that `value` is true.\n *\n * var teaServed = true;\n * assert.isTrue(teaServed, 'the tea has been served');\n *\n * @name isTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isTrue = function (val, msg) {\n new Assertion(val, msg).is['true'];\n };\n\n /**\n * ### .isNotTrue(value, [message])\n *\n * Asserts that `value` is not true.\n *\n * var tea = 'tasty chai';\n * assert.isNotTrue(tea, 'great, time for tea!');\n *\n * @name isNotTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotTrue = function (val, msg) {\n new Assertion(val, msg).to.not.equal(true);\n };\n\n /**\n * ### .isFalse(value, [message])\n *\n * Asserts that `value` is false.\n *\n * var teaServed = false;\n * assert.isFalse(teaServed, 'no tea yet? hmm...');\n *\n * @name isFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFalse = function (val, msg) {\n new Assertion(val, msg).is['false'];\n };\n\n /**\n * ### .isNotFalse(value, [message])\n *\n * Asserts that `value` is not false.\n *\n * var tea = 'tasty chai';\n * assert.isNotFalse(tea, 'great, time for tea!');\n *\n * @name isNotFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFalse = function (val, msg) {\n new Assertion(val, msg).to.not.equal(false);\n };\n\n /**\n * ### .isNull(value, [message])\n *\n * Asserts that `value` is null.\n *\n * assert.isNull(err, 'there was no error');\n *\n * @name isNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNull = function (val, msg) {\n new Assertion(val, msg).to.equal(null);\n };\n\n /**\n * ### .isNotNull(value, [message])\n *\n * Asserts that `value` is not null.\n *\n * var tea = 'tasty chai';\n * assert.isNotNull(tea, 'great, time for tea!');\n *\n * @name isNotNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNull = function (val, msg) {\n new Assertion(val, msg).to.not.equal(null);\n };\n\n /**\n * ### .isNaN\n * Asserts that value is NaN\n *\n * assert.isNaN('foo', 'foo is NaN');\n *\n * @name isNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNaN = function (val, msg) {\n new Assertion(val, msg).to.be.NaN;\n };\n\n /**\n * ### .isNotNaN\n * Asserts that value is not NaN\n *\n * assert.isNotNaN(4, '4 is not NaN');\n *\n * @name isNotNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n assert.isNotNaN = function (val, msg) {\n new Assertion(val, msg).not.to.be.NaN;\n };\n\n /**\n * ### .isUndefined(value, [message])\n *\n * Asserts that `value` is `undefined`.\n *\n * var tea;\n * assert.isUndefined(tea, 'no tea defined');\n *\n * @name isUndefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isUndefined = function (val, msg) {\n new Assertion(val, msg).to.equal(undefined);\n };\n\n /**\n * ### .isDefined(value, [message])\n *\n * Asserts that `value` is not `undefined`.\n *\n * var tea = 'cup of chai';\n * assert.isDefined(tea, 'tea has been defined');\n *\n * @name isDefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isDefined = function (val, msg) {\n new Assertion(val, msg).to.not.equal(undefined);\n };\n\n /**\n * ### .isFunction(value, [message])\n *\n * Asserts that `value` is a function.\n *\n * function serveTea() { return 'cup of tea'; };\n * assert.isFunction(serveTea, 'great, we can have tea now');\n *\n * @name isFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFunction = function (val, msg) {\n new Assertion(val, msg).to.be.a('function');\n };\n\n /**\n * ### .isNotFunction(value, [message])\n *\n * Asserts that `value` is _not_ a function.\n *\n * var serveTea = [ 'heat', 'pour', 'sip' ];\n * assert.isNotFunction(serveTea, 'great, we have listed the steps');\n *\n * @name isNotFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFunction = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('function');\n };\n\n /**\n * ### .isObject(value, [message])\n *\n * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n * _The assertion does not match subclassed objects._\n *\n * var selection = { name: 'Chai', serve: 'with spices' };\n * assert.isObject(selection, 'tea selection is an object');\n *\n * @name isObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isObject = function (val, msg) {\n new Assertion(val, msg).to.be.a('object');\n };\n\n /**\n * ### .isNotObject(value, [message])\n *\n * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n *\n * var selection = 'chai'\n * assert.isNotObject(selection, 'tea selection is not an object');\n * assert.isNotObject(null, 'null is not an object');\n *\n * @name isNotObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotObject = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('object');\n };\n\n /**\n * ### .isArray(value, [message])\n *\n * Asserts that `value` is an array.\n *\n * var menu = [ 'green', 'chai', 'oolong' ];\n * assert.isArray(menu, 'what kind of tea do we want?');\n *\n * @name isArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isArray = function (val, msg) {\n new Assertion(val, msg).to.be.an('array');\n };\n\n /**\n * ### .isNotArray(value, [message])\n *\n * Asserts that `value` is _not_ an array.\n *\n * var menu = 'green|chai|oolong';\n * assert.isNotArray(menu, 'what kind of tea do we want?');\n *\n * @name isNotArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotArray = function (val, msg) {\n new Assertion(val, msg).to.not.be.an('array');\n };\n\n /**\n * ### .isString(value, [message])\n *\n * Asserts that `value` is a string.\n *\n * var teaOrder = 'chai';\n * assert.isString(teaOrder, 'order placed');\n *\n * @name isString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isString = function (val, msg) {\n new Assertion(val, msg).to.be.a('string');\n };\n\n /**\n * ### .isNotString(value, [message])\n *\n * Asserts that `value` is _not_ a string.\n *\n * var teaOrder = 4;\n * assert.isNotString(teaOrder, 'order placed');\n *\n * @name isNotString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotString = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('string');\n };\n\n /**\n * ### .isNumber(value, [message])\n *\n * Asserts that `value` is a number.\n *\n * var cups = 2;\n * assert.isNumber(cups, 'how many cups');\n *\n * @name isNumber\n * @param {Number} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNumber = function (val, msg) {\n new Assertion(val, msg).to.be.a('number');\n };\n\n /**\n * ### .isNotNumber(value, [message])\n *\n * Asserts that `value` is _not_ a number.\n *\n * var cups = '2 cups please';\n * assert.isNotNumber(cups, 'how many cups');\n *\n * @name isNotNumber\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNumber = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('number');\n };\n\n /**\n * ### .isBoolean(value, [message])\n *\n * Asserts that `value` is a boolean.\n *\n * var teaReady = true\n * , teaServed = false;\n *\n * assert.isBoolean(teaReady, 'is the tea ready');\n * assert.isBoolean(teaServed, 'has tea been served');\n *\n * @name isBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBoolean = function (val, msg) {\n new Assertion(val, msg).to.be.a('boolean');\n };\n\n /**\n * ### .isNotBoolean(value, [message])\n *\n * Asserts that `value` is _not_ a boolean.\n *\n * var teaReady = 'yep'\n * , teaServed = 'nope';\n *\n * assert.isNotBoolean(teaReady, 'is the tea ready');\n * assert.isNotBoolean(teaServed, 'has tea been served');\n *\n * @name isNotBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotBoolean = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('boolean');\n };\n\n /**\n * ### .typeOf(value, name, [message])\n *\n * Asserts that `value`'s type is `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n * assert.typeOf('tea', 'string', 'we have a string');\n * assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n * assert.typeOf(null, 'null', 'we have a null');\n * assert.typeOf(undefined, 'undefined', 'we have an undefined');\n *\n * @name typeOf\n * @param {Mixed} value\n * @param {String} name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.typeOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.a(type);\n };\n\n /**\n * ### .notTypeOf(value, name, [message])\n *\n * Asserts that `value`'s type is _not_ `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.notTypeOf('tea', 'number', 'strings are not numbers');\n *\n * @name notTypeOf\n * @param {Mixed} value\n * @param {String} typeof name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notTypeOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.a(type);\n };\n\n /**\n * ### .instanceOf(object, constructor, [message])\n *\n * Asserts that `value` is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new Tea('chai');\n *\n * assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n *\n * @name instanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.instanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.instanceOf(type);\n };\n\n /**\n * ### .notInstanceOf(object, constructor, [message])\n *\n * Asserts `value` is not an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new String('chai');\n *\n * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n *\n * @name notInstanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInstanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.instanceOf(type);\n };\n\n /**\n * ### .include(haystack, needle, [message])\n *\n * Asserts that `haystack` includes `needle`. Works\n * for strings and arrays.\n *\n * assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n * assert.include([ 1, 2, 3 ], 3, 'array contains value');\n *\n * @name include\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.include = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.include).include(inc);\n };\n\n /**\n * ### .notInclude(haystack, needle, [message])\n *\n * Asserts that `haystack` does not include `needle`. Works\n * for strings and arrays.\n *\n * assert.notInclude('foobar', 'baz', 'string not include substring');\n * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n *\n * @name notInclude\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInclude = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.notInclude).not.include(inc);\n };\n\n /**\n * ### .match(value, regexp, [message])\n *\n * Asserts that `value` matches the regular expression `regexp`.\n *\n * assert.match('foobar', /^foo/, 'regexp matches');\n *\n * @name match\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.match = function (exp, re, msg) {\n new Assertion(exp, msg).to.match(re);\n };\n\n /**\n * ### .notMatch(value, regexp, [message])\n *\n * Asserts that `value` does not match the regular expression `regexp`.\n *\n * assert.notMatch('foobar', /^foo/, 'regexp does not match');\n *\n * @name notMatch\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notMatch = function (exp, re, msg) {\n new Assertion(exp, msg).to.not.match(re);\n };\n\n /**\n * ### .property(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`.\n *\n * assert.property({ tea: { green: 'matcha' }}, 'tea');\n *\n * @name property\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.property = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.property(prop);\n };\n\n /**\n * ### .notProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`.\n *\n * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n *\n * @name notProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.property(prop);\n };\n\n /**\n * ### .deepProperty(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`, which can be a\n * string using dot- and bracket-notation for deep reference.\n *\n * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n *\n * @name deepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop);\n };\n\n /**\n * ### .notDeepProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`, which\n * can be a string using dot- and bracket-notation for deep reference.\n *\n * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n *\n * @name notDeepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop);\n };\n\n /**\n * ### .propertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`.\n *\n * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n *\n * @name propertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.property(prop, val);\n };\n\n /**\n * ### .propertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`.\n *\n * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n *\n * @name propertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.property(prop, val);\n };\n\n /**\n * ### .deepPropertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`. `property` can use dot- and bracket-notation for deep\n * reference.\n *\n * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n *\n * @name deepPropertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop, val);\n };\n\n /**\n * ### .deepPropertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`. `property` can use dot- and\n * bracket-notation for deep reference.\n *\n * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n *\n * @name deepPropertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n };\n\n /**\n * ### .lengthOf(object, length, [message])\n *\n * Asserts that `object` has a `length` property with the expected value.\n *\n * assert.lengthOf([1,2,3], 3, 'array has length of 3');\n * assert.lengthOf('foobar', 6, 'string has length of 6');\n *\n * @name lengthOf\n * @param {Mixed} object\n * @param {Number} length\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.lengthOf = function (exp, len, msg) {\n new Assertion(exp, msg).to.have.length(len);\n };\n\n /**\n * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * assert.throws(fn, 'function throws a reference error');\n * assert.throws(fn, /function throws a reference error/);\n * assert.throws(fn, ReferenceError);\n * assert.throws(fn, ReferenceError, 'function throws a reference error');\n * assert.throws(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throws\n * @alias throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.throws = function (fn, errt, errs, msg) {\n if ('string' === typeof errt || errt instanceof RegExp) {\n errs = errt;\n errt = null;\n }\n\n var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n return flag(assertErr, 'object');\n };\n\n /**\n * ### .doesNotThrow(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * assert.doesNotThrow(fn, Error, 'function does not throw');\n *\n * @name doesNotThrow\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotThrow = function (fn, type, msg) {\n if ('string' === typeof type) {\n msg = type;\n type = null;\n }\n\n new Assertion(fn, msg).to.not.Throw(type);\n };\n\n /**\n * ### .operator(val1, operator, val2, [message])\n *\n * Compares two values using `operator`.\n *\n * assert.operator(1, '<', 2, 'everything is ok');\n * assert.operator(1, '>', 2, 'this will fail');\n *\n * @name operator\n * @param {Mixed} val1\n * @param {String} operator\n * @param {Mixed} val2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.operator = function (val, operator, val2, msg) {\n var ok;\n switch(operator) {\n case '==':\n ok = val == val2;\n break;\n case '===':\n ok = val === val2;\n break;\n case '>':\n ok = val > val2;\n break;\n case '>=':\n ok = val >= val2;\n break;\n case '<':\n ok = val < val2;\n break;\n case '<=':\n ok = val <= val2;\n break;\n case '!=':\n ok = val != val2;\n break;\n case '!==':\n ok = val !== val2;\n break;\n default:\n throw new Error('Invalid operator \"' + operator + '\"');\n }\n var test = new Assertion(ok, msg);\n test.assert(\n true === flag(test, 'object')\n , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n };\n\n /**\n * ### .closeTo(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n *\n * @name closeTo\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.closeTo = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.closeTo(exp, delta);\n };\n\n /**\n * ### .approximately(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.approximately(1.5, 1, 0.5, 'numbers are close');\n *\n * @name approximately\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.approximately = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.approximately(exp, delta);\n };\n\n /**\n * ### .sameMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members.\n * Order is not taken into account.\n *\n * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n *\n * @name sameMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.members(set2);\n }\n\n /**\n * ### .sameDeepMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n * Order is not taken into account.\n *\n * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n *\n * @name sameDeepMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameDeepMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.deep.members(set2);\n }\n\n /**\n * ### .includeMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset`.\n * Order is not taken into account.\n *\n * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n *\n * @name includeMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.members(subset);\n }\n\n /**\n * ### .includeDeepMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset` - using deep equality checking.\n * Order is not taken into account.\n * Duplicates are ignored.\n *\n * assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n *\n * @name includeDeepMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeDeepMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.deep.members(subset);\n }\n\n /**\n * ### .oneOf(inList, list, [message])\n *\n * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n *\n * assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n *\n * @name oneOf\n * @param {*} inList\n * @param {Array<*>} list\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.oneOf = function (inList, list, msg) {\n new Assertion(inList, msg).to.be.oneOf(list);\n }\n\n /**\n * ### .changes(function, object, property)\n *\n * Asserts that a function changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 22 };\n * assert.changes(fn, obj, 'val');\n *\n * @name changes\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.changes = function (fn, obj, prop) {\n new Assertion(fn).to.change(obj, prop);\n }\n\n /**\n * ### .doesNotChange(function, object, property)\n *\n * Asserts that a function does not changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { console.log('foo'); };\n * assert.doesNotChange(fn, obj, 'val');\n *\n * @name doesNotChange\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotChange = function (fn, obj, prop) {\n new Assertion(fn).to.not.change(obj, prop);\n }\n\n /**\n * ### .increases(function, object, property)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 13 };\n * assert.increases(fn, obj, 'val');\n *\n * @name increases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.increases = function (fn, obj, prop) {\n new Assertion(fn).to.increase(obj, prop);\n }\n\n /**\n * ### .doesNotIncrease(function, object, property)\n *\n * Asserts that a function does not increase object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 8 };\n * assert.doesNotIncrease(fn, obj, 'val');\n *\n * @name doesNotIncrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotIncrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.increase(obj, prop);\n }\n\n /**\n * ### .decreases(function, object, property)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * assert.decreases(fn, obj, 'val');\n *\n * @name decreases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.decreases = function (fn, obj, prop) {\n new Assertion(fn).to.decrease(obj, prop);\n }\n\n /**\n * ### .doesNotDecrease(function, object, property)\n *\n * Asserts that a function does not decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * assert.doesNotDecrease(fn, obj, 'val');\n *\n * @name doesNotDecrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotDecrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.decrease(obj, prop);\n }\n\n /*!\n * ### .ifError(object)\n *\n * Asserts if value is not a false value, and throws if it is a true value.\n * This is added to allow for chai to be a drop-in replacement for Node's\n * assert class.\n *\n * var err = new Error('I am a custom error');\n * assert.ifError(err); // Rethrows err!\n *\n * @name ifError\n * @param {Object} object\n * @namespace Assert\n * @api public\n */\n\n assert.ifError = function (val) {\n if (val) {\n throw(val);\n }\n };\n\n /**\n * ### .isExtensible(object)\n *\n * Asserts that `object` is extensible (can have new properties added to it).\n *\n * assert.isExtensible({});\n *\n * @name isExtensible\n * @alias extensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.be.extensible;\n };\n\n /**\n * ### .isNotExtensible(object)\n *\n * Asserts that `object` is _not_ extensible.\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freese({});\n *\n * assert.isNotExtensible(nonExtensibleObject);\n * assert.isNotExtensible(sealedObject);\n * assert.isNotExtensible(frozenObject);\n *\n * @name isNotExtensible\n * @alias notExtensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.extensible;\n };\n\n /**\n * ### .isSealed(object)\n *\n * Asserts that `object` is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.seal({});\n *\n * assert.isSealed(sealedObject);\n * assert.isSealed(frozenObject);\n *\n * @name isSealed\n * @alias sealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isSealed = function (obj, msg) {\n new Assertion(obj, msg).to.be.sealed;\n };\n\n /**\n * ### .isNotSealed(object)\n *\n * Asserts that `object` is _not_ sealed.\n *\n * assert.isNotSealed({});\n *\n * @name isNotSealed\n * @alias notSealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotSealed = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.sealed;\n };\n\n /**\n * ### .isFrozen(object)\n *\n * Asserts that `object` is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n * assert.frozen(frozenObject);\n *\n * @name isFrozen\n * @alias frozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.be.frozen;\n };\n\n /**\n * ### .isNotFrozen(object)\n *\n * Asserts that `object` is _not_ frozen.\n *\n * assert.isNotFrozen({});\n *\n * @name isNotFrozen\n * @alias notFrozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.frozen;\n };\n\n /*!\n * Aliases.\n */\n\n (function alias(name, as){\n assert[as] = assert[name];\n return alias;\n })\n ('isOk', 'ok')\n ('isNotOk', 'notOk')\n ('throws', 'throw')\n ('throws', 'Throw')\n ('isExtensible', 'extensible')\n ('isNotExtensible', 'notExtensible')\n ('isSealed', 'sealed')\n ('isNotSealed', 'notSealed')\n ('isFrozen', 'frozen')\n ('isNotFrozen', 'notFrozen');\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n chai.expect = function (val, message) {\n return new chai.Assertion(val, message);\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Expect\n * @api public\n */\n\n chai.expect.fail = function (actual, expected, message, operator) {\n message = message || 'expect.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, chai.expect.fail);\n };\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n var Assertion = chai.Assertion;\n\n function loadShould () {\n // explicitly define this method as function as to have it's name to include as `ssfi`\n function shouldGetter() {\n if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n return new Assertion(this.valueOf(), null, shouldGetter);\n }\n return new Assertion(this, null, shouldGetter);\n }\n function shouldSetter(value) {\n // See https://github.com/chaijs/chai/issues/86: this makes\n // `whatever.should = someValue` actually set `someValue`, which is\n // especially useful for `global.should = require('chai').should()`.\n //\n // Note that we have to use [[DefineProperty]] instead of [[Put]]\n // since otherwise we would trigger this very setter!\n Object.defineProperty(this, 'should', {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n }\n // modify Object.prototype to have `should`\n Object.defineProperty(Object.prototype, 'should', {\n set: shouldSetter\n , get: shouldGetter\n , configurable: true\n });\n\n var should = {};\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Should\n * @api public\n */\n\n should.fail = function (actual, expected, message, operator) {\n message = message || 'should.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, should.fail);\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * should.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * should.throw(fn, 'function throws a reference error');\n * should.throw(fn, /function throws a reference error/);\n * should.throw(fn, ReferenceError);\n * should.throw(fn, ReferenceError, 'function throws a reference error');\n * should.throw(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.Throw(errt, errs);\n };\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi';\n *\n * should.exist(foo, 'foo exists');\n *\n * @name exist\n * @namespace Should\n * @api public\n */\n\n should.exist = function (val, msg) {\n new Assertion(val, msg).to.exist;\n }\n\n // negation\n should.not = {}\n\n /**\n * ### .not.equal(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * should.not.equal(3, 4, 'these numbers are not equal');\n *\n * @name not.equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.not.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.not.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * should.not.throw(fn, Error, 'function does not throw');\n *\n * @name not.throw\n * @alias not.Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.not.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.not.Throw(errt, errs);\n };\n\n /**\n * ### .not.exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var bar = null;\n *\n * should.not.exist(bar, 'bar does not exist');\n *\n * @name not.exist\n * @namespace Should\n * @api public\n */\n\n should.not.exist = function (val, msg) {\n new Assertion(val, msg).to.not.exist;\n }\n\n should['throw'] = should['Throw'];\n should.not['throw'] = should.not['Throw'];\n\n return should;\n };\n\n chai.should = loadShould;\n chai.Should = loadShould;\n};\n","/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call = Function.prototype.call,\n apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n * expect(fooStr).to.be.foo('bar');\n * expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n if (typeof chainingBehavior !== 'function') {\n chainingBehavior = function () { };\n }\n\n var chainableBehavior = {\n method: method\n , chainingBehavior: chainingBehavior\n };\n\n // save the methods so we can overwrite them later, if we need to.\n if (!ctx.__methods) {\n ctx.__methods = {};\n }\n ctx.__methods[name] = chainableBehavior;\n\n Object.defineProperty(ctx, name,\n { get: function () {\n chainableBehavior.chainingBehavior.call(this);\n\n var assert = function assert() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', assert);\n var result = chainableBehavior.method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n\n // Use `__proto__` if available\n if (hasProtoSupport) {\n // Inherit all properties from the object by replacing the `Function` prototype\n var prototype = assert.__proto__ = Object.create(this);\n // Restore the `call` and `apply` methods from `Function`\n prototype.call = call;\n prototype.apply = apply;\n }\n // Otherwise, redefine all properties (slow!)\n else {\n var asserterNames = Object.getOwnPropertyNames(ctx);\n asserterNames.forEach(function (asserterName) {\n if (!excludeNames.test(asserterName)) {\n var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n Object.defineProperty(assert, asserterName, pd);\n }\n });\n }\n\n transferFlags(this, assert);\n return assert;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n ctx[name] = function () {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', ctx[name]);\n var result = method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n * utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.instanceof(Foo);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n Object.defineProperty(ctx, name,\n { get: function addProperty() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', addProperty);\n\n var result = getter.call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n * utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n var obj = flag(obj, 'object');\n types = types.map(function (t) { return t.toLowerCase(); });\n types.sort();\n\n // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n var str = types.map(function (t, index) {\n var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n return or + art + ' ' + t;\n }).join(', ');\n\n if (!types.some(function (expected) { return type(obj) === expected; })) {\n throw new AssertionError(\n 'object tested must be ' + str + ', but ' + type(obj) + ' given'\n );\n }\n};\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n * utils.flag(this, 'foo', 'bar'); // setter\n * utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n var flags = obj.__flags || (obj.__flags = Object.create(null));\n if (arguments.length === 3) {\n flags[key] = value;\n } else {\n return flags[key];\n }\n};\n","/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n return args.length > 4 ? args[4] : obj._obj;\n};\n","/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n var result = [];\n for (var name in object) {\n result.push(name);\n }\n return result;\n};\n","/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n , getActual = require('./getActual')\n , inspect = require('./inspect')\n , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , val = flag(obj, 'object')\n , expected = args[3]\n , actual = getActual(obj, args)\n , msg = negate ? args[2] : args[1]\n , flagMsg = flag(obj, 'message');\n\n if(typeof msg === \"function\") msg = msg();\n msg = msg || '';\n msg = msg\n .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n","/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n if (func.name) return func.name;\n\n var match = /^\\s?function ([^(]*)\\(/.exec(func);\n return match && match[1] ? match[1] : \"\";\n};\n","/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n var parsed = parsePath(path),\n last = parsed[parsed.length - 1];\n\n var info = {\n parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n name: last.p || last.i,\n value: _getPathValue(parsed, obj)\n };\n info.exists = hasProperty(info.name, info.parent);\n\n return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n * var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n return parts.map(function (value) {\n var re = /^\\[(\\d+)\\]$/\n , mArr = re.exec(value);\n if (mArr) return { i: parseFloat(mArr[1]) };\n else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n * var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n var tmp = obj\n , res;\n\n index = (index === undefined ? parsed.length : index);\n\n for (var i = 0, l = index; i < l; i++) {\n var part = parsed[i];\n if (tmp) {\n if ('undefined' !== typeof part.p)\n tmp = tmp[part.p];\n else if ('undefined' !== typeof part.i)\n tmp = tmp[part.i];\n if (i == (l - 1)) res = tmp;\n } else {\n res = undefined;\n }\n }\n return res;\n}\n","/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer \n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n * var obj = {\n * prop1: {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n * , prop2: {\n * arr: [ { nested: 'Universe' } ]\n * , str: 'Hello again!'\n * }\n * }\n *\n * The following would be the results.\n *\n * getPathValue('prop1.str', obj); // Hello\n * getPathValue('prop1.att[2]', obj); // b\n * getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n var info = getPathInfo(path, obj);\n return info.value;\n};\n","/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n var result = Object.getOwnPropertyNames(object);\n\n function addProperty(property) {\n if (result.indexOf(property) === -1) {\n result.push(property);\n }\n }\n\n var proto = Object.getPrototypeOf(object);\n while (proto !== null) {\n Object.getOwnPropertyNames(proto).forEach(addProperty);\n proto = Object.getPrototypeOf(proto);\n }\n\n return result;\n};\n","/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n * var obj = {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n *\n * The following would be the results.\n *\n * hasProperty('str', obj); // true\n * hasProperty('constructor', obj); // true\n * hasProperty('bar', obj); // false\n *\n * hasProperty('length', obj.str); // true\n * hasProperty(1, obj.str); // true\n * hasProperty(5, obj.str); // false\n *\n * hasProperty('length', obj.arr); // true\n * hasProperty(2, obj.arr); // true\n * hasProperty(3, obj.arr); // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n 'number': Number\n , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n var ot = type(obj);\n\n // Bad Object, obviously no props at all\n if(ot === 'null' || ot === 'undefined')\n return false;\n\n // The `in` operator does not work with certain literals\n // box these before the check\n if(literals[ot] && typeof obj !== 'object')\n obj = new literals[ot](obj);\n\n return name in obj;\n};\n","/*!\n * chai\n * Copyright(c) 2011 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n","// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n * properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n * output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n var ctx = {\n showHidden: showHidden,\n seen: [],\n stylize: function (str) { return str; }\n };\n return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n if (typeof HTMLElement === 'object') {\n return object instanceof HTMLElement;\n } else {\n return object &&\n typeof object === 'object' &&\n object.nodeType === 1 &&\n typeof object.nodeName === 'string';\n }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (value && typeof value.inspect === 'function' &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes);\n if (typeof ret !== 'string') {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // If this is a DOM element, try to get the outer HTML.\n if (isDOMElement(value)) {\n if ('outerHTML' in value) {\n return value.outerHTML;\n // This value does not have an outerHTML attribute,\n // it could still be an XML element\n } else {\n // Attempt to serialize it\n try {\n if (document.xmlVersion) {\n var xmlSerializer = new XMLSerializer();\n return xmlSerializer.serializeToString(value);\n } else {\n // Firefox 11- do not support outerHTML\n // It does, however, support innerHTML\n // Use the following to render the element\n var ns = \"http://www.w3.org/1999/xhtml\";\n var container = document.createElementNS(ns, '_');\n\n container.appendChild(value.cloneNode(false));\n html = container.innerHTML\n .replace('><', '>' + value.innerHTML + '<');\n container.innerHTML = '';\n return html;\n }\n } catch (err) {\n // This could be a non-native DOM implementation,\n // continue with the normal flow:\n // printing the element as if it is an object.\n }\n }\n }\n\n // Look up the keys of the object.\n var visibleKeys = getEnumerableProperties(value);\n var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n // Some type of object without properties can be shortcutted.\n // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n // a `stack` plus `description` property; ignore those for consistency.\n if (keys.length === 0 || (isError(value) && (\n (keys.length === 1 && keys[0] === 'stack') ||\n (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n ))) {\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n base = ' [Function' + nameSuffix + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n return formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n switch (typeof value) {\n case 'undefined':\n return ctx.stylize('undefined', 'undefined');\n\n case 'string':\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n\n case 'number':\n if (value === 0 && (1/value) === -Infinity) {\n return ctx.stylize('-0', 'number');\n }\n return ctx.stylize('' + value, 'number');\n\n case 'boolean':\n return ctx.stylize('' + value, 'boolean');\n }\n // For some reason typeof null is \"object\", so special case here.\n if (value === null) {\n return ctx.stylize('null', 'null');\n }\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str;\n if (value.__lookupGetter__) {\n if (value.__lookupGetter__(key)) {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n }\n if (visibleKeys.indexOf(key) < 0) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(value[key]) < 0) {\n if (recurseTimes === null) {\n str = formatValue(ctx, value[key], null);\n } else {\n str = formatValue(ctx, value[key], recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (typeof name === 'undefined') {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n return Array.isArray(ar) ||\n (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n var str = inspect(obj)\n , type = Object.prototype.toString.call(obj);\n\n if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n if (type === '[object Function]') {\n return !obj.name || obj.name === ''\n ? '[Function]'\n : '[Function: ' + obj.name + ']';\n } else if (type === '[object Array]') {\n return '[ Array(' + obj.length + ') ]';\n } else if (type === '[object Object]') {\n var keys = Object.keys(obj)\n , kstr = keys.length > 2\n ? keys.splice(0, 2).join(', ') + ', ...'\n : keys.join(', ');\n return '{ Object (' + kstr + ') }';\n } else {\n return str;\n }\n } else {\n return str;\n }\n};\n","/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property. Must return functions to be used for\n * name.\n *\n * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n * function (_super) {\n * }\n * , function (_super) {\n * }\n * );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.have.length(3);\n * expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n var chainableBehavior = ctx.__methods[name];\n\n var _chainingBehavior = chainableBehavior.chainingBehavior;\n chainableBehavior.chainingBehavior = function () {\n var result = chainingBehavior(_chainingBehavior).call(this);\n return result === undefined ? this : result;\n };\n\n var _method = chainableBehavior.method;\n chainableBehavior.method = function () {\n var result = method(_method).apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n * return function (str) {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.value).to.equal(str);\n * } else {\n * _super.apply(this, arguments);\n * }\n * }\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n var _method = ctx[name]\n , _super = function () { return this; };\n\n if (_method && 'function' === typeof _method)\n _super = _method;\n\n ctx[name] = function () {\n var result = method(_super).apply(this, arguments);\n return result === undefined ? this : result;\n }\n};\n","/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n * return function () {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.name).to.equal('bar');\n * } else {\n * _super.call(this);\n * }\n * }\n * });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n var _get = Object.getOwnPropertyDescriptor(ctx, name)\n , _super = function () {};\n\n if (_get && 'function' === typeof _get.get)\n _super = _get.get\n\n Object.defineProperty(ctx, name,\n { get: function () {\n var result = getter(_super).call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , expr = args[0];\n return negate ? !expr : expr;\n};\n","/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n * var newAssertion = new Assertion();\n * utils.transferFlags(assertion, newAssertion);\n *\n * var anotherAsseriton = new Assertion(myObj);\n * utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n if (!object.__flags) {\n object.__flags = Object.create(null);\n }\n\n includeAll = arguments.length === 3 ? includeAll : true;\n\n for (var flag in flags) {\n if (includeAll ||\n (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n object.__flags[flag] = flags[flag];\n }\n }\n};\n","\"use strict\";\n\nfunction dedent(strings) {\n\n var raw = void 0;\n if (typeof strings === \"string\") {\n // dedent can be used as a plain function\n raw = [strings];\n } else {\n raw = strings.raw;\n }\n\n // first, perform interpolation\n var result = \"\";\n for (var i = 0; i < raw.length; i++) {\n result += raw[i].\n // join lines when there is a suppressed newline\n replace(/\\\\\\n[ \\t]*/g, \"\").\n\n // handle escaped backticks\n replace(/\\\\`/g, \"`\");\n\n if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) {\n result += arguments.length <= i + 1 ? undefined : arguments[i + 1];\n }\n }\n\n // now strip indentation\n var lines = result.split(\"\\n\");\n var mindent = null;\n lines.forEach(function (l) {\n var m = l.match(/^(\\s+)\\S+/);\n if (m) {\n var indent = m[1].length;\n if (!mindent) {\n // this is the first indented line\n mindent = indent;\n } else {\n mindent = Math.min(mindent, indent);\n }\n }\n });\n\n if (mindent !== null) {\n result = lines.map(function (l) {\n return l[0] === \" \" ? l.slice(mindent) : l;\n }).join(\"\\n\");\n }\n\n // dedent eats leading and trailing whitespace too\n result = result.trim();\n\n // handle escaped newlines at the end to ensure they don't get stripped too\n return result.replace(/\\\\n/g, \"\\n\");\n}\n\nif (typeof module !== \"undefined\") {\n module.exports = dedent;\n}\n","module.exports = require('./lib/eql');\n","/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n Buffer = {};\n Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n if (sameValue(a, b)) {\n return true;\n } else if ('date' === type(a)) {\n return dateEqual(a, b);\n } else if ('regexp' === type(a)) {\n return regexpEqual(a, b);\n } else if (Buffer.isBuffer(a)) {\n return bufferEqual(a, b);\n } else if ('arguments' === type(a)) {\n return argumentsEqual(a, b, m);\n } else if (!typeEqual(a, b)) {\n return false;\n } else if (('object' !== type(a) && 'object' !== type(b))\n && ('array' !== type(a) && 'array' !== type(b))) {\n return sameValue(a, b);\n } else {\n return objectEqual(a, b, m);\n }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n if (a === b) return a !== 0 || 1 / a === 1 / b;\n return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n if ('date' !== type(b)) return false;\n return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n if ('regexp' !== type(b)) return false;\n return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n if ('arguments' !== type(b)) return false;\n a = [].slice.call(a);\n b = [].slice.call(b);\n return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n var res = [];\n for (var key in a) res.push(key);\n return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n if (a.length !== b.length) return false;\n\n var i = 0;\n var match = true;\n\n for (; i < a.length; i++) {\n if (a[i] !== b[i]) {\n match = false;\n break;\n }\n }\n\n return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n if (!Buffer.isBuffer(b)) return false;\n return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n if (!isValue(a) || !isValue(b)) {\n return false;\n }\n\n if (a.prototype !== b.prototype) {\n return false;\n }\n\n var i;\n if (m) {\n for (i = 0; i < m.length; i++) {\n if ((m[i][0] === a && m[i][1] === b)\n || (m[i][0] === b && m[i][1] === a)) {\n return true;\n }\n }\n } else {\n m = [];\n }\n\n try {\n var ka = enumerable(a);\n var kb = enumerable(b);\n } catch (ex) {\n return false;\n }\n\n ka.sort();\n kb.sort();\n\n if (!iterableEqual(ka, kb)) {\n return false;\n }\n\n m.push([ a, b ]);\n\n var key;\n for (i = ka.length - 1; i >= 0; i--) {\n key = ka[i];\n if (!deepEqual(a[key], b[key], m)) {\n return false;\n }\n }\n\n return true;\n}\n","/*!\n localForage -- Offline Storage, Improved\n Version 1.5.0\n https://localforage.github.io/localForage\n (c) 2013-2017 Mozilla, Apache License 2.0\n*/\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.localforage = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw (f.code=\"MODULE_NOT_FOUND\", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o element; its readystatechange event will be fired asynchronously once it is inserted\n // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.\n var scriptEl = global.document.createElement('script');\n scriptEl.onreadystatechange = function () {\n nextTick();\n\n scriptEl.onreadystatechange = null;\n scriptEl.parentNode.removeChild(scriptEl);\n scriptEl = null;\n };\n global.document.documentElement.appendChild(scriptEl);\n };\n } else {\n scheduleDrain = function () {\n setTimeout(nextTick, 0);\n };\n }\n}\n\nvar draining;\nvar queue = [];\n//named nextTick for less confusing stack traces\nfunction nextTick() {\n draining = true;\n var i, oldQueue;\n var len = queue.length;\n while (len) {\n oldQueue = queue;\n queue = [];\n i = -1;\n while (++i < len) {\n oldQueue[i]();\n }\n len = queue.length;\n }\n draining = false;\n}\n\nmodule.exports = immediate;\nfunction immediate(task) {\n if (queue.push(task) === 1 && !draining) {\n scheduleDrain();\n }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],2:[function(_dereq_,module,exports){\n'use strict';\nvar immediate = _dereq_(1);\n\n/* istanbul ignore next */\nfunction INTERNAL() {}\n\nvar handlers = {};\n\nvar REJECTED = ['REJECTED'];\nvar FULFILLED = ['FULFILLED'];\nvar PENDING = ['PENDING'];\n\nmodule.exports = exports = Promise;\n\nfunction Promise(resolver) {\n if (typeof resolver !== 'function') {\n throw new TypeError('resolver must be a function');\n }\n this.state = PENDING;\n this.queue = [];\n this.outcome = void 0;\n if (resolver !== INTERNAL) {\n safelyResolveThenable(this, resolver);\n }\n}\n\nPromise.prototype[\"catch\"] = function (onRejected) {\n return this.then(null, onRejected);\n};\nPromise.prototype.then = function (onFulfilled, onRejected) {\n if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||\n typeof onRejected !== 'function' && this.state === REJECTED) {\n return this;\n }\n var promise = new this.constructor(INTERNAL);\n if (this.state !== PENDING) {\n var resolver = this.state === FULFILLED ? onFulfilled : onRejected;\n unwrap(promise, resolver, this.outcome);\n } else {\n this.queue.push(new QueueItem(promise, onFulfilled, onRejected));\n }\n\n return promise;\n};\nfunction QueueItem(promise, onFulfilled, onRejected) {\n this.promise = promise;\n if (typeof onFulfilled === 'function') {\n this.onFulfilled = onFulfilled;\n this.callFulfilled = this.otherCallFulfilled;\n }\n if (typeof onRejected === 'function') {\n this.onRejected = onRejected;\n this.callRejected = this.otherCallRejected;\n }\n}\nQueueItem.prototype.callFulfilled = function (value) {\n handlers.resolve(this.promise, value);\n};\nQueueItem.prototype.otherCallFulfilled = function (value) {\n unwrap(this.promise, this.onFulfilled, value);\n};\nQueueItem.prototype.callRejected = function (value) {\n handlers.reject(this.promise, value);\n};\nQueueItem.prototype.otherCallRejected = function (value) {\n unwrap(this.promise, this.onRejected, value);\n};\n\nfunction unwrap(promise, func, value) {\n immediate(function () {\n var returnValue;\n try {\n returnValue = func(value);\n } catch (e) {\n return handlers.reject(promise, e);\n }\n if (returnValue === promise) {\n handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));\n } else {\n handlers.resolve(promise, returnValue);\n }\n });\n}\n\nhandlers.resolve = function (self, value) {\n var result = tryCatch(getThen, value);\n if (result.status === 'error') {\n return handlers.reject(self, result.value);\n }\n var thenable = result.value;\n\n if (thenable) {\n safelyResolveThenable(self, thenable);\n } else {\n self.state = FULFILLED;\n self.outcome = value;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callFulfilled(value);\n }\n }\n return self;\n};\nhandlers.reject = function (self, error) {\n self.state = REJECTED;\n self.outcome = error;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callRejected(error);\n }\n return self;\n};\n\nfunction getThen(obj) {\n // Make sure we only access the accessor once as required by the spec\n var then = obj && obj.then;\n if (obj && typeof obj === 'object' && typeof then === 'function') {\n return function appyThen() {\n then.apply(obj, arguments);\n };\n }\n}\n\nfunction safelyResolveThenable(self, thenable) {\n // Either fulfill, reject or reject with error\n var called = false;\n function onError(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.reject(self, value);\n }\n\n function onSuccess(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.resolve(self, value);\n }\n\n function tryToUnwrap() {\n thenable(onSuccess, onError);\n }\n\n var result = tryCatch(tryToUnwrap);\n if (result.status === 'error') {\n onError(result.value);\n }\n}\n\nfunction tryCatch(func, value) {\n var out = {};\n try {\n out.value = func(value);\n out.status = 'success';\n } catch (e) {\n out.status = 'error';\n out.value = e;\n }\n return out;\n}\n\nexports.resolve = resolve;\nfunction resolve(value) {\n if (value instanceof this) {\n return value;\n }\n return handlers.resolve(new this(INTERNAL), value);\n}\n\nexports.reject = reject;\nfunction reject(reason) {\n var promise = new this(INTERNAL);\n return handlers.reject(promise, reason);\n}\n\nexports.all = all;\nfunction all(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var values = new Array(len);\n var resolved = 0;\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n allResolver(iterable[i], i);\n }\n return promise;\n function allResolver(value, i) {\n self.resolve(value).then(resolveFromAll, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n function resolveFromAll(outValue) {\n values[i] = outValue;\n if (++resolved === len && !called) {\n called = true;\n handlers.resolve(promise, values);\n }\n }\n }\n}\n\nexports.race = race;\nfunction race(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n resolver(iterable[i]);\n }\n return promise;\n function resolver(value) {\n self.resolve(value).then(function (response) {\n if (!called) {\n called = true;\n handlers.resolve(promise, response);\n }\n }, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n }\n}\n\n},{\"1\":1}],3:[function(_dereq_,module,exports){\n(function (global){\n'use strict';\nif (typeof global.Promise !== 'function') {\n global.Promise = _dereq_(2);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"2\":2}],4:[function(_dereq_,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction getIDB() {\n /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */\n try {\n if (typeof indexedDB !== 'undefined') {\n return indexedDB;\n }\n if (typeof webkitIndexedDB !== 'undefined') {\n return webkitIndexedDB;\n }\n if (typeof mozIndexedDB !== 'undefined') {\n return mozIndexedDB;\n }\n if (typeof OIndexedDB !== 'undefined') {\n return OIndexedDB;\n }\n if (typeof msIndexedDB !== 'undefined') {\n return msIndexedDB;\n }\n } catch (e) {}\n}\n\nvar idb = getIDB();\n\nfunction isIndexedDBValid() {\n try {\n // Initialize IndexedDB; fall back to vendor-prefixed versions\n // if needed.\n if (!idb) {\n return false;\n }\n // We mimic PouchDB here;\n //\n // We test for openDatabase because IE Mobile identifies itself\n // as Safari. Oh the lulz...\n var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform);\n\n var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1;\n\n // Safari <10.1 does not meet our requirements for IDB support (#5572)\n // since Safari 10.1 shipped with fetch, we can use that to detect it\n return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' &&\n // some outdated implementations of IDB that appear on Samsung\n // and HTC Android devices <4.4 are missing IDBKeyRange\n typeof IDBKeyRange !== 'undefined';\n } catch (e) {\n return false;\n }\n}\n\nfunction isWebSQLValid() {\n return typeof openDatabase === 'function';\n}\n\nfunction isLocalStorageValid() {\n try {\n return typeof localStorage !== 'undefined' && 'setItem' in localStorage && localStorage.setItem;\n } catch (e) {\n return false;\n }\n}\n\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\nfunction createBlob(parts, properties) {\n /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */\n parts = parts || [];\n properties = properties || {};\n try {\n return new Blob(parts, properties);\n } catch (e) {\n if (e.name !== 'TypeError') {\n throw e;\n }\n var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder;\n var builder = new Builder();\n for (var i = 0; i < parts.length; i += 1) {\n builder.append(parts[i]);\n }\n return builder.getBlob(properties.type);\n }\n}\n\n// This is CommonJS because lie is an external dependency, so Rollup\n// can just ignore it.\nif (typeof Promise === 'undefined') {\n // In the \"nopromises\" build this will just throw if you don't have\n // a global promise object, but it would throw anyway later.\n _dereq_(3);\n}\nvar Promise$1 = Promise;\n\nfunction executeCallback(promise, callback) {\n if (callback) {\n promise.then(function (result) {\n callback(null, result);\n }, function (error) {\n callback(error);\n });\n }\n}\n\nfunction executeTwoCallbacks(promise, callback, errorCallback) {\n if (typeof callback === 'function') {\n promise.then(callback);\n }\n\n if (typeof errorCallback === 'function') {\n promise[\"catch\"](errorCallback);\n }\n}\n\n// Some code originally from async_storage.js in\n// [Gaia](https://github.com/mozilla-b2g/gaia).\n\nvar DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support';\nvar supportsBlobs;\nvar dbContexts;\nvar toString = Object.prototype.toString;\n\n// Transform a binary string to an array buffer, because otherwise\n// weird stuff happens when you try to work with the binary string directly.\n// It is known.\n// From http://stackoverflow.com/questions/14967647/ (continues on next line)\n// encode-decode-image-with-base64-breaks-image (2013-04-21)\nfunction _binStringToArrayBuffer(bin) {\n var length = bin.length;\n var buf = new ArrayBuffer(length);\n var arr = new Uint8Array(buf);\n for (var i = 0; i < length; i++) {\n arr[i] = bin.charCodeAt(i);\n }\n return buf;\n}\n\n//\n// Blobs are not supported in all versions of IndexedDB, notably\n// Chrome <37 and Android <5. In those versions, storing a blob will throw.\n//\n// Various other blob bugs exist in Chrome v37-42 (inclusive).\n// Detecting them is expensive and confusing to users, and Chrome 37-42\n// is at very low usage worldwide, so we do a hacky userAgent check instead.\n//\n// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120\n// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916\n// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836\n//\n// Code borrowed from PouchDB. See:\n// https://github.com/pouchdb/pouchdb/blob/master/packages/node_modules/pouchdb-adapter-idb/src/blobSupport.js\n//\nfunction _checkBlobSupportWithoutCaching(idb) {\n return new Promise$1(function (resolve) {\n var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, 'readwrite');\n var blob = createBlob(['']);\n txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');\n\n txn.onabort = function (e) {\n // If the transaction aborts now its due to not being able to\n // write to the database, likely due to the disk being full\n e.preventDefault();\n e.stopPropagation();\n resolve(false);\n };\n\n txn.oncomplete = function () {\n var matchedChrome = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n var matchedEdge = navigator.userAgent.match(/Edge\\//);\n // MS Edge pretends to be Chrome 42:\n // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx\n resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43);\n };\n })[\"catch\"](function () {\n return false; // error, so assume unsupported\n });\n}\n\nfunction _checkBlobSupport(idb) {\n if (typeof supportsBlobs === 'boolean') {\n return Promise$1.resolve(supportsBlobs);\n }\n return _checkBlobSupportWithoutCaching(idb).then(function (value) {\n supportsBlobs = value;\n return supportsBlobs;\n });\n}\n\nfunction _deferReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Create a deferred object representing the current database operation.\n var deferredOperation = {};\n\n deferredOperation.promise = new Promise$1(function (resolve) {\n deferredOperation.resolve = resolve;\n });\n\n // Enqueue the deferred operation.\n dbContext.deferredOperations.push(deferredOperation);\n\n // Chain its promise to the database readiness.\n if (!dbContext.dbReady) {\n dbContext.dbReady = deferredOperation.promise;\n } else {\n dbContext.dbReady = dbContext.dbReady.then(function () {\n return deferredOperation.promise;\n });\n }\n}\n\nfunction _advanceReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Dequeue a deferred operation.\n var deferredOperation = dbContext.deferredOperations.pop();\n\n // Resolve its promise (which is part of the database readiness\n // chain of promises).\n if (deferredOperation) {\n deferredOperation.resolve();\n }\n}\n\nfunction _getConnection(dbInfo, upgradeNeeded) {\n return new Promise$1(function (resolve, reject) {\n\n if (dbInfo.db) {\n if (upgradeNeeded) {\n _deferReadiness(dbInfo);\n dbInfo.db.close();\n } else {\n return resolve(dbInfo.db);\n }\n }\n\n var dbArgs = [dbInfo.name];\n\n if (upgradeNeeded) {\n dbArgs.push(dbInfo.version);\n }\n\n var openreq = idb.open.apply(idb, dbArgs);\n\n if (upgradeNeeded) {\n openreq.onupgradeneeded = function (e) {\n var db = openreq.result;\n try {\n db.createObjectStore(dbInfo.storeName);\n if (e.oldVersion <= 1) {\n // Added when support for blob shims was added\n db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);\n }\n } catch (ex) {\n if (ex.name === 'ConstraintError') {\n console.warn('The database \"' + dbInfo.name + '\"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage \"' + dbInfo.storeName + '\" already exists.');\n } else {\n throw ex;\n }\n }\n };\n }\n\n openreq.onerror = function (e) {\n e.preventDefault();\n reject(openreq.error);\n };\n\n openreq.onsuccess = function () {\n resolve(openreq.result);\n _advanceReadiness(dbInfo);\n };\n });\n}\n\nfunction _getOriginalConnection(dbInfo) {\n return _getConnection(dbInfo, false);\n}\n\nfunction _getUpgradedConnection(dbInfo) {\n return _getConnection(dbInfo, true);\n}\n\nfunction _isUpgradeNeeded(dbInfo, defaultVersion) {\n if (!dbInfo.db) {\n return true;\n }\n\n var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName);\n var isDowngrade = dbInfo.version < dbInfo.db.version;\n var isUpgrade = dbInfo.version > dbInfo.db.version;\n\n if (isDowngrade) {\n // If the version is not the default one\n // then warn for impossible downgrade.\n if (dbInfo.version !== defaultVersion) {\n console.warn('The database \"' + dbInfo.name + '\"' + ' can\\'t be downgraded from version ' + dbInfo.db.version + ' to version ' + dbInfo.version + '.');\n }\n // Align the versions to prevent errors.\n dbInfo.version = dbInfo.db.version;\n }\n\n if (isUpgrade || isNewStore) {\n // If the store is new then increment the version (if needed).\n // This will trigger an \"upgradeneeded\" event which is required\n // for creating a store.\n if (isNewStore) {\n var incVersion = dbInfo.db.version + 1;\n if (incVersion > dbInfo.version) {\n dbInfo.version = incVersion;\n }\n }\n\n return true;\n }\n\n return false;\n}\n\n// encode a blob for indexeddb engines that don't support blobs\nfunction _encodeBlob(blob) {\n return new Promise$1(function (resolve, reject) {\n var reader = new FileReader();\n reader.onerror = reject;\n reader.onloadend = function (e) {\n var base64 = btoa(e.target.result || '');\n resolve({\n __local_forage_encoded_blob: true,\n data: base64,\n type: blob.type\n });\n };\n reader.readAsBinaryString(blob);\n });\n}\n\n// decode an encoded blob\nfunction _decodeBlob(encodedBlob) {\n var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data));\n return createBlob([arrayBuff], { type: encodedBlob.type });\n}\n\n// is this one of our fancy encoded blobs?\nfunction _isEncodedBlob(value) {\n return value && value.__local_forage_encoded_blob;\n}\n\n// Specialize the default `ready()` function by making it dependent\n// on the current database operations. Thus, the driver will be actually\n// ready when it's been initialized (default) *and* there are no pending\n// operations on the database (initiated by some other instances).\nfunction _fullyReady(callback) {\n var self = this;\n\n var promise = self._initReady().then(function () {\n var dbContext = dbContexts[self._dbInfo.name];\n\n if (dbContext && dbContext.dbReady) {\n return dbContext.dbReady;\n }\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n}\n\n// Open the IndexedDB database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n // Initialize a singleton container for all running localForages.\n if (!dbContexts) {\n dbContexts = {};\n }\n\n // Get the current context of the database;\n var dbContext = dbContexts[dbInfo.name];\n\n // ...or create a new context.\n if (!dbContext) {\n dbContext = {\n // Running localForages sharing a database.\n forages: [],\n // Shared database.\n db: null,\n // Database readiness (promise).\n dbReady: null,\n // Deferred operations on the database.\n deferredOperations: []\n };\n // Register the new context in the global container.\n dbContexts[dbInfo.name] = dbContext;\n }\n\n // Register itself as a running localForage in the current context.\n dbContext.forages.push(self);\n\n // Replace the default `ready()` function with the specialized one.\n if (!self._initReady) {\n self._initReady = self.ready;\n self.ready = _fullyReady;\n }\n\n // Create an array of initialization states of the related localForages.\n var initPromises = [];\n\n function ignoreErrors() {\n // Don't handle errors here,\n // just makes sure related localForages aren't pending.\n return Promise$1.resolve();\n }\n\n for (var j = 0; j < dbContext.forages.length; j++) {\n var forage = dbContext.forages[j];\n if (forage !== self) {\n // Don't wait for itself...\n initPromises.push(forage._initReady()[\"catch\"](ignoreErrors));\n }\n }\n\n // Take a snapshot of the related localForages.\n var forages = dbContext.forages.slice(0);\n\n // Initialize the connection process only when\n // all the related localForages aren't pending.\n return Promise$1.all(initPromises).then(function () {\n dbInfo.db = dbContext.db;\n // Get the connection or open a new one without upgrade.\n return _getOriginalConnection(dbInfo);\n }).then(function (db) {\n dbInfo.db = db;\n if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) {\n // Reopen the database for upgrading.\n return _getUpgradedConnection(dbInfo);\n }\n return db;\n }).then(function (db) {\n dbInfo.db = dbContext.db = db;\n self._dbInfo = dbInfo;\n // Share the final connection amongst related localForages.\n for (var k = 0; k < forages.length; k++) {\n var forage = forages[k];\n if (forage !== self) {\n // Self is already up-to-date.\n forage._dbInfo.db = dbInfo.db;\n forage._dbInfo.version = dbInfo.version;\n }\n }\n });\n}\n\nfunction getItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.get(key);\n\n req.onsuccess = function () {\n var value = req.result;\n if (value === undefined) {\n value = null;\n }\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n resolve(value);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items stored in database.\nfunction iterate(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var iterationNumber = 1;\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (cursor) {\n var value = cursor.value;\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n var result = iterator(value, cursor.key, iterationNumber++);\n\n if (result !== void 0) {\n resolve(result);\n } else {\n cursor[\"continue\"]();\n }\n } else {\n resolve();\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n\n return promise;\n}\n\nfunction setItem(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n var dbInfo;\n self.ready().then(function () {\n dbInfo = self._dbInfo;\n if (toString.call(value) === '[object Blob]') {\n return _checkBlobSupport(dbInfo.db).then(function (blobSupport) {\n if (blobSupport) {\n return value;\n }\n return _encodeBlob(value);\n });\n }\n return value;\n }).then(function (value) {\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.put(value, key);\n\n // The reason we don't _save_ null is because IE 10 does\n // not support saving the `null` type in IndexedDB. How\n // ironic, given the bug below!\n // See: https://github.com/mozilla/localForage/issues/161\n if (value === null) {\n value = undefined;\n }\n\n transaction.oncomplete = function () {\n // Cast to undefined so the value passed to\n // callback/promise is the same as what one would get out\n // of `getItem()` later. This leads to some weirdness\n // (setItem('foo', undefined) will return `null`), but\n // it's not my fault localStorage is our baseline and that\n // it's weird.\n if (value === undefined) {\n value = null;\n }\n\n resolve(value);\n };\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction removeItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n\n // We use a Grunt task to make this safe for IE and some\n // versions of Android (including those used by Cordova).\n // Normally IE won't like `.delete()` and will insist on\n // using `['delete']()`, but we have a build step that\n // fixes this for us now.\n var req = store[\"delete\"](key);\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onerror = function () {\n reject(req.error);\n };\n\n // The request will be also be aborted if we've exceeded our storage\n // space.\n transaction.onabort = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction clear(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.clear();\n\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction length(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.count();\n\n req.onsuccess = function () {\n resolve(req.result);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction key(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n if (n < 0) {\n resolve(null);\n\n return;\n }\n\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var advanced = false;\n var req = store.openCursor();\n req.onsuccess = function () {\n var cursor = req.result;\n if (!cursor) {\n // this means there weren't enough keys\n resolve(null);\n\n return;\n }\n\n if (n === 0) {\n // We have the first key, return it if that's what they\n // wanted.\n resolve(cursor.key);\n } else {\n if (!advanced) {\n // Otherwise, ask the cursor to skip ahead n\n // records.\n advanced = true;\n cursor.advance(n);\n } else {\n // When we get here, we've got the nth key.\n resolve(cursor.key);\n }\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var keys = [];\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (!cursor) {\n resolve(keys);\n return;\n }\n\n keys.push(cursor.key);\n cursor[\"continue\"]();\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar asyncStorage = {\n _driver: 'asyncStorage',\n _initStorage: _initStorage,\n iterate: iterate,\n getItem: getItem,\n setItem: setItem,\n removeItem: removeItem,\n clear: clear,\n length: length,\n key: key,\n keys: keys\n};\n\n// Sadly, the best way to save binary data in WebSQL/localStorage is serializing\n// it to Base64, so this is how we store it to prevent very strange errors with less\n// verbose ways of binary <-> string data storage.\nvar BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\nvar BLOB_TYPE_PREFIX = '~~local_forage_type~';\nvar BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;\n\nvar SERIALIZED_MARKER = '__lfsc__:';\nvar SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;\n\n// OMG the serializations!\nvar TYPE_ARRAYBUFFER = 'arbf';\nvar TYPE_BLOB = 'blob';\nvar TYPE_INT8ARRAY = 'si08';\nvar TYPE_UINT8ARRAY = 'ui08';\nvar TYPE_UINT8CLAMPEDARRAY = 'uic8';\nvar TYPE_INT16ARRAY = 'si16';\nvar TYPE_INT32ARRAY = 'si32';\nvar TYPE_UINT16ARRAY = 'ur16';\nvar TYPE_UINT32ARRAY = 'ui32';\nvar TYPE_FLOAT32ARRAY = 'fl32';\nvar TYPE_FLOAT64ARRAY = 'fl64';\nvar TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;\n\nvar toString$1 = Object.prototype.toString;\n\nfunction stringToBuffer(serializedString) {\n // Fill the string into a ArrayBuffer.\n var bufferLength = serializedString.length * 0.75;\n var len = serializedString.length;\n var i;\n var p = 0;\n var encoded1, encoded2, encoded3, encoded4;\n\n if (serializedString[serializedString.length - 1] === '=') {\n bufferLength--;\n if (serializedString[serializedString.length - 2] === '=') {\n bufferLength--;\n }\n }\n\n var buffer = new ArrayBuffer(bufferLength);\n var bytes = new Uint8Array(buffer);\n\n for (i = 0; i < len; i += 4) {\n encoded1 = BASE_CHARS.indexOf(serializedString[i]);\n encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);\n encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);\n encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);\n\n /*jslint bitwise: true */\n bytes[p++] = encoded1 << 2 | encoded2 >> 4;\n bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;\n bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;\n }\n return buffer;\n}\n\n// Converts a buffer to a string to store, serialized, in the backend\n// storage library.\nfunction bufferToString(buffer) {\n // base64-arraybuffer\n var bytes = new Uint8Array(buffer);\n var base64String = '';\n var i;\n\n for (i = 0; i < bytes.length; i += 3) {\n /*jslint bitwise: true */\n base64String += BASE_CHARS[bytes[i] >> 2];\n base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];\n base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];\n base64String += BASE_CHARS[bytes[i + 2] & 63];\n }\n\n if (bytes.length % 3 === 2) {\n base64String = base64String.substring(0, base64String.length - 1) + '=';\n } else if (bytes.length % 3 === 1) {\n base64String = base64String.substring(0, base64String.length - 2) + '==';\n }\n\n return base64String;\n}\n\n// Serialize a value, afterwards executing a callback (which usually\n// instructs the `setItem()` callback/promise to be executed). This is how\n// we store binary data with localStorage.\nfunction serialize(value, callback) {\n var valueType = '';\n if (value) {\n valueType = toString$1.call(value);\n }\n\n // Cannot use `value instanceof ArrayBuffer` or such here, as these\n // checks fail when running the tests using casper.js...\n //\n // TODO: See why those tests fail and use a better solution.\n if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) {\n // Convert binary arrays to a string and prefix the string with\n // a special marker.\n var buffer;\n var marker = SERIALIZED_MARKER;\n\n if (value instanceof ArrayBuffer) {\n buffer = value;\n marker += TYPE_ARRAYBUFFER;\n } else {\n buffer = value.buffer;\n\n if (valueType === '[object Int8Array]') {\n marker += TYPE_INT8ARRAY;\n } else if (valueType === '[object Uint8Array]') {\n marker += TYPE_UINT8ARRAY;\n } else if (valueType === '[object Uint8ClampedArray]') {\n marker += TYPE_UINT8CLAMPEDARRAY;\n } else if (valueType === '[object Int16Array]') {\n marker += TYPE_INT16ARRAY;\n } else if (valueType === '[object Uint16Array]') {\n marker += TYPE_UINT16ARRAY;\n } else if (valueType === '[object Int32Array]') {\n marker += TYPE_INT32ARRAY;\n } else if (valueType === '[object Uint32Array]') {\n marker += TYPE_UINT32ARRAY;\n } else if (valueType === '[object Float32Array]') {\n marker += TYPE_FLOAT32ARRAY;\n } else if (valueType === '[object Float64Array]') {\n marker += TYPE_FLOAT64ARRAY;\n } else {\n callback(new Error('Failed to get type for BinaryArray'));\n }\n }\n\n callback(marker + bufferToString(buffer));\n } else if (valueType === '[object Blob]') {\n // Conver the blob to a binaryArray and then to a string.\n var fileReader = new FileReader();\n\n fileReader.onload = function () {\n // Backwards-compatible prefix for the blob type.\n var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result);\n\n callback(SERIALIZED_MARKER + TYPE_BLOB + str);\n };\n\n fileReader.readAsArrayBuffer(value);\n } else {\n try {\n callback(JSON.stringify(value));\n } catch (e) {\n console.error(\"Couldn't convert value into a JSON string: \", value);\n\n callback(null, e);\n }\n }\n}\n\n// Deserialize data we've inserted into a value column/field. We place\n// special markers into our strings to mark them as encoded; this isn't\n// as nice as a meta field, but it's the only sane thing we can do whilst\n// keeping localStorage support intact.\n//\n// Oftentimes this will just deserialize JSON content, but if we have a\n// special marker (SERIALIZED_MARKER, defined above), we will extract\n// some kind of arraybuffer/binary data/typed array out of the string.\nfunction deserialize(value) {\n // If we haven't marked this string as being specially serialized (i.e.\n // something other than serialized JSON), we can just return it and be\n // done with it.\n if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {\n return JSON.parse(value);\n }\n\n // The following code deals with deserializing some kind of Blob or\n // TypedArray. First we separate out the type of data we're dealing\n // with from the data itself.\n var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);\n var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH);\n\n var blobType;\n // Backwards-compatible blob type serialization strategy.\n // DBs created with older versions of localForage will simply not have the blob type.\n if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {\n var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);\n blobType = matcher[1];\n serializedString = serializedString.substring(matcher[0].length);\n }\n var buffer = stringToBuffer(serializedString);\n\n // Return the right type based on the code/type set during\n // serialization.\n switch (type) {\n case TYPE_ARRAYBUFFER:\n return buffer;\n case TYPE_BLOB:\n return createBlob([buffer], { type: blobType });\n case TYPE_INT8ARRAY:\n return new Int8Array(buffer);\n case TYPE_UINT8ARRAY:\n return new Uint8Array(buffer);\n case TYPE_UINT8CLAMPEDARRAY:\n return new Uint8ClampedArray(buffer);\n case TYPE_INT16ARRAY:\n return new Int16Array(buffer);\n case TYPE_UINT16ARRAY:\n return new Uint16Array(buffer);\n case TYPE_INT32ARRAY:\n return new Int32Array(buffer);\n case TYPE_UINT32ARRAY:\n return new Uint32Array(buffer);\n case TYPE_FLOAT32ARRAY:\n return new Float32Array(buffer);\n case TYPE_FLOAT64ARRAY:\n return new Float64Array(buffer);\n default:\n throw new Error('Unkown type: ' + type);\n }\n}\n\nvar localforageSerializer = {\n serialize: serialize,\n deserialize: deserialize,\n stringToBuffer: stringToBuffer,\n bufferToString: bufferToString\n};\n\n/*\n * Includes code from:\n *\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n// Open the WebSQL database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage$1(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i];\n }\n }\n\n var dbInfoPromise = new Promise$1(function (resolve, reject) {\n // Open the database; the openDatabase API will automatically\n // create it for us if it doesn't exist.\n try {\n dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size);\n } catch (e) {\n return reject(e);\n }\n\n // Create our key/value table if it doesn't exist.\n dbInfo.db.transaction(function (t) {\n t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' (id INTEGER PRIMARY KEY, key unique, value)', [], function () {\n self._dbInfo = dbInfo;\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n });\n\n dbInfo.serializer = localforageSerializer;\n return dbInfoPromise;\n}\n\nfunction getItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).value : null;\n\n // Check to see if this is serialized content we need to\n // unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction iterate$1(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName, [], function (t, results) {\n var rows = results.rows;\n var length = rows.length;\n\n for (var i = 0; i < length; i++) {\n var item = rows.item(i);\n var result = item.value;\n\n // Check to see if this is serialized content\n // we need to unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n result = iterator(result, item.key, i + 1);\n\n // void(0) prevents problems with redefinition\n // of `undefined`.\n if (result !== void 0) {\n resolve(result);\n return;\n }\n }\n\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction _setItem(key, value, callback, retriesLeft) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n // The localStorage API doesn't return undefined values in an\n // \"expected\" way, so undefined is always cast to null in all\n // drivers. See: https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n dbInfo.db.transaction(function (t) {\n t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + ' (key, value) VALUES (?, ?)', [key, value], function () {\n resolve(originalValue);\n }, function (t, error) {\n reject(error);\n });\n }, function (sqlError) {\n // The transaction failed; check\n // to see if it's a quota error.\n if (sqlError.code === sqlError.QUOTA_ERR) {\n // We reject the callback outright for now, but\n // it's worth trying to re-run the transaction.\n // Even if the user accepts the prompt to use\n // more storage on Safari, this error will\n // be called.\n //\n // Try to re-run the transaction.\n if (retriesLeft > 0) {\n resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1]));\n return;\n }\n reject(sqlError);\n }\n });\n }\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction setItem$1(key, value, callback) {\n return _setItem.apply(this, [key, value, callback, 1]);\n}\n\nfunction removeItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () {\n resolve();\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Deletes every item in the table.\n// TODO: Find out if this resets the AUTO_INCREMENT number.\nfunction clear$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function () {\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Does a simple `COUNT(key)` to get the number of items stored in\n// localForage.\nfunction length$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n // Ahhh, SQL makes this one soooooo easy.\n t.executeSql('SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) {\n var result = results.rows.item(0).c;\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Return the key located at key index X; essentially gets the key from a\n// `WHERE id = ?`. This is the most efficient way I can think to implement\n// this rarely-used (in my experience) part of the API, but it can seem\n// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so\n// the ID of each key will change every time it's updated. Perhaps a stored\n// procedure for the `setItem()` SQL would solve this problem?\n// TODO: Don't change ID on `setItem()`.\nfunction key$1(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).key : null;\n resolve(result);\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName, [], function (t, results) {\n var keys = [];\n\n for (var i = 0; i < results.rows.length; i++) {\n keys.push(results.rows.item(i).key);\n }\n\n resolve(keys);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar webSQLStorage = {\n _driver: 'webSQLStorage',\n _initStorage: _initStorage$1,\n iterate: iterate$1,\n getItem: getItem$1,\n setItem: setItem$1,\n removeItem: removeItem$1,\n clear: clear$1,\n length: length$1,\n key: key$1,\n keys: keys$1\n};\n\n// Config the localStorage backend, using options set in the config.\nfunction _initStorage$2(options) {\n var self = this;\n var dbInfo = {};\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n dbInfo.keyPrefix = dbInfo.name + '/';\n\n if (dbInfo.storeName !== self._defaultConfig.storeName) {\n dbInfo.keyPrefix += dbInfo.storeName + '/';\n }\n\n self._dbInfo = dbInfo;\n dbInfo.serializer = localforageSerializer;\n\n return Promise$1.resolve();\n}\n\n// Remove all keys from the datastore, effectively destroying all data in\n// the app's key/value store!\nfunction clear$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var keyPrefix = self._dbInfo.keyPrefix;\n\n for (var i = localStorage.length - 1; i >= 0; i--) {\n var key = localStorage.key(i);\n\n if (key.indexOf(keyPrefix) === 0) {\n localStorage.removeItem(key);\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Retrieve an item from the store. Unlike the original async_storage\n// library in Gaia, we don't modify return values at all. If a key's value\n// is `undefined`, we pass that value to the callback function.\nfunction getItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result = localStorage.getItem(dbInfo.keyPrefix + key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the key\n // is likely undefined and we'll pass it straight to the\n // callback.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items in the store.\nfunction iterate$2(iterator, callback) {\n var self = this;\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var keyPrefix = dbInfo.keyPrefix;\n var keyPrefixLength = keyPrefix.length;\n var length = localStorage.length;\n\n // We use a dedicated iterator instead of the `i` variable below\n // so other keys we fetch in localStorage aren't counted in\n // the `iterationNumber` argument passed to the `iterate()`\n // callback.\n //\n // See: github.com/mozilla/localForage/pull/435#discussion_r38061530\n var iterationNumber = 1;\n\n for (var i = 0; i < length; i++) {\n var key = localStorage.key(i);\n if (key.indexOf(keyPrefix) !== 0) {\n continue;\n }\n var value = localStorage.getItem(key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the\n // key is likely undefined and we'll pass it straight\n // to the iterator.\n if (value) {\n value = dbInfo.serializer.deserialize(value);\n }\n\n value = iterator(value, key.substring(keyPrefixLength), iterationNumber++);\n\n if (value !== void 0) {\n return value;\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Same as localStorage's key() method, except takes a callback.\nfunction key$2(n, callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result;\n try {\n result = localStorage.key(n);\n } catch (error) {\n result = null;\n }\n\n // Remove the prefix from the key, if a key is found.\n if (result) {\n result = result.substring(dbInfo.keyPrefix.length);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var length = localStorage.length;\n var keys = [];\n\n for (var i = 0; i < length; i++) {\n if (localStorage.key(i).indexOf(dbInfo.keyPrefix) === 0) {\n keys.push(localStorage.key(i).substring(dbInfo.keyPrefix.length));\n }\n }\n\n return keys;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Supply the number of keys in the datastore to the callback function.\nfunction length$2(callback) {\n var self = this;\n var promise = self.keys().then(function (keys) {\n return keys.length;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Remove an item from the store, nice and simple.\nfunction removeItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n localStorage.removeItem(dbInfo.keyPrefix + key);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Set a key's value and run an optional callback once the value is set.\n// Unlike Gaia's implementation, the callback function is passed the value,\n// in case you want to operate on that value only after you're sure it\n// saved, or something like that.\nfunction setItem$2(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n // Convert undefined values to null.\n // https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n return new Promise$1(function (resolve, reject) {\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n try {\n localStorage.setItem(dbInfo.keyPrefix + key, value);\n resolve(originalValue);\n } catch (e) {\n // localStorage capacity exceeded.\n // TODO: Make this a specific error/event.\n if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {\n reject(e);\n }\n reject(e);\n }\n }\n });\n });\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar localStorageWrapper = {\n _driver: 'localStorageWrapper',\n _initStorage: _initStorage$2,\n // Default API, from Gaia/localStorage.\n iterate: iterate$2,\n getItem: getItem$2,\n setItem: setItem$2,\n removeItem: removeItem$2,\n clear: clear$2,\n length: length$2,\n key: key$2,\n keys: keys$2\n};\n\n// Custom drivers are stored here when `defineDriver()` is called.\n// They are shared across all instances of localForage.\nvar CustomDrivers = {};\n\nvar DriverType = {\n INDEXEDDB: 'asyncStorage',\n LOCALSTORAGE: 'localStorageWrapper',\n WEBSQL: 'webSQLStorage'\n};\n\nvar DefaultDriverOrder = [DriverType.INDEXEDDB, DriverType.WEBSQL, DriverType.LOCALSTORAGE];\n\nvar LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem'];\n\nvar DefaultConfig = {\n description: '',\n driver: DefaultDriverOrder.slice(),\n name: 'localforage',\n // Default DB size is _JUST UNDER_ 5MB, as it's the highest size\n // we can use without a prompt.\n size: 4980736,\n storeName: 'keyvaluepairs',\n version: 1.0\n};\n\nvar driverSupport = {};\n// Check to see if IndexedDB is available and if it is the latest\n// implementation; it's our preferred backend library. We use \"_spec_test\"\n// as the name of the database because it's not the one we'll operate on,\n// but it's useful to make sure its using the right spec.\n// See: https://github.com/mozilla/localForage/issues/128\ndriverSupport[DriverType.INDEXEDDB] = isIndexedDBValid();\n\ndriverSupport[DriverType.WEBSQL] = isWebSQLValid();\n\ndriverSupport[DriverType.LOCALSTORAGE] = isLocalStorageValid();\n\nvar isArray = Array.isArray || function (arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n};\n\nfunction callWhenReady(localForageInstance, libraryMethod) {\n localForageInstance[libraryMethod] = function () {\n var _args = arguments;\n return localForageInstance.ready().then(function () {\n return localForageInstance[libraryMethod].apply(localForageInstance, _args);\n });\n };\n}\n\nfunction extend() {\n for (var i = 1; i < arguments.length; i++) {\n var arg = arguments[i];\n\n if (arg) {\n for (var key in arg) {\n if (arg.hasOwnProperty(key)) {\n if (isArray(arg[key])) {\n arguments[0][key] = arg[key].slice();\n } else {\n arguments[0][key] = arg[key];\n }\n }\n }\n }\n }\n\n return arguments[0];\n}\n\nfunction isLibraryDriver(driverName) {\n for (var driver in DriverType) {\n if (DriverType.hasOwnProperty(driver) && DriverType[driver] === driverName) {\n return true;\n }\n }\n\n return false;\n}\n\nvar LocalForage = function () {\n function LocalForage(options) {\n _classCallCheck(this, LocalForage);\n\n this.INDEXEDDB = DriverType.INDEXEDDB;\n this.LOCALSTORAGE = DriverType.LOCALSTORAGE;\n this.WEBSQL = DriverType.WEBSQL;\n\n this._defaultConfig = extend({}, DefaultConfig);\n this._config = extend({}, this._defaultConfig, options);\n this._driverSet = null;\n this._initDriver = null;\n this._ready = false;\n this._dbInfo = null;\n\n this._wrapLibraryMethodsWithReady();\n this.setDriver(this._config.driver)[\"catch\"](function () {});\n }\n\n // Set any config values for localForage; can be called anytime before\n // the first API call (e.g. `getItem`, `setItem`).\n // We loop through options so we don't overwrite existing config\n // values.\n\n\n LocalForage.prototype.config = function config(options) {\n // If the options argument is an object, we use it to set values.\n // Otherwise, we return either a specified config value or all\n // config values.\n if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {\n // If localforage is ready and fully initialized, we can't set\n // any new configuration values. Instead, we return an error.\n if (this._ready) {\n return new Error(\"Can't call config() after localforage \" + 'has been used.');\n }\n\n for (var i in options) {\n if (i === 'storeName') {\n options[i] = options[i].replace(/\\W/g, '_');\n }\n\n if (i === 'version' && typeof options[i] !== 'number') {\n return new Error('Database version must be a number.');\n }\n\n this._config[i] = options[i];\n }\n\n // after all config options are set and\n // the driver option is used, try setting it\n if ('driver' in options && options.driver) {\n return this.setDriver(this._config.driver);\n }\n\n return true;\n } else if (typeof options === 'string') {\n return this._config[options];\n } else {\n return this._config;\n }\n };\n\n // Used to define a custom driver, shared across all instances of\n // localForage.\n\n\n LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) {\n var promise = new Promise$1(function (resolve, reject) {\n try {\n var driverName = driverObject._driver;\n var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver');\n var namingError = new Error('Custom driver name already in use: ' + driverObject._driver);\n\n // A driver name should be defined and not overlap with the\n // library-defined, default drivers.\n if (!driverObject._driver) {\n reject(complianceError);\n return;\n }\n if (isLibraryDriver(driverObject._driver)) {\n reject(namingError);\n return;\n }\n\n var customDriverMethods = LibraryMethods.concat('_initStorage');\n for (var i = 0; i < customDriverMethods.length; i++) {\n var customDriverMethod = customDriverMethods[i];\n if (!customDriverMethod || !driverObject[customDriverMethod] || typeof driverObject[customDriverMethod] !== 'function') {\n reject(complianceError);\n return;\n }\n }\n\n var supportPromise = Promise$1.resolve(true);\n if ('_support' in driverObject) {\n if (driverObject._support && typeof driverObject._support === 'function') {\n supportPromise = driverObject._support();\n } else {\n supportPromise = Promise$1.resolve(!!driverObject._support);\n }\n }\n\n supportPromise.then(function (supportResult) {\n driverSupport[driverName] = supportResult;\n CustomDrivers[driverName] = driverObject;\n resolve();\n }, reject);\n } catch (e) {\n reject(e);\n }\n });\n\n executeTwoCallbacks(promise, callback, errorCallback);\n return promise;\n };\n\n LocalForage.prototype.driver = function driver() {\n return this._driver || null;\n };\n\n LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) {\n var self = this;\n var getDriverPromise = Promise$1.resolve().then(function () {\n if (isLibraryDriver(driverName)) {\n switch (driverName) {\n case self.INDEXEDDB:\n return asyncStorage;\n case self.LOCALSTORAGE:\n return localStorageWrapper;\n case self.WEBSQL:\n return webSQLStorage;\n }\n } else if (CustomDrivers[driverName]) {\n return CustomDrivers[driverName];\n } else {\n throw new Error('Driver not found.');\n }\n });\n executeTwoCallbacks(getDriverPromise, callback, errorCallback);\n return getDriverPromise;\n };\n\n LocalForage.prototype.getSerializer = function getSerializer(callback) {\n var serializerPromise = Promise$1.resolve(localforageSerializer);\n executeTwoCallbacks(serializerPromise, callback);\n return serializerPromise;\n };\n\n LocalForage.prototype.ready = function ready(callback) {\n var self = this;\n\n var promise = self._driverSet.then(function () {\n if (self._ready === null) {\n self._ready = self._initDriver();\n }\n\n return self._ready;\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n };\n\n LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) {\n var self = this;\n\n if (!isArray(drivers)) {\n drivers = [drivers];\n }\n\n var supportedDrivers = this._getSupportedDrivers(drivers);\n\n function setDriverToConfig() {\n self._config.driver = self.driver();\n }\n\n function extendSelfWithDriver(driver) {\n self._extend(driver);\n setDriverToConfig();\n\n self._ready = self._initStorage(self._config);\n return self._ready;\n }\n\n function initDriver(supportedDrivers) {\n return function () {\n var currentDriverIndex = 0;\n\n function driverPromiseLoop() {\n while (currentDriverIndex < supportedDrivers.length) {\n var driverName = supportedDrivers[currentDriverIndex];\n currentDriverIndex++;\n\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(extendSelfWithDriver)[\"catch\"](driverPromiseLoop);\n }\n\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n }\n\n return driverPromiseLoop();\n };\n }\n\n // There might be a driver initialization in progress\n // so wait for it to finish in order to avoid a possible\n // race condition to set _dbInfo\n var oldDriverSetDone = this._driverSet !== null ? this._driverSet[\"catch\"](function () {\n return Promise$1.resolve();\n }) : Promise$1.resolve();\n\n this._driverSet = oldDriverSetDone.then(function () {\n var driverName = supportedDrivers[0];\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(function (driver) {\n self._driver = driver._driver;\n setDriverToConfig();\n self._wrapLibraryMethodsWithReady();\n self._initDriver = initDriver(supportedDrivers);\n });\n })[\"catch\"](function () {\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n });\n\n executeTwoCallbacks(this._driverSet, callback, errorCallback);\n return this._driverSet;\n };\n\n LocalForage.prototype.supports = function supports(driverName) {\n return !!driverSupport[driverName];\n };\n\n LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) {\n extend(this, libraryMethodsAndProperties);\n };\n\n LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) {\n var supportedDrivers = [];\n for (var i = 0, len = drivers.length; i < len; i++) {\n var driverName = drivers[i];\n if (this.supports(driverName)) {\n supportedDrivers.push(driverName);\n }\n }\n return supportedDrivers;\n };\n\n LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() {\n // Add a stub for each driver API method that delays the call to the\n // corresponding driver method until localForage is ready. These stubs\n // will be replaced by the driver methods as soon as the driver is\n // loaded, so there is no performance impact.\n for (var i = 0; i < LibraryMethods.length; i++) {\n callWhenReady(this, LibraryMethods[i]);\n }\n };\n\n LocalForage.prototype.createInstance = function createInstance(options) {\n return new LocalForage(options);\n };\n\n return LocalForage;\n}();\n\n// The actual localForage object that we expose as a module or via a\n// global. It's extended by pulling in one of our other libraries.\n\n\nvar localforage_js = new LocalForage();\n\nmodule.exports = localforage_js;\n\n},{\"3\":3}]},{},[4])(4)\n});","const initial = require('./problems/initial');\nconst arrays = require('./problems/arrays');\n\nmodule.exports = {\n initial: initial,\n arrays: arrays\n};\n","module.exports = [\n {\n name: 'Access Array by index (first)',\n time: 10,\n prompt: 'Return the first value of the Array',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits[0];`,\n tests: [\n {\n name: 'Correct output',\n test: 'assert.deepEqual(output, \\'apple\\') === undefined'\n },\n {\n name: 'Returns a String',\n test: 'assert.isString(output) === undefined'\n }\n ]\n },\n {\n name: 'Access Array by index (last)',\n time: 10,\n prompt: 'Return the last value of the Array',\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n return fruits[fruits.length - 1];`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 'orange') === undefined;`\n },\n {\n name: 'Returns a String',\n test: `assert.isString(output) === undefined;`\n }\n ]\n },\n {\n name: 'Access Array by index (second)',\n time: 10,\n prompt: 'Return the second value of the Array',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits[1];`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 'banana') === undefined;`\n },\n {\n name: 'Returns a String',\n test: `assert.isString(output) === undefined;`\n }\n ]\n },\n {\n name: 'Array.forEach()',\n time: 20,\n prompt: 'Loop over the array, add an \\'x\\' to the end of each name, push each fruit into a new array, then return the new array.',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n const newFruits = [];\n fruits.forEach(function(item) {\n newFruits.push(item+'x');\n });\n return newFruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['applex', 'bananax']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.push()',\n time: 10,\n prompt: `Add 'orange' to the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n fruits.push('orange');\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `(assert.deepEqual(output, ['apple', 'banana', 'orange']) === undefined);`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n }\n ]\n },\n {\n name: 'Array.shift()',\n time: 10,\n prompt: `Remove 'apple' from the front of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.shift();\n return fruits;`,\n tests: [\n {\n name: 'Output must be correct',\n test: `assert.deepEqual(output, ['banana', 'orange']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.unshift()',\n time: 10,\n prompt: `Add 'strawberry' to the front of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.unshift('strawberry');\n return fruits;`,\n tests: [\n {\n name: 'Output must be correct',\n test: `(assert.deepEqual(output, [\n 'strawberry',\n 'apple',\n 'banana',\n 'orange'\n ]) === undefined)`\n },\n {\n name: 'Must return an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 4 items',\n test: `assert.lengthOf(output, 4) === undefined;`\n }\n ]\n },\n {\n name: 'Array.indexOf()',\n time: 10,\n prompt: `Return the index of 'banana' in the Array.`,\n given: `const fruits = ['strawberry', 'banana', 'mango'];\\r`,\n answer: `const fruits = ['strawberry', 'banana', 'mango'];\n const ind = fruits.indexOf('banana');\n return ind;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 1) === undefined;`\n },\n {\n name: 'Returns a Number',\n test: `assert.isNumber(output) === undefined;`\n }\n ]\n },\n {\n name: 'Array.concat()',\n time: 10,\n prompt: `Merge the two arrays using Array's 'concat()' method. Return the resulting array.`,\n given: `const fruits = ['strawberry', 'banana'];\\rconst otherFruits = ['pear','peach'];\\r`,\n answer: `const fruits = ['strawberry', 'banana'];\n const otherFruits = ['pear','peach'];\n const allTheFruits = fruits.concat(otherFruits);\n return allTheFruits;\\r`,\n tests: [\n {\n name: 'Correct output',\n test: `(assert.deepEqual(output, [\n 'strawberry',\n 'banana',\n 'pear',\n 'peach'\n ]) === undefined\n );`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 4 items',\n test: `assert.lengthOf(output, 4) === undefined;`\n }\n ]\n },\n {\n name: 'Array.join()',\n time: 10,\n prompt: `Mix the two flavors with a '-' using Array's 'join' method. Return the resulting hybrid flavor.`,\n given: `const fruits = ['strawberry', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'banana'];\n const hybrid = fruits.join('-');\n return hybrid;\\r`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 'strawberry-banana') === undefined;`\n },\n {\n name: 'Returns a String',\n test: `assert.isString(output) === undefined;`\n }\n ]\n },\n {\n name: 'Array.slice()',\n time: 20,\n prompt: `Return just the citrus fruits from the 'fruits' array using 'Array.slice()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const citrus = fruits.slice(1, 3);\n return citrus;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['orange', 'lemon']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.reverse()',\n time: 10,\n prompt: `Reverse the order of the 'fruit' array using 'Array.reverse()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const stiurf = fruits.reverse();\n return stiurf;`,\n tests: [\n {\n name: 'Correct output',\n test: `(assert.deepEqual(output, [\n 'banana',\n 'lemon',\n 'orange',\n 'strawberry'\n ]) === undefined);`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 4 items',\n test: `assert.lengthOf(output, 4) === undefined;`\n },\n {\n name: `First item is 'banana'`,\n test: `assert.deepEqual(output[0], 'banana') === undefined;`\n }\n ]\n },\n {\n name: 'Array.sort()',\n time: 10,\n prompt: `Return the 'fruits' Array after sorting them using 'Array.sort()'.`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const orderlyFruit = fruits.sort();\n return orderlyFruit;`,\n tests: [\n {\n name: 'Correct output',\n test: `(assert.deepEqual(output, [\n 'banana',\n 'lemon',\n 'orange',\n 'strawberry'\n ]) === undefined);`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 4 items',\n test: `assert.lengthOf(output, 4) === undefined;`\n },\n {\n name: `First item is 'banana'`,\n test: `assert.deepEqual(output[0], 'banana') === undefined;`\n }\n ]\n },\n {\n name: 'Array.lastIndexOf()',\n time: 10,\n prompt: `Return the index of the last 'peach' instance in the 'fruit' array using 'Array.lastIndexOf()'`,\n given: `const fruits = ['peach', 'orange', 'lemon', 'peach'];\\r`,\n answer: `const fruits = ['peach', 'orange', 'lemon', 'peach'];\n const wheresTheLastPeach = fruits.lastIndexOf('peach');\n return wheresTheLastPeach;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 3) === undefined;`\n },\n {\n name: 'Returns a Number',\n test: `assert.isNumber(output) === undefined;`\n }\n ]\n },\n {\n name: 'Array.filter()',\n time: 10,\n prompt: `Return an array of the numbers greater than 5 in 'numbers' using 'Array.filter()'`,\n given: `const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\\r`,\n answer: `const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\n const overFive = numbers.filter(num => num > 5);\n return overFive;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, [8, 13, 21]) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n },\n {\n name: `First item is 8`,\n test: `assert.deepEqual(output[0], 8) === undefined;`\n }\n ]\n },\n {\n name: 'Array.map()',\n time: 10,\n prompt: `Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,\n given: `const numbers = [25, 121, 169];\\r`,\n answer: `const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, [5, 11, 13]) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n },\n {\n name: `First item is 5`,\n test: `assert.deepEqual(output[0], 5) === undefined;`\n },\n {\n name: `Last item is 13`,\n test: `assert.deepEqual(output[output.length - 1], 13) === undefined;`\n }\n ]\n },\n {\n name: 'Array.every()',\n time: 10,\n prompt: `Return object that returns whether each array contains all even numbers using Array.every().`,\n given: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,\n answer: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n return element % 2 === 0\n }\n return {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n };`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;`\n },\n {\n name: 'Returns an Object',\n test: `assert.isObject(output) === undefined;`\n },\n {\n name: 'Object has 2 items',\n test: `assert.lengthOf(Object.keys(output), 2) === undefined;`\n },\n {\n name: `First value is true`,\n test: `assert.isTrue(output.evenNumbers) === undefined;`\n },\n {\n name: `Second value is false`,\n test: `assert.isFalse(output.someOddNumbers) === undefined;`\n }\n ]\n },\n {\n name: 'Array.some()',\n time: 10,\n prompt: `Return 'Object' that returns whether each array contains some odd numbers using 'Array.some()'.`,\n given: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 4, 7, 8];\n function isOdd(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,\n answer: `const evenNumbers = [1, 3, 5, 7];\n const someOddNumbers = [1, 3, 6, 7];\n function isOdd(element) {\n return element % 2 !== 0;\n }\n return {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n };`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;`\n },\n {\n name: 'Returns an Object',\n test: `assert.isObject(output) === undefined;`\n },\n {\n name: 'Object has 2 items',\n test: `assert.lengthOf(Object.keys(output), 2) === undefined;`\n },\n {\n name: `First value is false`,\n test: `assert.isFalse(output.evenNumbers) === undefined;`\n },\n {\n name: `Second value is true`,\n test: `assert.isTrue(output.someOddNumbers) === undefined;`\n }\n ]\n }\n // Next problems to create:\n // forEach? fix one above that tried, but can't verify forEach was used\n // some\n // reduce\n // reduceRight\n // Array.from and other ways to turn array-like into array\n];\n","module.exports = [\n {\n name: 'Create Array',\n time: 10,\n prompt: 'Create and return an array that contains \\'apple\\' and \\'banana\\'',\n given: `const fruits = [];\\rreturn fruits;`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.pop()',\n time: 10,\n prompt: `Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n }\n]\n","module.exports = require('./lib/type');\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n '[object Array]': 'array'\n , '[object RegExp]': 'regexp'\n , '[object Function]': 'function'\n , '[object Arguments]': 'arguments'\n , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n var str = Object.prototype.toString.call(obj);\n if (natives[str]) return natives[str];\n if (obj === null) return 'null';\n if (obj === undefined) return 'undefined';\n if (obj === Object(obj)) return 'object';\n return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n // Let \"new String('')\" return 'object'\n if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n // PhantomJS has type \"DOMWindow\" for null\n if (obj === null) return 'null';\n // PhantomJS has type \"DOMWindow\" for undefined\n if (obj === undefined) return 'undefined';\n return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n if (!(this instanceof Library)) return new Library();\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","(function (document, window) {\n // DEPENDENCIES\n // ============================================================\n const localforage = require('localforage');\n const probs = require('pjs-problems');\n const dedent = require('dedent');\n const assert = require('chai').assert;\n\n // PROBLEM TEMPLATE NICE-IFICATION\n // ============================================================\n\n function dedentStrings(problems) {\n return problems.map(prob => {\n prob.given = dedent(prob.given)\n prob.answer = dedent(prob.answer)\n return prob\n });\n }\n\n\n // PROBLEMS\n // ============================================================\n\n let problems = [];\n Object.keys(probs).forEach(subject => {\n problems.push(...probs[subject]);\n });\n problems = dedentStrings(problems);\n\n\n // CONFIG\n // ============================================================\n\n // Hoist current problem\n let currentProblem;\n\n // Keys to ignore while user is navigating around the textarea but not changing any code\n const ignoreKeyCodes = [\n 9, // Tab\n 37, // Left arrow\n 39, // Right arrow\n 38, // Up arrow\n 40 // Down arrow\n ];\n\n let config = {\n shuffle: true,\n timer: false,\n currentIndex: 0\n };\n\n // Pull config from localforage\n localforage\n .getItem('js_practice_config')\n .then(val => {\n if (val) {\n config = val;\n }\n loadApp(config);\n })\n .catch(err => {\n console.log('localforage err:', err);\n loadApp(config);\n });\n\n function updateLocalstore(config) {\n return localforage\n .setItem('js_practice_config', config)\n .then(val => val)\n .catch(err => {\n console.log('Settings update error:', err);\n });\n }\n\n // HELPERS\n // ============================================================\n\n function debounce(func, wait, immediate) {\n let timeout;\n return function () {\n const context = this;\n const args = arguments;\n const later = function () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n };\n const callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) {\n func.apply(context, args);\n }\n };\n }\n\n // UI\n // ============================================================\n\n // elements\n const problemEl = document.getElementById('problem');\n const codeEl = document.getElementById('code');\n const testSuiteEl = document.getElementById('test-suite');\n const testTotalEl = document.getElementById('test-total');\n const evalConsoleEl = document.getElementById('eval-output');\n const assertConsoleEl = document.getElementById('assert-output');\n const shuffleProblemsButtonEl = document.getElementById('shuffle-problems');\n const previousProblemButtonEl = document.getElementById('prev-problem');\n const nextProblemButtonEl = document.getElementById('next-problem');\n\n // Get indexes\n function getRandomIndex(problemsArr) {\n const ind = Math.floor(Math.random() * problemsArr.length);\n config.currentIndex = ind;\n updateLocalstore(config);\n return ind;\n }\n\n function getPreviousIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at beginning, go to end\n if (currentIndex === 0) {\n probInd = problemsArr.length - 1;\n } else {\n probInd = currentIndex - 1;\n }\n return probInd;\n }\n\n function getNextIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at end or invalid, restart series\n if (currentIndex >= problemsArr.length - 1 || currentIndex < 0) {\n probInd = 0;\n } else {\n probInd = currentIndex + 1;\n }\n return probInd;\n }\n\n // Get problems\n function getCurrentProblem(problemsArr) {\n return problemsArr[config.currentIndex];\n }\n\n function previousProblem() {\n console.log('previousProblem!');\n // Activate back button, for visual queue of nav feedback\n previousProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getPreviousIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function nextProblem() {\n console.log('nextProblem!');\n // Activate next button, for visual queue of nav feedback\n nextProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getNextIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function toggleShuffle() {\n console.log('toggle shuffle!');\n config.shuffle = !config.shuffle; // Flip it\n shuffleProblemsButtonEl.classList.toggle('active');\n previousProblemButtonEl.parentNode.classList.toggle('hidden');\n updateLocalstore(config);\n }\n\n function loadProblem(problemObj) {\n currentProblem = problemObj;\n // Prob question\n problemEl.innerText = problemObj.prompt;\n // Prob given code\n if (problemObj.given) {\n codeEl.value = problemObj.given;\n }\n // Seed the tests, pass (init = true) as second param\n testSuite(null, true);\n }\n\n // TODO: Build the assert errors into the test dom on each update.\n function updateTests(testStatus, init) {\n if (init === true) {\n buildTests(currentProblem.tests);\n }\n updateTestStatus(testStatus);\n }\n\n function buildTests(tests) {\n if (tests) {\n const testsDom = tests\n .map(test => {\n return `
\n
[✘]
\n
${test.name}
\n
`;\n })\n .join('');\n testSuiteEl.innerHTML = testsDom;\n }\n }\n\n function updateTestStatus(testStatuses) {\n if (!testStatuses) {\n throw new Error('No testStatuses provided.');\n }\n // Find out if all tests have passed or not\n let allPassed = true;\n testStatuses.forEach(testPassed => {\n if (testPassed !== true) {\n allPassed = false;\n }\n });\n const testEls = [].slice.call(testSuiteEl.querySelectorAll('.test-state'));\n testEls.forEach((testStatusEl, iter) => {\n if (testStatuses[iter] === true) {\n testStatusEl.innerHTML = '[✓]';\n testStatusEl.classList.remove('fail');\n testStatusEl.classList.add('pass');\n } else {\n testStatusEl.innerHTML = '[✘]';\n testStatusEl.classList.remove('pass');\n testStatusEl.classList.add('fail');\n }\n });\n\n if (allPassed === true) {\n testTotalEl.innerText = 'PASS';\n testTotalEl.classList.remove('fail');\n testTotalEl.classList.add('pass');\n } else {\n testTotalEl.innerText = 'FAIL';\n testTotalEl.classList.remove('pass');\n testTotalEl.classList.add('fail');\n }\n }\n\n function printAssertError(errObj) {\n // Make element string\n let inner = '';\n if (errObj !== null) {\n inner = `\n
\n Expected: ${JSON.stringify(errObj.expected)}\n Actual: ${JSON.stringify(errObj.actual)}\n
`;\n }\n\n // Prepend element\n assertConsoleEl.innerHTML = inner;\n }\n\n function printEvalOutput(errObj, output) {\n // Make element string\n let inner = '';\n if (errObj && errObj.message !== undefined) {\n inner = `\n
\n Syntax Error: ${JSON.stringify(errObj.message)}\n
`;\n } else if (output) {\n inner = `\n
\n Output: ${JSON.stringify(output)}\n
`;\n }\n // Prepend element\n evalConsoleEl.innerHTML = inner;\n }\n\n\n // VERIFICATION LOGIC\n // ============================================================\n\n function testSuite(init) {\n // Show 'working' indicator\n testTotalEl.classList.toggle('working');\n // Run stuff\n const output = getOutput(codeEl.value);\n // Run tests on code, return object/array of test results\n const tested = runTests(output);\n // Hide 'working' indicator\n testTotalEl.classList.toggle('working');\n // Update UI with results\n updateTests(tested, init);\n }\n\n function getOutput(code) {\n let evald = false;\n try {\n evald = eval(`(function(){${code}})()`); // eslint-disable-line no-eval\n printEvalOutput(null, evald); // Print current output\n } catch (err) {\n printEvalOutput(err);\n }\n return evald;\n }\n\n function runTests(output) {\n let tested = false;\n tested = currentProblem.tests.map(test => {\n let testOutcome = false;\n try {\n if (output) {\n // const testEval = eval(test.test);\n\n testOutcome = eval(test.test);\n console.log('testOutcome:', testOutcome);\n\n }\n printAssertError(null);\n } catch (err) {\n printAssertError(err);\n }\n return testOutcome;\n });\n return tested;\n }\n\n // Wrapped to prevent race with local config retrieval\n function loadApp(config) {\n console.log('loading app!');\n\n // Show current toggle state\n if (config.shuffle === true) {\n shuffleProblemsButtonEl.classList.add('active');\n previousProblemButtonEl.parentNode.classList.add('hidden');\n }\n\n // Keybinding stuff\n // ============================================================\n\n // Debounced code validation\n const debouncedInputValidation = debounce(e => {\n // If not arrow keys or other non-character keys\n if (ignoreKeyCodes.indexOf(e.keyCode) === -1) {\n // Run test suite\n testSuite();\n }\n }, 200);\n\n function problemNav(e) {\n // Go to previous problem keybinding\n // If CMD/CTRL + SHIFT + RETURN/ENTER\n if (config.shuffle === false && e.keyCode === 13 && e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem\n previousProblem();\n } else if (e.keyCode === 13 && !e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem keybinding\n // If CMD/CTRL + RETURN/ENTER\n // Go to next problem\n nextProblem();\n }\n }\n\n // Event Bindings\n // ============================================================\n\n // Bind it up\n codeEl.addEventListener('keydown', debouncedInputValidation);\n document.addEventListener('keydown', problemNav);\n shuffleProblemsButtonEl.addEventListener('click', toggleShuffle);\n previousProblemButtonEl.addEventListener('click', previousProblem);\n nextProblemButtonEl.addEventListener('click', nextProblem);\n\n // Start it up!\n // Load current problem\n const currProb = getCurrentProblem(problems);\n loadProblem(currProb);\n // Initalized test suite with starting failures\n testSuite(true);\n }\n})(document, window);\n"]} \ No newline at end of file diff --git a/public/service-worker.js b/public/service-worker.js index 6fc2951..48fc78c 100644 --- a/public/service-worker.js +++ b/public/service-worker.js @@ -1,2 +1,2 @@ -"use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}var precacheConfig=[["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","7c1a8058bb3d00c2b40283c735748cfc"],["/dist/js/bundle.min.js","c0432a6b64b4d59efc450a7b1e2c2de7"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]],cacheName="sw-precache-v3--"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(e){return e.redirected?("body"in e?Promise.resolve(e.body):e.blob()).then(function(t){return new Response(t,{headers:e.headers,status:e.status,statusText:e.statusText})}):Promise.resolve(e)},createCacheKey=function(e,t,n,r){var a=new URL(e);return r&&a.pathname.match(r)||(a.search+=(a.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),a.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,t){var n=new URL(e);return n.hash="",n.search=n.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),n.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],r=new URL(t,self.location),a=createCacheKey(r,hashParamName,n,!1);return[r.toString(),a]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(n){if(!t.has(n)){var r=new Request(n,{credentials:"same-origin"});return fetch(r).then(function(t){if(!t.ok)throw new Error("Request for "+n+" returned a response with status "+t.status);return cleanResponse(t).then(function(t){return e.put(n,t)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(n){return Promise.all(n.map(function(n){if(!t.has(n.url))return e.delete(n)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,n=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);(t=urlsToCacheKeys.has(n))||(n=addDirectoryIndex(n,"index.html"),t=urlsToCacheKeys.has(n));t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}); +"use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}var precacheConfig=[["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","7c1a8058bb3d00c2b40283c735748cfc"],["/dist/js/bundle.min.js","72b4f3c34fac3a128cb74efc7e15d71a"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]],cacheName="sw-precache-v3--"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(e){return e.redirected?("body"in e?Promise.resolve(e.body):e.blob()).then(function(t){return new Response(t,{headers:e.headers,status:e.status,statusText:e.statusText})}):Promise.resolve(e)},createCacheKey=function(e,t,n,r){var a=new URL(e);return r&&a.pathname.match(r)||(a.search+=(a.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),a.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,t){var n=new URL(e);return n.hash="",n.search=n.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),n.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],r=new URL(t,self.location),a=createCacheKey(r,hashParamName,n,!1);return[r.toString(),a]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(n){if(!t.has(n)){var r=new Request(n,{credentials:"same-origin"});return fetch(r).then(function(t){if(!t.ok)throw new Error("Request for "+n+" returned a response with status "+t.status);return cleanResponse(t).then(function(t){return e.put(n,t)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(n){return Promise.all(n.map(function(n){if(!t.has(n.url))return e.delete(n)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,n=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);(t=urlsToCacheKeys.has(n))||(n=addDirectoryIndex(n,"index.html"),t=urlsToCacheKeys.has(n));t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}); //# sourceMappingURL=service-worker.js.map diff --git a/public/service-worker.js.map b/public/service-worker.js.map index 4bea406..318e96e 100644 --- a/public/service-worker.js.map +++ b/public/service-worker.js.map @@ -1 +1 @@ -{"version":3,"sources":["service-worker.js"],"names":["setOfCachedUrls","cache","keys","then","requests","map","request","url","urls","Set","precacheConfig","cacheName","self","registration","scope","ignoreUrlParametersMatching","addDirectoryIndex","originalUrl","index","URL","pathname","slice","toString","cleanResponse","originalResponse","redirected","Promise","resolve","body","blob","Response","headers","status","statusText","createCacheKey","paramName","paramValue","dontCacheBustUrlsMatching","match","search","encodeURIComponent","isPathWhitelisted","whitelist","absoluteUrlString","length","path","some","whitelistedPathRegex","stripIgnoredUrlParameters","hash","split","kv","filter","every","ignoredRegex","test","join","hashParamName","urlsToCacheKeys","Map","item","relativeUrl","absoluteUrl","location","cacheKey","addEventListener","event","waitUntil","caches","open","cachedUrls","all","Array","from","values","has","Request","credentials","fetch","response","ok","Error","responseToCache","put","skipWaiting","setOfExpectedUrls","existingRequests","existingRequest","delete","clients","claim","method","shouldRespond","respondWith","get","catch","e","console","warn"],"mappings":"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","file":"service-worker.js","sourcesContent":["/**\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n*/\n\n// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY!\n// This file should be overwritten as part of your build process.\n// If you need to extend the behavior of the generated service worker, the best approach is to write\n// additional code and include it using the importScripts option:\n// https://github.com/GoogleChrome/sw-precache#importscripts-arraystring\n//\n// Alternatively, it's possible to make changes to the underlying template file and then use that as the\n// new base for generating output, via the templateFilePath option:\n// https://github.com/GoogleChrome/sw-precache#templatefilepath-string\n//\n// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any\n// changes made to this original template file with your modified copy.\n\n// This generated service worker JavaScript will precache your site's resources.\n// The code needs to be saved in a .js file at the top-level of your site, and registered\n// from your pages in order to be used. See\n// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js\n// for an example of how you can register this script and handle various service worker events.\n\n/* eslint-env worker, serviceworker */\n/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */\n'use strict';\n\nvar precacheConfig = [[\"/dist/css/style.css\",\"ba4d66c91d1ed66848154a34ab4948cf\"],[\"/dist/img/back.svg\",\"898ada2a32ec64bd5b6959c22e8f231d\"],[\"/dist/img/monitor.svg\",\"348592da5567b5a3c46acfb5dcd341bc\"],[\"/dist/img/next.svg\",\"045593410b9f51390e750b9e1e7fff15\"],[\"/dist/img/reload.svg\",\"a0ab1b765280e4d22e6fb747042f6503\"],[\"/dist/img/shuffle.svg\",\"3a5e3c1bf04eb3493d8a2ffa547aa58f\"],[\"/dist/img/social-banner.png\",\"7c1a8058bb3d00c2b40283c735748cfc\"],[\"/dist/js/bundle.min.js\",\"c0432a6b64b4d59efc450a7b1e2c2de7\"],[\"/dist/js/loadJS.js\",\"72c55936069f60560a386e46f462c73a\"],[\"/dist/js/sw-registration.js\",\"677217d8e642c1ccff69fc01c96b4431\"],[\"/index.html\",\"c7522a5d3255caca0f12c5282ef0644d\"]];\nvar cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');\n\n\nvar ignoreUrlParametersMatching = [/^utm_/];\n\n\n\nvar addDirectoryIndex = function (originalUrl, index) {\n var url = new URL(originalUrl);\n if (url.pathname.slice(-1) === '/') {\n url.pathname += index;\n }\n return url.toString();\n };\n\nvar cleanResponse = function (originalResponse) {\n // If this is not a redirected response, then we don't have to do anything.\n if (!originalResponse.redirected) {\n return Promise.resolve(originalResponse);\n }\n\n // Firefox 50 and below doesn't support the Response.body stream, so we may\n // need to read the entire body to memory as a Blob.\n var bodyPromise = 'body' in originalResponse ?\n Promise.resolve(originalResponse.body) :\n originalResponse.blob();\n\n return bodyPromise.then(function(body) {\n // new Response() is happy when passed either a stream or a Blob.\n return new Response(body, {\n headers: originalResponse.headers,\n status: originalResponse.status,\n statusText: originalResponse.statusText\n });\n });\n };\n\nvar createCacheKey = function (originalUrl, paramName, paramValue,\n dontCacheBustUrlsMatching) {\n // Create a new URL object to avoid modifying originalUrl.\n var url = new URL(originalUrl);\n\n // If dontCacheBustUrlsMatching is not set, or if we don't have a match,\n // then add in the extra cache-busting URL parameter.\n if (!dontCacheBustUrlsMatching ||\n !(url.pathname.match(dontCacheBustUrlsMatching))) {\n url.search += (url.search ? '&' : '') +\n encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);\n }\n\n return url.toString();\n };\n\nvar isPathWhitelisted = function (whitelist, absoluteUrlString) {\n // If the whitelist is empty, then consider all URLs to be whitelisted.\n if (whitelist.length === 0) {\n return true;\n }\n\n // Otherwise compare each path regex to the path of the URL passed in.\n var path = (new URL(absoluteUrlString)).pathname;\n return whitelist.some(function(whitelistedPathRegex) {\n return path.match(whitelistedPathRegex);\n });\n };\n\nvar stripIgnoredUrlParameters = function (originalUrl,\n ignoreUrlParametersMatching) {\n var url = new URL(originalUrl);\n // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290\n url.hash = '';\n\n url.search = url.search.slice(1) // Exclude initial '?'\n .split('&') // Split into an array of 'key=value' strings\n .map(function(kv) {\n return kv.split('='); // Split each 'key=value' string into a [key, value] array\n })\n .filter(function(kv) {\n return ignoreUrlParametersMatching.every(function(ignoredRegex) {\n return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.\n });\n })\n .map(function(kv) {\n return kv.join('='); // Join each [key, value] array into a 'key=value' string\n })\n .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each\n\n return url.toString();\n };\n\n\nvar hashParamName = '_sw-precache';\nvar urlsToCacheKeys = new Map(\n precacheConfig.map(function(item) {\n var relativeUrl = item[0];\n var hash = item[1];\n var absoluteUrl = new URL(relativeUrl, self.location);\n var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);\n return [absoluteUrl.toString(), cacheKey];\n })\n);\n\nfunction setOfCachedUrls(cache) {\n return cache.keys().then(function(requests) {\n return requests.map(function(request) {\n return request.url;\n });\n }).then(function(urls) {\n return new Set(urls);\n });\n}\n\nself.addEventListener('install', function(event) {\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return setOfCachedUrls(cache).then(function(cachedUrls) {\n return Promise.all(\n Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {\n // If we don't have a key matching url in the cache already, add it.\n if (!cachedUrls.has(cacheKey)) {\n var request = new Request(cacheKey, {credentials: 'same-origin'});\n return fetch(request).then(function(response) {\n // Bail out of installation unless we get back a 200 OK for\n // every request.\n if (!response.ok) {\n throw new Error('Request for ' + cacheKey + ' returned a ' +\n 'response with status ' + response.status);\n }\n\n return cleanResponse(response).then(function(responseToCache) {\n return cache.put(cacheKey, responseToCache);\n });\n });\n }\n })\n );\n });\n }).then(function() {\n \n // Force the SW to transition from installing -> active state\n return self.skipWaiting();\n \n })\n );\n});\n\nself.addEventListener('activate', function(event) {\n var setOfExpectedUrls = new Set(urlsToCacheKeys.values());\n\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return cache.keys().then(function(existingRequests) {\n return Promise.all(\n existingRequests.map(function(existingRequest) {\n if (!setOfExpectedUrls.has(existingRequest.url)) {\n return cache.delete(existingRequest);\n }\n })\n );\n });\n }).then(function() {\n \n return self.clients.claim();\n \n })\n );\n});\n\n\nself.addEventListener('fetch', function(event) {\n if (event.request.method === 'GET') {\n // Should we call event.respondWith() inside this fetch event handler?\n // This needs to be determined synchronously, which will give other fetch\n // handlers a chance to handle the request if need be.\n var shouldRespond;\n\n // First, remove all the ignored parameters and hash fragment, and see if we\n // have that URL in our cache. If so, great! shouldRespond will be true.\n var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);\n shouldRespond = urlsToCacheKeys.has(url);\n\n // If shouldRespond is false, check again, this time with 'index.html'\n // (or whatever the directoryIndex option is set to) at the end.\n var directoryIndex = 'index.html';\n if (!shouldRespond && directoryIndex) {\n url = addDirectoryIndex(url, directoryIndex);\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond is still false, check to see if this is a navigation\n // request, and if so, whether the URL matches navigateFallbackWhitelist.\n var navigateFallback = '';\n if (!shouldRespond &&\n navigateFallback &&\n (event.request.mode === 'navigate') &&\n isPathWhitelisted([], event.request.url)) {\n url = new URL(navigateFallback, self.location).toString();\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond was set to true at any point, then call\n // event.respondWith(), using the appropriate cache key.\n if (shouldRespond) {\n event.respondWith(\n caches.open(cacheName).then(function(cache) {\n return cache.match(urlsToCacheKeys.get(url)).then(function(response) {\n if (response) {\n return response;\n }\n throw Error('The cached response that was expected is missing.');\n });\n }).catch(function(e) {\n // Fall back to just fetch()ing the request if some unexpected error\n // prevented the cached response from being valid.\n console.warn('Couldn\\'t serve response for \"%s\" from cache: %O', event.request.url, e);\n return fetch(event.request);\n })\n );\n }\n }\n});\n\n\n\n\n\n\n\n"]} \ No newline at end of file +{"version":3,"sources":["service-worker.js"],"names":["setOfCachedUrls","cache","keys","then","requests","map","request","url","urls","Set","precacheConfig","cacheName","self","registration","scope","ignoreUrlParametersMatching","addDirectoryIndex","originalUrl","index","URL","pathname","slice","toString","cleanResponse","originalResponse","redirected","Promise","resolve","body","blob","Response","headers","status","statusText","createCacheKey","paramName","paramValue","dontCacheBustUrlsMatching","match","search","encodeURIComponent","isPathWhitelisted","whitelist","absoluteUrlString","length","path","some","whitelistedPathRegex","stripIgnoredUrlParameters","hash","split","kv","filter","every","ignoredRegex","test","join","hashParamName","urlsToCacheKeys","Map","item","relativeUrl","absoluteUrl","location","cacheKey","addEventListener","event","waitUntil","caches","open","cachedUrls","all","Array","from","values","has","Request","credentials","fetch","response","ok","Error","responseToCache","put","skipWaiting","setOfExpectedUrls","existingRequests","existingRequest","delete","clients","claim","method","shouldRespond","respondWith","get","catch","e","console","warn"],"mappings":"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","file":"service-worker.js","sourcesContent":["/**\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n*/\n\n// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY!\n// This file should be overwritten as part of your build process.\n// If you need to extend the behavior of the generated service worker, the best approach is to write\n// additional code and include it using the importScripts option:\n// https://github.com/GoogleChrome/sw-precache#importscripts-arraystring\n//\n// Alternatively, it's possible to make changes to the underlying template file and then use that as the\n// new base for generating output, via the templateFilePath option:\n// https://github.com/GoogleChrome/sw-precache#templatefilepath-string\n//\n// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any\n// changes made to this original template file with your modified copy.\n\n// This generated service worker JavaScript will precache your site's resources.\n// The code needs to be saved in a .js file at the top-level of your site, and registered\n// from your pages in order to be used. See\n// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js\n// for an example of how you can register this script and handle various service worker events.\n\n/* eslint-env worker, serviceworker */\n/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */\n'use strict';\n\nvar precacheConfig = [[\"/dist/css/style.css\",\"ba4d66c91d1ed66848154a34ab4948cf\"],[\"/dist/img/back.svg\",\"898ada2a32ec64bd5b6959c22e8f231d\"],[\"/dist/img/monitor.svg\",\"348592da5567b5a3c46acfb5dcd341bc\"],[\"/dist/img/next.svg\",\"045593410b9f51390e750b9e1e7fff15\"],[\"/dist/img/reload.svg\",\"a0ab1b765280e4d22e6fb747042f6503\"],[\"/dist/img/shuffle.svg\",\"3a5e3c1bf04eb3493d8a2ffa547aa58f\"],[\"/dist/img/social-banner.png\",\"7c1a8058bb3d00c2b40283c735748cfc\"],[\"/dist/js/bundle.min.js\",\"72b4f3c34fac3a128cb74efc7e15d71a\"],[\"/dist/js/loadJS.js\",\"72c55936069f60560a386e46f462c73a\"],[\"/dist/js/sw-registration.js\",\"677217d8e642c1ccff69fc01c96b4431\"],[\"/index.html\",\"c7522a5d3255caca0f12c5282ef0644d\"]];\nvar cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');\n\n\nvar ignoreUrlParametersMatching = [/^utm_/];\n\n\n\nvar addDirectoryIndex = function (originalUrl, index) {\n var url = new URL(originalUrl);\n if (url.pathname.slice(-1) === '/') {\n url.pathname += index;\n }\n return url.toString();\n };\n\nvar cleanResponse = function (originalResponse) {\n // If this is not a redirected response, then we don't have to do anything.\n if (!originalResponse.redirected) {\n return Promise.resolve(originalResponse);\n }\n\n // Firefox 50 and below doesn't support the Response.body stream, so we may\n // need to read the entire body to memory as a Blob.\n var bodyPromise = 'body' in originalResponse ?\n Promise.resolve(originalResponse.body) :\n originalResponse.blob();\n\n return bodyPromise.then(function(body) {\n // new Response() is happy when passed either a stream or a Blob.\n return new Response(body, {\n headers: originalResponse.headers,\n status: originalResponse.status,\n statusText: originalResponse.statusText\n });\n });\n };\n\nvar createCacheKey = function (originalUrl, paramName, paramValue,\n dontCacheBustUrlsMatching) {\n // Create a new URL object to avoid modifying originalUrl.\n var url = new URL(originalUrl);\n\n // If dontCacheBustUrlsMatching is not set, or if we don't have a match,\n // then add in the extra cache-busting URL parameter.\n if (!dontCacheBustUrlsMatching ||\n !(url.pathname.match(dontCacheBustUrlsMatching))) {\n url.search += (url.search ? '&' : '') +\n encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);\n }\n\n return url.toString();\n };\n\nvar isPathWhitelisted = function (whitelist, absoluteUrlString) {\n // If the whitelist is empty, then consider all URLs to be whitelisted.\n if (whitelist.length === 0) {\n return true;\n }\n\n // Otherwise compare each path regex to the path of the URL passed in.\n var path = (new URL(absoluteUrlString)).pathname;\n return whitelist.some(function(whitelistedPathRegex) {\n return path.match(whitelistedPathRegex);\n });\n };\n\nvar stripIgnoredUrlParameters = function (originalUrl,\n ignoreUrlParametersMatching) {\n var url = new URL(originalUrl);\n // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290\n url.hash = '';\n\n url.search = url.search.slice(1) // Exclude initial '?'\n .split('&') // Split into an array of 'key=value' strings\n .map(function(kv) {\n return kv.split('='); // Split each 'key=value' string into a [key, value] array\n })\n .filter(function(kv) {\n return ignoreUrlParametersMatching.every(function(ignoredRegex) {\n return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.\n });\n })\n .map(function(kv) {\n return kv.join('='); // Join each [key, value] array into a 'key=value' string\n })\n .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each\n\n return url.toString();\n };\n\n\nvar hashParamName = '_sw-precache';\nvar urlsToCacheKeys = new Map(\n precacheConfig.map(function(item) {\n var relativeUrl = item[0];\n var hash = item[1];\n var absoluteUrl = new URL(relativeUrl, self.location);\n var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);\n return [absoluteUrl.toString(), cacheKey];\n })\n);\n\nfunction setOfCachedUrls(cache) {\n return cache.keys().then(function(requests) {\n return requests.map(function(request) {\n return request.url;\n });\n }).then(function(urls) {\n return new Set(urls);\n });\n}\n\nself.addEventListener('install', function(event) {\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return setOfCachedUrls(cache).then(function(cachedUrls) {\n return Promise.all(\n Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {\n // If we don't have a key matching url in the cache already, add it.\n if (!cachedUrls.has(cacheKey)) {\n var request = new Request(cacheKey, {credentials: 'same-origin'});\n return fetch(request).then(function(response) {\n // Bail out of installation unless we get back a 200 OK for\n // every request.\n if (!response.ok) {\n throw new Error('Request for ' + cacheKey + ' returned a ' +\n 'response with status ' + response.status);\n }\n\n return cleanResponse(response).then(function(responseToCache) {\n return cache.put(cacheKey, responseToCache);\n });\n });\n }\n })\n );\n });\n }).then(function() {\n \n // Force the SW to transition from installing -> active state\n return self.skipWaiting();\n \n })\n );\n});\n\nself.addEventListener('activate', function(event) {\n var setOfExpectedUrls = new Set(urlsToCacheKeys.values());\n\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return cache.keys().then(function(existingRequests) {\n return Promise.all(\n existingRequests.map(function(existingRequest) {\n if (!setOfExpectedUrls.has(existingRequest.url)) {\n return cache.delete(existingRequest);\n }\n })\n );\n });\n }).then(function() {\n \n return self.clients.claim();\n \n })\n );\n});\n\n\nself.addEventListener('fetch', function(event) {\n if (event.request.method === 'GET') {\n // Should we call event.respondWith() inside this fetch event handler?\n // This needs to be determined synchronously, which will give other fetch\n // handlers a chance to handle the request if need be.\n var shouldRespond;\n\n // First, remove all the ignored parameters and hash fragment, and see if we\n // have that URL in our cache. If so, great! shouldRespond will be true.\n var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);\n shouldRespond = urlsToCacheKeys.has(url);\n\n // If shouldRespond is false, check again, this time with 'index.html'\n // (or whatever the directoryIndex option is set to) at the end.\n var directoryIndex = 'index.html';\n if (!shouldRespond && directoryIndex) {\n url = addDirectoryIndex(url, directoryIndex);\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond is still false, check to see if this is a navigation\n // request, and if so, whether the URL matches navigateFallbackWhitelist.\n var navigateFallback = '';\n if (!shouldRespond &&\n navigateFallback &&\n (event.request.mode === 'navigate') &&\n isPathWhitelisted([], event.request.url)) {\n url = new URL(navigateFallback, self.location).toString();\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond was set to true at any point, then call\n // event.respondWith(), using the appropriate cache key.\n if (shouldRespond) {\n event.respondWith(\n caches.open(cacheName).then(function(cache) {\n return cache.match(urlsToCacheKeys.get(url)).then(function(response) {\n if (response) {\n return response;\n }\n throw Error('The cached response that was expected is missing.');\n });\n }).catch(function(e) {\n // Fall back to just fetch()ing the request if some unexpected error\n // prevented the cached response from being valid.\n console.warn('Couldn\\'t serve response for \"%s\" from cache: %O', event.request.url, e);\n return fetch(event.request);\n })\n );\n }\n }\n});\n\n\n\n\n\n\n\n"]} \ No newline at end of file diff --git a/shrinkwrap.yaml b/shrinkwrap.yaml index 9319604..55d8e81 100644 --- a/shrinkwrap.yaml +++ b/shrinkwrap.yaml @@ -26,7 +26,7 @@ dependencies: husky@^0.13.3: 0.13.4 lint-staged@^3.4.0: 3.6.0 localforage@^1.5.0: 1.5.0 - 'pjs-problems@git+https://github.com/practicejavascript/pjs-problems.git': github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916 + pjs-problems@^1.0.3: 1.0.3 pump@^1.0.2: 1.0.2 rollup-stream@^1.19.0: 1.19.0 sw-precache@^5.1.1: 5.1.1 @@ -3486,6 +3486,7 @@ packages: resolution: 2135d6dfa7a358c069ac9b178776288228450ffa /pinkie/1.0.0: 5a47f28ba1015d0201bda7bf0f358e47bec8c7e4 /pinkie/2.0.4: 72556b80cfa0d48a974e80e77248e80ed4f7f870 + /pjs-problems/1.0.3: 861601b28fda9aa4752d38d161d4a29589d25151 /pkg-conf/2.0.0: dependencies: find-up: 2.1.0 @@ -4742,8 +4743,5 @@ packages: bin-wrapper: 3.0.2 logalot: 2.1.0 resolution: e3cd3d1264605f38f405a770c191e89520bfa22e - github.com/practicejavascript/pjs-problems/0823cc1cffb999352e3f0caed295df8633f13916: - resolution: - tarball: 'https://codeload.github.com/practicejavascript/pjs-problems/tar.gz/0823cc1cffb999352e3f0caed295df8633f13916' registry: 'https://registry.npmjs.org/' version: 2 diff --git a/src/service-worker.js b/src/service-worker.js index d7b2ab4..7cb47e2 100644 --- a/src/service-worker.js +++ b/src/service-worker.js @@ -37,7 +37,7 @@ /* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */ 'use strict'; -var precacheConfig = [["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","7c1a8058bb3d00c2b40283c735748cfc"],["/dist/js/bundle.min.js","c0432a6b64b4d59efc450a7b1e2c2de7"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]]; +var precacheConfig = [["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","7c1a8058bb3d00c2b40283c735748cfc"],["/dist/js/bundle.min.js","72b4f3c34fac3a128cb74efc7e15d71a"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]]; var cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : ''); From da59281a9f3000b62728c4f569d173d770f5e1a5 Mon Sep 17 00:00:00 2001 From: Jakob Anderson Date: Fri, 2 Jun 2017 23:43:32 -0600 Subject: [PATCH 6/8] 1.1.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0d0d1cd..bf47078 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "javascript-practice", - "version": "1.1.0", + "version": "1.1.1", "lockfileVersion": 1, "dependencies": { "@ava/babel-preset-stage-4": { diff --git a/package.json b/package.json index a2157dc..b0b826c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "javascript-practice", - "version": "1.1.0", + "version": "1.1.1", "description": "practice javascript", "main": "index.js", "engines": { From e35bef8c6e8289a9eb0d0cc3252762502736753e Mon Sep 17 00:00:00 2001 From: Jakob Anderson Date: Fri, 2 Jun 2017 23:46:12 -0600 Subject: [PATCH 7/8] removed log --- public/dist/js/bundle.min.js | 2 +- public/dist/js/bundle.min.js.map | 2 +- public/service-worker.js | 2 +- public/service-worker.js.map | 2 +- src/js/index.js | 4 ---- src/service-worker.js | 2 +- 6 files changed, 5 insertions(+), 9 deletions(-) diff --git a/public/dist/js/bundle.min.js b/public/dist/js/bundle.min.js index d3368f9..8916e27 100644 --- a/public/dist/js/bundle.min.js +++ b/public/dist/js/bundle.min.js @@ -1,2 +1,2 @@ -!function e(t,n,r){function o(a,s){if(!n[a]){if(!t[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(i)return i(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var f=n[a]={exports:{}};t[a][0].call(f.exports,function(e){var n=t[a][1][e];return o(n||e)},f,f.exports,e,t,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;ae,"expected #{this} to have a length above #{exp} but got #{act}","expected #{this} to not have a length above #{exp}",e,r)}else this.assert(n>e,"expected #{this} to be above "+e,"expected #{this} to be at most "+e)}function u(e,t){t&&P(this,"message",t);var n=P(this,"object");if(P(this,"doLength")){new N(n,t).to.have.property("length");var r=n.length;this.assert(r>=e,"expected #{this} to have a length at least #{exp} but got #{act}","expected #{this} to have a length below #{exp}",e,r)}else this.assert(n>=e,"expected #{this} to be at least "+e,"expected #{this} to be below "+e)}function f(e,t){t&&P(this,"message",t);var n=P(this,"object");if(P(this,"doLength")){new N(n,t).to.have.property("length");var r=n.length;this.assert(r1)throw new Error(i);break;case"object":if(arguments.length>1)throw new Error(i);e=Object.keys(e);break;default:e=Array.prototype.slice.call(arguments)}if(!e.length)throw new Error("keys required");var a=Object.keys(r),s=e,c=e.length,u=P(this,"any"),f=P(this,"all");if(u||f||(f=!0),u&&(o=s.filter(function(e){return~a.indexOf(e)}).length>0),f&&(o=e.every(function(e){return~a.indexOf(e)}),P(this,"negate")||P(this,"contains")||(o=o&&e.length==a.length)),c>1){var l=(e=e.map(function(e){return t.inspect(e)})).pop();f&&(n=e.join(", ")+", and "+l),u&&(n=e.join(", ")+", or "+l)}else n=t.inspect(e[0]);n=(c>1?"keys ":"key ")+n,n=(P(this,"contains")?"contain ":"have ")+n,this.assert(o,"expected #{this} to "+n,"expected #{this} to not "+n,s.slice(0).sort(),a.sort(),!0)}function m(e,n,r){r&&P(this,"message",r);var o=P(this,"object");new N(o,r).is.a("function");var i=!1,a=null,s=null,c=null;0===arguments.length?(n=null,e=null):e&&(e instanceof RegExp||"string"==typeof e)?(n=e,e=null):e&&e instanceof Error?(a=e,e=null,n=null):"function"==typeof e?(!(s=e.prototype.name)||"Error"===s&&e!==Error)&&(s=e.name||(new e).name):e=null;try{o()}catch(r){if(a)return this.assert(r===a,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp}",a instanceof Error?a.toString():a,r instanceof Error?r.toString():r),P(this,"object",r),this;if(e&&(this.assert(r instanceof e,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp} but #{act} was thrown",s,r instanceof Error?r.toString():r),!n))return P(this,"object",r),this;var u="error"===t.type(r)&&"message"in r?r.message:""+r;if(null!=u&&n&&n instanceof RegExp)return this.assert(n.exec(u),"expected #{this} to throw error matching #{exp} but got #{act}","expected #{this} to throw error not matching #{exp}",n,u),P(this,"object",r),this;if(null!=u&&n&&"string"==typeof n)return this.assert(~u.indexOf(n),"expected #{this} to throw error including #{exp} but got #{act}","expected #{this} to throw error not including #{act}",n,u),P(this,"object",r),this;i=!0,c=r}var f="",l=null!==s?s:a?"#{exp}":"an error";i&&(f=" but #{act} was thrown"),this.assert(!0===i,"expected #{this} to throw "+l+f,"expected #{this} to not throw "+l+f,a instanceof Error?a.toString():a,c instanceof Error?c.toString():c),P(this,"object",c)}function w(e,n){n&&P(this,"message",n);var r=P(this,"object"),o=P(this,"itself"),i="function"!==t.type(r)||o?r[e]:r.prototype[e];this.assert("function"==typeof i,"expected #{this} to respond to "+t.inspect(e),"expected #{this} to not respond to "+t.inspect(e))}function x(e,n){n&&P(this,"message",n);var r=e(P(this,"object"));this.assert(r,"expected #{this} to satisfy "+t.objDisplay(e),"expected #{this} to not satisfy"+t.objDisplay(e),!this.negate,r)}function j(e,n,r){r&&P(this,"message",r);var o=P(this,"object");if(new N(o,r).is.a("number"),"number"!==t.type(e)||"number"!==t.type(n))throw new Error("the arguments to closeTo or approximately must be numbers");this.assert(Math.abs(o-e)<=n,"expected #{this} to be close to "+e+" +/- "+n,"expected #{this} not to be close to "+e+" +/- "+n)}function E(e,t,n){return e.every(function(e){return n?t.some(function(t){return n(e,t)}):-1!==t.indexOf(e)})}function S(e,t){t&&P(this,"message",t);var n=P(this,"object");new N(e).to.be.an("array"),this.assert(e.indexOf(n)>-1,"expected #{this} to be one of #{exp}","expected #{this} to not be one of #{exp}",e,n)}function _(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(o!==e[t],"expected ."+t+" to change","expected ."+t+" to not change")}function O(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(e[t]-o>0,"expected ."+t+" to increase","expected ."+t+" to not increase")}function A(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(e[t]-o<0,"expected ."+t+" to decrease","expected ."+t+" to not decrease")}var N=e.Assertion,P=(Object.prototype.toString,t.flag);["to","be","been","is","and","has","have","with","that","which","at","of","same"].forEach(function(e){N.addProperty(e,function(){return this})}),N.addProperty("not",function(){P(this,"negate",!0)}),N.addProperty("deep",function(){P(this,"deep",!0)}),N.addProperty("any",function(){P(this,"any",!0),P(this,"all",!1)}),N.addProperty("all",function(){P(this,"all",!0),P(this,"any",!1)}),N.addChainableMethod("an",n),N.addChainableMethod("a",n),N.addChainableMethod("include",o,r),N.addChainableMethod("contain",o,r),N.addChainableMethod("contains",o,r),N.addChainableMethod("includes",o,r),N.addProperty("ok",function(){this.assert(P(this,"object"),"expected #{this} to be truthy","expected #{this} to be falsy")}),N.addProperty("true",function(){this.assert(!0===P(this,"object"),"expected #{this} to be true","expected #{this} to be false",!this.negate)}),N.addProperty("false",function(){this.assert(!1===P(this,"object"),"expected #{this} to be false","expected #{this} to be true",!!this.negate)}),N.addProperty("null",function(){this.assert(null===P(this,"object"),"expected #{this} to be null","expected #{this} not to be null")}),N.addProperty("undefined",function(){this.assert(void 0===P(this,"object"),"expected #{this} to be undefined","expected #{this} not to be undefined")}),N.addProperty("NaN",function(){this.assert(isNaN(P(this,"object")),"expected #{this} to be NaN","expected #{this} not to be NaN")}),N.addProperty("exist",function(){this.assert(null!=P(this,"object"),"expected #{this} to exist","expected #{this} to not exist")}),N.addProperty("empty",function(){var e=P(this,"object"),t=e;Array.isArray(e)||"string"==typeof object?t=e.length:"object"==typeof e&&(t=Object.keys(e).length),this.assert(!t,"expected #{this} to be empty","expected #{this} not to be empty")}),N.addProperty("arguments",i),N.addProperty("Arguments",i),N.addMethod("equal",a),N.addMethod("equals",a),N.addMethod("eq",a),N.addMethod("eql",s),N.addMethod("eqls",s),N.addMethod("above",c),N.addMethod("gt",c),N.addMethod("greaterThan",c),N.addMethod("least",u),N.addMethod("gte",u),N.addMethod("below",f),N.addMethod("lt",f),N.addMethod("lessThan",f),N.addMethod("most",l),N.addMethod("lte",l),N.addMethod("within",function(e,t,n){n&&P(this,"message",n);var r=P(this,"object"),o=e+".."+t;if(P(this,"doLength")){new N(r,n).to.have.property("length");var i=r.length;this.assert(i>=e&&i<=t,"expected #{this} to have a length within "+o,"expected #{this} to not have a length within "+o)}else this.assert(r>=e&&r<=t,"expected #{this} to be within "+o,"expected #{this} to not be within "+o)}),N.addMethod("instanceof",d),N.addMethod("instanceOf",d),N.addMethod("property",function(e,n,r){r&&P(this,"message",r);var o=!!P(this,"deep"),i=o?"deep property ":"property ",a=P(this,"negate"),s=P(this,"object"),c=o?t.getPathInfo(e,s):null,u=o?c.exists:t.hasProperty(e,s),f=o?c.value:s[e];if(a&&arguments.length>1){if(void 0===f)throw r=null!=r?r+": ":"",new Error(r+t.inspect(s)+" has no "+i+t.inspect(e))}else this.assert(u,"expected #{this} to have a "+i+t.inspect(e),"expected #{this} to not have "+i+t.inspect(e));arguments.length>1&&this.assert(n===f,"expected #{this} to have a "+i+t.inspect(e)+" of #{exp}, but got #{act}","expected #{this} to not have a "+i+t.inspect(e)+" of #{act}",n,f),P(this,"object",f)}),N.addMethod("ownProperty",h),N.addMethod("haveOwnProperty",h),N.addMethod("ownPropertyDescriptor",p),N.addMethod("haveOwnPropertyDescriptor",p),N.addChainableMethod("length",y,v),N.addMethod("lengthOf",y),N.addMethod("match",g),N.addMethod("matches",g),N.addMethod("string",function(e,n){n&&P(this,"message",n);var r=P(this,"object");new N(r,n).is.a("string"),this.assert(~r.indexOf(e),"expected #{this} to contain "+t.inspect(e),"expected #{this} to not contain "+t.inspect(e))}),N.addMethod("keys",b),N.addMethod("key",b),N.addMethod("throw",m),N.addMethod("throws",m),N.addMethod("Throw",m),N.addMethod("respondTo",w),N.addMethod("respondsTo",w),N.addProperty("itself",function(){P(this,"itself",!0)}),N.addMethod("satisfy",x),N.addMethod("satisfies",x),N.addMethod("closeTo",j),N.addMethod("approximately",j),N.addMethod("members",function(e,n){n&&P(this,"message",n);var r=P(this,"object");new N(r).to.be.an("array"),new N(e).to.be.an("array");var o=P(this,"deep")?t.eql:void 0;if(P(this,"contains"))return this.assert(E(e,r,o),"expected #{this} to be a superset of #{act}","expected #{this} to not be a superset of #{act}",r,e);this.assert(E(r,e,o)&&E(e,r,o),"expected #{this} to have the same members as #{act}","expected #{this} to not have the same members as #{act}",r,e)}),N.addMethod("oneOf",S),N.addChainableMethod("change",_),N.addChainableMethod("changes",_),N.addChainableMethod("increase",O),N.addChainableMethod("increases",O),N.addChainableMethod("decrease",A),N.addChainableMethod("decreases",A),N.addProperty("extensible",function(){var e,t=P(this,"object");try{e=Object.isExtensible(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!1}this.assert(e,"expected #{this} to be extensible","expected #{this} to not be extensible")}),N.addProperty("sealed",function(){var e,t=P(this,"object");try{e=Object.isSealed(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!0}this.assert(e,"expected #{this} to be sealed","expected #{this} to not be sealed")}),N.addProperty("frozen",function(){var e,t=P(this,"object");try{e=Object.isFrozen(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!0}this.assert(e,"expected #{this} to be frozen","expected #{this} to not be frozen")})}},{}],7:[function(e,t,n){t.exports=function(e,t){var n=e.Assertion,r=t.flag,o=e.assert=function(t,r){new n(null,null,e.assert).assert(t,r,"[ negation message unavailable ]")};o.fail=function(t,n,r,i){throw r=r||"assert.fail()",new e.AssertionError(r,{actual:t,expected:n,operator:i},o.fail)},o.isOk=function(e,t){new n(e,t).is.ok},o.isNotOk=function(e,t){new n(e,t).is.not.ok},o.equal=function(e,t,i){var a=new n(e,i,o.equal);a.assert(t==r(a,"object"),"expected #{this} to equal #{exp}","expected #{this} to not equal #{act}",t,e)},o.notEqual=function(e,t,i){var a=new n(e,i,o.notEqual);a.assert(t!=r(a,"object"),"expected #{this} to not equal #{exp}","expected #{this} to equal #{act}",t,e)},o.strictEqual=function(e,t,r){new n(e,r).to.equal(t)},o.notStrictEqual=function(e,t,r){new n(e,r).to.not.equal(t)},o.deepEqual=function(e,t,r){new n(e,r).to.eql(t)},o.notDeepEqual=function(e,t,r){new n(e,r).to.not.eql(t)},o.isAbove=function(e,t,r){new n(e,r).to.be.above(t)},o.isAtLeast=function(e,t,r){new n(e,r).to.be.least(t)},o.isBelow=function(e,t,r){new n(e,r).to.be.below(t)},o.isAtMost=function(e,t,r){new n(e,r).to.be.most(t)},o.isTrue=function(e,t){new n(e,t).is.true},o.isNotTrue=function(e,t){new n(e,t).to.not.equal(!0)},o.isFalse=function(e,t){new n(e,t).is.false},o.isNotFalse=function(e,t){new n(e,t).to.not.equal(!1)},o.isNull=function(e,t){new n(e,t).to.equal(null)},o.isNotNull=function(e,t){new n(e,t).to.not.equal(null)},o.isNaN=function(e,t){new n(e,t).to.be.NaN},o.isNotNaN=function(e,t){new n(e,t).not.to.be.NaN},o.isUndefined=function(e,t){new n(e,t).to.equal(void 0)},o.isDefined=function(e,t){new n(e,t).to.not.equal(void 0)},o.isFunction=function(e,t){new n(e,t).to.be.a("function")},o.isNotFunction=function(e,t){new n(e,t).to.not.be.a("function")},o.isObject=function(e,t){new n(e,t).to.be.a("object")},o.isNotObject=function(e,t){new n(e,t).to.not.be.a("object")},o.isArray=function(e,t){new n(e,t).to.be.an("array")},o.isNotArray=function(e,t){new n(e,t).to.not.be.an("array")},o.isString=function(e,t){new n(e,t).to.be.a("string")},o.isNotString=function(e,t){new n(e,t).to.not.be.a("string")},o.isNumber=function(e,t){new n(e,t).to.be.a("number")},o.isNotNumber=function(e,t){new n(e,t).to.not.be.a("number")},o.isBoolean=function(e,t){new n(e,t).to.be.a("boolean")},o.isNotBoolean=function(e,t){new n(e,t).to.not.be.a("boolean")},o.typeOf=function(e,t,r){new n(e,r).to.be.a(t)},o.notTypeOf=function(e,t,r){new n(e,r).to.not.be.a(t)},o.instanceOf=function(e,t,r){new n(e,r).to.be.instanceOf(t)},o.notInstanceOf=function(e,t,r){new n(e,r).to.not.be.instanceOf(t)},o.include=function(e,t,r){new n(e,r,o.include).include(t)},o.notInclude=function(e,t,r){new n(e,r,o.notInclude).not.include(t)},o.match=function(e,t,r){new n(e,r).to.match(t)},o.notMatch=function(e,t,r){new n(e,r).to.not.match(t)},o.property=function(e,t,r){new n(e,r).to.have.property(t)},o.notProperty=function(e,t,r){new n(e,r).to.not.have.property(t)},o.deepProperty=function(e,t,r){new n(e,r).to.have.deep.property(t)},o.notDeepProperty=function(e,t,r){new n(e,r).to.not.have.deep.property(t)},o.propertyVal=function(e,t,r,o){new n(e,o).to.have.property(t,r)},o.propertyNotVal=function(e,t,r,o){new n(e,o).to.not.have.property(t,r)},o.deepPropertyVal=function(e,t,r,o){new n(e,o).to.have.deep.property(t,r)},o.deepPropertyNotVal=function(e,t,r,o){new n(e,o).to.not.have.deep.property(t,r)},o.lengthOf=function(e,t,r){new n(e,r).to.have.length(t)},o.throws=function(e,t,o,i){("string"==typeof t||t instanceof RegExp)&&(o=t,t=null);var a=new n(e,i).to.throw(t,o);return r(a,"object")},o.doesNotThrow=function(e,t,r){"string"==typeof t&&(r=t,t=null),new n(e,r).to.not.Throw(t)},o.operator=function(e,o,i,a){var s;switch(o){case"==":s=e==i;break;case"===":s=e===i;break;case">":s=e>i;break;case">=":s=e>=i;break;case"<":s=e1&&n===t.length-1?"or ":"")+r+" "+e}).join(", ");if(!t.some(function(t){return i(e)===t}))throw new r("object tested must be "+n+", but "+i(e)+" given")}},{"./flag":14,"assertion-error":1,"type-detect":40}],14:[function(e,t,n){t.exports=function(e,t,n){var r=e.__flags||(e.__flags=Object.create(null));if(3!==arguments.length)return r[t];r[t]=n}},{}],15:[function(e,t,n){t.exports=function(e,t){return t.length>4?t[4]:e._obj}},{}],16:[function(e,t,n){t.exports=function(e){var t=[];for(var n in e)t.push(n);return t}},{}],17:[function(e,t,n){var r=e("./flag"),o=e("./getActual"),i=(e("./inspect"),e("./objDisplay"));t.exports=function(e,t){var n=r(e,"negate"),a=r(e,"object"),s=t[3],c=o(e,t),u=n?t[2]:t[1],f=r(e,"message");return"function"==typeof u&&(u=u()),u=u||"",u=u.replace(/#\{this\}/g,function(){return i(a)}).replace(/#\{act\}/g,function(){return i(c)}).replace(/#\{exp\}/g,function(){return i(s)}),f?f+": "+u:u}},{"./flag":14,"./getActual":15,"./inspect":24,"./objDisplay":25}],18:[function(e,t,n){t.exports=function(e){if(e.name)return e.name;var t=/^\s?function ([^(]*)\(/.exec(e);return t&&t[1]?t[1]:""}},{}],19:[function(e,t,n){function r(e){return e.replace(/([^\\])\[/g,"$1.[").match(/(\\\.|[^.]+?)+/g).map(function(e){var t=/^\[(\d+)\]$/.exec(e);return t?{i:parseFloat(t[1])}:{p:e.replace(/\\([.\[\]])/g,"$1")}})}function o(e,t,n){for(var r,o=t,i=0,a=n=void 0===n?e.length:n;i1?o(n,t,n.length-1):t,name:a.p||a.i,value:o(n,t)};return s.exists=i(s.name,s.parent),s}},{"./hasProperty":22}],20:[function(e,t,n){var r=e("./getPathInfo");t.exports=function(e,t){return r(e,t).value}},{"./getPathInfo":19}],21:[function(e,t,n){t.exports=function(e){function t(e){-1===n.indexOf(e)&&n.push(e)}for(var n=Object.getOwnPropertyNames(e),r=Object.getPrototypeOf(e);null!==r;)Object.getOwnPropertyNames(r).forEach(t),r=Object.getPrototypeOf(r);return n}},{}],22:[function(e,t,n){var r=e("type-detect"),o={number:Number,string:String};t.exports=function(e,t){var n=r(t);return"null"!==n&&"undefined"!==n&&(o[n]&&"object"!=typeof t&&(t=new o[n](t)),e in t)}},{"type-detect":40}],23:[function(e,t,n){(n=t.exports={}).test=e("./test"),n.type=e("type-detect"),n.expectTypes=e("./expectTypes"),n.getMessage=e("./getMessage"),n.getActual=e("./getActual"),n.inspect=e("./inspect"),n.objDisplay=e("./objDisplay"),n.flag=e("./flag"),n.transferFlags=e("./transferFlags"),n.eql=e("deep-eql"),n.getPathValue=e("./getPathValue"),n.getPathInfo=e("./getPathInfo"),n.hasProperty=e("./hasProperty"),n.getName=e("./getName"),n.addProperty=e("./addProperty"),n.addMethod=e("./addMethod"),n.overwriteProperty=e("./overwriteProperty"),n.overwriteMethod=e("./overwriteMethod"),n.addChainableMethod=e("./addChainableMethod"),n.overwriteChainableMethod=e("./overwriteChainableMethod")},{"./addChainableMethod":10,"./addMethod":11,"./addProperty":12,"./expectTypes":13,"./flag":14,"./getActual":15,"./getMessage":17,"./getName":18,"./getPathInfo":19,"./getPathValue":20,"./hasProperty":22,"./inspect":24,"./objDisplay":25,"./overwriteChainableMethod":26,"./overwriteMethod":27,"./overwriteProperty":28,"./test":29,"./transferFlags":30,"deep-eql":32,"type-detect":40}],24:[function(e,t,n){function r(e,t,n,r){return o({showHidden:t,seen:[],stylize:function(e){return e}},e,void 0===n?2:n)}function o(e,t,r){if(t&&"function"==typeof t.inspect&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var p=t.inspect(r);return"string"!=typeof p&&(p=o(e,p,r)),p}var m=i(e,t);if(m)return m;if(b(t)){if("outerHTML"in t)return t.outerHTML;try{if(document.xmlVersion)return(new XMLSerializer).serializeToString(t);var w=document.createElementNS("http://www.w3.org/1999/xhtml","_");return w.appendChild(t.cloneNode(!1)),html=w.innerHTML.replace("><",">"+t.innerHTML+"<"),w.innerHTML="",html}catch(e){}}var x=g(t),j=e.showHidden?y(t):x;if(0===j.length||h(t)&&(1===j.length&&"stack"===j[0]||2===j.length&&"description"===j[0]&&"stack"===j[1])){if("function"==typeof t){var E=(A=v(t))?": "+A:"";return e.stylize("[Function"+E+"]","special")}if(l(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(d(t))return e.stylize(Date.prototype.toUTCString.call(t),"date");if(h(t))return a(t)}var S="",_=!1,O=["{","}"];if(f(t)&&(_=!0,O=["[","]"]),"function"==typeof t){var A=v(t);S=" [Function"+(E=A?": "+A:"")+"]"}if(l(t)&&(S=" "+RegExp.prototype.toString.call(t)),d(t)&&(S=" "+Date.prototype.toUTCString.call(t)),h(t))return a(t);if(0===j.length&&(!_||0==t.length))return O[0]+S+O[1];if(r<0)return l(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var N;return N=_?s(e,t,r,x,j):j.map(function(n){return c(e,t,r,x,n,_)}),e.seen.pop(),u(N,S,O)}function i(e,t){switch(typeof t){case"undefined":return e.stylize("undefined","undefined");case"string":var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string");case"number":return 0===t&&1/t==-1/0?e.stylize("-0","number"):e.stylize(""+t,"number");case"boolean":return e.stylize(""+t,"boolean")}if(null===t)return e.stylize("null","null")}function a(e){return"["+Error.prototype.toString.call(e)+"]"}function s(e,t,n,r,o){for(var i=[],a=0,s=t.length;a-1&&(c=a?c.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+c.split("\n").map(function(e){return" "+e}).join("\n")):c=e.stylize("[Circular]","special")),void 0===s){if(a&&i.match(/^\d+$/))return c;(s=JSON.stringify(""+i)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(s=s.substr(1,s.length-2),s=e.stylize(s,"name")):(s=s.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),s=e.stylize(s,"string"))}return s+": "+c}function u(e,t,n){var r=0;return e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.length+1},0)>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function f(e){return Array.isArray(e)||"object"==typeof e&&"[object Array]"===p(e)}function l(e){return"object"==typeof e&&"[object RegExp]"===p(e)}function d(e){return"object"==typeof e&&"[object Date]"===p(e)}function h(e){return"object"==typeof e&&"[object Error]"===p(e)}function p(e){return Object.prototype.toString.call(e)}var v=e("./getName"),y=e("./getProperties"),g=e("./getEnumerableProperties");t.exports=r;var b=function(e){return"object"==typeof HTMLElement?e instanceof HTMLElement:e&&"object"==typeof e&&1===e.nodeType&&"string"==typeof e.nodeName}},{"./getEnumerableProperties":16,"./getName":18,"./getProperties":21}],25:[function(e,t,n){var r=e("./inspect"),o=e("../config");t.exports=function(e){var t=r(e),n=Object.prototype.toString.call(e);if(o.truncateThreshold&&t.length>=o.truncateThreshold){if("[object Function]"===n)return e.name&&""!==e.name?"[Function: "+e.name+"]":"[Function]";if("[object Array]"===n)return"[ Array("+e.length+") ]";if("[object Object]"===n){var i=Object.keys(e);return"{ Object ("+(i.length>2?i.splice(0,2).join(", ")+", ...":i.join(", "))+") }"}return t}return t}},{"../config":5,"./inspect":24}],26:[function(e,t,n){t.exports=function(e,t,n,r){var o=e.__methods[t],i=o.chainingBehavior;o.chainingBehavior=function(){var e=r(i).call(this);return void 0===e?this:e};var a=o.method;o.method=function(){var e=n(a).apply(this,arguments);return void 0===e?this:e}}},{}],27:[function(e,t,n){t.exports=function(e,t,n){var r=e[t],o=function(){return this};r&&"function"==typeof r&&(o=r),e[t]=function(){var e=n(o).apply(this,arguments);return void 0===e?this:e}}},{}],28:[function(e,t,n){t.exports=function(e,t,n){var r=Object.getOwnPropertyDescriptor(e,t),o=function(){};r&&"function"==typeof r.get&&(o=r.get),Object.defineProperty(e,t,{get:function(){var e=n(o).call(this);return void 0===e?this:e},configurable:!0})}},{}],29:[function(e,t,n){var r=e("./flag");t.exports=function(e,t){var n=r(e,"negate"),o=t[0];return n?!o:o}},{"./flag":14}],30:[function(e,t,n){t.exports=function(e,t,n){var r=e.__flags||(e.__flags=Object.create(null));t.__flags||(t.__flags=Object.create(null)),n=3!==arguments.length||n;for(var o in r)(n||"object"!==o&&"ssfi"!==o&&"message"!=o)&&(t.__flags[o]=r[o])}},{}],31:[function(e,t,n){"use strict";function r(e){var t=void 0;t="string"==typeof e?[e]:e.raw;for(var n="",r=0;r=0;o--)if(s=i[o],!r(e[s],t[s],n))return!1;return!0}var p,v=e("type-detect");try{p=e("buffer").Buffer}catch(e){(p={}).isBuffer=function(){return!1}}t.exports=r},{buffer:void 0,"type-detect":38}],34:[function(e,t,n){(function(r){!function(e){if("object"==typeof n&&void 0!==t)t.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:void 0!==r?r:"undefined"!=typeof self?self:this).localforage=e()}}(function(){return function t(n,r,o){function i(s,c){if(!r[s]){if(!n[s]){var u="function"==typeof e&&e;if(!c&&u)return u(s,!0);if(a)return a(s,!0);var f=new Error("Cannot find module '"+s+"'");throw f.code="MODULE_NOT_FOUND",f}var l=r[s]={exports:{}};n[s][0].call(l.exports,function(e){var t=n[s][1][e];return i(t||e)},l,l.exports,t,n,r,o)}return r[s].exports}for(var a="function"==typeof e&&e,s=0;s=43)}}).catch(function(){return!1})}function u(e){return"boolean"==typeof re?ie.resolve(re):c(e).then(function(e){return re=e})}function f(e){var t=oe[e.name],n={};n.promise=new ie(function(e){n.resolve=e}),t.deferredOperations.push(n),t.dbReady?t.dbReady=t.dbReady.then(function(){return n.promise}):t.dbReady=n.promise}function l(e){var t=oe[e.name].deferredOperations.pop();t&&t.resolve()}function d(e,t){return new ie(function(n,r){if(e.db){if(!t)return n(e.db);f(e),e.db.close()}var o=[e.name];t&&o.push(e.version);var i=ne.open.apply(ne,o);t&&(i.onupgradeneeded=function(t){var n=i.result;try{n.createObjectStore(e.storeName),t.oldVersion<=1&&n.createObjectStore(ae)}catch(n){if("ConstraintError"!==n.name)throw n;console.warn('The database "'+e.name+'" has been upgraded from version '+t.oldVersion+" to version "+t.newVersion+', but the storage "'+e.storeName+'" already exists.')}}),i.onerror=function(e){e.preventDefault(),r(i.error)},i.onsuccess=function(){n(i.result),l(e)}})}function h(e){return d(e,!1)}function p(e){return d(e,!0)}function v(e,t){if(!e.db)return!0;var n=!e.db.objectStoreNames.contains(e.storeName),r=e.versione.db.version;if(r&&(e.version!==t&&console.warn('The database "'+e.name+"\" can't be downgraded from version "+e.db.version+" to version "+e.version+"."),e.version=e.db.version),o||n){if(n){var i=e.db.version+1;i>e.version&&(e.version=i)}return!0}return!1}function y(e){return new ie(function(t,n){var r=new FileReader;r.onerror=n,r.onloadend=function(n){var r=btoa(n.target.result||"");t({__local_forage_encoded_blob:!0,data:r,type:e.type})},r.readAsBinaryString(e)})}function g(e){return o([s(atob(e.data))],{type:e.type})}function b(e){return e&&e.__local_forage_encoded_blob}function m(e){var t=this,n=t._initReady().then(function(){var e=oe[t._dbInfo.name];if(e&&e.dbReady)return e.dbReady});return a(n,e,e),n}function w(e){function t(){return ie.resolve()}var n=this,r={db:null};if(e)for(var o in e)r[o]=e[o];oe||(oe={});var i=oe[r.name];i||(i={forages:[],db:null,dbReady:null,deferredOperations:[]},oe[r.name]=i),i.forages.push(n),n._initReady||(n._initReady=n.ready,n.ready=m);for(var a=[],s=0;s>4,f[c++]=(15&r)<<4|o>>2,f[c++]=(3&o)<<6|63&i;return u}function M(e){var t,n=new Uint8Array(e),r="";for(t=0;t>2],r+=ue[(3&n[t])<<4|n[t+1]>>4],r+=ue[(15&n[t+1])<<2|n[t+2]>>6],r+=ue[63&n[t+2]];return n.length%3==2?r=r.substring(0,r.length-1)+"=":n.length%3==1&&(r=r.substring(0,r.length-2)+"=="),r}function I(e,t){var n="";if(e&&(n=Oe.call(e)),e&&("[object ArrayBuffer]"===n||e.buffer&&"[object ArrayBuffer]"===Oe.call(e.buffer))){var r,o=de;e instanceof ArrayBuffer?(r=e,o+=pe):(r=e.buffer,"[object Int8Array]"===n?o+=ye:"[object Uint8Array]"===n?o+=ge:"[object Uint8ClampedArray]"===n?o+=be:"[object Int16Array]"===n?o+=me:"[object Uint16Array]"===n?o+=xe:"[object Int32Array]"===n?o+=we:"[object Uint32Array]"===n?o+=je:"[object Float32Array]"===n?o+=Ee:"[object Float64Array]"===n?o+=Se:t(new Error("Failed to get type for BinaryArray"))),t(o+M(r))}else if("[object Blob]"===n){var i=new FileReader;i.onload=function(){var n=fe+e.type+"~"+M(this.result);t(de+ve+n)},i.readAsArrayBuffer(e)}else try{t(JSON.stringify(e))}catch(n){console.error("Couldn't convert value into a JSON string: ",e),t(null,n)}}function k(e){if(e.substring(0,he)!==de)return JSON.parse(e);var t,n=e.substring(_e),r=e.substring(he,_e);if(r===ve&&le.test(n)){var i=n.match(le);t=i[1],n=n.substring(i[0].length)}var a=P(n);switch(r){case pe:return a;case ve:return o([a],{type:t});case ye:return new Int8Array(a);case ge:return new Uint8Array(a);case be:return new Uint8ClampedArray(a);case me:return new Int16Array(a);case xe:return new Uint16Array(a);case we:return new Int32Array(a);case je:return new Uint32Array(a);case Ee:return new Float32Array(a);case Se:return new Float64Array(a);default:throw new Error("Unkown type: "+r)}}function T(e){var t=this,n={db:null};if(e)for(var r in e)n[r]="string"!=typeof e[r]?e[r].toString():e[r];var o=new ie(function(e,r){try{n.db=openDatabase(n.name,String(n.version),n.description,n.size)}catch(e){return r(e)}n.db.transaction(function(o){o.executeSql("CREATE TABLE IF NOT EXISTS "+n.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){t._dbInfo=n,e()},function(e,t){r(t)})})});return n.serializer=Ae,o}function C(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT * FROM "+o.storeName+" WHERE key = ? LIMIT 1",[e],function(e,n){var r=n.rows.length?n.rows.item(0).value:null;r&&(r=o.serializer.deserialize(r)),t(r)},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function D(e,t){var n=this,r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT * FROM "+o.storeName,[],function(n,r){for(var i=r.rows,a=i.length,s=0;s0)return void i(L.apply(o,[e,s,n,r-1]));a(t)}})})}).catch(a)});return i(a,n),a}function R(e,t,n){return L.apply(this,[e,t,n,1])}function B(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("DELETE FROM "+o.storeName+" WHERE key = ?",[e],function(){t()},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function q(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("DELETE FROM "+r.storeName,[],function(){e()},function(e,t){n(t)})})}).catch(n)});return i(n,e),n}function z(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("SELECT COUNT(key) as c FROM "+r.storeName,[],function(t,n){var r=n.rows.item(0).c;e(r)},function(e,t){n(t)})})}).catch(n)});return i(n,e),n}function F(e,t){var n=this,r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT key FROM "+o.storeName+" WHERE id = ? LIMIT 1",[e+1],function(e,n){var r=n.rows.length?n.rows.item(0).key:null;t(r)},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function U(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("SELECT key FROM "+r.storeName,[],function(t,n){for(var r=[],o=0;o=0;n--){var r=localStorage.key(n);0===r.indexOf(e)&&localStorage.removeItem(r)}});return i(n,e),n}function J(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=n.ready().then(function(){var t=n._dbInfo,r=localStorage.getItem(t.keyPrefix+e);return r&&(r=t.serializer.deserialize(r)),r});return i(r,t),r}function G(e,t){var n=this,r=n.ready().then(function(){for(var t=n._dbInfo,r=t.keyPrefix,o=r.length,i=localStorage.length,a=1,s=0;s num > 5);\n return overFive;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, [8, 13, 21]) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 3 items",test:`assert.lengthOf(output, 3) === undefined;`},{name:`First item is 8`,test:`assert.deepEqual(output[0], 8) === undefined;`}]},{name:"Array.map()",time:10,prompt:`Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,given:`const numbers = [25, 121, 169];\r`,answer:`const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, [5, 11, 13]) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 3 items",test:`assert.lengthOf(output, 3) === undefined;`},{name:`First item is 5`,test:`assert.deepEqual(output[0], 5) === undefined;`},{name:`Last item is 13`,test:`assert.deepEqual(output[output.length - 1], 13) === undefined;`}]},{name:"Array.every()",time:10,prompt:`Return object that returns whether each array contains all even numbers using Array.every().`,given:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,answer:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n return element % 2 === 0\n }\n return {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n };`,tests:[{name:"Correct output",test:`assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;`},{name:"Returns an Object",test:`assert.isObject(output) === undefined;`},{name:"Object has 2 items",test:`assert.lengthOf(Object.keys(output), 2) === undefined;`},{name:`First value is true`,test:`assert.isTrue(output.evenNumbers) === undefined;`},{name:`Second value is false`,test:`assert.isFalse(output.someOddNumbers) === undefined;`}]},{name:"Array.some()",time:10,prompt:`Return 'Object' that returns whether each array contains some odd numbers using 'Array.some()'.`,given:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 4, 7, 8];\n function isOdd(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,answer:`const evenNumbers = [1, 3, 5, 7];\n const someOddNumbers = [1, 3, 6, 7];\n function isOdd(element) {\n return element % 2 !== 0;\n }\n return {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n };`,tests:[{name:"Correct output",test:`assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;`},{name:"Returns an Object",test:`assert.isObject(output) === undefined;`},{name:"Object has 2 items",test:`assert.lengthOf(Object.keys(output), 2) === undefined;`},{name:`First value is false`,test:`assert.isFalse(output.evenNumbers) === undefined;`},{name:`Second value is true`,test:`assert.isTrue(output.someOddNumbers) === undefined;`}]}]},{}],37:[function(e,t,n){t.exports=[{name:"Create Array",time:10,prompt:"Create and return an array that contains 'apple' and 'banana'",given:`const fruits = [];\rreturn fruits;`,answer:`const fruits = ['apple', 'banana'];\n return fruits;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, ['apple', 'banana']) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 2 items",test:`assert.lengthOf(output, 2) === undefined;`}]},{name:"Array.pop()",time:10,prompt:`Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,given:`const fruits = ['apple', 'banana', 'orange'];\r`,answer:`const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, ['apple', 'banana']) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 2 items",test:`assert.lengthOf(output, 2) === undefined;`}]}]},{}],38:[function(e,t,n){t.exports=e("./lib/type")},{"./lib/type":39}],39:[function(e,t,n){function r(e){var t=Object.prototype.toString.call(e);return i[t]?i[t]:null===e?"null":void 0===e?"undefined":e===Object(e)?"object":typeof e}function o(){this.tests={}}var i={"[object Array]":"array","[object RegExp]":"regexp","[object Function]":"function","[object Arguments]":"arguments","[object Date]":"date"};(t.exports=r).Library=o,o.prototype.of=r,o.prototype.define=function(e,t){return 1===arguments.length?this.tests[e]:(this.tests[e]=t,this)},o.prototype.test=function(e,t){if(t===r(e))return!0;var n=this.tests[t];if(n&&"regexp"===r(n))return n.test(e);if(n&&"function"===r(n))return n(e);throw new ReferenceError('Type test "'+t+'" not defined or invalid.')}},{}],40:[function(e,t,n){arguments[4][38][0].apply(n,arguments)},{"./lib/type":41,dup:38}],41:[function(e,t,n){function r(e){var t=Object.prototype.toString.call(e).match(i)[1].toLowerCase();return"function"==typeof Promise&&e instanceof Promise?"promise":null===e?"null":void 0===e?"undefined":t}function o(){if(!(this instanceof o))return new o;this.tests={}}var i=/^\[object (.*)\]$/;(t.exports=r).Library=o,o.prototype.of=r,o.prototype.define=function(e,t){return 1===arguments.length?this.tests[e]:(this.tests[e]=t,this)},o.prototype.test=function(e,t){if(t===r(e))return!0;var n=this.tests[t];if(n&&"regexp"===r(n))return n.test(e);if(n&&"function"===r(n))return n(e);throw new ReferenceError('Type test "'+t+'" not defined or invalid.')}},{}],42:[function(require,module,exports){"use strict";function _toConsumableArray(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t=e.length-1||t<0?0:t+1}function getCurrentProblem(e){return e[config.currentIndex]}function previousProblem(){console.log("previousProblem!"),previousProblemButtonEl.classList.add("active"),config.currentIndex=config.shuffle?getRandomIndex(problems):getPreviousIndex(problems),updateLocalstore(config).then(function(){window.location.reload()})}function nextProblem(){console.log("nextProblem!"),nextProblemButtonEl.classList.add("active"),config.currentIndex=config.shuffle?getRandomIndex(problems):getNextIndex(problems),updateLocalstore(config).then(function(){window.location.reload()})}function toggleShuffle(){console.log("toggle shuffle!"),config.shuffle=!config.shuffle,shuffleProblemsButtonEl.classList.toggle("active"),previousProblemButtonEl.parentNode.classList.toggle("hidden"),updateLocalstore(config)}function loadProblem(e){currentProblem=e,problemEl.innerText=e.prompt,e.given&&(codeEl.value=e.given),testSuite(null,!0)}function updateTests(e,t){!0===t&&buildTests(currentProblem.tests),updateTestStatus(e)}function buildTests(e){if(e){var t=e.map(function(e){return'
\n
[✘]
\n
'+e.name+"
\n
"}).join("");testSuiteEl.innerHTML=t}}function updateTestStatus(e){if(!e)throw new Error("No testStatuses provided.");var t=!0;e.forEach(function(e){!0!==e&&(t=!1)}),[].slice.call(testSuiteEl.querySelectorAll(".test-state")).forEach(function(t,n){!0===e[n]?(t.innerHTML="[✓]",t.classList.remove("fail"),t.classList.add("pass")):(t.innerHTML="[✘]",t.classList.remove("pass"),t.classList.add("fail"))}),!0===t?(testTotalEl.innerText="PASS",testTotalEl.classList.remove("fail"),testTotalEl.classList.add("pass")):(testTotalEl.innerText="FAIL",testTotalEl.classList.remove("pass"),testTotalEl.classList.add("fail"))}function printAssertError(e){var t="";null!==e&&(t='\n
\n Expected: '+JSON.stringify(e.expected)+"\n Actual: "+JSON.stringify(e.actual)+"\n
"),assertConsoleEl.innerHTML=t}function printEvalOutput(e,t){var n="";e&&void 0!==e.message?n='\n
\n Syntax Error: '+JSON.stringify(e.message)+"\n
":t&&(n='\n
\n Output: '+JSON.stringify(t)+"\n
"),evalConsoleEl.innerHTML=n}function testSuite(e){testTotalEl.classList.toggle("working");var t=runTests(getOutput(codeEl.value));testTotalEl.classList.toggle("working"),updateTests(t,e)}function getOutput(code){var evald=!1;try{evald=eval("(function(){"+code+"})()"),printEvalOutput(null,evald)}catch(e){printEvalOutput(e)}return evald}function runTests(output){var tested=!1;return tested=currentProblem.tests.map(function(test){var testOutcome=!1;try{output&&(testOutcome=eval(test.test),console.log("testOutcome:",testOutcome)),printAssertError(null)}catch(e){printAssertError(e)}return testOutcome})}function loadApp(e){function t(t){!1===e.shuffle&&13===t.keyCode&&t.shiftKey&&(t.metaKey||t.ctrlKey)?previousProblem():13!==t.keyCode||t.shiftKey||!t.metaKey&&!t.ctrlKey||nextProblem()}console.log("loading app!"),!0===e.shuffle&&(shuffleProblemsButtonEl.classList.add("active"),previousProblemButtonEl.parentNode.classList.add("hidden"));var n=debounce(function(e){-1===ignoreKeyCodes.indexOf(e.keyCode)&&testSuite()},200);codeEl.addEventListener("keydown",n),document.addEventListener("keydown",t),shuffleProblemsButtonEl.addEventListener("click",toggleShuffle),previousProblemButtonEl.addEventListener("click",previousProblem),nextProblemButtonEl.addEventListener("click",nextProblem),loadProblem(getCurrentProblem(problems)),testSuite(!0)}var localforage=require("localforage"),probs=require("pjs-problems"),dedent=require("dedent"),assert=require("chai").assert,problems=[];Object.keys(probs).forEach(function(e){var t;(t=problems).push.apply(t,_toConsumableArray(probs[e]))}),problems=dedentStrings(problems);var currentProblem=void 0,ignoreKeyCodes=[9,37,39,38,40],config={shuffle:!0,timer:!1,currentIndex:0};localforage.getItem("js_practice_config").then(function(e){e&&(config=e),loadApp(config)}).catch(function(e){console.log("localforage err:",e),loadApp(config)});var problemEl=document.getElementById("problem"),codeEl=document.getElementById("code"),testSuiteEl=document.getElementById("test-suite"),testTotalEl=document.getElementById("test-total"),evalConsoleEl=document.getElementById("eval-output"),assertConsoleEl=document.getElementById("assert-output"),shuffleProblemsButtonEl=document.getElementById("shuffle-problems"),previousProblemButtonEl=document.getElementById("prev-problem"),nextProblemButtonEl=document.getElementById("next-problem")}(document,window)},{chai:2,dedent:31,localforage:34,"pjs-problems":35}]},{},[42]); +!function e(t,n,r){function o(a,s){if(!n[a]){if(!t[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(i)return i(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var f=n[a]={exports:{}};t[a][0].call(f.exports,function(e){var n=t[a][1][e];return o(n||e)},f,f.exports,e,t,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;ae,"expected #{this} to have a length above #{exp} but got #{act}","expected #{this} to not have a length above #{exp}",e,r)}else this.assert(n>e,"expected #{this} to be above "+e,"expected #{this} to be at most "+e)}function u(e,t){t&&P(this,"message",t);var n=P(this,"object");if(P(this,"doLength")){new N(n,t).to.have.property("length");var r=n.length;this.assert(r>=e,"expected #{this} to have a length at least #{exp} but got #{act}","expected #{this} to have a length below #{exp}",e,r)}else this.assert(n>=e,"expected #{this} to be at least "+e,"expected #{this} to be below "+e)}function f(e,t){t&&P(this,"message",t);var n=P(this,"object");if(P(this,"doLength")){new N(n,t).to.have.property("length");var r=n.length;this.assert(r1)throw new Error(i);break;case"object":if(arguments.length>1)throw new Error(i);e=Object.keys(e);break;default:e=Array.prototype.slice.call(arguments)}if(!e.length)throw new Error("keys required");var a=Object.keys(r),s=e,c=e.length,u=P(this,"any"),f=P(this,"all");if(u||f||(f=!0),u&&(o=s.filter(function(e){return~a.indexOf(e)}).length>0),f&&(o=e.every(function(e){return~a.indexOf(e)}),P(this,"negate")||P(this,"contains")||(o=o&&e.length==a.length)),c>1){var l=(e=e.map(function(e){return t.inspect(e)})).pop();f&&(n=e.join(", ")+", and "+l),u&&(n=e.join(", ")+", or "+l)}else n=t.inspect(e[0]);n=(c>1?"keys ":"key ")+n,n=(P(this,"contains")?"contain ":"have ")+n,this.assert(o,"expected #{this} to "+n,"expected #{this} to not "+n,s.slice(0).sort(),a.sort(),!0)}function m(e,n,r){r&&P(this,"message",r);var o=P(this,"object");new N(o,r).is.a("function");var i=!1,a=null,s=null,c=null;0===arguments.length?(n=null,e=null):e&&(e instanceof RegExp||"string"==typeof e)?(n=e,e=null):e&&e instanceof Error?(a=e,e=null,n=null):"function"==typeof e?(!(s=e.prototype.name)||"Error"===s&&e!==Error)&&(s=e.name||(new e).name):e=null;try{o()}catch(r){if(a)return this.assert(r===a,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp}",a instanceof Error?a.toString():a,r instanceof Error?r.toString():r),P(this,"object",r),this;if(e&&(this.assert(r instanceof e,"expected #{this} to throw #{exp} but #{act} was thrown","expected #{this} to not throw #{exp} but #{act} was thrown",s,r instanceof Error?r.toString():r),!n))return P(this,"object",r),this;var u="error"===t.type(r)&&"message"in r?r.message:""+r;if(null!=u&&n&&n instanceof RegExp)return this.assert(n.exec(u),"expected #{this} to throw error matching #{exp} but got #{act}","expected #{this} to throw error not matching #{exp}",n,u),P(this,"object",r),this;if(null!=u&&n&&"string"==typeof n)return this.assert(~u.indexOf(n),"expected #{this} to throw error including #{exp} but got #{act}","expected #{this} to throw error not including #{act}",n,u),P(this,"object",r),this;i=!0,c=r}var f="",l=null!==s?s:a?"#{exp}":"an error";i&&(f=" but #{act} was thrown"),this.assert(!0===i,"expected #{this} to throw "+l+f,"expected #{this} to not throw "+l+f,a instanceof Error?a.toString():a,c instanceof Error?c.toString():c),P(this,"object",c)}function w(e,n){n&&P(this,"message",n);var r=P(this,"object"),o=P(this,"itself"),i="function"!==t.type(r)||o?r[e]:r.prototype[e];this.assert("function"==typeof i,"expected #{this} to respond to "+t.inspect(e),"expected #{this} to not respond to "+t.inspect(e))}function x(e,n){n&&P(this,"message",n);var r=e(P(this,"object"));this.assert(r,"expected #{this} to satisfy "+t.objDisplay(e),"expected #{this} to not satisfy"+t.objDisplay(e),!this.negate,r)}function j(e,n,r){r&&P(this,"message",r);var o=P(this,"object");if(new N(o,r).is.a("number"),"number"!==t.type(e)||"number"!==t.type(n))throw new Error("the arguments to closeTo or approximately must be numbers");this.assert(Math.abs(o-e)<=n,"expected #{this} to be close to "+e+" +/- "+n,"expected #{this} not to be close to "+e+" +/- "+n)}function E(e,t,n){return e.every(function(e){return n?t.some(function(t){return n(e,t)}):-1!==t.indexOf(e)})}function S(e,t){t&&P(this,"message",t);var n=P(this,"object");new N(e).to.be.an("array"),this.assert(e.indexOf(n)>-1,"expected #{this} to be one of #{exp}","expected #{this} to not be one of #{exp}",e,n)}function _(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(o!==e[t],"expected ."+t+" to change","expected ."+t+" to not change")}function O(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(e[t]-o>0,"expected ."+t+" to increase","expected ."+t+" to not increase")}function A(e,t,n){n&&P(this,"message",n);var r=P(this,"object");new N(e,n).to.have.property(t),new N(r).is.a("function");var o=e[t];r(),this.assert(e[t]-o<0,"expected ."+t+" to decrease","expected ."+t+" to not decrease")}var N=e.Assertion,P=(Object.prototype.toString,t.flag);["to","be","been","is","and","has","have","with","that","which","at","of","same"].forEach(function(e){N.addProperty(e,function(){return this})}),N.addProperty("not",function(){P(this,"negate",!0)}),N.addProperty("deep",function(){P(this,"deep",!0)}),N.addProperty("any",function(){P(this,"any",!0),P(this,"all",!1)}),N.addProperty("all",function(){P(this,"all",!0),P(this,"any",!1)}),N.addChainableMethod("an",n),N.addChainableMethod("a",n),N.addChainableMethod("include",o,r),N.addChainableMethod("contain",o,r),N.addChainableMethod("contains",o,r),N.addChainableMethod("includes",o,r),N.addProperty("ok",function(){this.assert(P(this,"object"),"expected #{this} to be truthy","expected #{this} to be falsy")}),N.addProperty("true",function(){this.assert(!0===P(this,"object"),"expected #{this} to be true","expected #{this} to be false",!this.negate)}),N.addProperty("false",function(){this.assert(!1===P(this,"object"),"expected #{this} to be false","expected #{this} to be true",!!this.negate)}),N.addProperty("null",function(){this.assert(null===P(this,"object"),"expected #{this} to be null","expected #{this} not to be null")}),N.addProperty("undefined",function(){this.assert(void 0===P(this,"object"),"expected #{this} to be undefined","expected #{this} not to be undefined")}),N.addProperty("NaN",function(){this.assert(isNaN(P(this,"object")),"expected #{this} to be NaN","expected #{this} not to be NaN")}),N.addProperty("exist",function(){this.assert(null!=P(this,"object"),"expected #{this} to exist","expected #{this} to not exist")}),N.addProperty("empty",function(){var e=P(this,"object"),t=e;Array.isArray(e)||"string"==typeof object?t=e.length:"object"==typeof e&&(t=Object.keys(e).length),this.assert(!t,"expected #{this} to be empty","expected #{this} not to be empty")}),N.addProperty("arguments",i),N.addProperty("Arguments",i),N.addMethod("equal",a),N.addMethod("equals",a),N.addMethod("eq",a),N.addMethod("eql",s),N.addMethod("eqls",s),N.addMethod("above",c),N.addMethod("gt",c),N.addMethod("greaterThan",c),N.addMethod("least",u),N.addMethod("gte",u),N.addMethod("below",f),N.addMethod("lt",f),N.addMethod("lessThan",f),N.addMethod("most",l),N.addMethod("lte",l),N.addMethod("within",function(e,t,n){n&&P(this,"message",n);var r=P(this,"object"),o=e+".."+t;if(P(this,"doLength")){new N(r,n).to.have.property("length");var i=r.length;this.assert(i>=e&&i<=t,"expected #{this} to have a length within "+o,"expected #{this} to not have a length within "+o)}else this.assert(r>=e&&r<=t,"expected #{this} to be within "+o,"expected #{this} to not be within "+o)}),N.addMethod("instanceof",d),N.addMethod("instanceOf",d),N.addMethod("property",function(e,n,r){r&&P(this,"message",r);var o=!!P(this,"deep"),i=o?"deep property ":"property ",a=P(this,"negate"),s=P(this,"object"),c=o?t.getPathInfo(e,s):null,u=o?c.exists:t.hasProperty(e,s),f=o?c.value:s[e];if(a&&arguments.length>1){if(void 0===f)throw r=null!=r?r+": ":"",new Error(r+t.inspect(s)+" has no "+i+t.inspect(e))}else this.assert(u,"expected #{this} to have a "+i+t.inspect(e),"expected #{this} to not have "+i+t.inspect(e));arguments.length>1&&this.assert(n===f,"expected #{this} to have a "+i+t.inspect(e)+" of #{exp}, but got #{act}","expected #{this} to not have a "+i+t.inspect(e)+" of #{act}",n,f),P(this,"object",f)}),N.addMethod("ownProperty",h),N.addMethod("haveOwnProperty",h),N.addMethod("ownPropertyDescriptor",p),N.addMethod("haveOwnPropertyDescriptor",p),N.addChainableMethod("length",y,v),N.addMethod("lengthOf",y),N.addMethod("match",g),N.addMethod("matches",g),N.addMethod("string",function(e,n){n&&P(this,"message",n);var r=P(this,"object");new N(r,n).is.a("string"),this.assert(~r.indexOf(e),"expected #{this} to contain "+t.inspect(e),"expected #{this} to not contain "+t.inspect(e))}),N.addMethod("keys",b),N.addMethod("key",b),N.addMethod("throw",m),N.addMethod("throws",m),N.addMethod("Throw",m),N.addMethod("respondTo",w),N.addMethod("respondsTo",w),N.addProperty("itself",function(){P(this,"itself",!0)}),N.addMethod("satisfy",x),N.addMethod("satisfies",x),N.addMethod("closeTo",j),N.addMethod("approximately",j),N.addMethod("members",function(e,n){n&&P(this,"message",n);var r=P(this,"object");new N(r).to.be.an("array"),new N(e).to.be.an("array");var o=P(this,"deep")?t.eql:void 0;if(P(this,"contains"))return this.assert(E(e,r,o),"expected #{this} to be a superset of #{act}","expected #{this} to not be a superset of #{act}",r,e);this.assert(E(r,e,o)&&E(e,r,o),"expected #{this} to have the same members as #{act}","expected #{this} to not have the same members as #{act}",r,e)}),N.addMethod("oneOf",S),N.addChainableMethod("change",_),N.addChainableMethod("changes",_),N.addChainableMethod("increase",O),N.addChainableMethod("increases",O),N.addChainableMethod("decrease",A),N.addChainableMethod("decreases",A),N.addProperty("extensible",function(){var e,t=P(this,"object");try{e=Object.isExtensible(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!1}this.assert(e,"expected #{this} to be extensible","expected #{this} to not be extensible")}),N.addProperty("sealed",function(){var e,t=P(this,"object");try{e=Object.isSealed(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!0}this.assert(e,"expected #{this} to be sealed","expected #{this} to not be sealed")}),N.addProperty("frozen",function(){var e,t=P(this,"object");try{e=Object.isFrozen(t)}catch(t){if(!(t instanceof TypeError))throw t;e=!0}this.assert(e,"expected #{this} to be frozen","expected #{this} to not be frozen")})}},{}],7:[function(e,t,n){t.exports=function(e,t){var n=e.Assertion,r=t.flag,o=e.assert=function(t,r){new n(null,null,e.assert).assert(t,r,"[ negation message unavailable ]")};o.fail=function(t,n,r,i){throw r=r||"assert.fail()",new e.AssertionError(r,{actual:t,expected:n,operator:i},o.fail)},o.isOk=function(e,t){new n(e,t).is.ok},o.isNotOk=function(e,t){new n(e,t).is.not.ok},o.equal=function(e,t,i){var a=new n(e,i,o.equal);a.assert(t==r(a,"object"),"expected #{this} to equal #{exp}","expected #{this} to not equal #{act}",t,e)},o.notEqual=function(e,t,i){var a=new n(e,i,o.notEqual);a.assert(t!=r(a,"object"),"expected #{this} to not equal #{exp}","expected #{this} to equal #{act}",t,e)},o.strictEqual=function(e,t,r){new n(e,r).to.equal(t)},o.notStrictEqual=function(e,t,r){new n(e,r).to.not.equal(t)},o.deepEqual=function(e,t,r){new n(e,r).to.eql(t)},o.notDeepEqual=function(e,t,r){new n(e,r).to.not.eql(t)},o.isAbove=function(e,t,r){new n(e,r).to.be.above(t)},o.isAtLeast=function(e,t,r){new n(e,r).to.be.least(t)},o.isBelow=function(e,t,r){new n(e,r).to.be.below(t)},o.isAtMost=function(e,t,r){new n(e,r).to.be.most(t)},o.isTrue=function(e,t){new n(e,t).is.true},o.isNotTrue=function(e,t){new n(e,t).to.not.equal(!0)},o.isFalse=function(e,t){new n(e,t).is.false},o.isNotFalse=function(e,t){new n(e,t).to.not.equal(!1)},o.isNull=function(e,t){new n(e,t).to.equal(null)},o.isNotNull=function(e,t){new n(e,t).to.not.equal(null)},o.isNaN=function(e,t){new n(e,t).to.be.NaN},o.isNotNaN=function(e,t){new n(e,t).not.to.be.NaN},o.isUndefined=function(e,t){new n(e,t).to.equal(void 0)},o.isDefined=function(e,t){new n(e,t).to.not.equal(void 0)},o.isFunction=function(e,t){new n(e,t).to.be.a("function")},o.isNotFunction=function(e,t){new n(e,t).to.not.be.a("function")},o.isObject=function(e,t){new n(e,t).to.be.a("object")},o.isNotObject=function(e,t){new n(e,t).to.not.be.a("object")},o.isArray=function(e,t){new n(e,t).to.be.an("array")},o.isNotArray=function(e,t){new n(e,t).to.not.be.an("array")},o.isString=function(e,t){new n(e,t).to.be.a("string")},o.isNotString=function(e,t){new n(e,t).to.not.be.a("string")},o.isNumber=function(e,t){new n(e,t).to.be.a("number")},o.isNotNumber=function(e,t){new n(e,t).to.not.be.a("number")},o.isBoolean=function(e,t){new n(e,t).to.be.a("boolean")},o.isNotBoolean=function(e,t){new n(e,t).to.not.be.a("boolean")},o.typeOf=function(e,t,r){new n(e,r).to.be.a(t)},o.notTypeOf=function(e,t,r){new n(e,r).to.not.be.a(t)},o.instanceOf=function(e,t,r){new n(e,r).to.be.instanceOf(t)},o.notInstanceOf=function(e,t,r){new n(e,r).to.not.be.instanceOf(t)},o.include=function(e,t,r){new n(e,r,o.include).include(t)},o.notInclude=function(e,t,r){new n(e,r,o.notInclude).not.include(t)},o.match=function(e,t,r){new n(e,r).to.match(t)},o.notMatch=function(e,t,r){new n(e,r).to.not.match(t)},o.property=function(e,t,r){new n(e,r).to.have.property(t)},o.notProperty=function(e,t,r){new n(e,r).to.not.have.property(t)},o.deepProperty=function(e,t,r){new n(e,r).to.have.deep.property(t)},o.notDeepProperty=function(e,t,r){new n(e,r).to.not.have.deep.property(t)},o.propertyVal=function(e,t,r,o){new n(e,o).to.have.property(t,r)},o.propertyNotVal=function(e,t,r,o){new n(e,o).to.not.have.property(t,r)},o.deepPropertyVal=function(e,t,r,o){new n(e,o).to.have.deep.property(t,r)},o.deepPropertyNotVal=function(e,t,r,o){new n(e,o).to.not.have.deep.property(t,r)},o.lengthOf=function(e,t,r){new n(e,r).to.have.length(t)},o.throws=function(e,t,o,i){("string"==typeof t||t instanceof RegExp)&&(o=t,t=null);var a=new n(e,i).to.throw(t,o);return r(a,"object")},o.doesNotThrow=function(e,t,r){"string"==typeof t&&(r=t,t=null),new n(e,r).to.not.Throw(t)},o.operator=function(e,o,i,a){var s;switch(o){case"==":s=e==i;break;case"===":s=e===i;break;case">":s=e>i;break;case">=":s=e>=i;break;case"<":s=e1&&n===t.length-1?"or ":"")+r+" "+e}).join(", ");if(!t.some(function(t){return i(e)===t}))throw new r("object tested must be "+n+", but "+i(e)+" given")}},{"./flag":14,"assertion-error":1,"type-detect":40}],14:[function(e,t,n){t.exports=function(e,t,n){var r=e.__flags||(e.__flags=Object.create(null));if(3!==arguments.length)return r[t];r[t]=n}},{}],15:[function(e,t,n){t.exports=function(e,t){return t.length>4?t[4]:e._obj}},{}],16:[function(e,t,n){t.exports=function(e){var t=[];for(var n in e)t.push(n);return t}},{}],17:[function(e,t,n){var r=e("./flag"),o=e("./getActual"),i=(e("./inspect"),e("./objDisplay"));t.exports=function(e,t){var n=r(e,"negate"),a=r(e,"object"),s=t[3],c=o(e,t),u=n?t[2]:t[1],f=r(e,"message");return"function"==typeof u&&(u=u()),u=u||"",u=u.replace(/#\{this\}/g,function(){return i(a)}).replace(/#\{act\}/g,function(){return i(c)}).replace(/#\{exp\}/g,function(){return i(s)}),f?f+": "+u:u}},{"./flag":14,"./getActual":15,"./inspect":24,"./objDisplay":25}],18:[function(e,t,n){t.exports=function(e){if(e.name)return e.name;var t=/^\s?function ([^(]*)\(/.exec(e);return t&&t[1]?t[1]:""}},{}],19:[function(e,t,n){function r(e){return e.replace(/([^\\])\[/g,"$1.[").match(/(\\\.|[^.]+?)+/g).map(function(e){var t=/^\[(\d+)\]$/.exec(e);return t?{i:parseFloat(t[1])}:{p:e.replace(/\\([.\[\]])/g,"$1")}})}function o(e,t,n){for(var r,o=t,i=0,a=n=void 0===n?e.length:n;i1?o(n,t,n.length-1):t,name:a.p||a.i,value:o(n,t)};return s.exists=i(s.name,s.parent),s}},{"./hasProperty":22}],20:[function(e,t,n){var r=e("./getPathInfo");t.exports=function(e,t){return r(e,t).value}},{"./getPathInfo":19}],21:[function(e,t,n){t.exports=function(e){function t(e){-1===n.indexOf(e)&&n.push(e)}for(var n=Object.getOwnPropertyNames(e),r=Object.getPrototypeOf(e);null!==r;)Object.getOwnPropertyNames(r).forEach(t),r=Object.getPrototypeOf(r);return n}},{}],22:[function(e,t,n){var r=e("type-detect"),o={number:Number,string:String};t.exports=function(e,t){var n=r(t);return"null"!==n&&"undefined"!==n&&(o[n]&&"object"!=typeof t&&(t=new o[n](t)),e in t)}},{"type-detect":40}],23:[function(e,t,n){(n=t.exports={}).test=e("./test"),n.type=e("type-detect"),n.expectTypes=e("./expectTypes"),n.getMessage=e("./getMessage"),n.getActual=e("./getActual"),n.inspect=e("./inspect"),n.objDisplay=e("./objDisplay"),n.flag=e("./flag"),n.transferFlags=e("./transferFlags"),n.eql=e("deep-eql"),n.getPathValue=e("./getPathValue"),n.getPathInfo=e("./getPathInfo"),n.hasProperty=e("./hasProperty"),n.getName=e("./getName"),n.addProperty=e("./addProperty"),n.addMethod=e("./addMethod"),n.overwriteProperty=e("./overwriteProperty"),n.overwriteMethod=e("./overwriteMethod"),n.addChainableMethod=e("./addChainableMethod"),n.overwriteChainableMethod=e("./overwriteChainableMethod")},{"./addChainableMethod":10,"./addMethod":11,"./addProperty":12,"./expectTypes":13,"./flag":14,"./getActual":15,"./getMessage":17,"./getName":18,"./getPathInfo":19,"./getPathValue":20,"./hasProperty":22,"./inspect":24,"./objDisplay":25,"./overwriteChainableMethod":26,"./overwriteMethod":27,"./overwriteProperty":28,"./test":29,"./transferFlags":30,"deep-eql":32,"type-detect":40}],24:[function(e,t,n){function r(e,t,n,r){return o({showHidden:t,seen:[],stylize:function(e){return e}},e,void 0===n?2:n)}function o(e,t,r){if(t&&"function"==typeof t.inspect&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var p=t.inspect(r);return"string"!=typeof p&&(p=o(e,p,r)),p}var m=i(e,t);if(m)return m;if(b(t)){if("outerHTML"in t)return t.outerHTML;try{if(document.xmlVersion)return(new XMLSerializer).serializeToString(t);var w=document.createElementNS("http://www.w3.org/1999/xhtml","_");return w.appendChild(t.cloneNode(!1)),html=w.innerHTML.replace("><",">"+t.innerHTML+"<"),w.innerHTML="",html}catch(e){}}var x=g(t),j=e.showHidden?y(t):x;if(0===j.length||h(t)&&(1===j.length&&"stack"===j[0]||2===j.length&&"description"===j[0]&&"stack"===j[1])){if("function"==typeof t){var E=(A=v(t))?": "+A:"";return e.stylize("[Function"+E+"]","special")}if(l(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(d(t))return e.stylize(Date.prototype.toUTCString.call(t),"date");if(h(t))return a(t)}var S="",_=!1,O=["{","}"];if(f(t)&&(_=!0,O=["[","]"]),"function"==typeof t){var A=v(t);S=" [Function"+(E=A?": "+A:"")+"]"}if(l(t)&&(S=" "+RegExp.prototype.toString.call(t)),d(t)&&(S=" "+Date.prototype.toUTCString.call(t)),h(t))return a(t);if(0===j.length&&(!_||0==t.length))return O[0]+S+O[1];if(r<0)return l(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var N;return N=_?s(e,t,r,x,j):j.map(function(n){return c(e,t,r,x,n,_)}),e.seen.pop(),u(N,S,O)}function i(e,t){switch(typeof t){case"undefined":return e.stylize("undefined","undefined");case"string":var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string");case"number":return 0===t&&1/t==-1/0?e.stylize("-0","number"):e.stylize(""+t,"number");case"boolean":return e.stylize(""+t,"boolean")}if(null===t)return e.stylize("null","null")}function a(e){return"["+Error.prototype.toString.call(e)+"]"}function s(e,t,n,r,o){for(var i=[],a=0,s=t.length;a-1&&(c=a?c.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+c.split("\n").map(function(e){return" "+e}).join("\n")):c=e.stylize("[Circular]","special")),void 0===s){if(a&&i.match(/^\d+$/))return c;(s=JSON.stringify(""+i)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(s=s.substr(1,s.length-2),s=e.stylize(s,"name")):(s=s.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),s=e.stylize(s,"string"))}return s+": "+c}function u(e,t,n){var r=0;return e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.length+1},0)>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function f(e){return Array.isArray(e)||"object"==typeof e&&"[object Array]"===p(e)}function l(e){return"object"==typeof e&&"[object RegExp]"===p(e)}function d(e){return"object"==typeof e&&"[object Date]"===p(e)}function h(e){return"object"==typeof e&&"[object Error]"===p(e)}function p(e){return Object.prototype.toString.call(e)}var v=e("./getName"),y=e("./getProperties"),g=e("./getEnumerableProperties");t.exports=r;var b=function(e){return"object"==typeof HTMLElement?e instanceof HTMLElement:e&&"object"==typeof e&&1===e.nodeType&&"string"==typeof e.nodeName}},{"./getEnumerableProperties":16,"./getName":18,"./getProperties":21}],25:[function(e,t,n){var r=e("./inspect"),o=e("../config");t.exports=function(e){var t=r(e),n=Object.prototype.toString.call(e);if(o.truncateThreshold&&t.length>=o.truncateThreshold){if("[object Function]"===n)return e.name&&""!==e.name?"[Function: "+e.name+"]":"[Function]";if("[object Array]"===n)return"[ Array("+e.length+") ]";if("[object Object]"===n){var i=Object.keys(e);return"{ Object ("+(i.length>2?i.splice(0,2).join(", ")+", ...":i.join(", "))+") }"}return t}return t}},{"../config":5,"./inspect":24}],26:[function(e,t,n){t.exports=function(e,t,n,r){var o=e.__methods[t],i=o.chainingBehavior;o.chainingBehavior=function(){var e=r(i).call(this);return void 0===e?this:e};var a=o.method;o.method=function(){var e=n(a).apply(this,arguments);return void 0===e?this:e}}},{}],27:[function(e,t,n){t.exports=function(e,t,n){var r=e[t],o=function(){return this};r&&"function"==typeof r&&(o=r),e[t]=function(){var e=n(o).apply(this,arguments);return void 0===e?this:e}}},{}],28:[function(e,t,n){t.exports=function(e,t,n){var r=Object.getOwnPropertyDescriptor(e,t),o=function(){};r&&"function"==typeof r.get&&(o=r.get),Object.defineProperty(e,t,{get:function(){var e=n(o).call(this);return void 0===e?this:e},configurable:!0})}},{}],29:[function(e,t,n){var r=e("./flag");t.exports=function(e,t){var n=r(e,"negate"),o=t[0];return n?!o:o}},{"./flag":14}],30:[function(e,t,n){t.exports=function(e,t,n){var r=e.__flags||(e.__flags=Object.create(null));t.__flags||(t.__flags=Object.create(null)),n=3!==arguments.length||n;for(var o in r)(n||"object"!==o&&"ssfi"!==o&&"message"!=o)&&(t.__flags[o]=r[o])}},{}],31:[function(e,t,n){"use strict";function r(e){var t=void 0;t="string"==typeof e?[e]:e.raw;for(var n="",r=0;r=0;o--)if(s=i[o],!r(e[s],t[s],n))return!1;return!0}var p,v=e("type-detect");try{p=e("buffer").Buffer}catch(e){(p={}).isBuffer=function(){return!1}}t.exports=r},{buffer:void 0,"type-detect":38}],34:[function(e,t,n){(function(r){!function(e){if("object"==typeof n&&void 0!==t)t.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:void 0!==r?r:"undefined"!=typeof self?self:this).localforage=e()}}(function(){return function t(n,r,o){function i(s,c){if(!r[s]){if(!n[s]){var u="function"==typeof e&&e;if(!c&&u)return u(s,!0);if(a)return a(s,!0);var f=new Error("Cannot find module '"+s+"'");throw f.code="MODULE_NOT_FOUND",f}var l=r[s]={exports:{}};n[s][0].call(l.exports,function(e){var t=n[s][1][e];return i(t||e)},l,l.exports,t,n,r,o)}return r[s].exports}for(var a="function"==typeof e&&e,s=0;s=43)}}).catch(function(){return!1})}function u(e){return"boolean"==typeof re?ie.resolve(re):c(e).then(function(e){return re=e})}function f(e){var t=oe[e.name],n={};n.promise=new ie(function(e){n.resolve=e}),t.deferredOperations.push(n),t.dbReady?t.dbReady=t.dbReady.then(function(){return n.promise}):t.dbReady=n.promise}function l(e){var t=oe[e.name].deferredOperations.pop();t&&t.resolve()}function d(e,t){return new ie(function(n,r){if(e.db){if(!t)return n(e.db);f(e),e.db.close()}var o=[e.name];t&&o.push(e.version);var i=ne.open.apply(ne,o);t&&(i.onupgradeneeded=function(t){var n=i.result;try{n.createObjectStore(e.storeName),t.oldVersion<=1&&n.createObjectStore(ae)}catch(n){if("ConstraintError"!==n.name)throw n;console.warn('The database "'+e.name+'" has been upgraded from version '+t.oldVersion+" to version "+t.newVersion+', but the storage "'+e.storeName+'" already exists.')}}),i.onerror=function(e){e.preventDefault(),r(i.error)},i.onsuccess=function(){n(i.result),l(e)}})}function h(e){return d(e,!1)}function p(e){return d(e,!0)}function v(e,t){if(!e.db)return!0;var n=!e.db.objectStoreNames.contains(e.storeName),r=e.versione.db.version;if(r&&(e.version!==t&&console.warn('The database "'+e.name+"\" can't be downgraded from version "+e.db.version+" to version "+e.version+"."),e.version=e.db.version),o||n){if(n){var i=e.db.version+1;i>e.version&&(e.version=i)}return!0}return!1}function y(e){return new ie(function(t,n){var r=new FileReader;r.onerror=n,r.onloadend=function(n){var r=btoa(n.target.result||"");t({__local_forage_encoded_blob:!0,data:r,type:e.type})},r.readAsBinaryString(e)})}function g(e){return o([s(atob(e.data))],{type:e.type})}function b(e){return e&&e.__local_forage_encoded_blob}function m(e){var t=this,n=t._initReady().then(function(){var e=oe[t._dbInfo.name];if(e&&e.dbReady)return e.dbReady});return a(n,e,e),n}function w(e){function t(){return ie.resolve()}var n=this,r={db:null};if(e)for(var o in e)r[o]=e[o];oe||(oe={});var i=oe[r.name];i||(i={forages:[],db:null,dbReady:null,deferredOperations:[]},oe[r.name]=i),i.forages.push(n),n._initReady||(n._initReady=n.ready,n.ready=m);for(var a=[],s=0;s>4,f[c++]=(15&r)<<4|o>>2,f[c++]=(3&o)<<6|63&i;return u}function M(e){var t,n=new Uint8Array(e),r="";for(t=0;t>2],r+=ue[(3&n[t])<<4|n[t+1]>>4],r+=ue[(15&n[t+1])<<2|n[t+2]>>6],r+=ue[63&n[t+2]];return n.length%3==2?r=r.substring(0,r.length-1)+"=":n.length%3==1&&(r=r.substring(0,r.length-2)+"=="),r}function I(e,t){var n="";if(e&&(n=Oe.call(e)),e&&("[object ArrayBuffer]"===n||e.buffer&&"[object ArrayBuffer]"===Oe.call(e.buffer))){var r,o=de;e instanceof ArrayBuffer?(r=e,o+=pe):(r=e.buffer,"[object Int8Array]"===n?o+=ye:"[object Uint8Array]"===n?o+=ge:"[object Uint8ClampedArray]"===n?o+=be:"[object Int16Array]"===n?o+=me:"[object Uint16Array]"===n?o+=xe:"[object Int32Array]"===n?o+=we:"[object Uint32Array]"===n?o+=je:"[object Float32Array]"===n?o+=Ee:"[object Float64Array]"===n?o+=Se:t(new Error("Failed to get type for BinaryArray"))),t(o+M(r))}else if("[object Blob]"===n){var i=new FileReader;i.onload=function(){var n=fe+e.type+"~"+M(this.result);t(de+ve+n)},i.readAsArrayBuffer(e)}else try{t(JSON.stringify(e))}catch(n){console.error("Couldn't convert value into a JSON string: ",e),t(null,n)}}function k(e){if(e.substring(0,he)!==de)return JSON.parse(e);var t,n=e.substring(_e),r=e.substring(he,_e);if(r===ve&&le.test(n)){var i=n.match(le);t=i[1],n=n.substring(i[0].length)}var a=P(n);switch(r){case pe:return a;case ve:return o([a],{type:t});case ye:return new Int8Array(a);case ge:return new Uint8Array(a);case be:return new Uint8ClampedArray(a);case me:return new Int16Array(a);case xe:return new Uint16Array(a);case we:return new Int32Array(a);case je:return new Uint32Array(a);case Ee:return new Float32Array(a);case Se:return new Float64Array(a);default:throw new Error("Unkown type: "+r)}}function T(e){var t=this,n={db:null};if(e)for(var r in e)n[r]="string"!=typeof e[r]?e[r].toString():e[r];var o=new ie(function(e,r){try{n.db=openDatabase(n.name,String(n.version),n.description,n.size)}catch(e){return r(e)}n.db.transaction(function(o){o.executeSql("CREATE TABLE IF NOT EXISTS "+n.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){t._dbInfo=n,e()},function(e,t){r(t)})})});return n.serializer=Ae,o}function C(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT * FROM "+o.storeName+" WHERE key = ? LIMIT 1",[e],function(e,n){var r=n.rows.length?n.rows.item(0).value:null;r&&(r=o.serializer.deserialize(r)),t(r)},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function D(e,t){var n=this,r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT * FROM "+o.storeName,[],function(n,r){for(var i=r.rows,a=i.length,s=0;s0)return void i(L.apply(o,[e,s,n,r-1]));a(t)}})})}).catch(a)});return i(a,n),a}function R(e,t,n){return L.apply(this,[e,t,n,1])}function B(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("DELETE FROM "+o.storeName+" WHERE key = ?",[e],function(){t()},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function q(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("DELETE FROM "+r.storeName,[],function(){e()},function(e,t){n(t)})})}).catch(n)});return i(n,e),n}function z(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("SELECT COUNT(key) as c FROM "+r.storeName,[],function(t,n){var r=n.rows.item(0).c;e(r)},function(e,t){n(t)})})}).catch(n)});return i(n,e),n}function F(e,t){var n=this,r=new ie(function(t,r){n.ready().then(function(){var o=n._dbInfo;o.db.transaction(function(n){n.executeSql("SELECT key FROM "+o.storeName+" WHERE id = ? LIMIT 1",[e+1],function(e,n){var r=n.rows.length?n.rows.item(0).key:null;t(r)},function(e,t){r(t)})})}).catch(r)});return i(r,t),r}function U(e){var t=this,n=new ie(function(e,n){t.ready().then(function(){var r=t._dbInfo;r.db.transaction(function(t){t.executeSql("SELECT key FROM "+r.storeName,[],function(t,n){for(var r=[],o=0;o=0;n--){var r=localStorage.key(n);0===r.indexOf(e)&&localStorage.removeItem(r)}});return i(n,e),n}function J(e,t){var n=this;"string"!=typeof e&&(console.warn(e+" used as a key, but it is not a string."),e=String(e));var r=n.ready().then(function(){var t=n._dbInfo,r=localStorage.getItem(t.keyPrefix+e);return r&&(r=t.serializer.deserialize(r)),r});return i(r,t),r}function G(e,t){var n=this,r=n.ready().then(function(){for(var t=n._dbInfo,r=t.keyPrefix,o=r.length,i=localStorage.length,a=1,s=0;s num > 5);\n return overFive;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, [8, 13, 21]) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 3 items",test:`assert.lengthOf(output, 3) === undefined;`},{name:`First item is 8`,test:`assert.deepEqual(output[0], 8) === undefined;`}]},{name:"Array.map()",time:10,prompt:`Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,given:`const numbers = [25, 121, 169];\r`,answer:`const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, [5, 11, 13]) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 3 items",test:`assert.lengthOf(output, 3) === undefined;`},{name:`First item is 5`,test:`assert.deepEqual(output[0], 5) === undefined;`},{name:`Last item is 13`,test:`assert.deepEqual(output[output.length - 1], 13) === undefined;`}]},{name:"Array.every()",time:10,prompt:`Return object that returns whether each array contains all even numbers using Array.every().`,given:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,answer:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n return element % 2 === 0\n }\n return {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n };`,tests:[{name:"Correct output",test:`assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;`},{name:"Returns an Object",test:`assert.isObject(output) === undefined;`},{name:"Object has 2 items",test:`assert.lengthOf(Object.keys(output), 2) === undefined;`},{name:`First value is true`,test:`assert.isTrue(output.evenNumbers) === undefined;`},{name:`Second value is false`,test:`assert.isFalse(output.someOddNumbers) === undefined;`}]},{name:"Array.some()",time:10,prompt:`Return 'Object' that returns whether each array contains some odd numbers using 'Array.some()'.`,given:`const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 4, 7, 8];\n function isOdd(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,answer:`const evenNumbers = [1, 3, 5, 7];\n const someOddNumbers = [1, 3, 6, 7];\n function isOdd(element) {\n return element % 2 !== 0;\n }\n return {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n };`,tests:[{name:"Correct output",test:`assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;`},{name:"Returns an Object",test:`assert.isObject(output) === undefined;`},{name:"Object has 2 items",test:`assert.lengthOf(Object.keys(output), 2) === undefined;`},{name:`First value is false`,test:`assert.isFalse(output.evenNumbers) === undefined;`},{name:`Second value is true`,test:`assert.isTrue(output.someOddNumbers) === undefined;`}]}]},{}],37:[function(e,t,n){t.exports=[{name:"Create Array",time:10,prompt:"Create and return an array that contains 'apple' and 'banana'",given:`const fruits = [];\rreturn fruits;`,answer:`const fruits = ['apple', 'banana'];\n return fruits;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, ['apple', 'banana']) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 2 items",test:`assert.lengthOf(output, 2) === undefined;`}]},{name:"Array.pop()",time:10,prompt:`Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,given:`const fruits = ['apple', 'banana', 'orange'];\r`,answer:`const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,tests:[{name:"Correct output",test:`assert.deepEqual(output, ['apple', 'banana']) === undefined;`},{name:"Returns an Array",test:`assert.isArray(output) === undefined;`},{name:"Array has 2 items",test:`assert.lengthOf(output, 2) === undefined;`}]}]},{}],38:[function(e,t,n){t.exports=e("./lib/type")},{"./lib/type":39}],39:[function(e,t,n){function r(e){var t=Object.prototype.toString.call(e);return i[t]?i[t]:null===e?"null":void 0===e?"undefined":e===Object(e)?"object":typeof e}function o(){this.tests={}}var i={"[object Array]":"array","[object RegExp]":"regexp","[object Function]":"function","[object Arguments]":"arguments","[object Date]":"date"};(t.exports=r).Library=o,o.prototype.of=r,o.prototype.define=function(e,t){return 1===arguments.length?this.tests[e]:(this.tests[e]=t,this)},o.prototype.test=function(e,t){if(t===r(e))return!0;var n=this.tests[t];if(n&&"regexp"===r(n))return n.test(e);if(n&&"function"===r(n))return n(e);throw new ReferenceError('Type test "'+t+'" not defined or invalid.')}},{}],40:[function(e,t,n){arguments[4][38][0].apply(n,arguments)},{"./lib/type":41,dup:38}],41:[function(e,t,n){function r(e){var t=Object.prototype.toString.call(e).match(i)[1].toLowerCase();return"function"==typeof Promise&&e instanceof Promise?"promise":null===e?"null":void 0===e?"undefined":t}function o(){if(!(this instanceof o))return new o;this.tests={}}var i=/^\[object (.*)\]$/;(t.exports=r).Library=o,o.prototype.of=r,o.prototype.define=function(e,t){return 1===arguments.length?this.tests[e]:(this.tests[e]=t,this)},o.prototype.test=function(e,t){if(t===r(e))return!0;var n=this.tests[t];if(n&&"regexp"===r(n))return n.test(e);if(n&&"function"===r(n))return n(e);throw new ReferenceError('Type test "'+t+'" not defined or invalid.')}},{}],42:[function(require,module,exports){"use strict";function _toConsumableArray(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t=e.length-1||t<0?0:t+1}function getCurrentProblem(e){return e[config.currentIndex]}function previousProblem(){console.log("previousProblem!"),previousProblemButtonEl.classList.add("active"),config.currentIndex=config.shuffle?getRandomIndex(problems):getPreviousIndex(problems),updateLocalstore(config).then(function(){window.location.reload()})}function nextProblem(){console.log("nextProblem!"),nextProblemButtonEl.classList.add("active"),config.currentIndex=config.shuffle?getRandomIndex(problems):getNextIndex(problems),updateLocalstore(config).then(function(){window.location.reload()})}function toggleShuffle(){console.log("toggle shuffle!"),config.shuffle=!config.shuffle,shuffleProblemsButtonEl.classList.toggle("active"),previousProblemButtonEl.parentNode.classList.toggle("hidden"),updateLocalstore(config)}function loadProblem(e){currentProblem=e,problemEl.innerText=e.prompt,e.given&&(codeEl.value=e.given),testSuite(null,!0)}function updateTests(e,t){!0===t&&buildTests(currentProblem.tests),updateTestStatus(e)}function buildTests(e){if(e){var t=e.map(function(e){return'
\n
[✘]
\n
'+e.name+"
\n
"}).join("");testSuiteEl.innerHTML=t}}function updateTestStatus(e){if(!e)throw new Error("No testStatuses provided.");var t=!0;e.forEach(function(e){!0!==e&&(t=!1)}),[].slice.call(testSuiteEl.querySelectorAll(".test-state")).forEach(function(t,n){!0===e[n]?(t.innerHTML="[✓]",t.classList.remove("fail"),t.classList.add("pass")):(t.innerHTML="[✘]",t.classList.remove("pass"),t.classList.add("fail"))}),!0===t?(testTotalEl.innerText="PASS",testTotalEl.classList.remove("fail"),testTotalEl.classList.add("pass")):(testTotalEl.innerText="FAIL",testTotalEl.classList.remove("pass"),testTotalEl.classList.add("fail"))}function printAssertError(e){var t="";null!==e&&(t='\n
\n Expected: '+JSON.stringify(e.expected)+"\n Actual: "+JSON.stringify(e.actual)+"\n
"),assertConsoleEl.innerHTML=t}function printEvalOutput(e,t){var n="";e&&void 0!==e.message?n='\n
\n Syntax Error: '+JSON.stringify(e.message)+"\n
":t&&(n='\n
\n Output: '+JSON.stringify(t)+"\n
"),evalConsoleEl.innerHTML=n}function testSuite(e){testTotalEl.classList.toggle("working");var t=runTests(getOutput(codeEl.value));testTotalEl.classList.toggle("working"),updateTests(t,e)}function getOutput(code){var evald=!1;try{evald=eval("(function(){"+code+"})()"),printEvalOutput(null,evald)}catch(e){printEvalOutput(e)}return evald}function runTests(output){var tested=!1;return tested=currentProblem.tests.map(function(test){var testOutcome=!1;try{output&&(testOutcome=eval(test.test)),printAssertError(null)}catch(e){printAssertError(e)}return testOutcome})}function loadApp(e){function t(t){!1===e.shuffle&&13===t.keyCode&&t.shiftKey&&(t.metaKey||t.ctrlKey)?previousProblem():13!==t.keyCode||t.shiftKey||!t.metaKey&&!t.ctrlKey||nextProblem()}console.log("loading app!"),!0===e.shuffle&&(shuffleProblemsButtonEl.classList.add("active"),previousProblemButtonEl.parentNode.classList.add("hidden"));var n=debounce(function(e){-1===ignoreKeyCodes.indexOf(e.keyCode)&&testSuite()},200);codeEl.addEventListener("keydown",n),document.addEventListener("keydown",t),shuffleProblemsButtonEl.addEventListener("click",toggleShuffle),previousProblemButtonEl.addEventListener("click",previousProblem),nextProblemButtonEl.addEventListener("click",nextProblem),loadProblem(getCurrentProblem(problems)),testSuite(!0)}var localforage=require("localforage"),probs=require("pjs-problems"),dedent=require("dedent"),assert=require("chai").assert,problems=[];Object.keys(probs).forEach(function(e){var t;(t=problems).push.apply(t,_toConsumableArray(probs[e]))}),problems=dedentStrings(problems);var currentProblem=void 0,ignoreKeyCodes=[9,37,39,38,40],config={shuffle:!0,timer:!1,currentIndex:0};localforage.getItem("js_practice_config").then(function(e){e&&(config=e),loadApp(config)}).catch(function(e){console.log("localforage err:",e),loadApp(config)});var problemEl=document.getElementById("problem"),codeEl=document.getElementById("code"),testSuiteEl=document.getElementById("test-suite"),testTotalEl=document.getElementById("test-total"),evalConsoleEl=document.getElementById("eval-output"),assertConsoleEl=document.getElementById("assert-output"),shuffleProblemsButtonEl=document.getElementById("shuffle-problems"),previousProblemButtonEl=document.getElementById("prev-problem"),nextProblemButtonEl=document.getElementById("next-problem")}(document,window)},{chai:2,dedent:31,localforage:34,"pjs-problems":35}]},{},[42]); //# sourceMappingURL=bundle.min.js.map diff --git a/public/dist/js/bundle.min.js.map b/public/dist/js/bundle.min.js.map index 19ab410..708c565 100644 --- a/public/dist/js/bundle.min.js.map +++ b/public/dist/js/bundle.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["node_modules/.registry.npmjs.org/browser-pack/6.0.2/node_modules/browser-pack/_prelude.js","node_modules/.registry.npmjs.org/assertion-error/1.0.2/node_modules/assertion-error/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/assertion.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/config.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/core/assertions.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/assert.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/expect.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/should.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addChainableMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/expectTypes.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/flag.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getActual.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getEnumerableProperties.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getMessage.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getName.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getPathInfo.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getPathValue.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getProperties.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/hasProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/inspect.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/objDisplay.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/test.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/transferFlags.js","node_modules/.registry.npmjs.org/dedent/0.7.0/node_modules/dedent/dist/dedent.js","node_modules/.registry.npmjs.org/deep-eql/0.1.3/node_modules/deep-eql/index.js","node_modules/.registry.npmjs.org/deep-eql/0.1.3/node_modules/deep-eql/lib/eql.js","node_modules/.registry.npmjs.org/localforage/1.5.0/node_modules/localforage/dist/node_modules/localforage/dist/localforage.js","node_modules/.registry.npmjs.org/pjs-problems/1.0.3/node_modules/pjs-problems/index.js","node_modules/.registry.npmjs.org/pjs-problems/1.0.3/node_modules/pjs-problems/problems/arrays.js","node_modules/.registry.npmjs.org/pjs-problems/1.0.3/node_modules/pjs-problems/problems/initial.js","node_modules/.registry.npmjs.org/type-detect/0.1.1/node_modules/type-detect/index.js","node_modules/.registry.npmjs.org/type-detect/0.1.1/node_modules/type-detect/lib/type.js","node_modules/.registry.npmjs.org/type-detect/1.0.0/node_modules/type-detect/lib/type.js","src/js/index.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length","1","module","exclude","excludeProps","res","obj","Object","keys","forEach","key","excludes","indexOf","slice","arguments","args","AssertionError","message","_props","ssf","props","this","showDiff","callee","captureStackTrace","stack","prototype","create","name","constructor","toJSON","used","version","util","use","fn","push","config","assertion","core","expect","should","assert","_chai","Assertion","msg","flag","defineProperty","get","console","warn","includeStack","set","value","addProperty","addMethod","addChainableMethod","chainingBehavior","overwriteProperty","overwriteMethod","overwriteChainableMethod","expr","negateMsg","expected","_actual","ok","test","getMessage","actual","getActual","val","truncateThreshold","chai","_","an","type","toLowerCase","article","charAt","includeChainingBehavior","include","expectTypes","eql","k","property","subset","undefined","inspect","checkArguments","toString","assertEqual","_obj","assertEql","assertAbove","to","have","len","assertLeast","assertBelow","assertMost","assertInstanceOf","getName","assertOwnProperty","hasOwnProperty","assertOwnPropertyDescriptor","descriptor","actualDescriptor","getOwnPropertyDescriptor","assertLengthChain","assertLength","assertMatch","re","exec","assertKeys","str","mixedArgsMsg","Array","any","all","filter","every","last","map","pop","join","sort","assertThrows","errMsg","is","thrown","desiredError","thrownError","RegExp","err","actuallyGot","expectedThrown","respondTo","method","itself","context","satisfy","matcher","result","objDisplay","negate","closeTo","delta","Math","abs","isSubsetOf","superset","cmp","elem","some","elem2","oneOf","list","be","assertChanges","object","prop","initial","assertIncreases","assertDecreases","chain","isNaN","isArray","start","finish","range","isDeep","pathInfo","getPathInfo","hasProperty","exists","isExtensible","TypeError","isSealed","isFrozen","express","errmsg","fail","operator","isOk","isNotOk","not","equal","act","exp","notEqual","strictEqual","notStrictEqual","deepEqual","notDeepEqual","isAbove","abv","above","isAtLeast","atlst","least","isBelow","blw","below","isAtMost","atmst","most","isTrue","isNotTrue","isFalse","isNotFalse","isNull","isNotNull","NaN","isNotNaN","isUndefined","isDefined","isFunction","isNotFunction","isObject","isNotObject","isNotArray","isString","isNotString","isNumber","isNotNumber","isBoolean","isNotBoolean","typeOf","notTypeOf","instanceOf","notInstanceOf","inc","notInclude","match","notMatch","notProperty","deepProperty","deep","notDeepProperty","propertyVal","propertyNotVal","deepPropertyVal","deepPropertyNotVal","lengthOf","throws","errt","errs","assertErr","throw","doesNotThrow","Throw","val2","approximately","sameMembers","set1","set2","same","members","sameDeepMembers","includeMembers","includeDeepMembers","inList","changes","change","doesNotChange","increases","increase","doesNotIncrease","decreases","decrease","doesNotDecrease","ifError","extensible","isNotExtensible","sealed","isNotSealed","frozen","isNotFrozen","alias","as","loadShould","shouldGetter","String","Number","Boolean","valueOf","shouldSetter","enumerable","configurable","writable","val1","exist","Should","transferFlags","hasProtoSupport","excludeNames","Function","apply","ctx","chainableBehavior","__methods","__proto__","getOwnPropertyNames","asserterName","pd","getter","types","index","art","flags","__flags","flagMsg","replace","func","parsePath","path","mArr","parseFloat","p","_getPathValue","parsed","tmp","part","info","parent","proto","getPrototypeOf","literals","number","string","ot","getPathValue","showHidden","depth","colors","formatValue","seen","stylize","recurseTimes","ret","primitive","formatPrimitive","isDOMElement","outerHTML","document","xmlVersion","XMLSerializer","serializeToString","container","createElementNS","appendChild","cloneNode","html","innerHTML","visibleKeys","getEnumerableProperties","getProperties","isError","nameSuffix","isRegExp","isDate","Date","toUTCString","formatError","base","array","braces","output","formatArray","formatProperty","reduceToSingleString","simple","JSON","stringify","Infinity","__lookupGetter__","__lookupSetter__","split","line","substr","numLinesEst","reduce","prev","cur","ar","objectToString","d","HTMLElement","nodeType","nodeName","splice","_chainingBehavior","_method","_super","_get","includeAll","dedent","strings","raw","lines","mindent","m","indent","min","trim","b","sameValue","dateEqual","regexpEqual","Buffer","isBuffer","bufferEqual","argumentsEqual","typeEqual","objectEqual","getTime","iterableEqual","isValue","ka","kb","ex","define","amd","window","global","self","localforage","_dereq_","nextTick","draining","oldQueue","queue","immediate","task","scheduleDrain","Mutation","MutationObserver","WebKitMutationObserver","called","observer","element","createTextNode","observe","characterData","data","setImmediate","MessageChannel","createElement","scriptEl","onreadystatechange","parentNode","removeChild","documentElement","setTimeout","channel","port1","onmessage","port2","postMessage","2","INTERNAL","Promise","resolver","state","PENDING","outcome","safelyResolveThenable","QueueItem","promise","onFulfilled","onRejected","callFulfilled","otherCallFulfilled","callRejected","otherCallRejected","unwrap","returnValue","handlers","reject","resolve","getThen","then","thenable","onError","onSuccess","tryToUnwrap","tryCatch","status","out","reason","iterable","values","resolved","resolveFromAll","outValue","error","race","response","REJECTED","FULFILLED","3","4","_classCallCheck","instance","Constructor","createBlob","parts","properties","Blob","builder","BlobBuilder","MSBlobBuilder","MozBlobBuilder","WebKitBlobBuilder","append","getBlob","executeCallback","callback","executeTwoCallbacks","errorCallback","_binStringToArrayBuffer","bin","buf","ArrayBuffer","arr","Uint8Array","charCodeAt","_checkBlobSupportWithoutCaching","idb","Promise$1","txn","transaction","DETECT_BLOB_SUPPORT_STORE","blob","objectStore","put","onabort","preventDefault","stopPropagation","oncomplete","matchedChrome","navigator","userAgent","matchedEdge","parseInt","_checkBlobSupport","supportsBlobs","_deferReadiness","dbInfo","dbContext","dbContexts","deferredOperation","deferredOperations","dbReady","_advanceReadiness","_getConnection","upgradeNeeded","db","close","dbArgs","openreq","open","onupgradeneeded","createObjectStore","storeName","oldVersion","newVersion","onerror","onsuccess","_getOriginalConnection","_getUpgradedConnection","_isUpgradeNeeded","defaultVersion","isNewStore","objectStoreNames","contains","isDowngrade","isUpgrade","incVersion","_encodeBlob","reader","FileReader","onloadend","base64","btoa","target","__local_forage_encoded_blob","readAsBinaryString","_decodeBlob","encodedBlob","atob","_isEncodedBlob","_fullyReady","_initReady","_dbInfo","_initStorage","options","ignoreErrors","forages","ready","initPromises","j","forage","_defaultConfig","getItem","req","iterate","iterator","openCursor","iterationNumber","cursor","setItem","blobSupport","removeItem","clear","count","advanced","advance","stringToBuffer","serializedString","encoded1","encoded2","encoded3","encoded4","bufferLength","buffer","bytes","BASE_CHARS","bufferToString","base64String","substring","serialize","valueType","toString$1","marker","SERIALIZED_MARKER","TYPE_ARRAYBUFFER","TYPE_INT8ARRAY","TYPE_UINT8ARRAY","TYPE_UINT8CLAMPEDARRAY","TYPE_INT16ARRAY","TYPE_UINT16ARRAY","TYPE_INT32ARRAY","TYPE_UINT32ARRAY","TYPE_FLOAT32ARRAY","TYPE_FLOAT64ARRAY","fileReader","onload","BLOB_TYPE_PREFIX","TYPE_BLOB","readAsArrayBuffer","deserialize","SERIALIZED_MARKER_LENGTH","parse","blobType","TYPE_SERIALIZED_MARKER_LENGTH","BLOB_TYPE_PREFIX_REGEX","Int8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","_initStorage$1","dbInfoPromise","openDatabase","description","size","executeSql","serializer","localforageSerializer","getItem$1","results","rows","item","iterate$1","_setItem","retriesLeft","originalValue","sqlError","QUOTA_ERR","setItem$1","removeItem$1","clear$1","length$1","c","key$1","keys$1","_initStorage$2","keyPrefix","clear$2","localStorage","getItem$2","iterate$2","keyPrefixLength","key$2","keys$2","length$2","removeItem$2","setItem$2","callWhenReady","localForageInstance","libraryMethod","_args","extend","arg","isLibraryDriver","driverName","driver","DriverType","_typeof","Symbol","indexedDB","webkitIndexedDB","mozIndexedDB","OIndexedDB","msIndexedDB","asyncStorage","_driver","webSQLStorage","localStorageWrapper","CustomDrivers","INDEXEDDB","LOCALSTORAGE","WEBSQL","LibraryMethods","DefaultConfig","driverSupport","isSafari","platform","hasFetch","fetch","IDBKeyRange","localforage_js","LocalForage","_config","_driverSet","_initDriver","_ready","_wrapLibraryMethodsWithReady","setDriver","defineDriver","driverObject","complianceError","namingError","customDriverMethods","concat","customDriverMethod","supportPromise","_support","supportResult","getDriver","getDriverPromise","getSerializer","serializerPromise","drivers","setDriverToConfig","extendSelfWithDriver","_extend","initDriver","supportedDrivers","driverPromiseLoop","currentDriverIndex","_getSupportedDrivers","oldDriverSetDone","supports","libraryMethodsAndProperties","createInstance","arrays","time","prompt","given","answer","tests","getType","natives","Library","[object Array]","[object RegExp]","[object Function]","[object Arguments]","[object Date]","of","ReferenceError","objectTypeRegexp","dedentStrings","problems","prob","updateLocalstore","catch","log","debounce","wait","timeout","later","callNow","clearTimeout","getRandomIndex","problemsArr","ind","floor","random","currentIndex","getPreviousIndex","getNextIndex","getCurrentProblem","previousProblem","previousProblemButtonEl","classList","add","shuffle","location","reload","nextProblem","nextProblemButtonEl","toggleShuffle","shuffleProblemsButtonEl","toggle","loadProblem","problemObj","currentProblem","problemEl","innerText","codeEl","testSuite","updateTests","testStatus","init","buildTests","updateTestStatus","testsDom","testSuiteEl","testStatuses","allPassed","testPassed","querySelectorAll","testStatusEl","iter","remove","testTotalEl","printAssertError","errObj","inner","assertConsoleEl","printEvalOutput","evalConsoleEl","tested","runTests","getOutput","evald","eval","testOutcome","loadApp","problemNav","keyCode","shiftKey","metaKey","ctrlKey","debouncedInputValidation","ignoreKeyCodes","addEventListener","probs","subject","_problems","_toConsumableArray","timer","getElementById"],"mappings":"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","file":"bundle.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o\n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n var excludes = [].slice.call(arguments);\n\n function excludeProps (res, obj) {\n Object.keys(obj).forEach(function (key) {\n if (!~excludes.indexOf(key)) res[key] = obj[key];\n });\n }\n\n return function extendExclude () {\n var args = [].slice.call(arguments)\n , i = 0\n , res = {};\n\n for (; i < args.length; i++) {\n excludeProps(res, args[i]);\n }\n\n return res;\n };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n , props = extend(_props || {});\n\n // default values\n this.message = message || 'Unspecified AssertionError';\n this.showDiff = false;\n\n // copy from properties\n for (var key in props) {\n this[key] = props[key];\n }\n\n // capture stack trace\n ssf = ssf || arguments.callee;\n if (ssf && Error.captureStackTrace) {\n Error.captureStackTrace(this, ssf);\n } else {\n try {\n throw new Error();\n } catch(e) {\n this.stack = e.stack;\n }\n }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n var extend = exclude('constructor', 'toJSON', 'stack')\n , props = extend({ name: this.name }, this);\n\n // include stack if exists and not turned off\n if (false !== stack && this.stack) {\n props.stack = this.stack;\n }\n\n return props;\n};\n","module.exports = require('./lib/chai');\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar used = []\n , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n if (!~used.indexOf(fn)) {\n fn(this, util);\n used.push(fn);\n }\n\n return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n /*!\n * Module dependencies.\n */\n\n var AssertionError = _chai.AssertionError\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n _chai.Assertion = Assertion;\n\n /*!\n * Assertion Constructor\n *\n * Creates object for chaining.\n *\n * @api private\n */\n\n function Assertion (obj, msg, stack) {\n flag(this, 'ssfi', stack || arguments.callee);\n flag(this, 'object', obj);\n flag(this, 'message', msg);\n }\n\n Object.defineProperty(Assertion, 'includeStack', {\n get: function() {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n return config.includeStack;\n },\n set: function(value) {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n config.includeStack = value;\n }\n });\n\n Object.defineProperty(Assertion, 'showDiff', {\n get: function() {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n return config.showDiff;\n },\n set: function(value) {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n config.showDiff = value;\n }\n });\n\n Assertion.addProperty = function (name, fn) {\n util.addProperty(this.prototype, name, fn);\n };\n\n Assertion.addMethod = function (name, fn) {\n util.addMethod(this.prototype, name, fn);\n };\n\n Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n Assertion.overwriteProperty = function (name, fn) {\n util.overwriteProperty(this.prototype, name, fn);\n };\n\n Assertion.overwriteMethod = function (name, fn) {\n util.overwriteMethod(this.prototype, name, fn);\n };\n\n Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n /**\n * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n *\n * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n *\n * @name assert\n * @param {Philosophical} expression to be tested\n * @param {String|Function} message or function that returns message to display if expression fails\n * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n * @param {Mixed} expected value (remember to check for negation)\n * @param {Mixed} actual (optional) will default to `this.obj`\n * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n * @api private\n */\n\n Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n var ok = util.test(this, arguments);\n if (true !== showDiff) showDiff = false;\n if (true !== config.showDiff) showDiff = false;\n\n if (!ok) {\n var msg = util.getMessage(this, arguments)\n , actual = util.getActual(this, arguments);\n throw new AssertionError(msg, {\n actual: actual\n , expected: expected\n , showDiff: showDiff\n }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n }\n };\n\n /*!\n * ### ._obj\n *\n * Quick reference to stored `actual` value for plugin developers.\n *\n * @api private\n */\n\n Object.defineProperty(Assertion.prototype, '_obj',\n { get: function () {\n return flag(this, 'object');\n }\n , set: function (val) {\n flag(this, 'object', val);\n }\n });\n};\n","module.exports = {\n\n /**\n * ### config.includeStack\n *\n * User configurable property, influences whether stack trace\n * is included in Assertion error message. Default of false\n * suppresses stack trace in the error message.\n *\n * chai.config.includeStack = true; // enable stack on error\n *\n * @param {Boolean}\n * @api public\n */\n\n includeStack: false,\n\n /**\n * ### config.showDiff\n *\n * User configurable property, influences whether or not\n * the `showDiff` flag should be included in the thrown\n * AssertionErrors. `false` will always be `false`; `true`\n * will be true when the assertion has requested a diff\n * be shown.\n *\n * @param {Boolean}\n * @api public\n */\n\n showDiff: true,\n\n /**\n * ### config.truncateThreshold\n *\n * User configurable property, sets length threshold for actual and\n * expected values in assertion errors. If this threshold is exceeded, for\n * example for large data structures, the value is replaced with something\n * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n *\n * Set it to zero if you want to disable truncating altogether.\n *\n * This is especially userful when doing assertions on arrays: having this\n * set to a reasonable large value makes the failure messages readily\n * inspectable.\n *\n * chai.config.truncateThreshold = 0; // disable truncating\n *\n * @param {Number}\n * @api public\n */\n\n truncateThreshold: 40\n\n};\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n var Assertion = chai.Assertion\n , toString = Object.prototype.toString\n , flag = _.flag;\n\n /**\n * ### Language Chains\n *\n * The following are provided as chainable getters to\n * improve the readability of your assertions. They\n * do not provide testing capabilities unless they\n * have been overwritten by a plugin.\n *\n * **Chains**\n *\n * - to\n * - be\n * - been\n * - is\n * - that\n * - which\n * - and\n * - has\n * - have\n * - with\n * - at\n * - of\n * - same\n *\n * @name language chains\n * @namespace BDD\n * @api public\n */\n\n [ 'to', 'be', 'been'\n , 'is', 'and', 'has', 'have'\n , 'with', 'that', 'which', 'at'\n , 'of', 'same' ].forEach(function (chain) {\n Assertion.addProperty(chain, function () {\n return this;\n });\n });\n\n /**\n * ### .not\n *\n * Negates any of assertions following in the chain.\n *\n * expect(foo).to.not.equal('bar');\n * expect(goodFn).to.not.throw(Error);\n * expect({ foo: 'baz' }).to.have.property('foo')\n * .and.not.equal('bar');\n *\n * @name not\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('not', function () {\n flag(this, 'negate', true);\n });\n\n /**\n * ### .deep\n *\n * Sets the `deep` flag, later used by the `equal` and\n * `property` assertions.\n *\n * expect(foo).to.deep.equal({ bar: 'baz' });\n * expect({ foo: { bar: { baz: 'quux' } } })\n * .to.have.deep.property('foo.bar.baz', 'quux');\n *\n * `.deep.property` special characters can be escaped\n * by adding two slashes before the `.` or `[]`.\n *\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name deep\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('deep', function () {\n flag(this, 'deep', true);\n });\n\n /**\n * ### .any\n *\n * Sets the `any` flag, (opposite of the `all` flag)\n * later used in the `keys` assertion.\n *\n * expect(foo).to.have.any.keys('bar', 'baz');\n *\n * @name any\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('any', function () {\n flag(this, 'any', true);\n flag(this, 'all', false)\n });\n\n\n /**\n * ### .all\n *\n * Sets the `all` flag (opposite of the `any` flag)\n * later used by the `keys` assertion.\n *\n * expect(foo).to.have.all.keys('bar', 'baz');\n *\n * @name all\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('all', function () {\n flag(this, 'all', true);\n flag(this, 'any', false);\n });\n\n /**\n * ### .a(type)\n *\n * The `a` and `an` assertions are aliases that can be\n * used either as language chains or to assert a value's\n * type.\n *\n * // typeof\n * expect('test').to.be.a('string');\n * expect({ foo: 'bar' }).to.be.an('object');\n * expect(null).to.be.a('null');\n * expect(undefined).to.be.an('undefined');\n * expect(new Error).to.be.an('error');\n * expect(new Promise).to.be.a('promise');\n * expect(new Float32Array()).to.be.a('float32array');\n * expect(Symbol()).to.be.a('symbol');\n *\n * // es6 overrides\n * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n *\n * // language chain\n * expect(foo).to.be.an.instanceof(Foo);\n *\n * @name a\n * @alias an\n * @param {String} type\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function an (type, msg) {\n if (msg) flag(this, 'message', msg);\n type = type.toLowerCase();\n var obj = flag(this, 'object')\n , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n this.assert(\n type === _.type(obj)\n , 'expected #{this} to be ' + article + type\n , 'expected #{this} not to be ' + article + type\n );\n }\n\n Assertion.addChainableMethod('an', an);\n Assertion.addChainableMethod('a', an);\n\n /**\n * ### .include(value)\n *\n * The `include` and `contain` assertions can be used as either property\n * based language chains or as methods to assert the inclusion of an object\n * in an array or a substring in a string. When used as language chains,\n * they toggle the `contains` flag for the `keys` assertion.\n *\n * expect([1,2,3]).to.include(2);\n * expect('foobar').to.contain('foo');\n * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n *\n * @name include\n * @alias contain\n * @alias includes\n * @alias contains\n * @param {Object|String|Number} obj\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function includeChainingBehavior () {\n flag(this, 'contains', true);\n }\n\n function include (val, msg) {\n _.expectTypes(this, ['array', 'object', 'string']);\n\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var expected = false;\n\n if (_.type(obj) === 'array' && _.type(val) === 'object') {\n for (var i in obj) {\n if (_.eql(obj[i], val)) {\n expected = true;\n break;\n }\n }\n } else if (_.type(val) === 'object') {\n if (!flag(this, 'negate')) {\n for (var k in val) new Assertion(obj).property(k, val[k]);\n return;\n }\n var subset = {};\n for (var k in val) subset[k] = obj[k];\n expected = _.eql(subset, val);\n } else {\n expected = (obj != undefined) && ~obj.indexOf(val);\n }\n this.assert(\n expected\n , 'expected #{this} to include ' + _.inspect(val)\n , 'expected #{this} to not include ' + _.inspect(val));\n }\n\n Assertion.addChainableMethod('include', include, includeChainingBehavior);\n Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n /**\n * ### .ok\n *\n * Asserts that the target is truthy.\n *\n * expect('everything').to.be.ok;\n * expect(1).to.be.ok;\n * expect(false).to.not.be.ok;\n * expect(undefined).to.not.be.ok;\n * expect(null).to.not.be.ok;\n *\n * @name ok\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('ok', function () {\n this.assert(\n flag(this, 'object')\n , 'expected #{this} to be truthy'\n , 'expected #{this} to be falsy');\n });\n\n /**\n * ### .true\n *\n * Asserts that the target is `true`.\n *\n * expect(true).to.be.true;\n * expect(1).to.not.be.true;\n *\n * @name true\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('true', function () {\n this.assert(\n true === flag(this, 'object')\n , 'expected #{this} to be true'\n , 'expected #{this} to be false'\n , this.negate ? false : true\n );\n });\n\n /**\n * ### .false\n *\n * Asserts that the target is `false`.\n *\n * expect(false).to.be.false;\n * expect(0).to.not.be.false;\n *\n * @name false\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('false', function () {\n this.assert(\n false === flag(this, 'object')\n , 'expected #{this} to be false'\n , 'expected #{this} to be true'\n , this.negate ? true : false\n );\n });\n\n /**\n * ### .null\n *\n * Asserts that the target is `null`.\n *\n * expect(null).to.be.null;\n * expect(undefined).to.not.be.null;\n *\n * @name null\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('null', function () {\n this.assert(\n null === flag(this, 'object')\n , 'expected #{this} to be null'\n , 'expected #{this} not to be null'\n );\n });\n\n /**\n * ### .undefined\n *\n * Asserts that the target is `undefined`.\n *\n * expect(undefined).to.be.undefined;\n * expect(null).to.not.be.undefined;\n *\n * @name undefined\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('undefined', function () {\n this.assert(\n undefined === flag(this, 'object')\n , 'expected #{this} to be undefined'\n , 'expected #{this} not to be undefined'\n );\n });\n\n /**\n * ### .NaN\n * Asserts that the target is `NaN`.\n *\n * expect('foo').to.be.NaN;\n * expect(4).not.to.be.NaN;\n *\n * @name NaN\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('NaN', function () {\n this.assert(\n isNaN(flag(this, 'object'))\n , 'expected #{this} to be NaN'\n , 'expected #{this} not to be NaN'\n );\n });\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi'\n * , bar = null\n * , baz;\n *\n * expect(foo).to.exist;\n * expect(bar).to.not.exist;\n * expect(baz).to.not.exist;\n *\n * @name exist\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('exist', function () {\n this.assert(\n null != flag(this, 'object')\n , 'expected #{this} to exist'\n , 'expected #{this} to not exist'\n );\n });\n\n\n /**\n * ### .empty\n *\n * Asserts that the target's length is `0`. For arrays and strings, it checks\n * the `length` property. For objects, it gets the count of\n * enumerable keys.\n *\n * expect([]).to.be.empty;\n * expect('').to.be.empty;\n * expect({}).to.be.empty;\n *\n * @name empty\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('empty', function () {\n var obj = flag(this, 'object')\n , expected = obj;\n\n if (Array.isArray(obj) || 'string' === typeof object) {\n expected = obj.length;\n } else if (typeof obj === 'object') {\n expected = Object.keys(obj).length;\n }\n\n this.assert(\n !expected\n , 'expected #{this} to be empty'\n , 'expected #{this} not to be empty'\n );\n });\n\n /**\n * ### .arguments\n *\n * Asserts that the target is an arguments object.\n *\n * function test () {\n * expect(arguments).to.be.arguments;\n * }\n *\n * @name arguments\n * @alias Arguments\n * @namespace BDD\n * @api public\n */\n\n function checkArguments () {\n var obj = flag(this, 'object')\n , type = Object.prototype.toString.call(obj);\n this.assert(\n '[object Arguments]' === type\n , 'expected #{this} to be arguments but got ' + type\n , 'expected #{this} to not be arguments'\n );\n }\n\n Assertion.addProperty('arguments', checkArguments);\n Assertion.addProperty('Arguments', checkArguments);\n\n /**\n * ### .equal(value)\n *\n * Asserts that the target is strictly equal (`===`) to `value`.\n * Alternately, if the `deep` flag is set, asserts that\n * the target is deeply equal to `value`.\n *\n * expect('hello').to.equal('hello');\n * expect(42).to.equal(42);\n * expect(1).to.not.equal(true);\n * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n *\n * @name equal\n * @alias equals\n * @alias eq\n * @alias deep.equal\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEqual (val, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'deep')) {\n return this.eql(val);\n } else {\n this.assert(\n val === obj\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{exp}'\n , val\n , this._obj\n , true\n );\n }\n }\n\n Assertion.addMethod('equal', assertEqual);\n Assertion.addMethod('equals', assertEqual);\n Assertion.addMethod('eq', assertEqual);\n\n /**\n * ### .eql(value)\n *\n * Asserts that the target is deeply equal to `value`.\n *\n * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n *\n * @name eql\n * @alias eqls\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEql(obj, msg) {\n if (msg) flag(this, 'message', msg);\n this.assert(\n _.eql(obj, flag(this, 'object'))\n , 'expected #{this} to deeply equal #{exp}'\n , 'expected #{this} to not deeply equal #{exp}'\n , obj\n , this._obj\n , true\n );\n }\n\n Assertion.addMethod('eql', assertEql);\n Assertion.addMethod('eqls', assertEql);\n\n /**\n * ### .above(value)\n *\n * Asserts that the target is greater than `value`.\n *\n * expect(10).to.be.above(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n *\n * @name above\n * @alias gt\n * @alias greaterThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertAbove (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len > n\n , 'expected #{this} to have a length above #{exp} but got #{act}'\n , 'expected #{this} to not have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj > n\n , 'expected #{this} to be above ' + n\n , 'expected #{this} to be at most ' + n\n );\n }\n }\n\n Assertion.addMethod('above', assertAbove);\n Assertion.addMethod('gt', assertAbove);\n Assertion.addMethod('greaterThan', assertAbove);\n\n /**\n * ### .least(value)\n *\n * Asserts that the target is greater than or equal to `value`.\n *\n * expect(10).to.be.at.least(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.least(2);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n *\n * @name least\n * @alias gte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLeast (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= n\n , 'expected #{this} to have a length at least #{exp} but got #{act}'\n , 'expected #{this} to have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj >= n\n , 'expected #{this} to be at least ' + n\n , 'expected #{this} to be below ' + n\n );\n }\n }\n\n Assertion.addMethod('least', assertLeast);\n Assertion.addMethod('gte', assertLeast);\n\n /**\n * ### .below(value)\n *\n * Asserts that the target is less than `value`.\n *\n * expect(5).to.be.below(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n *\n * @name below\n * @alias lt\n * @alias lessThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertBelow (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len < n\n , 'expected #{this} to have a length below #{exp} but got #{act}'\n , 'expected #{this} to not have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj < n\n , 'expected #{this} to be below ' + n\n , 'expected #{this} to be at least ' + n\n );\n }\n }\n\n Assertion.addMethod('below', assertBelow);\n Assertion.addMethod('lt', assertBelow);\n Assertion.addMethod('lessThan', assertBelow);\n\n /**\n * ### .most(value)\n *\n * Asserts that the target is less than or equal to `value`.\n *\n * expect(5).to.be.at.most(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.most(4);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n *\n * @name most\n * @alias lte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertMost (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len <= n\n , 'expected #{this} to have a length at most #{exp} but got #{act}'\n , 'expected #{this} to have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj <= n\n , 'expected #{this} to be at most ' + n\n , 'expected #{this} to be above ' + n\n );\n }\n }\n\n Assertion.addMethod('most', assertMost);\n Assertion.addMethod('lte', assertMost);\n\n /**\n * ### .within(start, finish)\n *\n * Asserts that the target is within a range.\n *\n * expect(7).to.be.within(5,10);\n *\n * Can also be used in conjunction with `length` to\n * assert a length range. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * @name within\n * @param {Number} start lowerbound inclusive\n * @param {Number} finish upperbound inclusive\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('within', function (start, finish, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , range = start + '..' + finish;\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= start && len <= finish\n , 'expected #{this} to have a length within ' + range\n , 'expected #{this} to not have a length within ' + range\n );\n } else {\n this.assert(\n obj >= start && obj <= finish\n , 'expected #{this} to be within ' + range\n , 'expected #{this} to not be within ' + range\n );\n }\n });\n\n /**\n * ### .instanceof(constructor)\n *\n * Asserts that the target is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , Chai = new Tea('chai');\n *\n * expect(Chai).to.be.an.instanceof(Tea);\n * expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n *\n * @name instanceof\n * @param {Constructor} constructor\n * @param {String} message _optional_\n * @alias instanceOf\n * @namespace BDD\n * @api public\n */\n\n function assertInstanceOf (constructor, msg) {\n if (msg) flag(this, 'message', msg);\n var name = _.getName(constructor);\n this.assert(\n flag(this, 'object') instanceof constructor\n , 'expected #{this} to be an instance of ' + name\n , 'expected #{this} to not be an instance of ' + name\n );\n };\n\n Assertion.addMethod('instanceof', assertInstanceOf);\n Assertion.addMethod('instanceOf', assertInstanceOf);\n\n /**\n * ### .property(name, [value])\n *\n * Asserts that the target has a property `name`, optionally asserting that\n * the value of that property is strictly equal to `value`.\n * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n * references into objects and arrays.\n *\n * // simple referencing\n * var obj = { foo: 'bar' };\n * expect(obj).to.have.property('foo');\n * expect(obj).to.have.property('foo', 'bar');\n *\n * // deep referencing\n * var deepObj = {\n * green: { tea: 'matcha' }\n * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n * };\n *\n * expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n *\n * You can also use an array as the starting point of a `deep.property`\n * assertion, or traverse nested arrays.\n *\n * var arr = [\n * [ 'chai', 'matcha', 'konacha' ]\n * , [ { tea: 'chai' }\n * , { tea: 'matcha' }\n * , { tea: 'konacha' } ]\n * ];\n *\n * expect(arr).to.have.deep.property('[0][1]', 'matcha');\n * expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n *\n * Furthermore, `property` changes the subject of the assertion\n * to be the value of that property from the original object. This\n * permits for further chainable assertions on that property.\n *\n * expect(obj).to.have.property('foo')\n * .that.is.a('string');\n * expect(deepObj).to.have.property('green')\n * .that.is.an('object')\n * .that.deep.equals({ tea: 'matcha' });\n * expect(deepObj).to.have.property('teas')\n * .that.is.an('array')\n * .with.deep.property('[2]')\n * .that.deep.equals({ tea: 'konacha' });\n *\n * Note that dots and bracket in `name` must be backslash-escaped when\n * the `deep` flag is set, while they must NOT be escaped when the `deep`\n * flag is not set.\n *\n * // simple referencing\n * var css = { '.link[target]': 42 };\n * expect(css).to.have.property('.link[target]', 42);\n *\n * // deep referencing\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name property\n * @alias deep.property\n * @param {String} name\n * @param {Mixed} value (optional)\n * @param {String} message _optional_\n * @returns value of property for chaining\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('property', function (name, val, msg) {\n if (msg) flag(this, 'message', msg);\n\n var isDeep = !!flag(this, 'deep')\n , descriptor = isDeep ? 'deep property ' : 'property '\n , negate = flag(this, 'negate')\n , obj = flag(this, 'object')\n , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n , hasProperty = isDeep\n ? pathInfo.exists\n : _.hasProperty(name, obj)\n , value = isDeep\n ? pathInfo.value\n : obj[name];\n\n if (negate && arguments.length > 1) {\n if (undefined === value) {\n msg = (msg != null) ? msg + ': ' : '';\n throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n }\n } else {\n this.assert(\n hasProperty\n , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n }\n\n if (arguments.length > 1) {\n this.assert(\n val === value\n , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n , val\n , value\n );\n }\n\n flag(this, 'object', value);\n });\n\n\n /**\n * ### .ownProperty(name)\n *\n * Asserts that the target has an own property `name`.\n *\n * expect('test').to.have.ownProperty('length');\n *\n * @name ownProperty\n * @alias haveOwnProperty\n * @param {String} name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnProperty (name, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n obj.hasOwnProperty(name)\n , 'expected #{this} to have own property ' + _.inspect(name)\n , 'expected #{this} to not have own property ' + _.inspect(name)\n );\n }\n\n Assertion.addMethod('ownProperty', assertOwnProperty);\n Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n /**\n * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n *\n * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n *\n * expect('test').to.have.ownPropertyDescriptor('length');\n * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n * expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n *\n * @name ownPropertyDescriptor\n * @alias haveOwnPropertyDescriptor\n * @param {String} name\n * @param {Object} descriptor _optional_\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnPropertyDescriptor (name, descriptor, msg) {\n if (typeof descriptor === 'string') {\n msg = descriptor;\n descriptor = null;\n }\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n if (actualDescriptor && descriptor) {\n this.assert(\n _.eql(descriptor, actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n , descriptor\n , actualDescriptor\n , true\n );\n } else {\n this.assert(\n actualDescriptor\n , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n );\n }\n flag(this, 'object', actualDescriptor);\n }\n\n Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n /**\n * ### .length\n *\n * Sets the `doLength` flag later used as a chain precursor to a value\n * comparison for the `length` property.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * *Deprecation notice:* Using `length` as an assertion will be deprecated\n * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n * asserting for `length` property value using `length(value)` should be\n * switched to use `lengthOf(value)` instead.\n *\n * @name length\n * @namespace BDD\n * @api public\n */\n\n /**\n * ### .lengthOf(value[, message])\n *\n * Asserts that the target's `length` property has\n * the expected value.\n *\n * expect([ 1, 2, 3]).to.have.lengthOf(3);\n * expect('foobar').to.have.lengthOf(6);\n *\n * @name lengthOf\n * @param {Number} length\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLengthChain () {\n flag(this, 'doLength', true);\n }\n\n function assertLength (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n\n this.assert(\n len == n\n , 'expected #{this} to have a length of #{exp} but got #{act}'\n , 'expected #{this} to not have a length of #{act}'\n , n\n , len\n );\n }\n\n Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n Assertion.addMethod('lengthOf', assertLength);\n\n /**\n * ### .match(regexp)\n *\n * Asserts that the target matches a regular expression.\n *\n * expect('foobar').to.match(/^foo/);\n *\n * @name match\n * @alias matches\n * @param {RegExp} RegularExpression\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n function assertMatch(re, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n re.exec(obj)\n , 'expected #{this} to match ' + re\n , 'expected #{this} not to match ' + re\n );\n }\n\n Assertion.addMethod('match', assertMatch);\n Assertion.addMethod('matches', assertMatch);\n\n /**\n * ### .string(string)\n *\n * Asserts that the string target contains another string.\n *\n * expect('foobar').to.have.string('bar');\n *\n * @name string\n * @param {String} string\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('string', function (str, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('string');\n\n this.assert(\n ~obj.indexOf(str)\n , 'expected #{this} to contain ' + _.inspect(str)\n , 'expected #{this} to not contain ' + _.inspect(str)\n );\n });\n\n\n /**\n * ### .keys(key1, [key2], [...])\n *\n * Asserts that the target contains any or all of the passed-in keys.\n * Use in combination with `any`, `all`, `contains`, or `have` will affect\n * what will pass.\n *\n * When used in conjunction with `any`, at least one key that is passed\n * in must exist in the target object. This is regardless whether or not\n * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n * should be used in the assertion. If neither are used, the assertion is\n * defaulted to `all`.\n *\n * When both `all` and `contain` are used, the target object must have at\n * least all of the passed-in keys but may have more keys not listed.\n *\n * When both `all` and `have` are used, the target object must both contain\n * all of the passed-in keys AND the number of keys in the target object must\n * match the number of keys passed in (in other words, a target object must\n * have all and only all of the passed-in keys).\n *\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n *\n *\n * @name keys\n * @alias key\n * @param {...String|Array|Object} keys\n * @namespace BDD\n * @api public\n */\n\n function assertKeys (keys) {\n var obj = flag(this, 'object')\n , str\n , ok = true\n , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n switch (_.type(keys)) {\n case \"array\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n break;\n case \"object\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n keys = Object.keys(keys);\n break;\n default:\n keys = Array.prototype.slice.call(arguments);\n }\n\n if (!keys.length) throw new Error('keys required');\n\n var actual = Object.keys(obj)\n , expected = keys\n , len = keys.length\n , any = flag(this, 'any')\n , all = flag(this, 'all');\n\n if (!any && !all) {\n all = true;\n }\n\n // Has any\n if (any) {\n var intersection = expected.filter(function(key) {\n return ~actual.indexOf(key);\n });\n ok = intersection.length > 0;\n }\n\n // Has all\n if (all) {\n ok = keys.every(function(key){\n return ~actual.indexOf(key);\n });\n if (!flag(this, 'negate') && !flag(this, 'contains')) {\n ok = ok && keys.length == actual.length;\n }\n }\n\n // Key string\n if (len > 1) {\n keys = keys.map(function(key){\n return _.inspect(key);\n });\n var last = keys.pop();\n if (all) {\n str = keys.join(', ') + ', and ' + last;\n }\n if (any) {\n str = keys.join(', ') + ', or ' + last;\n }\n } else {\n str = _.inspect(keys[0]);\n }\n\n // Form\n str = (len > 1 ? 'keys ' : 'key ') + str;\n\n // Have / include\n str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n // Assertion\n this.assert(\n ok\n , 'expected #{this} to ' + str\n , 'expected #{this} to not ' + str\n , expected.slice(0).sort()\n , actual.sort()\n , true\n );\n }\n\n Assertion.addMethod('keys', assertKeys);\n Assertion.addMethod('key', assertKeys);\n\n /**\n * ### .throw(constructor)\n *\n * Asserts that the function target will throw a specific error, or specific type of error\n * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n * for the error's message.\n *\n * var err = new ReferenceError('This is a bad function.');\n * var fn = function () { throw err; }\n * expect(fn).to.throw(ReferenceError);\n * expect(fn).to.throw(Error);\n * expect(fn).to.throw(/bad function/);\n * expect(fn).to.not.throw('good function');\n * expect(fn).to.throw(ReferenceError, /bad function/);\n * expect(fn).to.throw(err);\n *\n * Please note that when a throw expectation is negated, it will check each\n * parameter independently, starting with error constructor type. The appropriate way\n * to check for the existence of a type of error but for a message that does not match\n * is to use `and`.\n *\n * expect(fn).to.throw(ReferenceError)\n * .and.not.throw(/good function/);\n *\n * @name throw\n * @alias throws\n * @alias Throw\n * @param {ErrorConstructor} constructor\n * @param {String|RegExp} expected error message\n * @param {String} message _optional_\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @returns error for chaining (null if no error)\n * @namespace BDD\n * @api public\n */\n\n function assertThrows (constructor, errMsg, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('function');\n\n var thrown = false\n , desiredError = null\n , name = null\n , thrownError = null;\n\n if (arguments.length === 0) {\n errMsg = null;\n constructor = null;\n } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n errMsg = constructor;\n constructor = null;\n } else if (constructor && constructor instanceof Error) {\n desiredError = constructor;\n constructor = null;\n errMsg = null;\n } else if (typeof constructor === 'function') {\n name = constructor.prototype.name;\n if (!name || (name === 'Error' && constructor !== Error)) {\n name = constructor.name || (new constructor()).name;\n }\n } else {\n constructor = null;\n }\n\n try {\n obj();\n } catch (err) {\n // first, check desired error\n if (desiredError) {\n this.assert(\n err === desiredError\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp}'\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (err instanceof Error ? err.toString() : err)\n );\n\n flag(this, 'object', err);\n return this;\n }\n\n // next, check constructor\n if (constructor) {\n this.assert(\n err instanceof constructor\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n , name\n , (err instanceof Error ? err.toString() : err)\n );\n\n if (!errMsg) {\n flag(this, 'object', err);\n return this;\n }\n }\n\n // next, check message\n var message = 'error' === _.type(err) && \"message\" in err\n ? err.message\n : '' + err;\n\n if ((message != null) && errMsg && errMsg instanceof RegExp) {\n this.assert(\n errMsg.exec(message)\n , 'expected #{this} to throw error matching #{exp} but got #{act}'\n , 'expected #{this} to throw error not matching #{exp}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n this.assert(\n ~message.indexOf(errMsg)\n , 'expected #{this} to throw error including #{exp} but got #{act}'\n , 'expected #{this} to throw error not including #{act}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else {\n thrown = true;\n thrownError = err;\n }\n }\n\n var actuallyGot = ''\n , expectedThrown = name !== null\n ? name\n : desiredError\n ? '#{exp}' //_.inspect(desiredError)\n : 'an error';\n\n if (thrown) {\n actuallyGot = ' but #{act} was thrown'\n }\n\n this.assert(\n thrown === true\n , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n );\n\n flag(this, 'object', thrownError);\n };\n\n Assertion.addMethod('throw', assertThrows);\n Assertion.addMethod('throws', assertThrows);\n Assertion.addMethod('Throw', assertThrows);\n\n /**\n * ### .respondTo(method)\n *\n * Asserts that the object or class target will respond to a method.\n *\n * Klass.prototype.bar = function(){};\n * expect(Klass).to.respondTo('bar');\n * expect(obj).to.respondTo('bar');\n *\n * To check if a constructor will respond to a static function,\n * set the `itself` flag.\n *\n * Klass.baz = function(){};\n * expect(Klass).itself.to.respondTo('baz');\n *\n * @name respondTo\n * @alias respondsTo\n * @param {String} method\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function respondTo (method, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , itself = flag(this, 'itself')\n , context = ('function' === _.type(obj) && !itself)\n ? obj.prototype[method]\n : obj[method];\n\n this.assert(\n 'function' === typeof context\n , 'expected #{this} to respond to ' + _.inspect(method)\n , 'expected #{this} to not respond to ' + _.inspect(method)\n );\n }\n\n Assertion.addMethod('respondTo', respondTo);\n Assertion.addMethod('respondsTo', respondTo);\n\n /**\n * ### .itself\n *\n * Sets the `itself` flag, later used by the `respondTo` assertion.\n *\n * function Foo() {}\n * Foo.bar = function() {}\n * Foo.prototype.baz = function() {}\n *\n * expect(Foo).itself.to.respondTo('bar');\n * expect(Foo).itself.not.to.respondTo('baz');\n *\n * @name itself\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('itself', function () {\n flag(this, 'itself', true);\n });\n\n /**\n * ### .satisfy(method)\n *\n * Asserts that the target passes a given truth test.\n *\n * expect(1).to.satisfy(function(num) { return num > 0; });\n *\n * @name satisfy\n * @alias satisfies\n * @param {Function} matcher\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function satisfy (matcher, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var result = matcher(obj);\n this.assert(\n result\n , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n , this.negate ? false : true\n , result\n );\n }\n\n Assertion.addMethod('satisfy', satisfy);\n Assertion.addMethod('satisfies', satisfy);\n\n /**\n * ### .closeTo(expected, delta)\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * expect(1.5).to.be.closeTo(1, 0.5);\n *\n * @name closeTo\n * @alias approximately\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function closeTo(expected, delta, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj, msg).is.a('number');\n if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n throw new Error('the arguments to closeTo or approximately must be numbers');\n }\n\n this.assert(\n Math.abs(obj - expected) <= delta\n , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n );\n }\n\n Assertion.addMethod('closeTo', closeTo);\n Assertion.addMethod('approximately', closeTo);\n\n function isSubsetOf(subset, superset, cmp) {\n return subset.every(function(elem) {\n if (!cmp) return superset.indexOf(elem) !== -1;\n\n return superset.some(function(elem2) {\n return cmp(elem, elem2);\n });\n })\n }\n\n /**\n * ### .members(set)\n *\n * Asserts that the target is a superset of `set`,\n * or that the target and `set` have the same strictly-equal (===) members.\n * Alternately, if the `deep` flag is set, set members are compared for deep\n * equality.\n *\n * expect([1, 2, 3]).to.include.members([3, 2]);\n * expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n *\n * expect([4, 2]).to.have.members([2, 4]);\n * expect([5, 2]).to.not.have.members([5, 2, 1]);\n *\n * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n *\n * @name members\n * @param {Array} set\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('members', function (subset, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj).to.be.an('array');\n new Assertion(subset).to.be.an('array');\n\n var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n if (flag(this, 'contains')) {\n return this.assert(\n isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to be a superset of #{act}'\n , 'expected #{this} to not be a superset of #{act}'\n , obj\n , subset\n );\n }\n\n this.assert(\n isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to have the same members as #{act}'\n , 'expected #{this} to not have the same members as #{act}'\n , obj\n , subset\n );\n });\n\n /**\n * ### .oneOf(list)\n *\n * Assert that a value appears somewhere in the top level of array `list`.\n *\n * expect('a').to.be.oneOf(['a', 'b', 'c']);\n * expect(9).to.not.be.oneOf(['z']);\n * expect([3]).to.not.be.oneOf([1, 2, [3]]);\n *\n * var three = [3];\n * // for object-types, contents are not compared\n * expect(three).to.not.be.oneOf([1, 2, [3]]);\n * // comparing references works\n * expect(three).to.be.oneOf([1, 2, three]);\n *\n * @name oneOf\n * @param {Array<*>} list\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function oneOf (list, msg) {\n if (msg) flag(this, 'message', msg);\n var expected = flag(this, 'object');\n new Assertion(list).to.be.an('array');\n\n this.assert(\n list.indexOf(expected) > -1\n , 'expected #{this} to be one of #{exp}'\n , 'expected #{this} to not be one of #{exp}'\n , list\n , expected\n );\n }\n\n Assertion.addMethod('oneOf', oneOf);\n\n\n /**\n * ### .change(function)\n *\n * Asserts that a function changes an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val += 3 };\n * var noChangeFn = function() { return 'foo' + 'bar'; }\n * expect(fn).to.change(obj, 'val');\n * expect(noChangeFn).to.not.change(obj, 'val')\n *\n * @name change\n * @alias changes\n * @alias Change\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertChanges (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n initial !== object[prop]\n , 'expected .' + prop + ' to change'\n , 'expected .' + prop + ' to not change'\n );\n }\n\n Assertion.addChainableMethod('change', assertChanges);\n Assertion.addChainableMethod('changes', assertChanges);\n\n /**\n * ### .increase(function)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * expect(fn).to.increase(obj, 'val');\n *\n * @name increase\n * @alias increases\n * @alias Increase\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertIncreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial > 0\n , 'expected .' + prop + ' to increase'\n , 'expected .' + prop + ' to not increase'\n );\n }\n\n Assertion.addChainableMethod('increase', assertIncreases);\n Assertion.addChainableMethod('increases', assertIncreases);\n\n /**\n * ### .decrease(function)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * expect(fn).to.decrease(obj, 'val');\n *\n * @name decrease\n * @alias decreases\n * @alias Decrease\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertDecreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial < 0\n , 'expected .' + prop + ' to decrease'\n , 'expected .' + prop + ' to not decrease'\n );\n }\n\n Assertion.addChainableMethod('decrease', assertDecreases);\n Assertion.addChainableMethod('decreases', assertDecreases);\n\n /**\n * ### .extensible\n *\n * Asserts that the target is extensible (can have new properties added to\n * it).\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect({}).to.be.extensible;\n * expect(nonExtensibleObject).to.not.be.extensible;\n * expect(sealedObject).to.not.be.extensible;\n * expect(frozenObject).to.not.be.extensible;\n *\n * @name extensible\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('extensible', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isExtensible;\n\n try {\n isExtensible = Object.isExtensible(obj);\n } catch (err) {\n if (err instanceof TypeError) isExtensible = false;\n else throw err;\n }\n\n this.assert(\n isExtensible\n , 'expected #{this} to be extensible'\n , 'expected #{this} to not be extensible'\n );\n });\n\n /**\n * ### .sealed\n *\n * Asserts that the target is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect(sealedObject).to.be.sealed;\n * expect(frozenObject).to.be.sealed;\n * expect({}).to.not.be.sealed;\n *\n * @name sealed\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('sealed', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isSealed;\n\n try {\n isSealed = Object.isSealed(obj);\n } catch (err) {\n if (err instanceof TypeError) isSealed = true;\n else throw err;\n }\n\n this.assert(\n isSealed\n , 'expected #{this} to be sealed'\n , 'expected #{this} to not be sealed'\n );\n });\n\n /**\n * ### .frozen\n *\n * Asserts that the target is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n *\n * expect(frozenObject).to.be.frozen;\n * expect({}).to.not.be.frozen;\n *\n * @name frozen\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('frozen', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isFrozen;\n\n try {\n isFrozen = Object.isFrozen(obj);\n } catch (err) {\n if (err instanceof TypeError) isFrozen = true;\n else throw err;\n }\n\n this.assert(\n isFrozen\n , 'expected #{this} to be frozen'\n , 'expected #{this} to not be frozen'\n );\n });\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n /*!\n * Chai dependencies.\n */\n\n var Assertion = chai.Assertion\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n /**\n * ### assert(expression, message)\n *\n * Write your own test expressions.\n *\n * assert('foo' !== 'bar', 'foo is not bar');\n * assert(Array.isArray([]), 'empty arrays are arrays');\n *\n * @param {Mixed} expression to test for truthiness\n * @param {String} message to display on error\n * @name assert\n * @namespace Assert\n * @api public\n */\n\n var assert = chai.assert = function (express, errmsg) {\n var test = new Assertion(null, null, chai.assert);\n test.assert(\n express\n , errmsg\n , '[ negation message unavailable ]'\n );\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure. Node.js `assert` module-compatible.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Assert\n * @api public\n */\n\n assert.fail = function (actual, expected, message, operator) {\n message = message || 'assert.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, assert.fail);\n };\n\n /**\n * ### .isOk(object, [message])\n *\n * Asserts that `object` is truthy.\n *\n * assert.isOk('everything', 'everything is ok');\n * assert.isOk(false, 'this will fail');\n *\n * @name isOk\n * @alias ok\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isOk = function (val, msg) {\n new Assertion(val, msg).is.ok;\n };\n\n /**\n * ### .isNotOk(object, [message])\n *\n * Asserts that `object` is falsy.\n *\n * assert.isNotOk('everything', 'this will fail');\n * assert.isNotOk(false, 'this will pass');\n *\n * @name isNotOk\n * @alias notOk\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotOk = function (val, msg) {\n new Assertion(val, msg).is.not.ok;\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * assert.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.equal = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.equal);\n\n test.assert(\n exp == flag(test, 'object')\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .notEqual(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * assert.notEqual(3, 4, 'these numbers are not equal');\n *\n * @name notEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notEqual = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.notEqual);\n\n test.assert(\n exp != flag(test, 'object')\n , 'expected #{this} to not equal #{exp}'\n , 'expected #{this} to equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .strictEqual(actual, expected, [message])\n *\n * Asserts strict equality (`===`) of `actual` and `expected`.\n *\n * assert.strictEqual(true, true, 'these booleans are strictly equal');\n *\n * @name strictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.strictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.equal(exp);\n };\n\n /**\n * ### .notStrictEqual(actual, expected, [message])\n *\n * Asserts strict inequality (`!==`) of `actual` and `expected`.\n *\n * assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n *\n * @name notStrictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notStrictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.equal(exp);\n };\n\n /**\n * ### .deepEqual(actual, expected, [message])\n *\n * Asserts that `actual` is deeply equal to `expected`.\n *\n * assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n *\n * @name deepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.eql(exp);\n };\n\n /**\n * ### .notDeepEqual(actual, expected, [message])\n *\n * Assert that `actual` is not deeply equal to `expected`.\n *\n * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n *\n * @name notDeepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.eql(exp);\n };\n\n /**\n * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n *\n * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n *\n * assert.isAbove(5, 2, '5 is strictly greater than 2');\n *\n * @name isAbove\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAbove\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAbove = function (val, abv, msg) {\n new Assertion(val, msg).to.be.above(abv);\n };\n\n /**\n * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n *\n * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n *\n * assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n * assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n *\n * @name isAtLeast\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtLeast\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtLeast = function (val, atlst, msg) {\n new Assertion(val, msg).to.be.least(atlst);\n };\n\n /**\n * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n *\n * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n *\n * assert.isBelow(3, 6, '3 is strictly less than 6');\n *\n * @name isBelow\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeBelow\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBelow = function (val, blw, msg) {\n new Assertion(val, msg).to.be.below(blw);\n };\n\n /**\n * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n *\n * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n *\n * assert.isAtMost(3, 6, '3 is less than or equal to 6');\n * assert.isAtMost(4, 4, '4 is less than or equal to 4');\n *\n * @name isAtMost\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtMost\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtMost = function (val, atmst, msg) {\n new Assertion(val, msg).to.be.most(atmst);\n };\n\n /**\n * ### .isTrue(value, [message])\n *\n * Asserts that `value` is true.\n *\n * var teaServed = true;\n * assert.isTrue(teaServed, 'the tea has been served');\n *\n * @name isTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isTrue = function (val, msg) {\n new Assertion(val, msg).is['true'];\n };\n\n /**\n * ### .isNotTrue(value, [message])\n *\n * Asserts that `value` is not true.\n *\n * var tea = 'tasty chai';\n * assert.isNotTrue(tea, 'great, time for tea!');\n *\n * @name isNotTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotTrue = function (val, msg) {\n new Assertion(val, msg).to.not.equal(true);\n };\n\n /**\n * ### .isFalse(value, [message])\n *\n * Asserts that `value` is false.\n *\n * var teaServed = false;\n * assert.isFalse(teaServed, 'no tea yet? hmm...');\n *\n * @name isFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFalse = function (val, msg) {\n new Assertion(val, msg).is['false'];\n };\n\n /**\n * ### .isNotFalse(value, [message])\n *\n * Asserts that `value` is not false.\n *\n * var tea = 'tasty chai';\n * assert.isNotFalse(tea, 'great, time for tea!');\n *\n * @name isNotFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFalse = function (val, msg) {\n new Assertion(val, msg).to.not.equal(false);\n };\n\n /**\n * ### .isNull(value, [message])\n *\n * Asserts that `value` is null.\n *\n * assert.isNull(err, 'there was no error');\n *\n * @name isNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNull = function (val, msg) {\n new Assertion(val, msg).to.equal(null);\n };\n\n /**\n * ### .isNotNull(value, [message])\n *\n * Asserts that `value` is not null.\n *\n * var tea = 'tasty chai';\n * assert.isNotNull(tea, 'great, time for tea!');\n *\n * @name isNotNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNull = function (val, msg) {\n new Assertion(val, msg).to.not.equal(null);\n };\n\n /**\n * ### .isNaN\n * Asserts that value is NaN\n *\n * assert.isNaN('foo', 'foo is NaN');\n *\n * @name isNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNaN = function (val, msg) {\n new Assertion(val, msg).to.be.NaN;\n };\n\n /**\n * ### .isNotNaN\n * Asserts that value is not NaN\n *\n * assert.isNotNaN(4, '4 is not NaN');\n *\n * @name isNotNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n assert.isNotNaN = function (val, msg) {\n new Assertion(val, msg).not.to.be.NaN;\n };\n\n /**\n * ### .isUndefined(value, [message])\n *\n * Asserts that `value` is `undefined`.\n *\n * var tea;\n * assert.isUndefined(tea, 'no tea defined');\n *\n * @name isUndefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isUndefined = function (val, msg) {\n new Assertion(val, msg).to.equal(undefined);\n };\n\n /**\n * ### .isDefined(value, [message])\n *\n * Asserts that `value` is not `undefined`.\n *\n * var tea = 'cup of chai';\n * assert.isDefined(tea, 'tea has been defined');\n *\n * @name isDefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isDefined = function (val, msg) {\n new Assertion(val, msg).to.not.equal(undefined);\n };\n\n /**\n * ### .isFunction(value, [message])\n *\n * Asserts that `value` is a function.\n *\n * function serveTea() { return 'cup of tea'; };\n * assert.isFunction(serveTea, 'great, we can have tea now');\n *\n * @name isFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFunction = function (val, msg) {\n new Assertion(val, msg).to.be.a('function');\n };\n\n /**\n * ### .isNotFunction(value, [message])\n *\n * Asserts that `value` is _not_ a function.\n *\n * var serveTea = [ 'heat', 'pour', 'sip' ];\n * assert.isNotFunction(serveTea, 'great, we have listed the steps');\n *\n * @name isNotFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFunction = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('function');\n };\n\n /**\n * ### .isObject(value, [message])\n *\n * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n * _The assertion does not match subclassed objects._\n *\n * var selection = { name: 'Chai', serve: 'with spices' };\n * assert.isObject(selection, 'tea selection is an object');\n *\n * @name isObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isObject = function (val, msg) {\n new Assertion(val, msg).to.be.a('object');\n };\n\n /**\n * ### .isNotObject(value, [message])\n *\n * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n *\n * var selection = 'chai'\n * assert.isNotObject(selection, 'tea selection is not an object');\n * assert.isNotObject(null, 'null is not an object');\n *\n * @name isNotObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotObject = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('object');\n };\n\n /**\n * ### .isArray(value, [message])\n *\n * Asserts that `value` is an array.\n *\n * var menu = [ 'green', 'chai', 'oolong' ];\n * assert.isArray(menu, 'what kind of tea do we want?');\n *\n * @name isArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isArray = function (val, msg) {\n new Assertion(val, msg).to.be.an('array');\n };\n\n /**\n * ### .isNotArray(value, [message])\n *\n * Asserts that `value` is _not_ an array.\n *\n * var menu = 'green|chai|oolong';\n * assert.isNotArray(menu, 'what kind of tea do we want?');\n *\n * @name isNotArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotArray = function (val, msg) {\n new Assertion(val, msg).to.not.be.an('array');\n };\n\n /**\n * ### .isString(value, [message])\n *\n * Asserts that `value` is a string.\n *\n * var teaOrder = 'chai';\n * assert.isString(teaOrder, 'order placed');\n *\n * @name isString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isString = function (val, msg) {\n new Assertion(val, msg).to.be.a('string');\n };\n\n /**\n * ### .isNotString(value, [message])\n *\n * Asserts that `value` is _not_ a string.\n *\n * var teaOrder = 4;\n * assert.isNotString(teaOrder, 'order placed');\n *\n * @name isNotString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotString = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('string');\n };\n\n /**\n * ### .isNumber(value, [message])\n *\n * Asserts that `value` is a number.\n *\n * var cups = 2;\n * assert.isNumber(cups, 'how many cups');\n *\n * @name isNumber\n * @param {Number} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNumber = function (val, msg) {\n new Assertion(val, msg).to.be.a('number');\n };\n\n /**\n * ### .isNotNumber(value, [message])\n *\n * Asserts that `value` is _not_ a number.\n *\n * var cups = '2 cups please';\n * assert.isNotNumber(cups, 'how many cups');\n *\n * @name isNotNumber\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNumber = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('number');\n };\n\n /**\n * ### .isBoolean(value, [message])\n *\n * Asserts that `value` is a boolean.\n *\n * var teaReady = true\n * , teaServed = false;\n *\n * assert.isBoolean(teaReady, 'is the tea ready');\n * assert.isBoolean(teaServed, 'has tea been served');\n *\n * @name isBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBoolean = function (val, msg) {\n new Assertion(val, msg).to.be.a('boolean');\n };\n\n /**\n * ### .isNotBoolean(value, [message])\n *\n * Asserts that `value` is _not_ a boolean.\n *\n * var teaReady = 'yep'\n * , teaServed = 'nope';\n *\n * assert.isNotBoolean(teaReady, 'is the tea ready');\n * assert.isNotBoolean(teaServed, 'has tea been served');\n *\n * @name isNotBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotBoolean = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('boolean');\n };\n\n /**\n * ### .typeOf(value, name, [message])\n *\n * Asserts that `value`'s type is `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n * assert.typeOf('tea', 'string', 'we have a string');\n * assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n * assert.typeOf(null, 'null', 'we have a null');\n * assert.typeOf(undefined, 'undefined', 'we have an undefined');\n *\n * @name typeOf\n * @param {Mixed} value\n * @param {String} name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.typeOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.a(type);\n };\n\n /**\n * ### .notTypeOf(value, name, [message])\n *\n * Asserts that `value`'s type is _not_ `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.notTypeOf('tea', 'number', 'strings are not numbers');\n *\n * @name notTypeOf\n * @param {Mixed} value\n * @param {String} typeof name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notTypeOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.a(type);\n };\n\n /**\n * ### .instanceOf(object, constructor, [message])\n *\n * Asserts that `value` is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new Tea('chai');\n *\n * assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n *\n * @name instanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.instanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.instanceOf(type);\n };\n\n /**\n * ### .notInstanceOf(object, constructor, [message])\n *\n * Asserts `value` is not an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new String('chai');\n *\n * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n *\n * @name notInstanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInstanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.instanceOf(type);\n };\n\n /**\n * ### .include(haystack, needle, [message])\n *\n * Asserts that `haystack` includes `needle`. Works\n * for strings and arrays.\n *\n * assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n * assert.include([ 1, 2, 3 ], 3, 'array contains value');\n *\n * @name include\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.include = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.include).include(inc);\n };\n\n /**\n * ### .notInclude(haystack, needle, [message])\n *\n * Asserts that `haystack` does not include `needle`. Works\n * for strings and arrays.\n *\n * assert.notInclude('foobar', 'baz', 'string not include substring');\n * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n *\n * @name notInclude\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInclude = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.notInclude).not.include(inc);\n };\n\n /**\n * ### .match(value, regexp, [message])\n *\n * Asserts that `value` matches the regular expression `regexp`.\n *\n * assert.match('foobar', /^foo/, 'regexp matches');\n *\n * @name match\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.match = function (exp, re, msg) {\n new Assertion(exp, msg).to.match(re);\n };\n\n /**\n * ### .notMatch(value, regexp, [message])\n *\n * Asserts that `value` does not match the regular expression `regexp`.\n *\n * assert.notMatch('foobar', /^foo/, 'regexp does not match');\n *\n * @name notMatch\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notMatch = function (exp, re, msg) {\n new Assertion(exp, msg).to.not.match(re);\n };\n\n /**\n * ### .property(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`.\n *\n * assert.property({ tea: { green: 'matcha' }}, 'tea');\n *\n * @name property\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.property = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.property(prop);\n };\n\n /**\n * ### .notProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`.\n *\n * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n *\n * @name notProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.property(prop);\n };\n\n /**\n * ### .deepProperty(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`, which can be a\n * string using dot- and bracket-notation for deep reference.\n *\n * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n *\n * @name deepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop);\n };\n\n /**\n * ### .notDeepProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`, which\n * can be a string using dot- and bracket-notation for deep reference.\n *\n * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n *\n * @name notDeepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop);\n };\n\n /**\n * ### .propertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`.\n *\n * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n *\n * @name propertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.property(prop, val);\n };\n\n /**\n * ### .propertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`.\n *\n * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n *\n * @name propertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.property(prop, val);\n };\n\n /**\n * ### .deepPropertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`. `property` can use dot- and bracket-notation for deep\n * reference.\n *\n * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n *\n * @name deepPropertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop, val);\n };\n\n /**\n * ### .deepPropertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`. `property` can use dot- and\n * bracket-notation for deep reference.\n *\n * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n *\n * @name deepPropertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n };\n\n /**\n * ### .lengthOf(object, length, [message])\n *\n * Asserts that `object` has a `length` property with the expected value.\n *\n * assert.lengthOf([1,2,3], 3, 'array has length of 3');\n * assert.lengthOf('foobar', 6, 'string has length of 6');\n *\n * @name lengthOf\n * @param {Mixed} object\n * @param {Number} length\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.lengthOf = function (exp, len, msg) {\n new Assertion(exp, msg).to.have.length(len);\n };\n\n /**\n * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * assert.throws(fn, 'function throws a reference error');\n * assert.throws(fn, /function throws a reference error/);\n * assert.throws(fn, ReferenceError);\n * assert.throws(fn, ReferenceError, 'function throws a reference error');\n * assert.throws(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throws\n * @alias throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.throws = function (fn, errt, errs, msg) {\n if ('string' === typeof errt || errt instanceof RegExp) {\n errs = errt;\n errt = null;\n }\n\n var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n return flag(assertErr, 'object');\n };\n\n /**\n * ### .doesNotThrow(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * assert.doesNotThrow(fn, Error, 'function does not throw');\n *\n * @name doesNotThrow\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotThrow = function (fn, type, msg) {\n if ('string' === typeof type) {\n msg = type;\n type = null;\n }\n\n new Assertion(fn, msg).to.not.Throw(type);\n };\n\n /**\n * ### .operator(val1, operator, val2, [message])\n *\n * Compares two values using `operator`.\n *\n * assert.operator(1, '<', 2, 'everything is ok');\n * assert.operator(1, '>', 2, 'this will fail');\n *\n * @name operator\n * @param {Mixed} val1\n * @param {String} operator\n * @param {Mixed} val2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.operator = function (val, operator, val2, msg) {\n var ok;\n switch(operator) {\n case '==':\n ok = val == val2;\n break;\n case '===':\n ok = val === val2;\n break;\n case '>':\n ok = val > val2;\n break;\n case '>=':\n ok = val >= val2;\n break;\n case '<':\n ok = val < val2;\n break;\n case '<=':\n ok = val <= val2;\n break;\n case '!=':\n ok = val != val2;\n break;\n case '!==':\n ok = val !== val2;\n break;\n default:\n throw new Error('Invalid operator \"' + operator + '\"');\n }\n var test = new Assertion(ok, msg);\n test.assert(\n true === flag(test, 'object')\n , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n };\n\n /**\n * ### .closeTo(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n *\n * @name closeTo\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.closeTo = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.closeTo(exp, delta);\n };\n\n /**\n * ### .approximately(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.approximately(1.5, 1, 0.5, 'numbers are close');\n *\n * @name approximately\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.approximately = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.approximately(exp, delta);\n };\n\n /**\n * ### .sameMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members.\n * Order is not taken into account.\n *\n * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n *\n * @name sameMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.members(set2);\n }\n\n /**\n * ### .sameDeepMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n * Order is not taken into account.\n *\n * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n *\n * @name sameDeepMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameDeepMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.deep.members(set2);\n }\n\n /**\n * ### .includeMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset`.\n * Order is not taken into account.\n *\n * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n *\n * @name includeMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.members(subset);\n }\n\n /**\n * ### .includeDeepMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset` - using deep equality checking.\n * Order is not taken into account.\n * Duplicates are ignored.\n *\n * assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n *\n * @name includeDeepMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeDeepMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.deep.members(subset);\n }\n\n /**\n * ### .oneOf(inList, list, [message])\n *\n * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n *\n * assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n *\n * @name oneOf\n * @param {*} inList\n * @param {Array<*>} list\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.oneOf = function (inList, list, msg) {\n new Assertion(inList, msg).to.be.oneOf(list);\n }\n\n /**\n * ### .changes(function, object, property)\n *\n * Asserts that a function changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 22 };\n * assert.changes(fn, obj, 'val');\n *\n * @name changes\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.changes = function (fn, obj, prop) {\n new Assertion(fn).to.change(obj, prop);\n }\n\n /**\n * ### .doesNotChange(function, object, property)\n *\n * Asserts that a function does not changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { console.log('foo'); };\n * assert.doesNotChange(fn, obj, 'val');\n *\n * @name doesNotChange\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotChange = function (fn, obj, prop) {\n new Assertion(fn).to.not.change(obj, prop);\n }\n\n /**\n * ### .increases(function, object, property)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 13 };\n * assert.increases(fn, obj, 'val');\n *\n * @name increases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.increases = function (fn, obj, prop) {\n new Assertion(fn).to.increase(obj, prop);\n }\n\n /**\n * ### .doesNotIncrease(function, object, property)\n *\n * Asserts that a function does not increase object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 8 };\n * assert.doesNotIncrease(fn, obj, 'val');\n *\n * @name doesNotIncrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotIncrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.increase(obj, prop);\n }\n\n /**\n * ### .decreases(function, object, property)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * assert.decreases(fn, obj, 'val');\n *\n * @name decreases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.decreases = function (fn, obj, prop) {\n new Assertion(fn).to.decrease(obj, prop);\n }\n\n /**\n * ### .doesNotDecrease(function, object, property)\n *\n * Asserts that a function does not decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * assert.doesNotDecrease(fn, obj, 'val');\n *\n * @name doesNotDecrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotDecrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.decrease(obj, prop);\n }\n\n /*!\n * ### .ifError(object)\n *\n * Asserts if value is not a false value, and throws if it is a true value.\n * This is added to allow for chai to be a drop-in replacement for Node's\n * assert class.\n *\n * var err = new Error('I am a custom error');\n * assert.ifError(err); // Rethrows err!\n *\n * @name ifError\n * @param {Object} object\n * @namespace Assert\n * @api public\n */\n\n assert.ifError = function (val) {\n if (val) {\n throw(val);\n }\n };\n\n /**\n * ### .isExtensible(object)\n *\n * Asserts that `object` is extensible (can have new properties added to it).\n *\n * assert.isExtensible({});\n *\n * @name isExtensible\n * @alias extensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.be.extensible;\n };\n\n /**\n * ### .isNotExtensible(object)\n *\n * Asserts that `object` is _not_ extensible.\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freese({});\n *\n * assert.isNotExtensible(nonExtensibleObject);\n * assert.isNotExtensible(sealedObject);\n * assert.isNotExtensible(frozenObject);\n *\n * @name isNotExtensible\n * @alias notExtensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.extensible;\n };\n\n /**\n * ### .isSealed(object)\n *\n * Asserts that `object` is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.seal({});\n *\n * assert.isSealed(sealedObject);\n * assert.isSealed(frozenObject);\n *\n * @name isSealed\n * @alias sealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isSealed = function (obj, msg) {\n new Assertion(obj, msg).to.be.sealed;\n };\n\n /**\n * ### .isNotSealed(object)\n *\n * Asserts that `object` is _not_ sealed.\n *\n * assert.isNotSealed({});\n *\n * @name isNotSealed\n * @alias notSealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotSealed = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.sealed;\n };\n\n /**\n * ### .isFrozen(object)\n *\n * Asserts that `object` is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n * assert.frozen(frozenObject);\n *\n * @name isFrozen\n * @alias frozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.be.frozen;\n };\n\n /**\n * ### .isNotFrozen(object)\n *\n * Asserts that `object` is _not_ frozen.\n *\n * assert.isNotFrozen({});\n *\n * @name isNotFrozen\n * @alias notFrozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.frozen;\n };\n\n /*!\n * Aliases.\n */\n\n (function alias(name, as){\n assert[as] = assert[name];\n return alias;\n })\n ('isOk', 'ok')\n ('isNotOk', 'notOk')\n ('throws', 'throw')\n ('throws', 'Throw')\n ('isExtensible', 'extensible')\n ('isNotExtensible', 'notExtensible')\n ('isSealed', 'sealed')\n ('isNotSealed', 'notSealed')\n ('isFrozen', 'frozen')\n ('isNotFrozen', 'notFrozen');\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n chai.expect = function (val, message) {\n return new chai.Assertion(val, message);\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Expect\n * @api public\n */\n\n chai.expect.fail = function (actual, expected, message, operator) {\n message = message || 'expect.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, chai.expect.fail);\n };\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n var Assertion = chai.Assertion;\n\n function loadShould () {\n // explicitly define this method as function as to have it's name to include as `ssfi`\n function shouldGetter() {\n if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n return new Assertion(this.valueOf(), null, shouldGetter);\n }\n return new Assertion(this, null, shouldGetter);\n }\n function shouldSetter(value) {\n // See https://github.com/chaijs/chai/issues/86: this makes\n // `whatever.should = someValue` actually set `someValue`, which is\n // especially useful for `global.should = require('chai').should()`.\n //\n // Note that we have to use [[DefineProperty]] instead of [[Put]]\n // since otherwise we would trigger this very setter!\n Object.defineProperty(this, 'should', {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n }\n // modify Object.prototype to have `should`\n Object.defineProperty(Object.prototype, 'should', {\n set: shouldSetter\n , get: shouldGetter\n , configurable: true\n });\n\n var should = {};\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Should\n * @api public\n */\n\n should.fail = function (actual, expected, message, operator) {\n message = message || 'should.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, should.fail);\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * should.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * should.throw(fn, 'function throws a reference error');\n * should.throw(fn, /function throws a reference error/);\n * should.throw(fn, ReferenceError);\n * should.throw(fn, ReferenceError, 'function throws a reference error');\n * should.throw(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.Throw(errt, errs);\n };\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi';\n *\n * should.exist(foo, 'foo exists');\n *\n * @name exist\n * @namespace Should\n * @api public\n */\n\n should.exist = function (val, msg) {\n new Assertion(val, msg).to.exist;\n }\n\n // negation\n should.not = {}\n\n /**\n * ### .not.equal(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * should.not.equal(3, 4, 'these numbers are not equal');\n *\n * @name not.equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.not.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.not.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * should.not.throw(fn, Error, 'function does not throw');\n *\n * @name not.throw\n * @alias not.Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.not.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.not.Throw(errt, errs);\n };\n\n /**\n * ### .not.exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var bar = null;\n *\n * should.not.exist(bar, 'bar does not exist');\n *\n * @name not.exist\n * @namespace Should\n * @api public\n */\n\n should.not.exist = function (val, msg) {\n new Assertion(val, msg).to.not.exist;\n }\n\n should['throw'] = should['Throw'];\n should.not['throw'] = should.not['Throw'];\n\n return should;\n };\n\n chai.should = loadShould;\n chai.Should = loadShould;\n};\n","/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call = Function.prototype.call,\n apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n * expect(fooStr).to.be.foo('bar');\n * expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n if (typeof chainingBehavior !== 'function') {\n chainingBehavior = function () { };\n }\n\n var chainableBehavior = {\n method: method\n , chainingBehavior: chainingBehavior\n };\n\n // save the methods so we can overwrite them later, if we need to.\n if (!ctx.__methods) {\n ctx.__methods = {};\n }\n ctx.__methods[name] = chainableBehavior;\n\n Object.defineProperty(ctx, name,\n { get: function () {\n chainableBehavior.chainingBehavior.call(this);\n\n var assert = function assert() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', assert);\n var result = chainableBehavior.method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n\n // Use `__proto__` if available\n if (hasProtoSupport) {\n // Inherit all properties from the object by replacing the `Function` prototype\n var prototype = assert.__proto__ = Object.create(this);\n // Restore the `call` and `apply` methods from `Function`\n prototype.call = call;\n prototype.apply = apply;\n }\n // Otherwise, redefine all properties (slow!)\n else {\n var asserterNames = Object.getOwnPropertyNames(ctx);\n asserterNames.forEach(function (asserterName) {\n if (!excludeNames.test(asserterName)) {\n var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n Object.defineProperty(assert, asserterName, pd);\n }\n });\n }\n\n transferFlags(this, assert);\n return assert;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n ctx[name] = function () {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', ctx[name]);\n var result = method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n * utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.instanceof(Foo);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n Object.defineProperty(ctx, name,\n { get: function addProperty() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', addProperty);\n\n var result = getter.call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n * utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n var obj = flag(obj, 'object');\n types = types.map(function (t) { return t.toLowerCase(); });\n types.sort();\n\n // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n var str = types.map(function (t, index) {\n var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n return or + art + ' ' + t;\n }).join(', ');\n\n if (!types.some(function (expected) { return type(obj) === expected; })) {\n throw new AssertionError(\n 'object tested must be ' + str + ', but ' + type(obj) + ' given'\n );\n }\n};\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n * utils.flag(this, 'foo', 'bar'); // setter\n * utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n var flags = obj.__flags || (obj.__flags = Object.create(null));\n if (arguments.length === 3) {\n flags[key] = value;\n } else {\n return flags[key];\n }\n};\n","/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n return args.length > 4 ? args[4] : obj._obj;\n};\n","/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n var result = [];\n for (var name in object) {\n result.push(name);\n }\n return result;\n};\n","/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n , getActual = require('./getActual')\n , inspect = require('./inspect')\n , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , val = flag(obj, 'object')\n , expected = args[3]\n , actual = getActual(obj, args)\n , msg = negate ? args[2] : args[1]\n , flagMsg = flag(obj, 'message');\n\n if(typeof msg === \"function\") msg = msg();\n msg = msg || '';\n msg = msg\n .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n","/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n if (func.name) return func.name;\n\n var match = /^\\s?function ([^(]*)\\(/.exec(func);\n return match && match[1] ? match[1] : \"\";\n};\n","/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n var parsed = parsePath(path),\n last = parsed[parsed.length - 1];\n\n var info = {\n parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n name: last.p || last.i,\n value: _getPathValue(parsed, obj)\n };\n info.exists = hasProperty(info.name, info.parent);\n\n return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n * var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n return parts.map(function (value) {\n var re = /^\\[(\\d+)\\]$/\n , mArr = re.exec(value);\n if (mArr) return { i: parseFloat(mArr[1]) };\n else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n * var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n var tmp = obj\n , res;\n\n index = (index === undefined ? parsed.length : index);\n\n for (var i = 0, l = index; i < l; i++) {\n var part = parsed[i];\n if (tmp) {\n if ('undefined' !== typeof part.p)\n tmp = tmp[part.p];\n else if ('undefined' !== typeof part.i)\n tmp = tmp[part.i];\n if (i == (l - 1)) res = tmp;\n } else {\n res = undefined;\n }\n }\n return res;\n}\n","/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer \n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n * var obj = {\n * prop1: {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n * , prop2: {\n * arr: [ { nested: 'Universe' } ]\n * , str: 'Hello again!'\n * }\n * }\n *\n * The following would be the results.\n *\n * getPathValue('prop1.str', obj); // Hello\n * getPathValue('prop1.att[2]', obj); // b\n * getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n var info = getPathInfo(path, obj);\n return info.value;\n};\n","/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n var result = Object.getOwnPropertyNames(object);\n\n function addProperty(property) {\n if (result.indexOf(property) === -1) {\n result.push(property);\n }\n }\n\n var proto = Object.getPrototypeOf(object);\n while (proto !== null) {\n Object.getOwnPropertyNames(proto).forEach(addProperty);\n proto = Object.getPrototypeOf(proto);\n }\n\n return result;\n};\n","/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n * var obj = {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n *\n * The following would be the results.\n *\n * hasProperty('str', obj); // true\n * hasProperty('constructor', obj); // true\n * hasProperty('bar', obj); // false\n *\n * hasProperty('length', obj.str); // true\n * hasProperty(1, obj.str); // true\n * hasProperty(5, obj.str); // false\n *\n * hasProperty('length', obj.arr); // true\n * hasProperty(2, obj.arr); // true\n * hasProperty(3, obj.arr); // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n 'number': Number\n , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n var ot = type(obj);\n\n // Bad Object, obviously no props at all\n if(ot === 'null' || ot === 'undefined')\n return false;\n\n // The `in` operator does not work with certain literals\n // box these before the check\n if(literals[ot] && typeof obj !== 'object')\n obj = new literals[ot](obj);\n\n return name in obj;\n};\n","/*!\n * chai\n * Copyright(c) 2011 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n","// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n * properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n * output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n var ctx = {\n showHidden: showHidden,\n seen: [],\n stylize: function (str) { return str; }\n };\n return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n if (typeof HTMLElement === 'object') {\n return object instanceof HTMLElement;\n } else {\n return object &&\n typeof object === 'object' &&\n object.nodeType === 1 &&\n typeof object.nodeName === 'string';\n }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (value && typeof value.inspect === 'function' &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes);\n if (typeof ret !== 'string') {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // If this is a DOM element, try to get the outer HTML.\n if (isDOMElement(value)) {\n if ('outerHTML' in value) {\n return value.outerHTML;\n // This value does not have an outerHTML attribute,\n // it could still be an XML element\n } else {\n // Attempt to serialize it\n try {\n if (document.xmlVersion) {\n var xmlSerializer = new XMLSerializer();\n return xmlSerializer.serializeToString(value);\n } else {\n // Firefox 11- do not support outerHTML\n // It does, however, support innerHTML\n // Use the following to render the element\n var ns = \"http://www.w3.org/1999/xhtml\";\n var container = document.createElementNS(ns, '_');\n\n container.appendChild(value.cloneNode(false));\n html = container.innerHTML\n .replace('><', '>' + value.innerHTML + '<');\n container.innerHTML = '';\n return html;\n }\n } catch (err) {\n // This could be a non-native DOM implementation,\n // continue with the normal flow:\n // printing the element as if it is an object.\n }\n }\n }\n\n // Look up the keys of the object.\n var visibleKeys = getEnumerableProperties(value);\n var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n // Some type of object without properties can be shortcutted.\n // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n // a `stack` plus `description` property; ignore those for consistency.\n if (keys.length === 0 || (isError(value) && (\n (keys.length === 1 && keys[0] === 'stack') ||\n (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n ))) {\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n base = ' [Function' + nameSuffix + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n return formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n switch (typeof value) {\n case 'undefined':\n return ctx.stylize('undefined', 'undefined');\n\n case 'string':\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n\n case 'number':\n if (value === 0 && (1/value) === -Infinity) {\n return ctx.stylize('-0', 'number');\n }\n return ctx.stylize('' + value, 'number');\n\n case 'boolean':\n return ctx.stylize('' + value, 'boolean');\n }\n // For some reason typeof null is \"object\", so special case here.\n if (value === null) {\n return ctx.stylize('null', 'null');\n }\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str;\n if (value.__lookupGetter__) {\n if (value.__lookupGetter__(key)) {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n }\n if (visibleKeys.indexOf(key) < 0) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(value[key]) < 0) {\n if (recurseTimes === null) {\n str = formatValue(ctx, value[key], null);\n } else {\n str = formatValue(ctx, value[key], recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (typeof name === 'undefined') {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n return Array.isArray(ar) ||\n (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n var str = inspect(obj)\n , type = Object.prototype.toString.call(obj);\n\n if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n if (type === '[object Function]') {\n return !obj.name || obj.name === ''\n ? '[Function]'\n : '[Function: ' + obj.name + ']';\n } else if (type === '[object Array]') {\n return '[ Array(' + obj.length + ') ]';\n } else if (type === '[object Object]') {\n var keys = Object.keys(obj)\n , kstr = keys.length > 2\n ? keys.splice(0, 2).join(', ') + ', ...'\n : keys.join(', ');\n return '{ Object (' + kstr + ') }';\n } else {\n return str;\n }\n } else {\n return str;\n }\n};\n","/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property. Must return functions to be used for\n * name.\n *\n * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n * function (_super) {\n * }\n * , function (_super) {\n * }\n * );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.have.length(3);\n * expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n var chainableBehavior = ctx.__methods[name];\n\n var _chainingBehavior = chainableBehavior.chainingBehavior;\n chainableBehavior.chainingBehavior = function () {\n var result = chainingBehavior(_chainingBehavior).call(this);\n return result === undefined ? this : result;\n };\n\n var _method = chainableBehavior.method;\n chainableBehavior.method = function () {\n var result = method(_method).apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n * return function (str) {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.value).to.equal(str);\n * } else {\n * _super.apply(this, arguments);\n * }\n * }\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n var _method = ctx[name]\n , _super = function () { return this; };\n\n if (_method && 'function' === typeof _method)\n _super = _method;\n\n ctx[name] = function () {\n var result = method(_super).apply(this, arguments);\n return result === undefined ? this : result;\n }\n};\n","/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n * return function () {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.name).to.equal('bar');\n * } else {\n * _super.call(this);\n * }\n * }\n * });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n var _get = Object.getOwnPropertyDescriptor(ctx, name)\n , _super = function () {};\n\n if (_get && 'function' === typeof _get.get)\n _super = _get.get\n\n Object.defineProperty(ctx, name,\n { get: function () {\n var result = getter(_super).call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , expr = args[0];\n return negate ? !expr : expr;\n};\n","/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n * var newAssertion = new Assertion();\n * utils.transferFlags(assertion, newAssertion);\n *\n * var anotherAsseriton = new Assertion(myObj);\n * utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n if (!object.__flags) {\n object.__flags = Object.create(null);\n }\n\n includeAll = arguments.length === 3 ? includeAll : true;\n\n for (var flag in flags) {\n if (includeAll ||\n (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n object.__flags[flag] = flags[flag];\n }\n }\n};\n","\"use strict\";\n\nfunction dedent(strings) {\n\n var raw = void 0;\n if (typeof strings === \"string\") {\n // dedent can be used as a plain function\n raw = [strings];\n } else {\n raw = strings.raw;\n }\n\n // first, perform interpolation\n var result = \"\";\n for (var i = 0; i < raw.length; i++) {\n result += raw[i].\n // join lines when there is a suppressed newline\n replace(/\\\\\\n[ \\t]*/g, \"\").\n\n // handle escaped backticks\n replace(/\\\\`/g, \"`\");\n\n if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) {\n result += arguments.length <= i + 1 ? undefined : arguments[i + 1];\n }\n }\n\n // now strip indentation\n var lines = result.split(\"\\n\");\n var mindent = null;\n lines.forEach(function (l) {\n var m = l.match(/^(\\s+)\\S+/);\n if (m) {\n var indent = m[1].length;\n if (!mindent) {\n // this is the first indented line\n mindent = indent;\n } else {\n mindent = Math.min(mindent, indent);\n }\n }\n });\n\n if (mindent !== null) {\n result = lines.map(function (l) {\n return l[0] === \" \" ? l.slice(mindent) : l;\n }).join(\"\\n\");\n }\n\n // dedent eats leading and trailing whitespace too\n result = result.trim();\n\n // handle escaped newlines at the end to ensure they don't get stripped too\n return result.replace(/\\\\n/g, \"\\n\");\n}\n\nif (typeof module !== \"undefined\") {\n module.exports = dedent;\n}\n","module.exports = require('./lib/eql');\n","/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n Buffer = {};\n Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n if (sameValue(a, b)) {\n return true;\n } else if ('date' === type(a)) {\n return dateEqual(a, b);\n } else if ('regexp' === type(a)) {\n return regexpEqual(a, b);\n } else if (Buffer.isBuffer(a)) {\n return bufferEqual(a, b);\n } else if ('arguments' === type(a)) {\n return argumentsEqual(a, b, m);\n } else if (!typeEqual(a, b)) {\n return false;\n } else if (('object' !== type(a) && 'object' !== type(b))\n && ('array' !== type(a) && 'array' !== type(b))) {\n return sameValue(a, b);\n } else {\n return objectEqual(a, b, m);\n }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n if (a === b) return a !== 0 || 1 / a === 1 / b;\n return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n if ('date' !== type(b)) return false;\n return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n if ('regexp' !== type(b)) return false;\n return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n if ('arguments' !== type(b)) return false;\n a = [].slice.call(a);\n b = [].slice.call(b);\n return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n var res = [];\n for (var key in a) res.push(key);\n return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n if (a.length !== b.length) return false;\n\n var i = 0;\n var match = true;\n\n for (; i < a.length; i++) {\n if (a[i] !== b[i]) {\n match = false;\n break;\n }\n }\n\n return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n if (!Buffer.isBuffer(b)) return false;\n return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n if (!isValue(a) || !isValue(b)) {\n return false;\n }\n\n if (a.prototype !== b.prototype) {\n return false;\n }\n\n var i;\n if (m) {\n for (i = 0; i < m.length; i++) {\n if ((m[i][0] === a && m[i][1] === b)\n || (m[i][0] === b && m[i][1] === a)) {\n return true;\n }\n }\n } else {\n m = [];\n }\n\n try {\n var ka = enumerable(a);\n var kb = enumerable(b);\n } catch (ex) {\n return false;\n }\n\n ka.sort();\n kb.sort();\n\n if (!iterableEqual(ka, kb)) {\n return false;\n }\n\n m.push([ a, b ]);\n\n var key;\n for (i = ka.length - 1; i >= 0; i--) {\n key = ka[i];\n if (!deepEqual(a[key], b[key], m)) {\n return false;\n }\n }\n\n return true;\n}\n","/*!\n localForage -- Offline Storage, Improved\n Version 1.5.0\n https://localforage.github.io/localForage\n (c) 2013-2017 Mozilla, Apache License 2.0\n*/\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.localforage = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw (f.code=\"MODULE_NOT_FOUND\", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o element; its readystatechange event will be fired asynchronously once it is inserted\n // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.\n var scriptEl = global.document.createElement('script');\n scriptEl.onreadystatechange = function () {\n nextTick();\n\n scriptEl.onreadystatechange = null;\n scriptEl.parentNode.removeChild(scriptEl);\n scriptEl = null;\n };\n global.document.documentElement.appendChild(scriptEl);\n };\n } else {\n scheduleDrain = function () {\n setTimeout(nextTick, 0);\n };\n }\n}\n\nvar draining;\nvar queue = [];\n//named nextTick for less confusing stack traces\nfunction nextTick() {\n draining = true;\n var i, oldQueue;\n var len = queue.length;\n while (len) {\n oldQueue = queue;\n queue = [];\n i = -1;\n while (++i < len) {\n oldQueue[i]();\n }\n len = queue.length;\n }\n draining = false;\n}\n\nmodule.exports = immediate;\nfunction immediate(task) {\n if (queue.push(task) === 1 && !draining) {\n scheduleDrain();\n }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],2:[function(_dereq_,module,exports){\n'use strict';\nvar immediate = _dereq_(1);\n\n/* istanbul ignore next */\nfunction INTERNAL() {}\n\nvar handlers = {};\n\nvar REJECTED = ['REJECTED'];\nvar FULFILLED = ['FULFILLED'];\nvar PENDING = ['PENDING'];\n\nmodule.exports = exports = Promise;\n\nfunction Promise(resolver) {\n if (typeof resolver !== 'function') {\n throw new TypeError('resolver must be a function');\n }\n this.state = PENDING;\n this.queue = [];\n this.outcome = void 0;\n if (resolver !== INTERNAL) {\n safelyResolveThenable(this, resolver);\n }\n}\n\nPromise.prototype[\"catch\"] = function (onRejected) {\n return this.then(null, onRejected);\n};\nPromise.prototype.then = function (onFulfilled, onRejected) {\n if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||\n typeof onRejected !== 'function' && this.state === REJECTED) {\n return this;\n }\n var promise = new this.constructor(INTERNAL);\n if (this.state !== PENDING) {\n var resolver = this.state === FULFILLED ? onFulfilled : onRejected;\n unwrap(promise, resolver, this.outcome);\n } else {\n this.queue.push(new QueueItem(promise, onFulfilled, onRejected));\n }\n\n return promise;\n};\nfunction QueueItem(promise, onFulfilled, onRejected) {\n this.promise = promise;\n if (typeof onFulfilled === 'function') {\n this.onFulfilled = onFulfilled;\n this.callFulfilled = this.otherCallFulfilled;\n }\n if (typeof onRejected === 'function') {\n this.onRejected = onRejected;\n this.callRejected = this.otherCallRejected;\n }\n}\nQueueItem.prototype.callFulfilled = function (value) {\n handlers.resolve(this.promise, value);\n};\nQueueItem.prototype.otherCallFulfilled = function (value) {\n unwrap(this.promise, this.onFulfilled, value);\n};\nQueueItem.prototype.callRejected = function (value) {\n handlers.reject(this.promise, value);\n};\nQueueItem.prototype.otherCallRejected = function (value) {\n unwrap(this.promise, this.onRejected, value);\n};\n\nfunction unwrap(promise, func, value) {\n immediate(function () {\n var returnValue;\n try {\n returnValue = func(value);\n } catch (e) {\n return handlers.reject(promise, e);\n }\n if (returnValue === promise) {\n handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));\n } else {\n handlers.resolve(promise, returnValue);\n }\n });\n}\n\nhandlers.resolve = function (self, value) {\n var result = tryCatch(getThen, value);\n if (result.status === 'error') {\n return handlers.reject(self, result.value);\n }\n var thenable = result.value;\n\n if (thenable) {\n safelyResolveThenable(self, thenable);\n } else {\n self.state = FULFILLED;\n self.outcome = value;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callFulfilled(value);\n }\n }\n return self;\n};\nhandlers.reject = function (self, error) {\n self.state = REJECTED;\n self.outcome = error;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callRejected(error);\n }\n return self;\n};\n\nfunction getThen(obj) {\n // Make sure we only access the accessor once as required by the spec\n var then = obj && obj.then;\n if (obj && typeof obj === 'object' && typeof then === 'function') {\n return function appyThen() {\n then.apply(obj, arguments);\n };\n }\n}\n\nfunction safelyResolveThenable(self, thenable) {\n // Either fulfill, reject or reject with error\n var called = false;\n function onError(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.reject(self, value);\n }\n\n function onSuccess(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.resolve(self, value);\n }\n\n function tryToUnwrap() {\n thenable(onSuccess, onError);\n }\n\n var result = tryCatch(tryToUnwrap);\n if (result.status === 'error') {\n onError(result.value);\n }\n}\n\nfunction tryCatch(func, value) {\n var out = {};\n try {\n out.value = func(value);\n out.status = 'success';\n } catch (e) {\n out.status = 'error';\n out.value = e;\n }\n return out;\n}\n\nexports.resolve = resolve;\nfunction resolve(value) {\n if (value instanceof this) {\n return value;\n }\n return handlers.resolve(new this(INTERNAL), value);\n}\n\nexports.reject = reject;\nfunction reject(reason) {\n var promise = new this(INTERNAL);\n return handlers.reject(promise, reason);\n}\n\nexports.all = all;\nfunction all(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var values = new Array(len);\n var resolved = 0;\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n allResolver(iterable[i], i);\n }\n return promise;\n function allResolver(value, i) {\n self.resolve(value).then(resolveFromAll, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n function resolveFromAll(outValue) {\n values[i] = outValue;\n if (++resolved === len && !called) {\n called = true;\n handlers.resolve(promise, values);\n }\n }\n }\n}\n\nexports.race = race;\nfunction race(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n resolver(iterable[i]);\n }\n return promise;\n function resolver(value) {\n self.resolve(value).then(function (response) {\n if (!called) {\n called = true;\n handlers.resolve(promise, response);\n }\n }, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n }\n}\n\n},{\"1\":1}],3:[function(_dereq_,module,exports){\n(function (global){\n'use strict';\nif (typeof global.Promise !== 'function') {\n global.Promise = _dereq_(2);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"2\":2}],4:[function(_dereq_,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction getIDB() {\n /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */\n try {\n if (typeof indexedDB !== 'undefined') {\n return indexedDB;\n }\n if (typeof webkitIndexedDB !== 'undefined') {\n return webkitIndexedDB;\n }\n if (typeof mozIndexedDB !== 'undefined') {\n return mozIndexedDB;\n }\n if (typeof OIndexedDB !== 'undefined') {\n return OIndexedDB;\n }\n if (typeof msIndexedDB !== 'undefined') {\n return msIndexedDB;\n }\n } catch (e) {}\n}\n\nvar idb = getIDB();\n\nfunction isIndexedDBValid() {\n try {\n // Initialize IndexedDB; fall back to vendor-prefixed versions\n // if needed.\n if (!idb) {\n return false;\n }\n // We mimic PouchDB here;\n //\n // We test for openDatabase because IE Mobile identifies itself\n // as Safari. Oh the lulz...\n var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform);\n\n var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1;\n\n // Safari <10.1 does not meet our requirements for IDB support (#5572)\n // since Safari 10.1 shipped with fetch, we can use that to detect it\n return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' &&\n // some outdated implementations of IDB that appear on Samsung\n // and HTC Android devices <4.4 are missing IDBKeyRange\n typeof IDBKeyRange !== 'undefined';\n } catch (e) {\n return false;\n }\n}\n\nfunction isWebSQLValid() {\n return typeof openDatabase === 'function';\n}\n\nfunction isLocalStorageValid() {\n try {\n return typeof localStorage !== 'undefined' && 'setItem' in localStorage && localStorage.setItem;\n } catch (e) {\n return false;\n }\n}\n\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\nfunction createBlob(parts, properties) {\n /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */\n parts = parts || [];\n properties = properties || {};\n try {\n return new Blob(parts, properties);\n } catch (e) {\n if (e.name !== 'TypeError') {\n throw e;\n }\n var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder;\n var builder = new Builder();\n for (var i = 0; i < parts.length; i += 1) {\n builder.append(parts[i]);\n }\n return builder.getBlob(properties.type);\n }\n}\n\n// This is CommonJS because lie is an external dependency, so Rollup\n// can just ignore it.\nif (typeof Promise === 'undefined') {\n // In the \"nopromises\" build this will just throw if you don't have\n // a global promise object, but it would throw anyway later.\n _dereq_(3);\n}\nvar Promise$1 = Promise;\n\nfunction executeCallback(promise, callback) {\n if (callback) {\n promise.then(function (result) {\n callback(null, result);\n }, function (error) {\n callback(error);\n });\n }\n}\n\nfunction executeTwoCallbacks(promise, callback, errorCallback) {\n if (typeof callback === 'function') {\n promise.then(callback);\n }\n\n if (typeof errorCallback === 'function') {\n promise[\"catch\"](errorCallback);\n }\n}\n\n// Some code originally from async_storage.js in\n// [Gaia](https://github.com/mozilla-b2g/gaia).\n\nvar DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support';\nvar supportsBlobs;\nvar dbContexts;\nvar toString = Object.prototype.toString;\n\n// Transform a binary string to an array buffer, because otherwise\n// weird stuff happens when you try to work with the binary string directly.\n// It is known.\n// From http://stackoverflow.com/questions/14967647/ (continues on next line)\n// encode-decode-image-with-base64-breaks-image (2013-04-21)\nfunction _binStringToArrayBuffer(bin) {\n var length = bin.length;\n var buf = new ArrayBuffer(length);\n var arr = new Uint8Array(buf);\n for (var i = 0; i < length; i++) {\n arr[i] = bin.charCodeAt(i);\n }\n return buf;\n}\n\n//\n// Blobs are not supported in all versions of IndexedDB, notably\n// Chrome <37 and Android <5. In those versions, storing a blob will throw.\n//\n// Various other blob bugs exist in Chrome v37-42 (inclusive).\n// Detecting them is expensive and confusing to users, and Chrome 37-42\n// is at very low usage worldwide, so we do a hacky userAgent check instead.\n//\n// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120\n// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916\n// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836\n//\n// Code borrowed from PouchDB. See:\n// https://github.com/pouchdb/pouchdb/blob/master/packages/node_modules/pouchdb-adapter-idb/src/blobSupport.js\n//\nfunction _checkBlobSupportWithoutCaching(idb) {\n return new Promise$1(function (resolve) {\n var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, 'readwrite');\n var blob = createBlob(['']);\n txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');\n\n txn.onabort = function (e) {\n // If the transaction aborts now its due to not being able to\n // write to the database, likely due to the disk being full\n e.preventDefault();\n e.stopPropagation();\n resolve(false);\n };\n\n txn.oncomplete = function () {\n var matchedChrome = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n var matchedEdge = navigator.userAgent.match(/Edge\\//);\n // MS Edge pretends to be Chrome 42:\n // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx\n resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43);\n };\n })[\"catch\"](function () {\n return false; // error, so assume unsupported\n });\n}\n\nfunction _checkBlobSupport(idb) {\n if (typeof supportsBlobs === 'boolean') {\n return Promise$1.resolve(supportsBlobs);\n }\n return _checkBlobSupportWithoutCaching(idb).then(function (value) {\n supportsBlobs = value;\n return supportsBlobs;\n });\n}\n\nfunction _deferReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Create a deferred object representing the current database operation.\n var deferredOperation = {};\n\n deferredOperation.promise = new Promise$1(function (resolve) {\n deferredOperation.resolve = resolve;\n });\n\n // Enqueue the deferred operation.\n dbContext.deferredOperations.push(deferredOperation);\n\n // Chain its promise to the database readiness.\n if (!dbContext.dbReady) {\n dbContext.dbReady = deferredOperation.promise;\n } else {\n dbContext.dbReady = dbContext.dbReady.then(function () {\n return deferredOperation.promise;\n });\n }\n}\n\nfunction _advanceReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Dequeue a deferred operation.\n var deferredOperation = dbContext.deferredOperations.pop();\n\n // Resolve its promise (which is part of the database readiness\n // chain of promises).\n if (deferredOperation) {\n deferredOperation.resolve();\n }\n}\n\nfunction _getConnection(dbInfo, upgradeNeeded) {\n return new Promise$1(function (resolve, reject) {\n\n if (dbInfo.db) {\n if (upgradeNeeded) {\n _deferReadiness(dbInfo);\n dbInfo.db.close();\n } else {\n return resolve(dbInfo.db);\n }\n }\n\n var dbArgs = [dbInfo.name];\n\n if (upgradeNeeded) {\n dbArgs.push(dbInfo.version);\n }\n\n var openreq = idb.open.apply(idb, dbArgs);\n\n if (upgradeNeeded) {\n openreq.onupgradeneeded = function (e) {\n var db = openreq.result;\n try {\n db.createObjectStore(dbInfo.storeName);\n if (e.oldVersion <= 1) {\n // Added when support for blob shims was added\n db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);\n }\n } catch (ex) {\n if (ex.name === 'ConstraintError') {\n console.warn('The database \"' + dbInfo.name + '\"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage \"' + dbInfo.storeName + '\" already exists.');\n } else {\n throw ex;\n }\n }\n };\n }\n\n openreq.onerror = function (e) {\n e.preventDefault();\n reject(openreq.error);\n };\n\n openreq.onsuccess = function () {\n resolve(openreq.result);\n _advanceReadiness(dbInfo);\n };\n });\n}\n\nfunction _getOriginalConnection(dbInfo) {\n return _getConnection(dbInfo, false);\n}\n\nfunction _getUpgradedConnection(dbInfo) {\n return _getConnection(dbInfo, true);\n}\n\nfunction _isUpgradeNeeded(dbInfo, defaultVersion) {\n if (!dbInfo.db) {\n return true;\n }\n\n var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName);\n var isDowngrade = dbInfo.version < dbInfo.db.version;\n var isUpgrade = dbInfo.version > dbInfo.db.version;\n\n if (isDowngrade) {\n // If the version is not the default one\n // then warn for impossible downgrade.\n if (dbInfo.version !== defaultVersion) {\n console.warn('The database \"' + dbInfo.name + '\"' + ' can\\'t be downgraded from version ' + dbInfo.db.version + ' to version ' + dbInfo.version + '.');\n }\n // Align the versions to prevent errors.\n dbInfo.version = dbInfo.db.version;\n }\n\n if (isUpgrade || isNewStore) {\n // If the store is new then increment the version (if needed).\n // This will trigger an \"upgradeneeded\" event which is required\n // for creating a store.\n if (isNewStore) {\n var incVersion = dbInfo.db.version + 1;\n if (incVersion > dbInfo.version) {\n dbInfo.version = incVersion;\n }\n }\n\n return true;\n }\n\n return false;\n}\n\n// encode a blob for indexeddb engines that don't support blobs\nfunction _encodeBlob(blob) {\n return new Promise$1(function (resolve, reject) {\n var reader = new FileReader();\n reader.onerror = reject;\n reader.onloadend = function (e) {\n var base64 = btoa(e.target.result || '');\n resolve({\n __local_forage_encoded_blob: true,\n data: base64,\n type: blob.type\n });\n };\n reader.readAsBinaryString(blob);\n });\n}\n\n// decode an encoded blob\nfunction _decodeBlob(encodedBlob) {\n var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data));\n return createBlob([arrayBuff], { type: encodedBlob.type });\n}\n\n// is this one of our fancy encoded blobs?\nfunction _isEncodedBlob(value) {\n return value && value.__local_forage_encoded_blob;\n}\n\n// Specialize the default `ready()` function by making it dependent\n// on the current database operations. Thus, the driver will be actually\n// ready when it's been initialized (default) *and* there are no pending\n// operations on the database (initiated by some other instances).\nfunction _fullyReady(callback) {\n var self = this;\n\n var promise = self._initReady().then(function () {\n var dbContext = dbContexts[self._dbInfo.name];\n\n if (dbContext && dbContext.dbReady) {\n return dbContext.dbReady;\n }\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n}\n\n// Open the IndexedDB database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n // Initialize a singleton container for all running localForages.\n if (!dbContexts) {\n dbContexts = {};\n }\n\n // Get the current context of the database;\n var dbContext = dbContexts[dbInfo.name];\n\n // ...or create a new context.\n if (!dbContext) {\n dbContext = {\n // Running localForages sharing a database.\n forages: [],\n // Shared database.\n db: null,\n // Database readiness (promise).\n dbReady: null,\n // Deferred operations on the database.\n deferredOperations: []\n };\n // Register the new context in the global container.\n dbContexts[dbInfo.name] = dbContext;\n }\n\n // Register itself as a running localForage in the current context.\n dbContext.forages.push(self);\n\n // Replace the default `ready()` function with the specialized one.\n if (!self._initReady) {\n self._initReady = self.ready;\n self.ready = _fullyReady;\n }\n\n // Create an array of initialization states of the related localForages.\n var initPromises = [];\n\n function ignoreErrors() {\n // Don't handle errors here,\n // just makes sure related localForages aren't pending.\n return Promise$1.resolve();\n }\n\n for (var j = 0; j < dbContext.forages.length; j++) {\n var forage = dbContext.forages[j];\n if (forage !== self) {\n // Don't wait for itself...\n initPromises.push(forage._initReady()[\"catch\"](ignoreErrors));\n }\n }\n\n // Take a snapshot of the related localForages.\n var forages = dbContext.forages.slice(0);\n\n // Initialize the connection process only when\n // all the related localForages aren't pending.\n return Promise$1.all(initPromises).then(function () {\n dbInfo.db = dbContext.db;\n // Get the connection or open a new one without upgrade.\n return _getOriginalConnection(dbInfo);\n }).then(function (db) {\n dbInfo.db = db;\n if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) {\n // Reopen the database for upgrading.\n return _getUpgradedConnection(dbInfo);\n }\n return db;\n }).then(function (db) {\n dbInfo.db = dbContext.db = db;\n self._dbInfo = dbInfo;\n // Share the final connection amongst related localForages.\n for (var k = 0; k < forages.length; k++) {\n var forage = forages[k];\n if (forage !== self) {\n // Self is already up-to-date.\n forage._dbInfo.db = dbInfo.db;\n forage._dbInfo.version = dbInfo.version;\n }\n }\n });\n}\n\nfunction getItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.get(key);\n\n req.onsuccess = function () {\n var value = req.result;\n if (value === undefined) {\n value = null;\n }\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n resolve(value);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items stored in database.\nfunction iterate(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var iterationNumber = 1;\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (cursor) {\n var value = cursor.value;\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n var result = iterator(value, cursor.key, iterationNumber++);\n\n if (result !== void 0) {\n resolve(result);\n } else {\n cursor[\"continue\"]();\n }\n } else {\n resolve();\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n\n return promise;\n}\n\nfunction setItem(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n var dbInfo;\n self.ready().then(function () {\n dbInfo = self._dbInfo;\n if (toString.call(value) === '[object Blob]') {\n return _checkBlobSupport(dbInfo.db).then(function (blobSupport) {\n if (blobSupport) {\n return value;\n }\n return _encodeBlob(value);\n });\n }\n return value;\n }).then(function (value) {\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.put(value, key);\n\n // The reason we don't _save_ null is because IE 10 does\n // not support saving the `null` type in IndexedDB. How\n // ironic, given the bug below!\n // See: https://github.com/mozilla/localForage/issues/161\n if (value === null) {\n value = undefined;\n }\n\n transaction.oncomplete = function () {\n // Cast to undefined so the value passed to\n // callback/promise is the same as what one would get out\n // of `getItem()` later. This leads to some weirdness\n // (setItem('foo', undefined) will return `null`), but\n // it's not my fault localStorage is our baseline and that\n // it's weird.\n if (value === undefined) {\n value = null;\n }\n\n resolve(value);\n };\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction removeItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n\n // We use a Grunt task to make this safe for IE and some\n // versions of Android (including those used by Cordova).\n // Normally IE won't like `.delete()` and will insist on\n // using `['delete']()`, but we have a build step that\n // fixes this for us now.\n var req = store[\"delete\"](key);\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onerror = function () {\n reject(req.error);\n };\n\n // The request will be also be aborted if we've exceeded our storage\n // space.\n transaction.onabort = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction clear(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.clear();\n\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction length(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.count();\n\n req.onsuccess = function () {\n resolve(req.result);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction key(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n if (n < 0) {\n resolve(null);\n\n return;\n }\n\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var advanced = false;\n var req = store.openCursor();\n req.onsuccess = function () {\n var cursor = req.result;\n if (!cursor) {\n // this means there weren't enough keys\n resolve(null);\n\n return;\n }\n\n if (n === 0) {\n // We have the first key, return it if that's what they\n // wanted.\n resolve(cursor.key);\n } else {\n if (!advanced) {\n // Otherwise, ask the cursor to skip ahead n\n // records.\n advanced = true;\n cursor.advance(n);\n } else {\n // When we get here, we've got the nth key.\n resolve(cursor.key);\n }\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var keys = [];\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (!cursor) {\n resolve(keys);\n return;\n }\n\n keys.push(cursor.key);\n cursor[\"continue\"]();\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar asyncStorage = {\n _driver: 'asyncStorage',\n _initStorage: _initStorage,\n iterate: iterate,\n getItem: getItem,\n setItem: setItem,\n removeItem: removeItem,\n clear: clear,\n length: length,\n key: key,\n keys: keys\n};\n\n// Sadly, the best way to save binary data in WebSQL/localStorage is serializing\n// it to Base64, so this is how we store it to prevent very strange errors with less\n// verbose ways of binary <-> string data storage.\nvar BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\nvar BLOB_TYPE_PREFIX = '~~local_forage_type~';\nvar BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;\n\nvar SERIALIZED_MARKER = '__lfsc__:';\nvar SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;\n\n// OMG the serializations!\nvar TYPE_ARRAYBUFFER = 'arbf';\nvar TYPE_BLOB = 'blob';\nvar TYPE_INT8ARRAY = 'si08';\nvar TYPE_UINT8ARRAY = 'ui08';\nvar TYPE_UINT8CLAMPEDARRAY = 'uic8';\nvar TYPE_INT16ARRAY = 'si16';\nvar TYPE_INT32ARRAY = 'si32';\nvar TYPE_UINT16ARRAY = 'ur16';\nvar TYPE_UINT32ARRAY = 'ui32';\nvar TYPE_FLOAT32ARRAY = 'fl32';\nvar TYPE_FLOAT64ARRAY = 'fl64';\nvar TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;\n\nvar toString$1 = Object.prototype.toString;\n\nfunction stringToBuffer(serializedString) {\n // Fill the string into a ArrayBuffer.\n var bufferLength = serializedString.length * 0.75;\n var len = serializedString.length;\n var i;\n var p = 0;\n var encoded1, encoded2, encoded3, encoded4;\n\n if (serializedString[serializedString.length - 1] === '=') {\n bufferLength--;\n if (serializedString[serializedString.length - 2] === '=') {\n bufferLength--;\n }\n }\n\n var buffer = new ArrayBuffer(bufferLength);\n var bytes = new Uint8Array(buffer);\n\n for (i = 0; i < len; i += 4) {\n encoded1 = BASE_CHARS.indexOf(serializedString[i]);\n encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);\n encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);\n encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);\n\n /*jslint bitwise: true */\n bytes[p++] = encoded1 << 2 | encoded2 >> 4;\n bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;\n bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;\n }\n return buffer;\n}\n\n// Converts a buffer to a string to store, serialized, in the backend\n// storage library.\nfunction bufferToString(buffer) {\n // base64-arraybuffer\n var bytes = new Uint8Array(buffer);\n var base64String = '';\n var i;\n\n for (i = 0; i < bytes.length; i += 3) {\n /*jslint bitwise: true */\n base64String += BASE_CHARS[bytes[i] >> 2];\n base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];\n base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];\n base64String += BASE_CHARS[bytes[i + 2] & 63];\n }\n\n if (bytes.length % 3 === 2) {\n base64String = base64String.substring(0, base64String.length - 1) + '=';\n } else if (bytes.length % 3 === 1) {\n base64String = base64String.substring(0, base64String.length - 2) + '==';\n }\n\n return base64String;\n}\n\n// Serialize a value, afterwards executing a callback (which usually\n// instructs the `setItem()` callback/promise to be executed). This is how\n// we store binary data with localStorage.\nfunction serialize(value, callback) {\n var valueType = '';\n if (value) {\n valueType = toString$1.call(value);\n }\n\n // Cannot use `value instanceof ArrayBuffer` or such here, as these\n // checks fail when running the tests using casper.js...\n //\n // TODO: See why those tests fail and use a better solution.\n if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) {\n // Convert binary arrays to a string and prefix the string with\n // a special marker.\n var buffer;\n var marker = SERIALIZED_MARKER;\n\n if (value instanceof ArrayBuffer) {\n buffer = value;\n marker += TYPE_ARRAYBUFFER;\n } else {\n buffer = value.buffer;\n\n if (valueType === '[object Int8Array]') {\n marker += TYPE_INT8ARRAY;\n } else if (valueType === '[object Uint8Array]') {\n marker += TYPE_UINT8ARRAY;\n } else if (valueType === '[object Uint8ClampedArray]') {\n marker += TYPE_UINT8CLAMPEDARRAY;\n } else if (valueType === '[object Int16Array]') {\n marker += TYPE_INT16ARRAY;\n } else if (valueType === '[object Uint16Array]') {\n marker += TYPE_UINT16ARRAY;\n } else if (valueType === '[object Int32Array]') {\n marker += TYPE_INT32ARRAY;\n } else if (valueType === '[object Uint32Array]') {\n marker += TYPE_UINT32ARRAY;\n } else if (valueType === '[object Float32Array]') {\n marker += TYPE_FLOAT32ARRAY;\n } else if (valueType === '[object Float64Array]') {\n marker += TYPE_FLOAT64ARRAY;\n } else {\n callback(new Error('Failed to get type for BinaryArray'));\n }\n }\n\n callback(marker + bufferToString(buffer));\n } else if (valueType === '[object Blob]') {\n // Conver the blob to a binaryArray and then to a string.\n var fileReader = new FileReader();\n\n fileReader.onload = function () {\n // Backwards-compatible prefix for the blob type.\n var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result);\n\n callback(SERIALIZED_MARKER + TYPE_BLOB + str);\n };\n\n fileReader.readAsArrayBuffer(value);\n } else {\n try {\n callback(JSON.stringify(value));\n } catch (e) {\n console.error(\"Couldn't convert value into a JSON string: \", value);\n\n callback(null, e);\n }\n }\n}\n\n// Deserialize data we've inserted into a value column/field. We place\n// special markers into our strings to mark them as encoded; this isn't\n// as nice as a meta field, but it's the only sane thing we can do whilst\n// keeping localStorage support intact.\n//\n// Oftentimes this will just deserialize JSON content, but if we have a\n// special marker (SERIALIZED_MARKER, defined above), we will extract\n// some kind of arraybuffer/binary data/typed array out of the string.\nfunction deserialize(value) {\n // If we haven't marked this string as being specially serialized (i.e.\n // something other than serialized JSON), we can just return it and be\n // done with it.\n if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {\n return JSON.parse(value);\n }\n\n // The following code deals with deserializing some kind of Blob or\n // TypedArray. First we separate out the type of data we're dealing\n // with from the data itself.\n var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);\n var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH);\n\n var blobType;\n // Backwards-compatible blob type serialization strategy.\n // DBs created with older versions of localForage will simply not have the blob type.\n if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {\n var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);\n blobType = matcher[1];\n serializedString = serializedString.substring(matcher[0].length);\n }\n var buffer = stringToBuffer(serializedString);\n\n // Return the right type based on the code/type set during\n // serialization.\n switch (type) {\n case TYPE_ARRAYBUFFER:\n return buffer;\n case TYPE_BLOB:\n return createBlob([buffer], { type: blobType });\n case TYPE_INT8ARRAY:\n return new Int8Array(buffer);\n case TYPE_UINT8ARRAY:\n return new Uint8Array(buffer);\n case TYPE_UINT8CLAMPEDARRAY:\n return new Uint8ClampedArray(buffer);\n case TYPE_INT16ARRAY:\n return new Int16Array(buffer);\n case TYPE_UINT16ARRAY:\n return new Uint16Array(buffer);\n case TYPE_INT32ARRAY:\n return new Int32Array(buffer);\n case TYPE_UINT32ARRAY:\n return new Uint32Array(buffer);\n case TYPE_FLOAT32ARRAY:\n return new Float32Array(buffer);\n case TYPE_FLOAT64ARRAY:\n return new Float64Array(buffer);\n default:\n throw new Error('Unkown type: ' + type);\n }\n}\n\nvar localforageSerializer = {\n serialize: serialize,\n deserialize: deserialize,\n stringToBuffer: stringToBuffer,\n bufferToString: bufferToString\n};\n\n/*\n * Includes code from:\n *\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n// Open the WebSQL database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage$1(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i];\n }\n }\n\n var dbInfoPromise = new Promise$1(function (resolve, reject) {\n // Open the database; the openDatabase API will automatically\n // create it for us if it doesn't exist.\n try {\n dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size);\n } catch (e) {\n return reject(e);\n }\n\n // Create our key/value table if it doesn't exist.\n dbInfo.db.transaction(function (t) {\n t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' (id INTEGER PRIMARY KEY, key unique, value)', [], function () {\n self._dbInfo = dbInfo;\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n });\n\n dbInfo.serializer = localforageSerializer;\n return dbInfoPromise;\n}\n\nfunction getItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).value : null;\n\n // Check to see if this is serialized content we need to\n // unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction iterate$1(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName, [], function (t, results) {\n var rows = results.rows;\n var length = rows.length;\n\n for (var i = 0; i < length; i++) {\n var item = rows.item(i);\n var result = item.value;\n\n // Check to see if this is serialized content\n // we need to unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n result = iterator(result, item.key, i + 1);\n\n // void(0) prevents problems with redefinition\n // of `undefined`.\n if (result !== void 0) {\n resolve(result);\n return;\n }\n }\n\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction _setItem(key, value, callback, retriesLeft) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n // The localStorage API doesn't return undefined values in an\n // \"expected\" way, so undefined is always cast to null in all\n // drivers. See: https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n dbInfo.db.transaction(function (t) {\n t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + ' (key, value) VALUES (?, ?)', [key, value], function () {\n resolve(originalValue);\n }, function (t, error) {\n reject(error);\n });\n }, function (sqlError) {\n // The transaction failed; check\n // to see if it's a quota error.\n if (sqlError.code === sqlError.QUOTA_ERR) {\n // We reject the callback outright for now, but\n // it's worth trying to re-run the transaction.\n // Even if the user accepts the prompt to use\n // more storage on Safari, this error will\n // be called.\n //\n // Try to re-run the transaction.\n if (retriesLeft > 0) {\n resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1]));\n return;\n }\n reject(sqlError);\n }\n });\n }\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction setItem$1(key, value, callback) {\n return _setItem.apply(this, [key, value, callback, 1]);\n}\n\nfunction removeItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () {\n resolve();\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Deletes every item in the table.\n// TODO: Find out if this resets the AUTO_INCREMENT number.\nfunction clear$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function () {\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Does a simple `COUNT(key)` to get the number of items stored in\n// localForage.\nfunction length$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n // Ahhh, SQL makes this one soooooo easy.\n t.executeSql('SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) {\n var result = results.rows.item(0).c;\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Return the key located at key index X; essentially gets the key from a\n// `WHERE id = ?`. This is the most efficient way I can think to implement\n// this rarely-used (in my experience) part of the API, but it can seem\n// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so\n// the ID of each key will change every time it's updated. Perhaps a stored\n// procedure for the `setItem()` SQL would solve this problem?\n// TODO: Don't change ID on `setItem()`.\nfunction key$1(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).key : null;\n resolve(result);\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName, [], function (t, results) {\n var keys = [];\n\n for (var i = 0; i < results.rows.length; i++) {\n keys.push(results.rows.item(i).key);\n }\n\n resolve(keys);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar webSQLStorage = {\n _driver: 'webSQLStorage',\n _initStorage: _initStorage$1,\n iterate: iterate$1,\n getItem: getItem$1,\n setItem: setItem$1,\n removeItem: removeItem$1,\n clear: clear$1,\n length: length$1,\n key: key$1,\n keys: keys$1\n};\n\n// Config the localStorage backend, using options set in the config.\nfunction _initStorage$2(options) {\n var self = this;\n var dbInfo = {};\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n dbInfo.keyPrefix = dbInfo.name + '/';\n\n if (dbInfo.storeName !== self._defaultConfig.storeName) {\n dbInfo.keyPrefix += dbInfo.storeName + '/';\n }\n\n self._dbInfo = dbInfo;\n dbInfo.serializer = localforageSerializer;\n\n return Promise$1.resolve();\n}\n\n// Remove all keys from the datastore, effectively destroying all data in\n// the app's key/value store!\nfunction clear$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var keyPrefix = self._dbInfo.keyPrefix;\n\n for (var i = localStorage.length - 1; i >= 0; i--) {\n var key = localStorage.key(i);\n\n if (key.indexOf(keyPrefix) === 0) {\n localStorage.removeItem(key);\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Retrieve an item from the store. Unlike the original async_storage\n// library in Gaia, we don't modify return values at all. If a key's value\n// is `undefined`, we pass that value to the callback function.\nfunction getItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result = localStorage.getItem(dbInfo.keyPrefix + key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the key\n // is likely undefined and we'll pass it straight to the\n // callback.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items in the store.\nfunction iterate$2(iterator, callback) {\n var self = this;\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var keyPrefix = dbInfo.keyPrefix;\n var keyPrefixLength = keyPrefix.length;\n var length = localStorage.length;\n\n // We use a dedicated iterator instead of the `i` variable below\n // so other keys we fetch in localStorage aren't counted in\n // the `iterationNumber` argument passed to the `iterate()`\n // callback.\n //\n // See: github.com/mozilla/localForage/pull/435#discussion_r38061530\n var iterationNumber = 1;\n\n for (var i = 0; i < length; i++) {\n var key = localStorage.key(i);\n if (key.indexOf(keyPrefix) !== 0) {\n continue;\n }\n var value = localStorage.getItem(key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the\n // key is likely undefined and we'll pass it straight\n // to the iterator.\n if (value) {\n value = dbInfo.serializer.deserialize(value);\n }\n\n value = iterator(value, key.substring(keyPrefixLength), iterationNumber++);\n\n if (value !== void 0) {\n return value;\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Same as localStorage's key() method, except takes a callback.\nfunction key$2(n, callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result;\n try {\n result = localStorage.key(n);\n } catch (error) {\n result = null;\n }\n\n // Remove the prefix from the key, if a key is found.\n if (result) {\n result = result.substring(dbInfo.keyPrefix.length);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var length = localStorage.length;\n var keys = [];\n\n for (var i = 0; i < length; i++) {\n if (localStorage.key(i).indexOf(dbInfo.keyPrefix) === 0) {\n keys.push(localStorage.key(i).substring(dbInfo.keyPrefix.length));\n }\n }\n\n return keys;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Supply the number of keys in the datastore to the callback function.\nfunction length$2(callback) {\n var self = this;\n var promise = self.keys().then(function (keys) {\n return keys.length;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Remove an item from the store, nice and simple.\nfunction removeItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n localStorage.removeItem(dbInfo.keyPrefix + key);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Set a key's value and run an optional callback once the value is set.\n// Unlike Gaia's implementation, the callback function is passed the value,\n// in case you want to operate on that value only after you're sure it\n// saved, or something like that.\nfunction setItem$2(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n // Convert undefined values to null.\n // https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n return new Promise$1(function (resolve, reject) {\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n try {\n localStorage.setItem(dbInfo.keyPrefix + key, value);\n resolve(originalValue);\n } catch (e) {\n // localStorage capacity exceeded.\n // TODO: Make this a specific error/event.\n if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {\n reject(e);\n }\n reject(e);\n }\n }\n });\n });\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar localStorageWrapper = {\n _driver: 'localStorageWrapper',\n _initStorage: _initStorage$2,\n // Default API, from Gaia/localStorage.\n iterate: iterate$2,\n getItem: getItem$2,\n setItem: setItem$2,\n removeItem: removeItem$2,\n clear: clear$2,\n length: length$2,\n key: key$2,\n keys: keys$2\n};\n\n// Custom drivers are stored here when `defineDriver()` is called.\n// They are shared across all instances of localForage.\nvar CustomDrivers = {};\n\nvar DriverType = {\n INDEXEDDB: 'asyncStorage',\n LOCALSTORAGE: 'localStorageWrapper',\n WEBSQL: 'webSQLStorage'\n};\n\nvar DefaultDriverOrder = [DriverType.INDEXEDDB, DriverType.WEBSQL, DriverType.LOCALSTORAGE];\n\nvar LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem'];\n\nvar DefaultConfig = {\n description: '',\n driver: DefaultDriverOrder.slice(),\n name: 'localforage',\n // Default DB size is _JUST UNDER_ 5MB, as it's the highest size\n // we can use without a prompt.\n size: 4980736,\n storeName: 'keyvaluepairs',\n version: 1.0\n};\n\nvar driverSupport = {};\n// Check to see if IndexedDB is available and if it is the latest\n// implementation; it's our preferred backend library. We use \"_spec_test\"\n// as the name of the database because it's not the one we'll operate on,\n// but it's useful to make sure its using the right spec.\n// See: https://github.com/mozilla/localForage/issues/128\ndriverSupport[DriverType.INDEXEDDB] = isIndexedDBValid();\n\ndriverSupport[DriverType.WEBSQL] = isWebSQLValid();\n\ndriverSupport[DriverType.LOCALSTORAGE] = isLocalStorageValid();\n\nvar isArray = Array.isArray || function (arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n};\n\nfunction callWhenReady(localForageInstance, libraryMethod) {\n localForageInstance[libraryMethod] = function () {\n var _args = arguments;\n return localForageInstance.ready().then(function () {\n return localForageInstance[libraryMethod].apply(localForageInstance, _args);\n });\n };\n}\n\nfunction extend() {\n for (var i = 1; i < arguments.length; i++) {\n var arg = arguments[i];\n\n if (arg) {\n for (var key in arg) {\n if (arg.hasOwnProperty(key)) {\n if (isArray(arg[key])) {\n arguments[0][key] = arg[key].slice();\n } else {\n arguments[0][key] = arg[key];\n }\n }\n }\n }\n }\n\n return arguments[0];\n}\n\nfunction isLibraryDriver(driverName) {\n for (var driver in DriverType) {\n if (DriverType.hasOwnProperty(driver) && DriverType[driver] === driverName) {\n return true;\n }\n }\n\n return false;\n}\n\nvar LocalForage = function () {\n function LocalForage(options) {\n _classCallCheck(this, LocalForage);\n\n this.INDEXEDDB = DriverType.INDEXEDDB;\n this.LOCALSTORAGE = DriverType.LOCALSTORAGE;\n this.WEBSQL = DriverType.WEBSQL;\n\n this._defaultConfig = extend({}, DefaultConfig);\n this._config = extend({}, this._defaultConfig, options);\n this._driverSet = null;\n this._initDriver = null;\n this._ready = false;\n this._dbInfo = null;\n\n this._wrapLibraryMethodsWithReady();\n this.setDriver(this._config.driver)[\"catch\"](function () {});\n }\n\n // Set any config values for localForage; can be called anytime before\n // the first API call (e.g. `getItem`, `setItem`).\n // We loop through options so we don't overwrite existing config\n // values.\n\n\n LocalForage.prototype.config = function config(options) {\n // If the options argument is an object, we use it to set values.\n // Otherwise, we return either a specified config value or all\n // config values.\n if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {\n // If localforage is ready and fully initialized, we can't set\n // any new configuration values. Instead, we return an error.\n if (this._ready) {\n return new Error(\"Can't call config() after localforage \" + 'has been used.');\n }\n\n for (var i in options) {\n if (i === 'storeName') {\n options[i] = options[i].replace(/\\W/g, '_');\n }\n\n if (i === 'version' && typeof options[i] !== 'number') {\n return new Error('Database version must be a number.');\n }\n\n this._config[i] = options[i];\n }\n\n // after all config options are set and\n // the driver option is used, try setting it\n if ('driver' in options && options.driver) {\n return this.setDriver(this._config.driver);\n }\n\n return true;\n } else if (typeof options === 'string') {\n return this._config[options];\n } else {\n return this._config;\n }\n };\n\n // Used to define a custom driver, shared across all instances of\n // localForage.\n\n\n LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) {\n var promise = new Promise$1(function (resolve, reject) {\n try {\n var driverName = driverObject._driver;\n var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver');\n var namingError = new Error('Custom driver name already in use: ' + driverObject._driver);\n\n // A driver name should be defined and not overlap with the\n // library-defined, default drivers.\n if (!driverObject._driver) {\n reject(complianceError);\n return;\n }\n if (isLibraryDriver(driverObject._driver)) {\n reject(namingError);\n return;\n }\n\n var customDriverMethods = LibraryMethods.concat('_initStorage');\n for (var i = 0; i < customDriverMethods.length; i++) {\n var customDriverMethod = customDriverMethods[i];\n if (!customDriverMethod || !driverObject[customDriverMethod] || typeof driverObject[customDriverMethod] !== 'function') {\n reject(complianceError);\n return;\n }\n }\n\n var supportPromise = Promise$1.resolve(true);\n if ('_support' in driverObject) {\n if (driverObject._support && typeof driverObject._support === 'function') {\n supportPromise = driverObject._support();\n } else {\n supportPromise = Promise$1.resolve(!!driverObject._support);\n }\n }\n\n supportPromise.then(function (supportResult) {\n driverSupport[driverName] = supportResult;\n CustomDrivers[driverName] = driverObject;\n resolve();\n }, reject);\n } catch (e) {\n reject(e);\n }\n });\n\n executeTwoCallbacks(promise, callback, errorCallback);\n return promise;\n };\n\n LocalForage.prototype.driver = function driver() {\n return this._driver || null;\n };\n\n LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) {\n var self = this;\n var getDriverPromise = Promise$1.resolve().then(function () {\n if (isLibraryDriver(driverName)) {\n switch (driverName) {\n case self.INDEXEDDB:\n return asyncStorage;\n case self.LOCALSTORAGE:\n return localStorageWrapper;\n case self.WEBSQL:\n return webSQLStorage;\n }\n } else if (CustomDrivers[driverName]) {\n return CustomDrivers[driverName];\n } else {\n throw new Error('Driver not found.');\n }\n });\n executeTwoCallbacks(getDriverPromise, callback, errorCallback);\n return getDriverPromise;\n };\n\n LocalForage.prototype.getSerializer = function getSerializer(callback) {\n var serializerPromise = Promise$1.resolve(localforageSerializer);\n executeTwoCallbacks(serializerPromise, callback);\n return serializerPromise;\n };\n\n LocalForage.prototype.ready = function ready(callback) {\n var self = this;\n\n var promise = self._driverSet.then(function () {\n if (self._ready === null) {\n self._ready = self._initDriver();\n }\n\n return self._ready;\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n };\n\n LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) {\n var self = this;\n\n if (!isArray(drivers)) {\n drivers = [drivers];\n }\n\n var supportedDrivers = this._getSupportedDrivers(drivers);\n\n function setDriverToConfig() {\n self._config.driver = self.driver();\n }\n\n function extendSelfWithDriver(driver) {\n self._extend(driver);\n setDriverToConfig();\n\n self._ready = self._initStorage(self._config);\n return self._ready;\n }\n\n function initDriver(supportedDrivers) {\n return function () {\n var currentDriverIndex = 0;\n\n function driverPromiseLoop() {\n while (currentDriverIndex < supportedDrivers.length) {\n var driverName = supportedDrivers[currentDriverIndex];\n currentDriverIndex++;\n\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(extendSelfWithDriver)[\"catch\"](driverPromiseLoop);\n }\n\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n }\n\n return driverPromiseLoop();\n };\n }\n\n // There might be a driver initialization in progress\n // so wait for it to finish in order to avoid a possible\n // race condition to set _dbInfo\n var oldDriverSetDone = this._driverSet !== null ? this._driverSet[\"catch\"](function () {\n return Promise$1.resolve();\n }) : Promise$1.resolve();\n\n this._driverSet = oldDriverSetDone.then(function () {\n var driverName = supportedDrivers[0];\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(function (driver) {\n self._driver = driver._driver;\n setDriverToConfig();\n self._wrapLibraryMethodsWithReady();\n self._initDriver = initDriver(supportedDrivers);\n });\n })[\"catch\"](function () {\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n });\n\n executeTwoCallbacks(this._driverSet, callback, errorCallback);\n return this._driverSet;\n };\n\n LocalForage.prototype.supports = function supports(driverName) {\n return !!driverSupport[driverName];\n };\n\n LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) {\n extend(this, libraryMethodsAndProperties);\n };\n\n LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) {\n var supportedDrivers = [];\n for (var i = 0, len = drivers.length; i < len; i++) {\n var driverName = drivers[i];\n if (this.supports(driverName)) {\n supportedDrivers.push(driverName);\n }\n }\n return supportedDrivers;\n };\n\n LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() {\n // Add a stub for each driver API method that delays the call to the\n // corresponding driver method until localForage is ready. These stubs\n // will be replaced by the driver methods as soon as the driver is\n // loaded, so there is no performance impact.\n for (var i = 0; i < LibraryMethods.length; i++) {\n callWhenReady(this, LibraryMethods[i]);\n }\n };\n\n LocalForage.prototype.createInstance = function createInstance(options) {\n return new LocalForage(options);\n };\n\n return LocalForage;\n}();\n\n// The actual localForage object that we expose as a module or via a\n// global. It's extended by pulling in one of our other libraries.\n\n\nvar localforage_js = new LocalForage();\n\nmodule.exports = localforage_js;\n\n},{\"3\":3}]},{},[4])(4)\n});","const initial = require('./problems/initial');\nconst arrays = require('./problems/arrays');\n\nmodule.exports = {\n initial: initial,\n arrays: arrays\n};\n","module.exports = [\n {\n name: 'Access Array by index (first)',\n time: 10,\n prompt: 'Return the first value of the Array',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits[0];`,\n tests: [\n {\n name: 'Correct output',\n test: 'assert.deepEqual(output, \\'apple\\') === undefined'\n },\n {\n name: 'Returns a String',\n test: 'assert.isString(output) === undefined'\n }\n ]\n },\n {\n name: 'Access Array by index (last)',\n time: 10,\n prompt: 'Return the last value of the Array',\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n return fruits[fruits.length - 1];`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 'orange') === undefined;`\n },\n {\n name: 'Returns a String',\n test: `assert.isString(output) === undefined;`\n }\n ]\n },\n {\n name: 'Access Array by index (second)',\n time: 10,\n prompt: 'Return the second value of the Array',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits[1];`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 'banana') === undefined;`\n },\n {\n name: 'Returns a String',\n test: `assert.isString(output) === undefined;`\n }\n ]\n },\n {\n name: 'Array.forEach()',\n time: 20,\n prompt: 'Loop over the array, add an \\'x\\' to the end of each name, push each fruit into a new array, then return the new array.',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n const newFruits = [];\n fruits.forEach(function(item) {\n newFruits.push(item+'x');\n });\n return newFruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['applex', 'bananax']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.push()',\n time: 10,\n prompt: `Add 'orange' to the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n fruits.push('orange');\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `(assert.deepEqual(output, ['apple', 'banana', 'orange']) === undefined);`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n }\n ]\n },\n {\n name: 'Array.shift()',\n time: 10,\n prompt: `Remove 'apple' from the front of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.shift();\n return fruits;`,\n tests: [\n {\n name: 'Output must be correct',\n test: `assert.deepEqual(output, ['banana', 'orange']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.unshift()',\n time: 10,\n prompt: `Add 'strawberry' to the front of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.unshift('strawberry');\n return fruits;`,\n tests: [\n {\n name: 'Output must be correct',\n test: `(assert.deepEqual(output, [\n 'strawberry',\n 'apple',\n 'banana',\n 'orange'\n ]) === undefined)`\n },\n {\n name: 'Must return an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 4 items',\n test: `assert.lengthOf(output, 4) === undefined;`\n }\n ]\n },\n {\n name: 'Array.indexOf()',\n time: 10,\n prompt: `Return the index of 'banana' in the Array.`,\n given: `const fruits = ['strawberry', 'banana', 'mango'];\\r`,\n answer: `const fruits = ['strawberry', 'banana', 'mango'];\n const ind = fruits.indexOf('banana');\n return ind;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 1) === undefined;`\n },\n {\n name: 'Returns a Number',\n test: `assert.isNumber(output) === undefined;`\n }\n ]\n },\n {\n name: 'Array.concat()',\n time: 10,\n prompt: `Merge the two arrays using Array's 'concat()' method. Return the resulting array.`,\n given: `const fruits = ['strawberry', 'banana'];\\rconst otherFruits = ['pear','peach'];\\r`,\n answer: `const fruits = ['strawberry', 'banana'];\n const otherFruits = ['pear','peach'];\n const allTheFruits = fruits.concat(otherFruits);\n return allTheFruits;\\r`,\n tests: [\n {\n name: 'Correct output',\n test: `(assert.deepEqual(output, [\n 'strawberry',\n 'banana',\n 'pear',\n 'peach'\n ]) === undefined\n );`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 4 items',\n test: `assert.lengthOf(output, 4) === undefined;`\n }\n ]\n },\n {\n name: 'Array.join()',\n time: 10,\n prompt: `Mix the two flavors with a '-' using Array's 'join' method. Return the resulting hybrid flavor.`,\n given: `const fruits = ['strawberry', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'banana'];\n const hybrid = fruits.join('-');\n return hybrid;\\r`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 'strawberry-banana') === undefined;`\n },\n {\n name: 'Returns a String',\n test: `assert.isString(output) === undefined;`\n }\n ]\n },\n {\n name: 'Array.slice()',\n time: 20,\n prompt: `Return just the citrus fruits from the 'fruits' array using 'Array.slice()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const citrus = fruits.slice(1, 3);\n return citrus;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['orange', 'lemon']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.reverse()',\n time: 10,\n prompt: `Reverse the order of the 'fruit' array using 'Array.reverse()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const stiurf = fruits.reverse();\n return stiurf;`,\n tests: [\n {\n name: 'Correct output',\n test: `(assert.deepEqual(output, [\n 'banana',\n 'lemon',\n 'orange',\n 'strawberry'\n ]) === undefined);`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 4 items',\n test: `assert.lengthOf(output, 4) === undefined;`\n },\n {\n name: `First item is 'banana'`,\n test: `assert.deepEqual(output[0], 'banana') === undefined;`\n }\n ]\n },\n {\n name: 'Array.sort()',\n time: 10,\n prompt: `Return the 'fruits' Array after sorting them using 'Array.sort()'.`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const orderlyFruit = fruits.sort();\n return orderlyFruit;`,\n tests: [\n {\n name: 'Correct output',\n test: `(assert.deepEqual(output, [\n 'banana',\n 'lemon',\n 'orange',\n 'strawberry'\n ]) === undefined);`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 4 items',\n test: `assert.lengthOf(output, 4) === undefined;`\n },\n {\n name: `First item is 'banana'`,\n test: `assert.deepEqual(output[0], 'banana') === undefined;`\n }\n ]\n },\n {\n name: 'Array.lastIndexOf()',\n time: 10,\n prompt: `Return the index of the last 'peach' instance in the 'fruit' array using 'Array.lastIndexOf()'`,\n given: `const fruits = ['peach', 'orange', 'lemon', 'peach'];\\r`,\n answer: `const fruits = ['peach', 'orange', 'lemon', 'peach'];\n const wheresTheLastPeach = fruits.lastIndexOf('peach');\n return wheresTheLastPeach;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 3) === undefined;`\n },\n {\n name: 'Returns a Number',\n test: `assert.isNumber(output) === undefined;`\n }\n ]\n },\n {\n name: 'Array.filter()',\n time: 10,\n prompt: `Return an array of the numbers greater than 5 in 'numbers' using 'Array.filter()'`,\n given: `const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\\r`,\n answer: `const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\n const overFive = numbers.filter(num => num > 5);\n return overFive;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, [8, 13, 21]) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n },\n {\n name: `First item is 8`,\n test: `assert.deepEqual(output[0], 8) === undefined;`\n }\n ]\n },\n {\n name: 'Array.map()',\n time: 10,\n prompt: `Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,\n given: `const numbers = [25, 121, 169];\\r`,\n answer: `const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, [5, 11, 13]) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n },\n {\n name: `First item is 5`,\n test: `assert.deepEqual(output[0], 5) === undefined;`\n },\n {\n name: `Last item is 13`,\n test: `assert.deepEqual(output[output.length - 1], 13) === undefined;`\n }\n ]\n },\n {\n name: 'Array.every()',\n time: 10,\n prompt: `Return object that returns whether each array contains all even numbers using Array.every().`,\n given: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,\n answer: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n return element % 2 === 0\n }\n return {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n };`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;`\n },\n {\n name: 'Returns an Object',\n test: `assert.isObject(output) === undefined;`\n },\n {\n name: 'Object has 2 items',\n test: `assert.lengthOf(Object.keys(output), 2) === undefined;`\n },\n {\n name: `First value is true`,\n test: `assert.isTrue(output.evenNumbers) === undefined;`\n },\n {\n name: `Second value is false`,\n test: `assert.isFalse(output.someOddNumbers) === undefined;`\n }\n ]\n },\n {\n name: 'Array.some()',\n time: 10,\n prompt: `Return 'Object' that returns whether each array contains some odd numbers using 'Array.some()'.`,\n given: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 4, 7, 8];\n function isOdd(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,\n answer: `const evenNumbers = [1, 3, 5, 7];\n const someOddNumbers = [1, 3, 6, 7];\n function isOdd(element) {\n return element % 2 !== 0;\n }\n return {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n };`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;`\n },\n {\n name: 'Returns an Object',\n test: `assert.isObject(output) === undefined;`\n },\n {\n name: 'Object has 2 items',\n test: `assert.lengthOf(Object.keys(output), 2) === undefined;`\n },\n {\n name: `First value is false`,\n test: `assert.isFalse(output.evenNumbers) === undefined;`\n },\n {\n name: `Second value is true`,\n test: `assert.isTrue(output.someOddNumbers) === undefined;`\n }\n ]\n }\n // Next problems to create:\n // forEach? fix one above that tried, but can't verify forEach was used\n // some\n // reduce\n // reduceRight\n // Array.from and other ways to turn array-like into array\n];\n","module.exports = [\n {\n name: 'Create Array',\n time: 10,\n prompt: 'Create and return an array that contains \\'apple\\' and \\'banana\\'',\n given: `const fruits = [];\\rreturn fruits;`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.pop()',\n time: 10,\n prompt: `Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n }\n]\n","module.exports = require('./lib/type');\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n '[object Array]': 'array'\n , '[object RegExp]': 'regexp'\n , '[object Function]': 'function'\n , '[object Arguments]': 'arguments'\n , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n var str = Object.prototype.toString.call(obj);\n if (natives[str]) return natives[str];\n if (obj === null) return 'null';\n if (obj === undefined) return 'undefined';\n if (obj === Object(obj)) return 'object';\n return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n // Let \"new String('')\" return 'object'\n if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n // PhantomJS has type \"DOMWindow\" for null\n if (obj === null) return 'null';\n // PhantomJS has type \"DOMWindow\" for undefined\n if (obj === undefined) return 'undefined';\n return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n if (!(this instanceof Library)) return new Library();\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","(function (document, window) {\n // DEPENDENCIES\n // ============================================================\n const localforage = require('localforage');\n const probs = require('pjs-problems');\n const dedent = require('dedent');\n const assert = require('chai').assert;\n\n // PROBLEM TEMPLATE NICE-IFICATION\n // ============================================================\n\n function dedentStrings(problems) {\n return problems.map(prob => {\n prob.given = dedent(prob.given)\n prob.answer = dedent(prob.answer)\n return prob\n });\n }\n\n\n // PROBLEMS\n // ============================================================\n\n let problems = [];\n Object.keys(probs).forEach(subject => {\n problems.push(...probs[subject]);\n });\n problems = dedentStrings(problems);\n\n\n // CONFIG\n // ============================================================\n\n // Hoist current problem\n let currentProblem;\n\n // Keys to ignore while user is navigating around the textarea but not changing any code\n const ignoreKeyCodes = [\n 9, // Tab\n 37, // Left arrow\n 39, // Right arrow\n 38, // Up arrow\n 40 // Down arrow\n ];\n\n let config = {\n shuffle: true,\n timer: false,\n currentIndex: 0\n };\n\n // Pull config from localforage\n localforage\n .getItem('js_practice_config')\n .then(val => {\n if (val) {\n config = val;\n }\n loadApp(config);\n })\n .catch(err => {\n console.log('localforage err:', err);\n loadApp(config);\n });\n\n function updateLocalstore(config) {\n return localforage\n .setItem('js_practice_config', config)\n .then(val => val)\n .catch(err => {\n console.log('Settings update error:', err);\n });\n }\n\n // HELPERS\n // ============================================================\n\n function debounce(func, wait, immediate) {\n let timeout;\n return function () {\n const context = this;\n const args = arguments;\n const later = function () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n };\n const callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) {\n func.apply(context, args);\n }\n };\n }\n\n // UI\n // ============================================================\n\n // elements\n const problemEl = document.getElementById('problem');\n const codeEl = document.getElementById('code');\n const testSuiteEl = document.getElementById('test-suite');\n const testTotalEl = document.getElementById('test-total');\n const evalConsoleEl = document.getElementById('eval-output');\n const assertConsoleEl = document.getElementById('assert-output');\n const shuffleProblemsButtonEl = document.getElementById('shuffle-problems');\n const previousProblemButtonEl = document.getElementById('prev-problem');\n const nextProblemButtonEl = document.getElementById('next-problem');\n\n // Get indexes\n function getRandomIndex(problemsArr) {\n const ind = Math.floor(Math.random() * problemsArr.length);\n config.currentIndex = ind;\n updateLocalstore(config);\n return ind;\n }\n\n function getPreviousIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at beginning, go to end\n if (currentIndex === 0) {\n probInd = problemsArr.length - 1;\n } else {\n probInd = currentIndex - 1;\n }\n return probInd;\n }\n\n function getNextIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at end or invalid, restart series\n if (currentIndex >= problemsArr.length - 1 || currentIndex < 0) {\n probInd = 0;\n } else {\n probInd = currentIndex + 1;\n }\n return probInd;\n }\n\n // Get problems\n function getCurrentProblem(problemsArr) {\n return problemsArr[config.currentIndex];\n }\n\n function previousProblem() {\n console.log('previousProblem!');\n // Activate back button, for visual queue of nav feedback\n previousProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getPreviousIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function nextProblem() {\n console.log('nextProblem!');\n // Activate next button, for visual queue of nav feedback\n nextProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getNextIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function toggleShuffle() {\n console.log('toggle shuffle!');\n config.shuffle = !config.shuffle; // Flip it\n shuffleProblemsButtonEl.classList.toggle('active');\n previousProblemButtonEl.parentNode.classList.toggle('hidden');\n updateLocalstore(config);\n }\n\n function loadProblem(problemObj) {\n currentProblem = problemObj;\n // Prob question\n problemEl.innerText = problemObj.prompt;\n // Prob given code\n if (problemObj.given) {\n codeEl.value = problemObj.given;\n }\n // Seed the tests, pass (init = true) as second param\n testSuite(null, true);\n }\n\n // TODO: Build the assert errors into the test dom on each update.\n function updateTests(testStatus, init) {\n if (init === true) {\n buildTests(currentProblem.tests);\n }\n updateTestStatus(testStatus);\n }\n\n function buildTests(tests) {\n if (tests) {\n const testsDom = tests\n .map(test => {\n return `
\n
[✘]
\n
${test.name}
\n
`;\n })\n .join('');\n testSuiteEl.innerHTML = testsDom;\n }\n }\n\n function updateTestStatus(testStatuses) {\n if (!testStatuses) {\n throw new Error('No testStatuses provided.');\n }\n // Find out if all tests have passed or not\n let allPassed = true;\n testStatuses.forEach(testPassed => {\n if (testPassed !== true) {\n allPassed = false;\n }\n });\n const testEls = [].slice.call(testSuiteEl.querySelectorAll('.test-state'));\n testEls.forEach((testStatusEl, iter) => {\n if (testStatuses[iter] === true) {\n testStatusEl.innerHTML = '[✓]';\n testStatusEl.classList.remove('fail');\n testStatusEl.classList.add('pass');\n } else {\n testStatusEl.innerHTML = '[✘]';\n testStatusEl.classList.remove('pass');\n testStatusEl.classList.add('fail');\n }\n });\n\n if (allPassed === true) {\n testTotalEl.innerText = 'PASS';\n testTotalEl.classList.remove('fail');\n testTotalEl.classList.add('pass');\n } else {\n testTotalEl.innerText = 'FAIL';\n testTotalEl.classList.remove('pass');\n testTotalEl.classList.add('fail');\n }\n }\n\n function printAssertError(errObj) {\n // Make element string\n let inner = '';\n if (errObj !== null) {\n inner = `\n
\n Expected: ${JSON.stringify(errObj.expected)}\n Actual: ${JSON.stringify(errObj.actual)}\n
`;\n }\n\n // Prepend element\n assertConsoleEl.innerHTML = inner;\n }\n\n function printEvalOutput(errObj, output) {\n // Make element string\n let inner = '';\n if (errObj && errObj.message !== undefined) {\n inner = `\n
\n Syntax Error: ${JSON.stringify(errObj.message)}\n
`;\n } else if (output) {\n inner = `\n
\n Output: ${JSON.stringify(output)}\n
`;\n }\n // Prepend element\n evalConsoleEl.innerHTML = inner;\n }\n\n\n // VERIFICATION LOGIC\n // ============================================================\n\n function testSuite(init) {\n // Show 'working' indicator\n testTotalEl.classList.toggle('working');\n // Run stuff\n const output = getOutput(codeEl.value);\n // Run tests on code, return object/array of test results\n const tested = runTests(output);\n // Hide 'working' indicator\n testTotalEl.classList.toggle('working');\n // Update UI with results\n updateTests(tested, init);\n }\n\n function getOutput(code) {\n let evald = false;\n try {\n evald = eval(`(function(){${code}})()`); // eslint-disable-line no-eval\n printEvalOutput(null, evald); // Print current output\n } catch (err) {\n printEvalOutput(err);\n }\n return evald;\n }\n\n function runTests(output) {\n let tested = false;\n tested = currentProblem.tests.map(test => {\n let testOutcome = false;\n try {\n if (output) {\n // const testEval = eval(test.test);\n\n testOutcome = eval(test.test);\n console.log('testOutcome:', testOutcome);\n\n }\n printAssertError(null);\n } catch (err) {\n printAssertError(err);\n }\n return testOutcome;\n });\n return tested;\n }\n\n // Wrapped to prevent race with local config retrieval\n function loadApp(config) {\n console.log('loading app!');\n\n // Show current toggle state\n if (config.shuffle === true) {\n shuffleProblemsButtonEl.classList.add('active');\n previousProblemButtonEl.parentNode.classList.add('hidden');\n }\n\n // Keybinding stuff\n // ============================================================\n\n // Debounced code validation\n const debouncedInputValidation = debounce(e => {\n // If not arrow keys or other non-character keys\n if (ignoreKeyCodes.indexOf(e.keyCode) === -1) {\n // Run test suite\n testSuite();\n }\n }, 200);\n\n function problemNav(e) {\n // Go to previous problem keybinding\n // If CMD/CTRL + SHIFT + RETURN/ENTER\n if (config.shuffle === false && e.keyCode === 13 && e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem\n previousProblem();\n } else if (e.keyCode === 13 && !e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem keybinding\n // If CMD/CTRL + RETURN/ENTER\n // Go to next problem\n nextProblem();\n }\n }\n\n // Event Bindings\n // ============================================================\n\n // Bind it up\n codeEl.addEventListener('keydown', debouncedInputValidation);\n document.addEventListener('keydown', problemNav);\n shuffleProblemsButtonEl.addEventListener('click', toggleShuffle);\n previousProblemButtonEl.addEventListener('click', previousProblem);\n nextProblemButtonEl.addEventListener('click', nextProblem);\n\n // Start it up!\n // Load current problem\n const currProb = getCurrentProblem(problems);\n loadProblem(currProb);\n // Initalized test suite with starting failures\n testSuite(true);\n }\n})(document, window);\n"]} \ No newline at end of file +{"version":3,"sources":["node_modules/.registry.npmjs.org/browser-pack/6.0.2/node_modules/browser-pack/_prelude.js","node_modules/.registry.npmjs.org/assertion-error/1.0.2/node_modules/assertion-error/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/assertion.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/config.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/core/assertions.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/assert.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/expect.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/interface/should.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addChainableMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/addProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/expectTypes.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/flag.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getActual.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getEnumerableProperties.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getMessage.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getName.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getPathInfo.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getPathValue.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/getProperties.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/hasProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/index.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/inspect.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/objDisplay.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteChainableMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteMethod.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/overwriteProperty.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/test.js","node_modules/.registry.npmjs.org/chai/3.5.0/node_modules/chai/lib/chai/utils/transferFlags.js","node_modules/.registry.npmjs.org/dedent/0.7.0/node_modules/dedent/dist/dedent.js","node_modules/.registry.npmjs.org/deep-eql/0.1.3/node_modules/deep-eql/index.js","node_modules/.registry.npmjs.org/deep-eql/0.1.3/node_modules/deep-eql/lib/eql.js","node_modules/.registry.npmjs.org/localforage/1.5.0/node_modules/localforage/dist/node_modules/localforage/dist/localforage.js","node_modules/.registry.npmjs.org/pjs-problems/1.0.3/node_modules/pjs-problems/index.js","node_modules/.registry.npmjs.org/pjs-problems/1.0.3/node_modules/pjs-problems/problems/arrays.js","node_modules/.registry.npmjs.org/pjs-problems/1.0.3/node_modules/pjs-problems/problems/initial.js","node_modules/.registry.npmjs.org/type-detect/0.1.1/node_modules/type-detect/index.js","node_modules/.registry.npmjs.org/type-detect/0.1.1/node_modules/type-detect/lib/type.js","node_modules/.registry.npmjs.org/type-detect/1.0.0/node_modules/type-detect/lib/type.js","src/js/index.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length","1","module","exclude","excludeProps","res","obj","Object","keys","forEach","key","excludes","indexOf","slice","arguments","args","AssertionError","message","_props","ssf","props","this","showDiff","callee","captureStackTrace","stack","prototype","create","name","constructor","toJSON","used","version","util","use","fn","push","config","assertion","core","expect","should","assert","_chai","Assertion","msg","flag","defineProperty","get","console","warn","includeStack","set","value","addProperty","addMethod","addChainableMethod","chainingBehavior","overwriteProperty","overwriteMethod","overwriteChainableMethod","expr","negateMsg","expected","_actual","ok","test","getMessage","actual","getActual","val","truncateThreshold","chai","_","an","type","toLowerCase","article","charAt","includeChainingBehavior","include","expectTypes","eql","k","property","subset","undefined","inspect","checkArguments","toString","assertEqual","_obj","assertEql","assertAbove","to","have","len","assertLeast","assertBelow","assertMost","assertInstanceOf","getName","assertOwnProperty","hasOwnProperty","assertOwnPropertyDescriptor","descriptor","actualDescriptor","getOwnPropertyDescriptor","assertLengthChain","assertLength","assertMatch","re","exec","assertKeys","str","mixedArgsMsg","Array","any","all","filter","every","last","map","pop","join","sort","assertThrows","errMsg","is","thrown","desiredError","thrownError","RegExp","err","actuallyGot","expectedThrown","respondTo","method","itself","context","satisfy","matcher","result","objDisplay","negate","closeTo","delta","Math","abs","isSubsetOf","superset","cmp","elem","some","elem2","oneOf","list","be","assertChanges","object","prop","initial","assertIncreases","assertDecreases","chain","isNaN","isArray","start","finish","range","isDeep","pathInfo","getPathInfo","hasProperty","exists","isExtensible","TypeError","isSealed","isFrozen","express","errmsg","fail","operator","isOk","isNotOk","not","equal","act","exp","notEqual","strictEqual","notStrictEqual","deepEqual","notDeepEqual","isAbove","abv","above","isAtLeast","atlst","least","isBelow","blw","below","isAtMost","atmst","most","isTrue","isNotTrue","isFalse","isNotFalse","isNull","isNotNull","NaN","isNotNaN","isUndefined","isDefined","isFunction","isNotFunction","isObject","isNotObject","isNotArray","isString","isNotString","isNumber","isNotNumber","isBoolean","isNotBoolean","typeOf","notTypeOf","instanceOf","notInstanceOf","inc","notInclude","match","notMatch","notProperty","deepProperty","deep","notDeepProperty","propertyVal","propertyNotVal","deepPropertyVal","deepPropertyNotVal","lengthOf","throws","errt","errs","assertErr","throw","doesNotThrow","Throw","val2","approximately","sameMembers","set1","set2","same","members","sameDeepMembers","includeMembers","includeDeepMembers","inList","changes","change","doesNotChange","increases","increase","doesNotIncrease","decreases","decrease","doesNotDecrease","ifError","extensible","isNotExtensible","sealed","isNotSealed","frozen","isNotFrozen","alias","as","loadShould","shouldGetter","String","Number","Boolean","valueOf","shouldSetter","enumerable","configurable","writable","val1","exist","Should","transferFlags","hasProtoSupport","excludeNames","Function","apply","ctx","chainableBehavior","__methods","__proto__","getOwnPropertyNames","asserterName","pd","getter","types","index","art","flags","__flags","flagMsg","replace","func","parsePath","path","mArr","parseFloat","p","_getPathValue","parsed","tmp","part","info","parent","proto","getPrototypeOf","literals","number","string","ot","getPathValue","showHidden","depth","colors","formatValue","seen","stylize","recurseTimes","ret","primitive","formatPrimitive","isDOMElement","outerHTML","document","xmlVersion","XMLSerializer","serializeToString","container","createElementNS","appendChild","cloneNode","html","innerHTML","visibleKeys","getEnumerableProperties","getProperties","isError","nameSuffix","isRegExp","isDate","Date","toUTCString","formatError","base","array","braces","output","formatArray","formatProperty","reduceToSingleString","simple","JSON","stringify","Infinity","__lookupGetter__","__lookupSetter__","split","line","substr","numLinesEst","reduce","prev","cur","ar","objectToString","d","HTMLElement","nodeType","nodeName","splice","_chainingBehavior","_method","_super","_get","includeAll","dedent","strings","raw","lines","mindent","m","indent","min","trim","b","sameValue","dateEqual","regexpEqual","Buffer","isBuffer","bufferEqual","argumentsEqual","typeEqual","objectEqual","getTime","iterableEqual","isValue","ka","kb","ex","define","amd","window","global","self","localforage","_dereq_","nextTick","draining","oldQueue","queue","immediate","task","scheduleDrain","Mutation","MutationObserver","WebKitMutationObserver","called","observer","element","createTextNode","observe","characterData","data","setImmediate","MessageChannel","createElement","scriptEl","onreadystatechange","parentNode","removeChild","documentElement","setTimeout","channel","port1","onmessage","port2","postMessage","2","INTERNAL","Promise","resolver","state","PENDING","outcome","safelyResolveThenable","QueueItem","promise","onFulfilled","onRejected","callFulfilled","otherCallFulfilled","callRejected","otherCallRejected","unwrap","returnValue","handlers","reject","resolve","getThen","then","thenable","onError","onSuccess","tryToUnwrap","tryCatch","status","out","reason","iterable","values","resolved","resolveFromAll","outValue","error","race","response","REJECTED","FULFILLED","3","4","_classCallCheck","instance","Constructor","createBlob","parts","properties","Blob","builder","BlobBuilder","MSBlobBuilder","MozBlobBuilder","WebKitBlobBuilder","append","getBlob","executeCallback","callback","executeTwoCallbacks","errorCallback","_binStringToArrayBuffer","bin","buf","ArrayBuffer","arr","Uint8Array","charCodeAt","_checkBlobSupportWithoutCaching","idb","Promise$1","txn","transaction","DETECT_BLOB_SUPPORT_STORE","blob","objectStore","put","onabort","preventDefault","stopPropagation","oncomplete","matchedChrome","navigator","userAgent","matchedEdge","parseInt","_checkBlobSupport","supportsBlobs","_deferReadiness","dbInfo","dbContext","dbContexts","deferredOperation","deferredOperations","dbReady","_advanceReadiness","_getConnection","upgradeNeeded","db","close","dbArgs","openreq","open","onupgradeneeded","createObjectStore","storeName","oldVersion","newVersion","onerror","onsuccess","_getOriginalConnection","_getUpgradedConnection","_isUpgradeNeeded","defaultVersion","isNewStore","objectStoreNames","contains","isDowngrade","isUpgrade","incVersion","_encodeBlob","reader","FileReader","onloadend","base64","btoa","target","__local_forage_encoded_blob","readAsBinaryString","_decodeBlob","encodedBlob","atob","_isEncodedBlob","_fullyReady","_initReady","_dbInfo","_initStorage","options","ignoreErrors","forages","ready","initPromises","j","forage","_defaultConfig","getItem","req","iterate","iterator","openCursor","iterationNumber","cursor","setItem","blobSupport","removeItem","clear","count","advanced","advance","stringToBuffer","serializedString","encoded1","encoded2","encoded3","encoded4","bufferLength","buffer","bytes","BASE_CHARS","bufferToString","base64String","substring","serialize","valueType","toString$1","marker","SERIALIZED_MARKER","TYPE_ARRAYBUFFER","TYPE_INT8ARRAY","TYPE_UINT8ARRAY","TYPE_UINT8CLAMPEDARRAY","TYPE_INT16ARRAY","TYPE_UINT16ARRAY","TYPE_INT32ARRAY","TYPE_UINT32ARRAY","TYPE_FLOAT32ARRAY","TYPE_FLOAT64ARRAY","fileReader","onload","BLOB_TYPE_PREFIX","TYPE_BLOB","readAsArrayBuffer","deserialize","SERIALIZED_MARKER_LENGTH","parse","blobType","TYPE_SERIALIZED_MARKER_LENGTH","BLOB_TYPE_PREFIX_REGEX","Int8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","_initStorage$1","dbInfoPromise","openDatabase","description","size","executeSql","serializer","localforageSerializer","getItem$1","results","rows","item","iterate$1","_setItem","retriesLeft","originalValue","sqlError","QUOTA_ERR","setItem$1","removeItem$1","clear$1","length$1","c","key$1","keys$1","_initStorage$2","keyPrefix","clear$2","localStorage","getItem$2","iterate$2","keyPrefixLength","key$2","keys$2","length$2","removeItem$2","setItem$2","callWhenReady","localForageInstance","libraryMethod","_args","extend","arg","isLibraryDriver","driverName","driver","DriverType","_typeof","Symbol","indexedDB","webkitIndexedDB","mozIndexedDB","OIndexedDB","msIndexedDB","asyncStorage","_driver","webSQLStorage","localStorageWrapper","CustomDrivers","INDEXEDDB","LOCALSTORAGE","WEBSQL","LibraryMethods","DefaultConfig","driverSupport","isSafari","platform","hasFetch","fetch","IDBKeyRange","localforage_js","LocalForage","_config","_driverSet","_initDriver","_ready","_wrapLibraryMethodsWithReady","setDriver","defineDriver","driverObject","complianceError","namingError","customDriverMethods","concat","customDriverMethod","supportPromise","_support","supportResult","getDriver","getDriverPromise","getSerializer","serializerPromise","drivers","setDriverToConfig","extendSelfWithDriver","_extend","initDriver","supportedDrivers","driverPromiseLoop","currentDriverIndex","_getSupportedDrivers","oldDriverSetDone","supports","libraryMethodsAndProperties","createInstance","arrays","time","prompt","given","answer","tests","getType","natives","Library","[object Array]","[object RegExp]","[object Function]","[object Arguments]","[object Date]","of","ReferenceError","objectTypeRegexp","dedentStrings","problems","prob","updateLocalstore","catch","log","debounce","wait","timeout","later","callNow","clearTimeout","getRandomIndex","problemsArr","ind","floor","random","currentIndex","getPreviousIndex","getNextIndex","getCurrentProblem","previousProblem","previousProblemButtonEl","classList","add","shuffle","location","reload","nextProblem","nextProblemButtonEl","toggleShuffle","shuffleProblemsButtonEl","toggle","loadProblem","problemObj","currentProblem","problemEl","innerText","codeEl","testSuite","updateTests","testStatus","init","buildTests","updateTestStatus","testsDom","testSuiteEl","testStatuses","allPassed","testPassed","querySelectorAll","testStatusEl","iter","remove","testTotalEl","printAssertError","errObj","inner","assertConsoleEl","printEvalOutput","evalConsoleEl","tested","runTests","getOutput","evald","eval","testOutcome","loadApp","problemNav","keyCode","shiftKey","metaKey","ctrlKey","debouncedInputValidation","ignoreKeyCodes","addEventListener","probs","subject","_problems","_toConsumableArray","timer","getElementById"],"mappings":"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","file":"bundle.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o\n * MIT Licensed\n */\n\n/*!\n * Return a function that will copy properties from\n * one object to another excluding any originally\n * listed. Returned function will create a new `{}`.\n *\n * @param {String} excluded properties ...\n * @return {Function}\n */\n\nfunction exclude () {\n var excludes = [].slice.call(arguments);\n\n function excludeProps (res, obj) {\n Object.keys(obj).forEach(function (key) {\n if (!~excludes.indexOf(key)) res[key] = obj[key];\n });\n }\n\n return function extendExclude () {\n var args = [].slice.call(arguments)\n , i = 0\n , res = {};\n\n for (; i < args.length; i++) {\n excludeProps(res, args[i]);\n }\n\n return res;\n };\n};\n\n/*!\n * Primary Exports\n */\n\nmodule.exports = AssertionError;\n\n/**\n * ### AssertionError\n *\n * An extension of the JavaScript `Error` constructor for\n * assertion and validation scenarios.\n *\n * @param {String} message\n * @param {Object} properties to include (optional)\n * @param {callee} start stack function (optional)\n */\n\nfunction AssertionError (message, _props, ssf) {\n var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')\n , props = extend(_props || {});\n\n // default values\n this.message = message || 'Unspecified AssertionError';\n this.showDiff = false;\n\n // copy from properties\n for (var key in props) {\n this[key] = props[key];\n }\n\n // capture stack trace\n ssf = ssf || arguments.callee;\n if (ssf && Error.captureStackTrace) {\n Error.captureStackTrace(this, ssf);\n } else {\n try {\n throw new Error();\n } catch(e) {\n this.stack = e.stack;\n }\n }\n}\n\n/*!\n * Inherit from Error.prototype\n */\n\nAssertionError.prototype = Object.create(Error.prototype);\n\n/*!\n * Statically set name\n */\n\nAssertionError.prototype.name = 'AssertionError';\n\n/*!\n * Ensure correct constructor\n */\n\nAssertionError.prototype.constructor = AssertionError;\n\n/**\n * Allow errors to be converted to JSON for static transfer.\n *\n * @param {Boolean} include stack (default: `true`)\n * @return {Object} object that can be `JSON.stringify`\n */\n\nAssertionError.prototype.toJSON = function (stack) {\n var extend = exclude('constructor', 'toJSON', 'stack')\n , props = extend({ name: this.name }, this);\n\n // include stack if exists and not turned off\n if (false !== stack && this.stack) {\n props.stack = this.stack;\n }\n\n return props;\n};\n","module.exports = require('./lib/chai');\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar used = []\n , exports = module.exports = {};\n\n/*!\n * Chai version\n */\n\nexports.version = '3.5.0';\n\n/*!\n * Assertion Error\n */\n\nexports.AssertionError = require('assertion-error');\n\n/*!\n * Utils for plugins (not exported)\n */\n\nvar util = require('./chai/utils');\n\n/**\n * # .use(function)\n *\n * Provides a way to extend the internals of Chai\n *\n * @param {Function}\n * @returns {this} for chaining\n * @api public\n */\n\nexports.use = function (fn) {\n if (!~used.indexOf(fn)) {\n fn(this, util);\n used.push(fn);\n }\n\n return this;\n};\n\n/*!\n * Utility Functions\n */\n\nexports.util = util;\n\n/*!\n * Configuration\n */\n\nvar config = require('./chai/config');\nexports.config = config;\n\n/*!\n * Primary `Assertion` prototype\n */\n\nvar assertion = require('./chai/assertion');\nexports.use(assertion);\n\n/*!\n * Core Assertions\n */\n\nvar core = require('./chai/core/assertions');\nexports.use(core);\n\n/*!\n * Expect interface\n */\n\nvar expect = require('./chai/interface/expect');\nexports.use(expect);\n\n/*!\n * Should interface\n */\n\nvar should = require('./chai/interface/should');\nexports.use(should);\n\n/*!\n * Assert interface\n */\n\nvar assert = require('./chai/interface/assert');\nexports.use(assert);\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('./config');\n\nmodule.exports = function (_chai, util) {\n /*!\n * Module dependencies.\n */\n\n var AssertionError = _chai.AssertionError\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n _chai.Assertion = Assertion;\n\n /*!\n * Assertion Constructor\n *\n * Creates object for chaining.\n *\n * @api private\n */\n\n function Assertion (obj, msg, stack) {\n flag(this, 'ssfi', stack || arguments.callee);\n flag(this, 'object', obj);\n flag(this, 'message', msg);\n }\n\n Object.defineProperty(Assertion, 'includeStack', {\n get: function() {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n return config.includeStack;\n },\n set: function(value) {\n console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');\n config.includeStack = value;\n }\n });\n\n Object.defineProperty(Assertion, 'showDiff', {\n get: function() {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n return config.showDiff;\n },\n set: function(value) {\n console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');\n config.showDiff = value;\n }\n });\n\n Assertion.addProperty = function (name, fn) {\n util.addProperty(this.prototype, name, fn);\n };\n\n Assertion.addMethod = function (name, fn) {\n util.addMethod(this.prototype, name, fn);\n };\n\n Assertion.addChainableMethod = function (name, fn, chainingBehavior) {\n util.addChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n Assertion.overwriteProperty = function (name, fn) {\n util.overwriteProperty(this.prototype, name, fn);\n };\n\n Assertion.overwriteMethod = function (name, fn) {\n util.overwriteMethod(this.prototype, name, fn);\n };\n\n Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {\n util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);\n };\n\n /**\n * ### .assert(expression, message, negateMessage, expected, actual, showDiff)\n *\n * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.\n *\n * @name assert\n * @param {Philosophical} expression to be tested\n * @param {String|Function} message or function that returns message to display if expression fails\n * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails\n * @param {Mixed} expected value (remember to check for negation)\n * @param {Mixed} actual (optional) will default to `this.obj`\n * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails\n * @api private\n */\n\n Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {\n var ok = util.test(this, arguments);\n if (true !== showDiff) showDiff = false;\n if (true !== config.showDiff) showDiff = false;\n\n if (!ok) {\n var msg = util.getMessage(this, arguments)\n , actual = util.getActual(this, arguments);\n throw new AssertionError(msg, {\n actual: actual\n , expected: expected\n , showDiff: showDiff\n }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));\n }\n };\n\n /*!\n * ### ._obj\n *\n * Quick reference to stored `actual` value for plugin developers.\n *\n * @api private\n */\n\n Object.defineProperty(Assertion.prototype, '_obj',\n { get: function () {\n return flag(this, 'object');\n }\n , set: function (val) {\n flag(this, 'object', val);\n }\n });\n};\n","module.exports = {\n\n /**\n * ### config.includeStack\n *\n * User configurable property, influences whether stack trace\n * is included in Assertion error message. Default of false\n * suppresses stack trace in the error message.\n *\n * chai.config.includeStack = true; // enable stack on error\n *\n * @param {Boolean}\n * @api public\n */\n\n includeStack: false,\n\n /**\n * ### config.showDiff\n *\n * User configurable property, influences whether or not\n * the `showDiff` flag should be included in the thrown\n * AssertionErrors. `false` will always be `false`; `true`\n * will be true when the assertion has requested a diff\n * be shown.\n *\n * @param {Boolean}\n * @api public\n */\n\n showDiff: true,\n\n /**\n * ### config.truncateThreshold\n *\n * User configurable property, sets length threshold for actual and\n * expected values in assertion errors. If this threshold is exceeded, for\n * example for large data structures, the value is replaced with something\n * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`.\n *\n * Set it to zero if you want to disable truncating altogether.\n *\n * This is especially userful when doing assertions on arrays: having this\n * set to a reasonable large value makes the failure messages readily\n * inspectable.\n *\n * chai.config.truncateThreshold = 0; // disable truncating\n *\n * @param {Number}\n * @api public\n */\n\n truncateThreshold: 40\n\n};\n","/*!\n * chai\n * http://chaijs.com\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, _) {\n var Assertion = chai.Assertion\n , toString = Object.prototype.toString\n , flag = _.flag;\n\n /**\n * ### Language Chains\n *\n * The following are provided as chainable getters to\n * improve the readability of your assertions. They\n * do not provide testing capabilities unless they\n * have been overwritten by a plugin.\n *\n * **Chains**\n *\n * - to\n * - be\n * - been\n * - is\n * - that\n * - which\n * - and\n * - has\n * - have\n * - with\n * - at\n * - of\n * - same\n *\n * @name language chains\n * @namespace BDD\n * @api public\n */\n\n [ 'to', 'be', 'been'\n , 'is', 'and', 'has', 'have'\n , 'with', 'that', 'which', 'at'\n , 'of', 'same' ].forEach(function (chain) {\n Assertion.addProperty(chain, function () {\n return this;\n });\n });\n\n /**\n * ### .not\n *\n * Negates any of assertions following in the chain.\n *\n * expect(foo).to.not.equal('bar');\n * expect(goodFn).to.not.throw(Error);\n * expect({ foo: 'baz' }).to.have.property('foo')\n * .and.not.equal('bar');\n *\n * @name not\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('not', function () {\n flag(this, 'negate', true);\n });\n\n /**\n * ### .deep\n *\n * Sets the `deep` flag, later used by the `equal` and\n * `property` assertions.\n *\n * expect(foo).to.deep.equal({ bar: 'baz' });\n * expect({ foo: { bar: { baz: 'quux' } } })\n * .to.have.deep.property('foo.bar.baz', 'quux');\n *\n * `.deep.property` special characters can be escaped\n * by adding two slashes before the `.` or `[]`.\n *\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name deep\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('deep', function () {\n flag(this, 'deep', true);\n });\n\n /**\n * ### .any\n *\n * Sets the `any` flag, (opposite of the `all` flag)\n * later used in the `keys` assertion.\n *\n * expect(foo).to.have.any.keys('bar', 'baz');\n *\n * @name any\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('any', function () {\n flag(this, 'any', true);\n flag(this, 'all', false)\n });\n\n\n /**\n * ### .all\n *\n * Sets the `all` flag (opposite of the `any` flag)\n * later used by the `keys` assertion.\n *\n * expect(foo).to.have.all.keys('bar', 'baz');\n *\n * @name all\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('all', function () {\n flag(this, 'all', true);\n flag(this, 'any', false);\n });\n\n /**\n * ### .a(type)\n *\n * The `a` and `an` assertions are aliases that can be\n * used either as language chains or to assert a value's\n * type.\n *\n * // typeof\n * expect('test').to.be.a('string');\n * expect({ foo: 'bar' }).to.be.an('object');\n * expect(null).to.be.a('null');\n * expect(undefined).to.be.an('undefined');\n * expect(new Error).to.be.an('error');\n * expect(new Promise).to.be.a('promise');\n * expect(new Float32Array()).to.be.a('float32array');\n * expect(Symbol()).to.be.a('symbol');\n *\n * // es6 overrides\n * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo');\n *\n * // language chain\n * expect(foo).to.be.an.instanceof(Foo);\n *\n * @name a\n * @alias an\n * @param {String} type\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function an (type, msg) {\n if (msg) flag(this, 'message', msg);\n type = type.toLowerCase();\n var obj = flag(this, 'object')\n , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';\n\n this.assert(\n type === _.type(obj)\n , 'expected #{this} to be ' + article + type\n , 'expected #{this} not to be ' + article + type\n );\n }\n\n Assertion.addChainableMethod('an', an);\n Assertion.addChainableMethod('a', an);\n\n /**\n * ### .include(value)\n *\n * The `include` and `contain` assertions can be used as either property\n * based language chains or as methods to assert the inclusion of an object\n * in an array or a substring in a string. When used as language chains,\n * they toggle the `contains` flag for the `keys` assertion.\n *\n * expect([1,2,3]).to.include(2);\n * expect('foobar').to.contain('foo');\n * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');\n *\n * @name include\n * @alias contain\n * @alias includes\n * @alias contains\n * @param {Object|String|Number} obj\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function includeChainingBehavior () {\n flag(this, 'contains', true);\n }\n\n function include (val, msg) {\n _.expectTypes(this, ['array', 'object', 'string']);\n\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var expected = false;\n\n if (_.type(obj) === 'array' && _.type(val) === 'object') {\n for (var i in obj) {\n if (_.eql(obj[i], val)) {\n expected = true;\n break;\n }\n }\n } else if (_.type(val) === 'object') {\n if (!flag(this, 'negate')) {\n for (var k in val) new Assertion(obj).property(k, val[k]);\n return;\n }\n var subset = {};\n for (var k in val) subset[k] = obj[k];\n expected = _.eql(subset, val);\n } else {\n expected = (obj != undefined) && ~obj.indexOf(val);\n }\n this.assert(\n expected\n , 'expected #{this} to include ' + _.inspect(val)\n , 'expected #{this} to not include ' + _.inspect(val));\n }\n\n Assertion.addChainableMethod('include', include, includeChainingBehavior);\n Assertion.addChainableMethod('contain', include, includeChainingBehavior);\n Assertion.addChainableMethod('contains', include, includeChainingBehavior);\n Assertion.addChainableMethod('includes', include, includeChainingBehavior);\n\n /**\n * ### .ok\n *\n * Asserts that the target is truthy.\n *\n * expect('everything').to.be.ok;\n * expect(1).to.be.ok;\n * expect(false).to.not.be.ok;\n * expect(undefined).to.not.be.ok;\n * expect(null).to.not.be.ok;\n *\n * @name ok\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('ok', function () {\n this.assert(\n flag(this, 'object')\n , 'expected #{this} to be truthy'\n , 'expected #{this} to be falsy');\n });\n\n /**\n * ### .true\n *\n * Asserts that the target is `true`.\n *\n * expect(true).to.be.true;\n * expect(1).to.not.be.true;\n *\n * @name true\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('true', function () {\n this.assert(\n true === flag(this, 'object')\n , 'expected #{this} to be true'\n , 'expected #{this} to be false'\n , this.negate ? false : true\n );\n });\n\n /**\n * ### .false\n *\n * Asserts that the target is `false`.\n *\n * expect(false).to.be.false;\n * expect(0).to.not.be.false;\n *\n * @name false\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('false', function () {\n this.assert(\n false === flag(this, 'object')\n , 'expected #{this} to be false'\n , 'expected #{this} to be true'\n , this.negate ? true : false\n );\n });\n\n /**\n * ### .null\n *\n * Asserts that the target is `null`.\n *\n * expect(null).to.be.null;\n * expect(undefined).to.not.be.null;\n *\n * @name null\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('null', function () {\n this.assert(\n null === flag(this, 'object')\n , 'expected #{this} to be null'\n , 'expected #{this} not to be null'\n );\n });\n\n /**\n * ### .undefined\n *\n * Asserts that the target is `undefined`.\n *\n * expect(undefined).to.be.undefined;\n * expect(null).to.not.be.undefined;\n *\n * @name undefined\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('undefined', function () {\n this.assert(\n undefined === flag(this, 'object')\n , 'expected #{this} to be undefined'\n , 'expected #{this} not to be undefined'\n );\n });\n\n /**\n * ### .NaN\n * Asserts that the target is `NaN`.\n *\n * expect('foo').to.be.NaN;\n * expect(4).not.to.be.NaN;\n *\n * @name NaN\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('NaN', function () {\n this.assert(\n isNaN(flag(this, 'object'))\n , 'expected #{this} to be NaN'\n , 'expected #{this} not to be NaN'\n );\n });\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi'\n * , bar = null\n * , baz;\n *\n * expect(foo).to.exist;\n * expect(bar).to.not.exist;\n * expect(baz).to.not.exist;\n *\n * @name exist\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('exist', function () {\n this.assert(\n null != flag(this, 'object')\n , 'expected #{this} to exist'\n , 'expected #{this} to not exist'\n );\n });\n\n\n /**\n * ### .empty\n *\n * Asserts that the target's length is `0`. For arrays and strings, it checks\n * the `length` property. For objects, it gets the count of\n * enumerable keys.\n *\n * expect([]).to.be.empty;\n * expect('').to.be.empty;\n * expect({}).to.be.empty;\n *\n * @name empty\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('empty', function () {\n var obj = flag(this, 'object')\n , expected = obj;\n\n if (Array.isArray(obj) || 'string' === typeof object) {\n expected = obj.length;\n } else if (typeof obj === 'object') {\n expected = Object.keys(obj).length;\n }\n\n this.assert(\n !expected\n , 'expected #{this} to be empty'\n , 'expected #{this} not to be empty'\n );\n });\n\n /**\n * ### .arguments\n *\n * Asserts that the target is an arguments object.\n *\n * function test () {\n * expect(arguments).to.be.arguments;\n * }\n *\n * @name arguments\n * @alias Arguments\n * @namespace BDD\n * @api public\n */\n\n function checkArguments () {\n var obj = flag(this, 'object')\n , type = Object.prototype.toString.call(obj);\n this.assert(\n '[object Arguments]' === type\n , 'expected #{this} to be arguments but got ' + type\n , 'expected #{this} to not be arguments'\n );\n }\n\n Assertion.addProperty('arguments', checkArguments);\n Assertion.addProperty('Arguments', checkArguments);\n\n /**\n * ### .equal(value)\n *\n * Asserts that the target is strictly equal (`===`) to `value`.\n * Alternately, if the `deep` flag is set, asserts that\n * the target is deeply equal to `value`.\n *\n * expect('hello').to.equal('hello');\n * expect(42).to.equal(42);\n * expect(1).to.not.equal(true);\n * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });\n * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });\n *\n * @name equal\n * @alias equals\n * @alias eq\n * @alias deep.equal\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEqual (val, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'deep')) {\n return this.eql(val);\n } else {\n this.assert(\n val === obj\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{exp}'\n , val\n , this._obj\n , true\n );\n }\n }\n\n Assertion.addMethod('equal', assertEqual);\n Assertion.addMethod('equals', assertEqual);\n Assertion.addMethod('eq', assertEqual);\n\n /**\n * ### .eql(value)\n *\n * Asserts that the target is deeply equal to `value`.\n *\n * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });\n * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);\n *\n * @name eql\n * @alias eqls\n * @param {Mixed} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertEql(obj, msg) {\n if (msg) flag(this, 'message', msg);\n this.assert(\n _.eql(obj, flag(this, 'object'))\n , 'expected #{this} to deeply equal #{exp}'\n , 'expected #{this} to not deeply equal #{exp}'\n , obj\n , this._obj\n , true\n );\n }\n\n Assertion.addMethod('eql', assertEql);\n Assertion.addMethod('eqls', assertEql);\n\n /**\n * ### .above(value)\n *\n * Asserts that the target is greater than `value`.\n *\n * expect(10).to.be.above(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n *\n * @name above\n * @alias gt\n * @alias greaterThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertAbove (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len > n\n , 'expected #{this} to have a length above #{exp} but got #{act}'\n , 'expected #{this} to not have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj > n\n , 'expected #{this} to be above ' + n\n , 'expected #{this} to be at most ' + n\n );\n }\n }\n\n Assertion.addMethod('above', assertAbove);\n Assertion.addMethod('gt', assertAbove);\n Assertion.addMethod('greaterThan', assertAbove);\n\n /**\n * ### .least(value)\n *\n * Asserts that the target is greater than or equal to `value`.\n *\n * expect(10).to.be.at.least(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a minimum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.least(2);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);\n *\n * @name least\n * @alias gte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLeast (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= n\n , 'expected #{this} to have a length at least #{exp} but got #{act}'\n , 'expected #{this} to have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj >= n\n , 'expected #{this} to be at least ' + n\n , 'expected #{this} to be below ' + n\n );\n }\n }\n\n Assertion.addMethod('least', assertLeast);\n Assertion.addMethod('gte', assertLeast);\n\n /**\n * ### .below(value)\n *\n * Asserts that the target is less than `value`.\n *\n * expect(5).to.be.below(10);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n *\n * @name below\n * @alias lt\n * @alias lessThan\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertBelow (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len < n\n , 'expected #{this} to have a length below #{exp} but got #{act}'\n , 'expected #{this} to not have a length below #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj < n\n , 'expected #{this} to be below ' + n\n , 'expected #{this} to be at least ' + n\n );\n }\n }\n\n Assertion.addMethod('below', assertBelow);\n Assertion.addMethod('lt', assertBelow);\n Assertion.addMethod('lessThan', assertBelow);\n\n /**\n * ### .most(value)\n *\n * Asserts that the target is less than or equal to `value`.\n *\n * expect(5).to.be.at.most(5);\n *\n * Can also be used in conjunction with `length` to\n * assert a maximum length. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.of.at.most(4);\n * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);\n *\n * @name most\n * @alias lte\n * @param {Number} value\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertMost (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len <= n\n , 'expected #{this} to have a length at most #{exp} but got #{act}'\n , 'expected #{this} to have a length above #{exp}'\n , n\n , len\n );\n } else {\n this.assert(\n obj <= n\n , 'expected #{this} to be at most ' + n\n , 'expected #{this} to be above ' + n\n );\n }\n }\n\n Assertion.addMethod('most', assertMost);\n Assertion.addMethod('lte', assertMost);\n\n /**\n * ### .within(start, finish)\n *\n * Asserts that the target is within a range.\n *\n * expect(7).to.be.within(5,10);\n *\n * Can also be used in conjunction with `length` to\n * assert a length range. The benefit being a\n * more informative error message than if the length\n * was supplied directly.\n *\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * @name within\n * @param {Number} start lowerbound inclusive\n * @param {Number} finish upperbound inclusive\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('within', function (start, finish, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , range = start + '..' + finish;\n if (flag(this, 'doLength')) {\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n this.assert(\n len >= start && len <= finish\n , 'expected #{this} to have a length within ' + range\n , 'expected #{this} to not have a length within ' + range\n );\n } else {\n this.assert(\n obj >= start && obj <= finish\n , 'expected #{this} to be within ' + range\n , 'expected #{this} to not be within ' + range\n );\n }\n });\n\n /**\n * ### .instanceof(constructor)\n *\n * Asserts that the target is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , Chai = new Tea('chai');\n *\n * expect(Chai).to.be.an.instanceof(Tea);\n * expect([ 1, 2, 3 ]).to.be.instanceof(Array);\n *\n * @name instanceof\n * @param {Constructor} constructor\n * @param {String} message _optional_\n * @alias instanceOf\n * @namespace BDD\n * @api public\n */\n\n function assertInstanceOf (constructor, msg) {\n if (msg) flag(this, 'message', msg);\n var name = _.getName(constructor);\n this.assert(\n flag(this, 'object') instanceof constructor\n , 'expected #{this} to be an instance of ' + name\n , 'expected #{this} to not be an instance of ' + name\n );\n };\n\n Assertion.addMethod('instanceof', assertInstanceOf);\n Assertion.addMethod('instanceOf', assertInstanceOf);\n\n /**\n * ### .property(name, [value])\n *\n * Asserts that the target has a property `name`, optionally asserting that\n * the value of that property is strictly equal to `value`.\n * If the `deep` flag is set, you can use dot- and bracket-notation for deep\n * references into objects and arrays.\n *\n * // simple referencing\n * var obj = { foo: 'bar' };\n * expect(obj).to.have.property('foo');\n * expect(obj).to.have.property('foo', 'bar');\n *\n * // deep referencing\n * var deepObj = {\n * green: { tea: 'matcha' }\n * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]\n * };\n *\n * expect(deepObj).to.have.deep.property('green.tea', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[1]', 'matcha');\n * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');\n *\n * You can also use an array as the starting point of a `deep.property`\n * assertion, or traverse nested arrays.\n *\n * var arr = [\n * [ 'chai', 'matcha', 'konacha' ]\n * , [ { tea: 'chai' }\n * , { tea: 'matcha' }\n * , { tea: 'konacha' } ]\n * ];\n *\n * expect(arr).to.have.deep.property('[0][1]', 'matcha');\n * expect(arr).to.have.deep.property('[1][2].tea', 'konacha');\n *\n * Furthermore, `property` changes the subject of the assertion\n * to be the value of that property from the original object. This\n * permits for further chainable assertions on that property.\n *\n * expect(obj).to.have.property('foo')\n * .that.is.a('string');\n * expect(deepObj).to.have.property('green')\n * .that.is.an('object')\n * .that.deep.equals({ tea: 'matcha' });\n * expect(deepObj).to.have.property('teas')\n * .that.is.an('array')\n * .with.deep.property('[2]')\n * .that.deep.equals({ tea: 'konacha' });\n *\n * Note that dots and bracket in `name` must be backslash-escaped when\n * the `deep` flag is set, while they must NOT be escaped when the `deep`\n * flag is not set.\n *\n * // simple referencing\n * var css = { '.link[target]': 42 };\n * expect(css).to.have.property('.link[target]', 42);\n *\n * // deep referencing\n * var deepCss = { '.link': { '[target]': 42 }};\n * expect(deepCss).to.have.deep.property('\\\\.link.\\\\[target\\\\]', 42);\n *\n * @name property\n * @alias deep.property\n * @param {String} name\n * @param {Mixed} value (optional)\n * @param {String} message _optional_\n * @returns value of property for chaining\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('property', function (name, val, msg) {\n if (msg) flag(this, 'message', msg);\n\n var isDeep = !!flag(this, 'deep')\n , descriptor = isDeep ? 'deep property ' : 'property '\n , negate = flag(this, 'negate')\n , obj = flag(this, 'object')\n , pathInfo = isDeep ? _.getPathInfo(name, obj) : null\n , hasProperty = isDeep\n ? pathInfo.exists\n : _.hasProperty(name, obj)\n , value = isDeep\n ? pathInfo.value\n : obj[name];\n\n if (negate && arguments.length > 1) {\n if (undefined === value) {\n msg = (msg != null) ? msg + ': ' : '';\n throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));\n }\n } else {\n this.assert(\n hasProperty\n , 'expected #{this} to have a ' + descriptor + _.inspect(name)\n , 'expected #{this} to not have ' + descriptor + _.inspect(name));\n }\n\n if (arguments.length > 1) {\n this.assert(\n val === value\n , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'\n , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'\n , val\n , value\n );\n }\n\n flag(this, 'object', value);\n });\n\n\n /**\n * ### .ownProperty(name)\n *\n * Asserts that the target has an own property `name`.\n *\n * expect('test').to.have.ownProperty('length');\n *\n * @name ownProperty\n * @alias haveOwnProperty\n * @param {String} name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnProperty (name, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n obj.hasOwnProperty(name)\n , 'expected #{this} to have own property ' + _.inspect(name)\n , 'expected #{this} to not have own property ' + _.inspect(name)\n );\n }\n\n Assertion.addMethod('ownProperty', assertOwnProperty);\n Assertion.addMethod('haveOwnProperty', assertOwnProperty);\n\n /**\n * ### .ownPropertyDescriptor(name[, descriptor[, message]])\n *\n * Asserts that the target has an own property descriptor `name`, that optionally matches `descriptor`.\n *\n * expect('test').to.have.ownPropertyDescriptor('length');\n * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 4 });\n * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable: false, configurable: false, writable: false, value: 3 });\n * expect('test').ownPropertyDescriptor('length').to.have.property('enumerable', false);\n * expect('test').ownPropertyDescriptor('length').to.have.keys('value');\n *\n * @name ownPropertyDescriptor\n * @alias haveOwnPropertyDescriptor\n * @param {String} name\n * @param {Object} descriptor _optional_\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertOwnPropertyDescriptor (name, descriptor, msg) {\n if (typeof descriptor === 'string') {\n msg = descriptor;\n descriptor = null;\n }\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name);\n if (actualDescriptor && descriptor) {\n this.assert(\n _.eql(descriptor, actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor)\n , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor)\n , descriptor\n , actualDescriptor\n , true\n );\n } else {\n this.assert(\n actualDescriptor\n , 'expected #{this} to have an own property descriptor for ' + _.inspect(name)\n , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name)\n );\n }\n flag(this, 'object', actualDescriptor);\n }\n\n Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor);\n Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor);\n\n /**\n * ### .length\n *\n * Sets the `doLength` flag later used as a chain precursor to a value\n * comparison for the `length` property.\n *\n * expect('foo').to.have.length.above(2);\n * expect([ 1, 2, 3 ]).to.have.length.above(2);\n * expect('foo').to.have.length.below(4);\n * expect([ 1, 2, 3 ]).to.have.length.below(4);\n * expect('foo').to.have.length.within(2,4);\n * expect([ 1, 2, 3 ]).to.have.length.within(2,4);\n *\n * *Deprecation notice:* Using `length` as an assertion will be deprecated\n * in version 2.4.0 and removed in 3.0.0. Code using the old style of\n * asserting for `length` property value using `length(value)` should be\n * switched to use `lengthOf(value)` instead.\n *\n * @name length\n * @namespace BDD\n * @api public\n */\n\n /**\n * ### .lengthOf(value[, message])\n *\n * Asserts that the target's `length` property has\n * the expected value.\n *\n * expect([ 1, 2, 3]).to.have.lengthOf(3);\n * expect('foobar').to.have.lengthOf(6);\n *\n * @name lengthOf\n * @param {Number} length\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertLengthChain () {\n flag(this, 'doLength', true);\n }\n\n function assertLength (n, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).to.have.property('length');\n var len = obj.length;\n\n this.assert(\n len == n\n , 'expected #{this} to have a length of #{exp} but got #{act}'\n , 'expected #{this} to not have a length of #{act}'\n , n\n , len\n );\n }\n\n Assertion.addChainableMethod('length', assertLength, assertLengthChain);\n Assertion.addMethod('lengthOf', assertLength);\n\n /**\n * ### .match(regexp)\n *\n * Asserts that the target matches a regular expression.\n *\n * expect('foobar').to.match(/^foo/);\n *\n * @name match\n * @alias matches\n * @param {RegExp} RegularExpression\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n function assertMatch(re, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n this.assert(\n re.exec(obj)\n , 'expected #{this} to match ' + re\n , 'expected #{this} not to match ' + re\n );\n }\n\n Assertion.addMethod('match', assertMatch);\n Assertion.addMethod('matches', assertMatch);\n\n /**\n * ### .string(string)\n *\n * Asserts that the string target contains another string.\n *\n * expect('foobar').to.have.string('bar');\n *\n * @name string\n * @param {String} string\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('string', function (str, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('string');\n\n this.assert(\n ~obj.indexOf(str)\n , 'expected #{this} to contain ' + _.inspect(str)\n , 'expected #{this} to not contain ' + _.inspect(str)\n );\n });\n\n\n /**\n * ### .keys(key1, [key2], [...])\n *\n * Asserts that the target contains any or all of the passed-in keys.\n * Use in combination with `any`, `all`, `contains`, or `have` will affect\n * what will pass.\n *\n * When used in conjunction with `any`, at least one key that is passed\n * in must exist in the target object. This is regardless whether or not\n * the `have` or `contain` qualifiers are used. Note, either `any` or `all`\n * should be used in the assertion. If neither are used, the assertion is\n * defaulted to `all`.\n *\n * When both `all` and `contain` are used, the target object must have at\n * least all of the passed-in keys but may have more keys not listed.\n *\n * When both `all` and `have` are used, the target object must both contain\n * all of the passed-in keys AND the number of keys in the target object must\n * match the number of keys passed in (in other words, a target object must\n * have all and only all of the passed-in keys).\n *\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz');\n * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz');\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']);\n * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6});\n * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7});\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']);\n * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6});\n *\n *\n * @name keys\n * @alias key\n * @param {...String|Array|Object} keys\n * @namespace BDD\n * @api public\n */\n\n function assertKeys (keys) {\n var obj = flag(this, 'object')\n , str\n , ok = true\n , mixedArgsMsg = 'keys must be given single argument of Array|Object|String, or multiple String arguments';\n\n switch (_.type(keys)) {\n case \"array\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n break;\n case \"object\":\n if (arguments.length > 1) throw (new Error(mixedArgsMsg));\n keys = Object.keys(keys);\n break;\n default:\n keys = Array.prototype.slice.call(arguments);\n }\n\n if (!keys.length) throw new Error('keys required');\n\n var actual = Object.keys(obj)\n , expected = keys\n , len = keys.length\n , any = flag(this, 'any')\n , all = flag(this, 'all');\n\n if (!any && !all) {\n all = true;\n }\n\n // Has any\n if (any) {\n var intersection = expected.filter(function(key) {\n return ~actual.indexOf(key);\n });\n ok = intersection.length > 0;\n }\n\n // Has all\n if (all) {\n ok = keys.every(function(key){\n return ~actual.indexOf(key);\n });\n if (!flag(this, 'negate') && !flag(this, 'contains')) {\n ok = ok && keys.length == actual.length;\n }\n }\n\n // Key string\n if (len > 1) {\n keys = keys.map(function(key){\n return _.inspect(key);\n });\n var last = keys.pop();\n if (all) {\n str = keys.join(', ') + ', and ' + last;\n }\n if (any) {\n str = keys.join(', ') + ', or ' + last;\n }\n } else {\n str = _.inspect(keys[0]);\n }\n\n // Form\n str = (len > 1 ? 'keys ' : 'key ') + str;\n\n // Have / include\n str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;\n\n // Assertion\n this.assert(\n ok\n , 'expected #{this} to ' + str\n , 'expected #{this} to not ' + str\n , expected.slice(0).sort()\n , actual.sort()\n , true\n );\n }\n\n Assertion.addMethod('keys', assertKeys);\n Assertion.addMethod('key', assertKeys);\n\n /**\n * ### .throw(constructor)\n *\n * Asserts that the function target will throw a specific error, or specific type of error\n * (as determined using `instanceof`), optionally with a RegExp or string inclusion test\n * for the error's message.\n *\n * var err = new ReferenceError('This is a bad function.');\n * var fn = function () { throw err; }\n * expect(fn).to.throw(ReferenceError);\n * expect(fn).to.throw(Error);\n * expect(fn).to.throw(/bad function/);\n * expect(fn).to.not.throw('good function');\n * expect(fn).to.throw(ReferenceError, /bad function/);\n * expect(fn).to.throw(err);\n *\n * Please note that when a throw expectation is negated, it will check each\n * parameter independently, starting with error constructor type. The appropriate way\n * to check for the existence of a type of error but for a message that does not match\n * is to use `and`.\n *\n * expect(fn).to.throw(ReferenceError)\n * .and.not.throw(/good function/);\n *\n * @name throw\n * @alias throws\n * @alias Throw\n * @param {ErrorConstructor} constructor\n * @param {String|RegExp} expected error message\n * @param {String} message _optional_\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @returns error for chaining (null if no error)\n * @namespace BDD\n * @api public\n */\n\n function assertThrows (constructor, errMsg, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n new Assertion(obj, msg).is.a('function');\n\n var thrown = false\n , desiredError = null\n , name = null\n , thrownError = null;\n\n if (arguments.length === 0) {\n errMsg = null;\n constructor = null;\n } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {\n errMsg = constructor;\n constructor = null;\n } else if (constructor && constructor instanceof Error) {\n desiredError = constructor;\n constructor = null;\n errMsg = null;\n } else if (typeof constructor === 'function') {\n name = constructor.prototype.name;\n if (!name || (name === 'Error' && constructor !== Error)) {\n name = constructor.name || (new constructor()).name;\n }\n } else {\n constructor = null;\n }\n\n try {\n obj();\n } catch (err) {\n // first, check desired error\n if (desiredError) {\n this.assert(\n err === desiredError\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp}'\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (err instanceof Error ? err.toString() : err)\n );\n\n flag(this, 'object', err);\n return this;\n }\n\n // next, check constructor\n if (constructor) {\n this.assert(\n err instanceof constructor\n , 'expected #{this} to throw #{exp} but #{act} was thrown'\n , 'expected #{this} to not throw #{exp} but #{act} was thrown'\n , name\n , (err instanceof Error ? err.toString() : err)\n );\n\n if (!errMsg) {\n flag(this, 'object', err);\n return this;\n }\n }\n\n // next, check message\n var message = 'error' === _.type(err) && \"message\" in err\n ? err.message\n : '' + err;\n\n if ((message != null) && errMsg && errMsg instanceof RegExp) {\n this.assert(\n errMsg.exec(message)\n , 'expected #{this} to throw error matching #{exp} but got #{act}'\n , 'expected #{this} to throw error not matching #{exp}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else if ((message != null) && errMsg && 'string' === typeof errMsg) {\n this.assert(\n ~message.indexOf(errMsg)\n , 'expected #{this} to throw error including #{exp} but got #{act}'\n , 'expected #{this} to throw error not including #{act}'\n , errMsg\n , message\n );\n\n flag(this, 'object', err);\n return this;\n } else {\n thrown = true;\n thrownError = err;\n }\n }\n\n var actuallyGot = ''\n , expectedThrown = name !== null\n ? name\n : desiredError\n ? '#{exp}' //_.inspect(desiredError)\n : 'an error';\n\n if (thrown) {\n actuallyGot = ' but #{act} was thrown'\n }\n\n this.assert(\n thrown === true\n , 'expected #{this} to throw ' + expectedThrown + actuallyGot\n , 'expected #{this} to not throw ' + expectedThrown + actuallyGot\n , (desiredError instanceof Error ? desiredError.toString() : desiredError)\n , (thrownError instanceof Error ? thrownError.toString() : thrownError)\n );\n\n flag(this, 'object', thrownError);\n };\n\n Assertion.addMethod('throw', assertThrows);\n Assertion.addMethod('throws', assertThrows);\n Assertion.addMethod('Throw', assertThrows);\n\n /**\n * ### .respondTo(method)\n *\n * Asserts that the object or class target will respond to a method.\n *\n * Klass.prototype.bar = function(){};\n * expect(Klass).to.respondTo('bar');\n * expect(obj).to.respondTo('bar');\n *\n * To check if a constructor will respond to a static function,\n * set the `itself` flag.\n *\n * Klass.baz = function(){};\n * expect(Klass).itself.to.respondTo('baz');\n *\n * @name respondTo\n * @alias respondsTo\n * @param {String} method\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function respondTo (method, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object')\n , itself = flag(this, 'itself')\n , context = ('function' === _.type(obj) && !itself)\n ? obj.prototype[method]\n : obj[method];\n\n this.assert(\n 'function' === typeof context\n , 'expected #{this} to respond to ' + _.inspect(method)\n , 'expected #{this} to not respond to ' + _.inspect(method)\n );\n }\n\n Assertion.addMethod('respondTo', respondTo);\n Assertion.addMethod('respondsTo', respondTo);\n\n /**\n * ### .itself\n *\n * Sets the `itself` flag, later used by the `respondTo` assertion.\n *\n * function Foo() {}\n * Foo.bar = function() {}\n * Foo.prototype.baz = function() {}\n *\n * expect(Foo).itself.to.respondTo('bar');\n * expect(Foo).itself.not.to.respondTo('baz');\n *\n * @name itself\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('itself', function () {\n flag(this, 'itself', true);\n });\n\n /**\n * ### .satisfy(method)\n *\n * Asserts that the target passes a given truth test.\n *\n * expect(1).to.satisfy(function(num) { return num > 0; });\n *\n * @name satisfy\n * @alias satisfies\n * @param {Function} matcher\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function satisfy (matcher, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n var result = matcher(obj);\n this.assert(\n result\n , 'expected #{this} to satisfy ' + _.objDisplay(matcher)\n , 'expected #{this} to not satisfy' + _.objDisplay(matcher)\n , this.negate ? false : true\n , result\n );\n }\n\n Assertion.addMethod('satisfy', satisfy);\n Assertion.addMethod('satisfies', satisfy);\n\n /**\n * ### .closeTo(expected, delta)\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * expect(1.5).to.be.closeTo(1, 0.5);\n *\n * @name closeTo\n * @alias approximately\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function closeTo(expected, delta, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj, msg).is.a('number');\n if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {\n throw new Error('the arguments to closeTo or approximately must be numbers');\n }\n\n this.assert(\n Math.abs(obj - expected) <= delta\n , 'expected #{this} to be close to ' + expected + ' +/- ' + delta\n , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta\n );\n }\n\n Assertion.addMethod('closeTo', closeTo);\n Assertion.addMethod('approximately', closeTo);\n\n function isSubsetOf(subset, superset, cmp) {\n return subset.every(function(elem) {\n if (!cmp) return superset.indexOf(elem) !== -1;\n\n return superset.some(function(elem2) {\n return cmp(elem, elem2);\n });\n })\n }\n\n /**\n * ### .members(set)\n *\n * Asserts that the target is a superset of `set`,\n * or that the target and `set` have the same strictly-equal (===) members.\n * Alternately, if the `deep` flag is set, set members are compared for deep\n * equality.\n *\n * expect([1, 2, 3]).to.include.members([3, 2]);\n * expect([1, 2, 3]).to.not.include.members([3, 2, 8]);\n *\n * expect([4, 2]).to.have.members([2, 4]);\n * expect([5, 2]).to.not.have.members([5, 2, 1]);\n *\n * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);\n *\n * @name members\n * @param {Array} set\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n Assertion.addMethod('members', function (subset, msg) {\n if (msg) flag(this, 'message', msg);\n var obj = flag(this, 'object');\n\n new Assertion(obj).to.be.an('array');\n new Assertion(subset).to.be.an('array');\n\n var cmp = flag(this, 'deep') ? _.eql : undefined;\n\n if (flag(this, 'contains')) {\n return this.assert(\n isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to be a superset of #{act}'\n , 'expected #{this} to not be a superset of #{act}'\n , obj\n , subset\n );\n }\n\n this.assert(\n isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)\n , 'expected #{this} to have the same members as #{act}'\n , 'expected #{this} to not have the same members as #{act}'\n , obj\n , subset\n );\n });\n\n /**\n * ### .oneOf(list)\n *\n * Assert that a value appears somewhere in the top level of array `list`.\n *\n * expect('a').to.be.oneOf(['a', 'b', 'c']);\n * expect(9).to.not.be.oneOf(['z']);\n * expect([3]).to.not.be.oneOf([1, 2, [3]]);\n *\n * var three = [3];\n * // for object-types, contents are not compared\n * expect(three).to.not.be.oneOf([1, 2, [3]]);\n * // comparing references works\n * expect(three).to.be.oneOf([1, 2, three]);\n *\n * @name oneOf\n * @param {Array<*>} list\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function oneOf (list, msg) {\n if (msg) flag(this, 'message', msg);\n var expected = flag(this, 'object');\n new Assertion(list).to.be.an('array');\n\n this.assert(\n list.indexOf(expected) > -1\n , 'expected #{this} to be one of #{exp}'\n , 'expected #{this} to not be one of #{exp}'\n , list\n , expected\n );\n }\n\n Assertion.addMethod('oneOf', oneOf);\n\n\n /**\n * ### .change(function)\n *\n * Asserts that a function changes an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val += 3 };\n * var noChangeFn = function() { return 'foo' + 'bar'; }\n * expect(fn).to.change(obj, 'val');\n * expect(noChangeFn).to.not.change(obj, 'val')\n *\n * @name change\n * @alias changes\n * @alias Change\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertChanges (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n initial !== object[prop]\n , 'expected .' + prop + ' to change'\n , 'expected .' + prop + ' to not change'\n );\n }\n\n Assertion.addChainableMethod('change', assertChanges);\n Assertion.addChainableMethod('changes', assertChanges);\n\n /**\n * ### .increase(function)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * expect(fn).to.increase(obj, 'val');\n *\n * @name increase\n * @alias increases\n * @alias Increase\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertIncreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial > 0\n , 'expected .' + prop + ' to increase'\n , 'expected .' + prop + ' to not increase'\n );\n }\n\n Assertion.addChainableMethod('increase', assertIncreases);\n Assertion.addChainableMethod('increases', assertIncreases);\n\n /**\n * ### .decrease(function)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * expect(fn).to.decrease(obj, 'val');\n *\n * @name decrease\n * @alias decreases\n * @alias Decrease\n * @param {String} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace BDD\n * @api public\n */\n\n function assertDecreases (object, prop, msg) {\n if (msg) flag(this, 'message', msg);\n var fn = flag(this, 'object');\n new Assertion(object, msg).to.have.property(prop);\n new Assertion(fn).is.a('function');\n\n var initial = object[prop];\n fn();\n\n this.assert(\n object[prop] - initial < 0\n , 'expected .' + prop + ' to decrease'\n , 'expected .' + prop + ' to not decrease'\n );\n }\n\n Assertion.addChainableMethod('decrease', assertDecreases);\n Assertion.addChainableMethod('decreases', assertDecreases);\n\n /**\n * ### .extensible\n *\n * Asserts that the target is extensible (can have new properties added to\n * it).\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect({}).to.be.extensible;\n * expect(nonExtensibleObject).to.not.be.extensible;\n * expect(sealedObject).to.not.be.extensible;\n * expect(frozenObject).to.not.be.extensible;\n *\n * @name extensible\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('extensible', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false.\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isExtensible;\n\n try {\n isExtensible = Object.isExtensible(obj);\n } catch (err) {\n if (err instanceof TypeError) isExtensible = false;\n else throw err;\n }\n\n this.assert(\n isExtensible\n , 'expected #{this} to be extensible'\n , 'expected #{this} to not be extensible'\n );\n });\n\n /**\n * ### .sealed\n *\n * Asserts that the target is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freeze({});\n *\n * expect(sealedObject).to.be.sealed;\n * expect(frozenObject).to.be.sealed;\n * expect({}).to.not.be.sealed;\n *\n * @name sealed\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('sealed', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isSealed;\n\n try {\n isSealed = Object.isSealed(obj);\n } catch (err) {\n if (err instanceof TypeError) isSealed = true;\n else throw err;\n }\n\n this.assert(\n isSealed\n , 'expected #{this} to be sealed'\n , 'expected #{this} to not be sealed'\n );\n });\n\n /**\n * ### .frozen\n *\n * Asserts that the target is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n *\n * expect(frozenObject).to.be.frozen;\n * expect({}).to.not.be.frozen;\n *\n * @name frozen\n * @namespace BDD\n * @api public\n */\n\n Assertion.addProperty('frozen', function() {\n var obj = flag(this, 'object');\n\n // In ES5, if the argument to this method is not an object (a primitive), then it will cause a TypeError.\n // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true.\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen\n // The following provides ES6 behavior when a TypeError is thrown under ES5.\n\n var isFrozen;\n\n try {\n isFrozen = Object.isFrozen(obj);\n } catch (err) {\n if (err instanceof TypeError) isFrozen = true;\n else throw err;\n }\n\n this.assert(\n isFrozen\n , 'expected #{this} to be frozen'\n , 'expected #{this} to not be frozen'\n );\n });\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\n\nmodule.exports = function (chai, util) {\n\n /*!\n * Chai dependencies.\n */\n\n var Assertion = chai.Assertion\n , flag = util.flag;\n\n /*!\n * Module export.\n */\n\n /**\n * ### assert(expression, message)\n *\n * Write your own test expressions.\n *\n * assert('foo' !== 'bar', 'foo is not bar');\n * assert(Array.isArray([]), 'empty arrays are arrays');\n *\n * @param {Mixed} expression to test for truthiness\n * @param {String} message to display on error\n * @name assert\n * @namespace Assert\n * @api public\n */\n\n var assert = chai.assert = function (express, errmsg) {\n var test = new Assertion(null, null, chai.assert);\n test.assert(\n express\n , errmsg\n , '[ negation message unavailable ]'\n );\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure. Node.js `assert` module-compatible.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Assert\n * @api public\n */\n\n assert.fail = function (actual, expected, message, operator) {\n message = message || 'assert.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, assert.fail);\n };\n\n /**\n * ### .isOk(object, [message])\n *\n * Asserts that `object` is truthy.\n *\n * assert.isOk('everything', 'everything is ok');\n * assert.isOk(false, 'this will fail');\n *\n * @name isOk\n * @alias ok\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isOk = function (val, msg) {\n new Assertion(val, msg).is.ok;\n };\n\n /**\n * ### .isNotOk(object, [message])\n *\n * Asserts that `object` is falsy.\n *\n * assert.isNotOk('everything', 'this will fail');\n * assert.isNotOk(false, 'this will pass');\n *\n * @name isNotOk\n * @alias notOk\n * @param {Mixed} object to test\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotOk = function (val, msg) {\n new Assertion(val, msg).is.not.ok;\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * assert.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.equal = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.equal);\n\n test.assert(\n exp == flag(test, 'object')\n , 'expected #{this} to equal #{exp}'\n , 'expected #{this} to not equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .notEqual(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * assert.notEqual(3, 4, 'these numbers are not equal');\n *\n * @name notEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notEqual = function (act, exp, msg) {\n var test = new Assertion(act, msg, assert.notEqual);\n\n test.assert(\n exp != flag(test, 'object')\n , 'expected #{this} to not equal #{exp}'\n , 'expected #{this} to equal #{act}'\n , exp\n , act\n );\n };\n\n /**\n * ### .strictEqual(actual, expected, [message])\n *\n * Asserts strict equality (`===`) of `actual` and `expected`.\n *\n * assert.strictEqual(true, true, 'these booleans are strictly equal');\n *\n * @name strictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.strictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.equal(exp);\n };\n\n /**\n * ### .notStrictEqual(actual, expected, [message])\n *\n * Asserts strict inequality (`!==`) of `actual` and `expected`.\n *\n * assert.notStrictEqual(3, '3', 'no coercion for strict equality');\n *\n * @name notStrictEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notStrictEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.equal(exp);\n };\n\n /**\n * ### .deepEqual(actual, expected, [message])\n *\n * Asserts that `actual` is deeply equal to `expected`.\n *\n * assert.deepEqual({ tea: 'green' }, { tea: 'green' });\n *\n * @name deepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.eql(exp);\n };\n\n /**\n * ### .notDeepEqual(actual, expected, [message])\n *\n * Assert that `actual` is not deeply equal to `expected`.\n *\n * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });\n *\n * @name notDeepEqual\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepEqual = function (act, exp, msg) {\n new Assertion(act, msg).to.not.eql(exp);\n };\n\n /**\n * ### .isAbove(valueToCheck, valueToBeAbove, [message])\n *\n * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`\n *\n * assert.isAbove(5, 2, '5 is strictly greater than 2');\n *\n * @name isAbove\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAbove\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAbove = function (val, abv, msg) {\n new Assertion(val, msg).to.be.above(abv);\n };\n\n /**\n * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message])\n *\n * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`\n *\n * assert.isAtLeast(5, 2, '5 is greater or equal to 2');\n * assert.isAtLeast(3, 3, '3 is greater or equal to 3');\n *\n * @name isAtLeast\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtLeast\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtLeast = function (val, atlst, msg) {\n new Assertion(val, msg).to.be.least(atlst);\n };\n\n /**\n * ### .isBelow(valueToCheck, valueToBeBelow, [message])\n *\n * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`\n *\n * assert.isBelow(3, 6, '3 is strictly less than 6');\n *\n * @name isBelow\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeBelow\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBelow = function (val, blw, msg) {\n new Assertion(val, msg).to.be.below(blw);\n };\n\n /**\n * ### .isAtMost(valueToCheck, valueToBeAtMost, [message])\n *\n * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`\n *\n * assert.isAtMost(3, 6, '3 is less than or equal to 6');\n * assert.isAtMost(4, 4, '4 is less than or equal to 4');\n *\n * @name isAtMost\n * @param {Mixed} valueToCheck\n * @param {Mixed} valueToBeAtMost\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isAtMost = function (val, atmst, msg) {\n new Assertion(val, msg).to.be.most(atmst);\n };\n\n /**\n * ### .isTrue(value, [message])\n *\n * Asserts that `value` is true.\n *\n * var teaServed = true;\n * assert.isTrue(teaServed, 'the tea has been served');\n *\n * @name isTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isTrue = function (val, msg) {\n new Assertion(val, msg).is['true'];\n };\n\n /**\n * ### .isNotTrue(value, [message])\n *\n * Asserts that `value` is not true.\n *\n * var tea = 'tasty chai';\n * assert.isNotTrue(tea, 'great, time for tea!');\n *\n * @name isNotTrue\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotTrue = function (val, msg) {\n new Assertion(val, msg).to.not.equal(true);\n };\n\n /**\n * ### .isFalse(value, [message])\n *\n * Asserts that `value` is false.\n *\n * var teaServed = false;\n * assert.isFalse(teaServed, 'no tea yet? hmm...');\n *\n * @name isFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFalse = function (val, msg) {\n new Assertion(val, msg).is['false'];\n };\n\n /**\n * ### .isNotFalse(value, [message])\n *\n * Asserts that `value` is not false.\n *\n * var tea = 'tasty chai';\n * assert.isNotFalse(tea, 'great, time for tea!');\n *\n * @name isNotFalse\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFalse = function (val, msg) {\n new Assertion(val, msg).to.not.equal(false);\n };\n\n /**\n * ### .isNull(value, [message])\n *\n * Asserts that `value` is null.\n *\n * assert.isNull(err, 'there was no error');\n *\n * @name isNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNull = function (val, msg) {\n new Assertion(val, msg).to.equal(null);\n };\n\n /**\n * ### .isNotNull(value, [message])\n *\n * Asserts that `value` is not null.\n *\n * var tea = 'tasty chai';\n * assert.isNotNull(tea, 'great, time for tea!');\n *\n * @name isNotNull\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNull = function (val, msg) {\n new Assertion(val, msg).to.not.equal(null);\n };\n\n /**\n * ### .isNaN\n * Asserts that value is NaN\n *\n * assert.isNaN('foo', 'foo is NaN');\n *\n * @name isNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNaN = function (val, msg) {\n new Assertion(val, msg).to.be.NaN;\n };\n\n /**\n * ### .isNotNaN\n * Asserts that value is not NaN\n *\n * assert.isNotNaN(4, '4 is not NaN');\n *\n * @name isNotNaN\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n assert.isNotNaN = function (val, msg) {\n new Assertion(val, msg).not.to.be.NaN;\n };\n\n /**\n * ### .isUndefined(value, [message])\n *\n * Asserts that `value` is `undefined`.\n *\n * var tea;\n * assert.isUndefined(tea, 'no tea defined');\n *\n * @name isUndefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isUndefined = function (val, msg) {\n new Assertion(val, msg).to.equal(undefined);\n };\n\n /**\n * ### .isDefined(value, [message])\n *\n * Asserts that `value` is not `undefined`.\n *\n * var tea = 'cup of chai';\n * assert.isDefined(tea, 'tea has been defined');\n *\n * @name isDefined\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isDefined = function (val, msg) {\n new Assertion(val, msg).to.not.equal(undefined);\n };\n\n /**\n * ### .isFunction(value, [message])\n *\n * Asserts that `value` is a function.\n *\n * function serveTea() { return 'cup of tea'; };\n * assert.isFunction(serveTea, 'great, we can have tea now');\n *\n * @name isFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isFunction = function (val, msg) {\n new Assertion(val, msg).to.be.a('function');\n };\n\n /**\n * ### .isNotFunction(value, [message])\n *\n * Asserts that `value` is _not_ a function.\n *\n * var serveTea = [ 'heat', 'pour', 'sip' ];\n * assert.isNotFunction(serveTea, 'great, we have listed the steps');\n *\n * @name isNotFunction\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFunction = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('function');\n };\n\n /**\n * ### .isObject(value, [message])\n *\n * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`).\n * _The assertion does not match subclassed objects._\n *\n * var selection = { name: 'Chai', serve: 'with spices' };\n * assert.isObject(selection, 'tea selection is an object');\n *\n * @name isObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isObject = function (val, msg) {\n new Assertion(val, msg).to.be.a('object');\n };\n\n /**\n * ### .isNotObject(value, [message])\n *\n * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`).\n *\n * var selection = 'chai'\n * assert.isNotObject(selection, 'tea selection is not an object');\n * assert.isNotObject(null, 'null is not an object');\n *\n * @name isNotObject\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotObject = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('object');\n };\n\n /**\n * ### .isArray(value, [message])\n *\n * Asserts that `value` is an array.\n *\n * var menu = [ 'green', 'chai', 'oolong' ];\n * assert.isArray(menu, 'what kind of tea do we want?');\n *\n * @name isArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isArray = function (val, msg) {\n new Assertion(val, msg).to.be.an('array');\n };\n\n /**\n * ### .isNotArray(value, [message])\n *\n * Asserts that `value` is _not_ an array.\n *\n * var menu = 'green|chai|oolong';\n * assert.isNotArray(menu, 'what kind of tea do we want?');\n *\n * @name isNotArray\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotArray = function (val, msg) {\n new Assertion(val, msg).to.not.be.an('array');\n };\n\n /**\n * ### .isString(value, [message])\n *\n * Asserts that `value` is a string.\n *\n * var teaOrder = 'chai';\n * assert.isString(teaOrder, 'order placed');\n *\n * @name isString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isString = function (val, msg) {\n new Assertion(val, msg).to.be.a('string');\n };\n\n /**\n * ### .isNotString(value, [message])\n *\n * Asserts that `value` is _not_ a string.\n *\n * var teaOrder = 4;\n * assert.isNotString(teaOrder, 'order placed');\n *\n * @name isNotString\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotString = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('string');\n };\n\n /**\n * ### .isNumber(value, [message])\n *\n * Asserts that `value` is a number.\n *\n * var cups = 2;\n * assert.isNumber(cups, 'how many cups');\n *\n * @name isNumber\n * @param {Number} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNumber = function (val, msg) {\n new Assertion(val, msg).to.be.a('number');\n };\n\n /**\n * ### .isNotNumber(value, [message])\n *\n * Asserts that `value` is _not_ a number.\n *\n * var cups = '2 cups please';\n * assert.isNotNumber(cups, 'how many cups');\n *\n * @name isNotNumber\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotNumber = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('number');\n };\n\n /**\n * ### .isBoolean(value, [message])\n *\n * Asserts that `value` is a boolean.\n *\n * var teaReady = true\n * , teaServed = false;\n *\n * assert.isBoolean(teaReady, 'is the tea ready');\n * assert.isBoolean(teaServed, 'has tea been served');\n *\n * @name isBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isBoolean = function (val, msg) {\n new Assertion(val, msg).to.be.a('boolean');\n };\n\n /**\n * ### .isNotBoolean(value, [message])\n *\n * Asserts that `value` is _not_ a boolean.\n *\n * var teaReady = 'yep'\n * , teaServed = 'nope';\n *\n * assert.isNotBoolean(teaReady, 'is the tea ready');\n * assert.isNotBoolean(teaServed, 'has tea been served');\n *\n * @name isNotBoolean\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.isNotBoolean = function (val, msg) {\n new Assertion(val, msg).to.not.be.a('boolean');\n };\n\n /**\n * ### .typeOf(value, name, [message])\n *\n * Asserts that `value`'s type is `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');\n * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');\n * assert.typeOf('tea', 'string', 'we have a string');\n * assert.typeOf(/tea/, 'regexp', 'we have a regular expression');\n * assert.typeOf(null, 'null', 'we have a null');\n * assert.typeOf(undefined, 'undefined', 'we have an undefined');\n *\n * @name typeOf\n * @param {Mixed} value\n * @param {String} name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.typeOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.a(type);\n };\n\n /**\n * ### .notTypeOf(value, name, [message])\n *\n * Asserts that `value`'s type is _not_ `name`, as determined by\n * `Object.prototype.toString`.\n *\n * assert.notTypeOf('tea', 'number', 'strings are not numbers');\n *\n * @name notTypeOf\n * @param {Mixed} value\n * @param {String} typeof name\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notTypeOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.a(type);\n };\n\n /**\n * ### .instanceOf(object, constructor, [message])\n *\n * Asserts that `value` is an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new Tea('chai');\n *\n * assert.instanceOf(chai, Tea, 'chai is an instance of tea');\n *\n * @name instanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.instanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.be.instanceOf(type);\n };\n\n /**\n * ### .notInstanceOf(object, constructor, [message])\n *\n * Asserts `value` is not an instance of `constructor`.\n *\n * var Tea = function (name) { this.name = name; }\n * , chai = new String('chai');\n *\n * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');\n *\n * @name notInstanceOf\n * @param {Object} object\n * @param {Constructor} constructor\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInstanceOf = function (val, type, msg) {\n new Assertion(val, msg).to.not.be.instanceOf(type);\n };\n\n /**\n * ### .include(haystack, needle, [message])\n *\n * Asserts that `haystack` includes `needle`. Works\n * for strings and arrays.\n *\n * assert.include('foobar', 'bar', 'foobar contains string \"bar\"');\n * assert.include([ 1, 2, 3 ], 3, 'array contains value');\n *\n * @name include\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.include = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.include).include(inc);\n };\n\n /**\n * ### .notInclude(haystack, needle, [message])\n *\n * Asserts that `haystack` does not include `needle`. Works\n * for strings and arrays.\n *\n * assert.notInclude('foobar', 'baz', 'string not include substring');\n * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');\n *\n * @name notInclude\n * @param {Array|String} haystack\n * @param {Mixed} needle\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notInclude = function (exp, inc, msg) {\n new Assertion(exp, msg, assert.notInclude).not.include(inc);\n };\n\n /**\n * ### .match(value, regexp, [message])\n *\n * Asserts that `value` matches the regular expression `regexp`.\n *\n * assert.match('foobar', /^foo/, 'regexp matches');\n *\n * @name match\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.match = function (exp, re, msg) {\n new Assertion(exp, msg).to.match(re);\n };\n\n /**\n * ### .notMatch(value, regexp, [message])\n *\n * Asserts that `value` does not match the regular expression `regexp`.\n *\n * assert.notMatch('foobar', /^foo/, 'regexp does not match');\n *\n * @name notMatch\n * @param {Mixed} value\n * @param {RegExp} regexp\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notMatch = function (exp, re, msg) {\n new Assertion(exp, msg).to.not.match(re);\n };\n\n /**\n * ### .property(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`.\n *\n * assert.property({ tea: { green: 'matcha' }}, 'tea');\n *\n * @name property\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.property = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.property(prop);\n };\n\n /**\n * ### .notProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`.\n *\n * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');\n *\n * @name notProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.property(prop);\n };\n\n /**\n * ### .deepProperty(object, property, [message])\n *\n * Asserts that `object` has a property named by `property`, which can be a\n * string using dot- and bracket-notation for deep reference.\n *\n * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');\n *\n * @name deepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop);\n };\n\n /**\n * ### .notDeepProperty(object, property, [message])\n *\n * Asserts that `object` does _not_ have a property named by `property`, which\n * can be a string using dot- and bracket-notation for deep reference.\n *\n * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');\n *\n * @name notDeepProperty\n * @param {Object} object\n * @param {String} property\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.notDeepProperty = function (obj, prop, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop);\n };\n\n /**\n * ### .propertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`.\n *\n * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');\n *\n * @name propertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.property(prop, val);\n };\n\n /**\n * ### .propertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`.\n *\n * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');\n *\n * @name propertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.propertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.property(prop, val);\n };\n\n /**\n * ### .deepPropertyVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property` with value given\n * by `value`. `property` can use dot- and bracket-notation for deep\n * reference.\n *\n * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');\n *\n * @name deepPropertyVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.have.deep.property(prop, val);\n };\n\n /**\n * ### .deepPropertyNotVal(object, property, value, [message])\n *\n * Asserts that `object` has a property named by `property`, but with a value\n * different from that given by `value`. `property` can use dot- and\n * bracket-notation for deep reference.\n *\n * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');\n *\n * @name deepPropertyNotVal\n * @param {Object} object\n * @param {String} property\n * @param {Mixed} value\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.deepPropertyNotVal = function (obj, prop, val, msg) {\n new Assertion(obj, msg).to.not.have.deep.property(prop, val);\n };\n\n /**\n * ### .lengthOf(object, length, [message])\n *\n * Asserts that `object` has a `length` property with the expected value.\n *\n * assert.lengthOf([1,2,3], 3, 'array has length of 3');\n * assert.lengthOf('foobar', 6, 'string has length of 6');\n *\n * @name lengthOf\n * @param {Mixed} object\n * @param {Number} length\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.lengthOf = function (exp, len, msg) {\n new Assertion(exp, msg).to.have.length(len);\n };\n\n /**\n * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * assert.throws(fn, 'function throws a reference error');\n * assert.throws(fn, /function throws a reference error/);\n * assert.throws(fn, ReferenceError);\n * assert.throws(fn, ReferenceError, 'function throws a reference error');\n * assert.throws(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throws\n * @alias throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.throws = function (fn, errt, errs, msg) {\n if ('string' === typeof errt || errt instanceof RegExp) {\n errs = errt;\n errt = null;\n }\n\n var assertErr = new Assertion(fn, msg).to.throw(errt, errs);\n return flag(assertErr, 'object');\n };\n\n /**\n * ### .doesNotThrow(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * assert.doesNotThrow(fn, Error, 'function does not throw');\n *\n * @name doesNotThrow\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotThrow = function (fn, type, msg) {\n if ('string' === typeof type) {\n msg = type;\n type = null;\n }\n\n new Assertion(fn, msg).to.not.Throw(type);\n };\n\n /**\n * ### .operator(val1, operator, val2, [message])\n *\n * Compares two values using `operator`.\n *\n * assert.operator(1, '<', 2, 'everything is ok');\n * assert.operator(1, '>', 2, 'this will fail');\n *\n * @name operator\n * @param {Mixed} val1\n * @param {String} operator\n * @param {Mixed} val2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.operator = function (val, operator, val2, msg) {\n var ok;\n switch(operator) {\n case '==':\n ok = val == val2;\n break;\n case '===':\n ok = val === val2;\n break;\n case '>':\n ok = val > val2;\n break;\n case '>=':\n ok = val >= val2;\n break;\n case '<':\n ok = val < val2;\n break;\n case '<=':\n ok = val <= val2;\n break;\n case '!=':\n ok = val != val2;\n break;\n case '!==':\n ok = val !== val2;\n break;\n default:\n throw new Error('Invalid operator \"' + operator + '\"');\n }\n var test = new Assertion(ok, msg);\n test.assert(\n true === flag(test, 'object')\n , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)\n , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );\n };\n\n /**\n * ### .closeTo(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.closeTo(1.5, 1, 0.5, 'numbers are close');\n *\n * @name closeTo\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.closeTo = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.closeTo(exp, delta);\n };\n\n /**\n * ### .approximately(actual, expected, delta, [message])\n *\n * Asserts that the target is equal `expected`, to within a +/- `delta` range.\n *\n * assert.approximately(1.5, 1, 0.5, 'numbers are close');\n *\n * @name approximately\n * @param {Number} actual\n * @param {Number} expected\n * @param {Number} delta\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.approximately = function (act, exp, delta, msg) {\n new Assertion(act, msg).to.be.approximately(exp, delta);\n };\n\n /**\n * ### .sameMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members.\n * Order is not taken into account.\n *\n * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');\n *\n * @name sameMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.members(set2);\n }\n\n /**\n * ### .sameDeepMembers(set1, set2, [message])\n *\n * Asserts that `set1` and `set2` have the same members - using a deep equality checking.\n * Order is not taken into account.\n *\n * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a: 2} ], 'same deep members');\n *\n * @name sameDeepMembers\n * @param {Array} set1\n * @param {Array} set2\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.sameDeepMembers = function (set1, set2, msg) {\n new Assertion(set1, msg).to.have.same.deep.members(set2);\n }\n\n /**\n * ### .includeMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset`.\n * Order is not taken into account.\n *\n * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');\n *\n * @name includeMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.members(subset);\n }\n\n /**\n * ### .includeDeepMembers(superset, subset, [message])\n *\n * Asserts that `subset` is included in `superset` - using deep equality checking.\n * Order is not taken into account.\n * Duplicates are ignored.\n *\n * assert.includeDeepMembers([ {a: 1}, {b: 2}, {c: 3} ], [ {b: 2}, {a: 1}, {b: 2} ], 'include deep members');\n *\n * @name includeDeepMembers\n * @param {Array} superset\n * @param {Array} subset\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.includeDeepMembers = function (superset, subset, msg) {\n new Assertion(superset, msg).to.include.deep.members(subset);\n }\n\n /**\n * ### .oneOf(inList, list, [message])\n *\n * Asserts that non-object, non-array value `inList` appears in the flat array `list`.\n *\n * assert.oneOf(1, [ 2, 1 ], 'Not found in list');\n *\n * @name oneOf\n * @param {*} inList\n * @param {Array<*>} list\n * @param {String} message\n * @namespace Assert\n * @api public\n */\n\n assert.oneOf = function (inList, list, msg) {\n new Assertion(inList, msg).to.be.oneOf(list);\n }\n\n /**\n * ### .changes(function, object, property)\n *\n * Asserts that a function changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 22 };\n * assert.changes(fn, obj, 'val');\n *\n * @name changes\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.changes = function (fn, obj, prop) {\n new Assertion(fn).to.change(obj, prop);\n }\n\n /**\n * ### .doesNotChange(function, object, property)\n *\n * Asserts that a function does not changes the value of a property\n *\n * var obj = { val: 10 };\n * var fn = function() { console.log('foo'); };\n * assert.doesNotChange(fn, obj, 'val');\n *\n * @name doesNotChange\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotChange = function (fn, obj, prop) {\n new Assertion(fn).to.not.change(obj, prop);\n }\n\n /**\n * ### .increases(function, object, property)\n *\n * Asserts that a function increases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 13 };\n * assert.increases(fn, obj, 'val');\n *\n * @name increases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.increases = function (fn, obj, prop) {\n new Assertion(fn).to.increase(obj, prop);\n }\n\n /**\n * ### .doesNotIncrease(function, object, property)\n *\n * Asserts that a function does not increase object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 8 };\n * assert.doesNotIncrease(fn, obj, 'val');\n *\n * @name doesNotIncrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotIncrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.increase(obj, prop);\n }\n\n /**\n * ### .decreases(function, object, property)\n *\n * Asserts that a function decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 5 };\n * assert.decreases(fn, obj, 'val');\n *\n * @name decreases\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.decreases = function (fn, obj, prop) {\n new Assertion(fn).to.decrease(obj, prop);\n }\n\n /**\n * ### .doesNotDecrease(function, object, property)\n *\n * Asserts that a function does not decreases an object property\n *\n * var obj = { val: 10 };\n * var fn = function() { obj.val = 15 };\n * assert.doesNotDecrease(fn, obj, 'val');\n *\n * @name doesNotDecrease\n * @param {Function} modifier function\n * @param {Object} object\n * @param {String} property name\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.doesNotDecrease = function (fn, obj, prop) {\n new Assertion(fn).to.not.decrease(obj, prop);\n }\n\n /*!\n * ### .ifError(object)\n *\n * Asserts if value is not a false value, and throws if it is a true value.\n * This is added to allow for chai to be a drop-in replacement for Node's\n * assert class.\n *\n * var err = new Error('I am a custom error');\n * assert.ifError(err); // Rethrows err!\n *\n * @name ifError\n * @param {Object} object\n * @namespace Assert\n * @api public\n */\n\n assert.ifError = function (val) {\n if (val) {\n throw(val);\n }\n };\n\n /**\n * ### .isExtensible(object)\n *\n * Asserts that `object` is extensible (can have new properties added to it).\n *\n * assert.isExtensible({});\n *\n * @name isExtensible\n * @alias extensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.be.extensible;\n };\n\n /**\n * ### .isNotExtensible(object)\n *\n * Asserts that `object` is _not_ extensible.\n *\n * var nonExtensibleObject = Object.preventExtensions({});\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.freese({});\n *\n * assert.isNotExtensible(nonExtensibleObject);\n * assert.isNotExtensible(sealedObject);\n * assert.isNotExtensible(frozenObject);\n *\n * @name isNotExtensible\n * @alias notExtensible\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotExtensible = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.extensible;\n };\n\n /**\n * ### .isSealed(object)\n *\n * Asserts that `object` is sealed (cannot have new properties added to it\n * and its existing properties cannot be removed).\n *\n * var sealedObject = Object.seal({});\n * var frozenObject = Object.seal({});\n *\n * assert.isSealed(sealedObject);\n * assert.isSealed(frozenObject);\n *\n * @name isSealed\n * @alias sealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isSealed = function (obj, msg) {\n new Assertion(obj, msg).to.be.sealed;\n };\n\n /**\n * ### .isNotSealed(object)\n *\n * Asserts that `object` is _not_ sealed.\n *\n * assert.isNotSealed({});\n *\n * @name isNotSealed\n * @alias notSealed\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotSealed = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.sealed;\n };\n\n /**\n * ### .isFrozen(object)\n *\n * Asserts that `object` is frozen (cannot have new properties added to it\n * and its existing properties cannot be modified).\n *\n * var frozenObject = Object.freeze({});\n * assert.frozen(frozenObject);\n *\n * @name isFrozen\n * @alias frozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.be.frozen;\n };\n\n /**\n * ### .isNotFrozen(object)\n *\n * Asserts that `object` is _not_ frozen.\n *\n * assert.isNotFrozen({});\n *\n * @name isNotFrozen\n * @alias notFrozen\n * @param {Object} object\n * @param {String} message _optional_\n * @namespace Assert\n * @api public\n */\n\n assert.isNotFrozen = function (obj, msg) {\n new Assertion(obj, msg).to.not.be.frozen;\n };\n\n /*!\n * Aliases.\n */\n\n (function alias(name, as){\n assert[as] = assert[name];\n return alias;\n })\n ('isOk', 'ok')\n ('isNotOk', 'notOk')\n ('throws', 'throw')\n ('throws', 'Throw')\n ('isExtensible', 'extensible')\n ('isNotExtensible', 'notExtensible')\n ('isSealed', 'sealed')\n ('isNotSealed', 'notSealed')\n ('isFrozen', 'frozen')\n ('isNotFrozen', 'notFrozen');\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n chai.expect = function (val, message) {\n return new chai.Assertion(val, message);\n };\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Expect\n * @api public\n */\n\n chai.expect.fail = function (actual, expected, message, operator) {\n message = message || 'expect.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, chai.expect.fail);\n };\n};\n","/*!\n * chai\n * Copyright(c) 2011-2014 Jake Luer \n * MIT Licensed\n */\n\nmodule.exports = function (chai, util) {\n var Assertion = chai.Assertion;\n\n function loadShould () {\n // explicitly define this method as function as to have it's name to include as `ssfi`\n function shouldGetter() {\n if (this instanceof String || this instanceof Number || this instanceof Boolean ) {\n return new Assertion(this.valueOf(), null, shouldGetter);\n }\n return new Assertion(this, null, shouldGetter);\n }\n function shouldSetter(value) {\n // See https://github.com/chaijs/chai/issues/86: this makes\n // `whatever.should = someValue` actually set `someValue`, which is\n // especially useful for `global.should = require('chai').should()`.\n //\n // Note that we have to use [[DefineProperty]] instead of [[Put]]\n // since otherwise we would trigger this very setter!\n Object.defineProperty(this, 'should', {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n }\n // modify Object.prototype to have `should`\n Object.defineProperty(Object.prototype, 'should', {\n set: shouldSetter\n , get: shouldGetter\n , configurable: true\n });\n\n var should = {};\n\n /**\n * ### .fail(actual, expected, [message], [operator])\n *\n * Throw a failure.\n *\n * @name fail\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @param {String} operator\n * @namespace Should\n * @api public\n */\n\n should.fail = function (actual, expected, message, operator) {\n message = message || 'should.fail()';\n throw new chai.AssertionError(message, {\n actual: actual\n , expected: expected\n , operator: operator\n }, should.fail);\n };\n\n /**\n * ### .equal(actual, expected, [message])\n *\n * Asserts non-strict equality (`==`) of `actual` and `expected`.\n *\n * should.equal(3, '3', '== coerces values to strings');\n *\n * @name equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/string/regexp], [string/regexp], [message])\n *\n * Asserts that `function` will throw an error that is an instance of\n * `constructor`, or alternately that it will throw an error with message\n * matching `regexp`.\n *\n * should.throw(fn, 'function throws a reference error');\n * should.throw(fn, /function throws a reference error/);\n * should.throw(fn, ReferenceError);\n * should.throw(fn, ReferenceError, 'function throws a reference error');\n * should.throw(fn, ReferenceError, /function throws a reference error/);\n *\n * @name throw\n * @alias Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.Throw(errt, errs);\n };\n\n /**\n * ### .exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var foo = 'hi';\n *\n * should.exist(foo, 'foo exists');\n *\n * @name exist\n * @namespace Should\n * @api public\n */\n\n should.exist = function (val, msg) {\n new Assertion(val, msg).to.exist;\n }\n\n // negation\n should.not = {}\n\n /**\n * ### .not.equal(actual, expected, [message])\n *\n * Asserts non-strict inequality (`!=`) of `actual` and `expected`.\n *\n * should.not.equal(3, 4, 'these numbers are not equal');\n *\n * @name not.equal\n * @param {Mixed} actual\n * @param {Mixed} expected\n * @param {String} message\n * @namespace Should\n * @api public\n */\n\n should.not.equal = function (val1, val2, msg) {\n new Assertion(val1, msg).to.not.equal(val2);\n };\n\n /**\n * ### .throw(function, [constructor/regexp], [message])\n *\n * Asserts that `function` will _not_ throw an error that is an instance of\n * `constructor`, or alternately that it will not throw an error with message\n * matching `regexp`.\n *\n * should.not.throw(fn, Error, 'function does not throw');\n *\n * @name not.throw\n * @alias not.Throw\n * @param {Function} function\n * @param {ErrorConstructor} constructor\n * @param {RegExp} regexp\n * @param {String} message\n * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types\n * @namespace Should\n * @api public\n */\n\n should.not.Throw = function (fn, errt, errs, msg) {\n new Assertion(fn, msg).to.not.Throw(errt, errs);\n };\n\n /**\n * ### .not.exist\n *\n * Asserts that the target is neither `null` nor `undefined`.\n *\n * var bar = null;\n *\n * should.not.exist(bar, 'bar does not exist');\n *\n * @name not.exist\n * @namespace Should\n * @api public\n */\n\n should.not.exist = function (val, msg) {\n new Assertion(val, msg).to.not.exist;\n }\n\n should['throw'] = should['Throw'];\n should.not['throw'] = should.not['Throw'];\n\n return should;\n };\n\n chai.should = loadShould;\n chai.Should = loadShould;\n};\n","/*!\n * Chai - addChainingMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar transferFlags = require('./transferFlags');\nvar flag = require('./flag');\nvar config = require('../config');\n\n/*!\n * Module variables\n */\n\n// Check whether `__proto__` is supported\nvar hasProtoSupport = '__proto__' in Object;\n\n// Without `__proto__` support, this module will need to add properties to a function.\n// However, some Function.prototype methods cannot be overwritten,\n// and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).\nvar excludeNames = /^(?:length|name|arguments|caller)$/;\n\n// Cache `Function` properties\nvar call = Function.prototype.call,\n apply = Function.prototype.apply;\n\n/**\n * ### addChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Adds a method to an object, such that the method can also be chained.\n *\n * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);\n *\n * The result can then be used as both a method assertion, executing both `method` and\n * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.\n *\n * expect(fooStr).to.be.foo('bar');\n * expect(fooStr).to.be.foo.equal('foo');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for `name`, when called\n * @param {Function} chainingBehavior function to be called every time the property is accessed\n * @namespace Utils\n * @name addChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n if (typeof chainingBehavior !== 'function') {\n chainingBehavior = function () { };\n }\n\n var chainableBehavior = {\n method: method\n , chainingBehavior: chainingBehavior\n };\n\n // save the methods so we can overwrite them later, if we need to.\n if (!ctx.__methods) {\n ctx.__methods = {};\n }\n ctx.__methods[name] = chainableBehavior;\n\n Object.defineProperty(ctx, name,\n { get: function () {\n chainableBehavior.chainingBehavior.call(this);\n\n var assert = function assert() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', assert);\n var result = chainableBehavior.method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n\n // Use `__proto__` if available\n if (hasProtoSupport) {\n // Inherit all properties from the object by replacing the `Function` prototype\n var prototype = assert.__proto__ = Object.create(this);\n // Restore the `call` and `apply` methods from `Function`\n prototype.call = call;\n prototype.apply = apply;\n }\n // Otherwise, redefine all properties (slow!)\n else {\n var asserterNames = Object.getOwnPropertyNames(ctx);\n asserterNames.forEach(function (asserterName) {\n if (!excludeNames.test(asserterName)) {\n var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);\n Object.defineProperty(assert, asserterName, pd);\n }\n });\n }\n\n transferFlags(this, assert);\n return assert;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - addMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\n\n/**\n * ### .addMethod (ctx, name, method)\n *\n * Adds a method to the prototype of an object.\n *\n * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.equal(str);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(fooStr).to.be.foo('bar');\n *\n * @param {Object} ctx object to which the method is added\n * @param {String} name of method to add\n * @param {Function} method function to be used for name\n * @namespace Utils\n * @name addMethod\n * @api public\n */\nvar flag = require('./flag');\n\nmodule.exports = function (ctx, name, method) {\n ctx[name] = function () {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', ctx[name]);\n var result = method.apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - addProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar config = require('../config');\nvar flag = require('./flag');\n\n/**\n * ### addProperty (ctx, name, getter)\n *\n * Adds a property to the prototype of an object.\n *\n * utils.addProperty(chai.Assertion.prototype, 'foo', function () {\n * var obj = utils.flag(this, 'object');\n * new chai.Assertion(obj).to.be.instanceof(Foo);\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.addProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.foo;\n *\n * @param {Object} ctx object to which the property is added\n * @param {String} name of property to add\n * @param {Function} getter function to be used for name\n * @namespace Utils\n * @name addProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n Object.defineProperty(ctx, name,\n { get: function addProperty() {\n var old_ssfi = flag(this, 'ssfi');\n if (old_ssfi && config.includeStack === false)\n flag(this, 'ssfi', addProperty);\n\n var result = getter.call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - expectTypes utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### expectTypes(obj, types)\n *\n * Ensures that the object being tested against is of a valid type.\n *\n * utils.expectTypes(this, ['array', 'object', 'string']);\n *\n * @param {Mixed} obj constructed Assertion\n * @param {Array} type A list of allowed types for this assertion\n * @namespace Utils\n * @name expectTypes\n * @api public\n */\n\nvar AssertionError = require('assertion-error');\nvar flag = require('./flag');\nvar type = require('type-detect');\n\nmodule.exports = function (obj, types) {\n var obj = flag(obj, 'object');\n types = types.map(function (t) { return t.toLowerCase(); });\n types.sort();\n\n // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum'\n var str = types.map(function (t, index) {\n var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a';\n var or = types.length > 1 && index === types.length - 1 ? 'or ' : '';\n return or + art + ' ' + t;\n }).join(', ');\n\n if (!types.some(function (expected) { return type(obj) === expected; })) {\n throw new AssertionError(\n 'object tested must be ' + str + ', but ' + type(obj) + ' given'\n );\n }\n};\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### flag(object, key, [value])\n *\n * Get or set a flag value on an object. If a\n * value is provided it will be set, else it will\n * return the currently set value or `undefined` if\n * the value is not set.\n *\n * utils.flag(this, 'foo', 'bar'); // setter\n * utils.flag(this, 'foo'); // getter, returns `bar`\n *\n * @param {Object} object constructed Assertion\n * @param {String} key\n * @param {Mixed} value (optional)\n * @namespace Utils\n * @name flag\n * @api private\n */\n\nmodule.exports = function (obj, key, value) {\n var flags = obj.__flags || (obj.__flags = Object.create(null));\n if (arguments.length === 3) {\n flags[key] = value;\n } else {\n return flags[key];\n }\n};\n","/*!\n * Chai - getActual utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getActual(object, [actual])\n *\n * Returns the `actual` value for an Assertion\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getActual\n */\n\nmodule.exports = function (obj, args) {\n return args.length > 4 ? args[4] : obj._obj;\n};\n","/*!\n * Chai - getEnumerableProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getEnumerableProperties(object)\n *\n * This allows the retrieval of enumerable property names of an object,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getEnumerableProperties\n * @api public\n */\n\nmodule.exports = function getEnumerableProperties(object) {\n var result = [];\n for (var name in object) {\n result.push(name);\n }\n return result;\n};\n","/*!\n * Chai - message composition utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag')\n , getActual = require('./getActual')\n , inspect = require('./inspect')\n , objDisplay = require('./objDisplay');\n\n/**\n * ### .getMessage(object, message, negateMessage)\n *\n * Construct the error message based on flags\n * and template tags. Template tags will return\n * a stringified inspection of the object referenced.\n *\n * Message template tags:\n * - `#{this}` current asserted object\n * - `#{act}` actual value\n * - `#{exp}` expected value\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name getMessage\n * @api public\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , val = flag(obj, 'object')\n , expected = args[3]\n , actual = getActual(obj, args)\n , msg = negate ? args[2] : args[1]\n , flagMsg = flag(obj, 'message');\n\n if(typeof msg === \"function\") msg = msg();\n msg = msg || '';\n msg = msg\n .replace(/#\\{this\\}/g, function () { return objDisplay(val); })\n .replace(/#\\{act\\}/g, function () { return objDisplay(actual); })\n .replace(/#\\{exp\\}/g, function () { return objDisplay(expected); });\n\n return flagMsg ? flagMsg + ': ' + msg : msg;\n};\n","/*!\n * Chai - getName utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * # getName(func)\n *\n * Gets the name of a function, in a cross-browser way.\n *\n * @param {Function} a function (usually a constructor)\n * @namespace Utils\n * @name getName\n */\n\nmodule.exports = function (func) {\n if (func.name) return func.name;\n\n var match = /^\\s?function ([^(]*)\\(/.exec(func);\n return match && match[1] ? match[1] : \"\";\n};\n","/*!\n * Chai - getPathInfo utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar hasProperty = require('./hasProperty');\n\n/**\n * ### .getPathInfo(path, object)\n *\n * This allows the retrieval of property info in an\n * object given a string path.\n *\n * The path info consists of an object with the\n * following properties:\n *\n * * parent - The parent object of the property referenced by `path`\n * * name - The name of the final property, a number if it was an array indexer\n * * value - The value of the property, if it exists, otherwise `undefined`\n * * exists - Whether the property exists or not\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} info\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nmodule.exports = function getPathInfo(path, obj) {\n var parsed = parsePath(path),\n last = parsed[parsed.length - 1];\n\n var info = {\n parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) : obj,\n name: last.p || last.i,\n value: _getPathValue(parsed, obj)\n };\n info.exists = hasProperty(info.name, info.parent);\n\n return info;\n};\n\n\n/*!\n * ## parsePath(path)\n *\n * Helper function used to parse string object\n * paths. Use in conjunction with `_getPathValue`.\n *\n * var parsed = parsePath('myobject.property.subprop');\n *\n * ### Paths:\n *\n * * Can be as near infinitely deep and nested\n * * Arrays are also valid using the formal `myobject.document[3].property`.\n * * Literal dots and brackets (not delimiter) must be backslash-escaped.\n *\n * @param {String} path\n * @returns {Object} parsed\n * @api private\n */\n\nfunction parsePath (path) {\n var str = path.replace(/([^\\\\])\\[/g, '$1.[')\n , parts = str.match(/(\\\\\\.|[^.]+?)+/g);\n return parts.map(function (value) {\n var re = /^\\[(\\d+)\\]$/\n , mArr = re.exec(value);\n if (mArr) return { i: parseFloat(mArr[1]) };\n else return { p: value.replace(/\\\\([.\\[\\]])/g, '$1') };\n });\n}\n\n\n/*!\n * ## _getPathValue(parsed, obj)\n *\n * Helper companion function for `.parsePath` that returns\n * the value located at the parsed address.\n *\n * var value = getPathValue(parsed, obj);\n *\n * @param {Object} parsed definition from `parsePath`.\n * @param {Object} object to search against\n * @param {Number} object to search against\n * @returns {Object|Undefined} value\n * @api private\n */\n\nfunction _getPathValue (parsed, obj, index) {\n var tmp = obj\n , res;\n\n index = (index === undefined ? parsed.length : index);\n\n for (var i = 0, l = index; i < l; i++) {\n var part = parsed[i];\n if (tmp) {\n if ('undefined' !== typeof part.p)\n tmp = tmp[part.p];\n else if ('undefined' !== typeof part.i)\n tmp = tmp[part.i];\n if (i == (l - 1)) res = tmp;\n } else {\n res = undefined;\n }\n }\n return res;\n}\n","/*!\n * Chai - getPathValue utility\n * Copyright(c) 2012-2014 Jake Luer \n * @see https://github.com/logicalparadox/filtr\n * MIT Licensed\n */\n\nvar getPathInfo = require('./getPathInfo');\n\n/**\n * ### .getPathValue(path, object)\n *\n * This allows the retrieval of values in an\n * object given a string path.\n *\n * var obj = {\n * prop1: {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n * , prop2: {\n * arr: [ { nested: 'Universe' } ]\n * , str: 'Hello again!'\n * }\n * }\n *\n * The following would be the results.\n *\n * getPathValue('prop1.str', obj); // Hello\n * getPathValue('prop1.att[2]', obj); // b\n * getPathValue('prop2.arr[0].nested', obj); // Universe\n *\n * @param {String} path\n * @param {Object} object\n * @returns {Object} value or `undefined`\n * @namespace Utils\n * @name getPathValue\n * @api public\n */\nmodule.exports = function(path, obj) {\n var info = getPathInfo(path, obj);\n return info.value;\n};\n","/*!\n * Chai - getProperties utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### .getProperties(object)\n *\n * This allows the retrieval of property names of an object, enumerable or not,\n * inherited or not.\n *\n * @param {Object} object\n * @returns {Array}\n * @namespace Utils\n * @name getProperties\n * @api public\n */\n\nmodule.exports = function getProperties(object) {\n var result = Object.getOwnPropertyNames(object);\n\n function addProperty(property) {\n if (result.indexOf(property) === -1) {\n result.push(property);\n }\n }\n\n var proto = Object.getPrototypeOf(object);\n while (proto !== null) {\n Object.getOwnPropertyNames(proto).forEach(addProperty);\n proto = Object.getPrototypeOf(proto);\n }\n\n return result;\n};\n","/*!\n * Chai - hasProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\nvar type = require('type-detect');\n\n/**\n * ### .hasProperty(object, name)\n *\n * This allows checking whether an object has\n * named property or numeric array index.\n *\n * Basically does the same thing as the `in`\n * operator but works properly with natives\n * and null/undefined values.\n *\n * var obj = {\n * arr: ['a', 'b', 'c']\n * , str: 'Hello'\n * }\n *\n * The following would be the results.\n *\n * hasProperty('str', obj); // true\n * hasProperty('constructor', obj); // true\n * hasProperty('bar', obj); // false\n *\n * hasProperty('length', obj.str); // true\n * hasProperty(1, obj.str); // true\n * hasProperty(5, obj.str); // false\n *\n * hasProperty('length', obj.arr); // true\n * hasProperty(2, obj.arr); // true\n * hasProperty(3, obj.arr); // false\n *\n * @param {Objuect} object\n * @param {String|Number} name\n * @returns {Boolean} whether it exists\n * @namespace Utils\n * @name getPathInfo\n * @api public\n */\n\nvar literals = {\n 'number': Number\n , 'string': String\n};\n\nmodule.exports = function hasProperty(name, obj) {\n var ot = type(obj);\n\n // Bad Object, obviously no props at all\n if(ot === 'null' || ot === 'undefined')\n return false;\n\n // The `in` operator does not work with certain literals\n // box these before the check\n if(literals[ot] && typeof obj !== 'object')\n obj = new literals[ot](obj);\n\n return name in obj;\n};\n","/*!\n * chai\n * Copyright(c) 2011 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Main exports\n */\n\nvar exports = module.exports = {};\n\n/*!\n * test utility\n */\n\nexports.test = require('./test');\n\n/*!\n * type utility\n */\n\nexports.type = require('type-detect');\n\n/*!\n * expectTypes utility\n */\nexports.expectTypes = require('./expectTypes');\n\n/*!\n * message utility\n */\n\nexports.getMessage = require('./getMessage');\n\n/*!\n * actual utility\n */\n\nexports.getActual = require('./getActual');\n\n/*!\n * Inspect util\n */\n\nexports.inspect = require('./inspect');\n\n/*!\n * Object Display util\n */\n\nexports.objDisplay = require('./objDisplay');\n\n/*!\n * Flag utility\n */\n\nexports.flag = require('./flag');\n\n/*!\n * Flag transferring utility\n */\n\nexports.transferFlags = require('./transferFlags');\n\n/*!\n * Deep equal utility\n */\n\nexports.eql = require('deep-eql');\n\n/*!\n * Deep path value\n */\n\nexports.getPathValue = require('./getPathValue');\n\n/*!\n * Deep path info\n */\n\nexports.getPathInfo = require('./getPathInfo');\n\n/*!\n * Check if a property exists\n */\n\nexports.hasProperty = require('./hasProperty');\n\n/*!\n * Function name\n */\n\nexports.getName = require('./getName');\n\n/*!\n * add Property\n */\n\nexports.addProperty = require('./addProperty');\n\n/*!\n * add Method\n */\n\nexports.addMethod = require('./addMethod');\n\n/*!\n * overwrite Property\n */\n\nexports.overwriteProperty = require('./overwriteProperty');\n\n/*!\n * overwrite Method\n */\n\nexports.overwriteMethod = require('./overwriteMethod');\n\n/*!\n * Add a chainable method\n */\n\nexports.addChainableMethod = require('./addChainableMethod');\n\n/*!\n * Overwrite chainable method\n */\n\nexports.overwriteChainableMethod = require('./overwriteChainableMethod');\n","// This is (almost) directly from Node.js utils\n// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js\n\nvar getName = require('./getName');\nvar getProperties = require('./getProperties');\nvar getEnumerableProperties = require('./getEnumerableProperties');\n\nmodule.exports = inspect;\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Boolean} showHidden Flag that shows hidden (not enumerable)\n * properties of objects.\n * @param {Number} depth Depth in which to descend in object. Default is 2.\n * @param {Boolean} colors Flag to turn on ANSI escape codes to color the\n * output. Default is false (no coloring).\n * @namespace Utils\n * @name inspect\n */\nfunction inspect(obj, showHidden, depth, colors) {\n var ctx = {\n showHidden: showHidden,\n seen: [],\n stylize: function (str) { return str; }\n };\n return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));\n}\n\n// Returns true if object is a DOM element.\nvar isDOMElement = function (object) {\n if (typeof HTMLElement === 'object') {\n return object instanceof HTMLElement;\n } else {\n return object &&\n typeof object === 'object' &&\n object.nodeType === 1 &&\n typeof object.nodeName === 'string';\n }\n};\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (value && typeof value.inspect === 'function' &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes);\n if (typeof ret !== 'string') {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // If this is a DOM element, try to get the outer HTML.\n if (isDOMElement(value)) {\n if ('outerHTML' in value) {\n return value.outerHTML;\n // This value does not have an outerHTML attribute,\n // it could still be an XML element\n } else {\n // Attempt to serialize it\n try {\n if (document.xmlVersion) {\n var xmlSerializer = new XMLSerializer();\n return xmlSerializer.serializeToString(value);\n } else {\n // Firefox 11- do not support outerHTML\n // It does, however, support innerHTML\n // Use the following to render the element\n var ns = \"http://www.w3.org/1999/xhtml\";\n var container = document.createElementNS(ns, '_');\n\n container.appendChild(value.cloneNode(false));\n html = container.innerHTML\n .replace('><', '>' + value.innerHTML + '<');\n container.innerHTML = '';\n return html;\n }\n } catch (err) {\n // This could be a non-native DOM implementation,\n // continue with the normal flow:\n // printing the element as if it is an object.\n }\n }\n }\n\n // Look up the keys of the object.\n var visibleKeys = getEnumerableProperties(value);\n var keys = ctx.showHidden ? getProperties(value) : visibleKeys;\n\n // Some type of object without properties can be shortcutted.\n // In IE, errors have a single `stack` property, or if they are vanilla `Error`,\n // a `stack` plus `description` property; ignore those for consistency.\n if (keys.length === 0 || (isError(value) && (\n (keys.length === 1 && keys[0] === 'stack') ||\n (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')\n ))) {\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n return ctx.stylize('[Function' + nameSuffix + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (typeof value === 'function') {\n var name = getName(value);\n var nameSuffix = name ? ': ' + name : '';\n base = ' [Function' + nameSuffix + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n return formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n switch (typeof value) {\n case 'undefined':\n return ctx.stylize('undefined', 'undefined');\n\n case 'string':\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n\n case 'number':\n if (value === 0 && (1/value) === -Infinity) {\n return ctx.stylize('-0', 'number');\n }\n return ctx.stylize('' + value, 'number');\n\n case 'boolean':\n return ctx.stylize('' + value, 'boolean');\n }\n // For some reason typeof null is \"object\", so special case here.\n if (value === null) {\n return ctx.stylize('null', 'null');\n }\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (Object.prototype.hasOwnProperty.call(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str;\n if (value.__lookupGetter__) {\n if (value.__lookupGetter__(key)) {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (value.__lookupSetter__(key)) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n }\n if (visibleKeys.indexOf(key) < 0) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(value[key]) < 0) {\n if (recurseTimes === null) {\n str = formatValue(ctx, value[key], null);\n } else {\n str = formatValue(ctx, value[key], recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (typeof name === 'undefined') {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\nfunction isArray(ar) {\n return Array.isArray(ar) ||\n (typeof ar === 'object' && objectToString(ar) === '[object Array]');\n}\n\nfunction isRegExp(re) {\n return typeof re === 'object' && objectToString(re) === '[object RegExp]';\n}\n\nfunction isDate(d) {\n return typeof d === 'object' && objectToString(d) === '[object Date]';\n}\n\nfunction isError(e) {\n return typeof e === 'object' && objectToString(e) === '[object Error]';\n}\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n","/*!\n * Chai - flag utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar inspect = require('./inspect');\nvar config = require('../config');\n\n/**\n * ### .objDisplay (object)\n *\n * Determines if an object or an array matches\n * criteria to be inspected in-line for error\n * messages or should be truncated.\n *\n * @param {Mixed} javascript object to inspect\n * @name objDisplay\n * @namespace Utils\n * @api public\n */\n\nmodule.exports = function (obj) {\n var str = inspect(obj)\n , type = Object.prototype.toString.call(obj);\n\n if (config.truncateThreshold && str.length >= config.truncateThreshold) {\n if (type === '[object Function]') {\n return !obj.name || obj.name === ''\n ? '[Function]'\n : '[Function: ' + obj.name + ']';\n } else if (type === '[object Array]') {\n return '[ Array(' + obj.length + ') ]';\n } else if (type === '[object Object]') {\n var keys = Object.keys(obj)\n , kstr = keys.length > 2\n ? keys.splice(0, 2).join(', ') + ', ...'\n : keys.join(', ');\n return '{ Object (' + kstr + ') }';\n } else {\n return str;\n }\n } else {\n return str;\n }\n};\n","/*!\n * Chai - overwriteChainableMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteChainableMethod (ctx, name, method, chainingBehavior)\n *\n * Overwites an already existing chainable method\n * and provides access to the previous function or\n * property. Must return functions to be used for\n * name.\n *\n * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',\n * function (_super) {\n * }\n * , function (_super) {\n * }\n * );\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteChainableMethod('foo', fn, fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.have.length(3);\n * expect(myFoo).to.have.length.above(3);\n *\n * @param {Object} ctx object whose method / property is to be overwritten\n * @param {String} name of method / property to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @param {Function} chainingBehavior function that returns a function to be used for property\n * @namespace Utils\n * @name overwriteChainableMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method, chainingBehavior) {\n var chainableBehavior = ctx.__methods[name];\n\n var _chainingBehavior = chainableBehavior.chainingBehavior;\n chainableBehavior.chainingBehavior = function () {\n var result = chainingBehavior(_chainingBehavior).call(this);\n return result === undefined ? this : result;\n };\n\n var _method = chainableBehavior.method;\n chainableBehavior.method = function () {\n var result = method(_method).apply(this, arguments);\n return result === undefined ? this : result;\n };\n};\n","/*!\n * Chai - overwriteMethod utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteMethod (ctx, name, fn)\n *\n * Overwites an already existing method and provides\n * access to previous function. Must return function\n * to be used for name.\n *\n * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {\n * return function (str) {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.value).to.equal(str);\n * } else {\n * _super.apply(this, arguments);\n * }\n * }\n * });\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteMethod('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.equal('bar');\n *\n * @param {Object} ctx object whose method is to be overwritten\n * @param {String} name of method to overwrite\n * @param {Function} method function that returns a function to be used for name\n * @namespace Utils\n * @name overwriteMethod\n * @api public\n */\n\nmodule.exports = function (ctx, name, method) {\n var _method = ctx[name]\n , _super = function () { return this; };\n\n if (_method && 'function' === typeof _method)\n _super = _method;\n\n ctx[name] = function () {\n var result = method(_super).apply(this, arguments);\n return result === undefined ? this : result;\n }\n};\n","/*!\n * Chai - overwriteProperty utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### overwriteProperty (ctx, name, fn)\n *\n * Overwites an already existing property getter and provides\n * access to previous value. Must return function to use as getter.\n *\n * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {\n * return function () {\n * var obj = utils.flag(this, 'object');\n * if (obj instanceof Foo) {\n * new chai.Assertion(obj.name).to.equal('bar');\n * } else {\n * _super.call(this);\n * }\n * }\n * });\n *\n *\n * Can also be accessed directly from `chai.Assertion`.\n *\n * chai.Assertion.overwriteProperty('foo', fn);\n *\n * Then can be used as any other assertion.\n *\n * expect(myFoo).to.be.ok;\n *\n * @param {Object} ctx object whose property is to be overwritten\n * @param {String} name of property to overwrite\n * @param {Function} getter function that returns a getter function to be used for name\n * @namespace Utils\n * @name overwriteProperty\n * @api public\n */\n\nmodule.exports = function (ctx, name, getter) {\n var _get = Object.getOwnPropertyDescriptor(ctx, name)\n , _super = function () {};\n\n if (_get && 'function' === typeof _get.get)\n _super = _get.get\n\n Object.defineProperty(ctx, name,\n { get: function () {\n var result = getter(_super).call(this);\n return result === undefined ? this : result;\n }\n , configurable: true\n });\n};\n","/*!\n * Chai - test utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependancies\n */\n\nvar flag = require('./flag');\n\n/**\n * # test(object, expression)\n *\n * Test and object for expression.\n *\n * @param {Object} object (constructed Assertion)\n * @param {Arguments} chai.Assertion.prototype.assert arguments\n * @namespace Utils\n * @name test\n */\n\nmodule.exports = function (obj, args) {\n var negate = flag(obj, 'negate')\n , expr = args[0];\n return negate ? !expr : expr;\n};\n","/*!\n * Chai - transferFlags utility\n * Copyright(c) 2012-2014 Jake Luer \n * MIT Licensed\n */\n\n/**\n * ### transferFlags(assertion, object, includeAll = true)\n *\n * Transfer all the flags for `assertion` to `object`. If\n * `includeAll` is set to `false`, then the base Chai\n * assertion flags (namely `object`, `ssfi`, and `message`)\n * will not be transferred.\n *\n *\n * var newAssertion = new Assertion();\n * utils.transferFlags(assertion, newAssertion);\n *\n * var anotherAsseriton = new Assertion(myObj);\n * utils.transferFlags(assertion, anotherAssertion, false);\n *\n * @param {Assertion} assertion the assertion to transfer the flags from\n * @param {Object} object the object to transfer the flags to; usually a new assertion\n * @param {Boolean} includeAll\n * @namespace Utils\n * @name transferFlags\n * @api private\n */\n\nmodule.exports = function (assertion, object, includeAll) {\n var flags = assertion.__flags || (assertion.__flags = Object.create(null));\n\n if (!object.__flags) {\n object.__flags = Object.create(null);\n }\n\n includeAll = arguments.length === 3 ? includeAll : true;\n\n for (var flag in flags) {\n if (includeAll ||\n (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {\n object.__flags[flag] = flags[flag];\n }\n }\n};\n","\"use strict\";\n\nfunction dedent(strings) {\n\n var raw = void 0;\n if (typeof strings === \"string\") {\n // dedent can be used as a plain function\n raw = [strings];\n } else {\n raw = strings.raw;\n }\n\n // first, perform interpolation\n var result = \"\";\n for (var i = 0; i < raw.length; i++) {\n result += raw[i].\n // join lines when there is a suppressed newline\n replace(/\\\\\\n[ \\t]*/g, \"\").\n\n // handle escaped backticks\n replace(/\\\\`/g, \"`\");\n\n if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) {\n result += arguments.length <= i + 1 ? undefined : arguments[i + 1];\n }\n }\n\n // now strip indentation\n var lines = result.split(\"\\n\");\n var mindent = null;\n lines.forEach(function (l) {\n var m = l.match(/^(\\s+)\\S+/);\n if (m) {\n var indent = m[1].length;\n if (!mindent) {\n // this is the first indented line\n mindent = indent;\n } else {\n mindent = Math.min(mindent, indent);\n }\n }\n });\n\n if (mindent !== null) {\n result = lines.map(function (l) {\n return l[0] === \" \" ? l.slice(mindent) : l;\n }).join(\"\\n\");\n }\n\n // dedent eats leading and trailing whitespace too\n result = result.trim();\n\n // handle escaped newlines at the end to ensure they don't get stripped too\n return result.replace(/\\\\n/g, \"\\n\");\n}\n\nif (typeof module !== \"undefined\") {\n module.exports = dedent;\n}\n","module.exports = require('./lib/eql');\n","/*!\n * deep-eql\n * Copyright(c) 2013 Jake Luer \n * MIT Licensed\n */\n\n/*!\n * Module dependencies\n */\n\nvar type = require('type-detect');\n\n/*!\n * Buffer.isBuffer browser shim\n */\n\nvar Buffer;\ntry { Buffer = require('buffer').Buffer; }\ncatch(ex) {\n Buffer = {};\n Buffer.isBuffer = function() { return false; }\n}\n\n/*!\n * Primary Export\n */\n\nmodule.exports = deepEqual;\n\n/**\n * Assert super-strict (egal) equality between\n * two objects of any type.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @param {Array} memoised (optional)\n * @return {Boolean} equal match\n */\n\nfunction deepEqual(a, b, m) {\n if (sameValue(a, b)) {\n return true;\n } else if ('date' === type(a)) {\n return dateEqual(a, b);\n } else if ('regexp' === type(a)) {\n return regexpEqual(a, b);\n } else if (Buffer.isBuffer(a)) {\n return bufferEqual(a, b);\n } else if ('arguments' === type(a)) {\n return argumentsEqual(a, b, m);\n } else if (!typeEqual(a, b)) {\n return false;\n } else if (('object' !== type(a) && 'object' !== type(b))\n && ('array' !== type(a) && 'array' !== type(b))) {\n return sameValue(a, b);\n } else {\n return objectEqual(a, b, m);\n }\n}\n\n/*!\n * Strict (egal) equality test. Ensures that NaN always\n * equals NaN and `-0` does not equal `+0`.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} equal match\n */\n\nfunction sameValue(a, b) {\n if (a === b) return a !== 0 || 1 / a === 1 / b;\n return a !== a && b !== b;\n}\n\n/*!\n * Compare the types of two given objects and\n * return if they are equal. Note that an Array\n * has a type of `array` (not `object`) and arguments\n * have a type of `arguments` (not `array`/`object`).\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction typeEqual(a, b) {\n return type(a) === type(b);\n}\n\n/*!\n * Compare two Date objects by asserting that\n * the time values are equal using `saveValue`.\n *\n * @param {Date} a\n * @param {Date} b\n * @return {Boolean} result\n */\n\nfunction dateEqual(a, b) {\n if ('date' !== type(b)) return false;\n return sameValue(a.getTime(), b.getTime());\n}\n\n/*!\n * Compare two regular expressions by converting them\n * to string and checking for `sameValue`.\n *\n * @param {RegExp} a\n * @param {RegExp} b\n * @return {Boolean} result\n */\n\nfunction regexpEqual(a, b) {\n if ('regexp' !== type(b)) return false;\n return sameValue(a.toString(), b.toString());\n}\n\n/*!\n * Assert deep equality of two `arguments` objects.\n * Unfortunately, these must be sliced to arrays\n * prior to test to ensure no bad behavior.\n *\n * @param {Arguments} a\n * @param {Arguments} b\n * @param {Array} memoize (optional)\n * @return {Boolean} result\n */\n\nfunction argumentsEqual(a, b, m) {\n if ('arguments' !== type(b)) return false;\n a = [].slice.call(a);\n b = [].slice.call(b);\n return deepEqual(a, b, m);\n}\n\n/*!\n * Get enumerable properties of a given object.\n *\n * @param {Object} a\n * @return {Array} property names\n */\n\nfunction enumerable(a) {\n var res = [];\n for (var key in a) res.push(key);\n return res;\n}\n\n/*!\n * Simple equality for flat iterable objects\n * such as Arrays or Node.js buffers.\n *\n * @param {Iterable} a\n * @param {Iterable} b\n * @return {Boolean} result\n */\n\nfunction iterableEqual(a, b) {\n if (a.length !== b.length) return false;\n\n var i = 0;\n var match = true;\n\n for (; i < a.length; i++) {\n if (a[i] !== b[i]) {\n match = false;\n break;\n }\n }\n\n return match;\n}\n\n/*!\n * Extension to `iterableEqual` specifically\n * for Node.js Buffers.\n *\n * @param {Buffer} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction bufferEqual(a, b) {\n if (!Buffer.isBuffer(b)) return false;\n return iterableEqual(a, b);\n}\n\n/*!\n * Block for `objectEqual` ensuring non-existing\n * values don't get in.\n *\n * @param {Mixed} object\n * @return {Boolean} result\n */\n\nfunction isValue(a) {\n return a !== null && a !== undefined;\n}\n\n/*!\n * Recursively check the equality of two objects.\n * Once basic sameness has been established it will\n * defer to `deepEqual` for each enumerable key\n * in the object.\n *\n * @param {Mixed} a\n * @param {Mixed} b\n * @return {Boolean} result\n */\n\nfunction objectEqual(a, b, m) {\n if (!isValue(a) || !isValue(b)) {\n return false;\n }\n\n if (a.prototype !== b.prototype) {\n return false;\n }\n\n var i;\n if (m) {\n for (i = 0; i < m.length; i++) {\n if ((m[i][0] === a && m[i][1] === b)\n || (m[i][0] === b && m[i][1] === a)) {\n return true;\n }\n }\n } else {\n m = [];\n }\n\n try {\n var ka = enumerable(a);\n var kb = enumerable(b);\n } catch (ex) {\n return false;\n }\n\n ka.sort();\n kb.sort();\n\n if (!iterableEqual(ka, kb)) {\n return false;\n }\n\n m.push([ a, b ]);\n\n var key;\n for (i = ka.length - 1; i >= 0; i--) {\n key = ka[i];\n if (!deepEqual(a[key], b[key], m)) {\n return false;\n }\n }\n\n return true;\n}\n","/*!\n localForage -- Offline Storage, Improved\n Version 1.5.0\n https://localforage.github.io/localForage\n (c) 2013-2017 Mozilla, Apache License 2.0\n*/\n(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"function\"&&define.amd){define([],f)}else{var g;if(typeof window!==\"undefined\"){g=window}else if(typeof global!==\"undefined\"){g=global}else if(typeof self!==\"undefined\"){g=self}else{g=this}g.localforage = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw (f.code=\"MODULE_NOT_FOUND\", f)}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o element; its readystatechange event will be fired asynchronously once it is inserted\n // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.\n var scriptEl = global.document.createElement('script');\n scriptEl.onreadystatechange = function () {\n nextTick();\n\n scriptEl.onreadystatechange = null;\n scriptEl.parentNode.removeChild(scriptEl);\n scriptEl = null;\n };\n global.document.documentElement.appendChild(scriptEl);\n };\n } else {\n scheduleDrain = function () {\n setTimeout(nextTick, 0);\n };\n }\n}\n\nvar draining;\nvar queue = [];\n//named nextTick for less confusing stack traces\nfunction nextTick() {\n draining = true;\n var i, oldQueue;\n var len = queue.length;\n while (len) {\n oldQueue = queue;\n queue = [];\n i = -1;\n while (++i < len) {\n oldQueue[i]();\n }\n len = queue.length;\n }\n draining = false;\n}\n\nmodule.exports = immediate;\nfunction immediate(task) {\n if (queue.push(task) === 1 && !draining) {\n scheduleDrain();\n }\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{}],2:[function(_dereq_,module,exports){\n'use strict';\nvar immediate = _dereq_(1);\n\n/* istanbul ignore next */\nfunction INTERNAL() {}\n\nvar handlers = {};\n\nvar REJECTED = ['REJECTED'];\nvar FULFILLED = ['FULFILLED'];\nvar PENDING = ['PENDING'];\n\nmodule.exports = exports = Promise;\n\nfunction Promise(resolver) {\n if (typeof resolver !== 'function') {\n throw new TypeError('resolver must be a function');\n }\n this.state = PENDING;\n this.queue = [];\n this.outcome = void 0;\n if (resolver !== INTERNAL) {\n safelyResolveThenable(this, resolver);\n }\n}\n\nPromise.prototype[\"catch\"] = function (onRejected) {\n return this.then(null, onRejected);\n};\nPromise.prototype.then = function (onFulfilled, onRejected) {\n if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||\n typeof onRejected !== 'function' && this.state === REJECTED) {\n return this;\n }\n var promise = new this.constructor(INTERNAL);\n if (this.state !== PENDING) {\n var resolver = this.state === FULFILLED ? onFulfilled : onRejected;\n unwrap(promise, resolver, this.outcome);\n } else {\n this.queue.push(new QueueItem(promise, onFulfilled, onRejected));\n }\n\n return promise;\n};\nfunction QueueItem(promise, onFulfilled, onRejected) {\n this.promise = promise;\n if (typeof onFulfilled === 'function') {\n this.onFulfilled = onFulfilled;\n this.callFulfilled = this.otherCallFulfilled;\n }\n if (typeof onRejected === 'function') {\n this.onRejected = onRejected;\n this.callRejected = this.otherCallRejected;\n }\n}\nQueueItem.prototype.callFulfilled = function (value) {\n handlers.resolve(this.promise, value);\n};\nQueueItem.prototype.otherCallFulfilled = function (value) {\n unwrap(this.promise, this.onFulfilled, value);\n};\nQueueItem.prototype.callRejected = function (value) {\n handlers.reject(this.promise, value);\n};\nQueueItem.prototype.otherCallRejected = function (value) {\n unwrap(this.promise, this.onRejected, value);\n};\n\nfunction unwrap(promise, func, value) {\n immediate(function () {\n var returnValue;\n try {\n returnValue = func(value);\n } catch (e) {\n return handlers.reject(promise, e);\n }\n if (returnValue === promise) {\n handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));\n } else {\n handlers.resolve(promise, returnValue);\n }\n });\n}\n\nhandlers.resolve = function (self, value) {\n var result = tryCatch(getThen, value);\n if (result.status === 'error') {\n return handlers.reject(self, result.value);\n }\n var thenable = result.value;\n\n if (thenable) {\n safelyResolveThenable(self, thenable);\n } else {\n self.state = FULFILLED;\n self.outcome = value;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callFulfilled(value);\n }\n }\n return self;\n};\nhandlers.reject = function (self, error) {\n self.state = REJECTED;\n self.outcome = error;\n var i = -1;\n var len = self.queue.length;\n while (++i < len) {\n self.queue[i].callRejected(error);\n }\n return self;\n};\n\nfunction getThen(obj) {\n // Make sure we only access the accessor once as required by the spec\n var then = obj && obj.then;\n if (obj && typeof obj === 'object' && typeof then === 'function') {\n return function appyThen() {\n then.apply(obj, arguments);\n };\n }\n}\n\nfunction safelyResolveThenable(self, thenable) {\n // Either fulfill, reject or reject with error\n var called = false;\n function onError(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.reject(self, value);\n }\n\n function onSuccess(value) {\n if (called) {\n return;\n }\n called = true;\n handlers.resolve(self, value);\n }\n\n function tryToUnwrap() {\n thenable(onSuccess, onError);\n }\n\n var result = tryCatch(tryToUnwrap);\n if (result.status === 'error') {\n onError(result.value);\n }\n}\n\nfunction tryCatch(func, value) {\n var out = {};\n try {\n out.value = func(value);\n out.status = 'success';\n } catch (e) {\n out.status = 'error';\n out.value = e;\n }\n return out;\n}\n\nexports.resolve = resolve;\nfunction resolve(value) {\n if (value instanceof this) {\n return value;\n }\n return handlers.resolve(new this(INTERNAL), value);\n}\n\nexports.reject = reject;\nfunction reject(reason) {\n var promise = new this(INTERNAL);\n return handlers.reject(promise, reason);\n}\n\nexports.all = all;\nfunction all(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var values = new Array(len);\n var resolved = 0;\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n allResolver(iterable[i], i);\n }\n return promise;\n function allResolver(value, i) {\n self.resolve(value).then(resolveFromAll, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n function resolveFromAll(outValue) {\n values[i] = outValue;\n if (++resolved === len && !called) {\n called = true;\n handlers.resolve(promise, values);\n }\n }\n }\n}\n\nexports.race = race;\nfunction race(iterable) {\n var self = this;\n if (Object.prototype.toString.call(iterable) !== '[object Array]') {\n return this.reject(new TypeError('must be an array'));\n }\n\n var len = iterable.length;\n var called = false;\n if (!len) {\n return this.resolve([]);\n }\n\n var i = -1;\n var promise = new this(INTERNAL);\n\n while (++i < len) {\n resolver(iterable[i]);\n }\n return promise;\n function resolver(value) {\n self.resolve(value).then(function (response) {\n if (!called) {\n called = true;\n handlers.resolve(promise, response);\n }\n }, function (error) {\n if (!called) {\n called = true;\n handlers.reject(promise, error);\n }\n });\n }\n}\n\n},{\"1\":1}],3:[function(_dereq_,module,exports){\n(function (global){\n'use strict';\nif (typeof global.Promise !== 'function') {\n global.Promise = _dereq_(2);\n}\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n},{\"2\":2}],4:[function(_dereq_,module,exports){\n'use strict';\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction getIDB() {\n /* global indexedDB,webkitIndexedDB,mozIndexedDB,OIndexedDB,msIndexedDB */\n try {\n if (typeof indexedDB !== 'undefined') {\n return indexedDB;\n }\n if (typeof webkitIndexedDB !== 'undefined') {\n return webkitIndexedDB;\n }\n if (typeof mozIndexedDB !== 'undefined') {\n return mozIndexedDB;\n }\n if (typeof OIndexedDB !== 'undefined') {\n return OIndexedDB;\n }\n if (typeof msIndexedDB !== 'undefined') {\n return msIndexedDB;\n }\n } catch (e) {}\n}\n\nvar idb = getIDB();\n\nfunction isIndexedDBValid() {\n try {\n // Initialize IndexedDB; fall back to vendor-prefixed versions\n // if needed.\n if (!idb) {\n return false;\n }\n // We mimic PouchDB here;\n //\n // We test for openDatabase because IE Mobile identifies itself\n // as Safari. Oh the lulz...\n var isSafari = typeof openDatabase !== 'undefined' && /(Safari|iPhone|iPad|iPod)/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) && !/BlackBerry/.test(navigator.platform);\n\n var hasFetch = typeof fetch === 'function' && fetch.toString().indexOf('[native code') !== -1;\n\n // Safari <10.1 does not meet our requirements for IDB support (#5572)\n // since Safari 10.1 shipped with fetch, we can use that to detect it\n return (!isSafari || hasFetch) && typeof indexedDB !== 'undefined' &&\n // some outdated implementations of IDB that appear on Samsung\n // and HTC Android devices <4.4 are missing IDBKeyRange\n typeof IDBKeyRange !== 'undefined';\n } catch (e) {\n return false;\n }\n}\n\nfunction isWebSQLValid() {\n return typeof openDatabase === 'function';\n}\n\nfunction isLocalStorageValid() {\n try {\n return typeof localStorage !== 'undefined' && 'setItem' in localStorage && localStorage.setItem;\n } catch (e) {\n return false;\n }\n}\n\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\n// Abstracts constructing a Blob object, so it also works in older\n// browsers that don't support the native Blob constructor. (i.e.\n// old QtWebKit versions, at least).\nfunction createBlob(parts, properties) {\n /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */\n parts = parts || [];\n properties = properties || {};\n try {\n return new Blob(parts, properties);\n } catch (e) {\n if (e.name !== 'TypeError') {\n throw e;\n }\n var Builder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : WebKitBlobBuilder;\n var builder = new Builder();\n for (var i = 0; i < parts.length; i += 1) {\n builder.append(parts[i]);\n }\n return builder.getBlob(properties.type);\n }\n}\n\n// This is CommonJS because lie is an external dependency, so Rollup\n// can just ignore it.\nif (typeof Promise === 'undefined') {\n // In the \"nopromises\" build this will just throw if you don't have\n // a global promise object, but it would throw anyway later.\n _dereq_(3);\n}\nvar Promise$1 = Promise;\n\nfunction executeCallback(promise, callback) {\n if (callback) {\n promise.then(function (result) {\n callback(null, result);\n }, function (error) {\n callback(error);\n });\n }\n}\n\nfunction executeTwoCallbacks(promise, callback, errorCallback) {\n if (typeof callback === 'function') {\n promise.then(callback);\n }\n\n if (typeof errorCallback === 'function') {\n promise[\"catch\"](errorCallback);\n }\n}\n\n// Some code originally from async_storage.js in\n// [Gaia](https://github.com/mozilla-b2g/gaia).\n\nvar DETECT_BLOB_SUPPORT_STORE = 'local-forage-detect-blob-support';\nvar supportsBlobs;\nvar dbContexts;\nvar toString = Object.prototype.toString;\n\n// Transform a binary string to an array buffer, because otherwise\n// weird stuff happens when you try to work with the binary string directly.\n// It is known.\n// From http://stackoverflow.com/questions/14967647/ (continues on next line)\n// encode-decode-image-with-base64-breaks-image (2013-04-21)\nfunction _binStringToArrayBuffer(bin) {\n var length = bin.length;\n var buf = new ArrayBuffer(length);\n var arr = new Uint8Array(buf);\n for (var i = 0; i < length; i++) {\n arr[i] = bin.charCodeAt(i);\n }\n return buf;\n}\n\n//\n// Blobs are not supported in all versions of IndexedDB, notably\n// Chrome <37 and Android <5. In those versions, storing a blob will throw.\n//\n// Various other blob bugs exist in Chrome v37-42 (inclusive).\n// Detecting them is expensive and confusing to users, and Chrome 37-42\n// is at very low usage worldwide, so we do a hacky userAgent check instead.\n//\n// content-type bug: https://code.google.com/p/chromium/issues/detail?id=408120\n// 404 bug: https://code.google.com/p/chromium/issues/detail?id=447916\n// FileReader bug: https://code.google.com/p/chromium/issues/detail?id=447836\n//\n// Code borrowed from PouchDB. See:\n// https://github.com/pouchdb/pouchdb/blob/master/packages/node_modules/pouchdb-adapter-idb/src/blobSupport.js\n//\nfunction _checkBlobSupportWithoutCaching(idb) {\n return new Promise$1(function (resolve) {\n var txn = idb.transaction(DETECT_BLOB_SUPPORT_STORE, 'readwrite');\n var blob = createBlob(['']);\n txn.objectStore(DETECT_BLOB_SUPPORT_STORE).put(blob, 'key');\n\n txn.onabort = function (e) {\n // If the transaction aborts now its due to not being able to\n // write to the database, likely due to the disk being full\n e.preventDefault();\n e.stopPropagation();\n resolve(false);\n };\n\n txn.oncomplete = function () {\n var matchedChrome = navigator.userAgent.match(/Chrome\\/(\\d+)/);\n var matchedEdge = navigator.userAgent.match(/Edge\\//);\n // MS Edge pretends to be Chrome 42:\n // https://msdn.microsoft.com/en-us/library/hh869301%28v=vs.85%29.aspx\n resolve(matchedEdge || !matchedChrome || parseInt(matchedChrome[1], 10) >= 43);\n };\n })[\"catch\"](function () {\n return false; // error, so assume unsupported\n });\n}\n\nfunction _checkBlobSupport(idb) {\n if (typeof supportsBlobs === 'boolean') {\n return Promise$1.resolve(supportsBlobs);\n }\n return _checkBlobSupportWithoutCaching(idb).then(function (value) {\n supportsBlobs = value;\n return supportsBlobs;\n });\n}\n\nfunction _deferReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Create a deferred object representing the current database operation.\n var deferredOperation = {};\n\n deferredOperation.promise = new Promise$1(function (resolve) {\n deferredOperation.resolve = resolve;\n });\n\n // Enqueue the deferred operation.\n dbContext.deferredOperations.push(deferredOperation);\n\n // Chain its promise to the database readiness.\n if (!dbContext.dbReady) {\n dbContext.dbReady = deferredOperation.promise;\n } else {\n dbContext.dbReady = dbContext.dbReady.then(function () {\n return deferredOperation.promise;\n });\n }\n}\n\nfunction _advanceReadiness(dbInfo) {\n var dbContext = dbContexts[dbInfo.name];\n\n // Dequeue a deferred operation.\n var deferredOperation = dbContext.deferredOperations.pop();\n\n // Resolve its promise (which is part of the database readiness\n // chain of promises).\n if (deferredOperation) {\n deferredOperation.resolve();\n }\n}\n\nfunction _getConnection(dbInfo, upgradeNeeded) {\n return new Promise$1(function (resolve, reject) {\n\n if (dbInfo.db) {\n if (upgradeNeeded) {\n _deferReadiness(dbInfo);\n dbInfo.db.close();\n } else {\n return resolve(dbInfo.db);\n }\n }\n\n var dbArgs = [dbInfo.name];\n\n if (upgradeNeeded) {\n dbArgs.push(dbInfo.version);\n }\n\n var openreq = idb.open.apply(idb, dbArgs);\n\n if (upgradeNeeded) {\n openreq.onupgradeneeded = function (e) {\n var db = openreq.result;\n try {\n db.createObjectStore(dbInfo.storeName);\n if (e.oldVersion <= 1) {\n // Added when support for blob shims was added\n db.createObjectStore(DETECT_BLOB_SUPPORT_STORE);\n }\n } catch (ex) {\n if (ex.name === 'ConstraintError') {\n console.warn('The database \"' + dbInfo.name + '\"' + ' has been upgraded from version ' + e.oldVersion + ' to version ' + e.newVersion + ', but the storage \"' + dbInfo.storeName + '\" already exists.');\n } else {\n throw ex;\n }\n }\n };\n }\n\n openreq.onerror = function (e) {\n e.preventDefault();\n reject(openreq.error);\n };\n\n openreq.onsuccess = function () {\n resolve(openreq.result);\n _advanceReadiness(dbInfo);\n };\n });\n}\n\nfunction _getOriginalConnection(dbInfo) {\n return _getConnection(dbInfo, false);\n}\n\nfunction _getUpgradedConnection(dbInfo) {\n return _getConnection(dbInfo, true);\n}\n\nfunction _isUpgradeNeeded(dbInfo, defaultVersion) {\n if (!dbInfo.db) {\n return true;\n }\n\n var isNewStore = !dbInfo.db.objectStoreNames.contains(dbInfo.storeName);\n var isDowngrade = dbInfo.version < dbInfo.db.version;\n var isUpgrade = dbInfo.version > dbInfo.db.version;\n\n if (isDowngrade) {\n // If the version is not the default one\n // then warn for impossible downgrade.\n if (dbInfo.version !== defaultVersion) {\n console.warn('The database \"' + dbInfo.name + '\"' + ' can\\'t be downgraded from version ' + dbInfo.db.version + ' to version ' + dbInfo.version + '.');\n }\n // Align the versions to prevent errors.\n dbInfo.version = dbInfo.db.version;\n }\n\n if (isUpgrade || isNewStore) {\n // If the store is new then increment the version (if needed).\n // This will trigger an \"upgradeneeded\" event which is required\n // for creating a store.\n if (isNewStore) {\n var incVersion = dbInfo.db.version + 1;\n if (incVersion > dbInfo.version) {\n dbInfo.version = incVersion;\n }\n }\n\n return true;\n }\n\n return false;\n}\n\n// encode a blob for indexeddb engines that don't support blobs\nfunction _encodeBlob(blob) {\n return new Promise$1(function (resolve, reject) {\n var reader = new FileReader();\n reader.onerror = reject;\n reader.onloadend = function (e) {\n var base64 = btoa(e.target.result || '');\n resolve({\n __local_forage_encoded_blob: true,\n data: base64,\n type: blob.type\n });\n };\n reader.readAsBinaryString(blob);\n });\n}\n\n// decode an encoded blob\nfunction _decodeBlob(encodedBlob) {\n var arrayBuff = _binStringToArrayBuffer(atob(encodedBlob.data));\n return createBlob([arrayBuff], { type: encodedBlob.type });\n}\n\n// is this one of our fancy encoded blobs?\nfunction _isEncodedBlob(value) {\n return value && value.__local_forage_encoded_blob;\n}\n\n// Specialize the default `ready()` function by making it dependent\n// on the current database operations. Thus, the driver will be actually\n// ready when it's been initialized (default) *and* there are no pending\n// operations on the database (initiated by some other instances).\nfunction _fullyReady(callback) {\n var self = this;\n\n var promise = self._initReady().then(function () {\n var dbContext = dbContexts[self._dbInfo.name];\n\n if (dbContext && dbContext.dbReady) {\n return dbContext.dbReady;\n }\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n}\n\n// Open the IndexedDB database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n // Initialize a singleton container for all running localForages.\n if (!dbContexts) {\n dbContexts = {};\n }\n\n // Get the current context of the database;\n var dbContext = dbContexts[dbInfo.name];\n\n // ...or create a new context.\n if (!dbContext) {\n dbContext = {\n // Running localForages sharing a database.\n forages: [],\n // Shared database.\n db: null,\n // Database readiness (promise).\n dbReady: null,\n // Deferred operations on the database.\n deferredOperations: []\n };\n // Register the new context in the global container.\n dbContexts[dbInfo.name] = dbContext;\n }\n\n // Register itself as a running localForage in the current context.\n dbContext.forages.push(self);\n\n // Replace the default `ready()` function with the specialized one.\n if (!self._initReady) {\n self._initReady = self.ready;\n self.ready = _fullyReady;\n }\n\n // Create an array of initialization states of the related localForages.\n var initPromises = [];\n\n function ignoreErrors() {\n // Don't handle errors here,\n // just makes sure related localForages aren't pending.\n return Promise$1.resolve();\n }\n\n for (var j = 0; j < dbContext.forages.length; j++) {\n var forage = dbContext.forages[j];\n if (forage !== self) {\n // Don't wait for itself...\n initPromises.push(forage._initReady()[\"catch\"](ignoreErrors));\n }\n }\n\n // Take a snapshot of the related localForages.\n var forages = dbContext.forages.slice(0);\n\n // Initialize the connection process only when\n // all the related localForages aren't pending.\n return Promise$1.all(initPromises).then(function () {\n dbInfo.db = dbContext.db;\n // Get the connection or open a new one without upgrade.\n return _getOriginalConnection(dbInfo);\n }).then(function (db) {\n dbInfo.db = db;\n if (_isUpgradeNeeded(dbInfo, self._defaultConfig.version)) {\n // Reopen the database for upgrading.\n return _getUpgradedConnection(dbInfo);\n }\n return db;\n }).then(function (db) {\n dbInfo.db = dbContext.db = db;\n self._dbInfo = dbInfo;\n // Share the final connection amongst related localForages.\n for (var k = 0; k < forages.length; k++) {\n var forage = forages[k];\n if (forage !== self) {\n // Self is already up-to-date.\n forage._dbInfo.db = dbInfo.db;\n forage._dbInfo.version = dbInfo.version;\n }\n }\n });\n}\n\nfunction getItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.get(key);\n\n req.onsuccess = function () {\n var value = req.result;\n if (value === undefined) {\n value = null;\n }\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n resolve(value);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items stored in database.\nfunction iterate(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var iterationNumber = 1;\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (cursor) {\n var value = cursor.value;\n if (_isEncodedBlob(value)) {\n value = _decodeBlob(value);\n }\n var result = iterator(value, cursor.key, iterationNumber++);\n\n if (result !== void 0) {\n resolve(result);\n } else {\n cursor[\"continue\"]();\n }\n } else {\n resolve();\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n\n return promise;\n}\n\nfunction setItem(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n var dbInfo;\n self.ready().then(function () {\n dbInfo = self._dbInfo;\n if (toString.call(value) === '[object Blob]') {\n return _checkBlobSupport(dbInfo.db).then(function (blobSupport) {\n if (blobSupport) {\n return value;\n }\n return _encodeBlob(value);\n });\n }\n return value;\n }).then(function (value) {\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.put(value, key);\n\n // The reason we don't _save_ null is because IE 10 does\n // not support saving the `null` type in IndexedDB. How\n // ironic, given the bug below!\n // See: https://github.com/mozilla/localForage/issues/161\n if (value === null) {\n value = undefined;\n }\n\n transaction.oncomplete = function () {\n // Cast to undefined so the value passed to\n // callback/promise is the same as what one would get out\n // of `getItem()` later. This leads to some weirdness\n // (setItem('foo', undefined) will return `null`), but\n // it's not my fault localStorage is our baseline and that\n // it's weird.\n if (value === undefined) {\n value = null;\n }\n\n resolve(value);\n };\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction removeItem(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n\n // We use a Grunt task to make this safe for IE and some\n // versions of Android (including those used by Cordova).\n // Normally IE won't like `.delete()` and will insist on\n // using `['delete']()`, but we have a build step that\n // fixes this for us now.\n var req = store[\"delete\"](key);\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onerror = function () {\n reject(req.error);\n };\n\n // The request will be also be aborted if we've exceeded our storage\n // space.\n transaction.onabort = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction clear(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var transaction = dbInfo.db.transaction(dbInfo.storeName, 'readwrite');\n var store = transaction.objectStore(dbInfo.storeName);\n var req = store.clear();\n\n transaction.oncomplete = function () {\n resolve();\n };\n\n transaction.onabort = transaction.onerror = function () {\n var err = req.error ? req.error : req.transaction.error;\n reject(err);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction length(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n var req = store.count();\n\n req.onsuccess = function () {\n resolve(req.result);\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction key(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n if (n < 0) {\n resolve(null);\n\n return;\n }\n\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var advanced = false;\n var req = store.openCursor();\n req.onsuccess = function () {\n var cursor = req.result;\n if (!cursor) {\n // this means there weren't enough keys\n resolve(null);\n\n return;\n }\n\n if (n === 0) {\n // We have the first key, return it if that's what they\n // wanted.\n resolve(cursor.key);\n } else {\n if (!advanced) {\n // Otherwise, ask the cursor to skip ahead n\n // records.\n advanced = true;\n cursor.advance(n);\n } else {\n // When we get here, we've got the nth key.\n resolve(cursor.key);\n }\n }\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var store = dbInfo.db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName);\n\n var req = store.openCursor();\n var keys = [];\n\n req.onsuccess = function () {\n var cursor = req.result;\n\n if (!cursor) {\n resolve(keys);\n return;\n }\n\n keys.push(cursor.key);\n cursor[\"continue\"]();\n };\n\n req.onerror = function () {\n reject(req.error);\n };\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar asyncStorage = {\n _driver: 'asyncStorage',\n _initStorage: _initStorage,\n iterate: iterate,\n getItem: getItem,\n setItem: setItem,\n removeItem: removeItem,\n clear: clear,\n length: length,\n key: key,\n keys: keys\n};\n\n// Sadly, the best way to save binary data in WebSQL/localStorage is serializing\n// it to Base64, so this is how we store it to prevent very strange errors with less\n// verbose ways of binary <-> string data storage.\nvar BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\nvar BLOB_TYPE_PREFIX = '~~local_forage_type~';\nvar BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;\n\nvar SERIALIZED_MARKER = '__lfsc__:';\nvar SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;\n\n// OMG the serializations!\nvar TYPE_ARRAYBUFFER = 'arbf';\nvar TYPE_BLOB = 'blob';\nvar TYPE_INT8ARRAY = 'si08';\nvar TYPE_UINT8ARRAY = 'ui08';\nvar TYPE_UINT8CLAMPEDARRAY = 'uic8';\nvar TYPE_INT16ARRAY = 'si16';\nvar TYPE_INT32ARRAY = 'si32';\nvar TYPE_UINT16ARRAY = 'ur16';\nvar TYPE_UINT32ARRAY = 'ui32';\nvar TYPE_FLOAT32ARRAY = 'fl32';\nvar TYPE_FLOAT64ARRAY = 'fl64';\nvar TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;\n\nvar toString$1 = Object.prototype.toString;\n\nfunction stringToBuffer(serializedString) {\n // Fill the string into a ArrayBuffer.\n var bufferLength = serializedString.length * 0.75;\n var len = serializedString.length;\n var i;\n var p = 0;\n var encoded1, encoded2, encoded3, encoded4;\n\n if (serializedString[serializedString.length - 1] === '=') {\n bufferLength--;\n if (serializedString[serializedString.length - 2] === '=') {\n bufferLength--;\n }\n }\n\n var buffer = new ArrayBuffer(bufferLength);\n var bytes = new Uint8Array(buffer);\n\n for (i = 0; i < len; i += 4) {\n encoded1 = BASE_CHARS.indexOf(serializedString[i]);\n encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);\n encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);\n encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);\n\n /*jslint bitwise: true */\n bytes[p++] = encoded1 << 2 | encoded2 >> 4;\n bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;\n bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;\n }\n return buffer;\n}\n\n// Converts a buffer to a string to store, serialized, in the backend\n// storage library.\nfunction bufferToString(buffer) {\n // base64-arraybuffer\n var bytes = new Uint8Array(buffer);\n var base64String = '';\n var i;\n\n for (i = 0; i < bytes.length; i += 3) {\n /*jslint bitwise: true */\n base64String += BASE_CHARS[bytes[i] >> 2];\n base64String += BASE_CHARS[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];\n base64String += BASE_CHARS[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];\n base64String += BASE_CHARS[bytes[i + 2] & 63];\n }\n\n if (bytes.length % 3 === 2) {\n base64String = base64String.substring(0, base64String.length - 1) + '=';\n } else if (bytes.length % 3 === 1) {\n base64String = base64String.substring(0, base64String.length - 2) + '==';\n }\n\n return base64String;\n}\n\n// Serialize a value, afterwards executing a callback (which usually\n// instructs the `setItem()` callback/promise to be executed). This is how\n// we store binary data with localStorage.\nfunction serialize(value, callback) {\n var valueType = '';\n if (value) {\n valueType = toString$1.call(value);\n }\n\n // Cannot use `value instanceof ArrayBuffer` or such here, as these\n // checks fail when running the tests using casper.js...\n //\n // TODO: See why those tests fail and use a better solution.\n if (value && (valueType === '[object ArrayBuffer]' || value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]')) {\n // Convert binary arrays to a string and prefix the string with\n // a special marker.\n var buffer;\n var marker = SERIALIZED_MARKER;\n\n if (value instanceof ArrayBuffer) {\n buffer = value;\n marker += TYPE_ARRAYBUFFER;\n } else {\n buffer = value.buffer;\n\n if (valueType === '[object Int8Array]') {\n marker += TYPE_INT8ARRAY;\n } else if (valueType === '[object Uint8Array]') {\n marker += TYPE_UINT8ARRAY;\n } else if (valueType === '[object Uint8ClampedArray]') {\n marker += TYPE_UINT8CLAMPEDARRAY;\n } else if (valueType === '[object Int16Array]') {\n marker += TYPE_INT16ARRAY;\n } else if (valueType === '[object Uint16Array]') {\n marker += TYPE_UINT16ARRAY;\n } else if (valueType === '[object Int32Array]') {\n marker += TYPE_INT32ARRAY;\n } else if (valueType === '[object Uint32Array]') {\n marker += TYPE_UINT32ARRAY;\n } else if (valueType === '[object Float32Array]') {\n marker += TYPE_FLOAT32ARRAY;\n } else if (valueType === '[object Float64Array]') {\n marker += TYPE_FLOAT64ARRAY;\n } else {\n callback(new Error('Failed to get type for BinaryArray'));\n }\n }\n\n callback(marker + bufferToString(buffer));\n } else if (valueType === '[object Blob]') {\n // Conver the blob to a binaryArray and then to a string.\n var fileReader = new FileReader();\n\n fileReader.onload = function () {\n // Backwards-compatible prefix for the blob type.\n var str = BLOB_TYPE_PREFIX + value.type + '~' + bufferToString(this.result);\n\n callback(SERIALIZED_MARKER + TYPE_BLOB + str);\n };\n\n fileReader.readAsArrayBuffer(value);\n } else {\n try {\n callback(JSON.stringify(value));\n } catch (e) {\n console.error(\"Couldn't convert value into a JSON string: \", value);\n\n callback(null, e);\n }\n }\n}\n\n// Deserialize data we've inserted into a value column/field. We place\n// special markers into our strings to mark them as encoded; this isn't\n// as nice as a meta field, but it's the only sane thing we can do whilst\n// keeping localStorage support intact.\n//\n// Oftentimes this will just deserialize JSON content, but if we have a\n// special marker (SERIALIZED_MARKER, defined above), we will extract\n// some kind of arraybuffer/binary data/typed array out of the string.\nfunction deserialize(value) {\n // If we haven't marked this string as being specially serialized (i.e.\n // something other than serialized JSON), we can just return it and be\n // done with it.\n if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {\n return JSON.parse(value);\n }\n\n // The following code deals with deserializing some kind of Blob or\n // TypedArray. First we separate out the type of data we're dealing\n // with from the data itself.\n var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);\n var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH);\n\n var blobType;\n // Backwards-compatible blob type serialization strategy.\n // DBs created with older versions of localForage will simply not have the blob type.\n if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {\n var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);\n blobType = matcher[1];\n serializedString = serializedString.substring(matcher[0].length);\n }\n var buffer = stringToBuffer(serializedString);\n\n // Return the right type based on the code/type set during\n // serialization.\n switch (type) {\n case TYPE_ARRAYBUFFER:\n return buffer;\n case TYPE_BLOB:\n return createBlob([buffer], { type: blobType });\n case TYPE_INT8ARRAY:\n return new Int8Array(buffer);\n case TYPE_UINT8ARRAY:\n return new Uint8Array(buffer);\n case TYPE_UINT8CLAMPEDARRAY:\n return new Uint8ClampedArray(buffer);\n case TYPE_INT16ARRAY:\n return new Int16Array(buffer);\n case TYPE_UINT16ARRAY:\n return new Uint16Array(buffer);\n case TYPE_INT32ARRAY:\n return new Int32Array(buffer);\n case TYPE_UINT32ARRAY:\n return new Uint32Array(buffer);\n case TYPE_FLOAT32ARRAY:\n return new Float32Array(buffer);\n case TYPE_FLOAT64ARRAY:\n return new Float64Array(buffer);\n default:\n throw new Error('Unkown type: ' + type);\n }\n}\n\nvar localforageSerializer = {\n serialize: serialize,\n deserialize: deserialize,\n stringToBuffer: stringToBuffer,\n bufferToString: bufferToString\n};\n\n/*\n * Includes code from:\n *\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n// Open the WebSQL database (automatically creates one if one didn't\n// previously exist), using any options set in the config.\nfunction _initStorage$1(options) {\n var self = this;\n var dbInfo = {\n db: null\n };\n\n if (options) {\n for (var i in options) {\n dbInfo[i] = typeof options[i] !== 'string' ? options[i].toString() : options[i];\n }\n }\n\n var dbInfoPromise = new Promise$1(function (resolve, reject) {\n // Open the database; the openDatabase API will automatically\n // create it for us if it doesn't exist.\n try {\n dbInfo.db = openDatabase(dbInfo.name, String(dbInfo.version), dbInfo.description, dbInfo.size);\n } catch (e) {\n return reject(e);\n }\n\n // Create our key/value table if it doesn't exist.\n dbInfo.db.transaction(function (t) {\n t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + ' (id INTEGER PRIMARY KEY, key unique, value)', [], function () {\n self._dbInfo = dbInfo;\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n });\n\n dbInfo.serializer = localforageSerializer;\n return dbInfoPromise;\n}\n\nfunction getItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).value : null;\n\n // Check to see if this is serialized content we need to\n // unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction iterate$1(iterator, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT * FROM ' + dbInfo.storeName, [], function (t, results) {\n var rows = results.rows;\n var length = rows.length;\n\n for (var i = 0; i < length; i++) {\n var item = rows.item(i);\n var result = item.value;\n\n // Check to see if this is serialized content\n // we need to unpack.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n result = iterator(result, item.key, i + 1);\n\n // void(0) prevents problems with redefinition\n // of `undefined`.\n if (result !== void 0) {\n resolve(result);\n return;\n }\n }\n\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction _setItem(key, value, callback, retriesLeft) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n // The localStorage API doesn't return undefined values in an\n // \"expected\" way, so undefined is always cast to null in all\n // drivers. See: https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n dbInfo.db.transaction(function (t) {\n t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + ' (key, value) VALUES (?, ?)', [key, value], function () {\n resolve(originalValue);\n }, function (t, error) {\n reject(error);\n });\n }, function (sqlError) {\n // The transaction failed; check\n // to see if it's a quota error.\n if (sqlError.code === sqlError.QUOTA_ERR) {\n // We reject the callback outright for now, but\n // it's worth trying to re-run the transaction.\n // Even if the user accepts the prompt to use\n // more storage on Safari, this error will\n // be called.\n //\n // Try to re-run the transaction.\n if (retriesLeft > 0) {\n resolve(_setItem.apply(self, [key, originalValue, callback, retriesLeft - 1]));\n return;\n }\n reject(sqlError);\n }\n });\n }\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction setItem$1(key, value, callback) {\n return _setItem.apply(this, [key, value, callback, 1]);\n}\n\nfunction removeItem$1(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function () {\n resolve();\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Deletes every item in the table.\n// TODO: Find out if this resets the AUTO_INCREMENT number.\nfunction clear$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function () {\n resolve();\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Does a simple `COUNT(key)` to get the number of items stored in\n// localForage.\nfunction length$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n // Ahhh, SQL makes this one soooooo easy.\n t.executeSql('SELECT COUNT(key) as c FROM ' + dbInfo.storeName, [], function (t, results) {\n var result = results.rows.item(0).c;\n\n resolve(result);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Return the key located at key index X; essentially gets the key from a\n// `WHERE id = ?`. This is the most efficient way I can think to implement\n// this rarely-used (in my experience) part of the API, but it can seem\n// inconsistent, because we do `INSERT OR REPLACE INTO` on `setItem()`, so\n// the ID of each key will change every time it's updated. Perhaps a stored\n// procedure for the `setItem()` SQL would solve this problem?\n// TODO: Don't change ID on `setItem()`.\nfunction key$1(n, callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) {\n var result = results.rows.length ? results.rows.item(0).key : null;\n resolve(result);\n }, function (t, error) {\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$1(callback) {\n var self = this;\n\n var promise = new Promise$1(function (resolve, reject) {\n self.ready().then(function () {\n var dbInfo = self._dbInfo;\n dbInfo.db.transaction(function (t) {\n t.executeSql('SELECT key FROM ' + dbInfo.storeName, [], function (t, results) {\n var keys = [];\n\n for (var i = 0; i < results.rows.length; i++) {\n keys.push(results.rows.item(i).key);\n }\n\n resolve(keys);\n }, function (t, error) {\n\n reject(error);\n });\n });\n })[\"catch\"](reject);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar webSQLStorage = {\n _driver: 'webSQLStorage',\n _initStorage: _initStorage$1,\n iterate: iterate$1,\n getItem: getItem$1,\n setItem: setItem$1,\n removeItem: removeItem$1,\n clear: clear$1,\n length: length$1,\n key: key$1,\n keys: keys$1\n};\n\n// Config the localStorage backend, using options set in the config.\nfunction _initStorage$2(options) {\n var self = this;\n var dbInfo = {};\n if (options) {\n for (var i in options) {\n dbInfo[i] = options[i];\n }\n }\n\n dbInfo.keyPrefix = dbInfo.name + '/';\n\n if (dbInfo.storeName !== self._defaultConfig.storeName) {\n dbInfo.keyPrefix += dbInfo.storeName + '/';\n }\n\n self._dbInfo = dbInfo;\n dbInfo.serializer = localforageSerializer;\n\n return Promise$1.resolve();\n}\n\n// Remove all keys from the datastore, effectively destroying all data in\n// the app's key/value store!\nfunction clear$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var keyPrefix = self._dbInfo.keyPrefix;\n\n for (var i = localStorage.length - 1; i >= 0; i--) {\n var key = localStorage.key(i);\n\n if (key.indexOf(keyPrefix) === 0) {\n localStorage.removeItem(key);\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Retrieve an item from the store. Unlike the original async_storage\n// library in Gaia, we don't modify return values at all. If a key's value\n// is `undefined`, we pass that value to the callback function.\nfunction getItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result = localStorage.getItem(dbInfo.keyPrefix + key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the key\n // is likely undefined and we'll pass it straight to the\n // callback.\n if (result) {\n result = dbInfo.serializer.deserialize(result);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Iterate over all items in the store.\nfunction iterate$2(iterator, callback) {\n var self = this;\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var keyPrefix = dbInfo.keyPrefix;\n var keyPrefixLength = keyPrefix.length;\n var length = localStorage.length;\n\n // We use a dedicated iterator instead of the `i` variable below\n // so other keys we fetch in localStorage aren't counted in\n // the `iterationNumber` argument passed to the `iterate()`\n // callback.\n //\n // See: github.com/mozilla/localForage/pull/435#discussion_r38061530\n var iterationNumber = 1;\n\n for (var i = 0; i < length; i++) {\n var key = localStorage.key(i);\n if (key.indexOf(keyPrefix) !== 0) {\n continue;\n }\n var value = localStorage.getItem(key);\n\n // If a result was found, parse it from the serialized\n // string into a JS object. If result isn't truthy, the\n // key is likely undefined and we'll pass it straight\n // to the iterator.\n if (value) {\n value = dbInfo.serializer.deserialize(value);\n }\n\n value = iterator(value, key.substring(keyPrefixLength), iterationNumber++);\n\n if (value !== void 0) {\n return value;\n }\n }\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Same as localStorage's key() method, except takes a callback.\nfunction key$2(n, callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var result;\n try {\n result = localStorage.key(n);\n } catch (error) {\n result = null;\n }\n\n // Remove the prefix from the key, if a key is found.\n if (result) {\n result = result.substring(dbInfo.keyPrefix.length);\n }\n\n return result;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nfunction keys$2(callback) {\n var self = this;\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n var length = localStorage.length;\n var keys = [];\n\n for (var i = 0; i < length; i++) {\n if (localStorage.key(i).indexOf(dbInfo.keyPrefix) === 0) {\n keys.push(localStorage.key(i).substring(dbInfo.keyPrefix.length));\n }\n }\n\n return keys;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Supply the number of keys in the datastore to the callback function.\nfunction length$2(callback) {\n var self = this;\n var promise = self.keys().then(function (keys) {\n return keys.length;\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Remove an item from the store, nice and simple.\nfunction removeItem$2(key, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n var dbInfo = self._dbInfo;\n localStorage.removeItem(dbInfo.keyPrefix + key);\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\n// Set a key's value and run an optional callback once the value is set.\n// Unlike Gaia's implementation, the callback function is passed the value,\n// in case you want to operate on that value only after you're sure it\n// saved, or something like that.\nfunction setItem$2(key, value, callback) {\n var self = this;\n\n // Cast the key to a string, as that's all we can set as a key.\n if (typeof key !== 'string') {\n console.warn(key + ' used as a key, but it is not a string.');\n key = String(key);\n }\n\n var promise = self.ready().then(function () {\n // Convert undefined values to null.\n // https://github.com/mozilla/localForage/pull/42\n if (value === undefined) {\n value = null;\n }\n\n // Save the original value to pass to the callback.\n var originalValue = value;\n\n return new Promise$1(function (resolve, reject) {\n var dbInfo = self._dbInfo;\n dbInfo.serializer.serialize(value, function (value, error) {\n if (error) {\n reject(error);\n } else {\n try {\n localStorage.setItem(dbInfo.keyPrefix + key, value);\n resolve(originalValue);\n } catch (e) {\n // localStorage capacity exceeded.\n // TODO: Make this a specific error/event.\n if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {\n reject(e);\n }\n reject(e);\n }\n }\n });\n });\n });\n\n executeCallback(promise, callback);\n return promise;\n}\n\nvar localStorageWrapper = {\n _driver: 'localStorageWrapper',\n _initStorage: _initStorage$2,\n // Default API, from Gaia/localStorage.\n iterate: iterate$2,\n getItem: getItem$2,\n setItem: setItem$2,\n removeItem: removeItem$2,\n clear: clear$2,\n length: length$2,\n key: key$2,\n keys: keys$2\n};\n\n// Custom drivers are stored here when `defineDriver()` is called.\n// They are shared across all instances of localForage.\nvar CustomDrivers = {};\n\nvar DriverType = {\n INDEXEDDB: 'asyncStorage',\n LOCALSTORAGE: 'localStorageWrapper',\n WEBSQL: 'webSQLStorage'\n};\n\nvar DefaultDriverOrder = [DriverType.INDEXEDDB, DriverType.WEBSQL, DriverType.LOCALSTORAGE];\n\nvar LibraryMethods = ['clear', 'getItem', 'iterate', 'key', 'keys', 'length', 'removeItem', 'setItem'];\n\nvar DefaultConfig = {\n description: '',\n driver: DefaultDriverOrder.slice(),\n name: 'localforage',\n // Default DB size is _JUST UNDER_ 5MB, as it's the highest size\n // we can use without a prompt.\n size: 4980736,\n storeName: 'keyvaluepairs',\n version: 1.0\n};\n\nvar driverSupport = {};\n// Check to see if IndexedDB is available and if it is the latest\n// implementation; it's our preferred backend library. We use \"_spec_test\"\n// as the name of the database because it's not the one we'll operate on,\n// but it's useful to make sure its using the right spec.\n// See: https://github.com/mozilla/localForage/issues/128\ndriverSupport[DriverType.INDEXEDDB] = isIndexedDBValid();\n\ndriverSupport[DriverType.WEBSQL] = isWebSQLValid();\n\ndriverSupport[DriverType.LOCALSTORAGE] = isLocalStorageValid();\n\nvar isArray = Array.isArray || function (arg) {\n return Object.prototype.toString.call(arg) === '[object Array]';\n};\n\nfunction callWhenReady(localForageInstance, libraryMethod) {\n localForageInstance[libraryMethod] = function () {\n var _args = arguments;\n return localForageInstance.ready().then(function () {\n return localForageInstance[libraryMethod].apply(localForageInstance, _args);\n });\n };\n}\n\nfunction extend() {\n for (var i = 1; i < arguments.length; i++) {\n var arg = arguments[i];\n\n if (arg) {\n for (var key in arg) {\n if (arg.hasOwnProperty(key)) {\n if (isArray(arg[key])) {\n arguments[0][key] = arg[key].slice();\n } else {\n arguments[0][key] = arg[key];\n }\n }\n }\n }\n }\n\n return arguments[0];\n}\n\nfunction isLibraryDriver(driverName) {\n for (var driver in DriverType) {\n if (DriverType.hasOwnProperty(driver) && DriverType[driver] === driverName) {\n return true;\n }\n }\n\n return false;\n}\n\nvar LocalForage = function () {\n function LocalForage(options) {\n _classCallCheck(this, LocalForage);\n\n this.INDEXEDDB = DriverType.INDEXEDDB;\n this.LOCALSTORAGE = DriverType.LOCALSTORAGE;\n this.WEBSQL = DriverType.WEBSQL;\n\n this._defaultConfig = extend({}, DefaultConfig);\n this._config = extend({}, this._defaultConfig, options);\n this._driverSet = null;\n this._initDriver = null;\n this._ready = false;\n this._dbInfo = null;\n\n this._wrapLibraryMethodsWithReady();\n this.setDriver(this._config.driver)[\"catch\"](function () {});\n }\n\n // Set any config values for localForage; can be called anytime before\n // the first API call (e.g. `getItem`, `setItem`).\n // We loop through options so we don't overwrite existing config\n // values.\n\n\n LocalForage.prototype.config = function config(options) {\n // If the options argument is an object, we use it to set values.\n // Otherwise, we return either a specified config value or all\n // config values.\n if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') {\n // If localforage is ready and fully initialized, we can't set\n // any new configuration values. Instead, we return an error.\n if (this._ready) {\n return new Error(\"Can't call config() after localforage \" + 'has been used.');\n }\n\n for (var i in options) {\n if (i === 'storeName') {\n options[i] = options[i].replace(/\\W/g, '_');\n }\n\n if (i === 'version' && typeof options[i] !== 'number') {\n return new Error('Database version must be a number.');\n }\n\n this._config[i] = options[i];\n }\n\n // after all config options are set and\n // the driver option is used, try setting it\n if ('driver' in options && options.driver) {\n return this.setDriver(this._config.driver);\n }\n\n return true;\n } else if (typeof options === 'string') {\n return this._config[options];\n } else {\n return this._config;\n }\n };\n\n // Used to define a custom driver, shared across all instances of\n // localForage.\n\n\n LocalForage.prototype.defineDriver = function defineDriver(driverObject, callback, errorCallback) {\n var promise = new Promise$1(function (resolve, reject) {\n try {\n var driverName = driverObject._driver;\n var complianceError = new Error('Custom driver not compliant; see ' + 'https://mozilla.github.io/localForage/#definedriver');\n var namingError = new Error('Custom driver name already in use: ' + driverObject._driver);\n\n // A driver name should be defined and not overlap with the\n // library-defined, default drivers.\n if (!driverObject._driver) {\n reject(complianceError);\n return;\n }\n if (isLibraryDriver(driverObject._driver)) {\n reject(namingError);\n return;\n }\n\n var customDriverMethods = LibraryMethods.concat('_initStorage');\n for (var i = 0; i < customDriverMethods.length; i++) {\n var customDriverMethod = customDriverMethods[i];\n if (!customDriverMethod || !driverObject[customDriverMethod] || typeof driverObject[customDriverMethod] !== 'function') {\n reject(complianceError);\n return;\n }\n }\n\n var supportPromise = Promise$1.resolve(true);\n if ('_support' in driverObject) {\n if (driverObject._support && typeof driverObject._support === 'function') {\n supportPromise = driverObject._support();\n } else {\n supportPromise = Promise$1.resolve(!!driverObject._support);\n }\n }\n\n supportPromise.then(function (supportResult) {\n driverSupport[driverName] = supportResult;\n CustomDrivers[driverName] = driverObject;\n resolve();\n }, reject);\n } catch (e) {\n reject(e);\n }\n });\n\n executeTwoCallbacks(promise, callback, errorCallback);\n return promise;\n };\n\n LocalForage.prototype.driver = function driver() {\n return this._driver || null;\n };\n\n LocalForage.prototype.getDriver = function getDriver(driverName, callback, errorCallback) {\n var self = this;\n var getDriverPromise = Promise$1.resolve().then(function () {\n if (isLibraryDriver(driverName)) {\n switch (driverName) {\n case self.INDEXEDDB:\n return asyncStorage;\n case self.LOCALSTORAGE:\n return localStorageWrapper;\n case self.WEBSQL:\n return webSQLStorage;\n }\n } else if (CustomDrivers[driverName]) {\n return CustomDrivers[driverName];\n } else {\n throw new Error('Driver not found.');\n }\n });\n executeTwoCallbacks(getDriverPromise, callback, errorCallback);\n return getDriverPromise;\n };\n\n LocalForage.prototype.getSerializer = function getSerializer(callback) {\n var serializerPromise = Promise$1.resolve(localforageSerializer);\n executeTwoCallbacks(serializerPromise, callback);\n return serializerPromise;\n };\n\n LocalForage.prototype.ready = function ready(callback) {\n var self = this;\n\n var promise = self._driverSet.then(function () {\n if (self._ready === null) {\n self._ready = self._initDriver();\n }\n\n return self._ready;\n });\n\n executeTwoCallbacks(promise, callback, callback);\n return promise;\n };\n\n LocalForage.prototype.setDriver = function setDriver(drivers, callback, errorCallback) {\n var self = this;\n\n if (!isArray(drivers)) {\n drivers = [drivers];\n }\n\n var supportedDrivers = this._getSupportedDrivers(drivers);\n\n function setDriverToConfig() {\n self._config.driver = self.driver();\n }\n\n function extendSelfWithDriver(driver) {\n self._extend(driver);\n setDriverToConfig();\n\n self._ready = self._initStorage(self._config);\n return self._ready;\n }\n\n function initDriver(supportedDrivers) {\n return function () {\n var currentDriverIndex = 0;\n\n function driverPromiseLoop() {\n while (currentDriverIndex < supportedDrivers.length) {\n var driverName = supportedDrivers[currentDriverIndex];\n currentDriverIndex++;\n\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(extendSelfWithDriver)[\"catch\"](driverPromiseLoop);\n }\n\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n }\n\n return driverPromiseLoop();\n };\n }\n\n // There might be a driver initialization in progress\n // so wait for it to finish in order to avoid a possible\n // race condition to set _dbInfo\n var oldDriverSetDone = this._driverSet !== null ? this._driverSet[\"catch\"](function () {\n return Promise$1.resolve();\n }) : Promise$1.resolve();\n\n this._driverSet = oldDriverSetDone.then(function () {\n var driverName = supportedDrivers[0];\n self._dbInfo = null;\n self._ready = null;\n\n return self.getDriver(driverName).then(function (driver) {\n self._driver = driver._driver;\n setDriverToConfig();\n self._wrapLibraryMethodsWithReady();\n self._initDriver = initDriver(supportedDrivers);\n });\n })[\"catch\"](function () {\n setDriverToConfig();\n var error = new Error('No available storage method found.');\n self._driverSet = Promise$1.reject(error);\n return self._driverSet;\n });\n\n executeTwoCallbacks(this._driverSet, callback, errorCallback);\n return this._driverSet;\n };\n\n LocalForage.prototype.supports = function supports(driverName) {\n return !!driverSupport[driverName];\n };\n\n LocalForage.prototype._extend = function _extend(libraryMethodsAndProperties) {\n extend(this, libraryMethodsAndProperties);\n };\n\n LocalForage.prototype._getSupportedDrivers = function _getSupportedDrivers(drivers) {\n var supportedDrivers = [];\n for (var i = 0, len = drivers.length; i < len; i++) {\n var driverName = drivers[i];\n if (this.supports(driverName)) {\n supportedDrivers.push(driverName);\n }\n }\n return supportedDrivers;\n };\n\n LocalForage.prototype._wrapLibraryMethodsWithReady = function _wrapLibraryMethodsWithReady() {\n // Add a stub for each driver API method that delays the call to the\n // corresponding driver method until localForage is ready. These stubs\n // will be replaced by the driver methods as soon as the driver is\n // loaded, so there is no performance impact.\n for (var i = 0; i < LibraryMethods.length; i++) {\n callWhenReady(this, LibraryMethods[i]);\n }\n };\n\n LocalForage.prototype.createInstance = function createInstance(options) {\n return new LocalForage(options);\n };\n\n return LocalForage;\n}();\n\n// The actual localForage object that we expose as a module or via a\n// global. It's extended by pulling in one of our other libraries.\n\n\nvar localforage_js = new LocalForage();\n\nmodule.exports = localforage_js;\n\n},{\"3\":3}]},{},[4])(4)\n});","const initial = require('./problems/initial');\nconst arrays = require('./problems/arrays');\n\nmodule.exports = {\n initial: initial,\n arrays: arrays\n};\n","module.exports = [\n {\n name: 'Access Array by index (first)',\n time: 10,\n prompt: 'Return the first value of the Array',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits[0];`,\n tests: [\n {\n name: 'Correct output',\n test: 'assert.deepEqual(output, \\'apple\\') === undefined'\n },\n {\n name: 'Returns a String',\n test: 'assert.isString(output) === undefined'\n }\n ]\n },\n {\n name: 'Access Array by index (last)',\n time: 10,\n prompt: 'Return the last value of the Array',\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n return fruits[fruits.length - 1];`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 'orange') === undefined;`\n },\n {\n name: 'Returns a String',\n test: `assert.isString(output) === undefined;`\n }\n ]\n },\n {\n name: 'Access Array by index (second)',\n time: 10,\n prompt: 'Return the second value of the Array',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits[1];`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 'banana') === undefined;`\n },\n {\n name: 'Returns a String',\n test: `assert.isString(output) === undefined;`\n }\n ]\n },\n {\n name: 'Array.forEach()',\n time: 20,\n prompt: 'Loop over the array, add an \\'x\\' to the end of each name, push each fruit into a new array, then return the new array.',\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n const newFruits = [];\n fruits.forEach(function(item) {\n newFruits.push(item+'x');\n });\n return newFruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['applex', 'bananax']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.push()',\n time: 10,\n prompt: `Add 'orange' to the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana'];\\r`,\n answer: `const fruits = ['apple', 'banana'];\n fruits.push('orange');\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `(assert.deepEqual(output, ['apple', 'banana', 'orange']) === undefined);`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n }\n ]\n },\n {\n name: 'Array.shift()',\n time: 10,\n prompt: `Remove 'apple' from the front of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.shift();\n return fruits;`,\n tests: [\n {\n name: 'Output must be correct',\n test: `assert.deepEqual(output, ['banana', 'orange']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.unshift()',\n time: 10,\n prompt: `Add 'strawberry' to the front of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.unshift('strawberry');\n return fruits;`,\n tests: [\n {\n name: 'Output must be correct',\n test: `(assert.deepEqual(output, [\n 'strawberry',\n 'apple',\n 'banana',\n 'orange'\n ]) === undefined)`\n },\n {\n name: 'Must return an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 4 items',\n test: `assert.lengthOf(output, 4) === undefined;`\n }\n ]\n },\n {\n name: 'Array.indexOf()',\n time: 10,\n prompt: `Return the index of 'banana' in the Array.`,\n given: `const fruits = ['strawberry', 'banana', 'mango'];\\r`,\n answer: `const fruits = ['strawberry', 'banana', 'mango'];\n const ind = fruits.indexOf('banana');\n return ind;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 1) === undefined;`\n },\n {\n name: 'Returns a Number',\n test: `assert.isNumber(output) === undefined;`\n }\n ]\n },\n {\n name: 'Array.concat()',\n time: 10,\n prompt: `Merge the two arrays using Array's 'concat()' method. Return the resulting array.`,\n given: `const fruits = ['strawberry', 'banana'];\\rconst otherFruits = ['pear','peach'];\\r`,\n answer: `const fruits = ['strawberry', 'banana'];\n const otherFruits = ['pear','peach'];\n const allTheFruits = fruits.concat(otherFruits);\n return allTheFruits;\\r`,\n tests: [\n {\n name: 'Correct output',\n test: `(assert.deepEqual(output, [\n 'strawberry',\n 'banana',\n 'pear',\n 'peach'\n ]) === undefined\n );`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 4 items',\n test: `assert.lengthOf(output, 4) === undefined;`\n }\n ]\n },\n {\n name: 'Array.join()',\n time: 10,\n prompt: `Mix the two flavors with a '-' using Array's 'join' method. Return the resulting hybrid flavor.`,\n given: `const fruits = ['strawberry', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'banana'];\n const hybrid = fruits.join('-');\n return hybrid;\\r`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 'strawberry-banana') === undefined;`\n },\n {\n name: 'Returns a String',\n test: `assert.isString(output) === undefined;`\n }\n ]\n },\n {\n name: 'Array.slice()',\n time: 20,\n prompt: `Return just the citrus fruits from the 'fruits' array using 'Array.slice()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const citrus = fruits.slice(1, 3);\n return citrus;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['orange', 'lemon']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.reverse()',\n time: 10,\n prompt: `Reverse the order of the 'fruit' array using 'Array.reverse()'`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const stiurf = fruits.reverse();\n return stiurf;`,\n tests: [\n {\n name: 'Correct output',\n test: `(assert.deepEqual(output, [\n 'banana',\n 'lemon',\n 'orange',\n 'strawberry'\n ]) === undefined);`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 4 items',\n test: `assert.lengthOf(output, 4) === undefined;`\n },\n {\n name: `First item is 'banana'`,\n test: `assert.deepEqual(output[0], 'banana') === undefined;`\n }\n ]\n },\n {\n name: 'Array.sort()',\n time: 10,\n prompt: `Return the 'fruits' Array after sorting them using 'Array.sort()'.`,\n given: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\\r`,\n answer: `const fruits = ['strawberry', 'orange', 'lemon', 'banana'];\n const orderlyFruit = fruits.sort();\n return orderlyFruit;`,\n tests: [\n {\n name: 'Correct output',\n test: `(assert.deepEqual(output, [\n 'banana',\n 'lemon',\n 'orange',\n 'strawberry'\n ]) === undefined);`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 4 items',\n test: `assert.lengthOf(output, 4) === undefined;`\n },\n {\n name: `First item is 'banana'`,\n test: `assert.deepEqual(output[0], 'banana') === undefined;`\n }\n ]\n },\n {\n name: 'Array.lastIndexOf()',\n time: 10,\n prompt: `Return the index of the last 'peach' instance in the 'fruit' array using 'Array.lastIndexOf()'`,\n given: `const fruits = ['peach', 'orange', 'lemon', 'peach'];\\r`,\n answer: `const fruits = ['peach', 'orange', 'lemon', 'peach'];\n const wheresTheLastPeach = fruits.lastIndexOf('peach');\n return wheresTheLastPeach;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, 3) === undefined;`\n },\n {\n name: 'Returns a Number',\n test: `assert.isNumber(output) === undefined;`\n }\n ]\n },\n {\n name: 'Array.filter()',\n time: 10,\n prompt: `Return an array of the numbers greater than 5 in 'numbers' using 'Array.filter()'`,\n given: `const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\\r`,\n answer: `const numbers = [1, 1, 2, 3, 5, 8, 13, 21];\n const overFive = numbers.filter(num => num > 5);\n return overFive;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, [8, 13, 21]) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n },\n {\n name: `First item is 8`,\n test: `assert.deepEqual(output[0], 8) === undefined;`\n }\n ]\n },\n {\n name: 'Array.map()',\n time: 10,\n prompt: `Return an array of 'numbers' array's square roots, using 'Array.map()' and 'Math.sqrt()'`,\n given: `const numbers = [25, 121, 169];\\r`,\n answer: `const numbers = [25, 121, 169];\n const roots = numbers.map(num => Math.sqrt(num));\n return roots;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, [5, 11, 13]) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 3 items',\n test: `assert.lengthOf(output, 3) === undefined;`\n },\n {\n name: `First item is 5`,\n test: `assert.deepEqual(output[0], 5) === undefined;`\n },\n {\n name: `Last item is 13`,\n test: `assert.deepEqual(output[output.length - 1], 13) === undefined;`\n }\n ]\n },\n {\n name: 'Array.every()',\n time: 10,\n prompt: `Return object that returns whether each array contains all even numbers using Array.every().`,\n given: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,\n answer: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 5, 6, 8];\n function isEven(element) {\n return element % 2 === 0\n }\n return {\n evenNumbers: evenNumbers.every(isEven),\n someOddNumbers: someOddNumbers.every(isEven)\n };`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, {\n evenNumbers: true,\n someOddNumbers: false\n }) === undefined;`\n },\n {\n name: 'Returns an Object',\n test: `assert.isObject(output) === undefined;`\n },\n {\n name: 'Object has 2 items',\n test: `assert.lengthOf(Object.keys(output), 2) === undefined;`\n },\n {\n name: `First value is true`,\n test: `assert.isTrue(output.evenNumbers) === undefined;`\n },\n {\n name: `Second value is false`,\n test: `assert.isFalse(output.someOddNumbers) === undefined;`\n }\n ]\n },\n {\n name: 'Array.some()',\n time: 10,\n prompt: `Return 'Object' that returns whether each array contains some odd numbers using 'Array.some()'.`,\n given: `const evenNumbers = [2, 4, 6, 8];\n const someOddNumbers = [2, 4, 7, 8];\n function isOdd(element) {\n \n }\n return {\n evenNumbers: evenNumbers.,\n someOddNumbers: someOddNumbers.\n };`,\n answer: `const evenNumbers = [1, 3, 5, 7];\n const someOddNumbers = [1, 3, 6, 7];\n function isOdd(element) {\n return element % 2 !== 0;\n }\n return {\n evenNumbers: evenNumbers.some(isOdd),\n someOddNumbers: someOddNumbers.some(isOdd)\n };`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, {\n evenNumbers: false,\n someOddNumbers: true\n }) === undefined;`\n },\n {\n name: 'Returns an Object',\n test: `assert.isObject(output) === undefined;`\n },\n {\n name: 'Object has 2 items',\n test: `assert.lengthOf(Object.keys(output), 2) === undefined;`\n },\n {\n name: `First value is false`,\n test: `assert.isFalse(output.evenNumbers) === undefined;`\n },\n {\n name: `Second value is true`,\n test: `assert.isTrue(output.someOddNumbers) === undefined;`\n }\n ]\n }\n // Next problems to create:\n // forEach? fix one above that tried, but can't verify forEach was used\n // some\n // reduce\n // reduceRight\n // Array.from and other ways to turn array-like into array\n];\n","module.exports = [\n {\n name: 'Create Array',\n time: 10,\n prompt: 'Create and return an array that contains \\'apple\\' and \\'banana\\'',\n given: `const fruits = [];\\rreturn fruits;`,\n answer: `const fruits = ['apple', 'banana'];\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n },\n {\n name: 'Array.pop()',\n time: 10,\n prompt: `Remove 'orange' from the end of the 'fruits' array and return 'fruits'.`,\n given: `const fruits = ['apple', 'banana', 'orange'];\\r`,\n answer: `const fruits = ['apple', 'banana', 'orange'];\n fruits.pop();\n return fruits;`,\n tests: [\n {\n name: 'Correct output',\n test: `assert.deepEqual(output, ['apple', 'banana']) === undefined;`\n },\n {\n name: 'Returns an Array',\n test: `assert.isArray(output) === undefined;`\n },\n {\n name: 'Array has 2 items',\n test: `assert.lengthOf(output, 2) === undefined;`\n }\n ]\n }\n]\n","module.exports = require('./lib/type');\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/*!\n * Detectable javascript natives\n */\n\nvar natives = {\n '[object Array]': 'array'\n , '[object RegExp]': 'regexp'\n , '[object Function]': 'function'\n , '[object Arguments]': 'arguments'\n , '[object Date]': 'date'\n};\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\n\nfunction getType (obj) {\n var str = Object.prototype.toString.call(obj);\n if (natives[str]) return natives[str];\n if (obj === null) return 'null';\n if (obj === undefined) return 'undefined';\n if (obj === Object(obj)) return 'object';\n return typeof obj;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library () {\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function (type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function (obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","/*!\n * type-detect\n * Copyright(c) 2013 jake luer \n * MIT Licensed\n */\n\n/*!\n * Primary Exports\n */\n\nvar exports = module.exports = getType;\n\n/**\n * ### typeOf (obj)\n *\n * Use several different techniques to determine\n * the type of object being tested.\n *\n *\n * @param {Mixed} object\n * @return {String} object type\n * @api public\n */\nvar objectTypeRegexp = /^\\[object (.*)\\]$/;\n\nfunction getType(obj) {\n var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase();\n // Let \"new String('')\" return 'object'\n if (typeof Promise === 'function' && obj instanceof Promise) return 'promise';\n // PhantomJS has type \"DOMWindow\" for null\n if (obj === null) return 'null';\n // PhantomJS has type \"DOMWindow\" for undefined\n if (obj === undefined) return 'undefined';\n return type;\n}\n\nexports.Library = Library;\n\n/**\n * ### Library\n *\n * Create a repository for custom type detection.\n *\n * ```js\n * var lib = new type.Library;\n * ```\n *\n */\n\nfunction Library() {\n if (!(this instanceof Library)) return new Library();\n this.tests = {};\n}\n\n/**\n * #### .of (obj)\n *\n * Expose replacement `typeof` detection to the library.\n *\n * ```js\n * if ('string' === lib.of('hello world')) {\n * // ...\n * }\n * ```\n *\n * @param {Mixed} object to test\n * @return {String} type\n */\n\nLibrary.prototype.of = getType;\n\n/**\n * #### .define (type, test)\n *\n * Add a test to for the `.test()` assertion.\n *\n * Can be defined as a regular expression:\n *\n * ```js\n * lib.define('int', /^[0-9]+$/);\n * ```\n *\n * ... or as a function:\n *\n * ```js\n * lib.define('bln', function (obj) {\n * if ('boolean' === lib.of(obj)) return true;\n * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];\n * if ('string' === lib.of(obj)) obj = obj.toLowerCase();\n * return !! ~blns.indexOf(obj);\n * });\n * ```\n *\n * @param {String} type\n * @param {RegExp|Function} test\n * @api public\n */\n\nLibrary.prototype.define = function(type, test) {\n if (arguments.length === 1) return this.tests[type];\n this.tests[type] = test;\n return this;\n};\n\n/**\n * #### .test (obj, test)\n *\n * Assert that an object is of type. Will first\n * check natives, and if that does not pass it will\n * use the user defined custom tests.\n *\n * ```js\n * assert(lib.test('1', 'int'));\n * assert(lib.test('yes', 'bln'));\n * ```\n *\n * @param {Mixed} object\n * @param {String} type\n * @return {Boolean} result\n * @api public\n */\n\nLibrary.prototype.test = function(obj, type) {\n if (type === getType(obj)) return true;\n var test = this.tests[type];\n\n if (test && 'regexp' === getType(test)) {\n return test.test(obj);\n } else if (test && 'function' === getType(test)) {\n return test(obj);\n } else {\n throw new ReferenceError('Type test \"' + type + '\" not defined or invalid.');\n }\n};\n","(function (document, window) {\n // DEPENDENCIES\n // ============================================================\n const localforage = require('localforage');\n const probs = require('pjs-problems');\n const dedent = require('dedent');\n const assert = require('chai').assert;\n\n // PROBLEM TEMPLATE NICE-IFICATION\n // ============================================================\n\n function dedentStrings(problems) {\n return problems.map(prob => {\n prob.given = dedent(prob.given)\n prob.answer = dedent(prob.answer)\n return prob\n });\n }\n\n\n // PROBLEMS\n // ============================================================\n\n let problems = [];\n Object.keys(probs).forEach(subject => {\n problems.push(...probs[subject]);\n });\n problems = dedentStrings(problems);\n\n\n // CONFIG\n // ============================================================\n\n // Hoist current problem\n let currentProblem;\n\n // Keys to ignore while user is navigating around the textarea but not changing any code\n const ignoreKeyCodes = [\n 9, // Tab\n 37, // Left arrow\n 39, // Right arrow\n 38, // Up arrow\n 40 // Down arrow\n ];\n\n let config = {\n shuffle: true,\n timer: false,\n currentIndex: 0\n };\n\n // Pull config from localforage\n localforage\n .getItem('js_practice_config')\n .then(val => {\n if (val) {\n config = val;\n }\n loadApp(config);\n })\n .catch(err => {\n console.log('localforage err:', err);\n loadApp(config);\n });\n\n function updateLocalstore(config) {\n return localforage\n .setItem('js_practice_config', config)\n .then(val => val)\n .catch(err => {\n console.log('Settings update error:', err);\n });\n }\n\n // HELPERS\n // ============================================================\n\n function debounce(func, wait, immediate) {\n let timeout;\n return function () {\n const context = this;\n const args = arguments;\n const later = function () {\n timeout = null;\n if (!immediate) {\n func.apply(context, args);\n }\n };\n const callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) {\n func.apply(context, args);\n }\n };\n }\n\n // UI\n // ============================================================\n\n // elements\n const problemEl = document.getElementById('problem');\n const codeEl = document.getElementById('code');\n const testSuiteEl = document.getElementById('test-suite');\n const testTotalEl = document.getElementById('test-total');\n const evalConsoleEl = document.getElementById('eval-output');\n const assertConsoleEl = document.getElementById('assert-output');\n const shuffleProblemsButtonEl = document.getElementById('shuffle-problems');\n const previousProblemButtonEl = document.getElementById('prev-problem');\n const nextProblemButtonEl = document.getElementById('next-problem');\n\n // Get indexes\n function getRandomIndex(problemsArr) {\n const ind = Math.floor(Math.random() * problemsArr.length);\n config.currentIndex = ind;\n updateLocalstore(config);\n return ind;\n }\n\n function getPreviousIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at beginning, go to end\n if (currentIndex === 0) {\n probInd = problemsArr.length - 1;\n } else {\n probInd = currentIndex - 1;\n }\n return probInd;\n }\n\n function getNextIndex(problemsArr) {\n let probInd;\n const currentIndex = config.currentIndex;\n // If at end or invalid, restart series\n if (currentIndex >= problemsArr.length - 1 || currentIndex < 0) {\n probInd = 0;\n } else {\n probInd = currentIndex + 1;\n }\n return probInd;\n }\n\n // Get problems\n function getCurrentProblem(problemsArr) {\n return problemsArr[config.currentIndex];\n }\n\n function previousProblem() {\n console.log('previousProblem!');\n // Activate back button, for visual queue of nav feedback\n previousProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getPreviousIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function nextProblem() {\n console.log('nextProblem!');\n // Activate next button, for visual queue of nav feedback\n nextProblemButtonEl.classList.add('active');\n config.currentIndex = config.shuffle\n ? getRandomIndex(problems)\n : getNextIndex(problems);\n updateLocalstore(config).then(() => {\n window.location.reload();\n });\n }\n\n function toggleShuffle() {\n console.log('toggle shuffle!');\n config.shuffle = !config.shuffle; // Flip it\n shuffleProblemsButtonEl.classList.toggle('active');\n previousProblemButtonEl.parentNode.classList.toggle('hidden');\n updateLocalstore(config);\n }\n\n function loadProblem(problemObj) {\n currentProblem = problemObj;\n // Prob question\n problemEl.innerText = problemObj.prompt;\n // Prob given code\n if (problemObj.given) {\n codeEl.value = problemObj.given;\n }\n // Seed the tests, pass (init = true) as second param\n testSuite(null, true);\n }\n\n // TODO: Build the assert errors into the test dom on each update.\n function updateTests(testStatus, init) {\n if (init === true) {\n buildTests(currentProblem.tests);\n }\n updateTestStatus(testStatus);\n }\n\n function buildTests(tests) {\n if (tests) {\n const testsDom = tests\n .map(test => {\n return `
\n
[✘]
\n
${test.name}
\n
`;\n })\n .join('');\n testSuiteEl.innerHTML = testsDom;\n }\n }\n\n function updateTestStatus(testStatuses) {\n if (!testStatuses) {\n throw new Error('No testStatuses provided.');\n }\n // Find out if all tests have passed or not\n let allPassed = true;\n testStatuses.forEach(testPassed => {\n if (testPassed !== true) {\n allPassed = false;\n }\n });\n const testEls = [].slice.call(testSuiteEl.querySelectorAll('.test-state'));\n testEls.forEach((testStatusEl, iter) => {\n if (testStatuses[iter] === true) {\n testStatusEl.innerHTML = '[✓]';\n testStatusEl.classList.remove('fail');\n testStatusEl.classList.add('pass');\n } else {\n testStatusEl.innerHTML = '[✘]';\n testStatusEl.classList.remove('pass');\n testStatusEl.classList.add('fail');\n }\n });\n\n if (allPassed === true) {\n testTotalEl.innerText = 'PASS';\n testTotalEl.classList.remove('fail');\n testTotalEl.classList.add('pass');\n } else {\n testTotalEl.innerText = 'FAIL';\n testTotalEl.classList.remove('pass');\n testTotalEl.classList.add('fail');\n }\n }\n\n function printAssertError(errObj) {\n // Make element string\n let inner = '';\n if (errObj !== null) {\n inner = `\n
\n Expected: ${JSON.stringify(errObj.expected)}\n Actual: ${JSON.stringify(errObj.actual)}\n
`;\n }\n\n // Prepend element\n assertConsoleEl.innerHTML = inner;\n }\n\n function printEvalOutput(errObj, output) {\n // Make element string\n let inner = '';\n if (errObj && errObj.message !== undefined) {\n inner = `\n
\n Syntax Error: ${JSON.stringify(errObj.message)}\n
`;\n } else if (output) {\n inner = `\n
\n Output: ${JSON.stringify(output)}\n
`;\n }\n // Prepend element\n evalConsoleEl.innerHTML = inner;\n }\n\n\n // VERIFICATION LOGIC\n // ============================================================\n\n function testSuite(init) {\n // Show 'working' indicator\n testTotalEl.classList.toggle('working');\n // Run stuff\n const output = getOutput(codeEl.value);\n // Run tests on code, return object/array of test results\n const tested = runTests(output);\n // Hide 'working' indicator\n testTotalEl.classList.toggle('working');\n // Update UI with results\n updateTests(tested, init);\n }\n\n function getOutput(code) {\n let evald = false;\n try {\n evald = eval(`(function(){${code}})()`); // eslint-disable-line no-eval\n printEvalOutput(null, evald); // Print current output\n } catch (err) {\n printEvalOutput(err);\n }\n return evald;\n }\n\n function runTests(output) {\n let tested = false;\n tested = currentProblem.tests.map(test => {\n let testOutcome = false;\n try {\n if (output) {\n testOutcome = eval(test.test);\n }\n printAssertError(null);\n } catch (err) {\n printAssertError(err);\n }\n return testOutcome;\n });\n return tested;\n }\n\n // Wrapped to prevent race with local config retrieval\n function loadApp(config) {\n console.log('loading app!');\n\n // Show current toggle state\n if (config.shuffle === true) {\n shuffleProblemsButtonEl.classList.add('active');\n previousProblemButtonEl.parentNode.classList.add('hidden');\n }\n\n // Keybinding stuff\n // ============================================================\n\n // Debounced code validation\n const debouncedInputValidation = debounce(e => {\n // If not arrow keys or other non-character keys\n if (ignoreKeyCodes.indexOf(e.keyCode) === -1) {\n // Run test suite\n testSuite();\n }\n }, 200);\n\n function problemNav(e) {\n // Go to previous problem keybinding\n // If CMD/CTRL + SHIFT + RETURN/ENTER\n if (config.shuffle === false && e.keyCode === 13 && e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem\n previousProblem();\n } else if (e.keyCode === 13 && !e.shiftKey && (e.metaKey || e.ctrlKey)) {\n // Go to next problem keybinding\n // If CMD/CTRL + RETURN/ENTER\n // Go to next problem\n nextProblem();\n }\n }\n\n // Event Bindings\n // ============================================================\n\n // Bind it up\n codeEl.addEventListener('keydown', debouncedInputValidation);\n document.addEventListener('keydown', problemNav);\n shuffleProblemsButtonEl.addEventListener('click', toggleShuffle);\n previousProblemButtonEl.addEventListener('click', previousProblem);\n nextProblemButtonEl.addEventListener('click', nextProblem);\n\n // Start it up!\n // Load current problem\n const currProb = getCurrentProblem(problems);\n loadProblem(currProb);\n // Initalized test suite with starting failures\n testSuite(true);\n }\n})(document, window);\n"]} \ No newline at end of file diff --git a/public/service-worker.js b/public/service-worker.js index 48fc78c..e2df7b3 100644 --- a/public/service-worker.js +++ b/public/service-worker.js @@ -1,2 +1,2 @@ -"use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}var precacheConfig=[["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","7c1a8058bb3d00c2b40283c735748cfc"],["/dist/js/bundle.min.js","72b4f3c34fac3a128cb74efc7e15d71a"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]],cacheName="sw-precache-v3--"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(e){return e.redirected?("body"in e?Promise.resolve(e.body):e.blob()).then(function(t){return new Response(t,{headers:e.headers,status:e.status,statusText:e.statusText})}):Promise.resolve(e)},createCacheKey=function(e,t,n,r){var a=new URL(e);return r&&a.pathname.match(r)||(a.search+=(a.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),a.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,t){var n=new URL(e);return n.hash="",n.search=n.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),n.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],r=new URL(t,self.location),a=createCacheKey(r,hashParamName,n,!1);return[r.toString(),a]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(n){if(!t.has(n)){var r=new Request(n,{credentials:"same-origin"});return fetch(r).then(function(t){if(!t.ok)throw new Error("Request for "+n+" returned a response with status "+t.status);return cleanResponse(t).then(function(t){return e.put(n,t)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(n){return Promise.all(n.map(function(n){if(!t.has(n.url))return e.delete(n)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,n=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);(t=urlsToCacheKeys.has(n))||(n=addDirectoryIndex(n,"index.html"),t=urlsToCacheKeys.has(n));t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}); +"use strict";function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}var precacheConfig=[["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","7c1a8058bb3d00c2b40283c735748cfc"],["/dist/js/bundle.min.js","d6329d2b9a6a07313555b757df5081d3"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]],cacheName="sw-precache-v3--"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(e){return e.redirected?("body"in e?Promise.resolve(e.body):e.blob()).then(function(t){return new Response(t,{headers:e.headers,status:e.status,statusText:e.statusText})}):Promise.resolve(e)},createCacheKey=function(e,t,n,r){var a=new URL(e);return r&&a.pathname.match(r)||(a.search+=(a.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),a.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,t){var n=new URL(e);return n.hash="",n.search=n.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return t.every(function(t){return!t.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),n.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],r=new URL(t,self.location),a=createCacheKey(r,hashParamName,n,!1);return[r.toString(),a]}));self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(t){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(n){if(!t.has(n)){var r=new Request(n,{credentials:"same-origin"});return fetch(r).then(function(t){if(!t.ok)throw new Error("Request for "+n+" returned a response with status "+t.status);return cleanResponse(t).then(function(t){return e.put(n,t)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var t=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(n){return Promise.all(n.map(function(n){if(!t.has(n.url))return e.delete(n)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var t,n=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching);(t=urlsToCacheKeys.has(n))||(n=addDirectoryIndex(n,"index.html"),t=urlsToCacheKeys.has(n));t&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(t){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,t),fetch(e.request)}))}}); //# sourceMappingURL=service-worker.js.map diff --git a/public/service-worker.js.map b/public/service-worker.js.map index 318e96e..e9cb7a5 100644 --- a/public/service-worker.js.map +++ b/public/service-worker.js.map @@ -1 +1 @@ -{"version":3,"sources":["service-worker.js"],"names":["setOfCachedUrls","cache","keys","then","requests","map","request","url","urls","Set","precacheConfig","cacheName","self","registration","scope","ignoreUrlParametersMatching","addDirectoryIndex","originalUrl","index","URL","pathname","slice","toString","cleanResponse","originalResponse","redirected","Promise","resolve","body","blob","Response","headers","status","statusText","createCacheKey","paramName","paramValue","dontCacheBustUrlsMatching","match","search","encodeURIComponent","isPathWhitelisted","whitelist","absoluteUrlString","length","path","some","whitelistedPathRegex","stripIgnoredUrlParameters","hash","split","kv","filter","every","ignoredRegex","test","join","hashParamName","urlsToCacheKeys","Map","item","relativeUrl","absoluteUrl","location","cacheKey","addEventListener","event","waitUntil","caches","open","cachedUrls","all","Array","from","values","has","Request","credentials","fetch","response","ok","Error","responseToCache","put","skipWaiting","setOfExpectedUrls","existingRequests","existingRequest","delete","clients","claim","method","shouldRespond","respondWith","get","catch","e","console","warn"],"mappings":"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","file":"service-worker.js","sourcesContent":["/**\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n*/\n\n// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY!\n// This file should be overwritten as part of your build process.\n// If you need to extend the behavior of the generated service worker, the best approach is to write\n// additional code and include it using the importScripts option:\n// https://github.com/GoogleChrome/sw-precache#importscripts-arraystring\n//\n// Alternatively, it's possible to make changes to the underlying template file and then use that as the\n// new base for generating output, via the templateFilePath option:\n// https://github.com/GoogleChrome/sw-precache#templatefilepath-string\n//\n// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any\n// changes made to this original template file with your modified copy.\n\n// This generated service worker JavaScript will precache your site's resources.\n// The code needs to be saved in a .js file at the top-level of your site, and registered\n// from your pages in order to be used. See\n// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js\n// for an example of how you can register this script and handle various service worker events.\n\n/* eslint-env worker, serviceworker */\n/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */\n'use strict';\n\nvar precacheConfig = [[\"/dist/css/style.css\",\"ba4d66c91d1ed66848154a34ab4948cf\"],[\"/dist/img/back.svg\",\"898ada2a32ec64bd5b6959c22e8f231d\"],[\"/dist/img/monitor.svg\",\"348592da5567b5a3c46acfb5dcd341bc\"],[\"/dist/img/next.svg\",\"045593410b9f51390e750b9e1e7fff15\"],[\"/dist/img/reload.svg\",\"a0ab1b765280e4d22e6fb747042f6503\"],[\"/dist/img/shuffle.svg\",\"3a5e3c1bf04eb3493d8a2ffa547aa58f\"],[\"/dist/img/social-banner.png\",\"7c1a8058bb3d00c2b40283c735748cfc\"],[\"/dist/js/bundle.min.js\",\"72b4f3c34fac3a128cb74efc7e15d71a\"],[\"/dist/js/loadJS.js\",\"72c55936069f60560a386e46f462c73a\"],[\"/dist/js/sw-registration.js\",\"677217d8e642c1ccff69fc01c96b4431\"],[\"/index.html\",\"c7522a5d3255caca0f12c5282ef0644d\"]];\nvar cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');\n\n\nvar ignoreUrlParametersMatching = [/^utm_/];\n\n\n\nvar addDirectoryIndex = function (originalUrl, index) {\n var url = new URL(originalUrl);\n if (url.pathname.slice(-1) === '/') {\n url.pathname += index;\n }\n return url.toString();\n };\n\nvar cleanResponse = function (originalResponse) {\n // If this is not a redirected response, then we don't have to do anything.\n if (!originalResponse.redirected) {\n return Promise.resolve(originalResponse);\n }\n\n // Firefox 50 and below doesn't support the Response.body stream, so we may\n // need to read the entire body to memory as a Blob.\n var bodyPromise = 'body' in originalResponse ?\n Promise.resolve(originalResponse.body) :\n originalResponse.blob();\n\n return bodyPromise.then(function(body) {\n // new Response() is happy when passed either a stream or a Blob.\n return new Response(body, {\n headers: originalResponse.headers,\n status: originalResponse.status,\n statusText: originalResponse.statusText\n });\n });\n };\n\nvar createCacheKey = function (originalUrl, paramName, paramValue,\n dontCacheBustUrlsMatching) {\n // Create a new URL object to avoid modifying originalUrl.\n var url = new URL(originalUrl);\n\n // If dontCacheBustUrlsMatching is not set, or if we don't have a match,\n // then add in the extra cache-busting URL parameter.\n if (!dontCacheBustUrlsMatching ||\n !(url.pathname.match(dontCacheBustUrlsMatching))) {\n url.search += (url.search ? '&' : '') +\n encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);\n }\n\n return url.toString();\n };\n\nvar isPathWhitelisted = function (whitelist, absoluteUrlString) {\n // If the whitelist is empty, then consider all URLs to be whitelisted.\n if (whitelist.length === 0) {\n return true;\n }\n\n // Otherwise compare each path regex to the path of the URL passed in.\n var path = (new URL(absoluteUrlString)).pathname;\n return whitelist.some(function(whitelistedPathRegex) {\n return path.match(whitelistedPathRegex);\n });\n };\n\nvar stripIgnoredUrlParameters = function (originalUrl,\n ignoreUrlParametersMatching) {\n var url = new URL(originalUrl);\n // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290\n url.hash = '';\n\n url.search = url.search.slice(1) // Exclude initial '?'\n .split('&') // Split into an array of 'key=value' strings\n .map(function(kv) {\n return kv.split('='); // Split each 'key=value' string into a [key, value] array\n })\n .filter(function(kv) {\n return ignoreUrlParametersMatching.every(function(ignoredRegex) {\n return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.\n });\n })\n .map(function(kv) {\n return kv.join('='); // Join each [key, value] array into a 'key=value' string\n })\n .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each\n\n return url.toString();\n };\n\n\nvar hashParamName = '_sw-precache';\nvar urlsToCacheKeys = new Map(\n precacheConfig.map(function(item) {\n var relativeUrl = item[0];\n var hash = item[1];\n var absoluteUrl = new URL(relativeUrl, self.location);\n var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);\n return [absoluteUrl.toString(), cacheKey];\n })\n);\n\nfunction setOfCachedUrls(cache) {\n return cache.keys().then(function(requests) {\n return requests.map(function(request) {\n return request.url;\n });\n }).then(function(urls) {\n return new Set(urls);\n });\n}\n\nself.addEventListener('install', function(event) {\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return setOfCachedUrls(cache).then(function(cachedUrls) {\n return Promise.all(\n Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {\n // If we don't have a key matching url in the cache already, add it.\n if (!cachedUrls.has(cacheKey)) {\n var request = new Request(cacheKey, {credentials: 'same-origin'});\n return fetch(request).then(function(response) {\n // Bail out of installation unless we get back a 200 OK for\n // every request.\n if (!response.ok) {\n throw new Error('Request for ' + cacheKey + ' returned a ' +\n 'response with status ' + response.status);\n }\n\n return cleanResponse(response).then(function(responseToCache) {\n return cache.put(cacheKey, responseToCache);\n });\n });\n }\n })\n );\n });\n }).then(function() {\n \n // Force the SW to transition from installing -> active state\n return self.skipWaiting();\n \n })\n );\n});\n\nself.addEventListener('activate', function(event) {\n var setOfExpectedUrls = new Set(urlsToCacheKeys.values());\n\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return cache.keys().then(function(existingRequests) {\n return Promise.all(\n existingRequests.map(function(existingRequest) {\n if (!setOfExpectedUrls.has(existingRequest.url)) {\n return cache.delete(existingRequest);\n }\n })\n );\n });\n }).then(function() {\n \n return self.clients.claim();\n \n })\n );\n});\n\n\nself.addEventListener('fetch', function(event) {\n if (event.request.method === 'GET') {\n // Should we call event.respondWith() inside this fetch event handler?\n // This needs to be determined synchronously, which will give other fetch\n // handlers a chance to handle the request if need be.\n var shouldRespond;\n\n // First, remove all the ignored parameters and hash fragment, and see if we\n // have that URL in our cache. If so, great! shouldRespond will be true.\n var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);\n shouldRespond = urlsToCacheKeys.has(url);\n\n // If shouldRespond is false, check again, this time with 'index.html'\n // (or whatever the directoryIndex option is set to) at the end.\n var directoryIndex = 'index.html';\n if (!shouldRespond && directoryIndex) {\n url = addDirectoryIndex(url, directoryIndex);\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond is still false, check to see if this is a navigation\n // request, and if so, whether the URL matches navigateFallbackWhitelist.\n var navigateFallback = '';\n if (!shouldRespond &&\n navigateFallback &&\n (event.request.mode === 'navigate') &&\n isPathWhitelisted([], event.request.url)) {\n url = new URL(navigateFallback, self.location).toString();\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond was set to true at any point, then call\n // event.respondWith(), using the appropriate cache key.\n if (shouldRespond) {\n event.respondWith(\n caches.open(cacheName).then(function(cache) {\n return cache.match(urlsToCacheKeys.get(url)).then(function(response) {\n if (response) {\n return response;\n }\n throw Error('The cached response that was expected is missing.');\n });\n }).catch(function(e) {\n // Fall back to just fetch()ing the request if some unexpected error\n // prevented the cached response from being valid.\n console.warn('Couldn\\'t serve response for \"%s\" from cache: %O', event.request.url, e);\n return fetch(event.request);\n })\n );\n }\n }\n});\n\n\n\n\n\n\n\n"]} \ No newline at end of file +{"version":3,"sources":["service-worker.js"],"names":["setOfCachedUrls","cache","keys","then","requests","map","request","url","urls","Set","precacheConfig","cacheName","self","registration","scope","ignoreUrlParametersMatching","addDirectoryIndex","originalUrl","index","URL","pathname","slice","toString","cleanResponse","originalResponse","redirected","Promise","resolve","body","blob","Response","headers","status","statusText","createCacheKey","paramName","paramValue","dontCacheBustUrlsMatching","match","search","encodeURIComponent","isPathWhitelisted","whitelist","absoluteUrlString","length","path","some","whitelistedPathRegex","stripIgnoredUrlParameters","hash","split","kv","filter","every","ignoredRegex","test","join","hashParamName","urlsToCacheKeys","Map","item","relativeUrl","absoluteUrl","location","cacheKey","addEventListener","event","waitUntil","caches","open","cachedUrls","all","Array","from","values","has","Request","credentials","fetch","response","ok","Error","responseToCache","put","skipWaiting","setOfExpectedUrls","existingRequests","existingRequest","delete","clients","claim","method","shouldRespond","respondWith","get","catch","e","console","warn"],"mappings":"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","file":"service-worker.js","sourcesContent":["/**\n * Copyright 2016 Google Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n*/\n\n// DO NOT EDIT THIS GENERATED OUTPUT DIRECTLY!\n// This file should be overwritten as part of your build process.\n// If you need to extend the behavior of the generated service worker, the best approach is to write\n// additional code and include it using the importScripts option:\n// https://github.com/GoogleChrome/sw-precache#importscripts-arraystring\n//\n// Alternatively, it's possible to make changes to the underlying template file and then use that as the\n// new base for generating output, via the templateFilePath option:\n// https://github.com/GoogleChrome/sw-precache#templatefilepath-string\n//\n// If you go that route, make sure that whenever you update your sw-precache dependency, you reconcile any\n// changes made to this original template file with your modified copy.\n\n// This generated service worker JavaScript will precache your site's resources.\n// The code needs to be saved in a .js file at the top-level of your site, and registered\n// from your pages in order to be used. See\n// https://github.com/googlechrome/sw-precache/blob/master/demo/app/js/service-worker-registration.js\n// for an example of how you can register this script and handle various service worker events.\n\n/* eslint-env worker, serviceworker */\n/* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */\n'use strict';\n\nvar precacheConfig = [[\"/dist/css/style.css\",\"ba4d66c91d1ed66848154a34ab4948cf\"],[\"/dist/img/back.svg\",\"898ada2a32ec64bd5b6959c22e8f231d\"],[\"/dist/img/monitor.svg\",\"348592da5567b5a3c46acfb5dcd341bc\"],[\"/dist/img/next.svg\",\"045593410b9f51390e750b9e1e7fff15\"],[\"/dist/img/reload.svg\",\"a0ab1b765280e4d22e6fb747042f6503\"],[\"/dist/img/shuffle.svg\",\"3a5e3c1bf04eb3493d8a2ffa547aa58f\"],[\"/dist/img/social-banner.png\",\"7c1a8058bb3d00c2b40283c735748cfc\"],[\"/dist/js/bundle.min.js\",\"d6329d2b9a6a07313555b757df5081d3\"],[\"/dist/js/loadJS.js\",\"72c55936069f60560a386e46f462c73a\"],[\"/dist/js/sw-registration.js\",\"677217d8e642c1ccff69fc01c96b4431\"],[\"/index.html\",\"c7522a5d3255caca0f12c5282ef0644d\"]];\nvar cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : '');\n\n\nvar ignoreUrlParametersMatching = [/^utm_/];\n\n\n\nvar addDirectoryIndex = function (originalUrl, index) {\n var url = new URL(originalUrl);\n if (url.pathname.slice(-1) === '/') {\n url.pathname += index;\n }\n return url.toString();\n };\n\nvar cleanResponse = function (originalResponse) {\n // If this is not a redirected response, then we don't have to do anything.\n if (!originalResponse.redirected) {\n return Promise.resolve(originalResponse);\n }\n\n // Firefox 50 and below doesn't support the Response.body stream, so we may\n // need to read the entire body to memory as a Blob.\n var bodyPromise = 'body' in originalResponse ?\n Promise.resolve(originalResponse.body) :\n originalResponse.blob();\n\n return bodyPromise.then(function(body) {\n // new Response() is happy when passed either a stream or a Blob.\n return new Response(body, {\n headers: originalResponse.headers,\n status: originalResponse.status,\n statusText: originalResponse.statusText\n });\n });\n };\n\nvar createCacheKey = function (originalUrl, paramName, paramValue,\n dontCacheBustUrlsMatching) {\n // Create a new URL object to avoid modifying originalUrl.\n var url = new URL(originalUrl);\n\n // If dontCacheBustUrlsMatching is not set, or if we don't have a match,\n // then add in the extra cache-busting URL parameter.\n if (!dontCacheBustUrlsMatching ||\n !(url.pathname.match(dontCacheBustUrlsMatching))) {\n url.search += (url.search ? '&' : '') +\n encodeURIComponent(paramName) + '=' + encodeURIComponent(paramValue);\n }\n\n return url.toString();\n };\n\nvar isPathWhitelisted = function (whitelist, absoluteUrlString) {\n // If the whitelist is empty, then consider all URLs to be whitelisted.\n if (whitelist.length === 0) {\n return true;\n }\n\n // Otherwise compare each path regex to the path of the URL passed in.\n var path = (new URL(absoluteUrlString)).pathname;\n return whitelist.some(function(whitelistedPathRegex) {\n return path.match(whitelistedPathRegex);\n });\n };\n\nvar stripIgnoredUrlParameters = function (originalUrl,\n ignoreUrlParametersMatching) {\n var url = new URL(originalUrl);\n // Remove the hash; see https://github.com/GoogleChrome/sw-precache/issues/290\n url.hash = '';\n\n url.search = url.search.slice(1) // Exclude initial '?'\n .split('&') // Split into an array of 'key=value' strings\n .map(function(kv) {\n return kv.split('='); // Split each 'key=value' string into a [key, value] array\n })\n .filter(function(kv) {\n return ignoreUrlParametersMatching.every(function(ignoredRegex) {\n return !ignoredRegex.test(kv[0]); // Return true iff the key doesn't match any of the regexes.\n });\n })\n .map(function(kv) {\n return kv.join('='); // Join each [key, value] array into a 'key=value' string\n })\n .join('&'); // Join the array of 'key=value' strings into a string with '&' in between each\n\n return url.toString();\n };\n\n\nvar hashParamName = '_sw-precache';\nvar urlsToCacheKeys = new Map(\n precacheConfig.map(function(item) {\n var relativeUrl = item[0];\n var hash = item[1];\n var absoluteUrl = new URL(relativeUrl, self.location);\n var cacheKey = createCacheKey(absoluteUrl, hashParamName, hash, false);\n return [absoluteUrl.toString(), cacheKey];\n })\n);\n\nfunction setOfCachedUrls(cache) {\n return cache.keys().then(function(requests) {\n return requests.map(function(request) {\n return request.url;\n });\n }).then(function(urls) {\n return new Set(urls);\n });\n}\n\nself.addEventListener('install', function(event) {\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return setOfCachedUrls(cache).then(function(cachedUrls) {\n return Promise.all(\n Array.from(urlsToCacheKeys.values()).map(function(cacheKey) {\n // If we don't have a key matching url in the cache already, add it.\n if (!cachedUrls.has(cacheKey)) {\n var request = new Request(cacheKey, {credentials: 'same-origin'});\n return fetch(request).then(function(response) {\n // Bail out of installation unless we get back a 200 OK for\n // every request.\n if (!response.ok) {\n throw new Error('Request for ' + cacheKey + ' returned a ' +\n 'response with status ' + response.status);\n }\n\n return cleanResponse(response).then(function(responseToCache) {\n return cache.put(cacheKey, responseToCache);\n });\n });\n }\n })\n );\n });\n }).then(function() {\n \n // Force the SW to transition from installing -> active state\n return self.skipWaiting();\n \n })\n );\n});\n\nself.addEventListener('activate', function(event) {\n var setOfExpectedUrls = new Set(urlsToCacheKeys.values());\n\n event.waitUntil(\n caches.open(cacheName).then(function(cache) {\n return cache.keys().then(function(existingRequests) {\n return Promise.all(\n existingRequests.map(function(existingRequest) {\n if (!setOfExpectedUrls.has(existingRequest.url)) {\n return cache.delete(existingRequest);\n }\n })\n );\n });\n }).then(function() {\n \n return self.clients.claim();\n \n })\n );\n});\n\n\nself.addEventListener('fetch', function(event) {\n if (event.request.method === 'GET') {\n // Should we call event.respondWith() inside this fetch event handler?\n // This needs to be determined synchronously, which will give other fetch\n // handlers a chance to handle the request if need be.\n var shouldRespond;\n\n // First, remove all the ignored parameters and hash fragment, and see if we\n // have that URL in our cache. If so, great! shouldRespond will be true.\n var url = stripIgnoredUrlParameters(event.request.url, ignoreUrlParametersMatching);\n shouldRespond = urlsToCacheKeys.has(url);\n\n // If shouldRespond is false, check again, this time with 'index.html'\n // (or whatever the directoryIndex option is set to) at the end.\n var directoryIndex = 'index.html';\n if (!shouldRespond && directoryIndex) {\n url = addDirectoryIndex(url, directoryIndex);\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond is still false, check to see if this is a navigation\n // request, and if so, whether the URL matches navigateFallbackWhitelist.\n var navigateFallback = '';\n if (!shouldRespond &&\n navigateFallback &&\n (event.request.mode === 'navigate') &&\n isPathWhitelisted([], event.request.url)) {\n url = new URL(navigateFallback, self.location).toString();\n shouldRespond = urlsToCacheKeys.has(url);\n }\n\n // If shouldRespond was set to true at any point, then call\n // event.respondWith(), using the appropriate cache key.\n if (shouldRespond) {\n event.respondWith(\n caches.open(cacheName).then(function(cache) {\n return cache.match(urlsToCacheKeys.get(url)).then(function(response) {\n if (response) {\n return response;\n }\n throw Error('The cached response that was expected is missing.');\n });\n }).catch(function(e) {\n // Fall back to just fetch()ing the request if some unexpected error\n // prevented the cached response from being valid.\n console.warn('Couldn\\'t serve response for \"%s\" from cache: %O', event.request.url, e);\n return fetch(event.request);\n })\n );\n }\n }\n});\n\n\n\n\n\n\n\n"]} \ No newline at end of file diff --git a/src/js/index.js b/src/js/index.js index 9188d0f..88af32b 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -314,11 +314,7 @@ let testOutcome = false; try { if (output) { - // const testEval = eval(test.test); - testOutcome = eval(test.test); - console.log('testOutcome:', testOutcome); - } printAssertError(null); } catch (err) { diff --git a/src/service-worker.js b/src/service-worker.js index 7cb47e2..b3f5aec 100644 --- a/src/service-worker.js +++ b/src/service-worker.js @@ -37,7 +37,7 @@ /* eslint-disable indent, no-unused-vars, no-multiple-empty-lines, max-nested-callbacks, space-before-function-paren, quotes, comma-spacing */ 'use strict'; -var precacheConfig = [["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","7c1a8058bb3d00c2b40283c735748cfc"],["/dist/js/bundle.min.js","72b4f3c34fac3a128cb74efc7e15d71a"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]]; +var precacheConfig = [["/dist/css/style.css","ba4d66c91d1ed66848154a34ab4948cf"],["/dist/img/back.svg","898ada2a32ec64bd5b6959c22e8f231d"],["/dist/img/monitor.svg","348592da5567b5a3c46acfb5dcd341bc"],["/dist/img/next.svg","045593410b9f51390e750b9e1e7fff15"],["/dist/img/reload.svg","a0ab1b765280e4d22e6fb747042f6503"],["/dist/img/shuffle.svg","3a5e3c1bf04eb3493d8a2ffa547aa58f"],["/dist/img/social-banner.png","7c1a8058bb3d00c2b40283c735748cfc"],["/dist/js/bundle.min.js","d6329d2b9a6a07313555b757df5081d3"],["/dist/js/loadJS.js","72c55936069f60560a386e46f462c73a"],["/dist/js/sw-registration.js","677217d8e642c1ccff69fc01c96b4431"],["/index.html","c7522a5d3255caca0f12c5282ef0644d"]]; var cacheName = 'sw-precache-v3--' + (self.registration ? self.registration.scope : ''); From 495a3e8edd11c132f583a1fe46e27235e25826ad Mon Sep 17 00:00:00 2001 From: Jakob Anderson Date: Fri, 2 Jun 2017 23:46:22 -0600 Subject: [PATCH 8/8] 1.1.2 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index bf47078..f286b52 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "javascript-practice", - "version": "1.1.1", + "version": "1.1.2", "lockfileVersion": 1, "dependencies": { "@ava/babel-preset-stage-4": { diff --git a/package.json b/package.json index b0b826c..02012ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "javascript-practice", - "version": "1.1.1", + "version": "1.1.2", "description": "practice javascript", "main": "index.js", "engines": {