From a8b9b2b49a4a0ca65dc262235788cb8a7dddaa30 Mon Sep 17 00:00:00 2001 From: Rodrigo Fernandes Date: Sun, 6 Oct 2019 21:04:33 +0100 Subject: [PATCH] refactor: Initial migration to typescript --- .circleci/config.yml | 9 +- .eslintignore | 13 +- .eslintrc.json | 332 +- .gitignore | 5 + dist/diff2html-ui.js | 366 -- dist/diff2html-ui.min.js | 1 - dist/diff2html.css | 367 -- dist/diff2html.d.ts | 71 - dist/diff2html.js | 4782 ----------------- dist/diff2html.min.css | 1 - dist/diff2html.min.js | 1 - docs/CNAME | 1 - docs/assets | 1 - docs/demo.html | 255 - docs/demo.js | 769 --- docs/demo.min.js | 1 - docs/favicon.ico | Bin 4682 -> 0 bytes docs/img/snapshot-1.png | Bin 94098 -> 0 bytes docs/img/snapshot-2.png | Bin 74351 -> 0 bytes docs/img/snapshot-3.png | Bin 123928 -> 0 bytes docs/index.html | 433 -- docs/main.css | 564 -- docs/main.min.css | 4 - docs/robots.txt | 1 - docs/sitemap.xml | 16 - jest.config.js | 15 + package.json | 59 +- scripts/hulk.js | 155 +- scripts/release-browser-bundle.sh | 36 + scripts/release-css.sh | 25 + scripts/release-templates.sh | 10 + scripts/release-website.js | 57 +- scripts/release-website.sh | 23 +- scripts/release.sh | 57 - src/__tests__/diff-parser-tests.js | 728 +++ {test => src/__tests__}/diff2html-tests.js | 547 +- .../__tests__}/file-list-printer-tests.js | 186 +- src/__tests__/hogan-cache-tests.js | 73 + {test => src/__tests__}/line-by-line-tests.js | 584 +- src/__tests__/printer-utils-tests.js | 126 + .../__tests__}/side-by-side-printer-tests.js | 455 +- src/__tests__/utils-tests.js | 23 + src/diff-parser.js | 177 +- src/diff2html.d.ts | 11 +- src/diff2html.js | 59 +- src/file-list-printer.js | 47 +- src/hoganjs-utils.js | 32 +- src/html-printer.js | 15 +- src/line-by-line-printer.js | 289 +- src/printer-utils.js | 150 +- src/rematch.js | 64 +- src/side-by-side-printer.js | 290 +- src/templates/diff2html-templates.js | 23 - src/ui/js/diff2html-ui.js | 142 +- src/ui/js/highlight.js-internals.js | 40 +- src/utils.js | 26 +- test/diff-parser-tests.js | 743 --- test/hogan-cache-tests.js | 70 - test/printer-utils-tests.js | 140 - test/utils-tests.js | 25 - tsconfig.json | 28 + website/templates/pages/demo/demo.js | 186 +- yarn.lock | 2618 +++++++-- 63 files changed, 5197 insertions(+), 11130 deletions(-) delete mode 100644 dist/diff2html-ui.js delete mode 100644 dist/diff2html-ui.min.js delete mode 100644 dist/diff2html.css delete mode 100644 dist/diff2html.d.ts delete mode 100644 dist/diff2html.js delete mode 100644 dist/diff2html.min.css delete mode 100644 dist/diff2html.min.js delete mode 100644 docs/CNAME delete mode 120000 docs/assets delete mode 100644 docs/demo.html delete mode 100644 docs/demo.js delete mode 100644 docs/demo.min.js delete mode 100644 docs/favicon.ico delete mode 100644 docs/img/snapshot-1.png delete mode 100644 docs/img/snapshot-2.png delete mode 100644 docs/img/snapshot-3.png delete mode 100644 docs/index.html delete mode 100644 docs/main.css delete mode 100644 docs/main.min.css delete mode 100644 docs/robots.txt delete mode 100644 docs/sitemap.xml create mode 100644 jest.config.js create mode 100755 scripts/release-browser-bundle.sh create mode 100755 scripts/release-css.sh create mode 100755 scripts/release-templates.sh delete mode 100755 scripts/release.sh create mode 100644 src/__tests__/diff-parser-tests.js rename {test => src/__tests__}/diff2html-tests.js (60%) rename {test => src/__tests__}/file-list-printer-tests.js (53%) create mode 100644 src/__tests__/hogan-cache-tests.js rename {test => src/__tests__}/line-by-line-tests.js (54%) create mode 100644 src/__tests__/printer-utils-tests.js rename {test => src/__tests__}/side-by-side-printer-tests.js (52%) create mode 100644 src/__tests__/utils-tests.js delete mode 100644 src/templates/diff2html-templates.js delete mode 100644 test/diff-parser-tests.js delete mode 100644 test/hogan-cache-tests.js delete mode 100644 test/printer-utils-tests.js delete mode 100644 test/utils-tests.js create mode 100644 tsconfig.json diff --git a/.circleci/config.yml b/.circleci/config.yml index 56d463f..e29e513 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -29,14 +29,14 @@ jobs: key: dependency-cache-{{ checksum "yarn.lock" }} paths: - ./node_modules - - run: yarn run test - run: yarn run lint + - run: yarn run coverage - run: yarn run codacy - persist_to_workspace: root: ~/diff2html paths: - docs - - dist + - build build-node_4: <<: *common-build @@ -80,11 +80,6 @@ jobs: steps: - attach_workspace: at: . - - run: - name: Prepare website sources - command: | - rm -f docs/assets - mv dist docs/assets - run: name: Deploy working_directory: ~/diff2html/docs diff --git a/.eslintignore b/.eslintignore index 74776ac..256e583 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,11 +1,6 @@ -# Skip coverage and build folders +# Skip build results coverage/** -dist/** - -# Ignore symlink to build folder +build/** docs/** - -# Ignore HTML templates generated code -src/** -!src/*.js -!src/ui/js/*.js +node_modules/** +src/diff2html-templates.js diff --git a/.eslintrc.json b/.eslintrc.json index 0096a89..2ab5590 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,10 +1,12 @@ { + "parser": "@typescript-eslint/parser", "parserOptions": { - "ecmaVersion": 6, + "ecmaVersion": 2018, + "sourceType": "module", "ecmaFeatures": { + "experimentalObjectRestSpread": true, "jsx": true - }, - "sourceType": "module" + } }, "env": { "es6": true, @@ -19,325 +21,17 @@ "worker": true, "qunit": true }, - "plugins": [ - "standard", - "promise" - ], + "plugins": ["standard", "node", "import", "promise", "@typescript-eslint", "jest"], "globals": { "document": false, "navigator": false, "window": false }, - "rules": { - "accessor-pairs": 2, - "arrow-spacing": [ - 2, - { - "before": true, - "after": true - } - ], - "block-spacing": [ - 2, - "always" - ], - "brace-style": [ - 2, - "1tbs", - { - "allowSingleLine": true - } - ], - "camelcase": [ - 2, - { - "properties": "never" - } - ], - "comma-dangle": [ - 2, - "never" - ], - "comma-spacing": [ - 2, - { - "before": false, - "after": true - } - ], - "comma-style": [ - 2, - "last" - ], - "constructor-super": 2, - "curly": [ - 2, - "multi-line" - ], - "dot-location": [ - 2, - "property" - ], - "eol-last": 2, - "eqeqeq": [ - 2, - "allow-null" - ], - "generator-star-spacing": [ - 2, - { - "before": true, - "after": true - } - ], - "handle-callback-err": [ - 2, - "^(err|error)$" - ], - "indent": [ - 2, - 2, - { - "SwitchCase": 1 - } - ], - "jsx-quotes": [ - 2, - "prefer-single" - ], - "key-spacing": [ - 2, - { - "beforeColon": false, - "afterColon": true - } - ], - "keyword-spacing": [ - 2, - { - "before": true, - "after": true - } - ], - "new-cap": [ - 2, - { - "newIsCap": true, - "capIsNew": false - } - ], - "new-parens": 2, - "no-array-constructor": 2, - "no-caller": 2, - "no-class-assign": 2, - "no-cond-assign": 2, - "no-const-assign": 2, - "no-control-regex": 2, - "no-debugger": 2, - "no-delete-var": 2, - "no-dupe-args": 2, - "no-dupe-class-members": 2, - "no-dupe-keys": 2, - "no-duplicate-case": 2, - "no-duplicate-imports": 2, - "no-empty-character-class": 2, - "no-empty-pattern": 2, - "no-eval": 2, - "no-ex-assign": 2, - "no-extend-native": 2, - "no-extra-bind": 2, - "no-extra-boolean-cast": 2, - "no-extra-parens": [ - 2, - "functions" - ], - "no-fallthrough": 2, - "no-floating-decimal": 2, - "no-func-assign": 2, - "no-implied-eval": 2, - "no-inner-declarations": [ - 2, - "functions" - ], - "no-invalid-regexp": 2, - "no-irregular-whitespace": 2, - "no-iterator": 2, - "no-label-var": 2, - "no-labels": [ - 2, - { - "allowLoop": false, - "allowSwitch": false - } - ], - "no-lone-blocks": 2, - "no-mixed-spaces-and-tabs": 2, - "no-multi-spaces": 2, - "no-multi-str": 2, - "no-multiple-empty-lines": [ - 2, - { - "max": 1 - } - ], - "no-native-reassign": 2, - "no-negated-in-lhs": 2, - "no-new": 2, - "no-new-func": 2, - "no-new-object": 2, - "no-new-require": 2, - "no-new-symbol": 2, - "no-new-wrappers": 2, - "no-obj-calls": 2, - "no-octal": 2, - "no-octal-escape": 2, - "no-path-concat": 2, - "no-proto": 2, - "no-redeclare": 2, - "no-regex-spaces": 2, - "no-return-assign": [ - 2, - "except-parens" - ], - "no-self-assign": 2, - "no-self-compare": 2, - "no-sequences": 2, - "no-shadow-restricted-names": 2, - "no-spaced-func": 2, - "no-sparse-arrays": 2, - "no-this-before-super": 2, - "no-throw-literal": 2, - "no-trailing-spaces": 2, - "no-undef": 2, - "no-undef-init": 2, - "no-unexpected-multiline": 2, - "no-unmodified-loop-condition": 2, - "no-unneeded-ternary": [ - 2, - { - "defaultAssignment": false - } - ], - "no-unreachable": 2, - "no-unsafe-finally": 2, - "no-unused-vars": [ - 2, - { - "vars": "all", - "args": "none" - } - ], - "no-useless-call": 2, - "no-useless-computed-key": 2, - "no-useless-constructor": 2, - "no-useless-escape": 2, - "no-whitespace-before-property": 2, - "no-with": 2, - "one-var": [ - 2, - { - "initialized": "never" - } - ], - "operator-linebreak": [ - 2, - "after", - { - "overrides": { - "?": "before", - ":": "before" - } - } - ], - "padded-blocks": [ - 2, - "never" - ], - "quotes": [ - 2, - "single", - "avoid-escape" - ], - "semi": [ - 2, - "always" - ], - "semi-spacing": [ - 2, - { - "before": false, - "after": true - } - ], - "space-before-blocks": [ - 2, - "always" - ], - "space-before-function-paren": [ - 2, - "never" - ], - "space-in-parens": [ - 2, - "never" - ], - "space-infix-ops": 2, - "space-unary-ops": [ - 2, - { - "words": true, - "nonwords": false - } - ], - "spaced-comment": [ - 2, - "always", - { - "markers": [ - "global", - "globals", - "eslint", - "eslint-disable", - "*package", - "!", - "," - ] - } - ], - "template-curly-spacing": [ - 2, - "never" - ], - "use-isnan": 2, - "valid-typeof": 2, - "wrap-iife": [ - 2, - "any" - ], - "yield-star-spacing": [ - 2, - "both" - ], - "yoda": [ - 2, - "never" - ], - "standard/object-curly-even-spacing": [ - 2, - "either" - ], - "standard/array-bracket-even-spacing": [ - 2, - "either" - ], - "standard/computed-property-even-spacing": [ - 2, - "even" - ], - "promise/param-names": 2, - "linebreak-style": [ - 2, - "unix" - ] - } + "extends": [ + "plugin:@typescript-eslint/recommended", + "plugin:jest/recommended", + "plugin:promise/recommended", + "standard", + "plugin:prettier/recommended" + ] } diff --git a/.gitignore b/.gitignore index bde6b2f..05edf8a 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,8 @@ bower_components/ # Terraform /terraform/.terraform + +/docs/ +/dist/ +/build/ +/src/diff2html-templates.js diff --git a/dist/diff2html-ui.js b/dist/diff2html-ui.js deleted file mode 100644 index 7885e25..0000000 --- a/dist/diff2html-ui.js +++ /dev/null @@ -1,366 +0,0 @@ -(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i/gm, '>'); - } - - function tag(node) { - return node.nodeName.toLowerCase(); - } - - /* Stream merging */ - - HighlightJS.prototype.nodeStream = function(node) { - var result = []; - (function _nodeStream(node, offset) { - for (var child = node.firstChild; child; child = child.nextSibling) { - if (child.nodeType === 3) { - offset += child.nodeValue.length; - } else if (child.nodeType === 1) { - result.push({ - event: 'start', - offset: offset, - node: child - }); - offset = _nodeStream(child, offset); - // Prevent void elements from having an end tag that would actually - // double them in the output. There are more void elements in HTML - // but we list only those realistically expected in code display. - if (!tag(child).match(/br|hr|img|input/)) { - result.push({ - event: 'stop', - offset: offset, - node: child - }); - } - } - } - return offset; - })(node, 0); - return result; - }; - - HighlightJS.prototype.mergeStreams = function(original, highlighted, value) { - var processed = 0; - var result = ''; - var nodeStack = []; - - function selectStream() { - if (!original.length || !highlighted.length) { - return original.length ? original : highlighted; - } - if (original[0].offset !== highlighted[0].offset) { - return (original[0].offset < highlighted[0].offset) ? original : highlighted; - } - - /* - To avoid starting the stream just before it should stop the order is - ensured that original always starts first and closes last: - if (event1 == 'start' && event2 == 'start') - return original; - if (event1 == 'start' && event2 == 'stop') - return highlighted; - if (event1 == 'stop' && event2 == 'start') - return original; - if (event1 == 'stop' && event2 == 'stop') - return highlighted; - ... which is collapsed to: - */ - return highlighted[0].event === 'start' ? original : highlighted; - } - - function open(node) { - function attr_str(a) { - return ' ' + a.nodeName + '="' + escape(a.value) + '"'; - } - - result += '<' + tag(node) + ArrayProto.map.call(node.attributes, attr_str).join('') + '>'; - } - - function close(node) { - result += ''; - } - - function render(event) { - (event.event === 'start' ? open : close)(event.node); - } - - while (original.length || highlighted.length) { - var stream = selectStream(); - result += escape(value.substring(processed, stream[0].offset)); - processed = stream[0].offset; - if (stream === original) { - /* - On any opening or closing tag of the original markup we first close - the entire highlighted node stack, then render the original tag along - with all the following original tags at the same offset and then - reopen all the tags on the highlighted stack. - */ - nodeStack.reverse().forEach(close); - do { - render(stream.splice(0, 1)[0]); - stream = selectStream(); - } while (stream === original && stream.length && stream[0].offset === processed); - nodeStack.reverse().forEach(open); - } else { - if (stream[0].event === 'start') { - nodeStack.push(stream[0].node); - } else { - nodeStack.pop(); - } - render(stream.splice(0, 1)[0]); - } - } - return result + escape(value.substr(processed)); - }; - - /* **** Highlight.js Private API **** */ - - module.exports.HighlightJS = new HighlightJS(); -})(); - -},{}]},{},[1]); diff --git a/dist/diff2html-ui.min.js b/dist/diff2html-ui.min.js deleted file mode 100644 index 02c14af..0000000 --- a/dist/diff2html-ui.min.js +++ /dev/null @@ -1 +0,0 @@ -!function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){return o(e[i][1][r]||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i/gm,">")}function tag(node){return node.nodeName.toLowerCase()}var ArrayProto;ArrayProto=[],HighlightJS.prototype.nodeStream=function(node){var result=[];return function _nodeStream(node,offset){for(var child=node.firstChild;child;child=child.nextSibling)3===child.nodeType?offset+=child.nodeValue.length:1===child.nodeType&&(result.push({event:"start",offset:offset,node:child}),offset=_nodeStream(child,offset),tag(child).match(/br|hr|img|input/)||result.push({event:"stop",offset:offset,node:child}));return offset}(node,0),result},HighlightJS.prototype.mergeStreams=function(original,highlighted,value){var processed=0,result="",nodeStack=[];function selectStream(){return original.length&&highlighted.length?original[0].offset!==highlighted[0].offset?original[0].offset"}function close(node){result+=""}function render(event){("start"===event.event?open:close)(event.node)}for(;original.length||highlighted.length;){var stream=selectStream();if(result+=escape(value.substring(processed,stream[0].offset)),processed=stream[0].offset,stream===original){for(nodeStack.reverse().forEach(close);render(stream.splice(0,1)[0]),(stream=selectStream())===original&&stream.length&&stream[0].offset===processed;);nodeStack.reverse().forEach(open)}else"start"===stream[0].event?nodeStack.push(stream[0].node):nodeStack.pop(),render(stream.splice(0,1)[0])}return result+escape(value.substr(processed))},module.exports.HighlightJS=new HighlightJS},{}]},{},[1]); \ No newline at end of file diff --git a/dist/diff2html.css b/dist/diff2html.css deleted file mode 100644 index 196719a..0000000 --- a/dist/diff2html.css +++ /dev/null @@ -1,367 +0,0 @@ -/* - * - * Diff to HTML (diff2html.css) - * Author: rtfpessoa - * - */ - -.d2h-wrapper { - text-align: left; -} - -.d2h-file-header { - height: 35px; - padding: 5px 10px; - border-bottom: 1px solid #d8d8d8; - background-color: #f7f7f7; -} - -.d2h-file-stats { - display: flex; - margin-left: auto; - font-size: 14px; -} - -.d2h-lines-added { - text-align: right; - border: 1px solid #b4e2b4; - border-radius: 5px 0 0 5px; - color: #399839; - padding: 2px; - vertical-align: middle; -} - -.d2h-lines-deleted { - text-align: left; - border: 1px solid #e9aeae; - border-radius: 0 5px 5px 0; - color: #c33; - padding: 2px; - vertical-align: middle; - margin-left: 1px; -} - -.d2h-file-name-wrapper { - display: flex; - align-items: center; - width: 100%; - font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 15px; -} - -.d2h-file-name { - white-space: nowrap; - text-overflow: ellipsis; - overflow-x: hidden; -} - -.d2h-file-wrapper { - border: 1px solid #ddd; - border-radius: 3px; - margin-bottom: 1em; -} - -.d2h-diff-table { - width: 100%; - border-collapse: collapse; - font-family: "Menlo", "Consolas", monospace; - font-size: 13px; -} - -.d2h-files-diff { - display: block; - width: 100%; - height: 100%; -} - -.d2h-file-diff { - overflow-y: hidden; -} - -.d2h-file-side-diff { - display: inline-block; - overflow-x: scroll; - overflow-y: hidden; - width: 50%; - margin-right: -4px; - margin-bottom: -8px; -} - -.d2h-code-line { - display: inline-block; - white-space: nowrap; - /* Compensate for the absolute positioning of the line numbers */ - padding: 0 8em; -} - -.d2h-code-side-line { - display: inline-block; - white-space: nowrap; - /* Compensate for the absolute positioning of the line numbers */ - padding: 0 4.5em; -} - -.d2h-code-line del, -.d2h-code-side-line del { - display: inline-block; - margin-top: -1px; - text-decoration: none; - background-color: #ffb6ba; - border-radius: 0.2em; -} - -.d2h-code-line ins, -.d2h-code-side-line ins { - display: inline-block; - margin-top: -1px; - text-decoration: none; - background-color: #97f295; - border-radius: 0.2em; - text-align: left; -} - -.d2h-code-line-prefix { - display: inline; - background: none; - padding: 0; - word-wrap: normal; - white-space: pre; -} - -.d2h-code-line-ctn { - display: inline; - background: none; - padding: 0; - word-wrap: normal; - white-space: pre; -} - -.line-num1 { - box-sizing: border-box; - float: left; - width: 3.5em; - overflow: hidden; - text-overflow: ellipsis; - padding: 0 0.5em 0 0.5em; -} - -.line-num2 { - box-sizing: border-box; - float: right; - width: 3.5em; - overflow: hidden; - text-overflow: ellipsis; - padding: 0 0.5em 0 0.5em; -} - -.d2h-code-linenumber { - box-sizing: border-box; - width: 7.5em; - /* Keep the numbers fixed on line contents scroll */ - position: absolute; - display: inline-block; - background-color: #fff; - color: rgba(0, 0, 0, 0.3); - text-align: right; - border: solid #eeeeee; - border-width: 0 1px 0 1px; - cursor: pointer; -} - -.d2h-code-linenumber:after { - content: '\200b'; -} - -.d2h-code-side-linenumber { - /* Keep the numbers fixed on line contents scroll */ - position: absolute; - display: inline-block; - box-sizing: border-box; - width: 4em; - background-color: #fff; - color: rgba(0, 0, 0, 0.3); - text-align: right; - border: solid #eeeeee; - border-width: 0 1px 0 1px; - cursor: pointer; - overflow: hidden; - text-overflow: ellipsis; -} - -.d2h-code-side-linenumber:after { - content: '\200b'; -} - -.d2h-code-side-emptyplaceholder, -.d2h-emptyplaceholder { - background-color: #f1f1f1; - border-color: #e1e1e1; -} - -/* - * Changes Highlight - */ - -.d2h-del { - background-color: #fee8e9; - border-color: #e9aeae; -} - -.d2h-ins { - background-color: #dfd; - border-color: #b4e2b4; -} - -.d2h-info { - background-color: #f8fafd; - color: rgba(0, 0, 0, 0.3); - border-color: #d5e4f2; -} - -.d2h-file-diff .d2h-del.d2h-change { - background-color: #fdf2d0; -} - -.d2h-file-diff .d2h-ins.d2h-change { - background-color: #ded; -} - -/* - * File Summary List - */ - -.d2h-file-list-wrapper { - margin-bottom: 10px; -} - -.d2h-file-list-wrapper a { - text-decoration: none; - color: #3572b0; -} - -.d2h-file-list-wrapper a:visited { - color: #3572b0; -} - -.d2h-file-list-header { - text-align: left; -} - -.d2h-file-list-title { - font-weight: bold; -} - -.d2h-file-list-line { - display: flex; - text-align: left; -} - -.d2h-file-list { - display: block; - list-style: none; - padding: 0; - margin: 0; -} - -.d2h-file-list > li { - border-bottom: #ddd solid 1px; - padding: 5px 10px; - margin: 0; -} - -.d2h-file-list > li:last-child { - border-bottom: none; -} - -.d2h-file-switch { - display: none; - font-size: 10px; - cursor: pointer; -} - -.d2h-icon { - vertical-align: middle; - margin-right: 10px; - fill: currentColor; -} - -.d2h-deleted { - color: #c33; -} - -.d2h-added { - color: #399839; -} - -.d2h-changed { - color: #d0b44c; -} - -.d2h-moved { - color: #3572b0; -} - -.d2h-tag { - display: flex; - font-size: 10px; - margin-left: 5px; - padding: 0 2px; - background-color: #fff; -} - -.d2h-deleted-tag { - border: #c33 1px solid; -} - -.d2h-added-tag { - border: #399839 1px solid; -} - -.d2h-changed-tag { - border: #d0b44c 1px solid; -} - -.d2h-moved-tag { - border: #3572b0 1px solid; -} - -/* - * Selection util. - */ - -.selecting-left .d2h-code-line, -.selecting-left .d2h-code-line *, -.selecting-right td.d2h-code-linenumber, -.selecting-right td.d2h-code-linenumber *, -.selecting-left .d2h-code-side-line, -.selecting-left .d2h-code-side-line *, -.selecting-right td.d2h-code-side-linenumber, -.selecting-right td.d2h-code-side-linenumber * { - -webkit-touch-callout: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.selecting-left .d2h-code-line::-moz-selection, -.selecting-left .d2h-code-line *::-moz-selection, -.selecting-right td.d2h-code-linenumber::-moz-selection, -.selecting-left .d2h-code-side-line::-moz-selection, -.selecting-left .d2h-code-side-line *::-moz-selection, -.selecting-right td.d2h-code-side-linenumber::-moz-selection, -.selecting-right td.d2h-code-side-linenumber *::-moz-selection { - background: transparent; -} - -.selecting-left .d2h-code-line::selection, -.selecting-left .d2h-code-line *::selection, -.selecting-right td.d2h-code-linenumber::selection, -.selecting-left .d2h-code-side-line::selection, -.selecting-left .d2h-code-side-line *::selection, -.selecting-right td.d2h-code-side-linenumber::selection, -.selecting-right td.d2h-code-side-linenumber *::selection { - background: transparent; -} - -/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy91aS9jc3MvZGlmZjJodG1sLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7RUFLRTs7QUFFRjtFQUNFLGdCQUFnQjtBQUNsQjs7QUFFQTtFQUNFLFlBQVk7RUFDWixpQkFBaUI7RUFDakIsZ0NBQWdDO0VBQ2hDLHlCQUF5QjtBQUMzQjs7QUFFQTtFQUdFLGFBQWE7RUFDYixpQkFBaUI7RUFDakIsZUFBZTtBQUNqQjs7QUFFQTtFQUNFLGlCQUFpQjtFQUNqQix5QkFBeUI7RUFDekIsMEJBQTBCO0VBQzFCLGNBQWM7RUFDZCxZQUFZO0VBQ1osc0JBQXNCO0FBQ3hCOztBQUVBO0VBQ0UsZ0JBQWdCO0VBQ2hCLHlCQUF5QjtFQUN6QiwwQkFBMEI7RUFDMUIsV0FBVztFQUNYLFlBQVk7RUFDWixzQkFBc0I7RUFDdEIsZ0JBQWdCO0FBQ2xCOztBQUVBO0VBR0UsYUFBYTtFQUdiLG1CQUFtQjtFQUNuQixXQUFXO0VBQ1gsOEVBQThFO0VBQzlFLGVBQWU7QUFDakI7O0FBRUE7RUFDRSxtQkFBbUI7RUFDbkIsdUJBQXVCO0VBQ3ZCLGtCQUFrQjtBQUNwQjs7QUFFQTtFQUNFLHNCQUFzQjtFQUN0QixrQkFBa0I7RUFDbEIsa0JBQWtCO0FBQ3BCOztBQUVBO0VBQ0UsV0FBVztFQUNYLHlCQUF5QjtFQUN6QiwyQ0FBMkM7RUFDM0MsZUFBZTtBQUNqQjs7QUFFQTtFQUNFLGNBQWM7RUFDZCxXQUFXO0VBQ1gsWUFBWTtBQUNkOztBQUVBO0VBQ0Usa0JBQWtCO0FBQ3BCOztBQUVBO0VBQ0UscUJBQXFCO0VBQ3JCLGtCQUFrQjtFQUNsQixrQkFBa0I7RUFDbEIsVUFBVTtFQUNWLGtCQUFrQjtFQUNsQixtQkFBbUI7QUFDckI7O0FBRUE7RUFDRSxxQkFBcUI7RUFDckIsbUJBQW1CO0VBQ25CLGdFQUFnRTtFQUNoRSxjQUFjO0FBQ2hCOztBQUVBO0VBQ0UscUJBQXFCO0VBQ3JCLG1CQUFtQjtFQUNuQixnRUFBZ0U7RUFDaEUsZ0JBQWdCO0FBQ2xC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Q25COztBQUVBOzs7Ozs7O0VBT0UsdUJBQXVCO0FBQ3pCOztBQUVBOzs7Ozs7O0VBT0UsdUJBQXVCO0FBQ3pCIiwiZmlsZSI6ImRpZmYyaHRtbC5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICpcbiAqIERpZmYgdG8gSFRNTCAoZGlmZjJodG1sLmNzcylcbiAqIEF1dGhvcjogcnRmcGVzc29hXG4gKlxuICovXG5cbi5kMmgtd3JhcHBlciB7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG59XG5cbi5kMmgtZmlsZS1oZWFkZXIge1xuICBoZWlnaHQ6IDM1cHg7XG4gIHBhZGRpbmc6IDVweCAxMHB4O1xuICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2Q4ZDhkODtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2Y3ZjdmNztcbn1cblxuLmQyaC1maWxlLXN0YXRzIHtcbiAgZGlzcGxheTogLXdlYmtpdC1ib3g7XG4gIGRpc3BsYXk6IC1tcy1mbGV4Ym94O1xuICBkaXNwbGF5OiBmbGV4O1xuICBtYXJnaW4tbGVmdDogYXV0bztcbiAgZm9udC1zaXplOiAxNHB4O1xufVxuXG4uZDJoLWxpbmVzLWFkZGVkIHtcbiAgdGV4dC1hbGlnbjogcmlnaHQ7XG4gIGJvcmRlcjogMXB4IHNvbGlkICNiNGUyYjQ7XG4gIGJvcmRlci1yYWRpdXM6IDVweCAwIDAgNXB4O1xuICBjb2xvcjogIzM5OTgzOTtcbiAgcGFkZGluZzogMnB4O1xuICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xufVxuXG4uZDJoLWxpbmVzLWRlbGV0ZWQge1xuICB0ZXh0LWFsaWduOiBsZWZ0O1xuICBib3JkZXI6IDFweCBzb2xpZCAjZTlhZWFlO1xuICBib3JkZXItcmFkaXVzOiAwIDVweCA1cHggMDtcbiAgY29sb3I6ICNjMzM7XG4gIHBhZGRpbmc6IDJweDtcbiAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbiAgbWFyZ2luLWxlZnQ6IDFweDtcbn1cblxuLmQyaC1maWxlLW5hbWUtd3JhcHBlciB7XG4gIGRpc3BsYXk6IC13ZWJraXQtYm94O1xuICBkaXNwbGF5OiAtbXMtZmxleGJveDtcbiAgZGlzcGxheTogZmxleDtcbiAgLXdlYmtpdC1ib3gtYWxpZ246IGNlbnRlcjtcbiAgLW1zLWZsZXgtYWxpZ246IGNlbnRlcjtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgd2lkdGg6IDEwMCU7XG4gIGZvbnQtZmFtaWx5OiBcIlNvdXJjZSBTYW5zIFByb1wiLCBcIkhlbHZldGljYSBOZXVlXCIsIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWY7XG4gIGZvbnQtc2l6ZTogMTVweDtcbn1cblxuLmQyaC1maWxlLW5hbWUge1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgb3ZlcmZsb3cteDogaGlkZGVuO1xufVxuXG4uZDJoLWZpbGUtd3JhcHBlciB7XG4gIGJvcmRlcjogMXB4IHNvbGlkICNkZGQ7XG4gIGJvcmRlci1yYWRpdXM6IDNweDtcbiAgbWFyZ2luLWJvdHRvbTogMWVtO1xufVxuXG4uZDJoLWRpZmYtdGFibGUge1xuICB3aWR0aDogMTAwJTtcbiAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTtcbiAgZm9udC1mYW1pbHk6IFwiTWVubG9cIiwgXCJDb25zb2xhc1wiLCBtb25vc3BhY2U7XG4gIGZvbnQtc2l6ZTogMTNweDtcbn1cblxuLmQyaC1maWxlcy1kaWZmIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG59XG5cbi5kMmgtZmlsZS1kaWZmIHtcbiAgb3ZlcmZsb3cteTogaGlkZGVuO1xufVxuXG4uZDJoLWZpbGUtc2lkZS1kaWZmIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICBvdmVyZmxvdy14OiBzY3JvbGw7XG4gIG92ZXJmbG93LXk6IGhpZGRlbjtcbiAgd2lkdGg6IDUwJTtcbiAgbWFyZ2luLXJpZ2h0OiAtNHB4O1xuICBtYXJnaW4tYm90dG9tOiAtOHB4O1xufVxuXG4uZDJoLWNvZGUtbGluZSB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgLyogQ29tcGVuc2F0ZSBmb3IgdGhlIGFic29sdXRlIHBvc2l0aW9uaW5nIG9mIHRoZSBsaW5lIG51bWJlcnMgKi9cbiAgcGFkZGluZzogMCA4ZW07XG59XG5cbi5kMmgtY29kZS1zaWRlLWxpbmUge1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIC8qIENvbXBlbnNhdGUgZm9yIHRoZSBhYnNvbHV0ZSBwb3NpdGlvbmluZyBvZiB0aGUgbGluZSBudW1iZXJzICovXG4gIHBhZGRpbmc6IDAgNC41ZW07XG59XG5cbi5kMmgtY29kZS1saW5lIGRlbCxcbi5kMmgtY29kZS1zaWRlLWxpbmUgZGVsIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICBtYXJnaW4tdG9wOiAtMXB4O1xuICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmI2YmE7XG4gIGJvcmRlci1yYWRpdXM6IDAuMmVtO1xufVxuXG4uZDJoLWNvZGUtbGluZSBpbnMsXG4uZDJoLWNvZGUtc2lkZS1saW5lIGlucyB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgbWFyZ2luLXRvcDogLTFweDtcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjOTdmMjk1O1xuICBib3JkZXItcmFkaXVzOiAwLjJlbTtcbiAgdGV4dC1hbGlnbjogbGVmdDtcbn1cblxuLmQyaC1jb2RlLWxpbmUtcHJlZml4IHtcbiAgZGlzcGxheTogaW5saW5lO1xuICBiYWNrZ3JvdW5kOiBub25lO1xuICBwYWRkaW5nOiAwO1xuICB3b3JkLXdyYXA6IG5vcm1hbDtcbiAgd2hpdGUtc3BhY2U6IHByZTtcbn1cblxuLmQyaC1jb2RlLWxpbmUtY3RuIHtcbiAgZGlzcGxheTogaW5saW5lO1xuICBiYWNrZ3JvdW5kOiBub25lO1xuICBwYWRkaW5nOiAwO1xuICB3b3JkLXdyYXA6IG5vcm1hbDtcbiAgd2hpdGUtc3BhY2U6IHByZTtcbn1cblxuLmxpbmUtbnVtMSB7XG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gIGZsb2F0OiBsZWZ0O1xuICB3aWR0aDogMy41ZW07XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICBwYWRkaW5nOiAwIDAuNWVtIDAgMC41ZW07XG59XG5cbi5saW5lLW51bTIge1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICBmbG9hdDogcmlnaHQ7XG4gIHdpZHRoOiAzLjVlbTtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIHBhZGRpbmc6IDAgMC41ZW0gMCAwLjVlbTtcbn1cblxuLmQyaC1jb2RlLWxpbmVudW1iZXIge1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICB3aWR0aDogNy41ZW07XG4gIC8qIEtlZXAgdGhlIG51bWJlcnMgZml4ZWQgb24gbGluZSBjb250ZW50cyBzY3JvbGwgKi9cbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XG4gIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuMyk7XG4gIHRleHQtYWxpZ246IHJpZ2h0O1xuICBib3JkZXI6IHNvbGlkICNlZWVlZWU7XG4gIGJvcmRlci13aWR0aDogMCAxcHggMCAxcHg7XG4gIGN1cnNvcjogcG9pbnRlcjtcbn1cblxuLmQyaC1jb2RlLWxpbmVudW1iZXI6YWZ0ZXIge1xuICBjb250ZW50OiAnXFwyMDBiJztcbn1cblxuLmQyaC1jb2RlLXNpZGUtbGluZW51bWJlciB7XG4gIC8qIEtlZXAgdGhlIG51bWJlcnMgZml4ZWQgb24gbGluZSBjb250ZW50cyBzY3JvbGwgKi9cbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gIHdpZHRoOiA0ZW07XG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XG4gIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuMyk7XG4gIHRleHQtYWxpZ246IHJpZ2h0O1xuICBib3JkZXI6IHNvbGlkICNlZWVlZWU7XG4gIGJvcmRlci13aWR0aDogMCAxcHggMCAxcHg7XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG59XG5cbi5kMmgtY29kZS1zaWRlLWxpbmVudW1iZXI6YWZ0ZXIge1xuICBjb250ZW50OiAnXFwyMDBiJztcbn1cblxuLmQyaC1jb2RlLXNpZGUtZW1wdHlwbGFjZWhvbGRlcixcbi5kMmgtZW1wdHlwbGFjZWhvbGRlciB7XG4gIGJhY2tncm91bmQtY29sb3I6ICNmMWYxZjE7XG4gIGJvcmRlci1jb2xvcjogI2UxZTFlMTtcbn1cblxuLypcbiAqIENoYW5nZXMgSGlnaGxpZ2h0XG4gKi9cblxuLmQyaC1kZWwge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmVlOGU5O1xuICBib3JkZXItY29sb3I6ICNlOWFlYWU7XG59XG5cbi5kMmgtaW5zIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2RmZDtcbiAgYm9yZGVyLWNvbG9yOiAjYjRlMmI0O1xufVxuXG4uZDJoLWluZm8ge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjhmYWZkO1xuICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjMpO1xuICBib3JkZXItY29sb3I6ICNkNWU0ZjI7XG59XG5cbi5kMmgtZmlsZS1kaWZmIC5kMmgtZGVsLmQyaC1jaGFuZ2Uge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmRmMmQwO1xufVxuXG4uZDJoLWZpbGUtZGlmZiAuZDJoLWlucy5kMmgtY2hhbmdlIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2RlZDtcbn1cblxuLypcbiAqIEZpbGUgU3VtbWFyeSBMaXN0XG4gKi9cblxuLmQyaC1maWxlLWxpc3Qtd3JhcHBlciB7XG4gIG1hcmdpbi1ib3R0b206IDEwcHg7XG59XG5cbi5kMmgtZmlsZS1saXN0LXdyYXBwZXIgYSB7XG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgY29sb3I6ICMzNTcyYjA7XG59XG5cbi5kMmgtZmlsZS1saXN0LXdyYXBwZXIgYTp2aXNpdGVkIHtcbiAgY29sb3I6ICMzNTcyYjA7XG59XG5cbi5kMmgtZmlsZS1saXN0LWhlYWRlciB7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG59XG5cbi5kMmgtZmlsZS1saXN0LXRpdGxlIHtcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XG59XG5cbi5kMmgtZmlsZS1saXN0LWxpbmUge1xuICBkaXNwbGF5OiAtd2Via2l0LWJveDtcbiAgZGlzcGxheTogLW1zLWZsZXhib3g7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG59XG5cbi5kMmgtZmlsZS1saXN0IHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIGxpc3Qtc3R5bGU6IG5vbmU7XG4gIHBhZGRpbmc6IDA7XG4gIG1hcmdpbjogMDtcbn1cblxuLmQyaC1maWxlLWxpc3QgPiBsaSB7XG4gIGJvcmRlci1ib3R0b206ICNkZGQgc29saWQgMXB4O1xuICBwYWRkaW5nOiA1cHggMTBweDtcbiAgbWFyZ2luOiAwO1xufVxuXG4uZDJoLWZpbGUtbGlzdCA+IGxpOmxhc3QtY2hpbGQge1xuICBib3JkZXItYm90dG9tOiBub25lO1xufVxuXG4uZDJoLWZpbGUtc3dpdGNoIHtcbiAgZGlzcGxheTogbm9uZTtcbiAgZm9udC1zaXplOiAxMHB4O1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cbi5kMmgtaWNvbiB7XG4gIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gIG1hcmdpbi1yaWdodDogMTBweDtcbiAgZmlsbDogY3VycmVudENvbG9yO1xufVxuXG4uZDJoLWRlbGV0ZWQge1xuICBjb2xvcjogI2MzMztcbn1cblxuLmQyaC1hZGRlZCB7XG4gIGNvbG9yOiAjMzk5ODM5O1xufVxuXG4uZDJoLWNoYW5nZWQge1xuICBjb2xvcjogI2QwYjQ0Yztcbn1cblxuLmQyaC1tb3ZlZCB7XG4gIGNvbG9yOiAjMzU3MmIwO1xufVxuXG4uZDJoLXRhZyB7XG4gIGRpc3BsYXk6IC13ZWJraXQtYm94O1xuICBkaXNwbGF5OiAtbXMtZmxleGJveDtcbiAgZGlzcGxheTogZmxleDtcbiAgZm9udC1zaXplOiAxMHB4O1xuICBtYXJnaW4tbGVmdDogNXB4O1xuICBwYWRkaW5nOiAwIDJweDtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjtcbn1cblxuLmQyaC1kZWxldGVkLXRhZyB7XG4gIGJvcmRlcjogI2MzMyAxcHggc29saWQ7XG59XG5cbi5kMmgtYWRkZWQtdGFnIHtcbiAgYm9yZGVyOiAjMzk5ODM5IDFweCBzb2xpZDtcbn1cblxuLmQyaC1jaGFuZ2VkLXRhZyB7XG4gIGJvcmRlcjogI2QwYjQ0YyAxcHggc29saWQ7XG59XG5cbi5kMmgtbW92ZWQtdGFnIHtcbiAgYm9yZGVyOiAjMzU3MmIwIDFweCBzb2xpZDtcbn1cblxuLypcbiAqIFNlbGVjdGlvbiB1dGlsLlxuICovXG5cbi5zZWxlY3RpbmctbGVmdCAuZDJoLWNvZGUtbGluZSxcbi5zZWxlY3RpbmctbGVmdCAuZDJoLWNvZGUtbGluZSAqLFxuLnNlbGVjdGluZy1yaWdodCB0ZC5kMmgtY29kZS1saW5lbnVtYmVyLFxuLnNlbGVjdGluZy1yaWdodCB0ZC5kMmgtY29kZS1saW5lbnVtYmVyICosXG4uc2VsZWN0aW5nLWxlZnQgLmQyaC1jb2RlLXNpZGUtbGluZSxcbi5zZWxlY3RpbmctbGVmdCAuZDJoLWNvZGUtc2lkZS1saW5lICosXG4uc2VsZWN0aW5nLXJpZ2h0IHRkLmQyaC1jb2RlLXNpZGUtbGluZW51bWJlcixcbi5zZWxlY3RpbmctcmlnaHQgdGQuZDJoLWNvZGUtc2lkZS1saW5lbnVtYmVyICoge1xuICAtd2Via2l0LXRvdWNoLWNhbGxvdXQ6IG5vbmU7XG4gIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7XG4gIC1tb3otdXNlci1zZWxlY3Q6IG5vbmU7XG4gIC1tcy11c2VyLXNlbGVjdDogbm9uZTtcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XG59XG5cbi5zZWxlY3RpbmctbGVmdCAuZDJoLWNvZGUtbGluZTo6LW1vei1zZWxlY3Rpb24sXG4uc2VsZWN0aW5nLWxlZnQgLmQyaC1jb2RlLWxpbmUgKjo6LW1vei1zZWxlY3Rpb24sXG4uc2VsZWN0aW5nLXJpZ2h0IHRkLmQyaC1jb2RlLWxpbmVudW1iZXI6Oi1tb3otc2VsZWN0aW9uLFxuLnNlbGVjdGluZy1sZWZ0IC5kMmgtY29kZS1zaWRlLWxpbmU6Oi1tb3otc2VsZWN0aW9uLFxuLnNlbGVjdGluZy1sZWZ0IC5kMmgtY29kZS1zaWRlLWxpbmUgKjo6LW1vei1zZWxlY3Rpb24sXG4uc2VsZWN0aW5nLXJpZ2h0IHRkLmQyaC1jb2RlLXNpZGUtbGluZW51bWJlcjo6LW1vei1zZWxlY3Rpb24sXG4uc2VsZWN0aW5nLXJpZ2h0IHRkLmQyaC1jb2RlLXNpZGUtbGluZW51bWJlciAqOjotbW96LXNlbGVjdGlvbiB7XG4gIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xufVxuXG4uc2VsZWN0aW5nLWxlZnQgLmQyaC1jb2RlLWxpbmU6OnNlbGVjdGlvbixcbi5zZWxlY3RpbmctbGVmdCAuZDJoLWNvZGUtbGluZSAqOjpzZWxlY3Rpb24sXG4uc2VsZWN0aW5nLXJpZ2h0IHRkLmQyaC1jb2RlLWxpbmVudW1iZXI6OnNlbGVjdGlvbixcbi5zZWxlY3RpbmctbGVmdCAuZDJoLWNvZGUtc2lkZS1saW5lOjpzZWxlY3Rpb24sXG4uc2VsZWN0aW5nLWxlZnQgLmQyaC1jb2RlLXNpZGUtbGluZSAqOjpzZWxlY3Rpb24sXG4uc2VsZWN0aW5nLXJpZ2h0IHRkLmQyaC1jb2RlLXNpZGUtbGluZW51bWJlcjo6c2VsZWN0aW9uLFxuLnNlbGVjdGluZy1yaWdodCB0ZC5kMmgtY29kZS1zaWRlLWxpbmVudW1iZXIgKjo6c2VsZWN0aW9uIHtcbiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG59XG4iXX0= */ \ No newline at end of file diff --git a/dist/diff2html.d.ts b/dist/diff2html.d.ts deleted file mode 100644 index cea93f6..0000000 --- a/dist/diff2html.d.ts +++ /dev/null @@ -1,71 +0,0 @@ -// Type definitions for diff2html -// Project: https://github.com/rtfpessoa/diff2html -// Definitions by: rtfpessoa -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped - -declare namespace Diff2Html { - - export interface Options { - inputFormat?: 'diff' | 'json'; - outputFormat?: 'line-by-line' | 'side-by-side'; - showFiles?: boolean; - diffStyle?: 'word' | 'char'; - matching?: 'lines' | 'words' | 'none'; - matchWordsThreshold?: number; - matchingMaxComparisons?: number; - maxLineSizeInBlockForComparison?: number; - maxLineLengthHighlight?: number; - templates?: object; - rawTemplates?: object; - renderNothingWhenEmpty?: boolean; - } - - export interface Line { - content: string; - type: string; - oldNumber: number; - newNumber: number; - } - - export interface Block { - oldStartLine: number; - oldStartLine2?: number; - newStartLine: number; - header: string; - lines: Line[]; - } - - export interface Result { - addedLines: number; - deletedLines: number; - isCombined: boolean; - isGitDiff: boolean; - oldName: string; - newName: string; - language: string; - blocks: Block[]; - oldMode?: string; - newMode?: string; - deletedFileMode?: string; - newFileMode?: string; - isDeleted?: boolean; - isNew?: boolean; - isCopy?: boolean; - isRename?: boolean; - unchangedPercentage?: number; - changedPercentage?: number; - checksumBefore?: string; - checksumAfter?: string; - mode?: string; - } - - export interface Diff2Html { - getJsonFromDiff(input: string, configuration?: Options): Result[]; - getPrettyHtml(input: any, configuration?: Options): string; - } -} - -declare module "diff2html" { - var d2h: { "Diff2Html": Diff2Html.Diff2Html }; - export = d2h; -} diff --git a/dist/diff2html.js b/dist/diff2html.js deleted file mode 100644 index 927cf84..0000000 --- a/dist/diff2html.js +++ /dev/null @@ -1,4782 +0,0 @@ -(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i - -All rights reserved. - -Redistribution and use of this software in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of Kevin Decker nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -@license -*/ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define(['exports'], factory) : - (global = global || self, factory(global.Diff = {})); -}(this, function (exports) { 'use strict'; - - function Diff() {} - Diff.prototype = { - diff: function diff(oldString, newString) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - var callback = options.callback; - - if (typeof options === 'function') { - callback = options; - options = {}; - } - - this.options = options; - var self = this; - - function done(value) { - if (callback) { - setTimeout(function () { - callback(undefined, value); - }, 0); - return true; - } else { - return value; - } - } // Allow subclasses to massage the input prior to running - - - oldString = this.castInput(oldString); - newString = this.castInput(newString); - oldString = this.removeEmpty(this.tokenize(oldString)); - newString = this.removeEmpty(this.tokenize(newString)); - var newLen = newString.length, - oldLen = oldString.length; - var editLength = 1; - var maxEditLength = newLen + oldLen; - var bestPath = [{ - newPos: -1, - components: [] - }]; // Seed editLength = 0, i.e. the content starts with the same values - - var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); - - if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { - // Identity per the equality and tokenizer - return done([{ - value: this.join(newString), - count: newString.length - }]); - } // Main worker method. checks all permutations of a given edit length for acceptance. - - - function execEditLength() { - for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { - var basePath = void 0; - - var addPath = bestPath[diagonalPath - 1], - removePath = bestPath[diagonalPath + 1], - _oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; - - if (addPath) { - // No one else is going to attempt to use this value, clear it - bestPath[diagonalPath - 1] = undefined; - } - - var canAdd = addPath && addPath.newPos + 1 < newLen, - canRemove = removePath && 0 <= _oldPos && _oldPos < oldLen; - - if (!canAdd && !canRemove) { - // If this path is a terminal then prune - bestPath[diagonalPath] = undefined; - continue; - } // Select the diagonal that we want to branch from. We select the prior - // path whose position in the new string is the farthest from the origin - // and does not pass the bounds of the diff graph - - - if (!canAdd || canRemove && addPath.newPos < removePath.newPos) { - basePath = clonePath(removePath); - self.pushComponent(basePath.components, undefined, true); - } else { - basePath = addPath; // No need to clone, we've pulled it from the list - - basePath.newPos++; - self.pushComponent(basePath.components, true, undefined); - } - - _oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); // If we have hit the end of both strings, then we are done - - if (basePath.newPos + 1 >= newLen && _oldPos + 1 >= oldLen) { - return done(buildValues(self, basePath.components, newString, oldString, self.useLongestToken)); - } else { - // Otherwise track this path as a potential candidate and continue. - bestPath[diagonalPath] = basePath; - } - } - - editLength++; - } // Performs the length of edit iteration. Is a bit fugly as this has to support the - // sync and async mode which is never fun. Loops over execEditLength until a value - // is produced. - - - if (callback) { - (function exec() { - setTimeout(function () { - // This should not happen, but we want to be safe. - - /* istanbul ignore next */ - if (editLength > maxEditLength) { - return callback(); - } - - if (!execEditLength()) { - exec(); - } - }, 0); - })(); - } else { - while (editLength <= maxEditLength) { - var ret = execEditLength(); - - if (ret) { - return ret; - } - } - } - }, - pushComponent: function pushComponent(components, added, removed) { - var last = components[components.length - 1]; - - if (last && last.added === added && last.removed === removed) { - // We need to clone here as the component clone operation is just - // as shallow array clone - components[components.length - 1] = { - count: last.count + 1, - added: added, - removed: removed - }; - } else { - components.push({ - count: 1, - added: added, - removed: removed - }); - } - }, - extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) { - var newLen = newString.length, - oldLen = oldString.length, - newPos = basePath.newPos, - oldPos = newPos - diagonalPath, - commonCount = 0; - - while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { - newPos++; - oldPos++; - commonCount++; - } - - if (commonCount) { - basePath.components.push({ - count: commonCount - }); - } - - basePath.newPos = newPos; - return oldPos; - }, - equals: function equals(left, right) { - if (this.options.comparator) { - return this.options.comparator(left, right); - } else { - return left === right || this.options.ignoreCase && left.toLowerCase() === right.toLowerCase(); - } - }, - removeEmpty: function removeEmpty(array) { - var ret = []; - - for (var i = 0; i < array.length; i++) { - if (array[i]) { - ret.push(array[i]); - } - } - - return ret; - }, - castInput: function castInput(value) { - return value; - }, - tokenize: function tokenize(value) { - return value.split(''); - }, - join: function join(chars) { - return chars.join(''); - } - }; - - function buildValues(diff, components, newString, oldString, useLongestToken) { - var componentPos = 0, - componentLen = components.length, - newPos = 0, - oldPos = 0; - - for (; componentPos < componentLen; componentPos++) { - var component = components[componentPos]; - - if (!component.removed) { - if (!component.added && useLongestToken) { - var value = newString.slice(newPos, newPos + component.count); - value = value.map(function (value, i) { - var oldValue = oldString[oldPos + i]; - return oldValue.length > value.length ? oldValue : value; - }); - component.value = diff.join(value); - } else { - component.value = diff.join(newString.slice(newPos, newPos + component.count)); - } - - newPos += component.count; // Common case - - if (!component.added) { - oldPos += component.count; - } - } else { - component.value = diff.join(oldString.slice(oldPos, oldPos + component.count)); - oldPos += component.count; // Reverse add and remove so removes are output first to match common convention - // The diffing algorithm is tied to add then remove output and this is the simplest - // route to get the desired output with minimal overhead. - - if (componentPos && components[componentPos - 1].added) { - var tmp = components[componentPos - 1]; - components[componentPos - 1] = components[componentPos]; - components[componentPos] = tmp; - } - } - } // Special case handle for when one terminal is ignored (i.e. whitespace). - // For this case we merge the terminal into the prior string and drop the change. - // This is only available for string mode. - - - var lastComponent = components[componentLen - 1]; - - if (componentLen > 1 && typeof lastComponent.value === 'string' && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) { - components[componentLen - 2].value += lastComponent.value; - components.pop(); - } - - return components; - } - - function clonePath(path) { - return { - newPos: path.newPos, - components: path.components.slice(0) - }; - } - - var characterDiff = new Diff(); - function diffChars(oldStr, newStr, options) { - return characterDiff.diff(oldStr, newStr, options); - } - - function generateOptions(options, defaults) { - if (typeof options === 'function') { - defaults.callback = options; - } else if (options) { - for (var name in options) { - /* istanbul ignore else */ - if (options.hasOwnProperty(name)) { - defaults[name] = options[name]; - } - } - } - - return defaults; - } - - // - // Ranges and exceptions: - // Latin-1 Supplement, 0080–00FF - // - U+00D7 × Multiplication sign - // - U+00F7 ÷ Division sign - // Latin Extended-A, 0100–017F - // Latin Extended-B, 0180–024F - // IPA Extensions, 0250–02AF - // Spacing Modifier Letters, 02B0–02FF - // - U+02C7 ˇ ˇ Caron - // - U+02D8 ˘ ˘ Breve - // - U+02D9 ˙ ˙ Dot Above - // - U+02DA ˚ ˚ Ring Above - // - U+02DB ˛ ˛ Ogonek - // - U+02DC ˜ ˜ Small Tilde - // - U+02DD ˝ ˝ Double Acute Accent - // Latin Extended Additional, 1E00–1EFF - - var extendedWordChars = /^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/; - var reWhitespace = /\S/; - var wordDiff = new Diff(); - - wordDiff.equals = function (left, right) { - if (this.options.ignoreCase) { - left = left.toLowerCase(); - right = right.toLowerCase(); - } - - return left === right || this.options.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right); - }; - - wordDiff.tokenize = function (value) { - var tokens = value.split(/(\s+|[()[\]{}'"]|\b)/); // Join the boundary splits that we do not consider to be boundaries. This is primarily the extended Latin character set. - - for (var i = 0; i < tokens.length - 1; i++) { - // If we have an empty string in the next field and we have only word chars before and after, merge - if (!tokens[i + 1] && tokens[i + 2] && extendedWordChars.test(tokens[i]) && extendedWordChars.test(tokens[i + 2])) { - tokens[i] += tokens[i + 2]; - tokens.splice(i + 1, 2); - i--; - } - } - - return tokens; - }; - - function diffWords(oldStr, newStr, options) { - options = generateOptions(options, { - ignoreWhitespace: true - }); - return wordDiff.diff(oldStr, newStr, options); - } - function diffWordsWithSpace(oldStr, newStr, options) { - return wordDiff.diff(oldStr, newStr, options); - } - - var lineDiff = new Diff(); - - lineDiff.tokenize = function (value) { - var retLines = [], - linesAndNewlines = value.split(/(\n|\r\n)/); // Ignore the final empty token that occurs if the string ends with a new line - - if (!linesAndNewlines[linesAndNewlines.length - 1]) { - linesAndNewlines.pop(); - } // Merge the content and line separators into single tokens - - - for (var i = 0; i < linesAndNewlines.length; i++) { - var line = linesAndNewlines[i]; - - if (i % 2 && !this.options.newlineIsToken) { - retLines[retLines.length - 1] += line; - } else { - if (this.options.ignoreWhitespace) { - line = line.trim(); - } - - retLines.push(line); - } - } - - return retLines; - }; - - function diffLines(oldStr, newStr, callback) { - return lineDiff.diff(oldStr, newStr, callback); - } - function diffTrimmedLines(oldStr, newStr, callback) { - var options = generateOptions(callback, { - ignoreWhitespace: true - }); - return lineDiff.diff(oldStr, newStr, options); - } - - var sentenceDiff = new Diff(); - - sentenceDiff.tokenize = function (value) { - return value.split(/(\S.+?[.!?])(?=\s+|$)/); - }; - - function diffSentences(oldStr, newStr, callback) { - return sentenceDiff.diff(oldStr, newStr, callback); - } - - var cssDiff = new Diff(); - - cssDiff.tokenize = function (value) { - return value.split(/([{}:;,]|\s+)/); - }; - - function diffCss(oldStr, newStr, callback) { - return cssDiff.diff(oldStr, newStr, callback); - } - - function _typeof(obj) { - if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { - _typeof = function (obj) { - return typeof obj; - }; - } else { - _typeof = function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; - } - - return _typeof(obj); - } - - function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); - } - - function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; - - return arr2; - } - } - - function _iterableToArray(iter) { - if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); - } - - function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance"); - } - - var objectPrototypeToString = Object.prototype.toString; - var jsonDiff = new Diff(); // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a - // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: - - jsonDiff.useLongestToken = true; - jsonDiff.tokenize = lineDiff.tokenize; - - jsonDiff.castInput = function (value) { - var _this$options = this.options, - undefinedReplacement = _this$options.undefinedReplacement, - _this$options$stringi = _this$options.stringifyReplacer, - stringifyReplacer = _this$options$stringi === void 0 ? function (k, v) { - return typeof v === 'undefined' ? undefinedReplacement : v; - } : _this$options$stringi; - return typeof value === 'string' ? value : JSON.stringify(canonicalize(value, null, null, stringifyReplacer), stringifyReplacer, ' '); - }; - - jsonDiff.equals = function (left, right) { - return Diff.prototype.equals.call(jsonDiff, left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1')); - }; - - function diffJson(oldObj, newObj, options) { - return jsonDiff.diff(oldObj, newObj, options); - } // This function handles the presence of circular references by bailing out when encountering an - // object that is already on the "stack" of items being processed. Accepts an optional replacer - - function canonicalize(obj, stack, replacementStack, replacer, key) { - stack = stack || []; - replacementStack = replacementStack || []; - - if (replacer) { - obj = replacer(key, obj); - } - - var i; - - for (i = 0; i < stack.length; i += 1) { - if (stack[i] === obj) { - return replacementStack[i]; - } - } - - var canonicalizedObj; - - if ('[object Array]' === objectPrototypeToString.call(obj)) { - stack.push(obj); - canonicalizedObj = new Array(obj.length); - replacementStack.push(canonicalizedObj); - - for (i = 0; i < obj.length; i += 1) { - canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack, replacer, key); - } - - stack.pop(); - replacementStack.pop(); - return canonicalizedObj; - } - - if (obj && obj.toJSON) { - obj = obj.toJSON(); - } - - if (_typeof(obj) === 'object' && obj !== null) { - stack.push(obj); - canonicalizedObj = {}; - replacementStack.push(canonicalizedObj); - - var sortedKeys = [], - _key; - - for (_key in obj) { - /* istanbul ignore else */ - if (obj.hasOwnProperty(_key)) { - sortedKeys.push(_key); - } - } - - sortedKeys.sort(); - - for (i = 0; i < sortedKeys.length; i += 1) { - _key = sortedKeys[i]; - canonicalizedObj[_key] = canonicalize(obj[_key], stack, replacementStack, replacer, _key); - } - - stack.pop(); - replacementStack.pop(); - } else { - canonicalizedObj = obj; - } - - return canonicalizedObj; - } - - var arrayDiff = new Diff(); - - arrayDiff.tokenize = function (value) { - return value.slice(); - }; - - arrayDiff.join = arrayDiff.removeEmpty = function (value) { - return value; - }; - - function diffArrays(oldArr, newArr, callback) { - return arrayDiff.diff(oldArr, newArr, callback); - } - - function parsePatch(uniDiff) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var diffstr = uniDiff.split(/\r\n|[\n\v\f\r\x85]/), - delimiters = uniDiff.match(/\r\n|[\n\v\f\r\x85]/g) || [], - list = [], - i = 0; - - function parseIndex() { - var index = {}; - list.push(index); // Parse diff metadata - - while (i < diffstr.length) { - var line = diffstr[i]; // File header found, end parsing diff metadata - - if (/^(\-\-\-|\+\+\+|@@)\s/.test(line)) { - break; - } // Diff index - - - var header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line); - - if (header) { - index.index = header[1]; - } - - i++; - } // Parse file headers if they are defined. Unified diff requires them, but - // there's no technical issues to have an isolated hunk without file header - - - parseFileHeader(index); - parseFileHeader(index); // Parse hunks - - index.hunks = []; - - while (i < diffstr.length) { - var _line = diffstr[i]; - - if (/^(Index:|diff|\-\-\-|\+\+\+)\s/.test(_line)) { - break; - } else if (/^@@/.test(_line)) { - index.hunks.push(parseHunk()); - } else if (_line && options.strict) { - // Ignore unexpected content unless in strict mode - throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(_line)); - } else { - i++; - } - } - } // Parses the --- and +++ headers, if none are found, no lines - // are consumed. - - - function parseFileHeader(index) { - var fileHeader = /^(---|\+\+\+)\s+(.*)$/.exec(diffstr[i]); - - if (fileHeader) { - var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new'; - var data = fileHeader[2].split('\t', 2); - var fileName = data[0].replace(/\\\\/g, '\\'); - - if (/^".*"$/.test(fileName)) { - fileName = fileName.substr(1, fileName.length - 2); - } - - index[keyPrefix + 'FileName'] = fileName; - index[keyPrefix + 'Header'] = (data[1] || '').trim(); - i++; - } - } // Parses a hunk - // This assumes that we are at the start of a hunk. - - - function parseHunk() { - var chunkHeaderIndex = i, - chunkHeaderLine = diffstr[i++], - chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/); - var hunk = { - oldStart: +chunkHeader[1], - oldLines: +chunkHeader[2] || 1, - newStart: +chunkHeader[3], - newLines: +chunkHeader[4] || 1, - lines: [], - linedelimiters: [] - }; - var addCount = 0, - removeCount = 0; - - for (; i < diffstr.length; i++) { - // Lines starting with '---' could be mistaken for the "remove line" operation - // But they could be the header for the next file. Therefore prune such cases out. - if (diffstr[i].indexOf('--- ') === 0 && i + 2 < diffstr.length && diffstr[i + 1].indexOf('+++ ') === 0 && diffstr[i + 2].indexOf('@@') === 0) { - break; - } - - var operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? ' ' : diffstr[i][0]; - - if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') { - hunk.lines.push(diffstr[i]); - hunk.linedelimiters.push(delimiters[i] || '\n'); - - if (operation === '+') { - addCount++; - } else if (operation === '-') { - removeCount++; - } else if (operation === ' ') { - addCount++; - removeCount++; - } - } else { - break; - } - } // Handle the empty block count case - - - if (!addCount && hunk.newLines === 1) { - hunk.newLines = 0; - } - - if (!removeCount && hunk.oldLines === 1) { - hunk.oldLines = 0; - } // Perform optional sanity checking - - - if (options.strict) { - if (addCount !== hunk.newLines) { - throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); - } - - if (removeCount !== hunk.oldLines) { - throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); - } - } - - return hunk; - } - - while (i < diffstr.length) { - parseIndex(); - } - - return list; - } - - // Iterator that traverses in the range of [min, max], stepping - // by distance from a given start position. I.e. for [0, 4], with - // start of 2, this will iterate 2, 3, 1, 4, 0. - function distanceIterator (start, minLine, maxLine) { - var wantForward = true, - backwardExhausted = false, - forwardExhausted = false, - localOffset = 1; - return function iterator() { - if (wantForward && !forwardExhausted) { - if (backwardExhausted) { - localOffset++; - } else { - wantForward = false; - } // Check if trying to fit beyond text length, and if not, check it fits - // after offset location (or desired location on first iteration) - - - if (start + localOffset <= maxLine) { - return localOffset; - } - - forwardExhausted = true; - } - - if (!backwardExhausted) { - if (!forwardExhausted) { - wantForward = true; - } // Check if trying to fit before text beginning, and if not, check it fits - // before offset location - - - if (minLine <= start - localOffset) { - return -localOffset++; - } - - backwardExhausted = true; - return iterator(); - } // We tried to fit hunk before text beginning and beyond text length, then - // hunk can't fit on the text. Return undefined - - }; - } - - function applyPatch(source, uniDiff) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - - if (typeof uniDiff === 'string') { - uniDiff = parsePatch(uniDiff); - } - - if (Array.isArray(uniDiff)) { - if (uniDiff.length > 1) { - throw new Error('applyPatch only works with a single input.'); - } - - uniDiff = uniDiff[0]; - } // Apply the diff to the input - - - var lines = source.split(/\r\n|[\n\v\f\r\x85]/), - delimiters = source.match(/\r\n|[\n\v\f\r\x85]/g) || [], - hunks = uniDiff.hunks, - compareLine = options.compareLine || function (lineNumber, line, operation, patchContent) { - return line === patchContent; - }, - errorCount = 0, - fuzzFactor = options.fuzzFactor || 0, - minLine = 0, - offset = 0, - removeEOFNL, - addEOFNL; - /** - * Checks if the hunk exactly fits on the provided location - */ - - - function hunkFits(hunk, toPos) { - for (var j = 0; j < hunk.lines.length; j++) { - var line = hunk.lines[j], - operation = line.length > 0 ? line[0] : ' ', - content = line.length > 0 ? line.substr(1) : line; - - if (operation === ' ' || operation === '-') { - // Context sanity check - if (!compareLine(toPos + 1, lines[toPos], operation, content)) { - errorCount++; - - if (errorCount > fuzzFactor) { - return false; - } - } - - toPos++; - } - } - - return true; - } // Search best fit offsets for each hunk based on the previous ones - - - for (var i = 0; i < hunks.length; i++) { - var hunk = hunks[i], - maxLine = lines.length - hunk.oldLines, - localOffset = 0, - toPos = offset + hunk.oldStart - 1; - var iterator = distanceIterator(toPos, minLine, maxLine); - - for (; localOffset !== undefined; localOffset = iterator()) { - if (hunkFits(hunk, toPos + localOffset)) { - hunk.offset = offset += localOffset; - break; - } - } - - if (localOffset === undefined) { - return false; - } // Set lower text limit to end of the current hunk, so next ones don't try - // to fit over already patched text - - - minLine = hunk.offset + hunk.oldStart + hunk.oldLines; - } // Apply patch hunks - - - var diffOffset = 0; - - for (var _i = 0; _i < hunks.length; _i++) { - var _hunk = hunks[_i], - _toPos = _hunk.oldStart + _hunk.offset + diffOffset - 1; - - diffOffset += _hunk.newLines - _hunk.oldLines; - - if (_toPos < 0) { - // Creating a new file - _toPos = 0; - } - - for (var j = 0; j < _hunk.lines.length; j++) { - var line = _hunk.lines[j], - operation = line.length > 0 ? line[0] : ' ', - content = line.length > 0 ? line.substr(1) : line, - delimiter = _hunk.linedelimiters[j]; - - if (operation === ' ') { - _toPos++; - } else if (operation === '-') { - lines.splice(_toPos, 1); - delimiters.splice(_toPos, 1); - /* istanbul ignore else */ - } else if (operation === '+') { - lines.splice(_toPos, 0, content); - delimiters.splice(_toPos, 0, delimiter); - _toPos++; - } else if (operation === '\\') { - var previousOperation = _hunk.lines[j - 1] ? _hunk.lines[j - 1][0] : null; - - if (previousOperation === '+') { - removeEOFNL = true; - } else if (previousOperation === '-') { - addEOFNL = true; - } - } - } - } // Handle EOFNL insertion/removal - - - if (removeEOFNL) { - while (!lines[lines.length - 1]) { - lines.pop(); - delimiters.pop(); - } - } else if (addEOFNL) { - lines.push(''); - delimiters.push('\n'); - } - - for (var _k = 0; _k < lines.length - 1; _k++) { - lines[_k] = lines[_k] + delimiters[_k]; - } - - return lines.join(''); - } // Wrapper that supports multiple file patches via callbacks. - - function applyPatches(uniDiff, options) { - if (typeof uniDiff === 'string') { - uniDiff = parsePatch(uniDiff); - } - - var currentIndex = 0; - - function processIndex() { - var index = uniDiff[currentIndex++]; - - if (!index) { - return options.complete(); - } - - options.loadFile(index, function (err, data) { - if (err) { - return options.complete(err); - } - - var updatedContent = applyPatch(data, index, options); - options.patched(index, updatedContent, function (err) { - if (err) { - return options.complete(err); - } - - processIndex(); - }); - }); - } - - processIndex(); - } - - function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { - if (!options) { - options = {}; - } - - if (typeof options.context === 'undefined') { - options.context = 4; - } - - var diff = diffLines(oldStr, newStr, options); - diff.push({ - value: '', - lines: [] - }); // Append an empty value to make cleanup easier - - function contextLines(lines) { - return lines.map(function (entry) { - return ' ' + entry; - }); - } - - var hunks = []; - var oldRangeStart = 0, - newRangeStart = 0, - curRange = [], - oldLine = 1, - newLine = 1; - - var _loop = function _loop(i) { - var current = diff[i], - lines = current.lines || current.value.replace(/\n$/, '').split('\n'); - current.lines = lines; - - if (current.added || current.removed) { - var _curRange; - - // If we have previous context, start with that - if (!oldRangeStart) { - var prev = diff[i - 1]; - oldRangeStart = oldLine; - newRangeStart = newLine; - - if (prev) { - curRange = options.context > 0 ? contextLines(prev.lines.slice(-options.context)) : []; - oldRangeStart -= curRange.length; - newRangeStart -= curRange.length; - } - } // Output our changes - - - (_curRange = curRange).push.apply(_curRange, _toConsumableArray(lines.map(function (entry) { - return (current.added ? '+' : '-') + entry; - }))); // Track the updated file position - - - if (current.added) { - newLine += lines.length; - } else { - oldLine += lines.length; - } - } else { - // Identical context lines. Track line changes - if (oldRangeStart) { - // Close out any changes that have been output (or join overlapping) - if (lines.length <= options.context * 2 && i < diff.length - 2) { - var _curRange2; - - // Overlapping - (_curRange2 = curRange).push.apply(_curRange2, _toConsumableArray(contextLines(lines))); - } else { - var _curRange3; - - // end the range and output - var contextSize = Math.min(lines.length, options.context); - - (_curRange3 = curRange).push.apply(_curRange3, _toConsumableArray(contextLines(lines.slice(0, contextSize)))); - - var hunk = { - oldStart: oldRangeStart, - oldLines: oldLine - oldRangeStart + contextSize, - newStart: newRangeStart, - newLines: newLine - newRangeStart + contextSize, - lines: curRange - }; - - if (i >= diff.length - 2 && lines.length <= options.context) { - // EOF is inside this hunk - var oldEOFNewline = /\n$/.test(oldStr); - var newEOFNewline = /\n$/.test(newStr); - var noNlBeforeAdds = lines.length == 0 && curRange.length > hunk.oldLines; - - if (!oldEOFNewline && noNlBeforeAdds) { - // special case: old has no eol and no trailing context; no-nl can end up before adds - curRange.splice(hunk.oldLines, 0, '\\ No newline at end of file'); - } - - if (!oldEOFNewline && !noNlBeforeAdds || !newEOFNewline) { - curRange.push('\\ No newline at end of file'); - } - } - - hunks.push(hunk); - oldRangeStart = 0; - newRangeStart = 0; - curRange = []; - } - } - - oldLine += lines.length; - newLine += lines.length; - } - }; - - for (var i = 0; i < diff.length; i++) { - _loop(i); - } - - return { - oldFileName: oldFileName, - newFileName: newFileName, - oldHeader: oldHeader, - newHeader: newHeader, - hunks: hunks - }; - } - function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { - var diff = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options); - var ret = []; - - if (oldFileName == newFileName) { - ret.push('Index: ' + oldFileName); - } - - ret.push('==================================================================='); - ret.push('--- ' + diff.oldFileName + (typeof diff.oldHeader === 'undefined' ? '' : '\t' + diff.oldHeader)); - ret.push('+++ ' + diff.newFileName + (typeof diff.newHeader === 'undefined' ? '' : '\t' + diff.newHeader)); - - for (var i = 0; i < diff.hunks.length; i++) { - var hunk = diff.hunks[i]; - ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + ' +' + hunk.newStart + ',' + hunk.newLines + ' @@'); - ret.push.apply(ret, hunk.lines); - } - - return ret.join('\n') + '\n'; - } - function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) { - return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options); - } - - function arrayEqual(a, b) { - if (a.length !== b.length) { - return false; - } - - return arrayStartsWith(a, b); - } - function arrayStartsWith(array, start) { - if (start.length > array.length) { - return false; - } - - for (var i = 0; i < start.length; i++) { - if (start[i] !== array[i]) { - return false; - } - } - - return true; - } - - function calcLineCount(hunk) { - var _calcOldNewLineCount = calcOldNewLineCount(hunk.lines), - oldLines = _calcOldNewLineCount.oldLines, - newLines = _calcOldNewLineCount.newLines; - - if (oldLines !== undefined) { - hunk.oldLines = oldLines; - } else { - delete hunk.oldLines; - } - - if (newLines !== undefined) { - hunk.newLines = newLines; - } else { - delete hunk.newLines; - } - } - function merge(mine, theirs, base) { - mine = loadPatch(mine, base); - theirs = loadPatch(theirs, base); - var ret = {}; // For index we just let it pass through as it doesn't have any necessary meaning. - // Leaving sanity checks on this to the API consumer that may know more about the - // meaning in their own context. - - if (mine.index || theirs.index) { - ret.index = mine.index || theirs.index; - } - - if (mine.newFileName || theirs.newFileName) { - if (!fileNameChanged(mine)) { - // No header or no change in ours, use theirs (and ours if theirs does not exist) - ret.oldFileName = theirs.oldFileName || mine.oldFileName; - ret.newFileName = theirs.newFileName || mine.newFileName; - ret.oldHeader = theirs.oldHeader || mine.oldHeader; - ret.newHeader = theirs.newHeader || mine.newHeader; - } else if (!fileNameChanged(theirs)) { - // No header or no change in theirs, use ours - ret.oldFileName = mine.oldFileName; - ret.newFileName = mine.newFileName; - ret.oldHeader = mine.oldHeader; - ret.newHeader = mine.newHeader; - } else { - // Both changed... figure it out - ret.oldFileName = selectField(ret, mine.oldFileName, theirs.oldFileName); - ret.newFileName = selectField(ret, mine.newFileName, theirs.newFileName); - ret.oldHeader = selectField(ret, mine.oldHeader, theirs.oldHeader); - ret.newHeader = selectField(ret, mine.newHeader, theirs.newHeader); - } - } - - ret.hunks = []; - var mineIndex = 0, - theirsIndex = 0, - mineOffset = 0, - theirsOffset = 0; - - while (mineIndex < mine.hunks.length || theirsIndex < theirs.hunks.length) { - var mineCurrent = mine.hunks[mineIndex] || { - oldStart: Infinity - }, - theirsCurrent = theirs.hunks[theirsIndex] || { - oldStart: Infinity - }; - - if (hunkBefore(mineCurrent, theirsCurrent)) { - // This patch does not overlap with any of the others, yay. - ret.hunks.push(cloneHunk(mineCurrent, mineOffset)); - mineIndex++; - theirsOffset += mineCurrent.newLines - mineCurrent.oldLines; - } else if (hunkBefore(theirsCurrent, mineCurrent)) { - // This patch does not overlap with any of the others, yay. - ret.hunks.push(cloneHunk(theirsCurrent, theirsOffset)); - theirsIndex++; - mineOffset += theirsCurrent.newLines - theirsCurrent.oldLines; - } else { - // Overlap, merge as best we can - var mergedHunk = { - oldStart: Math.min(mineCurrent.oldStart, theirsCurrent.oldStart), - oldLines: 0, - newStart: Math.min(mineCurrent.newStart + mineOffset, theirsCurrent.oldStart + theirsOffset), - newLines: 0, - lines: [] - }; - mergeLines(mergedHunk, mineCurrent.oldStart, mineCurrent.lines, theirsCurrent.oldStart, theirsCurrent.lines); - theirsIndex++; - mineIndex++; - ret.hunks.push(mergedHunk); - } - } - - return ret; - } - - function loadPatch(param, base) { - if (typeof param === 'string') { - if (/^@@/m.test(param) || /^Index:/m.test(param)) { - return parsePatch(param)[0]; - } - - if (!base) { - throw new Error('Must provide a base reference or pass in a patch'); - } - - return structuredPatch(undefined, undefined, base, param); - } - - return param; - } - - function fileNameChanged(patch) { - return patch.newFileName && patch.newFileName !== patch.oldFileName; - } - - function selectField(index, mine, theirs) { - if (mine === theirs) { - return mine; - } else { - index.conflict = true; - return { - mine: mine, - theirs: theirs - }; - } - } - - function hunkBefore(test, check) { - return test.oldStart < check.oldStart && test.oldStart + test.oldLines < check.oldStart; - } - - function cloneHunk(hunk, offset) { - return { - oldStart: hunk.oldStart, - oldLines: hunk.oldLines, - newStart: hunk.newStart + offset, - newLines: hunk.newLines, - lines: hunk.lines - }; - } - - function mergeLines(hunk, mineOffset, mineLines, theirOffset, theirLines) { - // This will generally result in a conflicted hunk, but there are cases where the context - // is the only overlap where we can successfully merge the content here. - var mine = { - offset: mineOffset, - lines: mineLines, - index: 0 - }, - their = { - offset: theirOffset, - lines: theirLines, - index: 0 - }; // Handle any leading content - - insertLeading(hunk, mine, their); - insertLeading(hunk, their, mine); // Now in the overlap content. Scan through and select the best changes from each. - - while (mine.index < mine.lines.length && their.index < their.lines.length) { - var mineCurrent = mine.lines[mine.index], - theirCurrent = their.lines[their.index]; - - if ((mineCurrent[0] === '-' || mineCurrent[0] === '+') && (theirCurrent[0] === '-' || theirCurrent[0] === '+')) { - // Both modified ... - mutualChange(hunk, mine, their); - } else if (mineCurrent[0] === '+' && theirCurrent[0] === ' ') { - var _hunk$lines; - - // Mine inserted - (_hunk$lines = hunk.lines).push.apply(_hunk$lines, _toConsumableArray(collectChange(mine))); - } else if (theirCurrent[0] === '+' && mineCurrent[0] === ' ') { - var _hunk$lines2; - - // Theirs inserted - (_hunk$lines2 = hunk.lines).push.apply(_hunk$lines2, _toConsumableArray(collectChange(their))); - } else if (mineCurrent[0] === '-' && theirCurrent[0] === ' ') { - // Mine removed or edited - removal(hunk, mine, their); - } else if (theirCurrent[0] === '-' && mineCurrent[0] === ' ') { - // Their removed or edited - removal(hunk, their, mine, true); - } else if (mineCurrent === theirCurrent) { - // Context identity - hunk.lines.push(mineCurrent); - mine.index++; - their.index++; - } else { - // Context mismatch - conflict(hunk, collectChange(mine), collectChange(their)); - } - } // Now push anything that may be remaining - - - insertTrailing(hunk, mine); - insertTrailing(hunk, their); - calcLineCount(hunk); - } - - function mutualChange(hunk, mine, their) { - var myChanges = collectChange(mine), - theirChanges = collectChange(their); - - if (allRemoves(myChanges) && allRemoves(theirChanges)) { - // Special case for remove changes that are supersets of one another - if (arrayStartsWith(myChanges, theirChanges) && skipRemoveSuperset(their, myChanges, myChanges.length - theirChanges.length)) { - var _hunk$lines3; - - (_hunk$lines3 = hunk.lines).push.apply(_hunk$lines3, _toConsumableArray(myChanges)); - - return; - } else if (arrayStartsWith(theirChanges, myChanges) && skipRemoveSuperset(mine, theirChanges, theirChanges.length - myChanges.length)) { - var _hunk$lines4; - - (_hunk$lines4 = hunk.lines).push.apply(_hunk$lines4, _toConsumableArray(theirChanges)); - - return; - } - } else if (arrayEqual(myChanges, theirChanges)) { - var _hunk$lines5; - - (_hunk$lines5 = hunk.lines).push.apply(_hunk$lines5, _toConsumableArray(myChanges)); - - return; - } - - conflict(hunk, myChanges, theirChanges); - } - - function removal(hunk, mine, their, swap) { - var myChanges = collectChange(mine), - theirChanges = collectContext(their, myChanges); - - if (theirChanges.merged) { - var _hunk$lines6; - - (_hunk$lines6 = hunk.lines).push.apply(_hunk$lines6, _toConsumableArray(theirChanges.merged)); - } else { - conflict(hunk, swap ? theirChanges : myChanges, swap ? myChanges : theirChanges); - } - } - - function conflict(hunk, mine, their) { - hunk.conflict = true; - hunk.lines.push({ - conflict: true, - mine: mine, - theirs: their - }); - } - - function insertLeading(hunk, insert, their) { - while (insert.offset < their.offset && insert.index < insert.lines.length) { - var line = insert.lines[insert.index++]; - hunk.lines.push(line); - insert.offset++; - } - } - - function insertTrailing(hunk, insert) { - while (insert.index < insert.lines.length) { - var line = insert.lines[insert.index++]; - hunk.lines.push(line); - } - } - - function collectChange(state) { - var ret = [], - operation = state.lines[state.index][0]; - - while (state.index < state.lines.length) { - var line = state.lines[state.index]; // Group additions that are immediately after subtractions and treat them as one "atomic" modify change. - - if (operation === '-' && line[0] === '+') { - operation = '+'; - } - - if (operation === line[0]) { - ret.push(line); - state.index++; - } else { - break; - } - } - - return ret; - } - - function collectContext(state, matchChanges) { - var changes = [], - merged = [], - matchIndex = 0, - contextChanges = false, - conflicted = false; - - while (matchIndex < matchChanges.length && state.index < state.lines.length) { - var change = state.lines[state.index], - match = matchChanges[matchIndex]; // Once we've hit our add, then we are done - - if (match[0] === '+') { - break; - } - - contextChanges = contextChanges || change[0] !== ' '; - merged.push(match); - matchIndex++; // Consume any additions in the other block as a conflict to attempt - // to pull in the remaining context after this - - if (change[0] === '+') { - conflicted = true; - - while (change[0] === '+') { - changes.push(change); - change = state.lines[++state.index]; - } - } - - if (match.substr(1) === change.substr(1)) { - changes.push(change); - state.index++; - } else { - conflicted = true; - } - } - - if ((matchChanges[matchIndex] || '')[0] === '+' && contextChanges) { - conflicted = true; - } - - if (conflicted) { - return changes; - } - - while (matchIndex < matchChanges.length) { - merged.push(matchChanges[matchIndex++]); - } - - return { - merged: merged, - changes: changes - }; - } - - function allRemoves(changes) { - return changes.reduce(function (prev, change) { - return prev && change[0] === '-'; - }, true); - } - - function skipRemoveSuperset(state, removeChanges, delta) { - for (var i = 0; i < delta; i++) { - var changeContent = removeChanges[removeChanges.length - delta + i].substr(1); - - if (state.lines[state.index + i] !== ' ' + changeContent) { - return false; - } - } - - state.index += delta; - return true; - } - - function calcOldNewLineCount(lines) { - var oldLines = 0; - var newLines = 0; - lines.forEach(function (line) { - if (typeof line !== 'string') { - var myCount = calcOldNewLineCount(line.mine); - var theirCount = calcOldNewLineCount(line.theirs); - - if (oldLines !== undefined) { - if (myCount.oldLines === theirCount.oldLines) { - oldLines += myCount.oldLines; - } else { - oldLines = undefined; - } - } - - if (newLines !== undefined) { - if (myCount.newLines === theirCount.newLines) { - newLines += myCount.newLines; - } else { - newLines = undefined; - } - } - } else { - if (newLines !== undefined && (line[0] === '+' || line[0] === ' ')) { - newLines++; - } - - if (oldLines !== undefined && (line[0] === '-' || line[0] === ' ')) { - oldLines++; - } - } - }); - return { - oldLines: oldLines, - newLines: newLines - }; - } - - // See: http://code.google.com/p/google-diff-match-patch/wiki/API - function convertChangesToDMP(changes) { - var ret = [], - change, - operation; - - for (var i = 0; i < changes.length; i++) { - change = changes[i]; - - if (change.added) { - operation = 1; - } else if (change.removed) { - operation = -1; - } else { - operation = 0; - } - - ret.push([operation, change.value]); - } - - return ret; - } - - function convertChangesToXML(changes) { - var ret = []; - - for (var i = 0; i < changes.length; i++) { - var change = changes[i]; - - if (change.added) { - ret.push(''); - } else if (change.removed) { - ret.push(''); - } - - ret.push(escapeHTML(change.value)); - - if (change.added) { - ret.push(''); - } else if (change.removed) { - ret.push(''); - } - } - - return ret.join(''); - } - - function escapeHTML(s) { - var n = s; - n = n.replace(/&/g, '&'); - n = n.replace(//g, '>'); - n = n.replace(/"/g, '"'); - return n; - } - - /* See LICENSE file for terms of use */ - - exports.Diff = Diff; - exports.diffChars = diffChars; - exports.diffWords = diffWords; - exports.diffWordsWithSpace = diffWordsWithSpace; - exports.diffLines = diffLines; - exports.diffTrimmedLines = diffTrimmedLines; - exports.diffSentences = diffSentences; - exports.diffCss = diffCss; - exports.diffJson = diffJson; - exports.diffArrays = diffArrays; - exports.structuredPatch = structuredPatch; - exports.createTwoFilesPatch = createTwoFilesPatch; - exports.createPatch = createPatch; - exports.applyPatch = applyPatch; - exports.applyPatches = applyPatches; - exports.parsePatch = parsePatch; - exports.merge = merge; - exports.convertChangesToDMP = convertChangesToDMP; - exports.convertChangesToXML = convertChangesToXML; - exports.canonicalize = canonicalize; - - Object.defineProperty(exports, '__esModule', { value: true }); - -})); - -},{}],3:[function(require,module,exports){ -/* - * Copyright 2011 Twitter, Inc. - * 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. - */ - -(function (Hogan) { - // Setup regex assignments - // remove whitespace according to Mustache spec - var rIsWhitespace = /\S/, - rQuot = /\"/g, - rNewline = /\n/g, - rCr = /\r/g, - rSlash = /\\/g, - rLineSep = /\u2028/, - rParagraphSep = /\u2029/; - - Hogan.tags = { - '#': 1, '^': 2, '<': 3, '$': 4, - '/': 5, '!': 6, '>': 7, '=': 8, '_v': 9, - '{': 10, '&': 11, '_t': 12 - }; - - Hogan.scan = function scan(text, delimiters) { - var len = text.length, - IN_TEXT = 0, - IN_TAG_TYPE = 1, - IN_TAG = 2, - state = IN_TEXT, - tagType = null, - tag = null, - buf = '', - tokens = [], - seenTag = false, - i = 0, - lineStart = 0, - otag = '{{', - ctag = '}}'; - - function addBuf() { - if (buf.length > 0) { - tokens.push({tag: '_t', text: new String(buf)}); - buf = ''; - } - } - - function lineIsWhitespace() { - var isAllWhitespace = true; - for (var j = lineStart; j < tokens.length; j++) { - isAllWhitespace = - (Hogan.tags[tokens[j].tag] < Hogan.tags['_v']) || - (tokens[j].tag == '_t' && tokens[j].text.match(rIsWhitespace) === null); - if (!isAllWhitespace) { - return false; - } - } - - return isAllWhitespace; - } - - function filterLine(haveSeenTag, noNewLine) { - addBuf(); - - if (haveSeenTag && lineIsWhitespace()) { - for (var j = lineStart, next; j < tokens.length; j++) { - if (tokens[j].text) { - if ((next = tokens[j+1]) && next.tag == '>') { - // set indent to token value - next.indent = tokens[j].text.toString() - } - tokens.splice(j, 1); - } - } - } else if (!noNewLine) { - tokens.push({tag:'\n'}); - } - - seenTag = false; - lineStart = tokens.length; - } - - function changeDelimiters(text, index) { - var close = '=' + ctag, - closeIndex = text.indexOf(close, index), - delimiters = trim( - text.substring(text.indexOf('=', index) + 1, closeIndex) - ).split(' '); - - otag = delimiters[0]; - ctag = delimiters[delimiters.length - 1]; - - return closeIndex + close.length - 1; - } - - if (delimiters) { - delimiters = delimiters.split(' '); - otag = delimiters[0]; - ctag = delimiters[1]; - } - - for (i = 0; i < len; i++) { - if (state == IN_TEXT) { - if (tagChange(otag, text, i)) { - --i; - addBuf(); - state = IN_TAG_TYPE; - } else { - if (text.charAt(i) == '\n') { - filterLine(seenTag); - } else { - buf += text.charAt(i); - } - } - } else if (state == IN_TAG_TYPE) { - i += otag.length - 1; - tag = Hogan.tags[text.charAt(i + 1)]; - tagType = tag ? text.charAt(i + 1) : '_v'; - if (tagType == '=') { - i = changeDelimiters(text, i); - state = IN_TEXT; - } else { - if (tag) { - i++; - } - state = IN_TAG; - } - seenTag = i; - } else { - if (tagChange(ctag, text, i)) { - tokens.push({tag: tagType, n: trim(buf), otag: otag, ctag: ctag, - i: (tagType == '/') ? seenTag - otag.length : i + ctag.length}); - buf = ''; - i += ctag.length - 1; - state = IN_TEXT; - if (tagType == '{') { - if (ctag == '}}') { - i++; - } else { - cleanTripleStache(tokens[tokens.length - 1]); - } - } - } else { - buf += text.charAt(i); - } - } - } - - filterLine(seenTag, true); - - return tokens; - } - - function cleanTripleStache(token) { - if (token.n.substr(token.n.length - 1) === '}') { - token.n = token.n.substring(0, token.n.length - 1); - } - } - - function trim(s) { - if (s.trim) { - return s.trim(); - } - - return s.replace(/^\s*|\s*$/g, ''); - } - - function tagChange(tag, text, index) { - if (text.charAt(index) != tag.charAt(0)) { - return false; - } - - for (var i = 1, l = tag.length; i < l; i++) { - if (text.charAt(index + i) != tag.charAt(i)) { - return false; - } - } - - return true; - } - - // the tags allowed inside super templates - var allowedInSuper = {'_t': true, '\n': true, '$': true, '/': true}; - - function buildTree(tokens, kind, stack, customTags) { - var instructions = [], - opener = null, - tail = null, - token = null; - - tail = stack[stack.length - 1]; - - while (tokens.length > 0) { - token = tokens.shift(); - - if (tail && tail.tag == '<' && !(token.tag in allowedInSuper)) { - throw new Error('Illegal content in < super tag.'); - } - - if (Hogan.tags[token.tag] <= Hogan.tags['$'] || isOpener(token, customTags)) { - stack.push(token); - token.nodes = buildTree(tokens, token.tag, stack, customTags); - } else if (token.tag == '/') { - if (stack.length === 0) { - throw new Error('Closing tag without opener: /' + token.n); - } - opener = stack.pop(); - if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) { - throw new Error('Nesting error: ' + opener.n + ' vs. ' + token.n); - } - opener.end = token.i; - return instructions; - } else if (token.tag == '\n') { - token.last = (tokens.length == 0) || (tokens[0].tag == '\n'); - } - - instructions.push(token); - } - - if (stack.length > 0) { - throw new Error('missing closing tag: ' + stack.pop().n); - } - - return instructions; - } - - function isOpener(token, tags) { - for (var i = 0, l = tags.length; i < l; i++) { - if (tags[i].o == token.n) { - token.tag = '#'; - return true; - } - } - } - - function isCloser(close, open, tags) { - for (var i = 0, l = tags.length; i < l; i++) { - if (tags[i].c == close && tags[i].o == open) { - return true; - } - } - } - - function stringifySubstitutions(obj) { - var items = []; - for (var key in obj) { - items.push('"' + esc(key) + '": function(c,p,t,i) {' + obj[key] + '}'); - } - return "{ " + items.join(",") + " }"; - } - - function stringifyPartials(codeObj) { - var partials = []; - for (var key in codeObj.partials) { - partials.push('"' + esc(key) + '":{name:"' + esc(codeObj.partials[key].name) + '", ' + stringifyPartials(codeObj.partials[key]) + "}"); - } - return "partials: {" + partials.join(",") + "}, subs: " + stringifySubstitutions(codeObj.subs); - } - - Hogan.stringify = function(codeObj, text, options) { - return "{code: function (c,p,i) { " + Hogan.wrapMain(codeObj.code) + " }," + stringifyPartials(codeObj) + "}"; - } - - var serialNo = 0; - Hogan.generate = function(tree, text, options) { - serialNo = 0; - var context = { code: '', subs: {}, partials: {} }; - Hogan.walk(tree, context); - - if (options.asString) { - return this.stringify(context, text, options); - } - - return this.makeTemplate(context, text, options); - } - - Hogan.wrapMain = function(code) { - return 'var t=this;t.b(i=i||"");' + code + 'return t.fl();'; - } - - Hogan.template = Hogan.Template; - - Hogan.makeTemplate = function(codeObj, text, options) { - var template = this.makePartials(codeObj); - template.code = new Function('c', 'p', 'i', this.wrapMain(codeObj.code)); - return new this.template(template, text, this, options); - } - - Hogan.makePartials = function(codeObj) { - var key, template = {subs: {}, partials: codeObj.partials, name: codeObj.name}; - for (key in template.partials) { - template.partials[key] = this.makePartials(template.partials[key]); - } - for (key in codeObj.subs) { - template.subs[key] = new Function('c', 'p', 't', 'i', codeObj.subs[key]); - } - return template; - } - - function esc(s) { - return s.replace(rSlash, '\\\\') - .replace(rQuot, '\\\"') - .replace(rNewline, '\\n') - .replace(rCr, '\\r') - .replace(rLineSep, '\\u2028') - .replace(rParagraphSep, '\\u2029'); - } - - function chooseMethod(s) { - return (~s.indexOf('.')) ? 'd' : 'f'; - } - - function createPartial(node, context) { - var prefix = "<" + (context.prefix || ""); - var sym = prefix + node.n + serialNo++; - context.partials[sym] = {name: node.n, partials: {}}; - context.code += 't.b(t.rp("' + esc(sym) + '",c,p,"' + (node.indent || '') + '"));'; - return sym; - } - - Hogan.codegen = { - '#': function(node, context) { - context.code += 'if(t.s(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),' + - 'c,p,0,' + node.i + ',' + node.end + ',"' + node.otag + " " + node.ctag + '")){' + - 't.rs(c,p,' + 'function(c,p,t){'; - Hogan.walk(node.nodes, context); - context.code += '});c.pop();}'; - }, - - '^': function(node, context) { - context.code += 'if(!t.s(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),c,p,1,0,0,"")){'; - Hogan.walk(node.nodes, context); - context.code += '};'; - }, - - '>': createPartial, - '<': function(node, context) { - var ctx = {partials: {}, code: '', subs: {}, inPartial: true}; - Hogan.walk(node.nodes, ctx); - var template = context.partials[createPartial(node, context)]; - template.subs = ctx.subs; - template.partials = ctx.partials; - }, - - '$': function(node, context) { - var ctx = {subs: {}, code: '', partials: context.partials, prefix: node.n}; - Hogan.walk(node.nodes, ctx); - context.subs[node.n] = ctx.code; - if (!context.inPartial) { - context.code += 't.sub("' + esc(node.n) + '",c,p,i);'; - } - }, - - '\n': function(node, context) { - context.code += write('"\\n"' + (node.last ? '' : ' + i')); - }, - - '_v': function(node, context) { - context.code += 't.b(t.v(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));'; - }, - - '_t': function(node, context) { - context.code += write('"' + esc(node.text) + '"'); - }, - - '{': tripleStache, - - '&': tripleStache - } - - function tripleStache(node, context) { - context.code += 't.b(t.t(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));'; - } - - function write(s) { - return 't.b(' + s + ');'; - } - - Hogan.walk = function(nodelist, context) { - var func; - for (var i = 0, l = nodelist.length; i < l; i++) { - func = Hogan.codegen[nodelist[i].tag]; - func && func(nodelist[i], context); - } - return context; - } - - Hogan.parse = function(tokens, text, options) { - options = options || {}; - return buildTree(tokens, '', [], options.sectionTags || []); - } - - Hogan.cache = {}; - - Hogan.cacheKey = function(text, options) { - return [text, !!options.asString, !!options.disableLambda, options.delimiters, !!options.modelGet].join('||'); - } - - Hogan.compile = function(text, options) { - options = options || {}; - var key = Hogan.cacheKey(text, options); - var template = this.cache[key]; - - if (template) { - var partials = template.partials; - for (var name in partials) { - delete partials[name].instance; - } - return template; - } - - template = this.generate(this.parse(this.scan(text, options.delimiters), text, options), text, options); - return this.cache[key] = template; - } -})(typeof exports !== 'undefined' ? exports : Hogan); - -},{}],4:[function(require,module,exports){ -/* - * Copyright 2011 Twitter, Inc. - * 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. - */ - -// This file is for use with Node.js. See dist/ for browser files. - -var Hogan = require('./compiler'); -Hogan.Template = require('./template').Template; -Hogan.template = Hogan.Template; -module.exports = Hogan; - -},{"./compiler":3,"./template":5}],5:[function(require,module,exports){ -/* - * Copyright 2011 Twitter, Inc. - * 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. - */ - -var Hogan = {}; - -(function (Hogan) { - Hogan.Template = function (codeObj, text, compiler, options) { - codeObj = codeObj || {}; - this.r = codeObj.code || this.r; - this.c = compiler; - this.options = options || {}; - this.text = text || ''; - this.partials = codeObj.partials || {}; - this.subs = codeObj.subs || {}; - this.buf = ''; - } - - Hogan.Template.prototype = { - // render: replaced by generated code. - r: function (context, partials, indent) { return ''; }, - - // variable escaping - v: hoganEscape, - - // triple stache - t: coerceToString, - - render: function render(context, partials, indent) { - return this.ri([context], partials || {}, indent); - }, - - // render internal -- a hook for overrides that catches partials too - ri: function (context, partials, indent) { - return this.r(context, partials, indent); - }, - - // ensurePartial - ep: function(symbol, partials) { - var partial = this.partials[symbol]; - - // check to see that if we've instantiated this partial before - var template = partials[partial.name]; - if (partial.instance && partial.base == template) { - return partial.instance; - } - - if (typeof template == 'string') { - if (!this.c) { - throw new Error("No compiler available."); - } - template = this.c.compile(template, this.options); - } - - if (!template) { - return null; - } - - // We use this to check whether the partials dictionary has changed - this.partials[symbol].base = template; - - if (partial.subs) { - // Make sure we consider parent template now - if (!partials.stackText) partials.stackText = {}; - for (key in partial.subs) { - if (!partials.stackText[key]) { - partials.stackText[key] = (this.activeSub !== undefined && partials.stackText[this.activeSub]) ? partials.stackText[this.activeSub] : this.text; - } - } - template = createSpecializedPartial(template, partial.subs, partial.partials, - this.stackSubs, this.stackPartials, partials.stackText); - } - this.partials[symbol].instance = template; - - return template; - }, - - // tries to find a partial in the current scope and render it - rp: function(symbol, context, partials, indent) { - var partial = this.ep(symbol, partials); - if (!partial) { - return ''; - } - - return partial.ri(context, partials, indent); - }, - - // render a section - rs: function(context, partials, section) { - var tail = context[context.length - 1]; - - if (!isArray(tail)) { - section(context, partials, this); - return; - } - - for (var i = 0; i < tail.length; i++) { - context.push(tail[i]); - section(context, partials, this); - context.pop(); - } - }, - - // maybe start a section - s: function(val, ctx, partials, inverted, start, end, tags) { - var pass; - - if (isArray(val) && val.length === 0) { - return false; - } - - if (typeof val == 'function') { - val = this.ms(val, ctx, partials, inverted, start, end, tags); - } - - pass = !!val; - - if (!inverted && pass && ctx) { - ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]); - } - - return pass; - }, - - // find values with dotted names - d: function(key, ctx, partials, returnFound) { - var found, - names = key.split('.'), - val = this.f(names[0], ctx, partials, returnFound), - doModelGet = this.options.modelGet, - cx = null; - - if (key === '.' && isArray(ctx[ctx.length - 2])) { - val = ctx[ctx.length - 1]; - } else { - for (var i = 1; i < names.length; i++) { - found = findInScope(names[i], val, doModelGet); - if (found !== undefined) { - cx = val; - val = found; - } else { - val = ''; - } - } - } - - if (returnFound && !val) { - return false; - } - - if (!returnFound && typeof val == 'function') { - ctx.push(cx); - val = this.mv(val, ctx, partials); - ctx.pop(); - } - - return val; - }, - - // find values with normal names - f: function(key, ctx, partials, returnFound) { - var val = false, - v = null, - found = false, - doModelGet = this.options.modelGet; - - for (var i = ctx.length - 1; i >= 0; i--) { - v = ctx[i]; - val = findInScope(key, v, doModelGet); - if (val !== undefined) { - found = true; - break; - } - } - - if (!found) { - return (returnFound) ? false : ""; - } - - if (!returnFound && typeof val == 'function') { - val = this.mv(val, ctx, partials); - } - - return val; - }, - - // higher order templates - ls: function(func, cx, partials, text, tags) { - var oldTags = this.options.delimiters; - - this.options.delimiters = tags; - this.b(this.ct(coerceToString(func.call(cx, text)), cx, partials)); - this.options.delimiters = oldTags; - - return false; - }, - - // compile text - ct: function(text, cx, partials) { - if (this.options.disableLambda) { - throw new Error('Lambda features disabled.'); - } - return this.c.compile(text, this.options).render(cx, partials); - }, - - // template result buffering - b: function(s) { this.buf += s; }, - - fl: function() { var r = this.buf; this.buf = ''; return r; }, - - // method replace section - ms: function(func, ctx, partials, inverted, start, end, tags) { - var textSource, - cx = ctx[ctx.length - 1], - result = func.call(cx); - - if (typeof result == 'function') { - if (inverted) { - return true; - } else { - textSource = (this.activeSub && this.subsText && this.subsText[this.activeSub]) ? this.subsText[this.activeSub] : this.text; - return this.ls(result, cx, partials, textSource.substring(start, end), tags); - } - } - - return result; - }, - - // method replace variable - mv: function(func, ctx, partials) { - var cx = ctx[ctx.length - 1]; - var result = func.call(cx); - - if (typeof result == 'function') { - return this.ct(coerceToString(result.call(cx)), cx, partials); - } - - return result; - }, - - sub: function(name, context, partials, indent) { - var f = this.subs[name]; - if (f) { - this.activeSub = name; - f(context, partials, this, indent); - this.activeSub = false; - } - } - - }; - - //Find a key in an object - function findInScope(key, scope, doModelGet) { - var val; - - if (scope && typeof scope == 'object') { - - if (scope[key] !== undefined) { - val = scope[key]; - - // try lookup with get for backbone or similar model data - } else if (doModelGet && scope.get && typeof scope.get == 'function') { - val = scope.get(key); - } - } - - return val; - } - - function createSpecializedPartial(instance, subs, partials, stackSubs, stackPartials, stackText) { - function PartialTemplate() {}; - PartialTemplate.prototype = instance; - function Substitutions() {}; - Substitutions.prototype = instance.subs; - var key; - var partial = new PartialTemplate(); - partial.subs = new Substitutions(); - partial.subsText = {}; //hehe. substext. - partial.buf = ''; - - stackSubs = stackSubs || {}; - partial.stackSubs = stackSubs; - partial.subsText = stackText; - for (key in subs) { - if (!stackSubs[key]) stackSubs[key] = subs[key]; - } - for (key in stackSubs) { - partial.subs[key] = stackSubs[key]; - } - - stackPartials = stackPartials || {}; - partial.stackPartials = stackPartials; - for (key in partials) { - if (!stackPartials[key]) stackPartials[key] = partials[key]; - } - for (key in stackPartials) { - partial.partials[key] = stackPartials[key]; - } - - return partial; - } - - var rAmp = /&/g, - rLt = //g, - rApos = /\'/g, - rQuot = /\"/g, - hChars = /[&<>\"\']/; - - function coerceToString(val) { - return String((val === null || val === undefined) ? '' : val); - } - - function hoganEscape(str) { - str = coerceToString(str); - return hChars.test(str) ? - str - .replace(rAmp, '&') - .replace(rLt, '<') - .replace(rGt, '>') - .replace(rApos, ''') - .replace(rQuot, '"') : - str; - } - - var isArray = Array.isArray || function(a) { - return Object.prototype.toString.call(a) === '[object Array]'; - }; - -})(typeof exports !== 'undefined' ? exports : Hogan); - -},{}],6:[function(require,module,exports){ -/*! - * @name JavaScript/NodeJS Merge v1.2.1 - * @author yeikos - * @repository https://github.com/yeikos/js.merge - - * Copyright 2014 yeikos - MIT license - * https://raw.github.com/yeikos/js.merge/master/LICENSE - */ - -;(function(isNode) { - - /** - * Merge one or more objects - * @param bool? clone - * @param mixed,... arguments - * @return object - */ - - var Public = function(clone) { - - return merge(clone === true, false, arguments); - - }, publicName = 'merge'; - - /** - * Merge two or more objects recursively - * @param bool? clone - * @param mixed,... arguments - * @return object - */ - - Public.recursive = function(clone) { - - return merge(clone === true, true, arguments); - - }; - - /** - * Clone the input removing any reference - * @param mixed input - * @return mixed - */ - - Public.clone = function(input) { - - var output = input, - type = typeOf(input), - index, size; - - if (type === 'array') { - - output = []; - size = input.length; - - for (index=0;index 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up--; up) { - parts.unshift('..'); - } - } - - return parts; -} - -// path.resolve([from ...], to) -// posix version -exports.resolve = function() { - var resolvedPath = '', - resolvedAbsolute = false; - - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : process.cwd(); - - // Skip empty and invalid entries - if (typeof path !== 'string') { - throw new TypeError('Arguments to path.resolve must be strings'); - } else if (!path) { - continue; - } - - resolvedPath = path + '/' + resolvedPath; - resolvedAbsolute = path.charAt(0) === '/'; - } - - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - - // Normalize the path - resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { - return !!p; - }), !resolvedAbsolute).join('/'); - - return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; -}; - -// path.normalize(path) -// posix version -exports.normalize = function(path) { - var isAbsolute = exports.isAbsolute(path), - trailingSlash = substr(path, -1) === '/'; - - // Normalize the path - path = normalizeArray(filter(path.split('/'), function(p) { - return !!p; - }), !isAbsolute).join('/'); - - if (!path && !isAbsolute) { - path = '.'; - } - if (path && trailingSlash) { - path += '/'; - } - - return (isAbsolute ? '/' : '') + path; -}; - -// posix version -exports.isAbsolute = function(path) { - return path.charAt(0) === '/'; -}; - -// posix version -exports.join = function() { - var paths = Array.prototype.slice.call(arguments, 0); - return exports.normalize(filter(paths, function(p, index) { - if (typeof p !== 'string') { - throw new TypeError('Arguments to path.join must be strings'); - } - return p; - }).join('/')); -}; - - -// path.relative(from, to) -// posix version -exports.relative = function(from, to) { - from = exports.resolve(from).substr(1); - to = exports.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') break; - } - - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') break; - } - - if (start > end) return []; - return arr.slice(start, end - start + 1); - } - - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); - } - - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - - return outputParts.join('/'); -}; - -exports.sep = '/'; -exports.delimiter = ':'; - -exports.dirname = function (path) { - if (typeof path !== 'string') path = path + ''; - if (path.length === 0) return '.'; - var code = path.charCodeAt(0); - var hasRoot = code === 47 /*/*/; - var end = -1; - var matchedSlash = true; - for (var i = path.length - 1; i >= 1; --i) { - code = path.charCodeAt(i); - if (code === 47 /*/*/) { - if (!matchedSlash) { - end = i; - break; - } - } else { - // We saw the first non-path separator - matchedSlash = false; - } - } - - if (end === -1) return hasRoot ? '/' : '.'; - if (hasRoot && end === 1) { - // return '//'; - // Backwards-compat fix: - return '/'; - } - return path.slice(0, end); -}; - -function basename(path) { - if (typeof path !== 'string') path = path + ''; - - var start = 0; - var end = -1; - var matchedSlash = true; - var i; - - for (i = path.length - 1; i >= 0; --i) { - if (path.charCodeAt(i) === 47 /*/*/) { - // If we reached a path separator that was not part of a set of path - // separators at the end of the string, stop now - if (!matchedSlash) { - start = i + 1; - break; - } - } else if (end === -1) { - // We saw the first non-path separator, mark this as the end of our - // path component - matchedSlash = false; - end = i + 1; - } - } - - if (end === -1) return ''; - return path.slice(start, end); -} - -// Uses a mixed approach for backwards-compatibility, as ext behavior changed -// in new Node.js versions, so only basename() above is backported here -exports.basename = function (path, ext) { - var f = basename(path); - if (ext && f.substr(-1 * ext.length) === ext) { - f = f.substr(0, f.length - ext.length); - } - return f; -}; - -exports.extname = function (path) { - if (typeof path !== 'string') path = path + ''; - var startDot = -1; - var startPart = 0; - var end = -1; - var matchedSlash = true; - // Track the state of characters (if any) we see before our first dot and - // after any path separator we find - var preDotState = 0; - for (var i = path.length - 1; i >= 0; --i) { - var code = path.charCodeAt(i); - if (code === 47 /*/*/) { - // If we reached a path separator that was not part of a set of path - // separators at the end of the string, stop now - if (!matchedSlash) { - startPart = i + 1; - break; - } - continue; - } - if (end === -1) { - // We saw the first non-path separator, mark this as the end of our - // extension - matchedSlash = false; - end = i + 1; - } - if (code === 46 /*.*/) { - // If this is our first dot, mark it as the start of our extension - if (startDot === -1) - startDot = i; - else if (preDotState !== 1) - preDotState = 1; - } else if (startDot !== -1) { - // We saw a non-dot and non-path separator before our dot, so we should - // have a good chance at having a non-empty extension - preDotState = -1; - } - } - - if (startDot === -1 || end === -1 || - // We saw a non-dot character immediately before the dot - preDotState === 0 || - // The (right-most) trimmed path component is exactly '..' - preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) { - return ''; - } - return path.slice(startDot, end); -}; - -function filter (xs, f) { - if (xs.filter) return xs.filter(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - if (f(xs[i], i, xs)) res.push(xs[i]); - } - return res; -} - -// String.prototype.substr - negative index don't work in IE8 -var substr = 'ab'.substr(-1) === 'b' - ? function (str, start, len) { return str.substr(start, len) } - : function (str, start, len) { - if (start < 0) start = str.length + start; - return str.substr(start, len); - } -; - -}).call(this,require('_process')) -},{"_process":8}],8:[function(require,module,exports){ -// shim for using process in browser -var process = module.exports = {}; - -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; - -function defaultSetTimout() { - throw new Error('setTimeout has not been defined'); -} -function defaultClearTimeout () { - throw new Error('clearTimeout has not been defined'); -} -(function () { - try { - if (typeof setTimeout === 'function') { - cachedSetTimeout = setTimeout; - } else { - cachedSetTimeout = defaultSetTimout; - } - } catch (e) { - cachedSetTimeout = defaultSetTimout; - } - try { - if (typeof clearTimeout === 'function') { - cachedClearTimeout = clearTimeout; - } else { - cachedClearTimeout = defaultClearTimeout; - } - } catch (e) { - cachedClearTimeout = defaultClearTimeout; - } -} ()) -function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - //normal enviroments in sane situations - return setTimeout(fun, 0); - } - // if setTimeout wasn't available but was latter defined - if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { - cachedSetTimeout = setTimeout; - return setTimeout(fun, 0); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedSetTimeout(fun, 0); - } catch(e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedSetTimeout.call(null, fun, 0); - } catch(e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error - return cachedSetTimeout.call(this, fun, 0); - } - } - - -} -function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - //normal enviroments in sane situations - return clearTimeout(marker); - } - // if clearTimeout wasn't available but was latter defined - if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { - cachedClearTimeout = clearTimeout; - return clearTimeout(marker); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedClearTimeout(marker); - } catch (e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedClearTimeout.call(null, marker); - } catch (e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. - // Some versions of I.E. have different rules for clearTimeout vs setTimeout - return cachedClearTimeout.call(this, marker); - } - } - - - -} -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = runTimeout(cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - runClearTimeout(timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - runTimeout(drainQueue); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; -process.prependListener = noop; -process.prependOnceListener = noop; - -process.listeners = function (name) { return [] } - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; - -},{}],9:[function(require,module,exports){ -/* - * - * Diff Parser (diff-parser.js) - * Author: rtfpessoa - * - */ - -(function() { - var utils = require('./utils.js').Utils; - - var LINE_TYPE = { - INSERTS: 'd2h-ins', - DELETES: 'd2h-del', - INSERT_CHANGES: 'd2h-ins d2h-change', - DELETE_CHANGES: 'd2h-del d2h-change', - CONTEXT: 'd2h-cntx', - INFO: 'd2h-info' - }; - - function DiffParser() { - } - - DiffParser.prototype.LINE_TYPE = LINE_TYPE; - - DiffParser.prototype.generateDiffJson = function(diffInput, configuration) { - var config = configuration || {}; - - var files = []; - var currentFile = null; - var currentBlock = null; - var oldLine = null; - var oldLine2 = null; // Used for combined diff - var newLine = null; - - var possibleOldName; - var possibleNewName; - - /* Diff Header */ - var oldFileNameHeader = '--- '; - var newFileNameHeader = '+++ '; - var hunkHeaderPrefix = '@@'; - - /* Add previous block(if exists) before start a new file */ - function saveBlock() { - if (currentBlock) { - currentFile.blocks.push(currentBlock); - currentBlock = null; - } - } - - /* - * Add previous file(if exists) before start a new one - * if it has name (to avoid binary files errors) - */ - function saveFile() { - if (currentFile) { - if (!currentFile.oldName) { - currentFile.oldName = possibleOldName; - } - - if (!currentFile.newName) { - currentFile.newName = possibleNewName; - } - - if (currentFile.newName) { - files.push(currentFile); - currentFile = null; - } - } - - possibleOldName = undefined; - possibleNewName = undefined; - } - - /* Create file structure */ - function startFile() { - saveBlock(); - saveFile(); - - currentFile = {}; - currentFile.blocks = []; - currentFile.deletedLines = 0; - currentFile.addedLines = 0; - } - - function startBlock(line) { - saveBlock(); - - var values; - - /** - * From Range: - * -[,] - * - * To Range: - * +[,] - * - * @@ from-file-range to-file-range @@ - * - * @@@ from-file-range from-file-range to-file-range @@@ - * - * number of lines is optional, if omited consider 0 - */ - - if ((values = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@.*/.exec(line))) { - currentFile.isCombined = false; - oldLine = values[1]; - newLine = values[2]; - } else if ((values = /^@@@ -(\d+)(?:,\d+)? -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@@.*/.exec(line))) { - currentFile.isCombined = true; - oldLine = values[1]; - oldLine2 = values[2]; - newLine = values[3]; - } else { - if (utils.startsWith(line, hunkHeaderPrefix)) { - console.error('Failed to parse lines, starting in 0!'); - } - - oldLine = 0; - newLine = 0; - currentFile.isCombined = false; - } - - /* Create block metadata */ - currentBlock = {}; - currentBlock.lines = []; - currentBlock.oldStartLine = oldLine; - currentBlock.oldStartLine2 = oldLine2; - currentBlock.newStartLine = newLine; - currentBlock.header = line; - } - - function createLine(line) { - var currentLine = {}; - currentLine.content = line; - - var newLinePrefixes = !currentFile.isCombined ? ['+'] : ['+', ' +']; - var delLinePrefixes = !currentFile.isCombined ? ['-'] : ['-', ' -']; - - /* Fill the line data */ - if (utils.startsWith(line, newLinePrefixes)) { - currentFile.addedLines++; - - currentLine.type = LINE_TYPE.INSERTS; - currentLine.oldNumber = null; - currentLine.newNumber = newLine++; - - currentBlock.lines.push(currentLine); - } else if (utils.startsWith(line, delLinePrefixes)) { - currentFile.deletedLines++; - - currentLine.type = LINE_TYPE.DELETES; - currentLine.oldNumber = oldLine++; - currentLine.newNumber = null; - - currentBlock.lines.push(currentLine); - } else { - currentLine.type = LINE_TYPE.CONTEXT; - currentLine.oldNumber = oldLine++; - currentLine.newNumber = newLine++; - - currentBlock.lines.push(currentLine); - } - } - - /* - * Checks if there is a hunk header coming before a new file starts - * - * Hunk header is a group of three lines started by ( `--- ` , `+++ ` , `@@` ) - */ - function existHunkHeader(line, lineIdx) { - var idx = lineIdx; - - while (idx < diffLines.length - 3) { - if (utils.startsWith(line, 'diff')) { - return false; - } - - if ( - utils.startsWith(diffLines[idx], oldFileNameHeader) && - utils.startsWith(diffLines[idx + 1], newFileNameHeader) && - utils.startsWith(diffLines[idx + 2], hunkHeaderPrefix) - ) { - return true; - } - - idx++; - } - - return false; - } - - var diffLines = - diffInput.replace(/\\ No newline at end of file/g, '') - .replace(/\r\n?/g, '\n') - .split('\n'); - - /* Diff */ - var oldMode = /^old mode (\d{6})/; - var newMode = /^new mode (\d{6})/; - var deletedFileMode = /^deleted file mode (\d{6})/; - var newFileMode = /^new file mode (\d{6})/; - - var copyFrom = /^copy from "?(.+)"?/; - var copyTo = /^copy to "?(.+)"?/; - - var renameFrom = /^rename from "?(.+)"?/; - var renameTo = /^rename to "?(.+)"?/; - - var similarityIndex = /^similarity index (\d+)%/; - var dissimilarityIndex = /^dissimilarity index (\d+)%/; - var index = /^index ([0-9a-z]+)\.\.([0-9a-z]+)\s*(\d{6})?/; - - var binaryFiles = /^Binary files (.*) and (.*) differ/; - var binaryDiff = /^GIT binary patch/; - - /* Combined Diff */ - var combinedIndex = /^index ([0-9a-z]+),([0-9a-z]+)\.\.([0-9a-z]+)/; - var combinedMode = /^mode (\d{6}),(\d{6})\.\.(\d{6})/; - var combinedNewFile = /^new file mode (\d{6})/; - var combinedDeletedFile = /^deleted file mode (\d{6}),(\d{6})/; - - diffLines.forEach(function(line, lineIndex) { - // Unmerged paths, and possibly other non-diffable files - // https://github.com/scottgonzalez/pretty-diff/issues/11 - // Also, remove some useless lines - if (!line || utils.startsWith(line, '*')) { - return; - } - - // Used to store regex capture groups - var values; - - var prevLine = diffLines[lineIndex - 1]; - var nxtLine = diffLines[lineIndex + 1]; - var afterNxtLine = diffLines[lineIndex + 2]; - - if (utils.startsWith(line, 'diff')) { - startFile(); - - // diff --git a/blocked_delta_results.png b/blocked_delta_results.png - var gitDiffStart = /^diff --git "?(.+)"? "?(.+)"?/; - if ((values = gitDiffStart.exec(line))) { - possibleOldName = _getFilename(null, values[1], config.dstPrefix); - possibleNewName = _getFilename(null, values[2], config.srcPrefix); - } - - currentFile.isGitDiff = true; - return; - } - - if (!currentFile || // If we do not have a file yet, we should crete one - ( - !currentFile.isGitDiff && currentFile && // If we already have some file in progress and - ( - utils.startsWith(line, oldFileNameHeader) && // If we get to an old file path header line - // And is followed by the new file path header line and the hunk header line - utils.startsWith(nxtLine, newFileNameHeader) && utils.startsWith(afterNxtLine, hunkHeaderPrefix) - ) - ) - ) { - startFile(); - } - - /* - * We need to make sure that we have the three lines of the header. - * This avoids cases like the ones described in: - * - https://github.com/rtfpessoa/diff2html/issues/87 - */ - if ( - (utils.startsWith(line, oldFileNameHeader) && - utils.startsWith(nxtLine, newFileNameHeader)) || - - (utils.startsWith(line, newFileNameHeader) && - utils.startsWith(prevLine, oldFileNameHeader)) - ) { - /* - * --- Date Timestamp[FractionalSeconds] TimeZone - * --- 2002-02-21 23:30:39.942229878 -0800 - */ - if (currentFile && !currentFile.oldName && - utils.startsWith(line, '--- ') && (values = getSrcFilename(line, config))) { - currentFile.oldName = values; - currentFile.language = getExtension(currentFile.oldName, currentFile.language); - return; - } - - /* - * +++ Date Timestamp[FractionalSeconds] TimeZone - * +++ 2002-02-21 23:30:39.942229878 -0800 - */ - if (currentFile && !currentFile.newName && - utils.startsWith(line, '+++ ') && (values = getDstFilename(line, config))) { - currentFile.newName = values; - currentFile.language = getExtension(currentFile.newName, currentFile.language); - return; - } - } - - if ( - (currentFile && utils.startsWith(line, hunkHeaderPrefix)) || - (currentFile.isGitDiff && currentFile && currentFile.oldName && currentFile.newName && !currentBlock) - ) { - startBlock(line); - return; - } - - /* - * There are three types of diff lines. These lines are defined by the way they start. - * 1. New line starts with: + - * 2. Old line starts with: - - * 3. Context line starts with: - */ - if (currentBlock && (utils.startsWith(line, '+') || utils.startsWith(line, '-') || utils.startsWith(line, ' '))) { - createLine(line); - return; - } - - var doesNotExistHunkHeader = !existHunkHeader(line, lineIndex); - - /* - * Git diffs provide more information regarding files modes, renames, copies, - * commits between changes and similarity indexes - */ - if ((values = oldMode.exec(line))) { - currentFile.oldMode = values[1]; - } else if ((values = newMode.exec(line))) { - currentFile.newMode = values[1]; - } else if ((values = deletedFileMode.exec(line))) { - currentFile.deletedFileMode = values[1]; - currentFile.isDeleted = true; - } else if ((values = newFileMode.exec(line))) { - currentFile.newFileMode = values[1]; - currentFile.isNew = true; - } else if ((values = copyFrom.exec(line))) { - if (doesNotExistHunkHeader) { - currentFile.oldName = values[1]; - } - currentFile.isCopy = true; - } else if ((values = copyTo.exec(line))) { - if (doesNotExistHunkHeader) { - currentFile.newName = values[1]; - } - currentFile.isCopy = true; - } else if ((values = renameFrom.exec(line))) { - if (doesNotExistHunkHeader) { - currentFile.oldName = values[1]; - } - currentFile.isRename = true; - } else if ((values = renameTo.exec(line))) { - if (doesNotExistHunkHeader) { - currentFile.newName = values[1]; - } - currentFile.isRename = true; - } else if ((values = binaryFiles.exec(line))) { - currentFile.isBinary = true; - currentFile.oldName = _getFilename(null, values[1], config.srcPrefix); - currentFile.newName = _getFilename(null, values[2], config.dstPrefix); - startBlock('Binary file'); - } else if ((values = binaryDiff.exec(line))) { - currentFile.isBinary = true; - startBlock(line); - } else if ((values = similarityIndex.exec(line))) { - currentFile.unchangedPercentage = values[1]; - } else if ((values = dissimilarityIndex.exec(line))) { - currentFile.changedPercentage = values[1]; - } else if ((values = index.exec(line))) { - currentFile.checksumBefore = values[1]; - currentFile.checksumAfter = values[2]; - values[3] && (currentFile.mode = values[3]); - } else if ((values = combinedIndex.exec(line))) { - currentFile.checksumBefore = [values[2], values[3]]; - currentFile.checksumAfter = values[1]; - } else if ((values = combinedMode.exec(line))) { - currentFile.oldMode = [values[2], values[3]]; - currentFile.newMode = values[1]; - } else if ((values = combinedNewFile.exec(line))) { - currentFile.newFileMode = values[1]; - currentFile.isNew = true; - } else if ((values = combinedDeletedFile.exec(line))) { - currentFile.deletedFileMode = values[1]; - currentFile.isDeleted = true; - } - }); - - saveBlock(); - saveFile(); - - return files; - }; - - function getExtension(filename, language) { - var nameSplit = filename.split('.'); - if (nameSplit.length > 1) { - return nameSplit[nameSplit.length - 1]; - } - - return language; - } - - function getSrcFilename(line, cfg) { - return _getFilename('---', line, cfg.srcPrefix); - } - - function getDstFilename(line, cfg) { - return _getFilename('\\+\\+\\+', line, cfg.dstPrefix); - } - - function _getFilename(linePrefix, line, extraPrefix) { - var prefixes = ['a/', 'b/', 'i/', 'w/', 'c/', 'o/']; - if (extraPrefix) { - prefixes.push(extraPrefix); - } - - var FilenameRegExp; - if (linePrefix) { - FilenameRegExp = new RegExp('^' + linePrefix + ' "?(.+?)"?$'); - } else { - FilenameRegExp = new RegExp('^"?(.+?)"?$'); - } - - var filename; - var values = FilenameRegExp.exec(line); - if (values && values[1]) { - filename = values[1]; - var matchingPrefixes = prefixes.filter(function(p) { - return filename.indexOf(p) === 0; - }); - - if (matchingPrefixes[0]) { - // Remove prefix if exists - filename = filename.slice(matchingPrefixes[0].length); - } - - // Cleanup timestamps generated by the unified diff (diff command) as specified in - // https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html - // Ie: 2016-10-25 11:37:14.000000000 +0200 - filename = filename.replace(/\s+\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)? [-+]\d{4}.*$/, ''); - } - - return filename; - } - - module.exports.DiffParser = new DiffParser(); -})(); - -},{"./utils.js":19}],10:[function(require,module,exports){ -(function (global){ -/* - * - * Diff to HTML (diff2html.js) - * Author: rtfpessoa - * - */ - -(function() { - var diffParser = require('./diff-parser.js').DiffParser; - var htmlPrinter = require('./html-printer.js').HtmlPrinter; - var utils = require('./utils.js').Utils; - - function Diff2Html() { - } - - var defaultConfig = { - inputFormat: 'diff', - outputFormat: 'line-by-line', - showFiles: false, - diffStyle: 'word', - matching: 'none', - matchWordsThreshold: 0.25, - matchingMaxComparisons: 2500, - maxLineSizeInBlockForComparison: 200, - maxLineLengthHighlight: 10000, - templates: {}, - rawTemplates: {}, - renderNothingWhenEmpty: false - }; - - /* - * Generates json object from string diff input - */ - Diff2Html.prototype.getJsonFromDiff = function(diffInput, config) { - var cfg = utils.safeConfig(config, defaultConfig); - return diffParser.generateDiffJson(diffInput, cfg); - }; - - /* - * Generates the html diff. The config parameter configures the output/input formats and other options - */ - Diff2Html.prototype.getPrettyHtml = function(diffInput, config) { - var cfg = utils.safeConfig(config, defaultConfig); - - var diffJson = diffInput; - if (!cfg.inputFormat || cfg.inputFormat === 'diff') { - diffJson = diffParser.generateDiffJson(diffInput, cfg); - } - - var fileList = ''; - if (cfg.showFiles === true) { - fileList = htmlPrinter.generateFileListSummary(diffJson, cfg); - } - - var diffOutput = ''; - if (cfg.outputFormat === 'side-by-side') { - diffOutput = htmlPrinter.generateSideBySideJsonHtml(diffJson, cfg); - } else { - diffOutput = htmlPrinter.generateLineByLineJsonHtml(diffJson, cfg); - } - - return fileList + diffOutput; - }; - - /* - * Deprecated methods - The following methods exist only to maintain compatibility with previous versions - */ - - /* - * Generates pretty html from string diff input - */ - Diff2Html.prototype.getPrettyHtmlFromDiff = function(diffInput, config) { - var cfg = utils.safeConfig(config, defaultConfig); - cfg.inputFormat = 'diff'; - cfg.outputFormat = 'line-by-line'; - return this.getPrettyHtml(diffInput, cfg); - }; - - /* - * Generates pretty html from a json object - */ - Diff2Html.prototype.getPrettyHtmlFromJson = function(diffJson, config) { - var cfg = utils.safeConfig(config, defaultConfig); - cfg.inputFormat = 'json'; - cfg.outputFormat = 'line-by-line'; - return this.getPrettyHtml(diffJson, cfg); - }; - - /* - * Generates pretty side by side html from string diff input - */ - Diff2Html.prototype.getPrettySideBySideHtmlFromDiff = function(diffInput, config) { - var cfg = utils.safeConfig(config, defaultConfig); - cfg.inputFormat = 'diff'; - cfg.outputFormat = 'side-by-side'; - return this.getPrettyHtml(diffInput, cfg); - }; - - /* - * Generates pretty side by side html from a json object - */ - Diff2Html.prototype.getPrettySideBySideHtmlFromJson = function(diffJson, config) { - var cfg = utils.safeConfig(config, defaultConfig); - cfg.inputFormat = 'json'; - cfg.outputFormat = 'side-by-side'; - return this.getPrettyHtml(diffJson, cfg); - }; - - var diffObject = new Diff2Html(); - module.exports.Diff2Html = diffObject; - - // Expose diff2html in the browser - global.Diff2Html = diffObject; -})(); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./diff-parser.js":9,"./html-printer.js":13,"./utils.js":19}],11:[function(require,module,exports){ -/* - * - * FileListPrinter (file-list-printer.js) - * Author: nmatpt - * - */ - -(function() { - var printerUtils = require('./printer-utils.js').PrinterUtils; - - var hoganUtils; - - var baseTemplatesPath = 'file-summary'; - var iconsBaseTemplatesPath = 'icon'; - - function FileListPrinter(config) { - this.config = config; - - var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils; - hoganUtils = new HoganJsUtils(config); - } - - FileListPrinter.prototype.generateFileList = function(diffFiles) { - var lineTemplate = hoganUtils.template(baseTemplatesPath, 'line'); - - var files = diffFiles.map(function(file) { - var fileTypeName = printerUtils.getFileTypeIcon(file); - var iconTemplate = hoganUtils.template(iconsBaseTemplatesPath, fileTypeName); - - return lineTemplate.render({ - fileHtmlId: printerUtils.getHtmlId(file), - oldName: file.oldName, - newName: file.newName, - fileName: printerUtils.getDiffName(file), - deletedLines: '-' + file.deletedLines, - addedLines: '+' + file.addedLines - }, { - fileIcon: iconTemplate - }); - }).join('\n'); - - return hoganUtils.render(baseTemplatesPath, 'wrapper', { - filesNumber: diffFiles.length, - files: files - }); - }; - - module.exports.FileListPrinter = FileListPrinter; -})(); - -},{"./hoganjs-utils.js":12,"./printer-utils.js":15}],12:[function(require,module,exports){ -(function (__dirname){ -/* - * - * Utils (hoganjs-utils.js) - * Author: rtfpessoa - * - */ - -(function() { - var fs = require('fs'); - var path = require('path'); - var hogan = require('hogan.js'); - - var hoganTemplates = require('./templates/diff2html-templates.js'); - - var extraTemplates; - - function HoganJsUtils(configuration) { - this.config = configuration || {}; - extraTemplates = this.config.templates || {}; - - var rawTemplates = this.config.rawTemplates || {}; - for (var templateName in rawTemplates) { - if (rawTemplates.hasOwnProperty(templateName)) { - if (!extraTemplates[templateName]) extraTemplates[templateName] = this.compile(rawTemplates[templateName]); - } - } - } - - HoganJsUtils.prototype.render = function(namespace, view, params) { - var template = this.template(namespace, view); - if (template) { - return template.render(params); - } - - return null; - }; - - HoganJsUtils.prototype.template = function(namespace, view) { - var templateKey = this._templateKey(namespace, view); - - return this._getTemplate(templateKey); - }; - - HoganJsUtils.prototype._getTemplate = function(templateKey) { - var template; - - if (!this.config.noCache) { - template = this._readFromCache(templateKey); - } - - if (!template) { - template = this._loadTemplate(templateKey); - } - - return template; - }; - - HoganJsUtils.prototype._loadTemplate = function(templateKey) { - var template; - - try { - if (fs.readFileSync) { - var templatesPath = path.resolve(__dirname, 'templates'); - var templatePath = path.join(templatesPath, templateKey); - var templateContent = fs.readFileSync(templatePath + '.mustache', 'utf8'); - template = hogan.compile(templateContent); - hoganTemplates[templateKey] = template; - } - } catch (e) { - console.error('Failed to read (template: ' + templateKey + ') from fs: ' + e.message); - } - - return template; - }; - - HoganJsUtils.prototype._readFromCache = function(templateKey) { - return extraTemplates[templateKey] || hoganTemplates[templateKey]; - }; - - HoganJsUtils.prototype._templateKey = function(namespace, view) { - return namespace + '-' + view; - }; - - HoganJsUtils.prototype.compile = function(templateStr) { - return hogan.compile(templateStr); - }; - - module.exports.HoganJsUtils = HoganJsUtils; -})(); - -}).call(this,"/src") -},{"./templates/diff2html-templates.js":18,"fs":1,"hogan.js":4,"path":7}],13:[function(require,module,exports){ -/* - * - * HtmlPrinter (html-printer.js) - * Author: rtfpessoa - * - */ - -(function() { - var LineByLinePrinter = require('./line-by-line-printer.js').LineByLinePrinter; - var SideBySidePrinter = require('./side-by-side-printer.js').SideBySidePrinter; - var FileListPrinter = require('./file-list-printer.js').FileListPrinter; - - function HtmlPrinter() { - } - - HtmlPrinter.prototype.generateLineByLineJsonHtml = function(diffFiles, config) { - var lineByLinePrinter = new LineByLinePrinter(config); - return lineByLinePrinter.generateLineByLineJsonHtml(diffFiles); - }; - - HtmlPrinter.prototype.generateSideBySideJsonHtml = function(diffFiles, config) { - var sideBySidePrinter = new SideBySidePrinter(config); - return sideBySidePrinter.generateSideBySideJsonHtml(diffFiles); - }; - - HtmlPrinter.prototype.generateFileListSummary = function(diffJson, config) { - var fileListPrinter = new FileListPrinter(config); - return fileListPrinter.generateFileList(diffJson); - }; - - module.exports.HtmlPrinter = new HtmlPrinter(); -})(); - -},{"./file-list-printer.js":11,"./line-by-line-printer.js":14,"./side-by-side-printer.js":17}],14:[function(require,module,exports){ -/* - * - * LineByLinePrinter (line-by-line-printer.js) - * Author: rtfpessoa - * - */ - -(function() { - var diffParser = require('./diff-parser.js').DiffParser; - var printerUtils = require('./printer-utils.js').PrinterUtils; - var utils = require('./utils.js').Utils; - var Rematch = require('./rematch.js').Rematch; - - var hoganUtils; - - var genericTemplatesPath = 'generic'; - var baseTemplatesPath = 'line-by-line'; - var iconsBaseTemplatesPath = 'icon'; - var tagsBaseTemplatesPath = 'tag'; - - function LineByLinePrinter(config) { - this.config = config; - - var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils; - hoganUtils = new HoganJsUtils(config); - } - - LineByLinePrinter.prototype.makeFileDiffHtml = function(file, diffs) { - if (this.config.renderNothingWhenEmpty && file.blocks && !file.blocks.length) return ''; - - var fileDiffTemplate = hoganUtils.template(baseTemplatesPath, 'file-diff'); - var filePathTemplate = hoganUtils.template(genericTemplatesPath, 'file-path'); - var fileIconTemplate = hoganUtils.template(iconsBaseTemplatesPath, 'file'); - var fileTagTemplate = hoganUtils.template(tagsBaseTemplatesPath, printerUtils.getFileTypeIcon(file)); - - return fileDiffTemplate.render({ - file: file, - fileHtmlId: printerUtils.getHtmlId(file), - diffs: diffs, - filePath: filePathTemplate.render({ - fileDiffName: printerUtils.getDiffName(file) - }, { - fileIcon: fileIconTemplate, - fileTag: fileTagTemplate - }) - }); - }; - - LineByLinePrinter.prototype.makeLineByLineHtmlWrapper = function(content) { - return hoganUtils.render(genericTemplatesPath, 'wrapper', {'content': content}); - }; - - LineByLinePrinter.prototype.generateLineByLineJsonHtml = function(diffFiles) { - var that = this; - var htmlDiffs = diffFiles.map(function(file) { - var diffs; - if (file.blocks.length) { - diffs = that._generateFileHtml(file); - } else { - diffs = that._generateEmptyDiff(); - } - return that.makeFileDiffHtml(file, diffs); - }); - - return this.makeLineByLineHtmlWrapper(htmlDiffs.join('\n')); - }; - - var matcher = Rematch.rematch(function(a, b) { - var amod = a.content.substr(1); - var bmod = b.content.substr(1); - - return Rematch.distance(amod, bmod); - }); - - LineByLinePrinter.prototype.makeColumnLineNumberHtml = function(block) { - return hoganUtils.render(genericTemplatesPath, 'column-line-number', { - diffParser: diffParser, - blockHeader: utils.escape(block.header), - lineClass: 'd2h-code-linenumber', - contentClass: 'd2h-code-line' - }); - }; - - LineByLinePrinter.prototype._generateFileHtml = function(file) { - var that = this; - return file.blocks.map(function(block) { - var lines = that.makeColumnLineNumberHtml(block); - var oldLines = []; - var newLines = []; - - function processChangeBlock() { - var matches; - var insertType; - var deleteType; - - var comparisons = oldLines.length * newLines.length; - - var maxLineSizeInBlock = Math.max.apply(null, - [0].concat((oldLines.concat(newLines)).map( - function(elem) { - return elem.content.length; - } - ))); - - var doMatching = comparisons < that.config.matchingMaxComparisons && - maxLineSizeInBlock < that.config.maxLineSizeInBlockForComparison && - (that.config.matching === 'lines' || that.config.matching === 'words'); - - if (doMatching) { - matches = matcher(oldLines, newLines); - insertType = diffParser.LINE_TYPE.INSERT_CHANGES; - deleteType = diffParser.LINE_TYPE.DELETE_CHANGES; - } else { - matches = [[oldLines, newLines]]; - insertType = diffParser.LINE_TYPE.INSERTS; - deleteType = diffParser.LINE_TYPE.DELETES; - } - - matches.forEach(function(match) { - oldLines = match[0]; - newLines = match[1]; - - var processedOldLines = []; - var processedNewLines = []; - - var common = Math.min(oldLines.length, newLines.length); - - var oldLine, newLine; - for (var j = 0; j < common; j++) { - oldLine = oldLines[j]; - newLine = newLines[j]; - - that.config.isCombined = file.isCombined; - var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config); - - processedOldLines += - that.makeLineHtml(file.isCombined, deleteType, oldLine.oldNumber, oldLine.newNumber, - diff.first.line, diff.first.prefix); - processedNewLines += - that.makeLineHtml(file.isCombined, insertType, newLine.oldNumber, newLine.newNumber, - diff.second.line, diff.second.prefix); - } - - lines += processedOldLines + processedNewLines; - lines += that._processLines(file.isCombined, oldLines.slice(common), newLines.slice(common)); - }); - - oldLines = []; - newLines = []; - } - - for (var i = 0; i < block.lines.length; i++) { - var line = block.lines[i]; - var escapedLine = utils.escape(line.content); - - if (line.type !== diffParser.LINE_TYPE.INSERTS && - (newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0))) { - processChangeBlock(); - } - - if (line.type === diffParser.LINE_TYPE.CONTEXT) { - lines += that.makeLineHtml(file.isCombined, line.type, line.oldNumber, line.newNumber, escapedLine); - } else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) { - lines += that.makeLineHtml(file.isCombined, line.type, line.oldNumber, line.newNumber, escapedLine); - } else if (line.type === diffParser.LINE_TYPE.DELETES) { - oldLines.push(line); - } else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) { - newLines.push(line); - } else { - console.error('Unknown state in html line-by-line generator'); - processChangeBlock(); - } - } - - processChangeBlock(); - - return lines; - }).join('\n'); - }; - - LineByLinePrinter.prototype._processLines = function(isCombined, oldLines, newLines) { - var lines = ''; - - for (var i = 0; i < oldLines.length; i++) { - var oldLine = oldLines[i]; - var oldEscapedLine = utils.escape(oldLine.content); - lines += this.makeLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine); - } - - for (var j = 0; j < newLines.length; j++) { - var newLine = newLines[j]; - var newEscapedLine = utils.escape(newLine.content); - lines += this.makeLineHtml(isCombined, newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine); - } - - return lines; - }; - - LineByLinePrinter.prototype.makeLineHtml = function(isCombined, type, oldNumber, newNumber, content, possiblePrefix) { - var lineNumberTemplate = hoganUtils.render(baseTemplatesPath, 'numbers', { - oldNumber: utils.valueOrEmpty(oldNumber), - newNumber: utils.valueOrEmpty(newNumber) - }); - - var lineWithoutPrefix = content; - var prefix = possiblePrefix; - - if (!prefix) { - var lineWithPrefix = printerUtils.separatePrefix(isCombined, content); - prefix = lineWithPrefix.prefix; - lineWithoutPrefix = lineWithPrefix.line; - } - - if (prefix === ' ') { - prefix = ' '; - } - - return hoganUtils.render(genericTemplatesPath, 'line', - { - type: type, - lineClass: 'd2h-code-linenumber', - contentClass: 'd2h-code-line', - prefix: prefix, - content: lineWithoutPrefix, - lineNumber: lineNumberTemplate - }); - }; - - LineByLinePrinter.prototype._generateEmptyDiff = function() { - return hoganUtils.render(genericTemplatesPath, 'empty-diff', { - contentClass: 'd2h-code-line', - diffParser: diffParser - }); - }; - - module.exports.LineByLinePrinter = LineByLinePrinter; -})(); - -},{"./diff-parser.js":9,"./hoganjs-utils.js":12,"./printer-utils.js":15,"./rematch.js":16,"./utils.js":19}],15:[function(require,module,exports){ -/* - * - * PrinterUtils (printer-utils.js) - * Author: rtfpessoa - * - */ - -(function() { - var jsDiff = require('diff'); - var utils = require('./utils.js').Utils; - var Rematch = require('./rematch.js').Rematch; - - var separator = '/'; - - function PrinterUtils() { - } - - PrinterUtils.prototype.separatePrefix = function(isCombined, line) { - var prefix; - var lineWithoutPrefix; - - if (isCombined) { - prefix = line.substring(0, 2); - lineWithoutPrefix = line.substring(2); - } else { - prefix = line.substring(0, 1); - lineWithoutPrefix = line.substring(1); - } - - return { - 'prefix': prefix, - 'line': lineWithoutPrefix - }; - }; - - PrinterUtils.prototype.getHtmlId = function(file) { - var hashCode = function(text) { - var i, chr, len; - var hash = 0; - - for (i = 0, len = text.length; i < len; i++) { - chr = text.charCodeAt(i); - hash = ((hash << 5) - hash) + chr; - hash |= 0; // Convert to 32bit integer - } - - return hash; - }; - - return 'd2h-' + hashCode(this.getDiffName(file)).toString().slice(-6); - }; - - PrinterUtils.prototype.getDiffName = function(file) { - var oldFilename = unifyPath(file.oldName); - var newFilename = unifyPath(file.newName); - - if (oldFilename && newFilename && oldFilename !== newFilename && !isDevNullName(oldFilename) && !isDevNullName(newFilename)) { - var prefixPaths = []; - var suffixPaths = []; - - var oldFilenameParts = oldFilename.split(separator); - var newFilenameParts = newFilename.split(separator); - - var oldFilenamePartsSize = oldFilenameParts.length; - var newFilenamePartsSize = newFilenameParts.length; - - var i = 0; - var j = oldFilenamePartsSize - 1; - var k = newFilenamePartsSize - 1; - - while (i < j && i < k) { - if (oldFilenameParts[i] === newFilenameParts[i]) { - prefixPaths.push(newFilenameParts[i]); - i += 1; - } else { - break; - } - } - - while (j > i && k > i) { - if (oldFilenameParts[j] === newFilenameParts[k]) { - suffixPaths.unshift(newFilenameParts[k]); - j -= 1; - k -= 1; - } else { - break; - } - } - - var finalPrefix = prefixPaths.join(separator); - var finalSuffix = suffixPaths.join(separator); - - var oldRemainingPath = oldFilenameParts.slice(i, j + 1).join(separator); - var newRemainingPath = newFilenameParts.slice(i, k + 1).join(separator); - - if (finalPrefix.length && finalSuffix.length) { - return finalPrefix + separator + '{' + oldRemainingPath + ' → ' + newRemainingPath + '}' + separator + finalSuffix; - } else if (finalPrefix.length) { - return finalPrefix + separator + '{' + oldRemainingPath + ' → ' + newRemainingPath + '}'; - } else if (finalSuffix.length) { - return '{' + oldRemainingPath + ' → ' + newRemainingPath + '}' + separator + finalSuffix; - } - - return oldFilename + ' → ' + newFilename; - } else if (newFilename && !isDevNullName(newFilename)) { - return newFilename; - } else if (oldFilename) { - return oldFilename; - } - - return 'unknown/file/path'; - }; - - PrinterUtils.prototype.getFileTypeIcon = function(file) { - var templateName = 'file-changed'; - - if (file.isRename) { - templateName = 'file-renamed'; - } else if (file.isCopy) { - templateName = 'file-renamed'; - } else if (file.isNew) { - templateName = 'file-added'; - } else if (file.isDeleted) { - templateName = 'file-deleted'; - } else if (file.newName !== file.oldName) { - // If file is not Added, not Deleted and the names changed it must be a rename :) - templateName = 'file-renamed'; - } - - return templateName; - }; - - PrinterUtils.prototype.diffHighlight = function(diffLine1, diffLine2, config) { - var linePrefix1, linePrefix2, unprefixedLine1, unprefixedLine2; - - var prefixSize = 1; - - if (config.isCombined) { - prefixSize = 2; - } - - linePrefix1 = diffLine1.substr(0, prefixSize); - linePrefix2 = diffLine2.substr(0, prefixSize); - unprefixedLine1 = diffLine1.substr(prefixSize); - unprefixedLine2 = diffLine2.substr(prefixSize); - - if (unprefixedLine1.length > config.maxLineLengthHighlight || - unprefixedLine2.length > config.maxLineLengthHighlight) { - return { - first: { - prefix: linePrefix1, - line: utils.escape(unprefixedLine1) - }, - second: { - prefix: linePrefix2, - line: utils.escape(unprefixedLine2) - } - }; - } - - var diff; - if (config.diffStyle === 'char') { - diff = jsDiff.diffChars(unprefixedLine1, unprefixedLine2); - } else { - diff = jsDiff.diffWordsWithSpace(unprefixedLine1, unprefixedLine2); - } - - var highlightedLine = ''; - - var changedWords = []; - if (config.diffStyle === 'word' && config.matching === 'words') { - var treshold = 0.25; - - if (typeof (config.matchWordsThreshold) !== 'undefined') { - treshold = config.matchWordsThreshold; - } - - var matcher = Rematch.rematch(function(a, b) { - var amod = a.value; - var bmod = b.value; - - return Rematch.distance(amod, bmod); - }); - - var removed = diff.filter(function isRemoved(element) { - return element.removed; - }); - - var added = diff.filter(function isAdded(element) { - return element.added; - }); - - var chunks = matcher(added, removed); - chunks.forEach(function(chunk) { - if (chunk[0].length === 1 && chunk[1].length === 1) { - var dist = Rematch.distance(chunk[0][0].value, chunk[1][0].value); - if (dist < treshold) { - changedWords.push(chunk[0][0]); - changedWords.push(chunk[1][0]); - } - } - }); - } - - diff.forEach(function(part) { - var addClass = changedWords.indexOf(part) > -1 ? ' class="d2h-change"' : ''; - var elemType = part.added ? 'ins' : part.removed ? 'del' : null; - var escapedValue = utils.escape(part.value); - - if (elemType !== null) { - highlightedLine += '<' + elemType + addClass + '>' + escapedValue + ''; - } else { - highlightedLine += escapedValue; - } - }); - - return { - first: { - prefix: linePrefix1, - line: removeIns(highlightedLine) - }, - second: { - prefix: linePrefix2, - line: removeDel(highlightedLine) - } - }; - }; - - function unifyPath(path) { - if (path) { - return path.replace('\\', '/'); - } - - return path; - } - - function isDevNullName(name) { - return name.indexOf('dev/null') !== -1; - } - - function removeIns(line) { - return line.replace(/(]*>((.|\n)*?)<\/ins>)/g, ''); - } - - function removeDel(line) { - return line.replace(/(]*>((.|\n)*?)<\/del>)/g, ''); - } - - module.exports.PrinterUtils = new PrinterUtils(); -})(); - -},{"./rematch.js":16,"./utils.js":19,"diff":2}],16:[function(require,module,exports){ -/* - * - * Rematch (rematch.js) - * Matching two sequences of objects by similarity - * Author: W. Illmeyer, Nexxar GmbH - * - */ - -(function() { - var Rematch = {}; - - /* - Copyright (c) 2011 Andrei Mackenzie - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated - documentation files (the "Software"), to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, - and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO - THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - function levenshtein(a, b) { - if (a.length === 0) { - return b.length; - } - if (b.length === 0) { - return a.length; - } - - var matrix = []; - - // Increment along the first column of each row - var i; - for (i = 0; i <= b.length; i++) { - matrix[i] = [i]; - } - - // Increment each column in the first row - var j; - for (j = 0; j <= a.length; j++) { - matrix[0][j] = j; - } - - // Fill in the rest of the matrix - for (i = 1; i <= b.length; i++) { - for (j = 1; j <= a.length; j++) { - if (b.charAt(i - 1) === a.charAt(j - 1)) { - matrix[i][j] = matrix[i - 1][j - 1]; - } else { - matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // Substitution - Math.min(matrix[i][j - 1] + 1, // Insertion - matrix[i - 1][j] + 1)); // Deletion - } - } - } - - return matrix[b.length][a.length]; - } - - Rematch.levenshtein = levenshtein; - - Rematch.distance = function distance(x, y) { - x = x.trim(); - y = y.trim(); - var lev = levenshtein(x, y); - var score = lev / (x.length + y.length); - - return score; - }; - - Rematch.rematch = function rematch(distanceFunction) { - function findBestMatch(a, b, cache) { - var bestMatchDist = Infinity; - var bestMatch; - for (var i = 0; i < a.length; ++i) { - for (var j = 0; j < b.length; ++j) { - var cacheKey = JSON.stringify([a[i], b[j]]); - var md; - if (cache.hasOwnProperty(cacheKey)) { - md = cache[cacheKey]; - } else { - md = distanceFunction(a[i], b[j]); - cache[cacheKey] = md; - } - if (md < bestMatchDist) { - bestMatchDist = md; - bestMatch = {indexA: i, indexB: j, score: bestMatchDist}; - } - } - } - - return bestMatch; - } - - function group(a, b, level, cache) { - if (typeof (cache) === 'undefined') { - cache = {}; - } - - var bm = findBestMatch(a, b, cache); - - if (!level) { - level = 0; - } - - if (!bm || (a.length + b.length < 3)) { - return [[a, b]]; - } - - var a1 = a.slice(0, bm.indexA); - var b1 = b.slice(0, bm.indexB); - var aMatch = [a[bm.indexA]]; - var bMatch = [b[bm.indexB]]; - var tailA = bm.indexA + 1; - var tailB = bm.indexB + 1; - var a2 = a.slice(tailA); - var b2 = b.slice(tailB); - - var group1 = group(a1, b1, level + 1, cache); - var groupMatch = group(aMatch, bMatch, level + 1, cache); - var group2 = group(a2, b2, level + 1, cache); - var result = groupMatch; - - if (bm.indexA > 0 || bm.indexB > 0) { - result = group1.concat(result); - } - - if (a.length > tailA || b.length > tailB) { - result = result.concat(group2); - } - - return result; - } - - return group; - }; - - module.exports.Rematch = Rematch; -})(); - -},{}],17:[function(require,module,exports){ -/* - * - * HtmlPrinter (html-printer.js) - * Author: rtfpessoa - * - */ - -(function() { - var diffParser = require('./diff-parser.js').DiffParser; - var printerUtils = require('./printer-utils.js').PrinterUtils; - var utils = require('./utils.js').Utils; - var Rematch = require('./rematch.js').Rematch; - - var hoganUtils; - - var genericTemplatesPath = 'generic'; - var baseTemplatesPath = 'side-by-side'; - var iconsBaseTemplatesPath = 'icon'; - var tagsBaseTemplatesPath = 'tag'; - - var matcher = Rematch.rematch(function(a, b) { - var amod = a.content.substr(1); - var bmod = b.content.substr(1); - - return Rematch.distance(amod, bmod); - }); - - function SideBySidePrinter(config) { - this.config = config; - - var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils; - hoganUtils = new HoganJsUtils(config); - } - - SideBySidePrinter.prototype.makeDiffHtml = function(file, diffs) { - var fileDiffTemplate = hoganUtils.template(baseTemplatesPath, 'file-diff'); - var filePathTemplate = hoganUtils.template(genericTemplatesPath, 'file-path'); - var fileIconTemplate = hoganUtils.template(iconsBaseTemplatesPath, 'file'); - var fileTagTemplate = hoganUtils.template(tagsBaseTemplatesPath, printerUtils.getFileTypeIcon(file)); - - return fileDiffTemplate.render({ - file: file, - fileHtmlId: printerUtils.getHtmlId(file), - diffs: diffs, - filePath: filePathTemplate.render({ - fileDiffName: printerUtils.getDiffName(file) - }, { - fileIcon: fileIconTemplate, - fileTag: fileTagTemplate - }) - }); - }; - - SideBySidePrinter.prototype.generateSideBySideJsonHtml = function(diffFiles) { - var that = this; - - var content = diffFiles.map(function(file) { - var diffs; - if (file.blocks.length) { - diffs = that.generateSideBySideFileHtml(file); - } else { - diffs = that.generateEmptyDiff(); - } - - return that.makeDiffHtml(file, diffs); - }).join('\n'); - - return hoganUtils.render(genericTemplatesPath, 'wrapper', {'content': content}); - }; - - SideBySidePrinter.prototype.makeSideHtml = function(blockHeader) { - return hoganUtils.render(genericTemplatesPath, 'column-line-number', { - diffParser: diffParser, - blockHeader: utils.escape(blockHeader), - lineClass: 'd2h-code-side-linenumber', - contentClass: 'd2h-code-side-line' - }); - }; - - SideBySidePrinter.prototype.generateSideBySideFileHtml = function(file) { - var that = this; - var fileHtml = {}; - fileHtml.left = ''; - fileHtml.right = ''; - - file.blocks.forEach(function(block) { - fileHtml.left += that.makeSideHtml(block.header); - fileHtml.right += that.makeSideHtml(''); - - var oldLines = []; - var newLines = []; - - function processChangeBlock() { - var matches; - var insertType; - var deleteType; - - var comparisons = oldLines.length * newLines.length; - - var maxLineSizeInBlock = Math.max.apply(null, (oldLines.concat(newLines)).map(function(elem) { - return elem.length; - })); - - var doMatching = comparisons < that.config.matchingMaxComparisons && - maxLineSizeInBlock < that.config.maxLineSizeInBlockForComparison && - (that.config.matching === 'lines' || that.config.matching === 'words'); - - if (doMatching) { - matches = matcher(oldLines, newLines); - insertType = diffParser.LINE_TYPE.INSERT_CHANGES; - deleteType = diffParser.LINE_TYPE.DELETE_CHANGES; - } else { - matches = [[oldLines, newLines]]; - insertType = diffParser.LINE_TYPE.INSERTS; - deleteType = diffParser.LINE_TYPE.DELETES; - } - - matches.forEach(function(match) { - oldLines = match[0]; - newLines = match[1]; - - var common = Math.min(oldLines.length, newLines.length); - var max = Math.max(oldLines.length, newLines.length); - - for (var j = 0; j < common; j++) { - var oldLine = oldLines[j]; - var newLine = newLines[j]; - - that.config.isCombined = file.isCombined; - - var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config); - - fileHtml.left += - that.generateSingleLineHtml(file.isCombined, deleteType, oldLine.oldNumber, - diff.first.line, diff.first.prefix); - fileHtml.right += - that.generateSingleLineHtml(file.isCombined, insertType, newLine.newNumber, - diff.second.line, diff.second.prefix); - } - - if (max > common) { - var oldSlice = oldLines.slice(common); - var newSlice = newLines.slice(common); - - var tmpHtml = that.processLines(file.isCombined, oldSlice, newSlice); - fileHtml.left += tmpHtml.left; - fileHtml.right += tmpHtml.right; - } - }); - - oldLines = []; - newLines = []; - } - - for (var i = 0; i < block.lines.length; i++) { - var line = block.lines[i]; - var prefix = line.content[0]; - var escapedLine = utils.escape(line.content.substr(1)); - - if (line.type !== diffParser.LINE_TYPE.INSERTS && - (newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0))) { - processChangeBlock(); - } - - if (line.type === diffParser.LINE_TYPE.CONTEXT) { - fileHtml.left += that.generateSingleLineHtml(file.isCombined, line.type, line.oldNumber, escapedLine, prefix); - fileHtml.right += that.generateSingleLineHtml(file.isCombined, line.type, line.newNumber, escapedLine, prefix); - } else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) { - fileHtml.left += that.generateSingleLineHtml(file.isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', ''); - fileHtml.right += that.generateSingleLineHtml(file.isCombined, line.type, line.newNumber, escapedLine, prefix); - } else if (line.type === diffParser.LINE_TYPE.DELETES) { - oldLines.push(line); - } else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) { - newLines.push(line); - } else { - console.error('unknown state in html side-by-side generator'); - processChangeBlock(); - } - } - - processChangeBlock(); - }); - - return fileHtml; - }; - - SideBySidePrinter.prototype.processLines = function(isCombined, oldLines, newLines) { - var that = this; - var fileHtml = {}; - fileHtml.left = ''; - fileHtml.right = ''; - - var maxLinesNumber = Math.max(oldLines.length, newLines.length); - for (var i = 0; i < maxLinesNumber; i++) { - var oldLine = oldLines[i]; - var newLine = newLines[i]; - var oldContent; - var newContent; - var oldPrefix; - var newPrefix; - - if (oldLine) { - oldContent = utils.escape(oldLine.content.substr(1)); - oldPrefix = oldLine.content[0]; - } - - if (newLine) { - newContent = utils.escape(newLine.content.substr(1)); - newPrefix = newLine.content[0]; - } - - if (oldLine && newLine) { - fileHtml.left += that.generateSingleLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldContent, oldPrefix); - fileHtml.right += that.generateSingleLineHtml(isCombined, newLine.type, newLine.newNumber, newContent, newPrefix); - } else if (oldLine) { - fileHtml.left += that.generateSingleLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldContent, oldPrefix); - fileHtml.right += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', ''); - } else if (newLine) { - fileHtml.left += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', ''); - fileHtml.right += that.generateSingleLineHtml(isCombined, newLine.type, newLine.newNumber, newContent, newPrefix); - } else { - console.error('How did it get here?'); - } - } - - return fileHtml; - }; - - SideBySidePrinter.prototype.generateSingleLineHtml = function(isCombined, type, number, content, possiblePrefix) { - var lineWithoutPrefix = content; - var prefix = possiblePrefix; - var lineClass = 'd2h-code-side-linenumber'; - var contentClass = 'd2h-code-side-line'; - - if (!number && !content) { - lineClass += ' d2h-code-side-emptyplaceholder'; - contentClass += ' d2h-code-side-emptyplaceholder'; - type += ' d2h-emptyplaceholder'; - prefix = ' '; - lineWithoutPrefix = ' '; - } else if (!prefix) { - var lineWithPrefix = printerUtils.separatePrefix(isCombined, content); - prefix = lineWithPrefix.prefix; - lineWithoutPrefix = lineWithPrefix.line; - } - - if (prefix === ' ') { - prefix = ' '; - } - - return hoganUtils.render(genericTemplatesPath, 'line', - { - type: type, - lineClass: lineClass, - contentClass: contentClass, - prefix: prefix, - content: lineWithoutPrefix, - lineNumber: number - }); - }; - - SideBySidePrinter.prototype.generateEmptyDiff = function() { - var fileHtml = {}; - fileHtml.right = ''; - - fileHtml.left = hoganUtils.render(genericTemplatesPath, 'empty-diff', { - contentClass: 'd2h-code-side-line', - diffParser: diffParser - }); - - return fileHtml; - }; - - module.exports.SideBySidePrinter = SideBySidePrinter; -})(); - -},{"./diff-parser.js":9,"./hoganjs-utils.js":12,"./printer-utils.js":15,"./rematch.js":16,"./utils.js":19}],18:[function(require,module,exports){ -(function (global){ -(function() { -if (!!!global.browserTemplates) global.browserTemplates = {}; -var Hogan = require("hogan.js");global.browserTemplates["file-summary-line"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("
  • ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(t.rp("");t.b(t.v(t.f("fileName",c,p,0)));t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b(t.v(t.f("addedLines",c,p,0)));t.b("");t.b("\n" + i);t.b(" ");t.b(t.v(t.f("deletedLines",c,p,0)));t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
  • ");return t.fl(); },partials: {"");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" Files changed (");t.b(t.v(t.f("filesNumber",c,p,0)));t.b(")");t.b("\n" + i);t.b(" hide");t.b("\n" + i);t.b(" show");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
      ");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("files",c,p,0)));t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["generic-column-line-number"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
    ");t.b(t.t(t.f("blockHeader",c,p,0)));t.b("
    ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["generic-empty-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" File without changes");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["generic-file-path"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(t.rp("");t.b(t.v(t.f("fileDiffName",c,p,0)));t.b("");t.b("\n" + i);t.b(t.rp("");return t.fl(); },partials: {"");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("lineNumber",c,p,0)));t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);if(t.s(t.f("prefix",c,p,1),c,p,0,171,247,"{{ }}")){t.rs(c,p,function(c,p,t){t.b(" ");t.b(t.t(t.f("prefix",c,p,0)));t.b("");t.b("\n" + i);});c.pop();}if(t.s(t.f("content",c,p,1),c,p,0,279,353,"{{ }}")){t.rs(c,p,function(c,p,t){t.b(" ");t.b(t.t(t.f("content",c,p,0)));t.b("");t.b("\n" + i);});c.pop();}t.b("
    ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["generic-wrapper"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("
    ");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("content",c,p,0)));t.b("\n" + i);t.b("
    ");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["icon-file-added"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["icon-file-changed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["icon-file-deleted"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["icon-file-renamed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["icon-file"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["line-by-line-file-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("filePath",c,p,0)));t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("diffs",c,p,0)));t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["line-by-line-numbers"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("
    ");t.b(t.v(t.f("oldNumber",c,p,0)));t.b("
    ");t.b("\n" + i);t.b("
    ");t.b(t.v(t.f("newNumber",c,p,0)));t.b("
    ");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["side-by-side-file-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("filePath",c,p,0)));t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b(t.t(t.d("diffs.left",c,p,0)));t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b(t.t(t.d("diffs.right",c,p,0)));t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["tag-file-added"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("ADDED");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["tag-file-changed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("CHANGED");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["tag-file-deleted"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("DELETED");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["tag-file-renamed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("RENAMED");return t.fl(); },partials: {}, subs: { }}); -module.exports = global.browserTemplates; -})(); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"hogan.js":4}],19:[function(require,module,exports){ -/* - * - * Utils (utils.js) - * Author: rtfpessoa - * - */ - -(function() { - var merge = require('merge'); - - function Utils() { - } - - Utils.prototype.escape = function(str) { - return str.slice(0) - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, ''') - .replace(/\//g, '/'); - }; - - Utils.prototype.startsWith = function(str, start) { - if (typeof start === 'object') { - var result = false; - start.forEach(function(s) { - if (str.indexOf(s) === 0) { - result = true; - } - }); - - return result; - } - - return str && str.indexOf(start) === 0; - }; - - Utils.prototype.valueOrEmpty = function(value) { - return value || ''; - }; - - Utils.prototype.safeConfig = function(cfg, defaultConfig) { - return merge.recursive(true, defaultConfig, cfg); - }; - - module.exports.Utils = new Utils(); -})(); - -},{"merge":6}]},{},[10]); diff --git a/dist/diff2html.min.css b/dist/diff2html.min.css deleted file mode 100644 index 171a77c..0000000 --- a/dist/diff2html.min.css +++ /dev/null @@ -1 +0,0 @@ -.d2h-wrapper{text-align:left}.d2h-file-header{height:35px;padding:5px 10px;border-bottom:1px solid #d8d8d8;background-color:#f7f7f7}.d2h-file-stats{display:flex;margin-left:auto;font-size:14px}.d2h-lines-added{text-align:right;border:1px solid #b4e2b4;border-radius:5px 0 0 5px;color:#399839;padding:2px;vertical-align:middle}.d2h-lines-deleted{text-align:left;border:1px solid #e9aeae;border-radius:0 5px 5px 0;color:#c33;padding:2px;vertical-align:middle;margin-left:1px}.d2h-file-name-wrapper{display:flex;align-items:center;width:100%;font-family:"Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px}.d2h-file-name{white-space:nowrap;text-overflow:ellipsis;overflow-x:hidden}.d2h-file-wrapper{border:1px solid #ddd;border-radius:3px;margin-bottom:1em}.d2h-diff-table{width:100%;border-collapse:collapse;font-family:Menlo,Consolas,monospace;font-size:13px}.d2h-files-diff{display:block;width:100%;height:100%}.d2h-file-diff{overflow-y:hidden}.d2h-file-side-diff{display:inline-block;overflow-x:scroll;overflow-y:hidden;width:50%;margin-right:-4px;margin-bottom:-8px}.d2h-code-line{display:inline-block;white-space:nowrap;padding:0 8em}.d2h-code-side-line{display:inline-block;white-space:nowrap;padding:0 4.5em}.d2h-code-line del,.d2h-code-side-line del{display:inline-block;margin-top:-1px;text-decoration:none;background-color:#ffb6ba;border-radius:.2em}.d2h-code-line ins,.d2h-code-side-line ins{display:inline-block;margin-top:-1px;text-decoration:none;background-color:#97f295;border-radius:.2em;text-align:left}.d2h-code-line-prefix{display:inline;background:0 0;padding:0;word-wrap:normal;white-space:pre}.d2h-code-line-ctn{display:inline;background:0 0;padding:0;word-wrap:normal;white-space:pre}.line-num1{box-sizing:border-box;float:left;width:3.5em;overflow:hidden;text-overflow:ellipsis;padding:0 .5em 0 .5em}.line-num2{box-sizing:border-box;float:right;width:3.5em;overflow:hidden;text-overflow:ellipsis;padding:0 .5em 0 .5em}.d2h-code-linenumber{box-sizing:border-box;width:7.5em;position:absolute;display:inline-block;background-color:#fff;color:rgba(0,0,0,.3);text-align:right;border:solid #eee;border-width:0 1px 0 1px;cursor:pointer}.d2h-code-linenumber:after{content:'\200b'}.d2h-code-side-linenumber{position:absolute;display:inline-block;box-sizing:border-box;width:4em;background-color:#fff;color:rgba(0,0,0,.3);text-align:right;border:solid #eee;border-width:0 1px 0 1px;cursor:pointer;overflow:hidden;text-overflow:ellipsis}.d2h-code-side-linenumber:after{content:'\200b'}.d2h-code-side-emptyplaceholder,.d2h-emptyplaceholder{background-color:#f1f1f1;border-color:#e1e1e1}.d2h-del{background-color:#fee8e9;border-color:#e9aeae}.d2h-ins{background-color:#dfd;border-color:#b4e2b4}.d2h-info{background-color:#f8fafd;color:rgba(0,0,0,.3);border-color:#d5e4f2}.d2h-file-diff .d2h-del.d2h-change{background-color:#fdf2d0}.d2h-file-diff .d2h-ins.d2h-change{background-color:#ded}.d2h-file-list-wrapper{margin-bottom:10px}.d2h-file-list-wrapper a{text-decoration:none;color:#3572b0}.d2h-file-list-wrapper a:visited{color:#3572b0}.d2h-file-list-header{text-align:left}.d2h-file-list-title{font-weight:700}.d2h-file-list-line{display:flex;text-align:left}.d2h-file-list{display:block;list-style:none;padding:0;margin:0}.d2h-file-list>li{border-bottom:#ddd solid 1px;padding:5px 10px;margin:0}.d2h-file-list>li:last-child{border-bottom:none}.d2h-file-switch{display:none;font-size:10px;cursor:pointer}.d2h-icon{vertical-align:middle;margin-right:10px;fill:currentColor}.d2h-deleted{color:#c33}.d2h-added{color:#399839}.d2h-changed{color:#d0b44c}.d2h-moved{color:#3572b0}.d2h-tag{display:flex;font-size:10px;margin-left:5px;padding:0 2px;background-color:#fff}.d2h-deleted-tag{border:#c33 1px solid}.d2h-added-tag{border:#399839 1px solid}.d2h-changed-tag{border:#d0b44c 1px solid}.d2h-moved-tag{border:#3572b0 1px solid}.selecting-left .d2h-code-line,.selecting-left .d2h-code-line *,.selecting-left .d2h-code-side-line,.selecting-left .d2h-code-side-line *,.selecting-right td.d2h-code-linenumber,.selecting-right td.d2h-code-linenumber *,.selecting-right td.d2h-code-side-linenumber,.selecting-right td.d2h-code-side-linenumber *{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.selecting-left .d2h-code-line ::-moz-selection,.selecting-left .d2h-code-line::-moz-selection,.selecting-left .d2h-code-side-line ::-moz-selection,.selecting-left .d2h-code-side-line::-moz-selection,.selecting-right td.d2h-code-linenumber::-moz-selection,.selecting-right td.d2h-code-side-linenumber ::-moz-selection,.selecting-right td.d2h-code-side-linenumber::-moz-selection{background:0 0}.selecting-left .d2h-code-line ::selection,.selecting-left .d2h-code-line::selection,.selecting-left .d2h-code-side-line ::selection,.selecting-left .d2h-code-side-line::selection,.selecting-right td.d2h-code-linenumber::selection,.selecting-right td.d2h-code-side-linenumber ::selection,.selecting-right td.d2h-code-side-linenumber::selection{background:0 0} \ No newline at end of file diff --git a/dist/diff2html.min.js b/dist/diff2html.min.js deleted file mode 100644 index ca724b3..0000000 --- a/dist/diff2html.min.js +++ /dev/null @@ -1 +0,0 @@ -!function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){return o(e[i][1][r]||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;ivalue.length?oldValue:value}),component.value=diff.join(value)}else component.value=diff.join(newString.slice(newPos,newPos+component.count));newPos+=component.count,component.added||(oldPos+=component.count)}}var lastComponent=components[componentLen-1];return 1=newLen&&oldLen<=oldPos+1)return done([{value:this.join(newString),count:newString.length}]);function execEditLength(){for(var diagonalPath=-1*editLength;diagonalPath<=editLength;diagonalPath+=2){var basePath=void 0,addPath=bestPath[diagonalPath-1],removePath=bestPath[diagonalPath+1],_oldPos=(removePath?removePath.newPos:0)-diagonalPath;addPath&&(bestPath[diagonalPath-1]=void 0);var canAdd=addPath&&addPath.newPos+1=newLen&&oldLen<=_oldPos+1)return done(buildValues(self,basePath.components,newString,oldString,self.useLongestToken));bestPath[diagonalPath]=basePath}else bestPath[diagonalPath]=void 0}var path;editLength++}if(callback)!function exec(){setTimeout(function(){if(maxEditLength=diff.length-2&&lines.length<=options.context){var oldEOFNewline=/\n$/.test(oldStr),newEOFNewline=/\n$/.test(newStr),noNlBeforeAdds=0==lines.length&&curRange.length>hunk.oldLines;!oldEOFNewline&&noNlBeforeAdds&&curRange.splice(hunk.oldLines,0,"\\ No newline at end of file"),(oldEOFNewline||noNlBeforeAdds)&&newEOFNewline||curRange.push("\\ No newline at end of file")}hunks.push(hunk),newRangeStart=oldRangeStart=0,curRange=[]}oldLine+=lines.length,newLine+=lines.length}},i=0;iarray.length)return!1;for(var i=0;i/g,">")).replace(/"/g,""")}arrayDiff.tokenize=function(value){return value.slice()},arrayDiff.join=arrayDiff.removeEmpty=function(value){return value},exports.Diff=Diff,exports.diffChars=function(oldStr,newStr,options){return characterDiff.diff(oldStr,newStr,options)},exports.diffWords=function(oldStr,newStr,options){return options=generateOptions(options,{ignoreWhitespace:!0}),wordDiff.diff(oldStr,newStr,options)},exports.diffWordsWithSpace=function(oldStr,newStr,options){return wordDiff.diff(oldStr,newStr,options)},exports.diffLines=diffLines,exports.diffTrimmedLines=function(oldStr,newStr,callback){var options=generateOptions(callback,{ignoreWhitespace:!0});return lineDiff.diff(oldStr,newStr,options)},exports.diffSentences=function(oldStr,newStr,callback){return sentenceDiff.diff(oldStr,newStr,callback)},exports.diffCss=function(oldStr,newStr,callback){return cssDiff.diff(oldStr,newStr,callback)},exports.diffJson=function(oldObj,newObj,options){return jsonDiff.diff(oldObj,newObj,options)},exports.diffArrays=function(oldArr,newArr,callback){return arrayDiff.diff(oldArr,newArr,callback)},exports.structuredPatch=structuredPatch,exports.createTwoFilesPatch=createTwoFilesPatch,exports.createPatch=function(fileName,oldStr,newStr,oldHeader,newHeader,options){return createTwoFilesPatch(fileName,fileName,oldStr,newStr,oldHeader,newHeader,options)},exports.applyPatch=applyPatch,exports.applyPatches=function(uniDiff,options){"string"==typeof uniDiff&&(uniDiff=parsePatch(uniDiff));var currentIndex=0;!function processIndex(){var index=uniDiff[currentIndex++];if(!index)return options.complete();options.loadFile(index,function(err,data){if(err)return options.complete(err);var updatedContent=applyPatch(data,index,options);options.patched(index,updatedContent,function(err){if(err)return options.complete(err);processIndex()})})}()},exports.parsePatch=parsePatch,exports.merge=function(mine,theirs,base){mine=loadPatch(mine,base),theirs=loadPatch(theirs,base);var ret={};(mine.index||theirs.index)&&(ret.index=mine.index||theirs.index),(mine.newFileName||theirs.newFileName)&&(fileNameChanged(mine)?fileNameChanged(theirs)?(ret.oldFileName=selectField(ret,mine.oldFileName,theirs.oldFileName),ret.newFileName=selectField(ret,mine.newFileName,theirs.newFileName),ret.oldHeader=selectField(ret,mine.oldHeader,theirs.oldHeader),ret.newHeader=selectField(ret,mine.newHeader,theirs.newHeader)):(ret.oldFileName=mine.oldFileName,ret.newFileName=mine.newFileName,ret.oldHeader=mine.oldHeader,ret.newHeader=mine.newHeader):(ret.oldFileName=theirs.oldFileName||mine.oldFileName,ret.newFileName=theirs.newFileName||mine.newFileName,ret.oldHeader=theirs.oldHeader||mine.oldHeader,ret.newHeader=theirs.newHeader||mine.newHeader)),ret.hunks=[];for(var mineIndex=0,theirsIndex=0,mineOffset=0,theirsOffset=0;mineIndex"):change.removed&&ret.push(""),ret.push(escapeHTML(change.value)),change.added?ret.push(""):change.removed&&ret.push("")}return ret.join("")},exports.canonicalize=canonicalize,Object.defineProperty(exports,"__esModule",{value:!0})},"object"==typeof exports&&void 0!==module?factory(exports):"function"==typeof define&&define.amd?define(["exports"],factory):factory((global=global||self).Diff={})},{}],3:[function(require,module,exports){!function(Hogan){var rIsWhitespace=/\S/,rQuot=/\"/g,rNewline=/\n/g,rCr=/\r/g,rSlash=/\\/g,rLineSep=/\u2028/,rParagraphSep=/\u2029/;function cleanTripleStache(token){"}"===token.n.substr(token.n.length-1)&&(token.n=token.n.substring(0,token.n.length-1))}function trim(s){return s.trim?s.trim():s.replace(/^\s*|\s*$/g,"")}function tagChange(tag,text,index){if(text.charAt(index)!=tag.charAt(0))return!1;for(var i=1,l=tag.length;i":7,"=":8,_v:9,"{":10,"&":11,_t:12},Hogan.scan=function(text,delimiters){var len=text.length,state=0,tagType=null,tag=null,buf="",tokens=[],seenTag=!1,i=0,lineStart=0,otag="{{",ctag="}}";function addBuf(){0"==next.tag&&(next.indent=tokens[j].text.toString()),tokens.splice(j,1));else noNewLine||tokens.push({tag:"\n"});seenTag=!1,lineStart=tokens.length}function changeDelimiters(text,index){var close="="+ctag,closeIndex=text.indexOf(close,index),delimiters=trim(text.substring(text.indexOf("=",index)+1,closeIndex)).split(" ");return otag=delimiters[0],ctag=delimiters[delimiters.length-1],closeIndex+close.length-1}for(delimiters&&(delimiters=delimiters.split(" "),otag=delimiters[0],ctag=delimiters[1]),i=0;i":createPartial,"<":function(node,context){var ctx={partials:{},code:"",subs:{},inPartial:!0};Hogan.walk(node.nodes,ctx);var template=context.partials[createPartial(node,context)];template.subs=ctx.subs,template.partials=ctx.partials},$:function(node,context){var ctx={subs:{},code:"",partials:context.partials,prefix:node.n};Hogan.walk(node.nodes,ctx),context.subs[node.n]=ctx.code,context.inPartial||(context.code+='t.sub("'+esc(node.n)+'",c,p,i);')},"\n":function(node,context){context.code+=write('"\\n"'+(node.last?"":" + i"))},_v:function(node,context){context.code+="t.b(t.v(t."+chooseMethod(node.n)+'("'+esc(node.n)+'",c,p,0)));'},_t:function(node,context){context.code+=write('"'+esc(node.text)+'"')},"{":tripleStache,"&":tripleStache},Hogan.walk=function(nodelist,context){for(var func,i=0,l=nodelist.length;i/g,rApos=/\'/g,rQuot=/\"/g,hChars=/[&<>\"\']/;function coerceToString(val){return String(null==val?"":val)}var isArray=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)}}(void 0!==exports?exports:{})},{}],6:[function(require,module,exports){function merge_recursive(base,extend){if("object"!==typeOf(base))return extend;for(var key in extend)"object"===typeOf(base[key])&&"object"===typeOf(extend[key])?base[key]=merge_recursive(base[key],extend[key]):base[key]=extend[key];return base}function merge(clone,recursive,argv){var result=argv[0],size=argv.length;!clone&&"object"===typeOf(result)||(result={});for(var index=0;indexconfig.maxLineLengthHighlight||unprefixedLine2.length>config.maxLineLengthHighlight)return{first:{prefix:linePrefix1,line:utils.escape(unprefixedLine1)},second:{prefix:linePrefix2,line:utils.escape(unprefixedLine2)}};diff="char"===config.diffStyle?jsDiff.diffChars(unprefixedLine1,unprefixedLine2):jsDiff.diffWordsWithSpace(unprefixedLine1,unprefixedLine2);var highlightedLine="",changedWords=[];if("word"===config.diffStyle&&"words"===config.matching){var treshold=.25;void 0!==config.matchWordsThreshold&&(treshold=config.matchWordsThreshold);var matcher=Rematch.rematch(function(a,b){var amod=a.value,bmod=b.value;return Rematch.distance(amod,bmod)}),removed=diff.filter(function(element){return element.removed});matcher(diff.filter(function(element){return element.added}),removed).forEach(function(chunk){1===chunk[0].length&&1===chunk[1].length&&Rematch.distance(chunk[0][0].value,chunk[1][0].value)"+escapedValue+"":escapedValue}),{first:{prefix:linePrefix1,line:function(line){return line.replace(/(]*>((.|\n)*?)<\/ins>)/g,"")}(highlightedLine)},second:{prefix:linePrefix2,line:function(line){return line.replace(/(]*>((.|\n)*?)<\/del>)/g,"")}(highlightedLine)}}},module.exports.PrinterUtils=new PrinterUtils},{"./rematch.js":16,"./utils.js":19,diff:2}],16:[function(require,module,exports){function levenshtein(a,b){if(0===a.length)return b.length;if(0===b.length)return a.length;var i,j,matrix=[];for(i=0;i<=b.length;i++)matrix[i]=[i];for(j=0;j<=a.length;j++)matrix[0][j]=j;for(i=1;i<=b.length;i++)for(j=1;j<=a.length;j++)b.charAt(i-1)===a.charAt(j-1)?matrix[i][j]=matrix[i-1][j-1]:matrix[i][j]=Math.min(matrix[i-1][j-1]+1,Math.min(matrix[i][j-1]+1,matrix[i-1][j]+1));return matrix[b.length][a.length]}var Rematch;(Rematch={}).levenshtein=levenshtein,Rematch.distance=function(x,y){return levenshtein(x=x.trim(),y=y.trim())/(x.length+y.length)},Rematch.rematch=function(distanceFunction){return function group(a,b,level,cache){void 0===cache&&(cache={});var bm=function(a,b,cache){for(var bestMatch,bestMatchDist=1/0,i=0;itailA||b.length>tailB)&&(result=result.concat(group2)),result}},module.exports.Rematch=Rematch},{}],17:[function(require,module,exports){function SideBySidePrinter(config){this.config=config;var HoganJsUtils=require("./hoganjs-utils.js").HoganJsUtils;hoganUtils=new HoganJsUtils(config)}var hoganUtils,diffParser,printerUtils,utils,Rematch,matcher;diffParser=require("./diff-parser.js").DiffParser,printerUtils=require("./printer-utils.js").PrinterUtils,utils=require("./utils.js").Utils,Rematch=require("./rematch.js").Rematch,matcher=Rematch.rematch(function(a,b){var amod=a.content.substr(1),bmod=b.content.substr(1);return Rematch.distance(amod,bmod)}),SideBySidePrinter.prototype.makeDiffHtml=function(file,diffs){var fileDiffTemplate=hoganUtils.template("side-by-side","file-diff"),filePathTemplate=hoganUtils.template("generic","file-path"),fileIconTemplate=hoganUtils.template("icon","file"),fileTagTemplate=hoganUtils.template("tag",printerUtils.getFileTypeIcon(file));return fileDiffTemplate.render({file:file,fileHtmlId:printerUtils.getHtmlId(file),diffs:diffs,filePath:filePathTemplate.render({fileDiffName:printerUtils.getDiffName(file)},{fileIcon:fileIconTemplate,fileTag:fileTagTemplate})})},SideBySidePrinter.prototype.generateSideBySideJsonHtml=function(diffFiles){var that=this,content=diffFiles.map(function(file){var diffs;return diffs=file.blocks.length?that.generateSideBySideFileHtml(file):that.generateEmptyDiff(),that.makeDiffHtml(file,diffs)}).join("\n");return hoganUtils.render("generic","wrapper",{content:content})},SideBySidePrinter.prototype.makeSideHtml=function(blockHeader){return hoganUtils.render("generic","column-line-number",{diffParser:diffParser,blockHeader:utils.escape(blockHeader),lineClass:"d2h-code-side-linenumber",contentClass:"d2h-code-side-line"})},SideBySidePrinter.prototype.generateSideBySideFileHtml=function(file){var that=this,fileHtml={left:"",right:""};return file.blocks.forEach(function(block){fileHtml.left+=that.makeSideHtml(block.header),fileHtml.right+=that.makeSideHtml("");var oldLines=[],newLines=[];function processChangeBlock(){var matches,insertType,deleteType,comparisons=oldLines.length*newLines.length,maxLineSizeInBlock=Math.max.apply(null,oldLines.concat(newLines).map(function(elem){return elem.length})),doMatching=comparisons'),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b(t.rp("'),t.b(t.v(t.f("fileName",c,p,0))),t.b(""),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b(' '),t.b(t.v(t.f("addedLines",c,p,0))),t.b(""),t.b("\n"+i),t.b(' '),t.b(t.v(t.f("deletedLines",c,p,0))),t.b(""),t.b("\n"+i),t.b(" "),t.b("\n"+i),t.b(" "),t.b("\n"+i),t.b(""),t.fl()},partials:{"'),t.b("\n"+i),t.b('
    '),t.b("\n"+i),t.b(' Files changed ('),t.b(t.v(t.f("filesNumber",c,p,0))),t.b(")"),t.b("\n"+i),t.b(' hide'),t.b("\n"+i),t.b(' show'),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b('
      '),t.b("\n"+i),t.b(" "),t.b(t.t(t.f("files",c,p,0))),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b(""),t.fl()},partials:{},subs:{}}),global.browserTemplates["generic-column-line-number"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b(""),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b('
    '),t.b(t.t(t.f("blockHeader",c,p,0))),t.b("
    "),t.b("\n"+i),t.b(" "),t.b("\n"+i),t.b(""),t.fl()},partials:{},subs:{}}),global.browserTemplates["generic-empty-diff"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b(""),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b('
    '),t.b("\n"+i),t.b(" File without changes"),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b(" "),t.b("\n"+i),t.b(""),t.fl()},partials:{},subs:{}}),global.browserTemplates["generic-file-path"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b(''),t.b("\n"+i),t.b(t.rp("'),t.b(t.v(t.f("fileDiffName",c,p,0))),t.b(""),t.b("\n"+i),t.b(t.rp(""),t.fl()},partials:{""),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b(" "),t.b(t.t(t.f("lineNumber",c,p,0))),t.b("\n"+i),t.b(" "),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b('
    '),t.b("\n"+i),t.s(t.f("prefix",c,p,1),c,p,0,171,247,"{{ }}")&&(t.rs(c,p,function(c,p,t){t.b(' '),t.b(t.t(t.f("prefix",c,p,0))),t.b(""),t.b("\n"+i)}),c.pop()),t.s(t.f("content",c,p,1),c,p,0,279,353,"{{ }}")&&(t.rs(c,p,function(c,p,t){t.b(' '),t.b(t.t(t.f("content",c,p,0))),t.b(""),t.b("\n"+i)}),c.pop()),t.b("
    "),t.b("\n"+i),t.b(" "),t.b("\n"+i),t.b(""),t.fl()},partials:{},subs:{}}),global.browserTemplates["generic-wrapper"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('
    '),t.b("\n"+i),t.b(" "),t.b(t.t(t.f("content",c,p,0))),t.b("\n"+i),t.b("
    "),t.fl()},partials:{},subs:{}}),global.browserTemplates["icon-file-added"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('"),t.fl()},partials:{},subs:{}}),global.browserTemplates["icon-file-changed"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('"),t.fl()},partials:{},subs:{}}),global.browserTemplates["icon-file-deleted"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('"),t.fl()},partials:{},subs:{}}),global.browserTemplates["icon-file-renamed"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('"),t.fl()},partials:{},subs:{}}),global.browserTemplates["icon-file"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('"),t.fl()},partials:{},subs:{}}),global.browserTemplates["line-by-line-file-diff"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('
    '),t.b("\n"+i),t.b('
    '),t.b("\n"+i),t.b(" "),t.b(t.t(t.f("filePath",c,p,0))),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b('
    '),t.b("\n"+i),t.b('
    '),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b(" "),t.b(t.t(t.f("diffs",c,p,0))),t.b("\n"+i),t.b(" "),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b("
    "),t.fl()},partials:{},subs:{}}),global.browserTemplates["line-by-line-numbers"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('
    '),t.b(t.v(t.f("oldNumber",c,p,0))),t.b("
    "),t.b("\n"+i),t.b('
    '),t.b(t.v(t.f("newNumber",c,p,0))),t.b("
    "),t.fl()},partials:{},subs:{}}),global.browserTemplates["side-by-side-file-diff"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('
    '),t.b("\n"+i),t.b('
    '),t.b("\n"+i),t.b(" "),t.b(t.t(t.f("filePath",c,p,0))),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b('
    '),t.b("\n"+i),t.b('
    '),t.b("\n"+i),t.b('
    '),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b(" "),t.b(t.t(t.d("diffs.left",c,p,0))),t.b("\n"+i),t.b(" "),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b('
    '),t.b("\n"+i),t.b('
    '),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b(' '),t.b("\n"+i),t.b(" "),t.b(t.t(t.d("diffs.right",c,p,0))),t.b("\n"+i),t.b(" "),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b("
    "),t.b("\n"+i),t.b("
    "),t.fl()},partials:{},subs:{}}),global.browserTemplates["tag-file-added"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('ADDED'),t.fl()},partials:{},subs:{}}),global.browserTemplates["tag-file-changed"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('CHANGED'),t.fl()},partials:{},subs:{}}),global.browserTemplates["tag-file-deleted"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('DELETED'),t.fl()},partials:{},subs:{}}),global.browserTemplates["tag-file-renamed"]=new Hogan.Template({code:function(c,p,i){var t=this;return t.b(i=i||""),t.b('RENAMED'),t.fl()},partials:{},subs:{}}),module.exports=global.browserTemplates}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"hogan.js":4}],19:[function(require,module,exports){function Utils(){}var merge;merge=require("merge"),Utils.prototype.escape=function(str){return str.slice(0).replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")},Utils.prototype.startsWith=function(str,start){if("object"!=typeof start)return str&&0===str.indexOf(start);var result=!1;return start.forEach(function(s){0===str.indexOf(s)&&(result=!0)}),result},Utils.prototype.valueOrEmpty=function(value){return value||""},Utils.prototype.safeConfig=function(cfg,defaultConfig){return merge.recursive(!0,defaultConfig,cfg)},module.exports.Utils=new Utils},{merge:6}]},{},[10]); \ No newline at end of file diff --git a/docs/CNAME b/docs/CNAME deleted file mode 100644 index 62ff2fd..0000000 --- a/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -diff2html.xyz \ No newline at end of file diff --git a/docs/assets b/docs/assets deleted file mode 120000 index 85d8c32..0000000 --- a/docs/assets +++ /dev/null @@ -1 +0,0 @@ -../dist \ No newline at end of file diff --git a/docs/demo.html b/docs/demo.html deleted file mode 100644 index 938d8ea..0000000 --- a/docs/demo.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - - - - - - - - diff2html - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    - - -

    Diff Prettifier - - -

    -

    GitHub, Bitbucket and GitLab commit and pull request compatible

    -

    Just paste the GitHub, Bitbucket or GitLab commit, pull request or merge request url - or any other git or unified compatible diff and we will render a pretty html representation of it - with code syntax highlight and line similarity matching for better code reviews. -

    -

    Options:

    -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    -
    -
    - - Load -
    -
    -
    -
    -
    -

    Help:

    -
      -
    • - Why should I use this instead of GitHub, Bitbucket or GitLab? -

      Code Syntax Highlight

      -

      Line similarity match (similar lines are together)

      -

      Line by Line and Side by Side diffs

      -

      Supports any git and unified compatible diffs

      -

      Easy code selection

      -
    • -
    • - What urls are supported? -

      Any GitHub, Bitbucket or GitLab Commit, Pull Request or Merge Request urls.

      -

      Any Git or Unified Raw Diff or Patch urls.

      -
    • -
    • - Can I send a custom url for a friend, colleague or co-worker? -

      Just add a url parameter called diff to current url using as value your Commit, Pull Request, Merge Request, Diff - or Patch url.

      -

      ex: https://diff2html.xyz/demo.html?diff=https://github.com/rtfpessoa/diff2html/pull/106 -

      -
    • -
    • - Why can't I paste a diff? -

      diffy.org is an amazing tool created by pbu88 - to share your diffs and uses diff2html under the hood.

      -

      Also, diff2html cli can directly publish diffs to diffy.org

      -
    • -
    -
    -

    Thank you

    -

    I want to thank kevinsimper for this great idea, - providing better diff support for existing online services. -

    - - -
    - - - -
    - - - - - - - - - - - - - - - - - - - - diff --git a/docs/demo.js b/docs/demo.js deleted file mode 100644 index a81d602..0000000 --- a/docs/demo.js +++ /dev/null @@ -1,769 +0,0 @@ -(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i -1 - }; - } - - function normalizeName(name) { - if (typeof name !== 'string') { - name = String(name); - } - if (/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(name)) { - throw new TypeError('Invalid character in header field name') - } - return name.toLowerCase() - } - - function normalizeValue(value) { - if (typeof value !== 'string') { - value = String(value); - } - return value - } - - // Build a destructive iterator for the value list - function iteratorFor(items) { - var iterator = { - next: function() { - var value = items.shift(); - return {done: value === undefined, value: value} - } - }; - - if (support.iterable) { - iterator[Symbol.iterator] = function() { - return iterator - }; - } - - return iterator - } - - function Headers(headers) { - this.map = {}; - - if (headers instanceof Headers) { - headers.forEach(function(value, name) { - this.append(name, value); - }, this); - } else if (Array.isArray(headers)) { - headers.forEach(function(header) { - this.append(header[0], header[1]); - }, this); - } else if (headers) { - Object.getOwnPropertyNames(headers).forEach(function(name) { - this.append(name, headers[name]); - }, this); - } - } - - Headers.prototype.append = function(name, value) { - name = normalizeName(name); - value = normalizeValue(value); - var oldValue = this.map[name]; - this.map[name] = oldValue ? oldValue + ', ' + value : value; - }; - - Headers.prototype['delete'] = function(name) { - delete this.map[normalizeName(name)]; - }; - - Headers.prototype.get = function(name) { - name = normalizeName(name); - return this.has(name) ? this.map[name] : null - }; - - Headers.prototype.has = function(name) { - return this.map.hasOwnProperty(normalizeName(name)) - }; - - Headers.prototype.set = function(name, value) { - this.map[normalizeName(name)] = normalizeValue(value); - }; - - Headers.prototype.forEach = function(callback, thisArg) { - for (var name in this.map) { - if (this.map.hasOwnProperty(name)) { - callback.call(thisArg, this.map[name], name, this); - } - } - }; - - Headers.prototype.keys = function() { - var items = []; - this.forEach(function(value, name) { - items.push(name); - }); - return iteratorFor(items) - }; - - Headers.prototype.values = function() { - var items = []; - this.forEach(function(value) { - items.push(value); - }); - return iteratorFor(items) - }; - - Headers.prototype.entries = function() { - var items = []; - this.forEach(function(value, name) { - items.push([name, value]); - }); - return iteratorFor(items) - }; - - if (support.iterable) { - Headers.prototype[Symbol.iterator] = Headers.prototype.entries; - } - - function consumed(body) { - if (body.bodyUsed) { - return Promise.reject(new TypeError('Already read')) - } - body.bodyUsed = true; - } - - function fileReaderReady(reader) { - return new Promise(function(resolve, reject) { - reader.onload = function() { - resolve(reader.result); - }; - reader.onerror = function() { - reject(reader.error); - }; - }) - } - - function readBlobAsArrayBuffer(blob) { - var reader = new FileReader(); - var promise = fileReaderReady(reader); - reader.readAsArrayBuffer(blob); - return promise - } - - function readBlobAsText(blob) { - var reader = new FileReader(); - var promise = fileReaderReady(reader); - reader.readAsText(blob); - return promise - } - - function readArrayBufferAsText(buf) { - var view = new Uint8Array(buf); - var chars = new Array(view.length); - - for (var i = 0; i < view.length; i++) { - chars[i] = String.fromCharCode(view[i]); - } - return chars.join('') - } - - function bufferClone(buf) { - if (buf.slice) { - return buf.slice(0) - } else { - var view = new Uint8Array(buf.byteLength); - view.set(new Uint8Array(buf)); - return view.buffer - } - } - - function Body() { - this.bodyUsed = false; - - this._initBody = function(body) { - this._bodyInit = body; - if (!body) { - this._bodyText = ''; - } else if (typeof body === 'string') { - this._bodyText = body; - } else if (support.blob && Blob.prototype.isPrototypeOf(body)) { - this._bodyBlob = body; - } else if (support.formData && FormData.prototype.isPrototypeOf(body)) { - this._bodyFormData = body; - } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { - this._bodyText = body.toString(); - } else if (support.arrayBuffer && support.blob && isDataView(body)) { - this._bodyArrayBuffer = bufferClone(body.buffer); - // IE 10-11 can't handle a DataView body. - this._bodyInit = new Blob([this._bodyArrayBuffer]); - } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) { - this._bodyArrayBuffer = bufferClone(body); - } else { - this._bodyText = body = Object.prototype.toString.call(body); - } - - if (!this.headers.get('content-type')) { - if (typeof body === 'string') { - this.headers.set('content-type', 'text/plain;charset=UTF-8'); - } else if (this._bodyBlob && this._bodyBlob.type) { - this.headers.set('content-type', this._bodyBlob.type); - } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { - this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8'); - } - } - }; - - if (support.blob) { - this.blob = function() { - var rejected = consumed(this); - if (rejected) { - return rejected - } - - if (this._bodyBlob) { - return Promise.resolve(this._bodyBlob) - } else if (this._bodyArrayBuffer) { - return Promise.resolve(new Blob([this._bodyArrayBuffer])) - } else if (this._bodyFormData) { - throw new Error('could not read FormData body as blob') - } else { - return Promise.resolve(new Blob([this._bodyText])) - } - }; - - this.arrayBuffer = function() { - if (this._bodyArrayBuffer) { - return consumed(this) || Promise.resolve(this._bodyArrayBuffer) - } else { - return this.blob().then(readBlobAsArrayBuffer) - } - }; - } - - this.text = function() { - var rejected = consumed(this); - if (rejected) { - return rejected - } - - if (this._bodyBlob) { - return readBlobAsText(this._bodyBlob) - } else if (this._bodyArrayBuffer) { - return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer)) - } else if (this._bodyFormData) { - throw new Error('could not read FormData body as text') - } else { - return Promise.resolve(this._bodyText) - } - }; - - if (support.formData) { - this.formData = function() { - return this.text().then(decode) - }; - } - - this.json = function() { - return this.text().then(JSON.parse) - }; - - return this - } - - // HTTP methods whose capitalization should be normalized - var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']; - - function normalizeMethod(method) { - var upcased = method.toUpperCase(); - return methods.indexOf(upcased) > -1 ? upcased : method - } - - function Request(input, options) { - options = options || {}; - var body = options.body; - - if (input instanceof Request) { - if (input.bodyUsed) { - throw new TypeError('Already read') - } - this.url = input.url; - this.credentials = input.credentials; - if (!options.headers) { - this.headers = new Headers(input.headers); - } - this.method = input.method; - this.mode = input.mode; - this.signal = input.signal; - if (!body && input._bodyInit != null) { - body = input._bodyInit; - input.bodyUsed = true; - } - } else { - this.url = String(input); - } - - this.credentials = options.credentials || this.credentials || 'same-origin'; - if (options.headers || !this.headers) { - this.headers = new Headers(options.headers); - } - this.method = normalizeMethod(options.method || this.method || 'GET'); - this.mode = options.mode || this.mode || null; - this.signal = options.signal || this.signal; - this.referrer = null; - - if ((this.method === 'GET' || this.method === 'HEAD') && body) { - throw new TypeError('Body not allowed for GET or HEAD requests') - } - this._initBody(body); - } - - Request.prototype.clone = function() { - return new Request(this, {body: this._bodyInit}) - }; - - function decode(body) { - var form = new FormData(); - body - .trim() - .split('&') - .forEach(function(bytes) { - if (bytes) { - var split = bytes.split('='); - var name = split.shift().replace(/\+/g, ' '); - var value = split.join('=').replace(/\+/g, ' '); - form.append(decodeURIComponent(name), decodeURIComponent(value)); - } - }); - return form - } - - function parseHeaders(rawHeaders) { - var headers = new Headers(); - // Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space - // https://tools.ietf.org/html/rfc7230#section-3.2 - var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' '); - preProcessedHeaders.split(/\r?\n/).forEach(function(line) { - var parts = line.split(':'); - var key = parts.shift().trim(); - if (key) { - var value = parts.join(':').trim(); - headers.append(key, value); - } - }); - return headers - } - - Body.call(Request.prototype); - - function Response(bodyInit, options) { - if (!options) { - options = {}; - } - - this.type = 'default'; - this.status = options.status === undefined ? 200 : options.status; - this.ok = this.status >= 200 && this.status < 300; - this.statusText = 'statusText' in options ? options.statusText : 'OK'; - this.headers = new Headers(options.headers); - this.url = options.url || ''; - this._initBody(bodyInit); - } - - Body.call(Response.prototype); - - Response.prototype.clone = function() { - return new Response(this._bodyInit, { - status: this.status, - statusText: this.statusText, - headers: new Headers(this.headers), - url: this.url - }) - }; - - Response.error = function() { - var response = new Response(null, {status: 0, statusText: ''}); - response.type = 'error'; - return response - }; - - var redirectStatuses = [301, 302, 303, 307, 308]; - - Response.redirect = function(url, status) { - if (redirectStatuses.indexOf(status) === -1) { - throw new RangeError('Invalid status code') - } - - return new Response(null, {status: status, headers: {location: url}}) - }; - - exports.DOMException = self.DOMException; - try { - new exports.DOMException(); - } catch (err) { - exports.DOMException = function(message, name) { - this.message = message; - this.name = name; - var error = Error(message); - this.stack = error.stack; - }; - exports.DOMException.prototype = Object.create(Error.prototype); - exports.DOMException.prototype.constructor = exports.DOMException; - } - - function fetch(input, init) { - return new Promise(function(resolve, reject) { - var request = new Request(input, init); - - if (request.signal && request.signal.aborted) { - return reject(new exports.DOMException('Aborted', 'AbortError')) - } - - var xhr = new XMLHttpRequest(); - - function abortXhr() { - xhr.abort(); - } - - xhr.onload = function() { - var options = { - status: xhr.status, - statusText: xhr.statusText, - headers: parseHeaders(xhr.getAllResponseHeaders() || '') - }; - options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL'); - var body = 'response' in xhr ? xhr.response : xhr.responseText; - resolve(new Response(body, options)); - }; - - xhr.onerror = function() { - reject(new TypeError('Network request failed')); - }; - - xhr.ontimeout = function() { - reject(new TypeError('Network request failed')); - }; - - xhr.onabort = function() { - reject(new exports.DOMException('Aborted', 'AbortError')); - }; - - xhr.open(request.method, request.url, true); - - if (request.credentials === 'include') { - xhr.withCredentials = true; - } else if (request.credentials === 'omit') { - xhr.withCredentials = false; - } - - if ('responseType' in xhr && support.blob) { - xhr.responseType = 'blob'; - } - - request.headers.forEach(function(value, name) { - xhr.setRequestHeader(name, value); - }); - - if (request.signal) { - request.signal.addEventListener('abort', abortXhr); - - xhr.onreadystatechange = function() { - // DONE (success or failure) - if (xhr.readyState === 4) { - request.signal.removeEventListener('abort', abortXhr); - } - }; - } - - xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit); - }) - } - - fetch.polyfill = true; - - if (!self.fetch) { - self.fetch = fetch; - self.Headers = Headers; - self.Request = Request; - self.Response = Response; - } - - exports.Headers = Headers; - exports.Request = Request; - exports.Response = Response; - exports.fetch = fetch; - - Object.defineProperty(exports, '__esModule', { value: true }); - -}))); - -},{}],2:[function(require,module,exports){ -/* global Diff2HtmlUI */ - -/* - * Example URLs: - * - * https://github.com/rtfpessoa/diff2html/commit/7d02e67f3b3386ac5d804f974d025cd7a1165839 - * https://github.com/rtfpessoa/diff2html/pull/106 - * - * https://gitlab.com/gitlab-org/gitlab-ce/commit/4e963fed42ad518caa7353d361a38a1250c99c41 - * https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6763 - * - * https://bitbucket.org/atlassian/amps/commits/52c38116f12475f75af4a147b7a7685478b83eca - * https://bitbucket.org/atlassian/amps/pull-requests/236 - */ - -$(document).ready(function() { - // Improves browser compatibility - require('whatwg-fetch'); - - var searchParam = 'diff'; - - var $container = $('.container'); - var $url = $('#url'); - var $outputFormat = $('#diff-url-options-output-format'); - var $showFiles = $('#diff-url-options-show-files'); - var $matching = $('#diff-url-options-matching'); - var $wordsThreshold = $('#diff-url-options-match-words-threshold'); - var $matchingMaxComparisons = $('#diff-url-options-matching-max-comparisons'); - - if (window.location.search) { - var url = getUrlFromSearch(window.location.search); - $url.val(url); - smartDraw(url); - } - - bind(); - - $outputFormat - .add($showFiles) - .add($matching) - .add($wordsThreshold) - .add($matchingMaxComparisons) - .change(function(e) { - console.log(''); - console.log(e); - console.log(''); - smartDraw(null, true); - }); - - function getUrlFromSearch(search) { - try { - return search - .split('?')[1] - .split(searchParam + '=')[1] - .split('&')[0]; - } catch (_ignore) { - } - - return null; - } - - function getParamsFromSearch(search) { - var map = {}; - try { - search - .split('?')[1] - .split('&') - .map(function(e) { - var values = e.split('='); - map[values[0]] = values[1]; - }); - } catch (_ignore) { - } - - return map; - } - - function bind() { - $('#url-btn').click(function(e) { - e.preventDefault(); - var url = $url.val(); - smartDraw(url); - }); - - $url.on('paste', function(e) { - var url = e.originalEvent.clipboardData.getData('Text'); - smartDraw(url); - }); - } - - function prepareUrl(url) { - var fetchUrl; - var headers = new Headers(); - - var githubCommitUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/; - var githubPrUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/pull\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/; - - var gitlabCommitUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/; - var gitlabPrUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/merge_requests\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/; - - var bitbucketCommitUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/commits\/(.*?)(?:\/raw)?(?:\/.*)?$/; - var bitbucketPrUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/pull-requests\/(.*?)(?:\/.*)?$/; - - function gitLabUrlGen(userName, projectName, type, value) { - return 'https://crossorigin.me/https://gitlab.com/' + userName + '/' + projectName + '/' + type + '/' + value + '.diff'; - } - - function gitHubUrlGen(userName, projectName, type, value) { - headers.append('Accept', 'application/vnd.github.v3.diff'); - return 'https://api.github.com/repos/' + userName + '/' + projectName + '/' + type + '/' + value; - } - - function bitbucketUrlGen(userName, projectName, type, value) { - var baseUrl = 'https://bitbucket.org/api/2.0/repositories/'; - if (type === 'pullrequests') { - return baseUrl + userName + '/' + projectName + '/pullrequests/' + value + '/diff'; - } - return baseUrl + userName + '/' + projectName + '/diff/' + value; - } - - var values; - if ((values = githubCommitUrl.exec(url))) { - fetchUrl = gitHubUrlGen(values[1], values[2], 'commits', values[3]); - } else if ((values = githubPrUrl.exec(url))) { - fetchUrl = gitHubUrlGen(values[1], values[2], 'pulls', values[3]); - } else if ((values = gitlabCommitUrl.exec(url))) { - fetchUrl = gitLabUrlGen(values[1], values[2], 'commit', values[3]); - } else if ((values = gitlabPrUrl.exec(url))) { - fetchUrl = gitLabUrlGen(values[1], values[2], 'merge_requests', values[3]); - } else if ((values = bitbucketCommitUrl.exec(url))) { - fetchUrl = bitbucketUrlGen(values[1], values[2], 'commit', values[3]); - } else if ((values = bitbucketPrUrl.exec(url))) { - fetchUrl = bitbucketUrlGen(values[1], values[2], 'pullrequests', values[3]); - } else { - console.info('Could not parse url, using the provided url.'); - fetchUrl = 'https://crossorigin.me/' + url; - } - - return { - originalUrl: url, - url: fetchUrl, - headers: headers - }; - } - - function smartDraw(urlOpt, forced) { - var url = urlOpt || $url.val(); - var req = prepareUrl(url); - draw(req, forced); - } - - function draw(req, forced) { - if (!validateUrl(req.url)) { - console.error('Invalid url provided!'); - return; - } - - if (validateUrl(req.originalUrl)) updateUrl(req.originalUrl); - - var outputFormat = $outputFormat.val(); - var showFiles = $showFiles.is(':checked'); - var matching = $matching.val(); - var wordsThreshold = $wordsThreshold.val(); - var matchingMaxComparisons = $matchingMaxComparisons.val(); - - fetch(req.url, { - method: 'GET', - headers: req.headers, - mode: 'cors', - cache: 'default' - }) - .then(function(res) { - return res.text(); - }) - .then(function(data) { - var container = '#url-diff-container'; - var diff2htmlUi = new Diff2HtmlUI({diff: data}); - - if (outputFormat === 'side-by-side') { - $container.css({'width': '100%'}); - } else { - $container.css({'width': ''}); - } - - var params = getParamsFromSearch(window.location.search); - delete params[searchParam]; - - if (forced) { - params['outputFormat'] = outputFormat; - params['showFiles'] = showFiles; - params['matching'] = matching; - params['wordsThreshold'] = wordsThreshold; - params['matchingMaxComparisons'] = matchingMaxComparisons; - } else { - params['outputFormat'] = params['outputFormat'] || outputFormat; - params['showFiles'] = String(params['showFiles']) !== 'false' || (params['showFiles'] === null && showFiles); - params['matching'] = params['matching'] || matching; - params['wordsThreshold'] = params['wordsThreshold'] || wordsThreshold; - params['matchingMaxComparisons'] = params['matchingMaxComparisons'] || matchingMaxComparisons; - - $outputFormat.val(params['outputFormat']); - $showFiles.prop('checked', params['showFiles']); - $matching.val(params['matching']); - $wordsThreshold.val(params['wordsThreshold']); - $matchingMaxComparisons.val(params['matchingMaxComparisons']); - } - - params['synchronisedScroll'] = params['synchronisedScroll'] || true; - - diff2htmlUi.draw(container, params); - diff2htmlUi.fileListCloseable(container, params['fileListCloseable'] || false); - if (params['highlight'] === undefined || params['highlight']) { - diff2htmlUi.highlightCode(container); - } - }); - } - - function validateUrl(url) { - return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(url); - } - - function updateUrl(url) { - var params = getParamsFromSearch(window.location.search); - - if (params[searchParam] === url) return; - - params[searchParam] = url; - - var paramString = Object.keys(params).map(function(k) { return k + '=' + params[k]; }).join('&'); - - window.location = 'demo.html?' + paramString; - } -}); - -},{"whatwg-fetch":1}]},{},[2]); diff --git a/docs/demo.min.js b/docs/demo.min.js deleted file mode 100644 index 63d41d1..0000000 --- a/docs/demo.min.js +++ /dev/null @@ -1 +0,0 @@ -!function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){return o(e[i][1][r]||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,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 diff --git a/docs/img/snapshot-2.png b/docs/img/snapshot-2.png deleted file mode 100644 index fb52e799eec2aff0fecd31a9c5dbd3a2f0f76dbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74351 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 diff --git a/docs/img/snapshot-3.png b/docs/img/snapshot-3.png deleted file mode 100644 index afe3a0f19ef5a7c37b302b0a79a63227575d384f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123928 zcmd43by!qg8#fBl(jnb3h!R70ii8Xxq9BqZ9YZ4`9nzgcC`b$-CEeZKjetrIA>DAc z`ue=j_kQQU^Uv8A*T6M++&j|kW1=-^d#hFmK|BfJAWuylE>$V2L|J=^dpaH>PuxEODoag7~ z0Yq}xOus*JSurp$#%5;n0+pfAZ$ATZ24bhCv@GrH*#8+Ly4pKD>}}S89k;b*Wocny z6h!>@>6Hpb9-b1Ye0%oi&!K@hf2IT;RHG>?FMntW|7V$inV7h^NA3U2$rSLf(b)K; zeuWrkZM7SCP|2#4R{sfi77DYI_yiqc8 z4AI;FoU3H)Rle#!IHrHjX{AWu1IL&VG=EjD|?(z4-eX*gpbAlRke51Sm z-!4{7j%PO=i|WM1OoxzFpo zDc2((+uGz{gj*IiHnh(5RaHVo%{e)%@eQpG>faZ9HoG@AEREg?WrF2P1NU{qGkTqV1QWI6;Z?>axxocz&4i91e&~8|_ z*vt0@9{Z0)*VCM`b8{6Jy>C5br=e7k%>A^eYq5=XLg|U7g8clL=xCzzE$!yd^Wg#+ zK?q1PGr##ze5zfO&PTU3Dt$9U=`9}z`~6Oeu&AhEA2Icn7SC+sh$^ng`BuG)rQ2&m z(YHS{wr9(`r=rFYs&RH+hp7jniVT+NGpF5g>QWrjhThjctHvP;t)5@p4$byYPm^|c zZ9_ssW1Fvc>>SU2La#l))Mc=#B=!K$(#$(_)1dNC z<>AIWB-*m<+Ius9s)MV6b<%ziIHevnYT?;+uy&%JG`pwrm$j)u#zGMA(>5co`$dM$ z23Tvv#Kc(_C-nYY*vBcuX3dL>26RWuxz`!vcuJ*1Udw@Yd**{FY=>)u<@j($5B^Bc z0lw`pRGuxt?vA}jl{iaXx8Et6i3kY^Bfi({HC>vVY|qw3c+xoF*@UIPG#hGdvb{WP zbsR^)=Bs)iQ|M>=-+uW5KL1AOop)`t#DKVsVDkH6VrKT4!zW!cS1lpQ;9ai}rDCH9 zW>ryMUbMQ@xxAy36YMf&2O_?Gc@AGI+t?~QuD^Crl};s)-3Uqo?+;wUDBhVWLPr@ zi-<@#9F{h`y1KGiH@4IJ#=ZrdnD;~7YFj${#S_oh-n88=Yc*LrJSy)e2h4##x?g2K?zk{E)>nR$20Gwb;j(v8#h0LcV`^I%TKi zMf(u9$n@pSRI$7=*XN`N`sA`%_W3G1qbKj*(#1K&yTRHZgt!1p{qWphP z`G+tBEW`8QK`f13g9cXCnPu}*ilFsTss;ZSYRdBLw8OH@)^k1Vb? z=}+XU8yW?lk4Aa1Iyg8`clzB&af%cX#v4;nQE`#3z=&bnprHhzz#bi;4`hvuJpEc+ zSO^ianaS`B@O6LoEH(vaBX#|wyV|11q3UdtXFau)abxY%C41t>!H~BXo4Lnnc8$kc zI@Pux2!OO&-vCze03h4eUiFe!eet8)41=rdW%!2fLe>VwL{u>Og53tcJOlKC ze5*_t!gxeej2ao@PB1@9!)QTs!!3QbjP{`q{o5g|`YYmcSxUZsXRxsqFAmqxnWB2* zbx2=vBB4jQY1bHI#QpQj@nVuh4K@v(NfO&@8{|ez(DeKM^mO}}jWp`7r;;U{I_n?v z)1mPY&wfQ)gN>5r=~pfbH?|piQcIfeB1J$jB~y~j_&UueslRZ{cC zObugA1%ztL<)`rOZL22g6v$0l{IZb0%`|?T0~KiLtV{TaU+$2QRwP4O)d20V=*(qW zKNqbwCKK{A;@JE4)El|%_^s`|V;7Zq&m%&~?BiDF^NZAB3+HUMcN#E2I zzN&n3^D{_#!-#aJ%YpZ-Y3p;rkskP|0xKS-6Icffe?RIk%ZAx_d$lgTYA$`5tYBb7 zg&8K|inrpRW_U4{u-8lL%4^X4(ETSP|q?yvO5xjZ326flZ?SNFb%JHeQ{?&R^(z?w21bnvsr zXSsWA!Jup`Q*XqWF-W=4j(rB~oagd%Pumy=fd(l~c&Ke9-gHt~vRPF#RYPdsNL&
    - -
    - - -
    - - diff2html - -

    Diff parser and pretty html generator

    -

    Better diffs, unmatched reviews.

    -

    Demo

    - -
    - - - - - - - - - -
    -
    - -
    -
    -
    -

    Each diff provides a comprehensive visualization of the code changes, - helping developers identify problems and better understand the changes.

    -
    -
    - -
    -
    - - - -
    Line by Line and Side by Side changes
    -

    Each diff features a line by line and side by side preview of your - changes.

    -
    - -
    - - - -
    Code syntax highlight
    -

    All the code changes are syntax highlighted using highlight.js, - providing more readability.

    -
    - -
    - - - -
    Line similarity matching
    -

    Similar lines are paired, allowing for easier change tracking.

    -
    -
    - -
    -
    -
    -
    -

    Install with Bower

    -

    You can install and manage diff2html's CSS and JS using Bower:

    -
    -

    > $ bower install diff2html

    - Copy -
    -
    -
    -
    -
    -

    Install with npm

    -

    You can also install diff2html using npm:

    -
    -

    > $ npm install diff2html

    - Copy -
    -
    -
    - -
    -
    - -
    -
    -

    With command line integration

    -

    We work hard to make sure you can have your diffs in a simple and flexible - way. Go here full - documentation.

    -
    -
    -
    -

    - > $ npm install -g diff2html-cli
    - diff2html cli installed! -

    -

    - > $ diff2html
    - Previous commit changes on your browser -

    -

    - > $ is that it?
    - Yup, it's that simple.
    -

    -
    -
    -
    - -
    -
    -
    -
    -

    Projects using diff2html

    -
    -
    -
    -
    -
    -
    -
    diff2html-cli
    -

    diff2html from your terminal to the browser.

    - - View GitHub - -
    -
    -
    -
    -
    -
    -
    Codacy
    -

    Check code style, security, duplication, complexity and coverage on every change.

    - - Website - -
    -
    -
    -
    -
    -
    -
    Ungit
    -

    The easiest way to use git. On any platform. Anywhere.

    - - View GitHub - -
    -
    -
    -
    -
    -
    -
    Diffy
    -

    Share your diffs and explain your ideas without committing.

    - - Website - -
    -
    -
    -
    -
    -
    -
    diff-pane
    -

    Atom - Diff two panes.

    - - View GitHub - -
    -
    -
    -
    -
    -
    -
    node-giff
    -

    Display git diff on browser.

    - - View GitHub - -
    -
    -
    -
    -
    -
    -
    edgar-monitor
    -

    A module that processes new Edgar filings and sends out - notifications.

    - - View GitHub - -
    -
    -
    -
    -
    -
    -
    node-git
    -

    Execute Git Command by Node.js.

    - - View GitHub - -
    -
    -
    -
    -
    -
    -
    Jenkins
    -

    Show diffs between builds

    - - Website - -
    -
    -
    -
    -
    -
    -
    Light Review
    -

    Code Reviews with maximum control for the leading developers

    - - Website - -
    -
    -
    -
    -
    -
    -
    Simple Git
    -

    A simple package to be able to drive GIT

    - - View GitHub - -
    -
    -
    -
    -
    -
    - -
    -
    -

    Open Source

    -

    diff2html is open source. - If you'd like to be part of the diff2html community or help us improve, - find us on GitHub and - Gitter. Need any help? -

    - - Read more in the Docs - -
    -
    - -
    - - -
    - - - -
    - - - - - - - - - - - - - diff --git a/docs/main.css b/docs/main.css deleted file mode 100644 index 020636b..0000000 --- a/docs/main.css +++ /dev/null @@ -1,564 +0,0 @@ -/*! - * Copyright Colossal 2015 - * Adapted by @rtfpessoa - */ - -.template-index { - width: 100%; -} - -.template-index-min { - min-width: 700px; -} - -.container { - width: 100%; - padding: 0 8%; -} - -.m-b-md { - margin-bottom: 23px !important -} - -.p-t { - padding-top: 15px !important -} - -@media (min-width: 768px) { - p.m-b { - height: 75px; - overflow-y: hidden; - } -} - -.btn { - display: inline-block; - color: #fff; - background: #26A65B; - font-weight: 400 -} - -.btn:hover { - color: #fff; - background: #5dbe5d; -} - -.btn-clipboard { - position: absolute; - top: 0; - right: 0; - z-index: 10; - display: block; - padding: 5px 8px; - font-size: 12px; - color: #fff; - background-color: #767676; - border-radius: 0 4px 0 4px; - cursor: pointer; -} - -.btn-clipboard:hover { - color: #000; - background-color: #dcdfe4; -} - -.footer { - position: relative; - padding: 40px 0; - text-align: center; - font-size: 14px; - border-top: 1px solid #dcdfe4 -} - -.footer p { - margin-bottom: 5px -} - -.footer a { - color: #26A65B; -} - -.container a { - color: #26A65B; -} - -.container a.btn { - color: #fff; -} - -.footer-list-item { - display: inline-block -} - -.footer-list-item:not(:last-child):after { - content: "\b7" -} - -.footer > ul { - padding: 0; -} - -@media (min-width: 768px) { - .footer { - padding: 60px 0; - } -} - -@media (min-width: 768px) { - .row-centered { - display: flex; - align-items: center; - } -} - -.row-bordered { - position: relative -} - -.row-bordered:before { - content: ''; - display: block; - width: 80%; - position: absolute; - bottom: 0; - left: 50%; - margin-left: -40%; - height: 1px; - background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.2) 0, rgba(255, 255, 255, 0) 75%) -} - -.hero { - position: relative; - text-align: center; - padding: 80px 0; - border-bottom: 1px solid #dcdfe4 -} - -.hero-booticon { - font-family: Helvetica Neue, Helvetica, Arial, sans-serif; - margin: 0 auto 30px; - width: 100%; - font-size: 8vw; - display: block; - font-weight: 500; - text-align: center; - cursor: default; -} - -.hero-homepage.hero { - padding-top: 0; - padding-bottom: 40px; - overflow: hidden; - border-bottom: 0; - border-bottom: 1px solid #dcdfe4; -} - -.hero-homepage > .btn { - margin-top: 20px -} - -.swag-line:before { - content: ''; - position: fixed; - display: block; - top: 0; - left: 0; - right: 0; - height: 5px; - z-index: 2; - background-color: #26A65B; - background: linear-gradient(45deg, #28a142, #26A65B) -} - -.navbar { - background-color: #fff; - border: 0 #fff; -} - -.navbar-header { - text-align: center -} - -.navbar-brand { - height: auto; - padding: 19px 25px; - font-size: 16px; - display: inline-block; - float: none; - text-align: center; - margin: 5px 0 0 -} - -.navbar-nav { - margin-right: -15px -} - -.navbar-nav > li > a { - font-size: 14px -} - -.navbar-default .navbar-brand, .navbar-default .navbar-brand:focus, .navbar-default .navbar-brand:hover, .navbar-default .navbar-nav > li > a, .navbar-default .navbar-nav > li > a:focus, .navbar-default .navbar-nav > li > a:hover { - background: transparent; - color: #293a46; - font-weight: 300 -} - -.navbar-default .navbar-toggle { - position: absolute; - left: 0; - top: 7px; - border-color: #fff; - color: #293a46; - margin-right: 0 -} - -.navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus { - background: #f9f9f9; - border-color: #f9f9f9 -} - -@media (min-width: 768px) { - .navbar-full .navbar-brand { - margin-left: -25px - } - - .navbar-tall { - height: 125px - } - - .navbar-tall .navbar-header, .navbar-tall .navbar-nav { - line-height: 125px; - text-align: left - } - - .navbar-brand { - float: none; - display: inline-block; - text-align: left; - margin: 0 - } - - .navbar-nav > li > a { - display: inline-block; - margin-left: 13px - } - - .navbar-nav > li:first-child > a { - margin-left: 0 - } - -} - -.screenshot { - display: block; - overflow: hidden; -} - -.screenshot > img { - width: 100% -} - -.screenshots-fan { - margin-top: 50px -} - -.screenshots-fan .screenshot { - position: relative; - width: auto; - display: inline-block; - text-align: center; -} - -.screenshots-fan .screenshot:last-child, .screenshots-fan .screenshot:first-child { - z-index: 2 -} - -.screenshots-fan .screenshot { - z-index: 3 -} - -@media (min-width: 768px) { - .screenshots-fan { - position: relative; - overflow: hidden; - margin-top: 60px; - height: 200px - } - - .screenshots-fan .screenshot { - height: auto; - top: 10px; - width: 350px - } - - .screenshots-fan .screenshot:first-child, .screenshots-fan .screenshot:last-child { - width: 250px; - position: absolute; - top: 65px - } - - .screenshots-fan .screenshot:first-child { - left: 10px - } - - .screenshots-fan .screenshot:last-child { - left: auto; - right: 10px - } -} - -@media (min-width: 992px) { - .screenshots-fan { - margin-top: 60px; - height: 240px - } - - .screenshots-fan .screenshot { - width: 400px - } - - .screenshots-fan .screenshot:first-child, .screenshots-fan .screenshot:last-child { - width: 300px - } -} - -@media (min-width: 1200px) { - .screenshots-fan { - margin-top: 80px; - height: 380px - } - - .screenshots-fan .screenshot { - width: 550px - } - - .screenshots-fan .screenshot:first-child, .screenshots-fan .screenshot:last-child { - width: 450px - } -} - -body { - font-size: 16px; - font-family: Roboto, sans-serif; - font-weight: 300; - line-height: 1.6 -} - -h1 { - font-size: 26px; - font-weight: 300 -} - -h2 { - font-size: 18px; - font-weight: 300 -} - -h3 { - font-size: 26px; - font-weight: 300 -} - -h4 { - font-size: 16px; - font-weight: 300 -} - -h5 { - font-size: 16px; - font-weight: 400 -} - -h1, h2, h3, h4, h5 { - line-height: 1.4 -} - -h1, h2 { - margin: 10px 0 -} - -h5 { - margin: 6px 0 -} - -@media (min-width: 768px) { - body { - font-size: 16px; - font-family: Roboto, sans-serif; - font-weight: 300; - line-height: 1.6 - } - - h1 { - font-size: 38px; - font-weight: 300 - } - - h2 { - font-size: 26px; - font-weight: 300; - line-height: 1.4 - } - - h3 { - font-size: 26px; - font-weight: 300 - } - - h4 { - font-size: 18px; - font-weight: 300 - } - - h5 { - font-size: 16px; - font-weight: 400 - } -} - -body { - color: #293a46; -} - -a { - text-decoration: none; - color: inherit; -} - -a:hover, a:focus { - text-decoration: underline; -} - -.nav li a { - text-decoration: none; - color: inherit; -} - -.nav li a:hover { - text-decoration: underline; -} - -.text-muted { - color: #697176 -} - -.template-index h3 { - font-size: 21px; - margin-bottom: 12px -} - -.template-index h4 { - color: #697176; - line-height: 1.6 -} - -.template-index h4 a, .template-index p a { - color: #26A65B; -} - -.template-index h5 { - font-size: 17px; - margin-bottom: 8px -} - -.homepage-terminal-example, .homepage-code-example { - position: relative; - font-family: monospace; - background: #272b38; - color: #48d8a0; - border-radius: 8px; - padding: 30px -} - -.homepage-terminal-example .text-muted, -.homepage-code-example .text-muted { - color: #6a7490 -} - -@media (min-width: 768px) { - .homepage-terminal-example { - padding: 50px; - } - - .homepage-code-example { - padding: 10px; - } - - .homepage-code-example > p { - margin: 0; - } -} - -.hero-green { - color: #26A65B; -} - -.hero-black { - color: #353535; -} - -.hero-red { - color: #CB2C37; -} - -.svg-icon-large { - width: 50px; - display: block; - margin: 0 auto; -} - -.svg-icon-large > svg { - width: 100%; - height: auto; -} - -.row-padded-small { - padding: 40px 0; -} - -*.unselectable { - -webkit-touch-callout: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.url-diff-container { - width: 980px; -} - -.diff-url-wrapper { - display: flex; - width: 100%; -} - -.diff-url-input { - display: inline-block; - margin-right: 10px; - flex-grow: 1; - height: 31px; -} - -.diff-url-btn { - display: inline-block; - float: right; - width: 48px; -} - -.options-label-value { - font-weight: normal; -} - -.diff-url-options-container label select, -.diff-url-options-container label input { - display: block; -} - -/* 15 columns */ - -.col-md- *.col-md-15 { - width: 20%; -} - -/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3dlYnNpdGUvbWFpbi5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztFQUdFOztBQUVGO0VBQ0UsV0FBVztBQUNiOztBQUVBO0VBQ0UsZ0JBQWdCO0FBQ2xCOztBQUVBO0VBQ0UsV0FBVztFQUNYLGFBQWE7QUFDZjs7QUFFQTtFQUNFO0FBQ0Y7O0FBRUE7RUFDRTtBQUNGOztBQUVBO0VBQ0U7SUFDRSxZQUFZO0lBQ1osa0JBQWtCO0VBQ3BCO0FBQ0Y7O0FBRUE7RUFDRSxxQkFBcUI7RUFDckIsV0FBVztFQUNYLG1CQUFtQjtFQUNuQjtBQUNGOztBQUVBO0VBQ0UsV0FBVztFQUNYLG1CQUFtQjtBQUNyQjs7QUFFQTtFQUNFLGtCQUFrQjtFQUNsQixNQUFNO0VBQ04sUUFBUTtFQUNSLFdBQVc7RUFDWCxjQUFjO0VBQ2QsZ0JBQWdCO0VBQ2hCLGVBQWU7RUFDZixXQUFXO0VBQ1gseUJBQXlCO0VBQ3pCLDBCQUEwQjtFQUMxQixlQUFlO0FBQ2pCOztBQUVBO0VBQ0UsV0FBVztFQUNYLHlCQUF5QjtBQUMzQjs7QUFFQTtFQUNFLGtCQUFrQjtFQUNsQixlQUFlO0VBQ2Ysa0JBQWtCO0VBQ2xCLGVBQWU7RUFDZjtBQUNGOztBQUVBO0VBQ0U7QUFDRjs7QUFFQTtFQUNFLGNBQWM7QUFDaEI7O0FBRUE7RUFDRSxjQUFjO0FBQ2hCOztBQUVBO0VBQ0UsV0FBVztBQUNiOztBQUVBO0VBQ0U7QUFDRjs7QUFFQTtFQUNFO0FBQ0Y7O0FBRUE7RUFDRSxVQUFVO0FBQ1o7O0FBRUE7RUFDRTtJQUNFLGVBQWU7RUFDakI7QUFDRjs7QUFFQTtFQUNFO0lBR0UsYUFBYTtJQUdiLG1CQUFtQjtFQUNyQjtBQUNGOztBQUVBO0VBQ0U7QUFDRjs7QUFFQTtFQUNFLFdBQVc7RUFDWCxjQUFjO0VBQ2QsVUFBVTtFQUNWLGtCQUFrQjtFQUNsQixTQUFTO0VBQ1QsU0FBUztFQUNULGlCQUFpQjtFQUNqQixXQUFXO0VBRVg7QUFDRjs7QUFFQTtFQUNFLGtCQUFrQjtFQUNs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O0FBQzVCOztBQUVBO0VBQ0UscUJBQXFCO0VBQ3JCLGNBQWM7QUFDaEI7O0FBRUE7RUFDRSwwQkFBMEI7QUFDNUI7O0FBRUE7RUFDRTtBQUNGOztBQUVBO0VBQ0UsZUFBZTtFQUNmO0FBQ0Y7O0FBRUE7RUFDRSxjQUFjO0VBQ2Q7QUFDRjs7QUFFQTtFQUNFLGNBQWM7QUFDaEI7O0FBRUE7RUFDRSxlQUFlO0VBQ2Y7QUFDRjs7QUFFQTtFQUNFLGtCQUFrQjtFQUNsQixzQkFBc0I7RUFDdEIsbUJBQW1CO0VBQ25CLGNBQWM7RUFDZCxrQkFBa0I7RUFDbEI7QUFDRjs7QUFFQTs7RUFFRTtBQUNGOztBQUVBO0VBQ0U7SUFDRSxhQUFhO0VBQ2Y7O0VBRUE7SUFDRSxhQUFhO0VBQ2Y7O0VBRUE7SUFDRSxTQUFTO0VBQ1g7QUFDRjs7QUFFQTtFQUNFLGNBQWM7QUFDaEI7O0FBRUE7RUFDRSxjQUFjO0FBQ2hCOztBQUVBO0VBQ0UsY0FBYztBQUNoQjs7QUFFQTtFQUNFLFdBQVc7RUFDWCxjQUFjO0VBQ2QsY0FBYztBQUNoQjs7QUFFQTtFQUNFLFdBQVc7RUFDWCxZQUFZO0FBQ2Q7O0FBRUE7RUFDRSxlQUFlO0FBQ2pCOztBQUVBO0VBQ0UsMkJBQTJCO0VBQzNCLHlCQUF5QjtFQUN6QixzQkFBc0I7RUFDdEIscUJBQXFCO0VBQ3JCLGlCQUFpQjtBQUNuQjs7QUFFQTtFQUNFLFlBQVk7QUFDZDs7QUFFQTtFQUNFLGFBQWE7RUFDYixXQUFXO0FBQ2I7O0FBRUE7RUFDRSxxQkFBcUI7RUFDckIsa0JBQWtCO0VBQ2xCLFlBQVk7RUFDWixZQUFZO0FBQ2Q7O0FBRUE7RUFDRSxxQkFBcUI7RUFDckIsWUFBWTtFQUNaLFdBQVc7QUFDYjs7QUFFQTtFQUNFLG1CQUFtQjtBQUNyQjs7QUFFQTs7RUFFRSxjQUFjO0FBQ2hCOztBQUVBLGVBQWU7O0FBRWY7RUFDRSxVQUFVO0FBQ1oiLCJmaWxlIjoibWFpbi5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIENvcHlyaWdodCBDb2xvc3NhbCAyMDE1XG4gKiBBZGFwdGVkIGJ5IEBydGZwZXNzb2FcbiAqL1xuXG4udGVtcGxhdGUtaW5kZXgge1xuICB3aWR0aDogMTAwJTtcbn1cblxuLnRlbXBsYXRlLWluZGV4LW1pbiB7XG4gIG1pbi13aWR0aDogNzAwcHg7XG59XG5cbi5jb250YWluZXIge1xuICB3aWR0aDogMTAwJTtcbiAgcGFkZGluZzogMCA4JTtcbn1cblxuLm0tYi1tZCB7XG4gIG1hcmdpbi1ib3R0b206IDIzcHggIWltcG9ydGFudFxufVxuXG4ucC10IHtcbiAgcGFkZGluZy10b3A6IDE1cHggIWltcG9ydGFudFxufVxuXG5AbWVkaWEgKG1pbi13aWR0aDogNzY4cHgpIHtcbiAgcC5tLWIge1xuICAgIGhlaWdodDogNzVweDtcbiAgICBvdmVyZmxvdy15OiBoaWRkZW47XG4gIH1cbn1cblxuLmJ0biB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgY29sb3I6ICNmZmY7XG4gIGJhY2tncm91bmQ6ICMyNkE2NUI7XG4gIGZvbnQtd2VpZ2h0OiA0MDBcbn1cblxuLmJ0bjpob3ZlciB7XG4gIGNvbG9yOiAjZmZmO1xuICBiYWNrZ3JvdW5kOiAjNWRiZTVkO1xufVxuXG4uYnRuLWNsaXBib2FyZCB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiAwO1xuICByaWdodDogMDtcbiAgei1pbmRleDogMTA7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBwYWRkaW5nOiA1cHggOHB4O1xuICBmb250LXNpemU6IDEycHg7XG4gIGNvbG9yOiAjZmZmO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjNzY3Njc2O1xuICBib3JkZXItcmFkaXVzOiAwIDRweCAwIDRweDtcbiAgY3Vyc29yOiBwb2ludGVyO1xufVxuXG4uYnRuLWNsaXBib2FyZDpob3ZlciB7XG4gIGNvbG9yOiAjMDAwO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZGNkZmU0O1xufVxuXG4uZm9vdGVyIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBwYWRkaW5nOiA0MHB4IDA7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgZm9udC1zaXplOiAxNHB4O1xuICBib3JkZXItdG9wOiAxcHggc29saWQgI2RjZGZlNFxufVxuXG4uZm9vdGVyIHAge1xuICBtYXJnaW4tYm90dG9tOiA1cHhcbn1cblxuLmZvb3RlciBhIHtcbiAgY29sb3I6ICMyNkE2NUI7XG59XG5cbi5jb250YWluZXIgYSB7XG4gIGNvbG9yOiAjMjZBNjVCO1xufVxuXG4uY29udGFpbmVyIGEuYnRuIHtcbiAgY29sb3I6ICNmZmY7XG59XG5cbi5mb290ZXItbGlzdC1pdGVtIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrXG59XG5cbi5mb290ZXItbGlzdC1pdGVtOm5vdCg6bGFzdC1jaGlsZCk6YWZ0ZXIge1xuICBjb250ZW50OiBcIlxcYjdcIlxufVxuXG4uZm9vdGVyID4gdWwge1xuICBwYWRkaW5nOiAwO1xufVxuXG5AbWVkaWEgKG1pbi13aWR0aDogNzY4cHgpIHtcbiAgLmZvb3RlciB7XG4gICAgcGFkZGluZzogNjBweCAwO1xuICB9XG59XG5cbkBtZWRpYSAobWluLXdpZHRoOiA3NjhweCkge1xuICAucm93LWNlbnRlcmVkIHtcbiAgICBkaXNwbGF5OiAtd2Via2l0LWJveDtcbiAgICBkaXNwbGF5OiAtbXMtZmxleGJveDtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIC13ZWJraXQtYm94LWFsaWduOiBjZW50ZXI7XG4gICAgLW1zLWZsZXgtYWxpZ246IGNlbnRlcjtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICB9XG59XG5cbi5yb3ctYm9yZGVyZWQge1xuICBwb3NpdGlvbjogcmVsYXRpdmVcbn1cblxuLnJvdy1ib3JkZXJlZDpiZWZvcmUge1xuICBjb250ZW50OiAnJztcbiAgZGlzcGxheTogYmxvY2s7XG4gIHdpZHRoOiA4MCU7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgYm90dG9tOiAwO1xuICBsZWZ0OiA1MCU7XG4gIG1hcmdpbi1sZWZ0OiAtNDAlO1xuICBoZWlnaHQ6IDFweDtcbiAgYmFja2dyb3VuZDogLXdlYmtpdC1yYWRpYWwtZ3JhZGllbnQoZWxsaXBzZSBhdCBjZW50ZXIsIHJnYmEoMCwgMCwgMCwgMC4yKSAwLCByZ2JhKDI1NSwgMjU1LCAyNTUsIDApIDc1JSk7XG4gIGJhY2tncm91bmQ6IHJhZGlhbC1ncmFkaWVudChlbGxpcHNlIGF0IGNlbnRlciwgcmdiYSgwLCAwLCAwLCAwLjIpIDAsIHJnYmEoMjU1LCAyNTUsIDI1NSwgMCkgNzUlKVxufVxuXG4uaGVybyB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBwYWRkaW5nOiA4MHB4IDA7XG4gIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZGNkZmU0XG59XG5cbi5oZXJvLWJvb3RpY29uIHtcbiAgZm9udC1mYW1pbHk6IEhlbHZldGljYSBOZXVlLCBIZWx2ZXRpY2EsIEFyaWFsLCBzYW5zLXNlcmlmO1xuICBtYXJnaW46IDAgYXV0byAzMHB4O1xuICB3aWR0aDogMTAwJTtcbiAgZm9udC1zaXplOiA4dnc7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBmb250LXdlaWdodDogNTAwO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIGN1cnNvcjogZGVmYXVsdDtcbn1cblxuLmhlcm8taG9tZXBhZ2UuaGVybyB7XG4gIHBhZGRpbmctdG9wOiAwO1xuICBwYWRkaW5nLWJvdHRvbTogNDBweDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgYm9yZGVyLWJvdHRvbTogMDtcbiAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNkY2RmZTQ7XG59XG5cbi5oZXJvLWhvbWVwYWdlID4gLmJ0biB7XG4gIG1hcmdpbi10b3A6IDIwcHhcbn1cblxuLnN3YWctbGluZTpiZWZvcmUge1xuICBjb250ZW50OiAnJztcbiAgcG9zaXRpb246IGZpeGVkO1xuICBkaXNwbGF5OiBibG9jaztcbiAgdG9wOiAwO1xuICBsZWZ0OiAwO1xuICByaWdodDogMDtcbiAgaGVpZ2h0OiA1cHg7XG4gIHotaW5kZXg6IDI7XG4gIGJhY2tncm91bmQtY29sb3I6ICMyNkE2NUI7XG4gIGJhY2tncm91bmQ6IC13ZWJraXQtbGluZWFyLWdyYWRpZW50KDQ1ZGVnLCAjMjhhMTQyLCAjMjZBNjVCKTtcbiAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDQ1ZGVnLCAjMjhhMTQyLCAjMjZBNjVCKVxufVxuXG4ubmF2YmFyIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjtcbiAgYm9yZGVyOiAwICNmZmY7XG59XG5cbi5uYXZiYXItaGVhZGVyIHtcbiAgdGV4dC1hbGlnbjogY2VudGVyXG59XG5cbi5uYXZiYXItYnJhbmQge1xuICBoZWlnaHQ6IGF1dG87XG4gIHBhZGRpbmc6IDE5cHggMjVweDtcbiAgZm9udC1zaXplOiAxNnB4O1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIGZsb2F0OiBub25lO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIG1hcmdpbjogNXB4IDAgMFxufVxuXG4ubmF2YmFyLW5hdiB7XG4gIG1hcmdpbi1yaWdodDogLTE1cHhcbn1cblxuLm5hdmJhci1uYXYgPiBsaSA+IGEge1xuICBmb250LXNpemU6IDE0cHhcbn1cblxuLm5hdmJhci1kZWZhdWx0IC5uYXZiYXItYnJhbmQsIC5uYXZiYXItZGVmYXVsdCAubmF2YmFyLWJyYW5kOmZvY3VzLCAubmF2YmFyLWRlZmF1bHQgLm5hdmJhci1icmFuZDpob3ZlciwgLm5hdmJhci1kZWZhdWx0IC5uYXZiYXItbmF2ID4gbGkgPiBhLCAubmF2YmFyLWRlZmF1bHQgLm5hdmJhci1uYXYgPiBsaSA+IGE6Zm9jdXMsIC5uYXZiYXItZGVmYXVsdCAubmF2YmFyLW5hdiA+IGxpID4gYTpob3ZlciB7XG4gIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICBjb2xvcjogIzI5M2E0NjtcbiAgZm9udC13ZWlnaHQ6IDMwMFxufVxuXG4ubmF2YmFyLWRlZmF1bHQgLm5hdmJhci10b2dnbGUge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIGxlZnQ6IDA7XG4gIHRvcDogN3B4O1xuICBib3JkZXItY29sb3I6ICNmZmY7XG4gIGNvbG9yOiAjMjkzYTQ2O1xuICBtYXJnaW4tcmlnaHQ6IDBcbn1cblxuLm5hdmJhci1kZWZhdWx0IC5uYXZiYXItdG9nZ2xlOmhvdmVyLCAubmF2YmFyLWRlZmF1bHQgLm5hdmJhci10b2dnbGU6Zm9jdXMge1xuICBiYWNrZ3JvdW5kOiAjZjlmOWY5O1xuICBib3JkZXItY29sb3I6ICNmOWY5Zjlcbn1cblxuQG1lZGlhIChtaW4td2lkdGg6IDc2OHB4KSB7XG4gIC5uYXZiYXItZnVsbCAubmF2YmFyLWJyYW5kIHtcbiAgICBtYXJnaW4tbGVmdDogLTI1cHhcbiAgfVxuXG4gIC5uYXZiYXItdGFsbCB7XG4gICAgaGVpZ2h0OiAxMjVweFxuICB9XG5cbiAgLm5hdmJhci10YWxsIC5uYXZiYXItaGVhZGVyLCAubmF2YmFyLXRhbGwgLm5hdmJhci1uYXYge1xuICAgIGxpbmUtaGVpZ2h0OiAxMjVweDtcbiAgICB0ZXh0LWFsaWduOiBsZWZ0XG4gIH1cblxuICAubmF2YmFyLWJyYW5kIHtcbiAgICBmbG9hdDogbm9uZTtcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgdGV4dC1hbGlnbjogbGVmdDtcbiAgICBtYXJnaW46IDBcbiAgfVxuXG4gIC5uYXZiYXItbmF2ID4gbGkgPiBhIHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgbWFyZ2luLWxlZnQ6IDEzcHhcbiAgfVxuXG4gIC5uYXZiYXItbmF2ID4gbGk6Zmlyc3QtY2hpbGQgPiBhIHtcbiAgICBtYXJnaW4tbGVmdDogMFxuICB9XG5cbn1cblxuLnNjcmVlbnNob3Qge1xuICBkaXNwbGF5OiBibG9jaztcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbn1cblxuLnNjcmVlbnNob3QgPiBpbWcge1xuICB3aWR0aDogMTAwJVxufVxuXG4uc2NyZWVuc2hvdHMtZmFuIHtcbiAgbWFyZ2luLXRvcDogNTBweFxufVxuXG4uc2NyZWVuc2hvdHMtZmFuIC5zY3JlZW5zaG90IHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB3aWR0aDogYXV0bztcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG59XG5cbi5zY3JlZW5zaG90cy1mYW4gLnNjcmVlbnNob3Q6bGFzdC1jaGlsZCwgLnNjcmVlbnNob3RzLWZhbiAuc2NyZWVuc2hvdDpmaXJzdC1jaGlsZCB7XG4gIHotaW5kZXg6IDJcbn1cblxuLnNjcmVlbnNob3RzLWZhbiAuc2NyZWVuc2hvdCB7XG4gIHotaW5kZXg6IDNcbn1cblxuQG1lZGlhIChtaW4td2lkdGg6IDc2OHB4KSB7XG4gIC5zY3JlZW5zaG90cy1mYW4ge1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIG1hcmdpbi10b3A6IDYwcHg7XG4gICAgaGVpZ2h0OiAyMDBweFxuICB9XG5cbiAgLnNjcmVlbnNob3RzLWZhbiAuc2NyZWVuc2hvdCB7XG4gICAgaGVpZ2h0OiBhdXRvO1xuICAgIHRvcDogMTBweDtcbiAgICB3aWR0aDogMzUwcHhcbiAgfVxuXG4gIC5zY3JlZW5zaG90cy1mYW4gLnNjcmVlbnNob3Q6Zmlyc3QtY2hpbGQsIC5zY3JlZW5zaG90cy1mYW4gLnNjcmVlbnNob3Q6bGFzdC1jaGlsZCB7XG4gICAgd2lkdGg6IDI1MHB4O1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDY1cHhcbiAgfVxuXG4gIC5zY3JlZW5zaG90cy1mYW4gLnNjcmVlbnNob3Q6Zmlyc3QtY2hpbGQge1xuICAgIGxlZnQ6IDEwcHhcbiAgfVxuXG4gIC5zY3JlZW5zaG90cy1mYW4gLnNjcmVlbnNob3Q6bGFzdC1jaGlsZCB7XG4gICAgbGVmdDogYXV0bztcbiAgICByaWdodDogMTBweFxuICB9XG59XG5cbkBtZWRpYSAobWluLXdpZHRoOiA5OTJweCkge1xuICAuc2NyZWVuc2hvdHMtZmFuIHtcbiAgICBtYXJnaW4tdG9wOiA2MHB4O1xuICAgIGhlaWdodDogMjQwcHhcbiAgfVxuXG4gIC5zY3JlZW5zaG90cy1mYW4gLnNjcmVlbnNob3Qge1xuICAgIHdpZHRoOiA0MDBweFxuICB9XG5cbiAgLnNjcmVlbnNob3RzLWZhbiAuc2NyZWVuc2hvdDpmaXJzdC1jaGlsZCwgLnNjcmVlbnNob3RzLWZhbiAuc2NyZWVuc2hvdDpsYXN0LWNoaWxkIHtcbiAgICB3aWR0aDogMzAwcHhcbiAgfVxufVxuXG5AbWVkaWEgKG1pbi13aWR0aDogMTIwMHB4KSB7XG4gIC5zY3JlZW5zaG90cy1mYW4ge1xuICAgIG1hcmdpbi10b3A6IDgwcHg7XG4gICAgaGVpZ2h0OiAzODBweFxuICB9XG5cbiAgLnNjcmVlbnNob3RzLWZhbiAuc2NyZWVuc2hvdCB7XG4gICAgd2lkdGg6IDU1MHB4XG4gIH1cblxuICAuc2NyZWVuc2hvdHMtZmFuIC5zY3JlZW5zaG90OmZpcnN0LWNoaWxkLCAuc2NyZWVuc2hvdHMtZmFuIC5zY3JlZW5zaG90Omxhc3QtY2hpbGQge1xuICAgIHdpZHRoOiA0NTBweFxuICB9XG59XG5cbmJvZHkge1xuICBmb250LXNpemU6IDE2cHg7XG4gIGZvbnQtZmFtaWx5OiBSb2JvdG8sIHNhbnMtc2VyaWY7XG4gIGZvbnQtd2VpZ2h0OiAzMDA7XG4gIGxpbmUtaGVpZ2h0OiAxLjZcbn1cblxuaDEge1xuICBmb250LXNpemU6IDI2cHg7XG4gIGZvbnQtd2VpZ2h0OiAzMDBcbn1cblxuaDIge1xuICBmb250LXNpemU6IDE4cHg7XG4gIGZvbnQtd2VpZ2h0OiAzMDBcbn1cblxuaDMge1xuICBmb250LXNpemU6IDI2cHg7XG4gIGZvbnQtd2VpZ2h0OiAzMDBcbn1cblxuaDQge1xuICBmb250LXNpemU6IDE2cHg7XG4gIGZvbnQtd2VpZ2h0OiAzMDBcbn1cblxuaDUge1xuICBmb250LXNpemU6IDE2cHg7XG4gIGZvbnQtd2VpZ2h0OiA0MDBcbn1cblxuaDEsIGgyLCBoMywgaDQsIGg1IHtcbiAgbGluZS1oZWlnaHQ6IDEuNFxufVxuXG5oMSwgaDIge1xuICBtYXJnaW46IDEwcHggMFxufVxuXG5oNSB7XG4gIG1hcmdpbjogNnB4IDBcbn1cblxuQG1lZGlhIChtaW4td2lkdGg6IDc2OHB4KSB7XG4gIGJvZHkge1xuICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICBmb250LWZhbWlseTogUm9ib3RvLCBzYW5zLXNlcmlmO1xuICAgIGZvbnQtd2VpZ2h0OiAzMDA7XG4gICAgbGluZS1oZWlnaHQ6IDEuNlxuICB9XG5cbiAgaDEge1xuICAgIGZvbnQtc2l6ZTogMzhweDtcbiAgICBmb250LXdlaWdodDogMzAwXG4gIH1cblxuICBoMiB7XG4gICAgZm9udC1zaXplOiAyNnB4O1xuICAgIGZvbnQtd2VpZ2h0OiAzMDA7XG4gICAgbGluZS1oZWlnaHQ6IDEuNFxuICB9XG5cbiAgaDMge1xuICAgIGZvbnQtc2l6ZTogMjZweDtcbiAgICBmb250LXdlaWdodDogMzAwXG4gIH1cblxuICBoNCB7XG4gICAgZm9udC1zaXplOiAxOHB4O1xuICAgIGZvbnQtd2VpZ2h0OiAzMDBcbiAgfVxuXG4gIGg1IHtcbiAgICBmb250LXNpemU6IDE2cHg7XG4gICAgZm9udC13ZWlnaHQ6IDQwMFxuICB9XG59XG5cbmJvZHkge1xuICBjb2xvcjogIzI5M2E0Njtcbn1cblxuYSB7XG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgY29sb3I6IGluaGVyaXQ7XG59XG5cbmE6aG92ZXIsIGE6Zm9jdXMge1xuICB0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTtcbn1cblxuLm5hdiBsaSBhIHtcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xuICBjb2xvcjogaW5oZXJpdDtcbn1cblxuLm5hdiBsaSBhOmhvdmVyIHtcbiAgdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7XG59XG5cbi50ZXh0LW11dGVkIHtcbiAgY29sb3I6ICM2OTcxNzZcbn1cblxuLnRlbXBsYXRlLWluZGV4IGgzIHtcbiAgZm9udC1zaXplOiAyMXB4O1xuICBtYXJnaW4tYm90dG9tOiAxMnB4XG59XG5cbi50ZW1wbGF0ZS1pbmRleCBoNCB7XG4gIGNvbG9yOiAjNjk3MTc2O1xuICBsaW5lLWhlaWdodDogMS42XG59XG5cbi50ZW1wbGF0ZS1pbmRleCBoNCBhLCAudGVtcGxhdGUtaW5kZXggcCBhIHtcbiAgY29sb3I6ICMyNkE2NUI7XG59XG5cbi50ZW1wbGF0ZS1pbmRleCBoNSB7XG4gIGZvbnQtc2l6ZTogMTdweDtcbiAgbWFyZ2luLWJvdHRvbTogOHB4XG59XG5cbi5ob21lcGFnZS10ZXJtaW5hbC1leGFtcGxlLCAuaG9tZXBhZ2UtY29kZS1leGFtcGxlIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBmb250LWZhbWlseTogbW9ub3NwYWNlO1xuICBiYWNrZ3JvdW5kOiAjMjcyYjM4O1xuICBjb2xvcjogIzQ4ZDhhMDtcbiAgYm9yZGVyLXJhZGl1czogOHB4O1xuICBwYWRkaW5nOiAzMHB4XG59XG5cbi5ob21lcGFnZS10ZXJtaW5hbC1leGFtcGxlIC50ZXh0LW11dGVkLFxuLmhvbWVwYWdlLWNvZGUtZXhhbXBsZSAudGV4dC1tdXRlZCB7XG4gIGNvbG9yOiAjNmE3NDkwXG59XG5cbkBtZWRpYSAobWluLXdpZHRoOiA3NjhweCkge1xuICAuaG9tZXBhZ2UtdGVybWluYWwtZXhhbXBsZSB7XG4gICAgcGFkZGluZzogNTBweDtcbiAgfVxuXG4gIC5ob21lcGFnZS1jb2RlLWV4YW1wbGUge1xuICAgIHBhZGRpbmc6IDEwcHg7XG4gIH1cblxuICAuaG9tZXBhZ2UtY29kZS1leGFtcGxlID4gcCB7XG4gICAgbWFyZ2luOiAwO1xuICB9XG59XG5cbi5oZXJvLWdyZWVuIHtcbiAgY29sb3I6ICMyNkE2NUI7XG59XG5cbi5oZXJvLWJsYWNrIHtcbiAgY29sb3I6ICMzNTM1MzU7XG59XG5cbi5oZXJvLXJlZCB7XG4gIGNvbG9yOiAjQ0IyQzM3O1xufVxuXG4uc3ZnLWljb24tbGFyZ2Uge1xuICB3aWR0aDogNTBweDtcbiAgZGlzcGxheTogYmxvY2s7XG4gIG1hcmdpbjogMCBhdXRvO1xufVxuXG4uc3ZnLWljb24tbGFyZ2UgPiBzdmcge1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiBhdXRvO1xufVxuXG4ucm93LXBhZGRlZC1zbWFsbCB7XG4gIHBhZGRpbmc6IDQwcHggMDtcbn1cblxuKi51bnNlbGVjdGFibGUge1xuICAtd2Via2l0LXRvdWNoLWNhbGxvdXQ6IG5vbmU7XG4gIC13ZWJraXQtdXNlci1zZWxlY3Q6IG5vbmU7XG4gIC1tb3otdXNlci1zZWxlY3Q6IG5vbmU7XG4gIC1tcy11c2VyLXNlbGVjdDogbm9uZTtcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XG59XG5cbi51cmwtZGlmZi1jb250YWluZXIge1xuICB3aWR0aDogOTgwcHg7XG59XG5cbi5kaWZmLXVybC13cmFwcGVyIHtcbiAgZGlzcGxheTogZmxleDtcbiAgd2lkdGg6IDEwMCU7XG59XG5cbi5kaWZmLXVybC1pbnB1dCB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgbWFyZ2luLXJpZ2h0OiAxMHB4O1xuICBmbGV4LWdyb3c6IDE7XG4gIGhlaWdodDogMzFweDtcbn1cblxuLmRpZmYtdXJsLWJ0biB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgZmxvYXQ6IHJpZ2h0O1xuICB3aWR0aDogNDhweDtcbn1cblxuLm9wdGlvbnMtbGFiZWwtdmFsdWUge1xuICBmb250LXdlaWdodDogbm9ybWFsO1xufVxuXG4uZGlmZi11cmwtb3B0aW9ucy1jb250YWluZXIgbGFiZWwgc2VsZWN0LFxuLmRpZmYtdXJsLW9wdGlvbnMtY29udGFpbmVyIGxhYmVsIGlucHV0IHtcbiAgZGlzcGxheTogYmxvY2s7XG59XG5cbi8qIDE1IGNvbHVtbnMgKi9cblxuLmNvbC1tZC0gKi5jb2wtbWQtMTUge1xuICB3aWR0aDogMjAlO1xufVxuIl19 */ \ No newline at end of file diff --git a/docs/main.min.css b/docs/main.min.css deleted file mode 100644 index 7e1fd93..0000000 --- a/docs/main.min.css +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * Copyright Colossal 2015 - * Adapted by @rtfpessoa - */.template-index{width:100%}.template-index-min{min-width:700px}.container{width:100%;padding:0 8%}.m-b-md{margin-bottom:23px!important}.p-t{padding-top:15px!important}@media (min-width:768px){p.m-b{height:75px;overflow-y:hidden}}.btn{display:inline-block;color:#fff;background:#26a65b;font-weight:400}.btn:hover{color:#fff;background:#5dbe5d}.btn-clipboard{position:absolute;top:0;right:0;z-index:10;display:block;padding:5px 8px;font-size:12px;color:#fff;background-color:#767676;border-radius:0 4px 0 4px;cursor:pointer}.btn-clipboard:hover{color:#000;background-color:#dcdfe4}.footer{position:relative;padding:40px 0;text-align:center;font-size:14px;border-top:1px solid #dcdfe4}.footer p{margin-bottom:5px}.footer a{color:#26a65b}.container a{color:#26a65b}.container a.btn{color:#fff}.footer-list-item{display:inline-block}.footer-list-item:not(:last-child):after{content:"\b7"}.footer>ul{padding:0}@media (min-width:768px){.footer{padding:60px 0}}@media (min-width:768px){.row-centered{display:flex;align-items:center}}.row-bordered{position:relative}.row-bordered:before{content:'';display:block;width:80%;position:absolute;bottom:0;left:50%;margin-left:-40%;height:1px;background:radial-gradient(ellipse at center,rgba(0,0,0,.2) 0,rgba(255,255,255,0) 75%)}.hero{position:relative;text-align:center;padding:80px 0;border-bottom:1px solid #dcdfe4}.hero-booticon{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;margin:0 auto 30px;width:100%;font-size:8vw;display:block;font-weight:500;text-align:center;cursor:default}.hero-homepage.hero{padding-top:0;padding-bottom:40px;overflow:hidden;border-bottom:0;border-bottom:1px solid #dcdfe4}.hero-homepage>.btn{margin-top:20px}.swag-line:before{content:'';position:fixed;display:block;top:0;left:0;right:0;height:5px;z-index:2;background-color:#26a65b;background:linear-gradient(45deg,#28a142,#26a65b)}.navbar{background-color:#fff;border:0 #fff}.navbar-header{text-align:center}.navbar-brand{height:auto;padding:19px 25px;font-size:16px;display:inline-block;float:none;text-align:center;margin:5px 0 0}.navbar-nav{margin-right:-15px}.navbar-nav>li>a{font-size:14px}.navbar-default .navbar-brand,.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover,.navbar-default .navbar-nav>li>a,.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{background:0 0;color:#293a46;font-weight:300}.navbar-default .navbar-toggle{position:absolute;left:0;top:7px;border-color:#fff;color:#293a46;margin-right:0}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background:#f9f9f9;border-color:#f9f9f9}@media (min-width:768px){.navbar-full .navbar-brand{margin-left:-25px}.navbar-tall{height:125px}.navbar-tall .navbar-header,.navbar-tall .navbar-nav{line-height:125px;text-align:left}.navbar-brand{float:none;display:inline-block;text-align:left;margin:0}.navbar-nav>li>a{display:inline-block;margin-left:13px}.navbar-nav>li:first-child>a{margin-left:0}}.screenshot{display:block;overflow:hidden}.screenshot>img{width:100%}.screenshots-fan{margin-top:50px}.screenshots-fan .screenshot{position:relative;width:auto;display:inline-block;text-align:center}.screenshots-fan .screenshot:first-child,.screenshots-fan .screenshot:last-child{z-index:2}.screenshots-fan .screenshot{z-index:3}@media (min-width:768px){.screenshots-fan{position:relative;overflow:hidden;margin-top:60px;height:200px}.screenshots-fan .screenshot{height:auto;top:10px;width:350px}.screenshots-fan .screenshot:first-child,.screenshots-fan .screenshot:last-child{width:250px;position:absolute;top:65px}.screenshots-fan .screenshot:first-child{left:10px}.screenshots-fan .screenshot:last-child{left:auto;right:10px}}@media (min-width:992px){.screenshots-fan{margin-top:60px;height:240px}.screenshots-fan .screenshot{width:400px}.screenshots-fan .screenshot:first-child,.screenshots-fan .screenshot:last-child{width:300px}}@media (min-width:1200px){.screenshots-fan{margin-top:80px;height:380px}.screenshots-fan .screenshot{width:550px}.screenshots-fan .screenshot:first-child,.screenshots-fan .screenshot:last-child{width:450px}}body{font-size:16px;font-family:Roboto,sans-serif;font-weight:300;line-height:1.6}h1{font-size:26px;font-weight:300}h2{font-size:18px;font-weight:300}h3{font-size:26px;font-weight:300}h4{font-size:16px;font-weight:300}h5{font-size:16px;font-weight:400}h1,h2,h3,h4,h5{line-height:1.4}h1,h2{margin:10px 0}h5{margin:6px 0}@media (min-width:768px){body{font-size:16px;font-family:Roboto,sans-serif;font-weight:300;line-height:1.6}h1{font-size:38px;font-weight:300}h2{font-size:26px;font-weight:300;line-height:1.4}h3{font-size:26px;font-weight:300}h4{font-size:18px;font-weight:300}h5{font-size:16px;font-weight:400}}body{color:#293a46}a{text-decoration:none;color:inherit}a:focus,a:hover{text-decoration:underline}.nav li a{text-decoration:none;color:inherit}.nav li a:hover{text-decoration:underline}.text-muted{color:#697176}.template-index h3{font-size:21px;margin-bottom:12px}.template-index h4{color:#697176;line-height:1.6}.template-index h4 a,.template-index p a{color:#26a65b}.template-index h5{font-size:17px;margin-bottom:8px}.homepage-code-example,.homepage-terminal-example{position:relative;font-family:monospace;background:#272b38;color:#48d8a0;border-radius:8px;padding:30px}.homepage-code-example .text-muted,.homepage-terminal-example .text-muted{color:#6a7490}@media (min-width:768px){.homepage-terminal-example{padding:50px}.homepage-code-example{padding:10px}.homepage-code-example>p{margin:0}}.hero-green{color:#26a65b}.hero-black{color:#353535}.hero-red{color:#cb2c37}.svg-icon-large{width:50px;display:block;margin:0 auto}.svg-icon-large>svg{width:100%;height:auto}.row-padded-small{padding:40px 0}.unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.url-diff-container{width:980px}.diff-url-wrapper{display:flex;width:100%}.diff-url-input{display:inline-block;margin-right:10px;flex-grow:1;height:31px}.diff-url-btn{display:inline-block;float:right;width:48px}.options-label-value{font-weight:400}.diff-url-options-container label input,.diff-url-options-container label select{display:block}.col-md- .col-md-15{width:20%} \ No newline at end of file diff --git a/docs/robots.txt b/docs/robots.txt deleted file mode 100644 index 4f9540b..0000000 --- a/docs/robots.txt +++ /dev/null @@ -1 +0,0 @@ -User-agent: * \ No newline at end of file diff --git a/docs/sitemap.xml b/docs/sitemap.xml deleted file mode 100644 index 3f5fd62..0000000 --- a/docs/sitemap.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - https://diff2html.xyz/ - - - https://diff2html.xyz/index.html - - - https://diff2html.xyz/demo.html - - diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..d311713 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,15 @@ +module.exports = { + verbose: true, + preset: "ts-jest", + testEnvironment: "node", + coverageDirectory: "./coverage", + coverageReporters: ["lcov", "text", "html"], + coverageThreshold: { + global: { + statements: 90, + branches: 85, + functions: 90, + lines: 90 + } + } +}; diff --git a/package.json b/package.json index e7cb771..57afd00 100644 --- a/package.json +++ b/package.json @@ -34,22 +34,25 @@ "engines": { "node": ">=4" }, - "preferGlobal": true, "scripts": { - "release": "./scripts/release.sh", - "release-website": "./scripts/release-website.sh", - "templates": "./scripts/hulk.js --wrapper node --variable 'browserTemplates' ./src/templates/*.mustache > ./src/templates/diff2html-templates.js", + "build": "tsc", + "lint": "eslint '*/**/*.{js,jsx,ts,tsx}'", "style": "yarn run lint", - "lint": "eslint .", - "coverage": "istanbul cover _mocha -- -u exports -R spec ./test/**/*", - "check-coverage": "istanbul check-coverage --statements 90 --functions 90 --branches 85 --lines 90 ./coverage/coverage.json", - "test": "yarn run coverage && yarn run check-coverage", + "test": "jest", + "coverage": "jest --collectCoverage", + "coverage-html": "yarn run coverage && open ./coverage/index.html", "codacy": "cat ./coverage/lcov.info | codacy-coverage", - "preversion": "yarn run release && yarn run release-website && yarn run lint && yarn test", - "version": "git add -A src dist docs package.json", + "release": "yarn run release-css && yarn run release-templates && yarn run release-ts && yarn run release-browser-bundle && yarn run release-website", + "release-css": "./scripts/release-css.sh", + "release-templates": "./scripts/release-templates.sh", + "release-ts": "yarn run build", + "release-browser-bundle": "./scripts/release-browser-bundle.sh", + "release-website": "./scripts/release-website.sh", + "preversion": "yarn run release && yarn run lint && yarn test", + "version": "git add -A package.json", "postversion": "git push && git push --tags" }, - "main": "./src/diff2html.js", + "main": "./build/commonjs-node/diff2html.js", "browser": { "fs": false }, @@ -60,28 +63,38 @@ "whatwg-fetch": "^3.0.0" }, "devDependencies": { + "@types/jest": "24.0.18", + "@types/node": "^12.7.2", + "@typescript-eslint/eslint-plugin": "2.0.0", + "@typescript-eslint/parser": "2.0.0", "autoprefixer": "^9.6.0", - "browserify": "^16.2.3", + "browserify": "^16.5.0", "clean-css-cli": "^4.3.0", "codacy-coverage": "^3.4.0", - "eslint": "^5.16.0", - "eslint-plugin-promise": "^4.1.1", - "eslint-plugin-standard": "^4.0.0", + "eslint": "6.2.2", + "eslint-config-prettier": "6.1.0", + "eslint-config-standard": "14.0.1", + "eslint-plugin-import": "2.18.2", + "eslint-plugin-jest": "22.15.2", + "eslint-plugin-node": "9.1.0", + "eslint-plugin-prettier": "3.1.0", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-standard": "^4.0.1", "fast-html-parser": "^1.0.1", - "istanbul": "^0.4.5", + "jest": "24.9.0", "mkdirp": "^0.5.1", - "mocha": "5.2.0", "nopt": "^4.0.1", - "postcss-cli": "^6.1.2", - "uglify-js": "^3.6.0" + "postcss-cli": "^6.1.3", + "prettier": "1.18.2", + "ts-jest": "24.0.2", + "typescript": "^3.6.3", + "terser": "^4.3.8" }, "resolutions": { - "lodash": "4.17.14" + "lodash": "4.17.15" }, "license": "MIT", "files": [ - "src", - "dist", - "typescript" + "build" ] } diff --git a/scripts/hulk.js b/scripts/hulk.js index a4b1a4d..d718a66 100755 --- a/scripts/hulk.js +++ b/scripts/hulk.js @@ -16,61 +16,66 @@ */ // dependencies -var hogan = require('hogan.js'); -var path = require('path'); -var nopt = require('nopt'); -var mkderp = require('mkdirp'); -var fs = require('fs'); +const path = require("path"); +const fs = require("fs"); +const hogan = require("hogan.js"); +const nopt = require("nopt"); +const mkderp = require("mkdirp"); // locals -var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\']; -var specialsRegExp = new RegExp('(\\' + specials.join('|\\') + ')', 'g'); -var options = { - 'namespace': String, - 'outputdir': path, - 'variable': String, - 'wrapper': String, - 'version': true, - 'help': true +const specials = ["/", ".", "*", "+", "?", "|", "(", ")", "[", "]", "{", "}", "\\"]; +const specialsRegExp = new RegExp("(\\" + specials.join("|\\") + ")", "g"); +let options = { + namespace: String, + outputdir: path, + variable: String, + wrapper: String, + version: true, + help: true }; -var shortHand = { - 'n': ['--namespace'], - 'o': ['--outputdir'], - 'vn': ['--variable'], - 'w': ['--wrapper'], - 'h': ['--help'], - 'v': ['--version'] +const shortHand = { + n: ["--namespace"], + o: ["--outputdir"], + vn: ["--variable"], + w: ["--wrapper"], + h: ["--help"], + v: ["--version"] }; -var templates; +let templates; // options options = nopt(options, shortHand); // escape special regexp characters function esc(text) { - return text.replace(specialsRegExp, '\\$1'); + return text.replace(specialsRegExp, "\\$1"); } // cyan function for rob function cyan(text) { - return '\x1B[36m' + text + '\x1B[39m'; + return "\x1B[36m" + text + "\x1B[39m"; } // check for dirs and correct ext (<3 for windows) function extractFiles(args) { - var usage = '\n' + - cyan('USAGE:') + ' hulk [--wrapper wrapper] [--outputdir outputdir] ' + - '[--namespace namespace] [--variable variable] FILES\n\n' + - cyan('OPTIONS:') + ' [-w, --wrapper] :: wraps the template (i.e. amd)\n' + - ' [-o, --outputdir] :: outputs the templates as individual files to a directory\n\n' + - ' [-n, --namespace] :: prepend string to template names\n\n' + - ' [-vn, --variable] :: variable name for non-amd wrapper\n\n' + - cyan('EXAMPLE:') + ' hulk --wrapper amd ./templates/*.mustache\n\n' + - cyan('NOTE:') + ' hulk supports the "*" wildcard and allows you to target specific extensions too\n'; - var files = []; + const usage = + "\n" + + cyan("USAGE:") + + " hulk [--wrapper wrapper] [--outputdir outputdir] " + + "[--namespace namespace] [--variable variable] FILES\n\n" + + cyan("OPTIONS:") + + " [-w, --wrapper] :: wraps the template (i.e. amd)\n" + + " [-o, --outputdir] :: outputs the templates as individual files to a directory\n\n" + + " [-n, --namespace] :: prepend string to template names\n\n" + + " [-vn, --variable] :: variable name for non-amd wrapper\n\n" + + cyan("EXAMPLE:") + + " hulk --wrapper amd ./templates/*.mustache\n\n" + + cyan("NOTE:") + + ' hulk supports the "*" wildcard and allows you to target specific extensions too\n'; + let files = []; if (options.version) { - console.log(require('../package.json').version); + console.log(require("../package.json").version); process.exit(0); } @@ -81,12 +86,13 @@ function extractFiles(args) { args.forEach(function(arg) { if (/\*/.test(arg)) { - arg = arg.split('*'); + arg = arg.split("*"); files = files.concat( - fs.readdirSync(arg[0] || '.') + fs + .readdirSync(arg[0] || ".") .map(function(f) { - var file = path.join(arg[0], f); - return new RegExp(esc(arg[1]) + '$').test(f) && fs.statSync(file).isFile() && file; + const file = path.join(arg[0], f); + return new RegExp(esc(arg[1]) + "$").test(f) && fs.statSync(file).isFile() && file; }) .filter(function(f) { return f; @@ -112,51 +118,65 @@ function removeByteOrderMark(text) { // wrap templates function wrap(file, name, openedFile) { switch (options.wrapper) { - case 'amd': - return 'define(' + (!options.outputdir ? '"' + path.join(path.dirname(file), name) + '", ' : '') + + case "amd": + return ( + "define(" + + (!options.outputdir ? '"' + path.join(path.dirname(file), name) + '", ' : "") + '[ "hogan.js" ], function(Hogan){ return new Hogan.Template(' + - hogan.compile(openedFile, {asString: 1}) + - ');});'; - case 'node': - var globalObj = 'global.' + (options.variable || 'templates') + '["' + name + '"]'; - var globalStmt = globalObj + ' = new Hogan.Template(' + hogan.compile(openedFile, {asString: 1}) + ');'; + hogan.compile(openedFile, { asString: 1 }) + + ");});" + ); + case "node": + var globalObj = "global." + (options.variable || "templates") + '["' + name + '"]'; + var globalStmt = globalObj + " = new Hogan.Template(" + hogan.compile(openedFile, { asString: 1 }) + ");"; var nodeOutput = globalStmt; // if we have a template per file the export will expose the template directly if (options.outputdir) { - nodeOutput = nodeOutput + '\n' + 'module.exports = ' + globalObj + ';'; + nodeOutput = nodeOutput + "\n" + "module.exports = " + globalObj + ";"; } return nodeOutput; default: - return (options.variable || 'templates') + - '["' + name + '"] = new Hogan.Template(' + - hogan.compile(openedFile, {asString: 1}) + - ');'; + return ( + (options.variable || "templates") + + '["' + + name + + '"] = new Hogan.Template(' + + hogan.compile(openedFile, { asString: 1 }) + + ");" + ); } } function prepareOutput(content) { - var variableName = options.variable || 'templates'; + const variableName = options.variable || "templates"; switch (options.wrapper) { - case 'amd': + case "amd": return content; - case 'node': - var nodeExport = ''; + case "node": + var nodeExport = ""; // if we have aggregated templates the export will expose the template map if (!options.outputdir) { - nodeExport = 'module.exports = global.' + variableName + ';\n'; + nodeExport = "module.exports = global." + variableName + ";\n"; } - return '(function() {\n' + - 'if (!!!global.' + variableName + ') global.' + variableName + ' = {};\n' + + return ( + "(function() {\n" + + "if (!!!global." + + variableName + + ") global." + + variableName + + " = {};\n" + 'var Hogan = require("hogan.js");' + - content + '\n' + + content + + "\n" + nodeExport + - '})();'; + "})();" + ); default: - return 'if (!!!' + variableName + ') var ' + variableName + ' = {};\n' + content; + return "if (!!!" + variableName + ") var " + variableName + " = {};\n" + content; } } @@ -167,21 +187,20 @@ if (options.outputdir) { // Prepend namespace to template name function namespace(name) { - return (options.namespace || '') + name; + return (options.namespace || "") + name; } // write a template foreach file that matches template extension templates = extractFiles(options.argv.remain) .map(function(file) { - var openedFile = fs.readFileSync(file, 'utf-8').trim(); - var name; + let openedFile = fs.readFileSync(file, "utf-8").trim(); + let name; if (!openedFile) return; - name = namespace(path.basename(file).replace(/\..*$/, '')); + name = namespace(path.basename(file).replace(/\..*$/, "")); openedFile = removeByteOrderMark(openedFile); openedFile = wrap(file, name, openedFile); if (!options.outputdir) return openedFile; - fs.writeFileSync(path.join(options.outputdir, name + '.js') - , prepareOutput(openedFile)); + fs.writeFileSync(path.join(options.outputdir, name + ".js"), prepareOutput(openedFile)); }) .filter(function(t) { return t; @@ -190,4 +209,4 @@ templates = extractFiles(options.argv.remain) // output templates if (!templates.length || options.outputdir) process.exit(0); -console.log(prepareOutput(templates.join('\n'))); +console.log(prepareOutput(templates.join("\n"))); diff --git a/scripts/release-browser-bundle.sh b/scripts/release-browser-bundle.sh new file mode 100755 index 0000000..6eb2cc3 --- /dev/null +++ b/scripts/release-browser-bundle.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +set -e + +SCRIPT_DIRECTORY="$( cd "$( dirname "$0" )" && pwd )" + +INPUT_DIR=${SCRIPT_DIRECTORY}/../build/commonjs-node +INPUT_UI_DIR=${INPUT_DIR}/ui +INPUT_JS_FILE=${INPUT_DIR}/diff2html.js +INPUT_JS_UI_FILE=${INPUT_UI_DIR}/js/diff2html-ui.js + +OUTPUT_DIR=${SCRIPT_DIRECTORY}/../build/browser +OUTPUT_JS_FILE=${OUTPUT_DIR}/diff2html.js +OUTPUT_MIN_JS_FILE=${OUTPUT_DIR}/diff2html.min.js +OUTPUT_JS_UI_FILE=${OUTPUT_DIR}/diff2html-ui.js +OUTPUT_MIN_JS_UI_FILE=${OUTPUT_DIR}/diff2html-ui.min.js + +echo "Creating diff2html browser bundle ..." + +echo "Cleaning previous versions ..." +rm -rf ${OUTPUT_DIR} +mkdir -p ${OUTPUT_DIR} + +echo "Generating js aggregation file in ${OUTPUT_JS_FILE}" +browserify -e ${INPUT_JS_FILE} -o ${OUTPUT_JS_FILE} + +echo "Minifying ${OUTPUT_JS_FILE} to ${OUTPUT_MIN_JS_FILE}" +terser ${OUTPUT_JS_FILE} -c -o ${OUTPUT_MIN_JS_FILE} + +echo "Generating js ui aggregation file in ${OUTPUT_JS_UI_FILE}" +browserify -e ${INPUT_JS_UI_FILE} -o ${OUTPUT_JS_UI_FILE} + +echo "Minifying ${OUTPUT_JS_UI_FILE} to ${OUTPUT_MIN_JS_UI_FILE}" +terser ${OUTPUT_JS_UI_FILE} -c -o ${OUTPUT_MIN_JS_UI_FILE} + +echo "diff2html browser bundle created successfully!" diff --git a/scripts/release-css.sh b/scripts/release-css.sh new file mode 100755 index 0000000..e1e55ef --- /dev/null +++ b/scripts/release-css.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -e + +SCRIPT_DIRECTORY="$( cd "$( dirname "$0" )" && pwd )" + +INPUT_DIR=${SCRIPT_DIRECTORY}/../src +INPUT_UI_DIR=${INPUT_DIR}/ui +INPUT_CSS_FILE=${INPUT_UI_DIR}/css/diff2html.css + +OUTPUT_DIR=${SCRIPT_DIRECTORY}/../build/css +OUTPUT_CSS_FILE=${OUTPUT_DIR}/diff2html.css +OUTPUT_MIN_CSS_FILE=${OUTPUT_DIR}/diff2html.min.css + +echo "Creating diff2html css ..." + +echo "Cleaning previous versions ..." +rm -rf ${OUTPUT_DIR} +mkdir -p ${OUTPUT_DIR} + +echo "Minifying ${OUTPUT_CSS_FILE} to ${OUTPUT_MIN_CSS_FILE}" +postcss --use autoprefixer -o ${OUTPUT_CSS_FILE} ${INPUT_CSS_FILE} +cleancss --advanced --compatibility=ie8 -o ${OUTPUT_MIN_CSS_FILE} ${OUTPUT_CSS_FILE} + +echo "diff2html css created successfully!" diff --git a/scripts/release-templates.sh b/scripts/release-templates.sh new file mode 100755 index 0000000..061b105 --- /dev/null +++ b/scripts/release-templates.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -e + +SCRIPT_DIRECTORY="$( cd "$( dirname "$0" )" && pwd )" + +node ${SCRIPT_DIRECTORY}/hulk.js \ + --wrapper node \ + --variable 'browserTemplates' \ + ${SCRIPT_DIRECTORY}/../src/templates/*.mustache > ${SCRIPT_DIRECTORY}/../src/diff2html-templates.js diff --git a/scripts/release-website.js b/scripts/release-website.js index 5e51132..8c5ff0f 100644 --- a/scripts/release-website.js +++ b/scripts/release-website.js @@ -1,34 +1,38 @@ -var fs = require('fs'); +#!/usr/bin/env node -var hogan = require('hogan.js'); +const fs = require("fs"); -var root = 'website/templates'; -var pagesRoot = root + '/pages'; +const hogan = require("hogan.js"); -var websitePages = fs.readdirSync(root + '/pages'); +const root = "website/templates"; +const pagesRoot = root + "/pages"; -var template = hogan.compile(readFile(root + '/template.mustache')); +const websitePages = fs.readdirSync(root + "/pages"); -var options = { - 'all': { - 'demoUrl': 'demo.html?diff=https://github.com/rtfpessoa/diff2html/pull/106' +const template = hogan.compile(readFile(root + "/template.mustache")); + +const options = { + all: { + demoUrl: "demo.html?diff=https://github.com/rtfpessoa/diff2html/pull/106" }, - 'demo': { - 'extraClass': 'template-index-min' + demo: { + extraClass: "template-index-min" } }; websitePages.map(function(page) { - var pagePartialTemplate = hogan.compile(readFile(pagesRoot + '/' + page + '/' + page + '.partial.mustache')); - var pageAssetsTemplate = hogan.compile(readFile(pagesRoot + '/' + page + '/' + page + '-assets.partial.mustache')); - var pageScriptsTemplate = hogan.compile(readFile(pagesRoot + '/' + page + '/' + page + '-scripts.partial.mustache')); + const pagePartialTemplate = hogan.compile(readFile(pagesRoot + "/" + page + "/" + page + ".partial.mustache")); + const pageAssetsTemplate = hogan.compile(readFile(pagesRoot + "/" + page + "/" + page + "-assets.partial.mustache")); + const pageScriptsTemplate = hogan.compile( + readFile(pagesRoot + "/" + page + "/" + page + "-scripts.partial.mustache") + ); - var templateOptions = {}; + const templateOptions = {}; - var key; + let key; // Allow the pages to share common options - var genericOptions = options['all'] || {}; + const genericOptions = options.all || {}; for (key in genericOptions) { if (genericOptions.hasOwnProperty(key)) { templateOptions[key] = genericOptions[key]; @@ -36,32 +40,31 @@ websitePages.map(function(page) { } // Allow each page to have custom options - var pageOptions = options[page] || {}; + const pageOptions = options[page] || {}; for (key in pageOptions) { if (pageOptions.hasOwnProperty(key)) { templateOptions[key] = pageOptions[key]; } } - var pagePartial = pagePartialTemplate.render(templateOptions); - var pageAssets = pageAssetsTemplate.render(templateOptions); - var pageScripts = pageScriptsTemplate.render(templateOptions); + const pagePartial = pagePartialTemplate.render(templateOptions); + const pageAssets = pageAssetsTemplate.render(templateOptions); + const pageScripts = pageScriptsTemplate.render(templateOptions); templateOptions.assets = pageAssets; templateOptions.scripts = pageScripts; templateOptions.content = pagePartial; - var pageHtml = template.render(templateOptions); - writeFile('docs/' + page + '.html', pageHtml); + const pageHtml = template.render(templateOptions); + writeFile("docs/" + page + ".html", pageHtml); }); function readFile(filePath) { try { - return fs.readFileSync(filePath, 'utf8'); - } catch (_ignore) { - } + return fs.readFileSync(filePath, "utf8"); + } catch (_ignore) {} - return ''; + return ""; } function writeFile(filePath, content) { diff --git a/scripts/release-website.sh b/scripts/release-website.sh index 841732a..82573ef 100755 --- a/scripts/release-website.sh +++ b/scripts/release-website.sh @@ -1,17 +1,14 @@ #!/bin/bash -# -# diff2html website release script -# by rtfpessoa -# - set -e -INPUT_DIR=website +SCRIPT_DIRECTORY="$( cd "$( dirname "$0" )" && pwd )" + +INPUT_DIR=${SCRIPT_DIRECTORY}/../website INPUT_DEMO_JS=${INPUT_DIR}/templates/pages/demo/demo.js INPUT_CSS_FILE=${INPUT_DIR}/main.css -OUTPUT_DIR=docs +OUTPUT_DIR=${SCRIPT_DIRECTORY}/../docs OUTPUT_DEMO_JS=${OUTPUT_DIR}/demo.js OUTPUT_DEMO_MIN_JS=${OUTPUT_DIR}/demo.min.js OUTPUT_CSS_FILE=${OUTPUT_DIR}/main.css @@ -21,7 +18,7 @@ echo "Creating diff2html website release ..." echo "Cleaning previous versions ..." rm -rf ${OUTPUT_DIR} -mkdir -p ${OUTPUT_DIR} +mkdir -p ${OUTPUT_DIR}/assets echo "Minifying ${OUTPUT_CSS_FILE} to ${OUTPUT_MIN_CSS_FILE}" postcss --use autoprefixer -o ${OUTPUT_CSS_FILE} ${INPUT_CSS_FILE} @@ -31,10 +28,10 @@ echo "Generating website js aggregation file in ${OUTPUT_DEMO_JS}" browserify -e ${INPUT_DEMO_JS} -o ${OUTPUT_DEMO_JS} echo "Minifying ${OUTPUT_DEMO_JS} to ${OUTPUT_DEMO_MIN_JS}" -uglifyjs ${OUTPUT_DEMO_JS} -c -o ${OUTPUT_DEMO_MIN_JS} +terser ${OUTPUT_DEMO_JS} -c -o ${OUTPUT_DEMO_MIN_JS} echo "Generating HTMLs from templates ..." -node ./scripts/release-website.js +node ${SCRIPT_DIRECTORY}/release-website.js echo "Copying static files ..." cp -rf ${INPUT_DIR}/img ${OUTPUT_DIR}/ @@ -43,7 +40,9 @@ cp -f ${INPUT_DIR}/favicon.ico ${OUTPUT_DIR}/ cp -f ${INPUT_DIR}/robots.txt ${OUTPUT_DIR}/ cp -f ${INPUT_DIR}/sitemap.xml ${OUTPUT_DIR}/ -echo "Creating diff2html assets symlink ..." -ln -s ../dist docs/assets +echo "Copying diff2html resources ..." +cp ${SCRIPT_DIRECTORY}/../build/browser/diff2html.min.js ${SCRIPT_DIRECTORY}/../docs/assets/ +cp ${SCRIPT_DIRECTORY}/../build/browser/diff2html-ui.min.js ${SCRIPT_DIRECTORY}/../docs/assets/ +cp ${SCRIPT_DIRECTORY}/../build/css/diff2html.min.css ${SCRIPT_DIRECTORY}/../docs/assets/ echo "diff2html website release created successfully!" diff --git a/scripts/release.sh b/scripts/release.sh deleted file mode 100755 index 0d891fb..0000000 --- a/scripts/release.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash - -# -# diff2html release script -# by rtfpessoa -# - -set -e - -INPUT_DIR=src -INTPUT_TEMPLATES_DIR=${INPUT_DIR}/templates -INPUT_UI_DIR=${INPUT_DIR}/ui -INPUT_JS_FILE=${INPUT_DIR}/diff2html.js -INPUT_JS_UI_FILE=${INPUT_UI_DIR}/js/diff2html-ui.js -INPUT_CSS_FILE=${INPUT_UI_DIR}/css/diff2html.css -INPUT_TYPINGS_D_TS_FILE=${INPUT_DIR}/diff2html.d.ts - -GENERATED_TEMPLATES_FILE=${INTPUT_TEMPLATES_DIR}/diff2html-templates.js - -OUTPUT_DIR=dist -OUTPUT_JS_FILE=${OUTPUT_DIR}/diff2html.js -OUTPUT_MIN_JS_FILE=${OUTPUT_DIR}/diff2html.min.js -OUTPUT_JS_UI_FILE=${OUTPUT_DIR}/diff2html-ui.js -OUTPUT_MIN_JS_UI_FILE=${OUTPUT_DIR}/diff2html-ui.min.js -OUTPUT_CSS_FILE=${OUTPUT_DIR}/diff2html.css -OUTPUT_MIN_CSS_FILE=${OUTPUT_DIR}/diff2html.min.css -OUTPUT_TYPINGS_D_TS_FILE=${OUTPUT_DIR}/diff2html.d.ts - -echo "Creating diff2html release ..." - -echo "Cleaning previous versions ..." -rm -rf ${OUTPUT_DIR} -mkdir -p ${OUTPUT_DIR} - -echo "Minifying ${OUTPUT_CSS_FILE} to ${OUTPUT_MIN_CSS_FILE}" -postcss --use autoprefixer -o ${OUTPUT_CSS_FILE} ${INPUT_CSS_FILE} -cleancss --advanced --compatibility=ie8 -o ${OUTPUT_MIN_CSS_FILE} ${OUTPUT_CSS_FILE} - -echo "Pre-compile hogan.js templates" -yarn run templates - -echo "Generating js aggregation file in ${OUTPUT_JS_FILE}" -browserify -e ${INPUT_JS_FILE} -o ${OUTPUT_JS_FILE} - -echo "Minifying ${OUTPUT_JS_FILE} to ${OUTPUT_MIN_JS_FILE}" -uglifyjs ${OUTPUT_JS_FILE} -c -o ${OUTPUT_MIN_JS_FILE} - -echo "Generating js ui aggregation file in ${OUTPUT_JS_UI_FILE}" -browserify -e ${INPUT_JS_UI_FILE} -o ${OUTPUT_JS_UI_FILE} - -echo "Minifying ${OUTPUT_JS_UI_FILE} to ${OUTPUT_MIN_JS_UI_FILE}" -uglifyjs ${OUTPUT_JS_UI_FILE} -c -o ${OUTPUT_MIN_JS_UI_FILE} - -echo "Copying types ${INPUT_TYPINGS_D_TS_FILE} to ${OUTPUT_TYPINGS_D_TS_FILE}" -cp -f ${INPUT_TYPINGS_D_TS_FILE} ${OUTPUT_TYPINGS_D_TS_FILE} - -echo "diff2html release created successfully!" diff --git a/src/__tests__/diff-parser-tests.js b/src/__tests__/diff-parser-tests.js new file mode 100644 index 0000000..c0de992 --- /dev/null +++ b/src/__tests__/diff-parser-tests.js @@ -0,0 +1,728 @@ +const DiffParser = require("../diff-parser.js").DiffParser; + +function checkDiffSample(diff) { + const result = DiffParser.generateDiffJson(diff); + const file1 = result[0]; + expect(1).toEqual(result.length); + expect(1).toEqual(file1.addedLines); + expect(1).toEqual(file1.deletedLines); + expect("sample").toEqual(file1.oldName); + expect("sample").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); +} + +describe("DiffParser", function() { + describe("generateDiffJson", function() { + it("should parse unix with \n diff", function() { + const diff = + "diff --git a/sample b/sample\n" + + "index 0000001..0ddf2ba\n" + + "--- a/sample\n" + + "+++ b/sample\n" + + "@@ -1 +1 @@\n" + + "-test\n" + + "+test1r\n"; + checkDiffSample(diff); + }); + + it("should parse windows with \r\n diff", function() { + const diff = + "diff --git a/sample b/sample\r\n" + + "index 0000001..0ddf2ba\r\n" + + "--- a/sample\r\n" + + "+++ b/sample\r\n" + + "@@ -1 +1 @@\r\n" + + "-test\r\n" + + "+test1r\r\n"; + checkDiffSample(diff); + }); + + it("should parse old os x with \r diff", function() { + const diff = + "diff --git a/sample b/sample\r" + + "index 0000001..0ddf2ba\r" + + "--- a/sample\r" + + "+++ b/sample\r" + + "@@ -1 +1 @@\r" + + "-test\r" + + "+test1r\r"; + checkDiffSample(diff); + }); + + it("should parse mixed eols diff", function() { + const diff = + "diff --git a/sample b/sample\n" + + "index 0000001..0ddf2ba\r\n" + + "--- a/sample\r" + + "+++ b/sample\r\n" + + "@@ -1 +1 @@\n" + + "-test\r" + + "+test1r\n"; + checkDiffSample(diff); + }); + + it("should parse diff with special characters", function() { + const diff = + 'diff --git "a/bla with \ttab.scala" "b/bla with \ttab.scala"\n' + + "index 4c679d7..e9bd385 100644\n" + + '--- "a/bla with \ttab.scala"\n' + + '+++ "b/bla with \ttab.scala"\n' + + "@@ -1 +1,2 @@\n" + + "-cenas\n" + + "+cenas com ananas\n" + + "+bananas"; + + const result = DiffParser.generateDiffJson(diff); + const file1 = result[0]; + expect(1).toEqual(result.length); + expect(2).toEqual(file1.addedLines); + expect(1).toEqual(file1.deletedLines); + expect("bla with \ttab.scala").toEqual(file1.oldName); + expect("bla with \ttab.scala").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + }); + + it("should parse diff with prefix", function() { + const diff = + 'diff --git "\tbla with \ttab.scala" "\tbla with \ttab.scala"\n' + + "index 4c679d7..e9bd385 100644\n" + + '--- "\tbla with \ttab.scala"\n' + + '+++ "\tbla with \ttab.scala"\n' + + "@@ -1 +1,2 @@\n" + + "-cenas\n" + + "+cenas com ananas\n" + + "+bananas"; + + const result = DiffParser.generateDiffJson(diff, { srcPrefix: "\t", dstPrefix: "\t" }); + const file1 = result[0]; + expect(1).toEqual(result.length); + expect(2).toEqual(file1.addedLines); + expect(1).toEqual(file1.deletedLines); + expect("bla with \ttab.scala").toEqual(file1.oldName); + expect("bla with \ttab.scala").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + }); + + it("should parse diff with deleted file", function() { + const diff = + "diff --git a/src/var/strundefined.js b/src/var/strundefined.js\n" + + "deleted file mode 100644\n" + + "index 04e16b0..0000000\n" + + "--- a/src/var/strundefined.js\n" + + "+++ /dev/null\n" + + "@@ -1,3 +0,0 @@\n" + + "-define(function() {\n" + + "- return typeof undefined;\n" + + "-});\n"; + + const result = DiffParser.generateDiffJson(diff); + expect(1).toEqual(result.length); + + const file1 = result[0]; + expect(false).toEqual(file1.isCombined); + expect(0).toEqual(file1.addedLines); + expect(3).toEqual(file1.deletedLines); + expect("src/var/strundefined.js").toEqual(file1.oldName); + expect("/dev/null").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + expect(true).toEqual(file1.isDeleted); + expect("04e16b0").toEqual(file1.checksumBefore); + expect("0000000").toEqual(file1.checksumAfter); + }); + + it("should parse diff with new file", function() { + const diff = + "diff --git a/test.js b/test.js\n" + + "new file mode 100644\n" + + "index 0000000..e1e22ec\n" + + "--- /dev/null\n" + + "+++ b/test.js\n" + + "@@ -0,0 +1,5 @@\n" + + "+var parser = require('./source/git-parser');\n" + + "+\n" + + "+var patchLineList = [ false, false, false, false ];\n" + + "+\n" + + "+console.log(parser.parsePatchDiffResult(text, patchLineList));\n"; + + const result = DiffParser.generateDiffJson(diff); + expect(1).toEqual(result.length); + + const file1 = result[0]; + expect(false).toEqual(file1.isCombined); + expect(5).toEqual(file1.addedLines); + expect(0).toEqual(file1.deletedLines); + expect("/dev/null").toEqual(file1.oldName); + expect("test.js").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + expect(true).toEqual(file1.isNew); + expect("100644").toEqual(file1.newFileMode); + expect("0000000").toEqual(file1.checksumBefore); + expect("e1e22ec").toEqual(file1.checksumAfter); + }); + + it("should parse diff with nested diff", function() { + const diff = + "diff --git a/src/offset.js b/src/offset.js\n" + + "index cc6ffb4..fa51f18 100644\n" + + "--- a/src/offset.js\n" + + "+++ b/src/offset.js\n" + + "@@ -1,6 +1,5 @@\n" + + "+var parser = require('./source/git-parser');\n" + + "+\n" + + "+var text = 'diff --git a/components/app/app.html b/components/app/app.html\\nindex ecb7a95..027bd9b 100644\\n--- a/components/app/app.html\\n+++ b/components/app/app.html\\n@@ -52,0 +53,3 @@\\n+\\n+\\n+\\n@@ -56,0 +60,3 @@\\n+\\n+\\n+\\n'\n" + + "+var patchLineList = [ false, false, false, false ];\n" + + "+\n" + + "+console.log(parser.parsePatchDiffResult(text, patchLineList));\n"; + + const result = DiffParser.generateDiffJson(diff); + expect(1).toEqual(result.length); + + const file1 = result[0]; + expect(false).toEqual(file1.isCombined); + expect(6).toEqual(file1.addedLines); + expect(0).toEqual(file1.deletedLines); + expect("src/offset.js").toEqual(file1.oldName); + expect("src/offset.js").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + expect(6).toEqual(file1.blocks[0].lines.length); + expect("cc6ffb4").toEqual(file1.checksumBefore); + expect("fa51f18").toEqual(file1.checksumAfter); + }); + + it("should parse diff with multiple blocks", function() { + const diff = + "diff --git a/src/attributes/classes.js b/src/attributes/classes.js\n" + + "index c617824..c8d1393 100644\n" + + "--- a/src/attributes/classes.js\n" + + "+++ b/src/attributes/classes.js\n" + + "@@ -1,10 +1,9 @@\n" + + " define([\n" + + ' "../core",\n' + + ' "../var/rnotwhite",\n' + + '- "../var/strundefined",\n' + + ' "../data/var/dataPriv",\n' + + ' "../core/init"\n' + + "-], function( jQuery, rnotwhite, strundefined, dataPriv ) {\n" + + "+], function( jQuery, rnotwhite, dataPriv ) {\n" + + " \n" + + " var rclass = /[\\t\\r\\n\\f]/g;\n" + + " \n" + + "@@ -128,7 +127,7 @@ jQuery.fn.extend({\n" + + " }\n" + + " \n" + + " // Toggle whole class name\n" + + '- } else if ( type === strundefined || type === "boolean" ) {\n' + + '+ } else if ( value === undefined || type === "boolean" ) {\n' + + " if ( this.className ) {\n" + + " // store className if set\n" + + ' dataPriv.set( this, "__className__", this.className );\n'; + + const result = DiffParser.generateDiffJson(diff); + expect(1).toEqual(result.length); + + const file1 = result[0]; + expect(false).toEqual(file1.isCombined); + expect(2).toEqual(file1.addedLines); + expect(3).toEqual(file1.deletedLines); + expect("src/attributes/classes.js").toEqual(file1.oldName); + expect("src/attributes/classes.js").toEqual(file1.newName); + expect(2).toEqual(file1.blocks.length); + expect(11).toEqual(file1.blocks[0].lines.length); + expect(8).toEqual(file1.blocks[1].lines.length); + expect("c617824").toEqual(file1.checksumBefore); + expect("c8d1393").toEqual(file1.checksumAfter); + }); + + it("should parse diff with multiple files", function() { + const diff = + "diff --git a/src/core/init.js b/src/core/init.js\n" + + "index e49196a..50f310c 100644\n" + + "--- a/src/core/init.js\n" + + "+++ b/src/core/init.js\n" + + "@@ -101,7 +101,7 @@ var rootjQuery,\n" + + " // HANDLE: $(function)\n" + + " // Shortcut for document ready\n" + + " } else if ( jQuery.isFunction( selector ) ) {\n" + + '- return typeof rootjQuery.ready !== "undefined" ?\n' + + "+ return rootjQuery.ready !== undefined ?\n" + + " rootjQuery.ready( selector ) :\n" + + " // Execute immediately if ready is not present\n" + + " selector( jQuery );\n" + + "diff --git a/src/event.js b/src/event.js\n" + + "index 7336f4d..6183f70 100644\n" + + "--- a/src/event.js\n" + + "+++ b/src/event.js\n" + + "@@ -1,6 +1,5 @@\n" + + " define([\n" + + ' "./core",\n' + + '- "./var/strundefined",\n' + + ' "./var/rnotwhite",\n' + + ' "./var/hasOwn",\n' + + ' "./var/slice",\n'; + + const result = DiffParser.generateDiffJson(diff); + expect(2).toEqual(result.length); + + const file1 = result[0]; + expect(false).toEqual(file1.isCombined); + expect(1).toEqual(file1.addedLines); + expect(1).toEqual(file1.deletedLines); + expect("src/core/init.js").toEqual(file1.oldName); + expect("src/core/init.js").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + expect(8).toEqual(file1.blocks[0].lines.length); + expect("e49196a").toEqual(file1.checksumBefore); + expect("50f310c").toEqual(file1.checksumAfter); + + const file2 = result[1]; + expect(false).toEqual(file2.isCombined); + expect(0).toEqual(file2.addedLines); + expect(1).toEqual(file2.deletedLines); + expect("src/event.js").toEqual(file2.oldName); + expect("src/event.js").toEqual(file2.newName); + expect(1).toEqual(file2.blocks.length); + expect(6).toEqual(file2.blocks[0].lines.length); + expect("7336f4d").toEqual(file2.checksumBefore); + expect("6183f70").toEqual(file2.checksumAfter); + }); + + it("should parse combined diff", function() { + const diff = + "diff --combined describe.c\n" + + "index fabadb8,cc95eb0..4866510\n" + + "--- a/describe.c\n" + + "+++ b/describe.c\n" + + "@@@ -98,20 -98,12 +98,20 @@@\n" + + " return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;\n" + + " }\n" + + " \n" + + "- static void describe(char *arg)\n" + + " -static void describe(struct commit *cmit, int last_one)\n" + + "++static void describe(char *arg, int last_one)\n" + + " {\n" + + " + unsigned char sha1[20];\n" + + " + struct commit *cmit;\n" + + " struct commit_list *list;\n" + + " static int initialized = 0;\n" + + " struct commit_name *n;\n" + + " \n" + + " + if (get_sha1(arg, sha1) < 0)\n" + + " + usage(describe_usage);\n" + + " + cmit = lookup_commit_reference(sha1);\n" + + " + if (!cmit)\n" + + " + usage(describe_usage);\n" + + " +\n" + + " if (!initialized) {\n" + + " initialized = 1;\n" + + " for_each_ref(get_name);\n"; + + const result = DiffParser.generateDiffJson(diff); + expect(1).toEqual(result.length); + + const file1 = result[0]; + expect(true).toEqual(file1.isCombined); + expect(9).toEqual(file1.addedLines); + expect(2).toEqual(file1.deletedLines); + expect("describe.c").toEqual(file1.oldName); + expect("describe.c").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + expect(22).toEqual(file1.blocks[0].lines.length); + expect(["4866510", "cc95eb0"].sort()).toEqual(file1.checksumBefore.sort()); + expect("fabadb8").toEqual(file1.checksumAfter); + }); + + it("should parse diffs with copied files", function() { + const diff = + "diff --git a/index.js b/more-index.js\n" + + "dissimilarity index 5%\n" + + "copy from index.js\n" + + "copy to more-index.js\n"; + + const result = DiffParser.generateDiffJson(diff); + expect(1).toEqual(result.length); + + const file1 = result[0]; + expect(0).toEqual(file1.addedLines); + expect(0).toEqual(file1.deletedLines); + expect("index.js").toEqual(file1.oldName); + expect("more-index.js").toEqual(file1.newName); + expect(0).toEqual(file1.blocks.length); + expect(true).toEqual(file1.isCopy); + expect("5").toEqual(file1.changedPercentage); + }); + + it("should parse diffs with moved files", function() { + const diff = + "diff --git a/more-index.js b/other-index.js\n" + + "similarity index 86%\n" + + "rename from more-index.js\n" + + "rename to other-index.js\n"; + + const result = DiffParser.generateDiffJson(diff); + expect(1).toEqual(result.length); + + const file1 = result[0]; + expect(0).toEqual(file1.addedLines); + expect(0).toEqual(file1.deletedLines); + expect("more-index.js").toEqual(file1.oldName); + expect("other-index.js").toEqual(file1.newName); + expect(0).toEqual(file1.blocks.length); + expect(true).toEqual(file1.isRename); + expect("86").toEqual(file1.unchangedPercentage); + }); + + it("should parse diffs correct line numbers", function() { + const diff = + "diff --git a/sample b/sample\n" + + "index 0000001..0ddf2ba\n" + + "--- a/sample\n" + + "+++ b/sample\n" + + "@@ -1 +1,2 @@\n" + + "-test\n" + + "+test1r\n"; + + const result = DiffParser.generateDiffJson(diff); + expect(1).toEqual(result.length); + + const file1 = result[0]; + expect(1).toEqual(file1.addedLines); + expect(1).toEqual(file1.deletedLines); + expect("sample").toEqual(file1.oldName); + expect("sample").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + expect(2).toEqual(file1.blocks[0].lines.length); + expect(1).toEqual(file1.blocks[0].lines[0].oldNumber); + expect(null).toEqual(file1.blocks[0].lines[0].newNumber); + expect(null).toEqual(file1.blocks[0].lines[1].oldNumber); + expect(1).toEqual(file1.blocks[0].lines[1].newNumber); + }); + + it("should parse unified non git diff and strip timestamps off the headers", function() { + const diffs = [ + // 2 hours ahead of GMT + "--- a/sample.js 2016-10-25 11:37:14.000000000 +0200\n" + + "+++ b/sample.js 2016-10-25 11:37:14.000000000 +0200\n" + + "@@ -1 +1,2 @@\n" + + "-test\n" + + "+test1r\n" + + "+test2r\n", + // 2 hours behind GMT + "--- a/sample.js 2016-10-25 11:37:14.000000000 -0200\n" + + "+++ b/sample.js 2016-10-25 11:37:14.000000000 -0200\n" + + "@@ -1 +1,2 @@\n" + + "-test\n" + + "+test1r\n" + + "+test2r\n" + ]; + + diffs.forEach(function(diff) { + const result = DiffParser.generateDiffJson(diff); + const file1 = result[0]; + expect(1).toEqual(result.length); + expect(2).toEqual(file1.addedLines); + expect(1).toEqual(file1.deletedLines); + expect("sample.js").toEqual(file1.oldName); + expect("sample.js").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + + const linesContent = file1.blocks[0].lines.map(function(line) { + return line.content; + }); + expect(linesContent).toEqual(["-test", "+test1r", "+test2r"]); + }); + }); + + it("should parse unified non git diff", function() { + const diff = + "--- a/sample.js\n" + "+++ b/sample.js\n" + "@@ -1 +1,2 @@\n" + "-test\n" + "+test1r\n" + "+test2r\n"; + + const result = DiffParser.generateDiffJson(diff); + const file1 = result[0]; + expect(1).toEqual(result.length); + expect(2).toEqual(file1.addedLines); + expect(1).toEqual(file1.deletedLines); + expect("sample.js").toEqual(file1.oldName); + expect("sample.js").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + + const linesContent = file1.blocks[0].lines.map(function(line) { + return line.content; + }); + expect(linesContent).toEqual(["-test", "+test1r", "+test2r"]); + }); + + it("should parse unified diff with multiple hunks and files", function() { + const diff = + "--- sample.js\n" + + "+++ sample.js\n" + + "@@ -1 +1,2 @@\n" + + "-test\n" + + "@@ -10 +20,2 @@\n" + + "+test\n" + + "--- sample1.js\n" + + "+++ sample1.js\n" + + "@@ -1 +1,2 @@\n" + + "+test1"; + + const result = DiffParser.generateDiffJson(diff); + expect(2).toEqual(result.length); + + const file1 = result[0]; + expect(1).toEqual(file1.addedLines); + expect(1).toEqual(file1.deletedLines); + expect("sample.js").toEqual(file1.oldName); + expect("sample.js").toEqual(file1.newName); + expect(2).toEqual(file1.blocks.length); + + const linesContent1 = file1.blocks[0].lines.map(function(line) { + return line.content; + }); + expect(linesContent1).toEqual(["-test"]); + + const linesContent2 = file1.blocks[1].lines.map(function(line) { + return line.content; + }); + expect(linesContent2).toEqual(["+test"]); + + const file2 = result[1]; + expect(1).toEqual(file2.addedLines); + expect(0).toEqual(file2.deletedLines); + expect("sample1.js").toEqual(file2.oldName); + expect("sample1.js").toEqual(file2.newName); + expect(1).toEqual(file2.blocks.length); + + const linesContent = file2.blocks[0].lines.map(function(line) { + return line.content; + }); + expect(linesContent).toEqual(["+test1"]); + }); + + it("should parse diff with --- and +++ in the context lines", function() { + const diff = + "--- sample.js\n" + + "+++ sample.js\n" + + "@@ -1,8 +1,8 @@\n" + + " test\n" + + " \n" + + "-- 1\n" + + "--- 1\n" + + "---- 1\n" + + " \n" + + "++ 2\n" + + "+++ 2\n" + + "++++ 2"; + + const result = DiffParser.generateDiffJson(diff); + const file1 = result[0]; + expect(1).toEqual(result.length); + expect(3).toEqual(file1.addedLines); + expect(3).toEqual(file1.deletedLines); + expect("sample.js").toEqual(file1.oldName); + expect("sample.js").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + + const linesContent = file1.blocks[0].lines.map(function(line) { + return line.content; + }); + expect(linesContent).toEqual([" test", " ", "-- 1", "--- 1", "---- 1", " ", "++ 2", "+++ 2", "++++ 2"]); + }); + + it("should parse diff without proper hunk headers", function() { + const diff = "--- sample.js\n" + "+++ sample.js\n" + "@@ @@\n" + " test"; + + const result = DiffParser.generateDiffJson(diff); + const file1 = result[0]; + expect(1).toEqual(result.length); + expect(0).toEqual(file1.addedLines); + expect(0).toEqual(file1.deletedLines); + expect("sample.js").toEqual(file1.oldName); + expect("sample.js").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + + const linesContent = file1.blocks[0].lines.map(function(line) { + return line.content; + }); + expect(linesContent).toEqual([" test"]); + }); + + it("should parse binary file diff", function() { + const diff = + "diff --git a/last-changes-config.png b/last-changes-config.png\n" + + "index 322248b..56fc1f2 100644\n" + + "--- a/last-changes-config.png\n" + + "+++ b/last-changes-config.png\n" + + "Binary files differ"; + + const result = DiffParser.generateDiffJson(diff); + const file1 = result[0]; + expect(1).toEqual(result.length); + expect(0).toEqual(file1.addedLines); + expect(0).toEqual(file1.deletedLines); + expect("last-changes-config.png").toEqual(file1.oldName); + expect("last-changes-config.png").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + expect(0).toEqual(file1.blocks[0].lines.length); + expect("Binary files differ").toEqual(file1.blocks[0].header); + }); + + it("should parse diff with --find-renames", function() { + const diff = + "diff --git a/src/test-bar.js b/src/test-baz.js\n" + + "similarity index 98%\n" + + "rename from src/test-bar.js\n" + + "rename to src/test-baz.js\n" + + "index e01513b..f14a870 100644\n" + + "--- a/src/test-bar.js\n" + + "+++ b/src/test-baz.js\n" + + "@@ -1,4 +1,32 @@\n" + + " function foo() {\n" + + '-var bar = "Whoops!";\n' + + '+var baz = "Whoops!";\n' + + " }\n" + + " "; + + const result = DiffParser.generateDiffJson(diff); + const file1 = result[0]; + expect(1).toEqual(result.length); + expect(1).toEqual(file1.addedLines); + expect(1).toEqual(file1.deletedLines); + expect("src/test-bar.js").toEqual(file1.oldName); + expect("src/test-baz.js").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + expect(5).toEqual(file1.blocks[0].lines.length); + const linesContent = file1.blocks[0].lines.map(function(line) { + return line.content; + }); + expect(linesContent).toEqual([" function foo() {", '-var bar = "Whoops!";', '+var baz = "Whoops!";', " }", " "]); + }); + + it("should parse diff with prefix 2", function() { + const diff = + 'diff --git "\tTest.scala" "\tScalaTest.scala"\n' + + "similarity index 88%\n" + + "rename from Test.scala\n" + + "rename to ScalaTest.scala\n" + + "index 7d1f9bf..8b13271 100644\n" + + '--- "\tTest.scala"\n' + + '+++ "\tScalaTest.scala"\n' + + "@@ -1,6 +1,8 @@\n" + + " class Test {\n" + + " \n" + + " def method1 = ???\n" + + "+\n" + + "+ def method2 = ???\n" + + " \n" + + " def myMethod = ???\n" + + " \n" + + "@@ -10,7 +12,6 @@ class Test {\n" + + " \n" + + " def + = ???\n" + + " \n" + + "- def |> = ???\n" + + " \n" + + " }\n" + + " \n" + + 'diff --git "\ttardis.png" "\ttardis.png"\n' + + "new file mode 100644\n" + + "index 0000000..d503a29\n" + + 'Binary files /dev/null and "\ttardis.png" differ\n' + + "diff --git a/src/test-bar.js b/src/test-baz.js\n" + + "similarity index 98%\n" + + "rename from src/test-bar.js\n" + + "rename to src/test-baz.js\n" + + "index e01513b..f14a870 100644\n" + + "--- a/src/test-bar.js\n" + + "+++ b/src/test-baz.js\n" + + "@@ -1,4 +1,32 @@\n" + + " function foo() {\n" + + '-var bar = "Whoops!";\n' + + '+var baz = "Whoops!";\n' + + " }\n" + + " "; + + const result = DiffParser.generateDiffJson(diff, { srcPrefix: "\t", dstPrefix: "\t" }); + expect(3).toEqual(result.length); + + const file1 = result[0]; + expect(2).toEqual(file1.addedLines); + expect(1).toEqual(file1.deletedLines); + expect("Test.scala").toEqual(file1.oldName); + expect("ScalaTest.scala").toEqual(file1.newName); + expect(2).toEqual(file1.blocks.length); + expect(8).toEqual(file1.blocks[0].lines.length); + expect(7).toEqual(file1.blocks[1].lines.length); + + const file2 = result[1]; + expect("/dev/null").toEqual(file2.oldName); + expect("tardis.png").toEqual(file2.newName); + + const file3 = result[2]; + expect(1).toEqual(file3.addedLines); + expect(1).toEqual(file3.deletedLines); + expect("src/test-bar.js").toEqual(file3.oldName); + expect("src/test-baz.js").toEqual(file3.newName); + expect(1).toEqual(file3.blocks.length); + expect(5).toEqual(file3.blocks[0].lines.length); + const linesContent = file3.blocks[0].lines.map(function(line) { + return line.content; + }); + expect(linesContent).toEqual([" function foo() {", '-var bar = "Whoops!";', '+var baz = "Whoops!";', " }", " "]); + }); + + it("should parse binary with content", function() { + const diff = + "diff --git a/favicon.png b/favicon.png\n" + + "deleted file mode 100644\n" + + "index 2a9d516a5647205d7be510dd0dff93a3663eff6f..0000000000000000000000000000000000000000\n" + + "GIT binary patch\n" + + "literal 0\n" + + "HcmV?d00001\n" + + "\n" + + "literal 471\n" + + "zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ\n" + + "za0`JjqPVOAS4ANVKzqmCp=Cty@U^(7zk!jHsvT~YI{F^=Ex6g|gox78w\n" + + "z+Sn2Du3GS9U7qU`1*NYYlJi3u-!-_B#8k9H0\n" + + "zGl{FnZs<2$wz5^=Q2h-1XI^s{LQL1#T4epqNPC%Orl(tD_@!*EY++~^Lt2<2&!&%=\n" + + "z`m>(TYj6uS7jDdt=eH>iOyQg(QMR<-Fw8)Dk^ZG)XQTuzEgl{`GpS?Cfq9818R9~=\n" + + "z{&h9@9n8F^?|qusoPy{k#%tVHzu7H$t26CR`BJZk*Ixf&u36WuS=?6m2^ho-p00i_\n" + + "I>zopr0Nz-&lmGw#\n" + + "diff --git a/src/test-bar.js b/src/test-baz.js\n" + + "similarity index 98%\n" + + "rename from src/test-bar.js\n" + + "rename to src/test-baz.js\n" + + "index e01513b..f14a870 100644\n" + + "--- a/src/test-bar.js\n" + + "+++ b/src/test-baz.js\n" + + "@@ -1,4 +1,32 @@\n" + + " function foo() {\n" + + '-var bar = "Whoops!";\n' + + '+var baz = "Whoops!";\n' + + " }\n" + + " "; + + const result = DiffParser.generateDiffJson(diff); + expect(2).toEqual(result.length); + + const file1 = result[0]; + expect("favicon.png").toEqual(file1.oldName); + expect("favicon.png").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); + expect(0).toEqual(file1.blocks[0].lines.length); + + const file2 = result[1]; + expect(1).toEqual(file2.addedLines); + expect(1).toEqual(file2.deletedLines); + expect("src/test-bar.js").toEqual(file2.oldName); + expect("src/test-baz.js").toEqual(file2.newName); + expect(1).toEqual(file2.blocks.length); + expect(5).toEqual(file2.blocks[0].lines.length); + const linesContent = file2.blocks[0].lines.map(function(line) { + return line.content; + }); + expect(linesContent).toEqual([" function foo() {", '-var bar = "Whoops!";', '+var baz = "Whoops!";', " }", " "]); + }); + }); +}); diff --git a/test/diff2html-tests.js b/src/__tests__/diff2html-tests.js similarity index 60% rename from test/diff2html-tests.js rename to src/__tests__/diff2html-tests.js index af9914c..04810e7 100644 --- a/test/diff2html-tests.js +++ b/src/__tests__/diff2html-tests.js @@ -1,59 +1,56 @@ -var assert = require('assert'); +const Diff2Html = require("../diff2html.js").Diff2Html; -var Diff2Html = require('../src/diff2html.js').Diff2Html; +const diffExample1 = + "diff --git a/sample b/sample\n" + + "index 0000001..0ddf2ba\n" + + "--- a/sample\n" + + "+++ b/sample\n" + + "@@ -1 +1 @@\n" + + "-test\n" + + "+test1\n"; -var diffExample1 = - 'diff --git a/sample b/sample\n' + - 'index 0000001..0ddf2ba\n' + - '--- a/sample\n' + - '+++ b/sample\n' + - '@@ -1 +1 @@\n' + - '-test\n' + - '+test1\n'; +const jsonExample1 = [ + { + blocks: [ + { + lines: [ + { + content: "-test", + type: "d2h-del", + oldNumber: 1, + newNumber: null + }, + { + content: "+test1", + type: "d2h-ins", + oldNumber: null, + newNumber: 1 + } + ], + oldStartLine: "1", + oldStartLine2: null, + newStartLine: "1", + header: "@@ -1 +1 @@" + } + ], + deletedLines: 1, + addedLines: 1, + checksumBefore: "0000001", + checksumAfter: "0ddf2ba", + oldName: "sample", + language: undefined, + newName: "sample", + isCombined: false + } +]; -var jsonExample1 = - [ - { - blocks: [ - { - lines: [ - { - content: '-test', - type: 'd2h-del', - oldNumber: 1, - newNumber: null - }, - { - content: '+test1', - type: 'd2h-ins', - oldNumber: null, - newNumber: 1 - } - ], - oldStartLine: '1', - oldStartLine2: null, - newStartLine: '1', - header: '@@ -1 +1 @@' - } - ], - deletedLines: 1, - addedLines: 1, - checksumBefore: '0000001', - checksumAfter: '0ddf2ba', - oldName: 'sample', - language: undefined, - newName: 'sample', - isCombined: false - } - ]; - -var filesExample1 = +const filesExample1 = '
    \n' + '
    \n' + ' Files changed (1)\n' + ' hide\n' + ' show\n' + - '
    \n' + + "
    \n" + '
      \n' + '
    1. \n' + ' \n' + @@ -64,13 +61,13 @@ var filesExample1 = ' \n' + ' +1\n' + ' -1\n' + - ' \n' + - ' \n' + - '
    2. \n' + - '
    \n' + - ''; + " \n" + + " \n" + + "\n" + + " \n" + + ""; -var htmlLineExample1 = +const htmlLineExample1 = '
    \n' + '
    \n' + '
    \n' + @@ -79,49 +76,49 @@ var htmlLineExample1 = ' \n' + ' sample\n' + ' CHANGED\n' + - '
    \n' + + "
    \n" + '
    \n' + '
    \n' + ' \n' + ' \n' + - ' \n' + + " \n" + ' \n' + ' \n' + - '\n' + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + - ' \n' + - '
    \n' + '
    @@ -1 +1 @@
    \n' + - '
    \n' + '
    1
    \n' + '
    \n' + - '
    \n' + '
    \n' + ' -\n' + ' test\n' + - '
    \n' + - '
    \n' + '
    \n' + '
    1
    \n' + - '
    \n' + '
    \n' + ' +\n' + ' test1\n' + - '
    \n' + - '
    \n' + - '
    \n' + - '
    \n' + - '
    \n' + - ''; + " \n" + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n" + + ""; -var htmlLineExample1WithFilesSummary = filesExample1 + htmlLineExample1; +const htmlLineExample1WithFilesSummary = filesExample1 + htmlLineExample1; -var htmlSideExample1 = +const htmlSideExample1 = '
    \n' + '
    \n' + '
    \n' + @@ -130,187 +127,189 @@ var htmlSideExample1 = ' \n' + ' sample\n' + ' CHANGED\n' + - '
    \n' + + "
    \n" + '
    \n' + '
    \n' + '
    \n' + ' \n' + ' \n' + - ' \n' + + " \n" + ' \n' + ' \n' + - '\n' + + " \n" + + "\n" + ' \n' + + " 1\n" + + " \n" + ' \n' + - '\n' + - ' \n' + - '
    \n' + '
    @@ -1 +1 @@
    \n' + - '
    \n' + - ' 1\n' + - ' \n' + '
    \n' + ' -\n' + ' test\n' + - '
    \n' + - '
    \n' + - '
    \n' + - '
    \n' + + "
    \n" + + " \n" + + "\n" + + " \n" + + " \n" + + "
    \n" + + " \n" + '
    \n' + '
    \n' + ' \n' + ' \n' + - ' \n' + + " \n" + ' \n' + ' \n' + - '\n' + + " \n" + + "\n" + ' \n' + + " 1\n" + + " \n" + ' \n' + - '\n' + - ' \n' + - '
    \n' + '
    \n' + - '
    \n' + - ' 1\n' + - ' \n' + '
    \n' + ' +\n' + ' test1\n' + - '
    \n' + - '
    \n' + - '
    \n' + - '
    \n' + - ' \n' + - '\n' + - ''; + " \n" + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n" + + ""; -var htmlSideExample1WithFilesSummary = filesExample1 + htmlSideExample1; +const htmlSideExample1WithFilesSummary = filesExample1 + htmlSideExample1; -describe('Diff2Html', function() { - describe('getJsonFromDiff', function() { - it('should parse simple diff to json', function() { - var diff = - 'diff --git a/sample b/sample\n' + - 'index 0000001..0ddf2ba\n' + - '--- a/sample\n' + - '+++ b/sample\n' + - '@@ -1 +1 @@\n' + - '-test\n' + - '+test1\n'; - var result = Diff2Html.getJsonFromDiff(diff); +describe("Diff2Html", function() { + describe("getJsonFromDiff", function() { + it("should parse simple diff to json", function() { + const diff = + "diff --git a/sample b/sample\n" + + "index 0000001..0ddf2ba\n" + + "--- a/sample\n" + + "+++ b/sample\n" + + "@@ -1 +1 @@\n" + + "-test\n" + + "+test1\n"; + const result = Diff2Html.getJsonFromDiff(diff); - var file1 = result[0]; - assert.equal(1, result.length); - assert.equal(1, file1.addedLines); - assert.equal(1, file1.deletedLines); - assert.equal('sample', file1.oldName); - assert.equal('sample', file1.newName); - assert.equal(1, file1.blocks.length); + const file1 = result[0]; + expect(1).toEqual(result.length); + expect(1).toEqual(file1.addedLines); + expect(1).toEqual(file1.deletedLines); + expect("sample").toEqual(file1.oldName); + expect("sample").toEqual(file1.newName); + expect(1).toEqual(file1.blocks.length); }); // Test case for issue #49 - it('should parse diff with added EOF', function() { - var diff = - 'diff --git a/sample.scala b/sample.scala\n' + - 'index b583263..8b2fc3e 100644\n' + - '--- a/b583263..8b2fc3e\n' + - '+++ b/8b2fc3e\n' + - '@@ -50,5 +50,7 @@ case class Response[+A](value: Option[A],\n' + - ' object ResponseErrorCode extends JsonEnumeration {\n' + - ' val NoError, ServiceError, JsonError,\n' + - ' InvalidPermissions, MissingPermissions, GenericError,\n' + - '- TokenRevoked, MissingToken = Value\n' + - '-}\n' + - '\\ No newline at end of file\n' + - '+ TokenRevoked, MissingToken,\n' + - '+ IndexLock, RepositoryError, NotValidRepo, PullRequestNotMergeable, BranchError,\n' + - '+ PluginError, CodeParserError, EngineError = Value\n' + - '+}\n'; - var result = Diff2Html.getJsonFromDiff(diff); + it("should parse diff with added EOF", function() { + const diff = + "diff --git a/sample.scala b/sample.scala\n" + + "index b583263..8b2fc3e 100644\n" + + "--- a/b583263..8b2fc3e\n" + + "+++ b/8b2fc3e\n" + + "@@ -50,5 +50,7 @@ case class Response[+A](value: Option[A],\n" + + " object ResponseErrorCode extends JsonEnumeration {\n" + + " val NoError, ServiceError, JsonError,\n" + + " InvalidPermissions, MissingPermissions, GenericError,\n" + + "- TokenRevoked, MissingToken = Value\n" + + "-}\n" + + "\\ No newline at end of file\n" + + "+ TokenRevoked, MissingToken,\n" + + "+ IndexLock, RepositoryError, NotValidRepo, PullRequestNotMergeable, BranchError,\n" + + "+ PluginError, CodeParserError, EngineError = Value\n" + + "+}\n"; + const result = Diff2Html.getJsonFromDiff(diff); - assert.equal(50, result[0].blocks[0].lines[0].oldNumber); - assert.equal(50, result[0].blocks[0].lines[0].newNumber); + expect(50).toEqual(result[0].blocks[0].lines[0].oldNumber); + expect(50).toEqual(result[0].blocks[0].lines[0].newNumber); - assert.equal(51, result[0].blocks[0].lines[1].oldNumber); - assert.equal(51, result[0].blocks[0].lines[1].newNumber); + expect(51).toEqual(result[0].blocks[0].lines[1].oldNumber); + expect(51).toEqual(result[0].blocks[0].lines[1].newNumber); - assert.equal(52, result[0].blocks[0].lines[2].oldNumber); - assert.equal(52, result[0].blocks[0].lines[2].newNumber); + expect(52).toEqual(result[0].blocks[0].lines[2].oldNumber); + expect(52).toEqual(result[0].blocks[0].lines[2].newNumber); - assert.equal(53, result[0].blocks[0].lines[3].oldNumber); - assert.equal(null, result[0].blocks[0].lines[3].newNumber); + expect(53).toEqual(result[0].blocks[0].lines[3].oldNumber); + expect(null).toEqual(result[0].blocks[0].lines[3].newNumber); - assert.equal(54, result[0].blocks[0].lines[4].oldNumber); - assert.equal(null, result[0].blocks[0].lines[4].newNumber); + expect(54).toEqual(result[0].blocks[0].lines[4].oldNumber); + expect(null).toEqual(result[0].blocks[0].lines[4].newNumber); - assert.equal(null, result[0].blocks[0].lines[5].oldNumber); - assert.equal(53, result[0].blocks[0].lines[5].newNumber); + expect(null).toEqual(result[0].blocks[0].lines[5].oldNumber); + expect(53).toEqual(result[0].blocks[0].lines[5].newNumber); - assert.equal(null, result[0].blocks[0].lines[6].oldNumber); - assert.equal(54, result[0].blocks[0].lines[6].newNumber); + expect(null).toEqual(result[0].blocks[0].lines[6].oldNumber); + expect(54).toEqual(result[0].blocks[0].lines[6].newNumber); - assert.equal(null, result[0].blocks[0].lines[7].oldNumber); - assert.equal(55, result[0].blocks[0].lines[7].newNumber); + expect(null).toEqual(result[0].blocks[0].lines[7].oldNumber); + expect(55).toEqual(result[0].blocks[0].lines[7].newNumber); - assert.equal(null, result[0].blocks[0].lines[8].oldNumber); - assert.equal(56, result[0].blocks[0].lines[8].newNumber); + expect(null).toEqual(result[0].blocks[0].lines[8].oldNumber); + expect(56).toEqual(result[0].blocks[0].lines[8].newNumber); }); - it('should generate pretty line by line html from diff', function() { - var result = Diff2Html.getPrettyHtmlFromDiff(diffExample1); - assert.equal(htmlLineExample1, result); + it("should generate pretty line by line html from diff", function() { + const result = Diff2Html.getPrettyHtmlFromDiff(diffExample1); + expect(htmlLineExample1).toEqual(result); }); - it('should generate pretty line by line html from json', function() { - var result = Diff2Html.getPrettyHtmlFromJson(jsonExample1); - assert.equal(htmlLineExample1, result); + it("should generate pretty line by line html from json", function() { + const result = Diff2Html.getPrettyHtmlFromJson(jsonExample1); + expect(htmlLineExample1).toEqual(result); }); - it('should generate pretty diff with files summary', function() { - var result = Diff2Html.getPrettyHtmlFromDiff(diffExample1, {showFiles: true}); - assert.equal(htmlLineExample1WithFilesSummary, result); + it("should generate pretty diff with files summary", function() { + const result = Diff2Html.getPrettyHtmlFromDiff(diffExample1, { showFiles: true }); + expect(htmlLineExample1WithFilesSummary).toEqual(result); }); - it('should generate pretty side by side html from diff', function() { - var result = Diff2Html.getPrettySideBySideHtmlFromDiff(diffExample1); - assert.equal(htmlSideExample1, result); + it("should generate pretty side by side html from diff", function() { + const result = Diff2Html.getPrettySideBySideHtmlFromDiff(diffExample1); + expect(htmlSideExample1).toEqual(result); }); - it('should generate pretty side by side html from json', function() { - var result = Diff2Html.getPrettySideBySideHtmlFromJson(jsonExample1); - assert.equal(htmlSideExample1, result); + it("should generate pretty side by side html from json", function() { + const result = Diff2Html.getPrettySideBySideHtmlFromJson(jsonExample1); + expect(htmlSideExample1).toEqual(result); }); - it('should generate pretty side by side html from diff', function() { - var result = Diff2Html.getPrettySideBySideHtmlFromDiff(diffExample1, {showFiles: true}); - assert.equal(htmlSideExample1WithFilesSummary, result); + it("should generate pretty side by side html from diff 2", function() { + const result = Diff2Html.getPrettySideBySideHtmlFromDiff(diffExample1, { showFiles: true }); + expect(htmlSideExample1WithFilesSummary).toEqual(result); }); - it('should generate pretty side by side html from diff with html on headers', function() { - var diffExample2 = 'diff --git a/CHANGELOG.md b/CHANGELOG.md\n' + - 'index fc3e3f4..b486d10 100644\n' + - '--- a/CHANGELOG.md\n' + - '+++ b/CHANGELOG.md\n' + - '@@ -1,7 +1,6 @@\n' + - ' # Change Log\n' + - ' All notable changes to this project will be documented in this file.\n' + - ' This project adheres to [Semantic Versioning](http://semver.org/).\n' + + it("should generate pretty side by side html from diff with html on headers", function() { + const diffExample2 = + "diff --git a/CHANGELOG.md b/CHANGELOG.md\n" + + "index fc3e3f4..b486d10 100644\n" + + "--- a/CHANGELOG.md\n" + + "+++ b/CHANGELOG.md\n" + + "@@ -1,7 +1,6 @@\n" + + " # Change Log\n" + + " All notable changes to this project will be documented in this file.\n" + + " This project adheres to [Semantic Versioning](http://semver.org/).\n" + '-$a="\n" + + "
    Use the following format for additions: ` - VERSION: [feature/patch (if applicable)] Short description of change. Links to relevant issues/PRs.`\n' + ' $a="\n" + + "
    \n' + " $a=\"\n" + + ' \n" + + ""; + + it("should render view", function() { + const result = HoganJsUtils.render("generic", "empty-diff", { + contentClass: "d2h-code-line", + diffParser: diffParser + }); + expect(emptyDiffHtml).toEqual(result); + }); + + it("should render view without cache", function() { + const result = HoganJsUtils.render( + "generic", + "empty-diff", + { + contentClass: "d2h-code-line", + diffParser: diffParser + }, + { noCache: true } + ); + expect(emptyDiffHtml).toEqual(result); + }); + + it("should return null if template is missing", function() { + const hoganUtils = new (require("../hoganjs-utils.js")).HoganJsUtils({ noCache: true }); + const result = hoganUtils.render("generic", "missing-template", {}); + expect(null).toEqual(result); + }); + + it("should allow templates to be overridden with compiled templates", function() { + const emptyDiffTemplate = HoganJsUtils.compile("

    {{myName}}

    "); + + const config = { templates: { "generic-empty-diff": emptyDiffTemplate } }; + const hoganUtils = new (require("../hoganjs-utils.js")).HoganJsUtils(config); + const result = hoganUtils.render("generic", "empty-diff", { myName: "Rodrigo Fernandes" }); + expect("

    Rodrigo Fernandes

    ").toEqual(result); + }); + + it("should allow templates to be overridden with uncompiled templates", function() { + const emptyDiffTemplate = "

    {{myName}}

    "; + + const config = { rawTemplates: { "generic-empty-diff": emptyDiffTemplate } }; + const hoganUtils = new (require("../hoganjs-utils.js")).HoganJsUtils(config); + const result = hoganUtils.render("generic", "empty-diff", { myName: "Rodrigo Fernandes" }); + expect("

    Rodrigo Fernandes

    ").toEqual(result); + }); + + it("should allow templates to be overridden giving priority to compiled templates", function() { + const emptyDiffTemplate = HoganJsUtils.compile("

    {{myName}}

    "); + const emptyDiffTemplateUncompiled = "

    Not used!

    "; + + const config = { + templates: { "generic-empty-diff": emptyDiffTemplate }, + rawTemplates: { "generic-empty-diff": emptyDiffTemplateUncompiled } + }; + const hoganUtils = new (require("../hoganjs-utils.js")).HoganJsUtils(config); + const result = hoganUtils.render("generic", "empty-diff", { myName: "Rodrigo Fernandes" }); + expect("

    Rodrigo Fernandes

    ").toEqual(result); + }); + }); +}); diff --git a/test/line-by-line-tests.js b/src/__tests__/line-by-line-tests.js similarity index 54% rename from test/line-by-line-tests.js rename to src/__tests__/line-by-line-tests.js index 72d3711..60b5836 100644 --- a/test/line-by-line-tests.js +++ b/src/__tests__/line-by-line-tests.js @@ -1,153 +1,152 @@ -var assert = require('assert'); +const LineByLinePrinter = require("../line-by-line-printer.js").LineByLinePrinter; -var LineByLinePrinter = require('../src/line-by-line-printer.js').LineByLinePrinter; - -describe('LineByLinePrinter', function() { - describe('_generateEmptyDiff', function() { - it('should return an empty diff', function() { - var lineByLinePrinter = new LineByLinePrinter({}); - var fileHtml = lineByLinePrinter._generateEmptyDiff(); - var expected = '\n' + +describe("LineByLinePrinter", function() { + describe("_generateEmptyDiff", function() { + it("should return an empty diff", function() { + const lineByLinePrinter = new LineByLinePrinter({}); + const fileHtml = lineByLinePrinter._generateEmptyDiff(); + const expected = + "\n" + ' \n' + - ''; + " File without changes\n" + + " \n" + + " \n" + + ""; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); }); - describe('makeLineHtml', function() { - it('should work for insertions', function() { - var diffParser = require('../src/diff-parser.js').DiffParser; - var lineByLinePrinter = new LineByLinePrinter({}); - var fileHtml = lineByLinePrinter.makeLineHtml(false, - diffParser.LINE_TYPE.INSERTS, '', 30, 'test', '+'); - fileHtml = fileHtml.replace(/\n\n+/g, '\n'); - var expected = '\n' + + describe("makeLineHtml", function() { + it("should work for insertions", function() { + const diffParser = require("../diff-parser.js").DiffParser; + const lineByLinePrinter = new LineByLinePrinter({}); + let fileHtml = lineByLinePrinter.makeLineHtml(false, diffParser.LINE_TYPE.INSERTS, "", 30, "test", "+"); + fileHtml = fileHtml.replace(/\n\n+/g, "\n"); + const expected = + "\n" + ' \n' + + " \n" + ' \n' + - ''; + " \n" + + " \n" + + ""; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); - it('should work for deletions', function() { - var diffParser = require('../src/diff-parser.js').DiffParser; - var lineByLinePrinter = new LineByLinePrinter({}); - var fileHtml = lineByLinePrinter.makeLineHtml(false, - diffParser.LINE_TYPE.DELETES, 30, '', 'test', '-'); - fileHtml = fileHtml.replace(/\n\n+/g, '\n'); - var expected = '\n' + + it("should work for deletions", function() { + const diffParser = require("../diff-parser.js").DiffParser; + const lineByLinePrinter = new LineByLinePrinter({}); + let fileHtml = lineByLinePrinter.makeLineHtml(false, diffParser.LINE_TYPE.DELETES, 30, "", "test", "-"); + fileHtml = fileHtml.replace(/\n\n+/g, "\n"); + const expected = + "\n" + ' \n' + + " \n" + ' \n' + - ''; + " \n" + + " \n" + + ""; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); - it('should convert indents into non breakin spaces (2 white spaces)', function() { - var diffParser = require('../src/diff-parser.js').DiffParser; - var lineByLinePrinter = new LineByLinePrinter({}); - var fileHtml = lineByLinePrinter.makeLineHtml(false, - diffParser.LINE_TYPE.INSERTS, '', 30, ' test', '+'); - fileHtml = fileHtml.replace(/\n\n+/g, '\n'); - var expected = '\n' + + it("should convert indents into non breakin spaces (2 white spaces)", function() { + const diffParser = require("../diff-parser.js").DiffParser; + const lineByLinePrinter = new LineByLinePrinter({}); + let fileHtml = lineByLinePrinter.makeLineHtml(false, diffParser.LINE_TYPE.INSERTS, "", 30, " test", "+"); + fileHtml = fileHtml.replace(/\n\n+/g, "\n"); + const expected = + "\n" + ' \n' + + " \n" + ' \n' + - ''; + " \n" + + " \n" + + ""; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); - it('should convert indents into non breakin spaces (4 white spaces)', function() { - var diffParser = require('../src/diff-parser.js').DiffParser; - var lineByLinePrinter = new LineByLinePrinter({}); - var fileHtml = lineByLinePrinter.makeLineHtml(false, - diffParser.LINE_TYPE.INSERTS, '', 30, ' test', '+'); - fileHtml = fileHtml.replace(/\n\n+/g, '\n'); - var expected = '\n' + + it("should convert indents into non breakin spaces (4 white spaces)", function() { + const diffParser = require("../diff-parser.js").DiffParser; + const lineByLinePrinter = new LineByLinePrinter({}); + let fileHtml = lineByLinePrinter.makeLineHtml(false, diffParser.LINE_TYPE.INSERTS, "", 30, " test", "+"); + fileHtml = fileHtml.replace(/\n\n+/g, "\n"); + const expected = + "\n" + ' \n' + + " \n" + ' \n' + - ''; + " \n" + + " \n" + + ""; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); - it('should preserve tabs', function() { - var diffParser = require('../src/diff-parser.js').DiffParser; - var lineByLinePrinter = new LineByLinePrinter({}); - var fileHtml = lineByLinePrinter.makeLineHtml(false, - diffParser.LINE_TYPE.INSERTS, '', 30, '\ttest', '+'); - fileHtml = fileHtml.replace(/\n\n+/g, '\n'); - var expected = '\n' + + it("should preserve tabs", function() { + const diffParser = require("../diff-parser.js").DiffParser; + const lineByLinePrinter = new LineByLinePrinter({}); + let fileHtml = lineByLinePrinter.makeLineHtml(false, diffParser.LINE_TYPE.INSERTS, "", 30, "\ttest", "+"); + fileHtml = fileHtml.replace(/\n\n+/g, "\n"); + const expected = + "\n" + ' \n' + + " \n" + ' \n' + - ''; + " \n" + + " \n" + + ""; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); }); - describe('makeFileDiffHtml', function() { - it('should work for simple file', function() { - var lineByLinePrinter = new LineByLinePrinter({}); + describe("makeFileDiffHtml", function() { + it("should work for simple file", function() { + const lineByLinePrinter = new LineByLinePrinter({}); - var file = { + const file = { addedLines: 12, deletedLines: 41, - language: 'js', - oldName: 'my/file/name.js', - newName: 'my/file/name.js' + language: "js", + oldName: "my/file/name.js", + newName: "my/file/name.js" }; - var diffs = 'Random Html'; + const diffs = "Random Html"; - var fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs); + const fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs); - var expected = + const expected = '
    \n' + '
    \n' + ' \n' + @@ -155,36 +154,36 @@ describe('LineByLinePrinter', function() { ' \n' + ' my/file/name.js\n' + ' CHANGED\n' + - '
    \n' + + "
    \n" + '
    \n' + '
    \n' + '
    - 1.1.9: Fix around ubuntu's inability to cache promises. [#877](https://github.com/FredrikNoren/ungit/pull/878)\n" + - ' - 1.1.8:\n' + + " - 1.1.8:\n" + "@@ -11,7 +10,7 @@ $a=\"\n" + + "\n" + + " \n" + + "
    - 1.1.9: Fix around ubuntu's inability to cache promises. [#8\n" + - ' - 1.1.7:\n' + - ' - Fix diff flickering issue and optimization [#865](https://github.com/FredrikNoren/ungit/pull/865)\n' + - ' - Fix credential dialog issue [#864](https://github.com/FredrikNoren/ungit/pull/864)\n' + - '- - Fix HEAD branch order when redraw [#858](https://github.com/FredrikNoren/ungit/issues/858)\n' + - '+4 - Fix HEAD branch order when redraw [#858](https://github.com/FredrikNoren/ungit/issues/858)\n' + - ' - 1.1.6: Fix path auto complete [#861](https://github.com/FredrikNoren/ungit/issues/861)\n' + + " - 1.1.7:\n" + + " - Fix diff flickering issue and optimization [#865](https://github.com/FredrikNoren/ungit/pull/865)\n" + + " - Fix credential dialog issue [#864](https://github.com/FredrikNoren/ungit/pull/864)\n" + + "- - Fix HEAD branch order when redraw [#858](https://github.com/FredrikNoren/ungit/issues/858)\n" + + "+4 - Fix HEAD branch order when redraw [#858](https://github.com/FredrikNoren/ungit/issues/858)\n" + + " - 1.1.6: Fix path auto complete [#861](https://github.com/FredrikNoren/ungit/issues/861)\n" + ' - 1.1.5: Update "Toggle all" button after commit or changing selected files [#859](https://github.com/FredrikNoren/ungit/issues/859)\n' + - ' - 1.1.4: [patch] Promise refactoring\n' + - ' \n'; + " - 1.1.4: [patch] Promise refactoring\n" + + " \n"; - var htmlExample2 = '
    \n' + + const htmlExample2 = + '
    \n' + '
    \n' + '
    \n' + ' \n' + @@ -318,207 +317,207 @@ describe('Diff2Html', function() { ' \n' + ' CHANGELOG.md\n' + ' CHANGED\n' + - '
    \n' + + "
    \n" + '
    \n' + '
    \n' + ' \n' + ' \n' + - ' \n' + + " \n" + ' \n' + ' \n' + - '\n' + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + - '\n' + + " \n" + + " \n" + + "\n" + + "\n" + ' \n' + ' \n' + - '\n' + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + - ' \n' + - '
    \n' + '
    @@ -1,7 +1,6 @@
    \n' + - '
    \n' + '
    1
    \n' + '
    1
    \n' + - '
    \n' + '
    \n' + '  \n' + ' # Change Log\n' + - '
    \n' + - '
    \n' + '
    2
    \n' + '
    2
    \n' + - '
    \n' + '
    \n' + '  \n' + ' All notable changes to this project will be documented in this file.\n' + - '
    \n' + - '
    \n' + '
    3
    \n' + '
    3
    \n' + - '
    \n' + '
    \n' + '  \n' + ' This project adheres to [Semantic Versioning](http://semver.org/).\n' + - '
    \n' + - '
    \n' + '
    4
    \n' + '
    \n' + - '
    \n' + '
    \n' + ' -\n' + ' $a="<table><tr><td>Use the following format for additions: ` - VERSION: [feature/patch (if applicable)] Short description of change. Links to relevant issues/PRs.`\n' + - '
    \n' + - '
    \n' + '
    5
    \n' + '
    4
    \n' + - '
    \n' + '
    \n' + '  \n' + ' $a="<table><tr><td>\n' + - '
    \n' + - '
    \n' + '
    6
    \n' + '
    5
    \n' + - '
    \n' + '
    \n' + '  \n' + ' $a="<table><tr><td>- 1.1.9: Fix around ubuntu's inability to cache promises. [#877](https://github.com/FredrikNoren/ungit/pull/878)\n' + - '
    \n' + - '
    \n' + '
    7
    \n' + '
    6
    \n' + - '
    \n' + '
    \n' + '  \n' + ' - 1.1.8:\n' + - '
    \n' + - '
    \n' + '
    @@ -11,7 +10,7 @@ $a="<table><tr><td>- 1.1.9: Fix around ubuntu's inability to cache promises. [#8
    \n' + - '
    \n' + '
    11
    \n' + '
    10
    \n' + - '
    \n' + '
    \n' + '  \n' + ' - 1.1.7:\n' + - '
    \n' + - '
    \n' + '
    12
    \n' + '
    11
    \n' + - '
    \n' + '
    \n' + '  \n' + ' - Fix diff flickering issue and optimization [#865](https://github.com/FredrikNoren/ungit/pull/865)\n' + - '
    \n' + - '
    \n' + '
    13
    \n' + '
    12
    \n' + - '
    \n' + '
    \n' + '  \n' + ' - Fix credential dialog issue [#864](https://github.com/FredrikNoren/ungit/pull/864)\n' + - '
    \n' + - '
    \n' + '
    14
    \n' + '
    \n' + - '
    \n' + '
    \n' + ' -\n' + ' - Fix HEAD branch order when redraw [#858](https://github.com/FredrikNoren/ungit/issues/858)\n' + - '
    \n' + - '
    \n' + '
    \n' + '
    13
    \n' + - '
    \n' + '
    \n' + ' +\n' + ' 4 - Fix HEAD branch order when redraw [#858](https://github.com/FredrikNoren/ungit/issues/858)\n' + - '
    \n' + - '
    \n' + '
    15
    \n' + '
    14
    \n' + - '
    \n' + '
    \n' + '  \n' + ' - 1.1.6: Fix path auto complete [#861](https://github.com/FredrikNoren/ungit/issues/861)\n' + - '
    \n' + - '
    \n' + '
    16
    \n' + '
    15
    \n' + - '
    \n' + '
    \n' + '  \n' + ' - 1.1.5: Update "Toggle all" button after commit or changing selected files [#859](https://github.com/FredrikNoren/ungit/issues/859)\n' + - '
    \n' + - '
    \n' + '
    17
    \n' + '
    16
    \n' + - '
    \n' + '
    \n' + '  \n' + ' - 1.1.4: [patch] Promise refactoring\n' + - '
    \n' + - '
    \n' + '
    18
    \n' + '
    17
    \n' + - '
    \n' + '
    \n' + '  \n' + - '
    \n' + - '
    \n' + - '
    \n' + - '
    \n' + - '
    \n' + - '
    '; + " \n" + + "
    \n" + + " \n" + + " \n" + + "\n" + + ""; - var result = Diff2Html.getPrettyHtmlFromDiff(diffExample2); - assert.equal(result, htmlExample2); + const result = Diff2Html.getPrettyHtmlFromDiff(diffExample2); + expect(result).toEqual(htmlExample2); }); }); }); diff --git a/test/file-list-printer-tests.js b/src/__tests__/file-list-printer-tests.js similarity index 53% rename from test/file-list-printer-tests.js rename to src/__tests__/file-list-printer-tests.js index 55c6cfe..9361474 100644 --- a/test/file-list-printer-tests.js +++ b/src/__tests__/file-list-printer-tests.js @@ -1,92 +1,102 @@ -var assert = require('assert'); -var FileListPrinter = require('../src/file-list-printer.js').FileListPrinter; +const FileListPrinter = require("../file-list-printer.js").FileListPrinter; -describe('FileListPrinter', function() { - describe('generateFileList', function() { - it('should expose old and new files to templates', function() { - var files = [{ - addedlines: 12, - deletedlines: 41, - language: 'js', - oldName: 'my/file/name.js', - newName: 'my/file/name.js' - }, { - addedLines: 12, - deletedLines: 41, - language: 'js', - oldName: 'my/file/name1.js', - newName: 'my/file/name2.js' - }, { - addedLines: 12, - deletedLines: 0, - language: 'js', - oldName: 'dev/null', - newName: 'my/file/name.js', - isNew: true - }, { - addedLines: 0, - deletedLines: 41, - language: 'js', - oldName: 'my/file/name.js', - newName: 'dev/null', - isDeleted: true - }]; +describe("FileListPrinter", function() { + describe("generateFileList", function() { + it("should expose old and new files to templates", function() { + const files = [ + { + addedlines: 12, + deletedlines: 41, + language: "js", + oldName: "my/file/name.js", + newName: "my/file/name.js" + }, + { + addedLines: 12, + deletedLines: 41, + language: "js", + oldName: "my/file/name1.js", + newName: "my/file/name2.js" + }, + { + addedLines: 12, + deletedLines: 0, + language: "js", + oldName: "dev/null", + newName: "my/file/name.js", + isNew: true + }, + { + addedLines: 0, + deletedLines: 41, + language: "js", + oldName: "my/file/name.js", + newName: "dev/null", + isDeleted: true + } + ]; - var fileListPrinter = new FileListPrinter({ + const fileListPrinter = new FileListPrinter({ rawTemplates: { - 'file-summary-wrapper': '{{{files}}}', - 'file-summary-line': '{{oldName}}, {{newName}}, {{fileName}}' + "file-summary-wrapper": "{{{files}}}", + "file-summary-line": "{{oldName}}, {{newName}}, {{fileName}}" } }); - var fileHtml = fileListPrinter.generateFileList(files); - var expected = 'my/file/name.js, my/file/name.js, my/file/name.js\n' + - 'my/file/name1.js, my/file/name2.js, my/file/{name1.js → name2.js}\n' + - 'dev/null, my/file/name.js, my/file/name.js\n' + - 'my/file/name.js, dev/null, my/file/name.js'; + const fileHtml = fileListPrinter.generateFileList(files); + const expected = + "my/file/name.js, my/file/name.js, my/file/name.js\n" + + "my/file/name1.js, my/file/name2.js, my/file/{name1.js → name2.js}\n" + + "dev/null, my/file/name.js, my/file/name.js\n" + + "my/file/name.js, dev/null, my/file/name.js"; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); - it('should work for all kinds of files', function() { - var files = [{ - addedLines: 12, - deletedLines: 41, - language: 'js', - oldName: 'my/file/name.js', - newName: 'my/file/name.js' - }, { - addedLines: 12, - deletedLines: 41, - language: 'js', - oldName: 'my/file/name1.js', - newName: 'my/file/name2.js' - }, { - addedLines: 12, - deletedLines: 0, - language: 'js', - oldName: 'dev/null', - newName: 'my/file/name.js', - isNew: true - }, { - addedLines: 0, - deletedLines: 41, - language: 'js', - oldName: 'my/file/name.js', - newName: 'dev/null', - isDeleted: true - }]; + it("should work for all kinds of files", function() { + const files = [ + { + addedLines: 12, + deletedLines: 41, + language: "js", + oldName: "my/file/name.js", + newName: "my/file/name.js" + }, + { + addedLines: 12, + deletedLines: 41, + language: "js", + oldName: "my/file/name1.js", + newName: "my/file/name2.js" + }, + { + addedLines: 12, + deletedLines: 0, + language: "js", + oldName: "dev/null", + newName: "my/file/name.js", + isNew: true + }, + { + addedLines: 0, + deletedLines: 41, + language: "js", + oldName: "my/file/name.js", + newName: "dev/null", + isDeleted: true + } + ]; - var fileListPrinter = new FileListPrinter(); - var fileHtml = fileListPrinter.generateFileList(files); + const fileListPrinter = new FileListPrinter(); + const fileHtml = fileListPrinter.generateFileList(files); - var expected = + const expected = '
    \n' + '
    \n' + ' Files changed (4)\n' + ' hide\n' + ' show\n' + - '
    \n' + + "
    \n" + '
      \n' + '
    1. \n' + ' \n' + @@ -97,9 +107,9 @@ describe('FileListPrinter', function() { ' \n' + ' +12\n' + ' -41\n' + - ' \n' + - ' \n' + - '
    2. \n' + + " \n" + + " \n" + + "\n" + '
    3. \n' + ' \n' + ' +12\n' + ' -41\n' + - ' \n' + - ' \n' + - '
    4. \n' + + " \n" + + " \n" + + "\n" + '
    5. \n' + ' \n' + ' +12\n' + ' -0\n' + - ' \n' + - ' \n' + - '
    6. \n' + + " \n" + + " \n" + + "\n" + '
    7. \n' + ' \n' + ' +0\n' + ' -41\n' + - ' \n' + - ' \n' + - '
    8. \n' + - '
    \n' + - ''; + " \n" + + " \n" + + "\n" + + " \n" + + ""; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); }); }); diff --git a/src/__tests__/hogan-cache-tests.js b/src/__tests__/hogan-cache-tests.js new file mode 100644 index 0000000..f1b40fe --- /dev/null +++ b/src/__tests__/hogan-cache-tests.js @@ -0,0 +1,73 @@ +const HoganJsUtils = new (require("../hoganjs-utils.js")).HoganJsUtils(); +const diffParser = require("../diff-parser.js").DiffParser; + +describe("HoganJsUtils", function() { + describe("render", function() { + const emptyDiffHtml = + "
    \n' + + '
    \n' + + " File without changes\n" + + "
    \n" + + "
    \n' + '
    \n' + - ' File without changes\n' + - '
    \n' + - '
    \n' + '
    \n' + '
    30
    \n' + - '
    \n' + '
    \n' + ' +\n' + ' test\n' + - '
    \n' + - '
    \n' + '
    30
    \n' + '
    \n' + - '
    \n' + '
    \n' + ' -\n' + ' test\n' + - '
    \n' + - '
    \n' + '
    \n' + '
    30
    \n' + - '
    \n' + '
    \n' + ' +\n' + ' test\n' + - '
    \n' + - '
    \n' + '
    \n' + '
    30
    \n' + - '
    \n' + '
    \n' + ' +\n' + ' test\n' + - '
    \n' + - '
    \n' + '
    \n' + - '' + + "" + '
    30
    \n' + - '
    \n' + '
    \n' + ' +\n' + ' \ttest\n' + - '
    \n' + - '
    \n' + ' \n' + - ' Random Html\n' + - ' \n' + - '
    \n' + - ' \n' + - ' \n' + - ''; + " Random Html\n" + + "
    \n" + + " \n" + + " \n" + + ""; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); - it('should work for simple added file', function() { - var lineByLinePrinter = new LineByLinePrinter({}); + it("should work for simple added file", function() { + const lineByLinePrinter = new LineByLinePrinter({}); - var file = { + const file = { addedLines: 12, deletedLines: 0, - language: 'js', - oldName: 'dev/null', - newName: 'my/file/name.js', + language: "js", + oldName: "dev/null", + newName: "my/file/name.js", isNew: true }; - var diffs = 'Random Html'; + const diffs = "Random Html"; - var fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs); + const fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs); - var expected = + const expected = '
    \n' + '
    \n' + ' \n' + @@ -192,36 +191,36 @@ describe('LineByLinePrinter', function() { ' \n' + ' my/file/name.js\n' + ' ADDED\n' + - '
    \n' + + "
    \n" + '
    \n' + '
    \n' + ' \n' + ' \n' + - ' Random Html\n' + - ' \n' + - '
    \n' + - '
    \n' + - '
    \n' + - ''; + " Random Html\n" + + "
    \n" + + " \n" + + " \n" + + ""; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); - it('should work for simple deleted file', function() { - var lineByLinePrinter = new LineByLinePrinter({}); + it("should work for simple deleted file", function() { + const lineByLinePrinter = new LineByLinePrinter({}); - var file = { + const file = { addedLines: 0, deletedLines: 41, - language: 'js', - oldName: 'my/file/name.js', - newName: 'dev/null', + language: "js", + oldName: "my/file/name.js", + newName: "dev/null", isDeleted: true }; - var diffs = 'Random Html'; + const diffs = "Random Html"; - var fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs); + const fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs); - var expected = + const expected = '
    \n' + '
    \n' + ' \n' + @@ -229,36 +228,36 @@ describe('LineByLinePrinter', function() { ' \n' + ' my/file/name.js\n' + ' DELETED\n' + - '
    \n' + + "
    \n" + '
    \n' + '
    \n' + ' \n' + ' \n' + - ' Random Html\n' + - ' \n' + - '
    \n' + - '
    \n' + - '
    \n' + - ''; + " Random Html\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); - it('should work for simple renamed file', function() { - var lineByLinePrinter = new LineByLinePrinter({}); + it("should work for simple renamed file", function() { + const lineByLinePrinter = new LineByLinePrinter({}); - var file = { + const file = { addedLines: 12, deletedLines: 41, - language: 'js', - oldName: 'my/file/name1.js', - newName: 'my/file/name2.js', + language: "js", + oldName: "my/file/name1.js", + newName: "my/file/name2.js", isRename: true }; - var diffs = 'Random Html'; + const diffs = "Random Html"; - var fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs); + const fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs); - var expected = + const expected = '
    \n' + '
    \n' + ' \n' + @@ -266,93 +265,90 @@ describe('LineByLinePrinter', function() { ' \n' + ' my/file/{name1.js → name2.js}\n' + ' RENAMED\n' + - '
    \n' + + "
    \n" + '
    \n' + '
    \n' + ' \n' + ' \n' + - ' Random Html\n' + - ' \n' + - '
    \n' + - '
    \n' + - '
    \n' + - ''; + " Random Html\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); - it('should return empty when option renderNothingWhenEmpty is true and file blocks not present', function() { - var lineByLinePrinter = new LineByLinePrinter({ + it("should return empty when option renderNothingWhenEmpty is true and file blocks not present", function() { + const lineByLinePrinter = new LineByLinePrinter({ renderNothingWhenEmpty: true }); - var file = { + const file = { blocks: [] }; - var diffs = 'Random Html'; + const diffs = "Random Html"; - var fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs); + const fileHtml = lineByLinePrinter.makeFileDiffHtml(file, diffs); - var expected = ''; + const expected = ""; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); }); - describe('makeLineByLineHtmlWrapper', function() { - it('should work for simple content', function() { - var lineByLinePrinter = new LineByLinePrinter({}); - var fileHtml = lineByLinePrinter.makeLineByLineHtmlWrapper('Random Html'); + describe("makeLineByLineHtmlWrapper", function() { + it("should work for simple content", function() { + const lineByLinePrinter = new LineByLinePrinter({}); + const fileHtml = lineByLinePrinter.makeLineByLineHtmlWrapper("Random Html"); - var expected = - '
    \n' + - ' Random Html\n' + - '
    '; + const expected = '
    \n' + " Random Html\n" + "
    "; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); }); - describe('generateLineByLineJsonHtml', function() { - it('should work for list of files', function() { - var exampleJson = [ + describe("generateLineByLineJsonHtml", function() { + it("should work for list of files", function() { + const exampleJson = [ { blocks: [ { lines: [ { - content: '-test', - type: 'd2h-del', + content: "-test", + type: "d2h-del", oldNumber: 1, newNumber: null }, { - content: '+test1r', - type: 'd2h-ins', + content: "+test1r", + type: "d2h-ins", oldNumber: null, newNumber: 1 } ], - oldStartLine: '1', + oldStartLine: "1", oldStartLine2: null, - newStartLine: '1', - header: '@@ -1 +1 @@' + newStartLine: "1", + header: "@@ -1 +1 @@" } ], deletedLines: 1, addedLines: 1, - checksumBefore: '0000001', - checksumAfter: '0ddf2ba', - oldName: 'sample', + checksumBefore: "0000001", + checksumAfter: "0ddf2ba", + oldName: "sample", language: undefined, - newName: 'sample', + newName: "sample", isCombined: false } ]; - var lineByLinePrinter = new LineByLinePrinter({matching: 'lines'}); - var html = lineByLinePrinter.generateLineByLineJsonHtml(exampleJson); - var expected = + const lineByLinePrinter = new LineByLinePrinter({ matching: "lines" }); + const html = lineByLinePrinter.generateLineByLineJsonHtml(exampleJson); + const expected = '
    \n' + '
    \n' + '
    \n' + @@ -361,63 +357,65 @@ describe('LineByLinePrinter', function() { ' \n' + ' sample\n' + ' CHANGED\n' + - '
    \n' + + "
    \n" + '
    \n' + '
    \n' + ' \n' + ' \n' + - ' \n' + + " \n" + ' \n' + ' \n' + - '\n' + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + + " \n" + ' \n' + - '\n' + - ' \n' + - '
    \n' + '
    @@ -1 +1 @@
    \n' + - '
    \n' + '
    1
    \n' + '
    \n' + - '
    \n' + '
    \n' + ' -\n' + ' test\n' + - '
    \n' + - '
    \n' + '
    \n' + '
    1
    \n' + - '
    \n' + '
    \n' + ' +\n' + ' test1r\n' + - '
    \n' + - '
    \n' + - '
    \n' + - '
    \n' + - '
    \n' + - ''; + " \n" + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n" + + ""; - assert.equal(expected, html); + expect(expected).toEqual(html); }); - it('should work for empty blocks', function() { - var exampleJson = [{ - blocks: [], - deletedLines: 0, - addedLines: 0, - oldName: 'sample', - language: 'js', - newName: 'sample', - isCombined: false - }]; + it("should work for empty blocks", function() { + const exampleJson = [ + { + blocks: [], + deletedLines: 0, + addedLines: 0, + oldName: "sample", + language: "js", + newName: "sample", + isCombined: false + } + ]; - var lineByLinePrinter = new LineByLinePrinter({ renderNothingWhenEmpty: false }); - var html = lineByLinePrinter.generateLineByLineJsonHtml(exampleJson); - var expected = + const lineByLinePrinter = new LineByLinePrinter({ renderNothingWhenEmpty: false }); + const html = lineByLinePrinter.generateLineByLineJsonHtml(exampleJson); + const expected = '
    \n' + '
    \n' + '
    \n' + @@ -426,179 +424,183 @@ describe('LineByLinePrinter', function() { ' \n' + ' sample\n' + ' CHANGED\n' + - '
    \n' + + "
    \n" + '
    \n' + '
    \n' + ' \n' + ' \n' + - ' \n' + + " \n" + ' \n' + - '\n' + - ' \n' + - '
    \n' + '
    \n' + - ' File without changes\n' + - '
    \n' + - '
    \n' + - '
    \n' + - '
    \n' + - '
    \n' + - ''; + " File without changes\n" + + " \n" + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n" + + ""; - assert.equal(expected, html); + expect(expected).toEqual(html); }); }); - describe('_processLines', function() { - it('should work for simple block header', function() { - var lineByLinePrinter = new LineByLinePrinter({}); - var oldLines = [{ - content: '-test', - type: 'd2h-del', - oldNumber: 1, - newNumber: null - }]; - var newLines = [{ - content: '+test1r', - type: 'd2h-ins', - oldNumber: null, - newNumber: 1 - }]; + describe("_processLines", function() { + it("should work for simple block header", function() { + const lineByLinePrinter = new LineByLinePrinter({}); + const oldLines = [ + { + content: "-test", + type: "d2h-del", + oldNumber: 1, + newNumber: null + } + ]; + const newLines = [ + { + content: "+test1r", + type: "d2h-ins", + oldNumber: null, + newNumber: 1 + } + ]; - var html = lineByLinePrinter._processLines(false, oldLines, newLines); + const html = lineByLinePrinter._processLines(false, oldLines, newLines); - var expected = - '\n' + + const expected = + "\n" + ' \n' + '
    1
    \n' + '
    \n' + - ' \n' + + " \n" + ' \n' + '
    \n' + ' -\n' + ' test\n' + - '
    \n' + - ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + '
    \n' + '
    1
    \n' + - ' \n' + + " \n" + ' \n' + '
    \n' + ' +\n' + ' test1r\n' + - '
    \n' + - ' \n' + - ''; + " \n" + + " \n" + + ""; - assert.equal(expected, html); + expect(expected).toEqual(html); }); }); - describe('_generateFileHtml', function() { - it('should work for simple file', function() { - var lineByLinePrinter = new LineByLinePrinter({}); - var file = { + describe("_generateFileHtml", function() { + it("should work for simple file", function() { + const lineByLinePrinter = new LineByLinePrinter({}); + const file = { blocks: [ { lines: [ { - content: ' one context line', - type: 'd2h-cntx', + content: " one context line", + type: "d2h-cntx", oldNumber: 1, newNumber: 1 }, { - content: '-test', - type: 'd2h-del', + content: "-test", + type: "d2h-del", oldNumber: 2, newNumber: null }, { - content: '+test1r', - type: 'd2h-ins', + content: "+test1r", + type: "d2h-ins", oldNumber: null, newNumber: 2 }, { - content: '+test2r', - type: 'd2h-ins', + content: "+test2r", + type: "d2h-ins", oldNumber: null, newNumber: 3 } ], - oldStartLine: '1', + oldStartLine: "1", oldStartLine2: null, - newStartLine: '1', - header: '@@ -1 +1 @@' + newStartLine: "1", + header: "@@ -1 +1 @@" } ], deletedLines: 1, addedLines: 1, - checksumBefore: '0000001', - checksumAfter: '0ddf2ba', - oldName: 'sample', + checksumBefore: "0000001", + checksumAfter: "0ddf2ba", + oldName: "sample", language: undefined, - newName: 'sample', + newName: "sample", isCombined: false }; - var html = lineByLinePrinter._generateFileHtml(file); + const html = lineByLinePrinter._generateFileHtml(file); - var expected = - '\n' + + const expected = + "\n" + ' \n' + ' \n' + '
    @@ -1 +1 @@
    \n' + - ' \n' + - '\n' + + " \n" + + "\n" + ' \n' + '
    1
    \n' + '
    1
    \n' + - ' \n' + + " \n" + ' \n' + '
    \n' + '  \n' + ' one context line\n' + - '
    \n' + - ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + '
    2
    \n' + '
    \n' + - ' \n' + + " \n" + ' \n' + '
    \n' + ' -\n' + ' test\n' + - '
    \n' + - ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + '
    \n' + '
    2
    \n' + - ' \n' + + " \n" + ' \n' + '
    \n' + ' +\n' + ' test1r\n' + - '
    \n' + - ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + '
    \n' + '
    3
    \n' + - ' \n' + + " \n" + ' \n' + '
    \n' + ' +\n' + ' test2r\n' + - '
    \n' + - ' \n' + - ''; + " \n" + + " \n" + + ""; - assert.equal(expected, html); + expect(expected).toEqual(html); }); }); }); diff --git a/src/__tests__/printer-utils-tests.js b/src/__tests__/printer-utils-tests.js new file mode 100644 index 0000000..5e92a6b --- /dev/null +++ b/src/__tests__/printer-utils-tests.js @@ -0,0 +1,126 @@ +const PrinterUtils = require("../printer-utils.js").PrinterUtils; + +describe("Utils", function() { + describe("getHtmlId", function() { + it("should generate file unique id", function() { + const result = PrinterUtils.getHtmlId({ + oldName: "sample.js", + newName: "sample.js" + }); + expect("d2h-960013").toEqual(result); + }); + it("should generate file unique id for empty hashes", function() { + const result = PrinterUtils.getHtmlId({ + oldName: "sample.js", + newName: "sample.js" + }); + expect("d2h-960013").toEqual(result); + }); + }); + + describe("getDiffName", function() { + it("should generate the file name for a changed file", function() { + const result = PrinterUtils.getDiffName({ + oldName: "sample.js", + newName: "sample.js" + }); + expect("sample.js").toEqual(result); + }); + it("should generate the file name for a changed file and full rename", function() { + const result = PrinterUtils.getDiffName({ + oldName: "sample1.js", + newName: "sample2.js" + }); + expect("sample1.js → sample2.js").toEqual(result); + }); + it("should generate the file name for a changed file and prefix rename", function() { + const result = PrinterUtils.getDiffName({ + oldName: "src/path/sample.js", + newName: "source/path/sample.js" + }); + expect("{src → source}/path/sample.js").toEqual(result); + }); + it("should generate the file name for a changed file and suffix rename", function() { + const result = PrinterUtils.getDiffName({ + oldName: "src/path/sample1.js", + newName: "src/path/sample2.js" + }); + expect("src/path/{sample1.js → sample2.js}").toEqual(result); + }); + it("should generate the file name for a changed file and middle rename", function() { + const result = PrinterUtils.getDiffName({ + oldName: "src/really/big/path/sample.js", + newName: "src/small/path/sample.js" + }); + expect("src/{really/big → small}/path/sample.js").toEqual(result); + }); + it("should generate the file name for a deleted file", function() { + const result = PrinterUtils.getDiffName({ + oldName: "src/my/file.js", + newName: "/dev/null" + }); + expect("src/my/file.js").toEqual(result); + }); + it("should generate the file name for a new file", function() { + const result = PrinterUtils.getDiffName({ + oldName: "/dev/null", + newName: "src/my/file.js" + }); + expect("src/my/file.js").toEqual(result); + }); + it("should generate handle undefined filename", function() { + const result = PrinterUtils.getDiffName({}); + expect("unknown/file/path").toEqual(result); + }); + }); + + describe("diffHighlight", function() { + it("should highlight two lines", function() { + const result = PrinterUtils.diffHighlight("-var myVar = 2;", "+var myVariable = 3;", { matching: "words" }); + + expect({ + first: { + prefix: "-", + line: "var myVar = 2;" + }, + second: { + prefix: "+", + line: "var myVariable = 3;" + } + }).toEqual(result); + }); + it("should highlight two lines char by char", function() { + const result = PrinterUtils.diffHighlight("-var myVar = 2;", "+var myVariable = 3;", { diffStyle: "char" }); + + expect({ + first: { + prefix: "-", + line: "var myVar = 2;" + }, + second: { + prefix: "+", + line: "var myVariable = 3;" + } + }).toEqual(result); + }); + it("should highlight combined diff lines", function() { + const result = PrinterUtils.diffHighlight(" -var myVar = 2;", " +var myVariable = 3;", { + diffStyle: "word", + isCombined: true, + matching: "words", + matchWordsThreshold: 1.0 + }); + + expect({ + first: { + prefix: " -", + line: 'var myVar = 2;' + }, + second: { + prefix: " +", + line: 'var myVariable = 3;' + } + }).toEqual(result); + }); + }); +}); diff --git a/test/side-by-side-printer-tests.js b/src/__tests__/side-by-side-printer-tests.js similarity index 52% rename from test/side-by-side-printer-tests.js rename to src/__tests__/side-by-side-printer-tests.js index ee10c39..fb2b007 100644 --- a/test/side-by-side-printer-tests.js +++ b/src/__tests__/side-by-side-printer-tests.js @@ -1,240 +1,239 @@ -var assert = require('assert'); +const SideBySidePrinter = require("../side-by-side-printer.js").SideBySidePrinter; -var SideBySidePrinter = require('../src/side-by-side-printer.js').SideBySidePrinter; - -describe('SideBySidePrinter', function() { - describe('generateEmptyDiff', function() { - it('should return an empty diff', function() { - var sideBySidePrinter = new SideBySidePrinter({}); - var fileHtml = sideBySidePrinter.generateEmptyDiff(); - var expectedRight = ''; - var expectedLeft = '\n' + +describe("SideBySidePrinter", function() { + describe("generateEmptyDiff", function() { + it("should return an empty diff", function() { + const sideBySidePrinter = new SideBySidePrinter({}); + const fileHtml = sideBySidePrinter.generateEmptyDiff(); + const expectedRight = ""; + const expectedLeft = + "\n" + ' \n' + '
    \n' + - ' File without changes\n' + - '
    \n' + - ' \n' + - ''; + " File without changes\n" + + " \n" + + " \n" + + ""; - assert.equal(expectedRight, fileHtml.right); - assert.equal(expectedLeft, fileHtml.left); + expect(expectedRight).toEqual(fileHtml.right); + expect(expectedLeft).toEqual(fileHtml.left); }); }); - describe('generateSideBySideFileHtml', function() { - it('should generate lines with the right prefixes', function() { - var sideBySidePrinter = new SideBySidePrinter({}); + describe("generateSideBySideFileHtml", function() { + it("should generate lines with the right prefixes", function() { + const sideBySidePrinter = new SideBySidePrinter({}); - var file = { - 'blocks': [ + const file = { + blocks: [ { - 'lines': [ + lines: [ { - 'content': ' context', - 'type': 'd2h-cntx', - 'oldNumber': 19, - 'newNumber': 19 + content: " context", + type: "d2h-cntx", + oldNumber: 19, + newNumber: 19 }, { - 'content': '-removed', - 'type': 'd2h-del', - 'oldNumber': 20, - 'newNumber': null + content: "-removed", + type: "d2h-del", + oldNumber: 20, + newNumber: null }, { - 'content': '+added', - 'type': 'd2h-ins', - 'oldNumber': null, - 'newNumber': 20 + content: "+added", + type: "d2h-ins", + oldNumber: null, + newNumber: 20 }, { - 'content': '+another added', - 'type': 'd2h-ins', - 'oldNumber': null, - 'newNumber': 21 + content: "+another added", + type: "d2h-ins", + oldNumber: null, + newNumber: 21 } ], - 'oldStartLine': '19', - 'newStartLine': '19', - 'header': '@@ -19,7 +19,7 @@' + oldStartLine: "19", + newStartLine: "19", + header: "@@ -19,7 +19,7 @@" } ], - 'deletedLines': 1, - 'addedLines': 1, - 'checksumBefore': 'fc56817', - 'checksumAfter': 'e8e7e49', - 'mode': '100644', - 'oldName': 'coverage.init', - 'language': 'init', - 'newName': 'coverage.init', - 'isCombined': false + deletedLines: 1, + addedLines: 1, + checksumBefore: "fc56817", + checksumAfter: "e8e7e49", + mode: "100644", + oldName: "coverage.init", + language: "init", + newName: "coverage.init", + isCombined: false }; - var fileHtml = sideBySidePrinter.generateSideBySideFileHtml(file); + const fileHtml = sideBySidePrinter.generateSideBySideFileHtml(file); - var expectedLeft = - '\n' + + const expectedLeft = + "\n" + ' \n' + ' \n' + '
    @@ -19,7 +19,7 @@
    \n' + - ' \n' + - '\n' + + " \n" + + "\n" + ' \n' + - ' 19\n' + - ' \n' + + " 19\n" + + " \n" + ' \n' + '
    \n' + '  \n' + ' context\n' + - '
    \n' + - ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + - ' 20\n' + - ' \n' + + " 20\n" + + " \n" + ' \n' + '
    \n' + ' -\n' + ' removed\n' + - '
    \n' + - ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + - ' ' + - '\n' + - ' \n' + + " " + + "\n" + + " \n" + ' \n' + '
    \n' + '  \n' + '  \n' + - '
    \n' + - ' \n' + - ''; + " \n" + + " \n" + + ""; - var expectedRight = - '\n' + + const expectedRight = + "\n" + ' \n' + ' \n' + '
    \n' + - ' \n' + - '\n' + + " \n" + + "\n" + ' \n' + - ' 19\n' + - ' \n' + + " 19\n" + + " \n" + ' \n' + '
    \n' + '  \n' + ' context\n' + - '
    \n' + - ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + - ' 20\n' + - ' \n' + + " 20\n" + + " \n" + ' \n' + '
    \n' + ' +\n' + ' added\n' + - '
    \n' + - ' \n' + - '\n' + + " \n" + + " \n" + + "\n" + ' \n' + - ' 21\n' + - ' \n' + + " 21\n" + + " \n" + ' \n' + '
    \n' + ' +\n' + ' another added\n' + - '
    \n' + - ' \n' + - ''; + " \n" + + " \n" + + ""; - assert.equal(expectedLeft, fileHtml.left); - assert.equal(expectedRight, fileHtml.right); + expect(expectedLeft).toEqual(fileHtml.left); + expect(expectedRight).toEqual(fileHtml.right); }); }); - describe('generateSingleLineHtml', function() { - it('should work for insertions', function() { - var diffParser = require('../src/diff-parser.js').DiffParser; - var sideBySidePrinter = new SideBySidePrinter({}); - var fileHtml = sideBySidePrinter.generateSingleLineHtml(false, - diffParser.LINE_TYPE.INSERTS, 30, 'test', '+'); - var expected = '\n' + + describe("generateSingleLineHtml", function() { + it("should work for insertions", function() { + const diffParser = require("../diff-parser.js").DiffParser; + const sideBySidePrinter = new SideBySidePrinter({}); + const fileHtml = sideBySidePrinter.generateSingleLineHtml(false, diffParser.LINE_TYPE.INSERTS, 30, "test", "+"); + const expected = + "\n" + ' \n' + - ' 30\n' + - ' \n' + + " 30\n" + + " \n" + ' \n' + '
    \n' + ' +\n' + ' test\n' + - '
    \n' + - ' \n' + - ''; + " \n" + + " \n" + + ""; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); - it('should work for deletions', function() { - var diffParser = require('../src/diff-parser.js').DiffParser; - var sideBySidePrinter = new SideBySidePrinter({}); - var fileHtml = sideBySidePrinter.generateSingleLineHtml(false, - diffParser.LINE_TYPE.DELETES, 30, 'test', '-'); - var expected = '\n' + + it("should work for deletions", function() { + const diffParser = require("../diff-parser.js").DiffParser; + const sideBySidePrinter = new SideBySidePrinter({}); + const fileHtml = sideBySidePrinter.generateSingleLineHtml(false, diffParser.LINE_TYPE.DELETES, 30, "test", "-"); + const expected = + "\n" + ' \n' + - ' 30\n' + - ' \n' + + " 30\n" + + " \n" + ' \n' + '
    \n' + ' -\n' + ' test\n' + - '
    \n' + - ' \n' + - ''; + " \n" + + " \n" + + ""; - assert.equal(expected, fileHtml); + expect(expected).toEqual(fileHtml); }); }); - describe('generateSideBySideJsonHtml', function() { - it('should work for list of files', function() { - var exampleJson = [ + describe("generateSideBySideJsonHtml", function() { + it("should work for list of files", function() { + const exampleJson = [ { blocks: [ { lines: [ { - content: '-test', - type: 'd2h-del', + content: "-test", + type: "d2h-del", oldNumber: 1, newNumber: null }, { - content: '+test1r', - type: 'd2h-ins', + content: "+test1r", + type: "d2h-ins", oldNumber: null, newNumber: 1 } ], - oldStartLine: '1', + oldStartLine: "1", oldStartLine2: null, - newStartLine: '1', - header: '@@ -1 +1 @@' + newStartLine: "1", + header: "@@ -1 +1 @@" } ], deletedLines: 1, addedLines: 1, - checksumBefore: '0000001', - checksumAfter: '0ddf2ba', - oldName: 'sample', + checksumBefore: "0000001", + checksumAfter: "0ddf2ba", + oldName: "sample", language: undefined, - newName: 'sample', + newName: "sample", isCombined: false } ]; - var sideBySidePrinter = new SideBySidePrinter({matching: 'lines'}); - var html = sideBySidePrinter.generateSideBySideJsonHtml(exampleJson); - var expected = + const sideBySidePrinter = new SideBySidePrinter({ matching: "lines" }); + const html = sideBySidePrinter.generateSideBySideJsonHtml(exampleJson); + const expected = '
    \n' + '
    \n' + '
    \n' + @@ -243,74 +242,76 @@ describe('SideBySidePrinter', function() { ' \n' + ' sample\n' + ' CHANGED\n' + - '
    \n' + + "
    \n" + '
    \n' + '
    \n' + '
    \n' + ' \n' + ' \n' + - ' \n' + + " \n" + ' \n' + ' \n' + - '\n' + + " \n" + + "\n" + ' \n' + + " 1\n" + + " \n" + ' \n' + - '\n' + - ' \n' + - '
    \n' + '
    @@ -1 +1 @@
    \n' + - '
    \n' + - ' 1\n' + - ' \n' + '
    \n' + ' -\n' + ' test\n' + - '
    \n' + - '
    \n' + - '
    \n' + - '
    \n' + + "
    \n" + + " \n" + + "\n" + + " \n" + + " \n" + + "
    \n" + + " \n" + '
    \n' + '
    \n' + ' \n' + ' \n' + - ' \n' + + " \n" + ' \n' + ' \n' + - '\n' + + " \n" + + "\n" + ' \n' + + " 1\n" + + " \n" + ' \n' + - '\n' + - ' \n' + - '
    \n' + '
    \n' + - '
    \n' + - ' 1\n' + - ' \n' + '
    \n' + ' +\n' + ' test1r\n' + - '
    \n' + - '
    \n' + - '
    \n' + - '
    \n' + - ' \n' + - '\n' + - ''; + " \n" + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n" + + ""; - assert.equal(expected, html); + expect(expected).toEqual(html); }); - it('should work for files without blocks', function() { - var exampleJson = [{ - blocks: [], - oldName: 'sample', - language: 'js', - newName: 'sample', - isCombined: false - }]; + it("should work for files without blocks", function() { + const exampleJson = [ + { + blocks: [], + oldName: "sample", + language: "js", + newName: "sample", + isCombined: false + } + ]; - var sideBySidePrinter = new SideBySidePrinter(); - var html = sideBySidePrinter.generateSideBySideJsonHtml(exampleJson); - var expected = + const sideBySidePrinter = new SideBySidePrinter(); + const html = sideBySidePrinter.generateSideBySideJsonHtml(exampleJson); + const expected = '
    \n' + '
    \n' + '
    \n' + @@ -319,86 +320,90 @@ describe('SideBySidePrinter', function() { ' \n' + ' sample\n' + ' CHANGED\n' + - '
    \n' + + "
    \n" + '
    \n' + '
    \n' + '
    \n' + ' \n' + ' \n' + - ' \n' + + " \n" + ' \n' + - '\n' + - ' \n' + - '
    \n' + '
    \n' + - ' File without changes\n' + - '
    \n' + - '
    \n' + - '
    \n' + - '
    \n' + + " File without changes\n" + + "
    \n" + + " \n" + + "\n" + + " \n" + + " \n" + + "
    \n" + + " \n" + '
    \n' + '
    \n' + ' \n' + ' \n' + - ' \n' + - ' \n' + - '
    \n' + - '
    \n' + - '
    \n' + - ' \n' + - '\n' + - ''; + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n" + + ""; - assert.equal(expected, html); + expect(expected).toEqual(html); }); }); - describe('processLines', function() { - it('should process file lines', function() { - var oldLines = [{ - content: '-test', - type: 'd2h-del', - oldNumber: 1, - newNumber: null - }]; + describe("processLines", function() { + it("should process file lines", function() { + const oldLines = [ + { + content: "-test", + type: "d2h-del", + oldNumber: 1, + newNumber: null + } + ]; - var newLines = [{ - content: '+test1r', - type: 'd2h-ins', - oldNumber: null, - newNumber: 1 - }]; + const newLines = [ + { + content: "+test1r", + type: "d2h-ins", + oldNumber: null, + newNumber: 1 + } + ]; - var sideBySidePrinter = new SideBySidePrinter({matching: 'lines'}); - var html = sideBySidePrinter.processLines(false, oldLines, newLines); - var expectedLeft = - '\n' + + const sideBySidePrinter = new SideBySidePrinter({ matching: "lines" }); + const html = sideBySidePrinter.processLines(false, oldLines, newLines); + const expectedLeft = + "\n" + ' \n' + - ' 1\n' + - ' \n' + + " 1\n" + + " \n" + ' \n' + '
    \n' + ' -\n' + ' test\n' + - '
    \n' + - ' \n' + - ''; + " \n" + + " \n" + + ""; - var expectedRight = - '\n' + + const expectedRight = + "\n" + ' \n' + - ' 1\n' + - ' \n' + + " 1\n" + + " \n" + ' \n' + '
    \n' + ' +\n' + ' test1r\n' + - '
    \n' + - ' \n' + - ''; + " \n" + + " \n" + + ""; - assert.equal(expectedLeft, html.left); - assert.equal(expectedRight, html.right); + expect(expectedLeft).toEqual(html.left); + expect(expectedRight).toEqual(html.right); }); }); }); diff --git a/src/__tests__/utils-tests.js b/src/__tests__/utils-tests.js new file mode 100644 index 0000000..295b098 --- /dev/null +++ b/src/__tests__/utils-tests.js @@ -0,0 +1,23 @@ +const Utils = require("../utils.js").Utils; + +describe("Utils", function() { + describe("escape", function() { + it("should escape & with &", function() { + const result = Utils.escape("&"); + expect("&").toEqual(result); + }); + it("should escape < with <", function() { + const result = Utils.escape("<"); + expect("<").toEqual(result); + }); + it("should escape > with >", function() { + const result = Utils.escape(">"); + expect(">").toEqual(result); + }); + it("should escape a string with multiple problematic characters", function() { + const result = Utils.escape('\tlink text'); + const expected = "<a href="#">\tlink text</a>"; + expect(expected).toEqual(result); + }); + }); +}); diff --git a/src/diff-parser.js b/src/diff-parser.js index 57892cb..faaa4ef 100644 --- a/src/diff-parser.js +++ b/src/diff-parser.js @@ -6,39 +6,38 @@ */ (function() { - var utils = require('./utils.js').Utils; + const utils = require("./utils.js").Utils; - var LINE_TYPE = { - INSERTS: 'd2h-ins', - DELETES: 'd2h-del', - INSERT_CHANGES: 'd2h-ins d2h-change', - DELETE_CHANGES: 'd2h-del d2h-change', - CONTEXT: 'd2h-cntx', - INFO: 'd2h-info' + const LINE_TYPE = { + INSERTS: "d2h-ins", + DELETES: "d2h-del", + INSERT_CHANGES: "d2h-ins d2h-change", + DELETE_CHANGES: "d2h-del d2h-change", + CONTEXT: "d2h-cntx", + INFO: "d2h-info" }; - function DiffParser() { - } + function DiffParser() {} DiffParser.prototype.LINE_TYPE = LINE_TYPE; DiffParser.prototype.generateDiffJson = function(diffInput, configuration) { - var config = configuration || {}; + const config = configuration || {}; - var files = []; - var currentFile = null; - var currentBlock = null; - var oldLine = null; - var oldLine2 = null; // Used for combined diff - var newLine = null; + const files = []; + let currentFile = null; + let currentBlock = null; + let oldLine = null; + let oldLine2 = null; // Used for combined diff + let newLine = null; - var possibleOldName; - var possibleNewName; + let possibleOldName; + let possibleNewName; /* Diff Header */ - var oldFileNameHeader = '--- '; - var newFileNameHeader = '+++ '; - var hunkHeaderPrefix = '@@'; + const oldFileNameHeader = "--- "; + const newFileNameHeader = "+++ "; + const hunkHeaderPrefix = "@@"; /* Add previous block(if exists) before start a new file */ function saveBlock() { @@ -86,7 +85,7 @@ function startBlock(line) { saveBlock(); - var values; + let values; /** * From Range: @@ -113,7 +112,7 @@ newLine = values[3]; } else { if (utils.startsWith(line, hunkHeaderPrefix)) { - console.error('Failed to parse lines, starting in 0!'); + console.error("Failed to parse lines, starting in 0!"); } oldLine = 0; @@ -131,11 +130,11 @@ } function createLine(line) { - var currentLine = {}; + const currentLine = {}; currentLine.content = line; - var newLinePrefixes = !currentFile.isCombined ? ['+'] : ['+', ' +']; - var delLinePrefixes = !currentFile.isCombined ? ['-'] : ['-', ' -']; + const newLinePrefixes = !currentFile.isCombined ? ["+"] : ["+", " +"]; + const delLinePrefixes = !currentFile.isCombined ? ["-"] : ["-", " -"]; /* Fill the line data */ if (utils.startsWith(line, newLinePrefixes)) { @@ -169,10 +168,10 @@ * Hunk header is a group of three lines started by ( `--- ` , `+++ ` , `@@` ) */ function existHunkHeader(line, lineIdx) { - var idx = lineIdx; + let idx = lineIdx; while (idx < diffLines.length - 3) { - if (utils.startsWith(line, 'diff')) { + if (utils.startsWith(line, "diff")) { return false; } @@ -190,56 +189,56 @@ return false; } - var diffLines = - diffInput.replace(/\\ No newline at end of file/g, '') - .replace(/\r\n?/g, '\n') - .split('\n'); + var diffLines = diffInput + .replace(/\\ No newline at end of file/g, "") + .replace(/\r\n?/g, "\n") + .split("\n"); /* Diff */ - var oldMode = /^old mode (\d{6})/; - var newMode = /^new mode (\d{6})/; - var deletedFileMode = /^deleted file mode (\d{6})/; - var newFileMode = /^new file mode (\d{6})/; + const oldMode = /^old mode (\d{6})/; + const newMode = /^new mode (\d{6})/; + const deletedFileMode = /^deleted file mode (\d{6})/; + const newFileMode = /^new file mode (\d{6})/; - var copyFrom = /^copy from "?(.+)"?/; - var copyTo = /^copy to "?(.+)"?/; + const copyFrom = /^copy from "?(.+)"?/; + const copyTo = /^copy to "?(.+)"?/; - var renameFrom = /^rename from "?(.+)"?/; - var renameTo = /^rename to "?(.+)"?/; + const renameFrom = /^rename from "?(.+)"?/; + const renameTo = /^rename to "?(.+)"?/; - var similarityIndex = /^similarity index (\d+)%/; - var dissimilarityIndex = /^dissimilarity index (\d+)%/; - var index = /^index ([0-9a-z]+)\.\.([0-9a-z]+)\s*(\d{6})?/; + const similarityIndex = /^similarity index (\d+)%/; + const dissimilarityIndex = /^dissimilarity index (\d+)%/; + const index = /^index ([0-9a-z]+)\.\.([0-9a-z]+)\s*(\d{6})?/; - var binaryFiles = /^Binary files (.*) and (.*) differ/; - var binaryDiff = /^GIT binary patch/; + const binaryFiles = /^Binary files (.*) and (.*) differ/; + const binaryDiff = /^GIT binary patch/; /* Combined Diff */ - var combinedIndex = /^index ([0-9a-z]+),([0-9a-z]+)\.\.([0-9a-z]+)/; - var combinedMode = /^mode (\d{6}),(\d{6})\.\.(\d{6})/; - var combinedNewFile = /^new file mode (\d{6})/; - var combinedDeletedFile = /^deleted file mode (\d{6}),(\d{6})/; + const combinedIndex = /^index ([0-9a-z]+),([0-9a-z]+)\.\.([0-9a-z]+)/; + const combinedMode = /^mode (\d{6}),(\d{6})\.\.(\d{6})/; + const combinedNewFile = /^new file mode (\d{6})/; + const combinedDeletedFile = /^deleted file mode (\d{6}),(\d{6})/; diffLines.forEach(function(line, lineIndex) { // Unmerged paths, and possibly other non-diffable files // https://github.com/scottgonzalez/pretty-diff/issues/11 // Also, remove some useless lines - if (!line || utils.startsWith(line, '*')) { + if (!line || utils.startsWith(line, "*")) { return; } // Used to store regex capture groups - var values; + let values; - var prevLine = diffLines[lineIndex - 1]; - var nxtLine = diffLines[lineIndex + 1]; - var afterNxtLine = diffLines[lineIndex + 2]; + const prevLine = diffLines[lineIndex - 1]; + const nxtLine = diffLines[lineIndex + 1]; + const afterNxtLine = diffLines[lineIndex + 2]; - if (utils.startsWith(line, 'diff')) { + if (utils.startsWith(line, "diff")) { startFile(); // diff --git a/blocked_delta_results.png b/blocked_delta_results.png - var gitDiffStart = /^diff --git "?(.+)"? "?(.+)"?/; + const gitDiffStart = /^diff --git "?(.+)"? "?(.+)"?/; if ((values = gitDiffStart.exec(line))) { possibleOldName = _getFilename(null, values[1], config.dstPrefix); possibleNewName = _getFilename(null, values[2], config.srcPrefix); @@ -249,15 +248,14 @@ return; } - if (!currentFile || // If we do not have a file yet, we should crete one - ( - !currentFile.isGitDiff && currentFile && // If we already have some file in progress and - ( - utils.startsWith(line, oldFileNameHeader) && // If we get to an old file path header line + if ( + !currentFile || // If we do not have a file yet, we should crete one + (!currentFile.isGitDiff && + currentFile && // If we already have some file in progress and + (utils.startsWith(line, oldFileNameHeader) && // If we get to an old file path header line // And is followed by the new file path header line and the hunk header line - utils.startsWith(nxtLine, newFileNameHeader) && utils.startsWith(afterNxtLine, hunkHeaderPrefix) - ) - ) + utils.startsWith(nxtLine, newFileNameHeader) && + utils.startsWith(afterNxtLine, hunkHeaderPrefix))) ) { startFile(); } @@ -268,18 +266,19 @@ * - https://github.com/rtfpessoa/diff2html/issues/87 */ if ( - (utils.startsWith(line, oldFileNameHeader) && - utils.startsWith(nxtLine, newFileNameHeader)) || - - (utils.startsWith(line, newFileNameHeader) && - utils.startsWith(prevLine, oldFileNameHeader)) + (utils.startsWith(line, oldFileNameHeader) && utils.startsWith(nxtLine, newFileNameHeader)) || + (utils.startsWith(line, newFileNameHeader) && utils.startsWith(prevLine, oldFileNameHeader)) ) { /* * --- Date Timestamp[FractionalSeconds] TimeZone * --- 2002-02-21 23:30:39.942229878 -0800 */ - if (currentFile && !currentFile.oldName && - utils.startsWith(line, '--- ') && (values = getSrcFilename(line, config))) { + if ( + currentFile && + !currentFile.oldName && + utils.startsWith(line, "--- ") && + (values = getSrcFilename(line, config)) + ) { currentFile.oldName = values; currentFile.language = getExtension(currentFile.oldName, currentFile.language); return; @@ -289,8 +288,12 @@ * +++ Date Timestamp[FractionalSeconds] TimeZone * +++ 2002-02-21 23:30:39.942229878 -0800 */ - if (currentFile && !currentFile.newName && - utils.startsWith(line, '+++ ') && (values = getDstFilename(line, config))) { + if ( + currentFile && + !currentFile.newName && + utils.startsWith(line, "+++ ") && + (values = getDstFilename(line, config)) + ) { currentFile.newName = values; currentFile.language = getExtension(currentFile.newName, currentFile.language); return; @@ -311,12 +314,12 @@ * 2. Old line starts with: - * 3. Context line starts with: */ - if (currentBlock && (utils.startsWith(line, '+') || utils.startsWith(line, '-') || utils.startsWith(line, ' '))) { + if (currentBlock && (utils.startsWith(line, "+") || utils.startsWith(line, "-") || utils.startsWith(line, " "))) { createLine(line); return; } - var doesNotExistHunkHeader = !existHunkHeader(line, lineIndex); + const doesNotExistHunkHeader = !existHunkHeader(line, lineIndex); /* * Git diffs provide more information regarding files modes, renames, copies, @@ -356,7 +359,7 @@ currentFile.isBinary = true; currentFile.oldName = _getFilename(null, values[1], config.srcPrefix); currentFile.newName = _getFilename(null, values[2], config.dstPrefix); - startBlock('Binary file'); + startBlock("Binary file"); } else if ((values = binaryDiff.exec(line))) { currentFile.isBinary = true; startBlock(line); @@ -390,7 +393,7 @@ }; function getExtension(filename, language) { - var nameSplit = filename.split('.'); + const nameSplit = filename.split("."); if (nameSplit.length > 1) { return nameSplit[nameSplit.length - 1]; } @@ -399,31 +402,31 @@ } function getSrcFilename(line, cfg) { - return _getFilename('---', line, cfg.srcPrefix); + return _getFilename("---", line, cfg.srcPrefix); } function getDstFilename(line, cfg) { - return _getFilename('\\+\\+\\+', line, cfg.dstPrefix); + return _getFilename("\\+\\+\\+", line, cfg.dstPrefix); } function _getFilename(linePrefix, line, extraPrefix) { - var prefixes = ['a/', 'b/', 'i/', 'w/', 'c/', 'o/']; + const prefixes = ["a/", "b/", "i/", "w/", "c/", "o/"]; if (extraPrefix) { prefixes.push(extraPrefix); } - var FilenameRegExp; + let FilenameRegExp; if (linePrefix) { - FilenameRegExp = new RegExp('^' + linePrefix + ' "?(.+?)"?$'); + FilenameRegExp = new RegExp("^" + linePrefix + ' "?(.+?)"?$'); } else { FilenameRegExp = new RegExp('^"?(.+?)"?$'); } - var filename; - var values = FilenameRegExp.exec(line); + let filename; + const values = FilenameRegExp.exec(line); if (values && values[1]) { filename = values[1]; - var matchingPrefixes = prefixes.filter(function(p) { + const matchingPrefixes = prefixes.filter(function(p) { return filename.indexOf(p) === 0; }); @@ -435,7 +438,7 @@ // Cleanup timestamps generated by the unified diff (diff command) as specified in // https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html // Ie: 2016-10-25 11:37:14.000000000 +0200 - filename = filename.replace(/\s+\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)? [-+]\d{4}.*$/, ''); + filename = filename.replace(/\s+\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)? [-+]\d{4}.*$/, ""); } return filename; diff --git a/src/diff2html.d.ts b/src/diff2html.d.ts index cea93f6..de77dbf 100644 --- a/src/diff2html.d.ts +++ b/src/diff2html.d.ts @@ -4,13 +4,12 @@ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped declare namespace Diff2Html { - export interface Options { - inputFormat?: 'diff' | 'json'; - outputFormat?: 'line-by-line' | 'side-by-side'; + inputFormat?: "diff" | "json"; + outputFormat?: "line-by-line" | "side-by-side"; showFiles?: boolean; - diffStyle?: 'word' | 'char'; - matching?: 'lines' | 'words' | 'none'; + diffStyle?: "word" | "char"; + matching?: "lines" | "words" | "none"; matchWordsThreshold?: number; matchingMaxComparisons?: number; maxLineSizeInBlockForComparison?: number; @@ -66,6 +65,6 @@ declare namespace Diff2Html { } declare module "diff2html" { - var d2h: { "Diff2Html": Diff2Html.Diff2Html }; + var d2h: { Diff2Html: Diff2Html.Diff2Html }; export = d2h; } diff --git a/src/diff2html.js b/src/diff2html.js index 4d4155d..2b89372 100644 --- a/src/diff2html.js +++ b/src/diff2html.js @@ -6,19 +6,18 @@ */ (function() { - var diffParser = require('./diff-parser.js').DiffParser; - var htmlPrinter = require('./html-printer.js').HtmlPrinter; - var utils = require('./utils.js').Utils; + const diffParser = require("./diff-parser.js").DiffParser; + const htmlPrinter = require("./html-printer.js").HtmlPrinter; + const utils = require("./utils.js").Utils; - function Diff2Html() { - } + function Diff2Html() {} - var defaultConfig = { - inputFormat: 'diff', - outputFormat: 'line-by-line', + const defaultConfig = { + inputFormat: "diff", + outputFormat: "line-by-line", showFiles: false, - diffStyle: 'word', - matching: 'none', + diffStyle: "word", + matching: "none", matchWordsThreshold: 0.25, matchingMaxComparisons: 2500, maxLineSizeInBlockForComparison: 200, @@ -32,7 +31,7 @@ * Generates json object from string diff input */ Diff2Html.prototype.getJsonFromDiff = function(diffInput, config) { - var cfg = utils.safeConfig(config, defaultConfig); + const cfg = utils.safeConfig(config, defaultConfig); return diffParser.generateDiffJson(diffInput, cfg); }; @@ -40,20 +39,20 @@ * Generates the html diff. The config parameter configures the output/input formats and other options */ Diff2Html.prototype.getPrettyHtml = function(diffInput, config) { - var cfg = utils.safeConfig(config, defaultConfig); + const cfg = utils.safeConfig(config, defaultConfig); - var diffJson = diffInput; - if (!cfg.inputFormat || cfg.inputFormat === 'diff') { + let diffJson = diffInput; + if (!cfg.inputFormat || cfg.inputFormat === "diff") { diffJson = diffParser.generateDiffJson(diffInput, cfg); } - var fileList = ''; + let fileList = ""; if (cfg.showFiles === true) { fileList = htmlPrinter.generateFileListSummary(diffJson, cfg); } - var diffOutput = ''; - if (cfg.outputFormat === 'side-by-side') { + let diffOutput = ""; + if (cfg.outputFormat === "side-by-side") { diffOutput = htmlPrinter.generateSideBySideJsonHtml(diffJson, cfg); } else { diffOutput = htmlPrinter.generateLineByLineJsonHtml(diffJson, cfg); @@ -70,9 +69,9 @@ * Generates pretty html from string diff input */ Diff2Html.prototype.getPrettyHtmlFromDiff = function(diffInput, config) { - var cfg = utils.safeConfig(config, defaultConfig); - cfg.inputFormat = 'diff'; - cfg.outputFormat = 'line-by-line'; + const cfg = utils.safeConfig(config, defaultConfig); + cfg.inputFormat = "diff"; + cfg.outputFormat = "line-by-line"; return this.getPrettyHtml(diffInput, cfg); }; @@ -80,9 +79,9 @@ * Generates pretty html from a json object */ Diff2Html.prototype.getPrettyHtmlFromJson = function(diffJson, config) { - var cfg = utils.safeConfig(config, defaultConfig); - cfg.inputFormat = 'json'; - cfg.outputFormat = 'line-by-line'; + const cfg = utils.safeConfig(config, defaultConfig); + cfg.inputFormat = "json"; + cfg.outputFormat = "line-by-line"; return this.getPrettyHtml(diffJson, cfg); }; @@ -90,9 +89,9 @@ * Generates pretty side by side html from string diff input */ Diff2Html.prototype.getPrettySideBySideHtmlFromDiff = function(diffInput, config) { - var cfg = utils.safeConfig(config, defaultConfig); - cfg.inputFormat = 'diff'; - cfg.outputFormat = 'side-by-side'; + const cfg = utils.safeConfig(config, defaultConfig); + cfg.inputFormat = "diff"; + cfg.outputFormat = "side-by-side"; return this.getPrettyHtml(diffInput, cfg); }; @@ -100,13 +99,13 @@ * Generates pretty side by side html from a json object */ Diff2Html.prototype.getPrettySideBySideHtmlFromJson = function(diffJson, config) { - var cfg = utils.safeConfig(config, defaultConfig); - cfg.inputFormat = 'json'; - cfg.outputFormat = 'side-by-side'; + const cfg = utils.safeConfig(config, defaultConfig); + cfg.inputFormat = "json"; + cfg.outputFormat = "side-by-side"; return this.getPrettyHtml(diffJson, cfg); }; - var diffObject = new Diff2Html(); + const diffObject = new Diff2Html(); module.exports.Diff2Html = diffObject; // Expose diff2html in the browser diff --git a/src/file-list-printer.js b/src/file-list-printer.js index da371c9..97e31b7 100644 --- a/src/file-list-printer.js +++ b/src/file-list-printer.js @@ -6,40 +6,45 @@ */ (function() { - var printerUtils = require('./printer-utils.js').PrinterUtils; + const printerUtils = require("./printer-utils.js").PrinterUtils; - var hoganUtils; + let hoganUtils; - var baseTemplatesPath = 'file-summary'; - var iconsBaseTemplatesPath = 'icon'; + const baseTemplatesPath = "file-summary"; + const iconsBaseTemplatesPath = "icon"; function FileListPrinter(config) { this.config = config; - var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils; + const HoganJsUtils = require("./hoganjs-utils.js").HoganJsUtils; hoganUtils = new HoganJsUtils(config); } FileListPrinter.prototype.generateFileList = function(diffFiles) { - var lineTemplate = hoganUtils.template(baseTemplatesPath, 'line'); + const lineTemplate = hoganUtils.template(baseTemplatesPath, "line"); - var files = diffFiles.map(function(file) { - var fileTypeName = printerUtils.getFileTypeIcon(file); - var iconTemplate = hoganUtils.template(iconsBaseTemplatesPath, fileTypeName); + const files = diffFiles + .map(function(file) { + const fileTypeName = printerUtils.getFileTypeIcon(file); + const iconTemplate = hoganUtils.template(iconsBaseTemplatesPath, fileTypeName); - return lineTemplate.render({ - fileHtmlId: printerUtils.getHtmlId(file), - oldName: file.oldName, - newName: file.newName, - fileName: printerUtils.getDiffName(file), - deletedLines: '-' + file.deletedLines, - addedLines: '+' + file.addedLines - }, { - fileIcon: iconTemplate - }); - }).join('\n'); + return lineTemplate.render( + { + fileHtmlId: printerUtils.getHtmlId(file), + oldName: file.oldName, + newName: file.newName, + fileName: printerUtils.getDiffName(file), + deletedLines: "-" + file.deletedLines, + addedLines: "+" + file.addedLines + }, + { + fileIcon: iconTemplate + } + ); + }) + .join("\n"); - return hoganUtils.render(baseTemplatesPath, 'wrapper', { + return hoganUtils.render(baseTemplatesPath, "wrapper", { filesNumber: diffFiles.length, files: files }); diff --git a/src/hoganjs-utils.js b/src/hoganjs-utils.js index b2e9c27..9727557 100644 --- a/src/hoganjs-utils.js +++ b/src/hoganjs-utils.js @@ -6,20 +6,20 @@ */ (function() { - var fs = require('fs'); - var path = require('path'); - var hogan = require('hogan.js'); + const fs = require("fs"); + const path = require("path"); + const hogan = require("hogan.js"); - var hoganTemplates = require('./templates/diff2html-templates.js'); + const hoganTemplates = require("./diff2html-templates.js"); - var extraTemplates; + let extraTemplates; function HoganJsUtils(configuration) { this.config = configuration || {}; extraTemplates = this.config.templates || {}; - var rawTemplates = this.config.rawTemplates || {}; - for (var templateName in rawTemplates) { + const rawTemplates = this.config.rawTemplates || {}; + for (const templateName in rawTemplates) { if (rawTemplates.hasOwnProperty(templateName)) { if (!extraTemplates[templateName]) extraTemplates[templateName] = this.compile(rawTemplates[templateName]); } @@ -27,7 +27,7 @@ } HoganJsUtils.prototype.render = function(namespace, view, params) { - var template = this.template(namespace, view); + const template = this.template(namespace, view); if (template) { return template.render(params); } @@ -36,13 +36,13 @@ }; HoganJsUtils.prototype.template = function(namespace, view) { - var templateKey = this._templateKey(namespace, view); + const templateKey = this._templateKey(namespace, view); return this._getTemplate(templateKey); }; HoganJsUtils.prototype._getTemplate = function(templateKey) { - var template; + let template; if (!this.config.noCache) { template = this._readFromCache(templateKey); @@ -56,18 +56,18 @@ }; HoganJsUtils.prototype._loadTemplate = function(templateKey) { - var template; + let template; try { if (fs.readFileSync) { - var templatesPath = path.resolve(__dirname, 'templates'); - var templatePath = path.join(templatesPath, templateKey); - var templateContent = fs.readFileSync(templatePath + '.mustache', 'utf8'); + const templatesPath = path.resolve(__dirname, "templates"); + const templatePath = path.join(templatesPath, templateKey); + const templateContent = fs.readFileSync(templatePath + ".mustache", "utf8"); template = hogan.compile(templateContent); hoganTemplates[templateKey] = template; } } catch (e) { - console.error('Failed to read (template: ' + templateKey + ') from fs: ' + e.message); + console.error("Failed to read (template: " + templateKey + ") from fs: " + e.message); } return template; @@ -78,7 +78,7 @@ }; HoganJsUtils.prototype._templateKey = function(namespace, view) { - return namespace + '-' + view; + return namespace + "-" + view; }; HoganJsUtils.prototype.compile = function(templateStr) { diff --git a/src/html-printer.js b/src/html-printer.js index 13f8304..2c76d83 100644 --- a/src/html-printer.js +++ b/src/html-printer.js @@ -6,25 +6,24 @@ */ (function() { - var LineByLinePrinter = require('./line-by-line-printer.js').LineByLinePrinter; - var SideBySidePrinter = require('./side-by-side-printer.js').SideBySidePrinter; - var FileListPrinter = require('./file-list-printer.js').FileListPrinter; + const LineByLinePrinter = require("./line-by-line-printer.js").LineByLinePrinter; + const SideBySidePrinter = require("./side-by-side-printer.js").SideBySidePrinter; + const FileListPrinter = require("./file-list-printer.js").FileListPrinter; - function HtmlPrinter() { - } + function HtmlPrinter() {} HtmlPrinter.prototype.generateLineByLineJsonHtml = function(diffFiles, config) { - var lineByLinePrinter = new LineByLinePrinter(config); + const lineByLinePrinter = new LineByLinePrinter(config); return lineByLinePrinter.generateLineByLineJsonHtml(diffFiles); }; HtmlPrinter.prototype.generateSideBySideJsonHtml = function(diffFiles, config) { - var sideBySidePrinter = new SideBySidePrinter(config); + const sideBySidePrinter = new SideBySidePrinter(config); return sideBySidePrinter.generateSideBySideJsonHtml(diffFiles); }; HtmlPrinter.prototype.generateFileListSummary = function(diffJson, config) { - var fileListPrinter = new FileListPrinter(config); + const fileListPrinter = new FileListPrinter(config); return fileListPrinter.generateFileList(diffJson); }; diff --git a/src/line-by-line-printer.js b/src/line-by-line-printer.js index 49f183f..8a0f5ac 100644 --- a/src/line-by-line-printer.js +++ b/src/line-by-line-printer.js @@ -6,54 +6,57 @@ */ (function() { - var diffParser = require('./diff-parser.js').DiffParser; - var printerUtils = require('./printer-utils.js').PrinterUtils; - var utils = require('./utils.js').Utils; - var Rematch = require('./rematch.js').Rematch; + const diffParser = require("./diff-parser.js").DiffParser; + const printerUtils = require("./printer-utils.js").PrinterUtils; + const utils = require("./utils.js").Utils; + const Rematch = require("./rematch.js").Rematch; - var hoganUtils; + let hoganUtils; - var genericTemplatesPath = 'generic'; - var baseTemplatesPath = 'line-by-line'; - var iconsBaseTemplatesPath = 'icon'; - var tagsBaseTemplatesPath = 'tag'; + const genericTemplatesPath = "generic"; + const baseTemplatesPath = "line-by-line"; + const iconsBaseTemplatesPath = "icon"; + const tagsBaseTemplatesPath = "tag"; function LineByLinePrinter(config) { this.config = config; - var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils; + const HoganJsUtils = require("./hoganjs-utils.js").HoganJsUtils; hoganUtils = new HoganJsUtils(config); } LineByLinePrinter.prototype.makeFileDiffHtml = function(file, diffs) { - if (this.config.renderNothingWhenEmpty && file.blocks && !file.blocks.length) return ''; + if (this.config.renderNothingWhenEmpty && file.blocks && !file.blocks.length) return ""; - var fileDiffTemplate = hoganUtils.template(baseTemplatesPath, 'file-diff'); - var filePathTemplate = hoganUtils.template(genericTemplatesPath, 'file-path'); - var fileIconTemplate = hoganUtils.template(iconsBaseTemplatesPath, 'file'); - var fileTagTemplate = hoganUtils.template(tagsBaseTemplatesPath, printerUtils.getFileTypeIcon(file)); + const fileDiffTemplate = hoganUtils.template(baseTemplatesPath, "file-diff"); + const filePathTemplate = hoganUtils.template(genericTemplatesPath, "file-path"); + const fileIconTemplate = hoganUtils.template(iconsBaseTemplatesPath, "file"); + const fileTagTemplate = hoganUtils.template(tagsBaseTemplatesPath, printerUtils.getFileTypeIcon(file)); return fileDiffTemplate.render({ file: file, fileHtmlId: printerUtils.getHtmlId(file), diffs: diffs, - filePath: filePathTemplate.render({ - fileDiffName: printerUtils.getDiffName(file) - }, { - fileIcon: fileIconTemplate, - fileTag: fileTagTemplate - }) + filePath: filePathTemplate.render( + { + fileDiffName: printerUtils.getDiffName(file) + }, + { + fileIcon: fileIconTemplate, + fileTag: fileTagTemplate + } + ) }); }; LineByLinePrinter.prototype.makeLineByLineHtmlWrapper = function(content) { - return hoganUtils.render(genericTemplatesPath, 'wrapper', {'content': content}); + return hoganUtils.render(genericTemplatesPath, "wrapper", { content: content }); }; LineByLinePrinter.prototype.generateLineByLineJsonHtml = function(diffFiles) { - var that = this; - var htmlDiffs = diffFiles.map(function(file) { - var diffs; + const that = this; + const htmlDiffs = diffFiles.map(function(file) { + let diffs; if (file.blocks.length) { diffs = that._generateFileHtml(file); } else { @@ -62,134 +65,151 @@ return that.makeFileDiffHtml(file, diffs); }); - return this.makeLineByLineHtmlWrapper(htmlDiffs.join('\n')); + return this.makeLineByLineHtmlWrapper(htmlDiffs.join("\n")); }; - var matcher = Rematch.rematch(function(a, b) { - var amod = a.content.substr(1); - var bmod = b.content.substr(1); + const matcher = Rematch.rematch(function(a, b) { + const amod = a.content.substr(1); + const bmod = b.content.substr(1); return Rematch.distance(amod, bmod); }); LineByLinePrinter.prototype.makeColumnLineNumberHtml = function(block) { - return hoganUtils.render(genericTemplatesPath, 'column-line-number', { + return hoganUtils.render(genericTemplatesPath, "column-line-number", { diffParser: diffParser, blockHeader: utils.escape(block.header), - lineClass: 'd2h-code-linenumber', - contentClass: 'd2h-code-line' + lineClass: "d2h-code-linenumber", + contentClass: "d2h-code-line" }); }; LineByLinePrinter.prototype._generateFileHtml = function(file) { - var that = this; - return file.blocks.map(function(block) { - var lines = that.makeColumnLineNumberHtml(block); - var oldLines = []; - var newLines = []; + const that = this; + return file.blocks + .map(function(block) { + let lines = that.makeColumnLineNumberHtml(block); + let oldLines = []; + let newLines = []; - function processChangeBlock() { - var matches; - var insertType; - var deleteType; + function processChangeBlock() { + let matches; + let insertType; + let deleteType; - var comparisons = oldLines.length * newLines.length; + const comparisons = oldLines.length * newLines.length; - var maxLineSizeInBlock = Math.max.apply(null, - [0].concat((oldLines.concat(newLines)).map( - function(elem) { - return elem.content.length; - } - ))); + const maxLineSizeInBlock = Math.max.apply( + null, + [0].concat( + oldLines.concat(newLines).map(function(elem) { + return elem.content.length; + }) + ) + ); - var doMatching = comparisons < that.config.matchingMaxComparisons && - maxLineSizeInBlock < that.config.maxLineSizeInBlockForComparison && - (that.config.matching === 'lines' || that.config.matching === 'words'); + const doMatching = + comparisons < that.config.matchingMaxComparisons && + maxLineSizeInBlock < that.config.maxLineSizeInBlockForComparison && + (that.config.matching === "lines" || that.config.matching === "words"); - if (doMatching) { - matches = matcher(oldLines, newLines); - insertType = diffParser.LINE_TYPE.INSERT_CHANGES; - deleteType = diffParser.LINE_TYPE.DELETE_CHANGES; - } else { - matches = [[oldLines, newLines]]; - insertType = diffParser.LINE_TYPE.INSERTS; - deleteType = diffParser.LINE_TYPE.DELETES; - } - - matches.forEach(function(match) { - oldLines = match[0]; - newLines = match[1]; - - var processedOldLines = []; - var processedNewLines = []; - - var common = Math.min(oldLines.length, newLines.length); - - var oldLine, newLine; - for (var j = 0; j < common; j++) { - oldLine = oldLines[j]; - newLine = newLines[j]; - - that.config.isCombined = file.isCombined; - var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config); - - processedOldLines += - that.makeLineHtml(file.isCombined, deleteType, oldLine.oldNumber, oldLine.newNumber, - diff.first.line, diff.first.prefix); - processedNewLines += - that.makeLineHtml(file.isCombined, insertType, newLine.oldNumber, newLine.newNumber, - diff.second.line, diff.second.prefix); + if (doMatching) { + matches = matcher(oldLines, newLines); + insertType = diffParser.LINE_TYPE.INSERT_CHANGES; + deleteType = diffParser.LINE_TYPE.DELETE_CHANGES; + } else { + matches = [[oldLines, newLines]]; + insertType = diffParser.LINE_TYPE.INSERTS; + deleteType = diffParser.LINE_TYPE.DELETES; } - lines += processedOldLines + processedNewLines; - lines += that._processLines(file.isCombined, oldLines.slice(common), newLines.slice(common)); - }); + matches.forEach(function(match) { + oldLines = match[0]; + newLines = match[1]; - oldLines = []; - newLines = []; - } + let processedOldLines = []; + let processedNewLines = []; - for (var i = 0; i < block.lines.length; i++) { - var line = block.lines[i]; - var escapedLine = utils.escape(line.content); + const common = Math.min(oldLines.length, newLines.length); - if (line.type !== diffParser.LINE_TYPE.INSERTS && - (newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0))) { - processChangeBlock(); + let oldLine, newLine; + for (let j = 0; j < common; j++) { + oldLine = oldLines[j]; + newLine = newLines[j]; + + that.config.isCombined = file.isCombined; + const diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config); + + processedOldLines += that.makeLineHtml( + file.isCombined, + deleteType, + oldLine.oldNumber, + oldLine.newNumber, + diff.first.line, + diff.first.prefix + ); + processedNewLines += that.makeLineHtml( + file.isCombined, + insertType, + newLine.oldNumber, + newLine.newNumber, + diff.second.line, + diff.second.prefix + ); + } + + lines += processedOldLines + processedNewLines; + lines += that._processLines(file.isCombined, oldLines.slice(common), newLines.slice(common)); + }); + + oldLines = []; + newLines = []; } - if (line.type === diffParser.LINE_TYPE.CONTEXT) { - lines += that.makeLineHtml(file.isCombined, line.type, line.oldNumber, line.newNumber, escapedLine); - } else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) { - lines += that.makeLineHtml(file.isCombined, line.type, line.oldNumber, line.newNumber, escapedLine); - } else if (line.type === diffParser.LINE_TYPE.DELETES) { - oldLines.push(line); - } else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) { - newLines.push(line); - } else { - console.error('Unknown state in html line-by-line generator'); - processChangeBlock(); + for (let i = 0; i < block.lines.length; i++) { + const line = block.lines[i]; + const escapedLine = utils.escape(line.content); + + if ( + line.type !== diffParser.LINE_TYPE.INSERTS && + (newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0)) + ) { + processChangeBlock(); + } + + if (line.type === diffParser.LINE_TYPE.CONTEXT) { + lines += that.makeLineHtml(file.isCombined, line.type, line.oldNumber, line.newNumber, escapedLine); + } else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) { + lines += that.makeLineHtml(file.isCombined, line.type, line.oldNumber, line.newNumber, escapedLine); + } else if (line.type === diffParser.LINE_TYPE.DELETES) { + oldLines.push(line); + } else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) { + newLines.push(line); + } else { + console.error("Unknown state in html line-by-line generator"); + processChangeBlock(); + } } - } - processChangeBlock(); + processChangeBlock(); - return lines; - }).join('\n'); + return lines; + }) + .join("\n"); }; LineByLinePrinter.prototype._processLines = function(isCombined, oldLines, newLines) { - var lines = ''; + let lines = ""; - for (var i = 0; i < oldLines.length; i++) { - var oldLine = oldLines[i]; - var oldEscapedLine = utils.escape(oldLine.content); + for (let i = 0; i < oldLines.length; i++) { + const oldLine = oldLines[i]; + const oldEscapedLine = utils.escape(oldLine.content); lines += this.makeLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldLine.newNumber, oldEscapedLine); } - for (var j = 0; j < newLines.length; j++) { - var newLine = newLines[j]; - var newEscapedLine = utils.escape(newLine.content); + for (let j = 0; j < newLines.length; j++) { + const newLine = newLines[j]; + const newEscapedLine = utils.escape(newLine.content); lines += this.makeLineHtml(isCombined, newLine.type, newLine.oldNumber, newLine.newNumber, newEscapedLine); } @@ -197,38 +217,37 @@ }; LineByLinePrinter.prototype.makeLineHtml = function(isCombined, type, oldNumber, newNumber, content, possiblePrefix) { - var lineNumberTemplate = hoganUtils.render(baseTemplatesPath, 'numbers', { + const lineNumberTemplate = hoganUtils.render(baseTemplatesPath, "numbers", { oldNumber: utils.valueOrEmpty(oldNumber), newNumber: utils.valueOrEmpty(newNumber) }); - var lineWithoutPrefix = content; - var prefix = possiblePrefix; + let lineWithoutPrefix = content; + let prefix = possiblePrefix; if (!prefix) { - var lineWithPrefix = printerUtils.separatePrefix(isCombined, content); + const lineWithPrefix = printerUtils.separatePrefix(isCombined, content); prefix = lineWithPrefix.prefix; lineWithoutPrefix = lineWithPrefix.line; } - if (prefix === ' ') { - prefix = ' '; + if (prefix === " ") { + prefix = " "; } - return hoganUtils.render(genericTemplatesPath, 'line', - { - type: type, - lineClass: 'd2h-code-linenumber', - contentClass: 'd2h-code-line', - prefix: prefix, - content: lineWithoutPrefix, - lineNumber: lineNumberTemplate - }); + return hoganUtils.render(genericTemplatesPath, "line", { + type: type, + lineClass: "d2h-code-linenumber", + contentClass: "d2h-code-line", + prefix: prefix, + content: lineWithoutPrefix, + lineNumber: lineNumberTemplate + }); }; LineByLinePrinter.prototype._generateEmptyDiff = function() { - return hoganUtils.render(genericTemplatesPath, 'empty-diff', { - contentClass: 'd2h-code-line', + return hoganUtils.render(genericTemplatesPath, "empty-diff", { + contentClass: "d2h-code-line", diffParser: diffParser }); }; diff --git a/src/printer-utils.js b/src/printer-utils.js index d4a61be..9e2ee49 100644 --- a/src/printer-utils.js +++ b/src/printer-utils.js @@ -6,18 +6,17 @@ */ (function() { - var jsDiff = require('diff'); - var utils = require('./utils.js').Utils; - var Rematch = require('./rematch.js').Rematch; + const jsDiff = require("diff"); + const utils = require("./utils.js").Utils; + const Rematch = require("./rematch.js").Rematch; - var separator = '/'; + const separator = "/"; - function PrinterUtils() { - } + function PrinterUtils() {} PrinterUtils.prototype.separatePrefix = function(isCombined, line) { - var prefix; - var lineWithoutPrefix; + let prefix; + let lineWithoutPrefix; if (isCombined) { prefix = line.substring(0, 2); @@ -28,45 +27,56 @@ } return { - 'prefix': prefix, - 'line': lineWithoutPrefix + prefix: prefix, + line: lineWithoutPrefix }; }; PrinterUtils.prototype.getHtmlId = function(file) { - var hashCode = function(text) { - var i, chr, len; - var hash = 0; + const hashCode = function(text) { + let i, chr, len; + let hash = 0; for (i = 0, len = text.length; i < len; i++) { chr = text.charCodeAt(i); - hash = ((hash << 5) - hash) + chr; + hash = (hash << 5) - hash + chr; hash |= 0; // Convert to 32bit integer } return hash; }; - return 'd2h-' + hashCode(this.getDiffName(file)).toString().slice(-6); + return ( + "d2h-" + + hashCode(this.getDiffName(file)) + .toString() + .slice(-6) + ); }; PrinterUtils.prototype.getDiffName = function(file) { - var oldFilename = unifyPath(file.oldName); - var newFilename = unifyPath(file.newName); + const oldFilename = unifyPath(file.oldName); + const newFilename = unifyPath(file.newName); - if (oldFilename && newFilename && oldFilename !== newFilename && !isDevNullName(oldFilename) && !isDevNullName(newFilename)) { - var prefixPaths = []; - var suffixPaths = []; + if ( + oldFilename && + newFilename && + oldFilename !== newFilename && + !isDevNullName(oldFilename) && + !isDevNullName(newFilename) + ) { + const prefixPaths = []; + const suffixPaths = []; - var oldFilenameParts = oldFilename.split(separator); - var newFilenameParts = newFilename.split(separator); + const oldFilenameParts = oldFilename.split(separator); + const newFilenameParts = newFilename.split(separator); - var oldFilenamePartsSize = oldFilenameParts.length; - var newFilenamePartsSize = newFilenameParts.length; + const oldFilenamePartsSize = oldFilenameParts.length; + const newFilenamePartsSize = newFilenameParts.length; - var i = 0; - var j = oldFilenamePartsSize - 1; - var k = newFilenamePartsSize - 1; + let i = 0; + let j = oldFilenamePartsSize - 1; + let k = newFilenamePartsSize - 1; while (i < j && i < k) { if (oldFilenameParts[i] === newFilenameParts[i]) { @@ -87,53 +97,55 @@ } } - var finalPrefix = prefixPaths.join(separator); - var finalSuffix = suffixPaths.join(separator); + const finalPrefix = prefixPaths.join(separator); + const finalSuffix = suffixPaths.join(separator); - var oldRemainingPath = oldFilenameParts.slice(i, j + 1).join(separator); - var newRemainingPath = newFilenameParts.slice(i, k + 1).join(separator); + const oldRemainingPath = oldFilenameParts.slice(i, j + 1).join(separator); + const newRemainingPath = newFilenameParts.slice(i, k + 1).join(separator); if (finalPrefix.length && finalSuffix.length) { - return finalPrefix + separator + '{' + oldRemainingPath + ' → ' + newRemainingPath + '}' + separator + finalSuffix; + return ( + finalPrefix + separator + "{" + oldRemainingPath + " → " + newRemainingPath + "}" + separator + finalSuffix + ); } else if (finalPrefix.length) { - return finalPrefix + separator + '{' + oldRemainingPath + ' → ' + newRemainingPath + '}'; + return finalPrefix + separator + "{" + oldRemainingPath + " → " + newRemainingPath + "}"; } else if (finalSuffix.length) { - return '{' + oldRemainingPath + ' → ' + newRemainingPath + '}' + separator + finalSuffix; + return "{" + oldRemainingPath + " → " + newRemainingPath + "}" + separator + finalSuffix; } - return oldFilename + ' → ' + newFilename; + return oldFilename + " → " + newFilename; } else if (newFilename && !isDevNullName(newFilename)) { return newFilename; } else if (oldFilename) { return oldFilename; } - return 'unknown/file/path'; + return "unknown/file/path"; }; PrinterUtils.prototype.getFileTypeIcon = function(file) { - var templateName = 'file-changed'; + let templateName = "file-changed"; if (file.isRename) { - templateName = 'file-renamed'; + templateName = "file-renamed"; } else if (file.isCopy) { - templateName = 'file-renamed'; + templateName = "file-renamed"; } else if (file.isNew) { - templateName = 'file-added'; + templateName = "file-added"; } else if (file.isDeleted) { - templateName = 'file-deleted'; + templateName = "file-deleted"; } else if (file.newName !== file.oldName) { // If file is not Added, not Deleted and the names changed it must be a rename :) - templateName = 'file-renamed'; + templateName = "file-renamed"; } return templateName; }; PrinterUtils.prototype.diffHighlight = function(diffLine1, diffLine2, config) { - var linePrefix1, linePrefix2, unprefixedLine1, unprefixedLine2; + let linePrefix1, linePrefix2, unprefixedLine1, unprefixedLine2; - var prefixSize = 1; + let prefixSize = 1; if (config.isCombined) { prefixSize = 2; @@ -144,8 +156,10 @@ unprefixedLine1 = diffLine1.substr(prefixSize); unprefixedLine2 = diffLine2.substr(prefixSize); - if (unprefixedLine1.length > config.maxLineLengthHighlight || - unprefixedLine2.length > config.maxLineLengthHighlight) { + if ( + unprefixedLine1.length > config.maxLineLengthHighlight || + unprefixedLine2.length > config.maxLineLengthHighlight + ) { return { first: { prefix: linePrefix1, @@ -158,42 +172,42 @@ }; } - var diff; - if (config.diffStyle === 'char') { + let diff; + if (config.diffStyle === "char") { diff = jsDiff.diffChars(unprefixedLine1, unprefixedLine2); } else { diff = jsDiff.diffWordsWithSpace(unprefixedLine1, unprefixedLine2); } - var highlightedLine = ''; + let highlightedLine = ""; - var changedWords = []; - if (config.diffStyle === 'word' && config.matching === 'words') { - var treshold = 0.25; + const changedWords = []; + if (config.diffStyle === "word" && config.matching === "words") { + let treshold = 0.25; - if (typeof (config.matchWordsThreshold) !== 'undefined') { + if (typeof config.matchWordsThreshold !== "undefined") { treshold = config.matchWordsThreshold; } - var matcher = Rematch.rematch(function(a, b) { - var amod = a.value; - var bmod = b.value; + const matcher = Rematch.rematch(function(a, b) { + const amod = a.value; + const bmod = b.value; return Rematch.distance(amod, bmod); }); - var removed = diff.filter(function isRemoved(element) { + const removed = diff.filter(function isRemoved(element) { return element.removed; }); - var added = diff.filter(function isAdded(element) { + const added = diff.filter(function isAdded(element) { return element.added; }); - var chunks = matcher(added, removed); + const chunks = matcher(added, removed); chunks.forEach(function(chunk) { if (chunk[0].length === 1 && chunk[1].length === 1) { - var dist = Rematch.distance(chunk[0][0].value, chunk[1][0].value); + const dist = Rematch.distance(chunk[0][0].value, chunk[1][0].value); if (dist < treshold) { changedWords.push(chunk[0][0]); changedWords.push(chunk[1][0]); @@ -203,12 +217,12 @@ } diff.forEach(function(part) { - var addClass = changedWords.indexOf(part) > -1 ? ' class="d2h-change"' : ''; - var elemType = part.added ? 'ins' : part.removed ? 'del' : null; - var escapedValue = utils.escape(part.value); + const addClass = changedWords.indexOf(part) > -1 ? ' class="d2h-change"' : ""; + const elemType = part.added ? "ins" : part.removed ? "del" : null; + const escapedValue = utils.escape(part.value); if (elemType !== null) { - highlightedLine += '<' + elemType + addClass + '>' + escapedValue + ''; + highlightedLine += "<" + elemType + addClass + ">" + escapedValue + ""; } else { highlightedLine += escapedValue; } @@ -228,22 +242,22 @@ function unifyPath(path) { if (path) { - return path.replace('\\', '/'); + return path.replace("\\", "/"); } return path; } function isDevNullName(name) { - return name.indexOf('dev/null') !== -1; + return name.indexOf("dev/null") !== -1; } function removeIns(line) { - return line.replace(/(]*>((.|\n)*?)<\/ins>)/g, ''); + return line.replace(/(]*>((.|\n)*?)<\/ins>)/g, ""); } function removeDel(line) { - return line.replace(/(]*>((.|\n)*?)<\/del>)/g, ''); + return line.replace(/(]*>((.|\n)*?)<\/del>)/g, ""); } module.exports.PrinterUtils = new PrinterUtils(); diff --git a/src/rematch.js b/src/rematch.js index bad5665..b8b26a5 100644 --- a/src/rematch.js +++ b/src/rematch.js @@ -7,7 +7,7 @@ */ (function() { - var Rematch = {}; + const Rematch = {}; /* Copyright (c) 2011 Andrei Mackenzie @@ -29,16 +29,16 @@ return a.length; } - var matrix = []; + const matrix = []; // Increment along the first column of each row - var i; + let i; for (i = 0; i <= b.length; i++) { matrix[i] = [i]; } // Increment each column in the first row - var j; + let j; for (j = 0; j <= a.length; j++) { matrix[0][j] = j; } @@ -49,9 +49,13 @@ if (b.charAt(i - 1) === a.charAt(j - 1)) { matrix[i][j] = matrix[i - 1][j - 1]; } else { - matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // Substitution - Math.min(matrix[i][j - 1] + 1, // Insertion - matrix[i - 1][j] + 1)); // Deletion + matrix[i][j] = Math.min( + matrix[i - 1][j - 1] + 1, // Substitution + Math.min( + matrix[i][j - 1] + 1, // Insertion + matrix[i - 1][j] + 1 + ) + ); // Deletion } } } @@ -64,19 +68,19 @@ Rematch.distance = function distance(x, y) { x = x.trim(); y = y.trim(); - var lev = levenshtein(x, y); - var score = lev / (x.length + y.length); + const lev = levenshtein(x, y); + const score = lev / (x.length + y.length); return score; }; Rematch.rematch = function rematch(distanceFunction) { function findBestMatch(a, b, cache) { - var bestMatchDist = Infinity; - var bestMatch; - for (var i = 0; i < a.length; ++i) { - for (var j = 0; j < b.length; ++j) { - var cacheKey = JSON.stringify([a[i], b[j]]); + let bestMatchDist = Infinity; + let bestMatch; + for (let i = 0; i < a.length; ++i) { + for (let j = 0; j < b.length; ++j) { + const cacheKey = JSON.stringify([a[i], b[j]]); var md; if (cache.hasOwnProperty(cacheKey)) { md = cache[cacheKey]; @@ -86,7 +90,7 @@ } if (md < bestMatchDist) { bestMatchDist = md; - bestMatch = {indexA: i, indexB: j, score: bestMatchDist}; + bestMatch = { indexA: i, indexB: j, score: bestMatchDist }; } } } @@ -95,33 +99,33 @@ } function group(a, b, level, cache) { - if (typeof (cache) === 'undefined') { + if (typeof cache === "undefined") { cache = {}; } - var bm = findBestMatch(a, b, cache); + const bm = findBestMatch(a, b, cache); if (!level) { level = 0; } - if (!bm || (a.length + b.length < 3)) { + if (!bm || a.length + b.length < 3) { return [[a, b]]; } - var a1 = a.slice(0, bm.indexA); - var b1 = b.slice(0, bm.indexB); - var aMatch = [a[bm.indexA]]; - var bMatch = [b[bm.indexB]]; - var tailA = bm.indexA + 1; - var tailB = bm.indexB + 1; - var a2 = a.slice(tailA); - var b2 = b.slice(tailB); + const a1 = a.slice(0, bm.indexA); + const b1 = b.slice(0, bm.indexB); + const aMatch = [a[bm.indexA]]; + const bMatch = [b[bm.indexB]]; + const tailA = bm.indexA + 1; + const tailB = bm.indexB + 1; + const a2 = a.slice(tailA); + const b2 = b.slice(tailB); - var group1 = group(a1, b1, level + 1, cache); - var groupMatch = group(aMatch, bMatch, level + 1, cache); - var group2 = group(a2, b2, level + 1, cache); - var result = groupMatch; + const group1 = group(a1, b1, level + 1, cache); + const groupMatch = group(aMatch, bMatch, level + 1, cache); + const group2 = group(a2, b2, level + 1, cache); + let result = groupMatch; if (bm.indexA > 0 || bm.indexB > 0) { result = group1.concat(result); diff --git a/src/side-by-side-printer.js b/src/side-by-side-printer.js index 91fb84b..7655081 100644 --- a/src/side-by-side-printer.js +++ b/src/side-by-side-printer.js @@ -6,21 +6,21 @@ */ (function() { - var diffParser = require('./diff-parser.js').DiffParser; - var printerUtils = require('./printer-utils.js').PrinterUtils; - var utils = require('./utils.js').Utils; - var Rematch = require('./rematch.js').Rematch; + const diffParser = require("./diff-parser.js").DiffParser; + const printerUtils = require("./printer-utils.js").PrinterUtils; + const utils = require("./utils.js").Utils; + const Rematch = require("./rematch.js").Rematch; - var hoganUtils; + let hoganUtils; - var genericTemplatesPath = 'generic'; - var baseTemplatesPath = 'side-by-side'; - var iconsBaseTemplatesPath = 'icon'; - var tagsBaseTemplatesPath = 'tag'; + const genericTemplatesPath = "generic"; + const baseTemplatesPath = "side-by-side"; + const iconsBaseTemplatesPath = "icon"; + const tagsBaseTemplatesPath = "tag"; - var matcher = Rematch.rematch(function(a, b) { - var amod = a.content.substr(1); - var bmod = b.content.substr(1); + const matcher = Rematch.rematch(function(a, b) { + const amod = a.content.substr(1); + const bmod = b.content.substr(1); return Rematch.distance(amod, bmod); }); @@ -28,82 +28,91 @@ function SideBySidePrinter(config) { this.config = config; - var HoganJsUtils = require('./hoganjs-utils.js').HoganJsUtils; + const HoganJsUtils = require("./hoganjs-utils.js").HoganJsUtils; hoganUtils = new HoganJsUtils(config); } SideBySidePrinter.prototype.makeDiffHtml = function(file, diffs) { - var fileDiffTemplate = hoganUtils.template(baseTemplatesPath, 'file-diff'); - var filePathTemplate = hoganUtils.template(genericTemplatesPath, 'file-path'); - var fileIconTemplate = hoganUtils.template(iconsBaseTemplatesPath, 'file'); - var fileTagTemplate = hoganUtils.template(tagsBaseTemplatesPath, printerUtils.getFileTypeIcon(file)); + const fileDiffTemplate = hoganUtils.template(baseTemplatesPath, "file-diff"); + const filePathTemplate = hoganUtils.template(genericTemplatesPath, "file-path"); + const fileIconTemplate = hoganUtils.template(iconsBaseTemplatesPath, "file"); + const fileTagTemplate = hoganUtils.template(tagsBaseTemplatesPath, printerUtils.getFileTypeIcon(file)); return fileDiffTemplate.render({ file: file, fileHtmlId: printerUtils.getHtmlId(file), diffs: diffs, - filePath: filePathTemplate.render({ - fileDiffName: printerUtils.getDiffName(file) - }, { - fileIcon: fileIconTemplate, - fileTag: fileTagTemplate - }) + filePath: filePathTemplate.render( + { + fileDiffName: printerUtils.getDiffName(file) + }, + { + fileIcon: fileIconTemplate, + fileTag: fileTagTemplate + } + ) }); }; SideBySidePrinter.prototype.generateSideBySideJsonHtml = function(diffFiles) { - var that = this; + const that = this; - var content = diffFiles.map(function(file) { - var diffs; - if (file.blocks.length) { - diffs = that.generateSideBySideFileHtml(file); - } else { - diffs = that.generateEmptyDiff(); - } + const content = diffFiles + .map(function(file) { + let diffs; + if (file.blocks.length) { + diffs = that.generateSideBySideFileHtml(file); + } else { + diffs = that.generateEmptyDiff(); + } - return that.makeDiffHtml(file, diffs); - }).join('\n'); + return that.makeDiffHtml(file, diffs); + }) + .join("\n"); - return hoganUtils.render(genericTemplatesPath, 'wrapper', {'content': content}); + return hoganUtils.render(genericTemplatesPath, "wrapper", { content: content }); }; SideBySidePrinter.prototype.makeSideHtml = function(blockHeader) { - return hoganUtils.render(genericTemplatesPath, 'column-line-number', { + return hoganUtils.render(genericTemplatesPath, "column-line-number", { diffParser: diffParser, blockHeader: utils.escape(blockHeader), - lineClass: 'd2h-code-side-linenumber', - contentClass: 'd2h-code-side-line' + lineClass: "d2h-code-side-linenumber", + contentClass: "d2h-code-side-line" }); }; SideBySidePrinter.prototype.generateSideBySideFileHtml = function(file) { - var that = this; - var fileHtml = {}; - fileHtml.left = ''; - fileHtml.right = ''; + const that = this; + const fileHtml = {}; + fileHtml.left = ""; + fileHtml.right = ""; file.blocks.forEach(function(block) { fileHtml.left += that.makeSideHtml(block.header); - fileHtml.right += that.makeSideHtml(''); + fileHtml.right += that.makeSideHtml(""); - var oldLines = []; - var newLines = []; + let oldLines = []; + let newLines = []; function processChangeBlock() { - var matches; - var insertType; - var deleteType; + let matches; + let insertType; + let deleteType; - var comparisons = oldLines.length * newLines.length; + const comparisons = oldLines.length * newLines.length; - var maxLineSizeInBlock = Math.max.apply(null, (oldLines.concat(newLines)).map(function(elem) { - return elem.length; - })); + const maxLineSizeInBlock = Math.max.apply( + null, + oldLines.concat(newLines).map(function(elem) { + return elem.length; + }) + ); - var doMatching = comparisons < that.config.matchingMaxComparisons && + const doMatching = + comparisons < that.config.matchingMaxComparisons && maxLineSizeInBlock < that.config.maxLineSizeInBlockForComparison && - (that.config.matching === 'lines' || that.config.matching === 'words'); + (that.config.matching === "lines" || that.config.matching === "words"); if (doMatching) { matches = matcher(oldLines, newLines); @@ -119,30 +128,38 @@ oldLines = match[0]; newLines = match[1]; - var common = Math.min(oldLines.length, newLines.length); - var max = Math.max(oldLines.length, newLines.length); + const common = Math.min(oldLines.length, newLines.length); + const max = Math.max(oldLines.length, newLines.length); - for (var j = 0; j < common; j++) { - var oldLine = oldLines[j]; - var newLine = newLines[j]; + for (let j = 0; j < common; j++) { + const oldLine = oldLines[j]; + const newLine = newLines[j]; that.config.isCombined = file.isCombined; - var diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config); + const diff = printerUtils.diffHighlight(oldLine.content, newLine.content, that.config); - fileHtml.left += - that.generateSingleLineHtml(file.isCombined, deleteType, oldLine.oldNumber, - diff.first.line, diff.first.prefix); - fileHtml.right += - that.generateSingleLineHtml(file.isCombined, insertType, newLine.newNumber, - diff.second.line, diff.second.prefix); + fileHtml.left += that.generateSingleLineHtml( + file.isCombined, + deleteType, + oldLine.oldNumber, + diff.first.line, + diff.first.prefix + ); + fileHtml.right += that.generateSingleLineHtml( + file.isCombined, + insertType, + newLine.newNumber, + diff.second.line, + diff.second.prefix + ); } if (max > common) { - var oldSlice = oldLines.slice(common); - var newSlice = newLines.slice(common); + const oldSlice = oldLines.slice(common); + const newSlice = newLines.slice(common); - var tmpHtml = that.processLines(file.isCombined, oldSlice, newSlice); + const tmpHtml = that.processLines(file.isCombined, oldSlice, newSlice); fileHtml.left += tmpHtml.left; fileHtml.right += tmpHtml.right; } @@ -152,28 +169,42 @@ newLines = []; } - for (var i = 0; i < block.lines.length; i++) { - var line = block.lines[i]; - var prefix = line.content[0]; - var escapedLine = utils.escape(line.content.substr(1)); + for (let i = 0; i < block.lines.length; i++) { + const line = block.lines[i]; + const prefix = line.content[0]; + const escapedLine = utils.escape(line.content.substr(1)); - if (line.type !== diffParser.LINE_TYPE.INSERTS && - (newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0))) { + if ( + line.type !== diffParser.LINE_TYPE.INSERTS && + (newLines.length > 0 || (line.type !== diffParser.LINE_TYPE.DELETES && oldLines.length > 0)) + ) { processChangeBlock(); } if (line.type === diffParser.LINE_TYPE.CONTEXT) { fileHtml.left += that.generateSingleLineHtml(file.isCombined, line.type, line.oldNumber, escapedLine, prefix); - fileHtml.right += that.generateSingleLineHtml(file.isCombined, line.type, line.newNumber, escapedLine, prefix); + fileHtml.right += that.generateSingleLineHtml( + file.isCombined, + line.type, + line.newNumber, + escapedLine, + prefix + ); } else if (line.type === diffParser.LINE_TYPE.INSERTS && !oldLines.length) { - fileHtml.left += that.generateSingleLineHtml(file.isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', ''); - fileHtml.right += that.generateSingleLineHtml(file.isCombined, line.type, line.newNumber, escapedLine, prefix); + fileHtml.left += that.generateSingleLineHtml(file.isCombined, diffParser.LINE_TYPE.CONTEXT, "", "", ""); + fileHtml.right += that.generateSingleLineHtml( + file.isCombined, + line.type, + line.newNumber, + escapedLine, + prefix + ); } else if (line.type === diffParser.LINE_TYPE.DELETES) { oldLines.push(line); } else if (line.type === diffParser.LINE_TYPE.INSERTS && Boolean(oldLines.length)) { newLines.push(line); } else { - console.error('unknown state in html side-by-side generator'); + console.error("unknown state in html side-by-side generator"); processChangeBlock(); } } @@ -185,15 +216,15 @@ }; SideBySidePrinter.prototype.processLines = function(isCombined, oldLines, newLines) { - var that = this; - var fileHtml = {}; - fileHtml.left = ''; - fileHtml.right = ''; + const that = this; + const fileHtml = {}; + fileHtml.left = ""; + fileHtml.right = ""; - var maxLinesNumber = Math.max(oldLines.length, newLines.length); - for (var i = 0; i < maxLinesNumber; i++) { - var oldLine = oldLines[i]; - var newLine = newLines[i]; + const maxLinesNumber = Math.max(oldLines.length, newLines.length); + for (let i = 0; i < maxLinesNumber; i++) { + const oldLine = oldLines[i]; + const newLine = newLines[i]; var oldContent; var newContent; var oldPrefix; @@ -210,16 +241,40 @@ } if (oldLine && newLine) { - fileHtml.left += that.generateSingleLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldContent, oldPrefix); - fileHtml.right += that.generateSingleLineHtml(isCombined, newLine.type, newLine.newNumber, newContent, newPrefix); + fileHtml.left += that.generateSingleLineHtml( + isCombined, + oldLine.type, + oldLine.oldNumber, + oldContent, + oldPrefix + ); + fileHtml.right += that.generateSingleLineHtml( + isCombined, + newLine.type, + newLine.newNumber, + newContent, + newPrefix + ); } else if (oldLine) { - fileHtml.left += that.generateSingleLineHtml(isCombined, oldLine.type, oldLine.oldNumber, oldContent, oldPrefix); - fileHtml.right += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', ''); + fileHtml.left += that.generateSingleLineHtml( + isCombined, + oldLine.type, + oldLine.oldNumber, + oldContent, + oldPrefix + ); + fileHtml.right += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, "", "", ""); } else if (newLine) { - fileHtml.left += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, '', '', ''); - fileHtml.right += that.generateSingleLineHtml(isCombined, newLine.type, newLine.newNumber, newContent, newPrefix); + fileHtml.left += that.generateSingleLineHtml(isCombined, diffParser.LINE_TYPE.CONTEXT, "", "", ""); + fileHtml.right += that.generateSingleLineHtml( + isCombined, + newLine.type, + newLine.newNumber, + newContent, + newPrefix + ); } else { - console.error('How did it get here?'); + console.error("How did it get here?"); } } @@ -227,44 +282,43 @@ }; SideBySidePrinter.prototype.generateSingleLineHtml = function(isCombined, type, number, content, possiblePrefix) { - var lineWithoutPrefix = content; - var prefix = possiblePrefix; - var lineClass = 'd2h-code-side-linenumber'; - var contentClass = 'd2h-code-side-line'; + let lineWithoutPrefix = content; + let prefix = possiblePrefix; + let lineClass = "d2h-code-side-linenumber"; + let contentClass = "d2h-code-side-line"; if (!number && !content) { - lineClass += ' d2h-code-side-emptyplaceholder'; - contentClass += ' d2h-code-side-emptyplaceholder'; - type += ' d2h-emptyplaceholder'; - prefix = ' '; - lineWithoutPrefix = ' '; + lineClass += " d2h-code-side-emptyplaceholder"; + contentClass += " d2h-code-side-emptyplaceholder"; + type += " d2h-emptyplaceholder"; + prefix = " "; + lineWithoutPrefix = " "; } else if (!prefix) { - var lineWithPrefix = printerUtils.separatePrefix(isCombined, content); + const lineWithPrefix = printerUtils.separatePrefix(isCombined, content); prefix = lineWithPrefix.prefix; lineWithoutPrefix = lineWithPrefix.line; } - if (prefix === ' ') { - prefix = ' '; + if (prefix === " ") { + prefix = " "; } - return hoganUtils.render(genericTemplatesPath, 'line', - { - type: type, - lineClass: lineClass, - contentClass: contentClass, - prefix: prefix, - content: lineWithoutPrefix, - lineNumber: number - }); + return hoganUtils.render(genericTemplatesPath, "line", { + type: type, + lineClass: lineClass, + contentClass: contentClass, + prefix: prefix, + content: lineWithoutPrefix, + lineNumber: number + }); }; SideBySidePrinter.prototype.generateEmptyDiff = function() { - var fileHtml = {}; - fileHtml.right = ''; + const fileHtml = {}; + fileHtml.right = ""; - fileHtml.left = hoganUtils.render(genericTemplatesPath, 'empty-diff', { - contentClass: 'd2h-code-side-line', + fileHtml.left = hoganUtils.render(genericTemplatesPath, "empty-diff", { + contentClass: "d2h-code-side-line", diffParser: diffParser }); diff --git a/src/templates/diff2html-templates.js b/src/templates/diff2html-templates.js deleted file mode 100644 index 945a9f2..0000000 --- a/src/templates/diff2html-templates.js +++ /dev/null @@ -1,23 +0,0 @@ -(function() { -if (!!!global.browserTemplates) global.browserTemplates = {}; -var Hogan = require("hogan.js");global.browserTemplates["file-summary-line"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("
  • ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(t.rp("");t.b(t.v(t.f("fileName",c,p,0)));t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b(t.v(t.f("addedLines",c,p,0)));t.b("");t.b("\n" + i);t.b(" ");t.b(t.v(t.f("deletedLines",c,p,0)));t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
  • ");return t.fl(); },partials: {"");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" Files changed (");t.b(t.v(t.f("filesNumber",c,p,0)));t.b(")");t.b("\n" + i);t.b(" hide");t.b("\n" + i);t.b(" show");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
      ");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("files",c,p,0)));t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["generic-column-line-number"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
    ");t.b(t.t(t.f("blockHeader",c,p,0)));t.b("
    ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["generic-empty-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" File without changes");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["generic-file-path"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(t.rp("");t.b(t.v(t.f("fileDiffName",c,p,0)));t.b("");t.b("\n" + i);t.b(t.rp("");return t.fl(); },partials: {"");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("lineNumber",c,p,0)));t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);if(t.s(t.f("prefix",c,p,1),c,p,0,171,247,"{{ }}")){t.rs(c,p,function(c,p,t){t.b(" ");t.b(t.t(t.f("prefix",c,p,0)));t.b("");t.b("\n" + i);});c.pop();}if(t.s(t.f("content",c,p,1),c,p,0,279,353,"{{ }}")){t.rs(c,p,function(c,p,t){t.b(" ");t.b(t.t(t.f("content",c,p,0)));t.b("");t.b("\n" + i);});c.pop();}t.b("
    ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["generic-wrapper"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("
    ");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("content",c,p,0)));t.b("\n" + i);t.b("
    ");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["icon-file-added"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["icon-file-changed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["icon-file-deleted"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["icon-file-renamed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["icon-file"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["line-by-line-file-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("filePath",c,p,0)));t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("diffs",c,p,0)));t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["line-by-line-numbers"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("
    ");t.b(t.v(t.f("oldNumber",c,p,0)));t.b("
    ");t.b("\n" + i);t.b("
    ");t.b(t.v(t.f("newNumber",c,p,0)));t.b("
    ");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["side-by-side-file-diff"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" ");t.b(t.t(t.f("filePath",c,p,0)));t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b(t.t(t.d("diffs.left",c,p,0)));t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b(t.t(t.d("diffs.right",c,p,0)));t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");t.b("\n" + i);t.b("
    ");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["tag-file-added"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("ADDED");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["tag-file-changed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("CHANGED");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["tag-file-deleted"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("DELETED");return t.fl(); },partials: {}, subs: { }}); -global.browserTemplates["tag-file-renamed"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("RENAMED");return t.fl(); },partials: {}, subs: { }}); -module.exports = global.browserTemplates; -})(); diff --git a/src/ui/js/diff2html-ui.js b/src/ui/js/diff2html-ui.js index 979939b..f7c1138 100644 --- a/src/ui/js/diff2html-ui.js +++ b/src/ui/js/diff2html-ui.js @@ -8,17 +8,17 @@ * */ -/*global $, hljs, Diff2Html*/ +/* global $, hljs, Diff2Html */ (function() { - var highlightJS = require('./highlight.js-internals.js').HighlightJS; + const highlightJS = require("./highlight.js-internals.js").HighlightJS; - var diffJson = null; - var defaultTarget = 'body'; - var currentSelectionColumnId = -1; + let diffJson = null; + const defaultTarget = "body"; + let currentSelectionColumnId = -1; function Diff2HtmlUI(config) { - var cfg = config || {}; + const cfg = config || {}; if (cfg.diff) { diffJson = Diff2Html.getJsonFromDiff(cfg.diff); @@ -30,9 +30,9 @@ } Diff2HtmlUI.prototype.draw = function(targetId, config) { - var cfg = config || {}; - cfg.inputFormat = 'json'; - var $target = this._getTarget(targetId); + const cfg = config || {}; + cfg.inputFormat = "json"; + const $target = this._getTarget(targetId); $target.html(Diff2Html.getPrettyHtml(diffJson, cfg)); if (cfg.synchronisedScroll) { @@ -41,25 +41,27 @@ }; Diff2HtmlUI.prototype.synchronisedScroll = function(targetId) { - var $target = this._getTarget(targetId); - $target.find('.d2h-file-side-diff').scroll(function() { - var $this = $(this); - $this.closest('.d2h-file-wrapper').find('.d2h-file-side-diff') + const $target = this._getTarget(targetId); + $target.find(".d2h-file-side-diff").scroll(function() { + const $this = $(this); + $this + .closest(".d2h-file-wrapper") + .find(".d2h-file-side-diff") .scrollLeft($this.scrollLeft()); }); }; Diff2HtmlUI.prototype.fileListCloseable = function(targetId, startVisible) { - var $target = this._getTarget(targetId); + const $target = this._getTarget(targetId); - var hashTag = this._getHashTag(); + const hashTag = this._getHashTag(); - var $showBtn = $target.find('.d2h-show'); - var $hideBtn = $target.find('.d2h-hide'); - var $fileList = $target.find('.d2h-file-list'); + const $showBtn = $target.find(".d2h-show"); + const $hideBtn = $target.find(".d2h-hide"); + const $fileList = $target.find(".d2h-file-list"); - if (hashTag === 'files-summary-show') show(); - else if (hashTag === 'files-summary-hide') hide(); + if (hashTag === "files-summary-show") show(); + else if (hashTag === "files-summary-hide") hide(); else if (startVisible) show(); else hide(); @@ -80,51 +82,53 @@ }; Diff2HtmlUI.prototype.highlightCode = function(targetId) { - var that = this; + const that = this; - var $target = that._getTarget(targetId); + const $target = that._getTarget(targetId); // collect all the diff files and execute the highlight on their lines - var $files = $target.find('.d2h-file-wrapper'); + const $files = $target.find(".d2h-file-wrapper"); $files.map(function(_i, file) { - var oldLinesState; - var newLinesState; - var $file = $(file); - var language = $file.data('lang'); + let oldLinesState; + let newLinesState; + const $file = $(file); + const language = $file.data("lang"); // collect all the code lines and execute the highlight on them - var $codeLines = $file.find('.d2h-code-line-ctn'); + const $codeLines = $file.find(".d2h-code-line-ctn"); $codeLines.map(function(_j, line) { - var $line = $(line); - var text = line.textContent; - var lineParent = line.parentNode; + const $line = $(line); + const text = line.textContent; + const lineParent = line.parentNode; - var lineState; - if (lineParent.className.indexOf('d2h-del') !== -1) { + let lineState; + if (lineParent.className.indexOf("d2h-del") !== -1) { lineState = oldLinesState; } else { lineState = newLinesState; } - var result = hljs.getLanguage(language) ? hljs.highlight(language, text, true, lineState) : hljs.highlightAuto(text); + const result = hljs.getLanguage(language) + ? hljs.highlight(language, text, true, lineState) + : hljs.highlightAuto(text); - if (lineParent.className.indexOf('d2h-del') !== -1) { + if (lineParent.className.indexOf("d2h-del") !== -1) { oldLinesState = result.top; - } else if (lineParent.className.indexOf('d2h-ins') !== -1) { + } else if (lineParent.className.indexOf("d2h-ins") !== -1) { newLinesState = result.top; } else { oldLinesState = result.top; newLinesState = result.top; } - var originalStream = highlightJS.nodeStream(line); + const originalStream = highlightJS.nodeStream(line); if (originalStream.length) { - var resultNode = document.createElementNS('http://www.w3.org/1999/xhtml', 'div'); + const resultNode = document.createElementNS("http://www.w3.org/1999/xhtml", "div"); resultNode.innerHTML = result.value; result.value = highlightJS.mergeStreams(originalStream, highlightJS.nodeStream(resultNode), text); } - $line.addClass('hljs'); + $line.addClass("hljs"); $line.addClass(result.language); $line.html(result.value); }); @@ -132,15 +136,15 @@ }; Diff2HtmlUI.prototype._getTarget = function(targetId) { - var $target; + let $target; - if (typeof targetId === 'object' && targetId instanceof jQuery) { + if (typeof targetId === "object" && targetId instanceof jQuery) { $target = targetId; - } else if (typeof targetId === 'string') { + } else if (typeof targetId === "string") { $target = $(targetId); } else { console.error("Wrong target provided! Falling back to default value 'body'."); - console.log('Please provide a jQuery object or a valid DOM query string.'); + console.log("Please provide a jQuery object or a valid DOM query string."); $target = $(defaultTarget); } @@ -148,10 +152,10 @@ }; Diff2HtmlUI.prototype._getHashTag = function() { - var docUrl = document.URL; - var hashTagIndex = docUrl.indexOf('#'); + const docUrl = document.URL; + const hashTagIndex = docUrl.indexOf("#"); - var hashTag = null; + let hashTag = null; if (hashTagIndex !== -1) { hashTag = docUrl.substr(hashTagIndex + 1); } @@ -166,46 +170,46 @@ }; Diff2HtmlUI.prototype._initSelection = function() { - var body = $('body'); - var that = this; + const body = $("body"); + const that = this; - body.on('mousedown', '.d2h-diff-table', function(event) { - var target = $(event.target); - var table = target.closest('.d2h-diff-table'); + body.on("mousedown", ".d2h-diff-table", function(event) { + const target = $(event.target); + const table = target.closest(".d2h-diff-table"); - if (target.closest('.d2h-code-line,.d2h-code-side-line').length) { - table.removeClass('selecting-left'); - table.addClass('selecting-right'); + if (target.closest(".d2h-code-line,.d2h-code-side-line").length) { + table.removeClass("selecting-left"); + table.addClass("selecting-right"); currentSelectionColumnId = 1; - } else if (target.closest('.d2h-code-linenumber,.d2h-code-side-linenumber').length) { - table.removeClass('selecting-right'); - table.addClass('selecting-left'); + } else if (target.closest(".d2h-code-linenumber,.d2h-code-side-linenumber").length) { + table.removeClass("selecting-right"); + table.addClass("selecting-left"); currentSelectionColumnId = 0; } }); - body.on('copy', '.d2h-diff-table', function(event) { - var clipboardData = event.originalEvent.clipboardData; - var text = that._getSelectedText(); - clipboardData.setData('text', text); + body.on("copy", ".d2h-diff-table", function(event) { + const clipboardData = event.originalEvent.clipboardData; + const text = that._getSelectedText(); + clipboardData.setData("text", text); event.preventDefault(); }); }; Diff2HtmlUI.prototype._getSelectedText = function() { - var sel = window.getSelection(); - var range = sel.getRangeAt(0); - var doc = range.cloneContents(); - var nodes = doc.querySelectorAll('tr'); - var text = ''; - var idx = currentSelectionColumnId; + const sel = window.getSelection(); + const range = sel.getRangeAt(0); + const doc = range.cloneContents(); + const nodes = doc.querySelectorAll("tr"); + let text = ""; + const idx = currentSelectionColumnId; if (nodes.length === 0) { text = doc.textContent; } else { [].forEach.call(nodes, function(tr, i) { - var td = tr.cells[tr.cells.length === 1 ? 0 : idx]; - text += (i ? '\n' : '') + td.textContent.replace(/(?:\r\n|\r|\n)/g, ''); + const td = tr.cells[tr.cells.length === 1 ? 0 : idx]; + text += (i ? "\n" : "") + td.textContent.replace(/(?:\r\n|\r|\n)/g, ""); }); } diff --git a/src/ui/js/highlight.js-internals.js b/src/ui/js/highlight.js-internals.js index 52a1ccd..3bf89f0 100644 --- a/src/ui/js/highlight.js-internals.js +++ b/src/ui/js/highlight.js-internals.js @@ -6,8 +6,7 @@ */ (function() { - function HighlightJS() { - } + function HighlightJS() {} /* * Copied from Highlight.js Private API @@ -16,12 +15,15 @@ /* Utility vars */ - var ArrayProto = []; + const ArrayProto = []; /* Utility functions */ function escape(value) { - return value.replace(/&/gm, '&').replace(//gm, '>'); + return value + .replace(/&/gm, "&") + .replace(//gm, ">"); } function tag(node) { @@ -31,14 +33,14 @@ /* Stream merging */ HighlightJS.prototype.nodeStream = function(node) { - var result = []; + const result = []; (function _nodeStream(node, offset) { - for (var child = node.firstChild; child; child = child.nextSibling) { + for (let child = node.firstChild; child; child = child.nextSibling) { if (child.nodeType === 3) { offset += child.nodeValue.length; } else if (child.nodeType === 1) { result.push({ - event: 'start', + event: "start", offset: offset, node: child }); @@ -48,7 +50,7 @@ // but we list only those realistically expected in code display. if (!tag(child).match(/br|hr|img|input/)) { result.push({ - event: 'stop', + event: "stop", offset: offset, node: child }); @@ -61,16 +63,16 @@ }; HighlightJS.prototype.mergeStreams = function(original, highlighted, value) { - var processed = 0; - var result = ''; - var nodeStack = []; + let processed = 0; + let result = ""; + const nodeStack = []; function selectStream() { if (!original.length || !highlighted.length) { return original.length ? original : highlighted; } if (original[0].offset !== highlighted[0].offset) { - return (original[0].offset < highlighted[0].offset) ? original : highlighted; + return original[0].offset < highlighted[0].offset ? original : highlighted; } /* @@ -86,27 +88,27 @@ return highlighted; ... which is collapsed to: */ - return highlighted[0].event === 'start' ? original : highlighted; + return highlighted[0].event === "start" ? original : highlighted; } function open(node) { function attr_str(a) { - return ' ' + a.nodeName + '="' + escape(a.value) + '"'; + return " " + a.nodeName + '="' + escape(a.value) + '"'; } - result += '<' + tag(node) + ArrayProto.map.call(node.attributes, attr_str).join('') + '>'; + result += "<" + tag(node) + ArrayProto.map.call(node.attributes, attr_str).join("") + ">"; } function close(node) { - result += ''; + result += ""; } function render(event) { - (event.event === 'start' ? open : close)(event.node); + (event.event === "start" ? open : close)(event.node); } while (original.length || highlighted.length) { - var stream = selectStream(); + let stream = selectStream(); result += escape(value.substring(processed, stream[0].offset)); processed = stream[0].offset; if (stream === original) { @@ -123,7 +125,7 @@ } while (stream === original && stream.length && stream[0].offset === processed); nodeStack.reverse().forEach(open); } else { - if (stream[0].event === 'start') { + if (stream[0].event === "start") { nodeStack.push(stream[0].node); } else { nodeStack.pop(); diff --git a/src/utils.js b/src/utils.js index 395d267..4b62912 100644 --- a/src/utils.js +++ b/src/utils.js @@ -6,24 +6,24 @@ */ (function() { - var merge = require('merge'); + const merge = require("merge"); - function Utils() { - } + function Utils() {} Utils.prototype.escape = function(str) { - return str.slice(0) - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, ''') - .replace(/\//g, '/'); + return str + .slice(0) + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'") + .replace(/\//g, "/"); }; Utils.prototype.startsWith = function(str, start) { - if (typeof start === 'object') { - var result = false; + if (typeof start === "object") { + let result = false; start.forEach(function(s) { if (str.indexOf(s) === 0) { result = true; @@ -37,7 +37,7 @@ }; Utils.prototype.valueOrEmpty = function(value) { - return value || ''; + return value || ""; }; Utils.prototype.safeConfig = function(cfg, defaultConfig) { diff --git a/test/diff-parser-tests.js b/test/diff-parser-tests.js deleted file mode 100644 index 2574c19..0000000 --- a/test/diff-parser-tests.js +++ /dev/null @@ -1,743 +0,0 @@ -var assert = require('assert'); - -var DiffParser = require('../src/diff-parser.js').DiffParser; - -describe('DiffParser', function() { - describe('generateDiffJson', function() { - it('should parse unix with \n diff', function() { - var diff = - 'diff --git a/sample b/sample\n' + - 'index 0000001..0ddf2ba\n' + - '--- a/sample\n' + - '+++ b/sample\n' + - '@@ -1 +1 @@\n' + - '-test\n' + - '+test1r\n'; - checkDiffSample(diff); - }); - - it('should parse windows with \r\n diff', function() { - var diff = - 'diff --git a/sample b/sample\r\n' + - 'index 0000001..0ddf2ba\r\n' + - '--- a/sample\r\n' + - '+++ b/sample\r\n' + - '@@ -1 +1 @@\r\n' + - '-test\r\n' + - '+test1r\r\n'; - checkDiffSample(diff); - }); - - it('should parse old os x with \r diff', function() { - var diff = - 'diff --git a/sample b/sample\r' + - 'index 0000001..0ddf2ba\r' + - '--- a/sample\r' + - '+++ b/sample\r' + - '@@ -1 +1 @@\r' + - '-test\r' + - '+test1r\r'; - checkDiffSample(diff); - }); - - it('should parse mixed eols diff', function() { - var diff = - 'diff --git a/sample b/sample\n' + - 'index 0000001..0ddf2ba\r\n' + - '--- a/sample\r' + - '+++ b/sample\r\n' + - '@@ -1 +1 @@\n' + - '-test\r' + - '+test1r\n'; - checkDiffSample(diff); - }); - - function checkDiffSample(diff) { - var result = DiffParser.generateDiffJson(diff); - var file1 = result[0]; - assert.equal(1, result.length); - assert.equal(1, file1.addedLines); - assert.equal(1, file1.deletedLines); - assert.equal('sample', file1.oldName); - assert.equal('sample', file1.newName); - assert.equal(1, file1.blocks.length); - } - - it('should parse diff with special characters', function() { - var diff = - 'diff --git "a/bla with \ttab.scala" "b/bla with \ttab.scala"\n' + - 'index 4c679d7..e9bd385 100644\n' + - '--- "a/bla with \ttab.scala"\n' + - '+++ "b/bla with \ttab.scala"\n' + - '@@ -1 +1,2 @@\n' + - '-cenas\n' + - '+cenas com ananas\n' + - '+bananas'; - - var result = DiffParser.generateDiffJson(diff); - var file1 = result[0]; - assert.equal(1, result.length); - assert.equal(2, file1.addedLines); - assert.equal(1, file1.deletedLines); - assert.equal('bla with \ttab.scala', file1.oldName); - assert.equal('bla with \ttab.scala', file1.newName); - assert.equal(1, file1.blocks.length); - }); - - it('should parse diff with prefix', function() { - var diff = - 'diff --git "\tbla with \ttab.scala" "\tbla with \ttab.scala"\n' + - 'index 4c679d7..e9bd385 100644\n' + - '--- "\tbla with \ttab.scala"\n' + - '+++ "\tbla with \ttab.scala"\n' + - '@@ -1 +1,2 @@\n' + - '-cenas\n' + - '+cenas com ananas\n' + - '+bananas'; - - var result = DiffParser.generateDiffJson(diff, {'srcPrefix': '\t', 'dstPrefix': '\t'}); - var file1 = result[0]; - assert.equal(1, result.length); - assert.equal(2, file1.addedLines); - assert.equal(1, file1.deletedLines); - assert.equal('bla with \ttab.scala', file1.oldName); - assert.equal('bla with \ttab.scala', file1.newName); - assert.equal(1, file1.blocks.length); - }); - - it('should parse diff with deleted file', function() { - var diff = - 'diff --git a/src/var/strundefined.js b/src/var/strundefined.js\n' + - 'deleted file mode 100644\n' + - 'index 04e16b0..0000000\n' + - '--- a/src/var/strundefined.js\n' + - '+++ /dev/null\n' + - '@@ -1,3 +0,0 @@\n' + - '-define(function() {\n' + - '- return typeof undefined;\n' + - '-});\n'; - - var result = DiffParser.generateDiffJson(diff); - assert.equal(1, result.length); - - var file1 = result[0]; - assert.equal(false, file1.isCombined); - assert.equal(0, file1.addedLines); - assert.equal(3, file1.deletedLines); - assert.equal('src/var/strundefined.js', file1.oldName); - assert.equal('/dev/null', file1.newName); - assert.equal(1, file1.blocks.length); - assert.equal(true, file1.isDeleted); - assert.equal('04e16b0', file1.checksumBefore); - assert.equal('0000000', file1.checksumAfter); - }); - - it('should parse diff with new file', function() { - var diff = - 'diff --git a/test.js b/test.js\n' + - 'new file mode 100644\n' + - 'index 0000000..e1e22ec\n' + - '--- /dev/null\n' + - '+++ b/test.js\n' + - '@@ -0,0 +1,5 @@\n' + - "+var parser = require('./source/git-parser');\n" + - '+\n' + - '+var patchLineList = [ false, false, false, false ];\n' + - '+\n' + - '+console.log(parser.parsePatchDiffResult(text, patchLineList));\n'; - - var result = DiffParser.generateDiffJson(diff); - assert.equal(1, result.length); - - var file1 = result[0]; - assert.equal(false, file1.isCombined); - assert.equal(5, file1.addedLines); - assert.equal(0, file1.deletedLines); - assert.equal('/dev/null', file1.oldName); - assert.equal('test.js', file1.newName); - assert.equal(1, file1.blocks.length); - assert.equal(true, file1.isNew); - assert.equal(100644, file1.newFileMode); - assert.equal('0000000', file1.checksumBefore); - assert.equal('e1e22ec', file1.checksumAfter); - }); - - it('should parse diff with nested diff', function() { - var diff = - 'diff --git a/src/offset.js b/src/offset.js\n' + - 'index cc6ffb4..fa51f18 100644\n' + - '--- a/src/offset.js\n' + - '+++ b/src/offset.js\n' + - '@@ -1,6 +1,5 @@\n' + - "+var parser = require('./source/git-parser');\n" + - '+\n' + - "+var text = 'diff --git a/components/app/app.html b/components/app/app.html\\nindex ecb7a95..027bd9b 100644\\n--- a/components/app/app.html\\n+++ b/components/app/app.html\\n@@ -52,0 +53,3 @@\\n+\\n+\\n+\\n@@ -56,0 +60,3 @@\\n+\\n+\\n+\\n'\n" + - '+var patchLineList = [ false, false, false, false ];\n' + - '+\n' + - '+console.log(parser.parsePatchDiffResult(text, patchLineList));\n'; - - var result = DiffParser.generateDiffJson(diff); - assert.equal(1, result.length); - - var file1 = result[0]; - assert.equal(false, file1.isCombined); - assert.equal(6, file1.addedLines); - assert.equal(0, file1.deletedLines); - assert.equal('src/offset.js', file1.oldName); - assert.equal('src/offset.js', file1.newName); - assert.equal(1, file1.blocks.length); - assert.equal(6, file1.blocks[0].lines.length); - assert.equal('cc6ffb4', file1.checksumBefore); - assert.equal('fa51f18', file1.checksumAfter); - }); - - it('should parse diff with multiple blocks', function() { - var diff = - 'diff --git a/src/attributes/classes.js b/src/attributes/classes.js\n' + - 'index c617824..c8d1393 100644\n' + - '--- a/src/attributes/classes.js\n' + - '+++ b/src/attributes/classes.js\n' + - '@@ -1,10 +1,9 @@\n' + - ' define([\n' + - ' "../core",\n' + - ' "../var/rnotwhite",\n' + - '- "../var/strundefined",\n' + - ' "../data/var/dataPriv",\n' + - ' "../core/init"\n' + - '-], function( jQuery, rnotwhite, strundefined, dataPriv ) {\n' + - '+], function( jQuery, rnotwhite, dataPriv ) {\n' + - ' \n' + - ' var rclass = /[\\t\\r\\n\\f]/g;\n' + - ' \n' + - '@@ -128,7 +127,7 @@ jQuery.fn.extend({\n' + - ' }\n' + - ' \n' + - ' // Toggle whole class name\n' + - '- } else if ( type === strundefined || type === "boolean" ) {\n' + - '+ } else if ( value === undefined || type === "boolean" ) {\n' + - ' if ( this.className ) {\n' + - ' // store className if set\n' + - ' dataPriv.set( this, "__className__", this.className );\n'; - - var result = DiffParser.generateDiffJson(diff); - assert.equal(1, result.length); - - var file1 = result[0]; - assert.equal(false, file1.isCombined); - assert.equal(2, file1.addedLines); - assert.equal(3, file1.deletedLines); - assert.equal('src/attributes/classes.js', file1.oldName); - assert.equal('src/attributes/classes.js', file1.newName); - assert.equal(2, file1.blocks.length); - assert.equal(11, file1.blocks[0].lines.length); - assert.equal(8, file1.blocks[1].lines.length); - assert.equal('c617824', file1.checksumBefore); - assert.equal('c8d1393', file1.checksumAfter); - }); - - it('should parse diff with multiple files', function() { - var diff = - 'diff --git a/src/core/init.js b/src/core/init.js\n' + - 'index e49196a..50f310c 100644\n' + - '--- a/src/core/init.js\n' + - '+++ b/src/core/init.js\n' + - '@@ -101,7 +101,7 @@ var rootjQuery,\n' + - ' // HANDLE: $(function)\n' + - ' // Shortcut for document ready\n' + - ' } else if ( jQuery.isFunction( selector ) ) {\n' + - '- return typeof rootjQuery.ready !== "undefined" ?\n' + - '+ return rootjQuery.ready !== undefined ?\n' + - ' rootjQuery.ready( selector ) :\n' + - ' // Execute immediately if ready is not present\n' + - ' selector( jQuery );\n' + - 'diff --git a/src/event.js b/src/event.js\n' + - 'index 7336f4d..6183f70 100644\n' + - '--- a/src/event.js\n' + - '+++ b/src/event.js\n' + - '@@ -1,6 +1,5 @@\n' + - ' define([\n' + - ' "./core",\n' + - '- "./var/strundefined",\n' + - ' "./var/rnotwhite",\n' + - ' "./var/hasOwn",\n' + - ' "./var/slice",\n'; - - var result = DiffParser.generateDiffJson(diff); - assert.equal(2, result.length); - - var file1 = result[0]; - assert.equal(false, file1.isCombined); - assert.equal(1, file1.addedLines); - assert.equal(1, file1.deletedLines); - assert.equal('src/core/init.js', file1.oldName); - assert.equal('src/core/init.js', file1.newName); - assert.equal(1, file1.blocks.length); - assert.equal(8, file1.blocks[0].lines.length); - assert.equal('e49196a', file1.checksumBefore); - assert.equal('50f310c', file1.checksumAfter); - - var file2 = result[1]; - assert.equal(false, file2.isCombined); - assert.equal(0, file2.addedLines); - assert.equal(1, file2.deletedLines); - assert.equal('src/event.js', file2.oldName); - assert.equal('src/event.js', file2.newName); - assert.equal(1, file2.blocks.length); - assert.equal(6, file2.blocks[0].lines.length); - assert.equal('7336f4d', file2.checksumBefore); - assert.equal('6183f70', file2.checksumAfter); - }); - - it('should parse combined diff', function() { - var diff = - 'diff --combined describe.c\n' + - 'index fabadb8,cc95eb0..4866510\n' + - '--- a/describe.c\n' + - '+++ b/describe.c\n' + - '@@@ -98,20 -98,12 +98,20 @@@\n' + - ' return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;\n' + - ' }\n' + - ' \n' + - '- static void describe(char *arg)\n' + - ' -static void describe(struct commit *cmit, int last_one)\n' + - '++static void describe(char *arg, int last_one)\n' + - ' {\n' + - ' + unsigned char sha1[20];\n' + - ' + struct commit *cmit;\n' + - ' struct commit_list *list;\n' + - ' static int initialized = 0;\n' + - ' struct commit_name *n;\n' + - ' \n' + - ' + if (get_sha1(arg, sha1) < 0)\n' + - ' + usage(describe_usage);\n' + - ' + cmit = lookup_commit_reference(sha1);\n' + - ' + if (!cmit)\n' + - ' + usage(describe_usage);\n' + - ' +\n' + - ' if (!initialized) {\n' + - ' initialized = 1;\n' + - ' for_each_ref(get_name);\n'; - - var result = DiffParser.generateDiffJson(diff); - assert.equal(1, result.length); - - var file1 = result[0]; - assert.equal(true, file1.isCombined); - assert.equal(9, file1.addedLines); - assert.equal(2, file1.deletedLines); - assert.equal('describe.c', file1.oldName); - assert.equal('describe.c', file1.newName); - assert.equal(1, file1.blocks.length); - assert.equal(22, file1.blocks[0].lines.length); - assert.deepEqual(['4866510', 'cc95eb0'].sort(), file1.checksumBefore.sort()); - assert.equal('fabadb8', file1.checksumAfter); - }); - - it('should parse diffs with copied files', function() { - var diff = - 'diff --git a/index.js b/more-index.js\n' + - 'dissimilarity index 5%\n' + - 'copy from index.js\n' + - 'copy to more-index.js\n'; - - var result = DiffParser.generateDiffJson(diff); - assert.equal(1, result.length); - - var file1 = result[0]; - assert.equal(0, file1.addedLines); - assert.equal(0, file1.deletedLines); - assert.equal('index.js', file1.oldName); - assert.equal('more-index.js', file1.newName); - assert.equal(0, file1.blocks.length); - assert.equal(true, file1.isCopy); - assert.equal(5, file1.changedPercentage); - }); - - it('should parse diffs with moved files', function() { - var diff = - 'diff --git a/more-index.js b/other-index.js\n' + - 'similarity index 86%\n' + - 'rename from more-index.js\n' + - 'rename to other-index.js\n'; - - var result = DiffParser.generateDiffJson(diff); - assert.equal(1, result.length); - - var file1 = result[0]; - assert.equal(0, file1.addedLines); - assert.equal(0, file1.deletedLines); - assert.equal('more-index.js', file1.oldName); - assert.equal('other-index.js', file1.newName); - assert.equal(0, file1.blocks.length); - assert.equal(true, file1.isRename); - assert.equal(86, file1.unchangedPercentage); - }); - - it('should parse diffs correct line numbers', function() { - var diff = - 'diff --git a/sample b/sample\n' + - 'index 0000001..0ddf2ba\n' + - '--- a/sample\n' + - '+++ b/sample\n' + - '@@ -1 +1,2 @@\n' + - '-test\n' + - '+test1r\n'; - - var result = DiffParser.generateDiffJson(diff); - assert.equal(1, result.length); - - var file1 = result[0]; - assert.equal(1, file1.addedLines); - assert.equal(1, file1.deletedLines); - assert.equal('sample', file1.oldName); - assert.equal('sample', file1.newName); - assert.equal(1, file1.blocks.length); - assert.equal(2, file1.blocks[0].lines.length); - assert.equal(1, file1.blocks[0].lines[0].oldNumber); - assert.equal(null, file1.blocks[0].lines[0].newNumber); - assert.equal(null, file1.blocks[0].lines[1].oldNumber); - assert.equal(1, file1.blocks[0].lines[1].newNumber); - }); - - it('should parse unified non git diff and strip timestamps off the headers', function() { - var diffs = [ - // 2 hours ahead of GMT - '--- a/sample.js 2016-10-25 11:37:14.000000000 +0200\n' + - '+++ b/sample.js 2016-10-25 11:37:14.000000000 +0200\n' + - '@@ -1 +1,2 @@\n' + - '-test\n' + - '+test1r\n' + - '+test2r\n', - // 2 hours behind GMT - '--- a/sample.js 2016-10-25 11:37:14.000000000 -0200\n' + - '+++ b/sample.js 2016-10-25 11:37:14.000000000 -0200\n' + - '@@ -1 +1,2 @@\n' + - '-test\n' + - '+test1r\n' + - '+test2r\n' - ]; - - diffs.forEach(function(diff) { - var result = DiffParser.generateDiffJson(diff); - var file1 = result[0]; - assert.equal(1, result.length); - assert.equal(2, file1.addedLines); - assert.equal(1, file1.deletedLines); - assert.equal('sample.js', file1.oldName); - assert.equal('sample.js', file1.newName); - assert.equal(1, file1.blocks.length); - - var linesContent = file1.blocks[0].lines.map(function(line) { - return line.content; - }); - assert.deepEqual(linesContent, ['-test', '+test1r', '+test2r']); - }); - }); - - it('should parse unified non git diff', function() { - var diff = - '--- a/sample.js\n' + - '+++ b/sample.js\n' + - '@@ -1 +1,2 @@\n' + - '-test\n' + - '+test1r\n' + - '+test2r\n'; - - var result = DiffParser.generateDiffJson(diff); - var file1 = result[0]; - assert.equal(1, result.length); - assert.equal(2, file1.addedLines); - assert.equal(1, file1.deletedLines); - assert.equal('sample.js', file1.oldName); - assert.equal('sample.js', file1.newName); - assert.equal(1, file1.blocks.length); - - var linesContent = file1.blocks[0].lines.map(function(line) { - return line.content; - }); - assert.deepEqual(linesContent, ['-test', '+test1r', '+test2r']); - }); - - it('should parse unified diff with multiple hunks and files', function() { - var diff = - '--- sample.js\n' + - '+++ sample.js\n' + - '@@ -1 +1,2 @@\n' + - '-test\n' + - '@@ -10 +20,2 @@\n' + - '+test\n' + - '--- sample1.js\n' + - '+++ sample1.js\n' + - '@@ -1 +1,2 @@\n' + - '+test1'; - - var result = DiffParser.generateDiffJson(diff); - assert.equal(2, result.length); - - var file1 = result[0]; - assert.equal(1, file1.addedLines); - assert.equal(1, file1.deletedLines); - assert.equal('sample.js', file1.oldName); - assert.equal('sample.js', file1.newName); - assert.equal(2, file1.blocks.length); - - var linesContent1 = file1.blocks[0].lines.map(function(line) { - return line.content; - }); - assert.deepEqual(linesContent1, ['-test']); - - var linesContent2 = file1.blocks[1].lines.map(function(line) { - return line.content; - }); - assert.deepEqual(linesContent2, ['+test']); - - var file2 = result[1]; - assert.equal(1, file2.addedLines); - assert.equal(0, file2.deletedLines); - assert.equal('sample1.js', file2.oldName); - assert.equal('sample1.js', file2.newName); - assert.equal(1, file2.blocks.length); - - var linesContent = file2.blocks[0].lines.map(function(line) { - return line.content; - }); - assert.deepEqual(linesContent, ['+test1']); - }); - - it('should parse diff with --- and +++ in the context lines', function() { - var diff = - '--- sample.js\n' + - '+++ sample.js\n' + - '@@ -1,8 +1,8 @@\n' + - ' test\n' + - ' \n' + - '-- 1\n' + - '--- 1\n' + - '---- 1\n' + - ' \n' + - '++ 2\n' + - '+++ 2\n' + - '++++ 2'; - - var result = DiffParser.generateDiffJson(diff); - var file1 = result[0]; - assert.equal(1, result.length); - assert.equal(3, file1.addedLines); - assert.equal(3, file1.deletedLines); - assert.equal('sample.js', file1.oldName); - assert.equal('sample.js', file1.newName); - assert.equal(1, file1.blocks.length); - - var linesContent = file1.blocks[0].lines.map(function(line) { - return line.content; - }); - assert.deepEqual(linesContent, - [' test', ' ', '-- 1', '--- 1', '---- 1', ' ', '++ 2', '+++ 2', '++++ 2']); - }); - - it('should parse diff without proper hunk headers', function() { - var diff = - '--- sample.js\n' + - '+++ sample.js\n' + - '@@ @@\n' + - ' test'; - - var result = DiffParser.generateDiffJson(diff); - var file1 = result[0]; - assert.equal(1, result.length); - assert.equal(0, file1.addedLines); - assert.equal(0, file1.deletedLines); - assert.equal('sample.js', file1.oldName); - assert.equal('sample.js', file1.newName); - assert.equal(1, file1.blocks.length); - - var linesContent = file1.blocks[0].lines.map(function(line) { - return line.content; - }); - assert.deepEqual(linesContent, [' test']); - }); - - it('should parse binary file diff', function() { - var diff = - 'diff --git a/last-changes-config.png b/last-changes-config.png\n' + - 'index 322248b..56fc1f2 100644\n' + - '--- a/last-changes-config.png\n' + - '+++ b/last-changes-config.png\n' + - 'Binary files differ'; - - var result = DiffParser.generateDiffJson(diff); - var file1 = result[0]; - assert.equal(1, result.length); - assert.equal(0, file1.addedLines); - assert.equal(0, file1.deletedLines); - assert.equal('last-changes-config.png', file1.oldName); - assert.equal('last-changes-config.png', file1.newName); - assert.equal(1, file1.blocks.length); - assert.equal(0, file1.blocks[0].lines.length); - assert.equal('Binary files differ', file1.blocks[0].header); - }); - - it('should parse diff with --find-renames', function() { - var diff = - 'diff --git a/src/test-bar.js b/src/test-baz.js\n' + - 'similarity index 98%\n' + - 'rename from src/test-bar.js\n' + - 'rename to src/test-baz.js\n' + - 'index e01513b..f14a870 100644\n' + - '--- a/src/test-bar.js\n' + - '+++ b/src/test-baz.js\n' + - '@@ -1,4 +1,32 @@\n' + - ' function foo() {\n' + - '-var bar = "Whoops!";\n' + - '+var baz = "Whoops!";\n' + - ' }\n' + - ' '; - - var result = DiffParser.generateDiffJson(diff); - var file1 = result[0]; - assert.equal(1, result.length); - assert.equal(1, file1.addedLines); - assert.equal(1, file1.deletedLines); - assert.equal('src/test-bar.js', file1.oldName); - assert.equal('src/test-baz.js', file1.newName); - assert.equal(1, file1.blocks.length); - assert.equal(5, file1.blocks[0].lines.length); - var linesContent = file1.blocks[0].lines.map(function(line) { - return line.content; - }); - assert.deepEqual(linesContent, - [' function foo() {', '-var bar = "Whoops!";', '+var baz = "Whoops!";', ' }', ' ']); - }); - - it('should parse diff with prefix', function() { - var diff = - 'diff --git "\tTest.scala" "\tScalaTest.scala"\n' + - 'similarity index 88%\n' + - 'rename from Test.scala\n' + - 'rename to ScalaTest.scala\n' + - 'index 7d1f9bf..8b13271 100644\n' + - '--- "\tTest.scala"\n' + - '+++ "\tScalaTest.scala"\n' + - '@@ -1,6 +1,8 @@\n' + - ' class Test {\n' + - ' \n' + - ' def method1 = ???\n' + - '+\n' + - '+ def method2 = ???\n' + - ' \n' + - ' def myMethod = ???\n' + - ' \n' + - '@@ -10,7 +12,6 @@ class Test {\n' + - ' \n' + - ' def + = ???\n' + - ' \n' + - '- def |> = ???\n' + - ' \n' + - ' }\n' + - ' \n' + - 'diff --git "\ttardis.png" "\ttardis.png"\n' + - 'new file mode 100644\n' + - 'index 0000000..d503a29\n' + - 'Binary files /dev/null and "\ttardis.png" differ\n' + - 'diff --git a/src/test-bar.js b/src/test-baz.js\n' + - 'similarity index 98%\n' + - 'rename from src/test-bar.js\n' + - 'rename to src/test-baz.js\n' + - 'index e01513b..f14a870 100644\n' + - '--- a/src/test-bar.js\n' + - '+++ b/src/test-baz.js\n' + - '@@ -1,4 +1,32 @@\n' + - ' function foo() {\n' + - '-var bar = "Whoops!";\n' + - '+var baz = "Whoops!";\n' + - ' }\n' + - ' '; - - var result = DiffParser.generateDiffJson(diff, {'srcPrefix': '\t', 'dstPrefix': '\t'}); - assert.equal(3, result.length); - - var file1 = result[0]; - assert.equal(2, file1.addedLines); - assert.equal(1, file1.deletedLines); - assert.equal('Test.scala', file1.oldName); - assert.equal('ScalaTest.scala', file1.newName); - assert.equal(2, file1.blocks.length); - assert.equal(8, file1.blocks[0].lines.length); - assert.equal(7, file1.blocks[1].lines.length); - - var file2 = result[1]; - assert.equal('/dev/null', file2.oldName); - assert.equal('tardis.png', file2.newName); - - var file3 = result[2]; - assert.equal(1, file3.addedLines); - assert.equal(1, file3.deletedLines); - assert.equal('src/test-bar.js', file3.oldName); - assert.equal('src/test-baz.js', file3.newName); - assert.equal(1, file3.blocks.length); - assert.equal(5, file3.blocks[0].lines.length); - var linesContent = file3.blocks[0].lines.map(function(line) { - return line.content; - }); - assert.deepEqual(linesContent, - [' function foo() {', '-var bar = "Whoops!";', '+var baz = "Whoops!";', ' }', ' ']); - }); - - it('should parse binary with content', function() { - var diff = - 'diff --git a/favicon.png b/favicon.png\n' + - 'deleted file mode 100644\n' + - 'index 2a9d516a5647205d7be510dd0dff93a3663eff6f..0000000000000000000000000000000000000000\n' + - 'GIT binary patch\n' + - 'literal 0\n' + - 'HcmV?d00001\n' + - '\n' + - 'literal 471\n' + - 'zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf4nJ\n' + - 'za0`JjqPVOAS4ANVKzqmCp=Cty@U^(7zk!jHsvT~YI{F^=Ex6g|gox78w\n' + - 'z+Sn2Du3GS9U7qU`1*NYYlJi3u-!-_B#8k9H0\n' + - 'zGl{FnZs<2$wz5^=Q2h-1XI^s{LQL1#T4epqNPC%Orl(tD_@!*EY++~^Lt2<2&!&%=\n' + - 'z`m>(TYj6uS7jDdt=eH>iOyQg(QMR<-Fw8)Dk^ZG)XQTuzEgl{`GpS?Cfq9818R9~=\n' + - 'z{&h9@9n8F^?|qusoPy{k#%tVHzu7H$t26CR`BJZk*Ixf&u36WuS=?6m2^ho-p00i_\n' + - 'I>zopr0Nz-&lmGw#\n' + - 'diff --git a/src/test-bar.js b/src/test-baz.js\n' + - 'similarity index 98%\n' + - 'rename from src/test-bar.js\n' + - 'rename to src/test-baz.js\n' + - 'index e01513b..f14a870 100644\n' + - '--- a/src/test-bar.js\n' + - '+++ b/src/test-baz.js\n' + - '@@ -1,4 +1,32 @@\n' + - ' function foo() {\n' + - '-var bar = "Whoops!";\n' + - '+var baz = "Whoops!";\n' + - ' }\n' + - ' '; - - var result = DiffParser.generateDiffJson(diff); - assert.equal(2, result.length); - - var file1 = result[0]; - assert.equal('favicon.png', file1.oldName); - assert.equal('favicon.png', file1.newName); - assert.equal(1, file1.blocks.length); - assert.equal(0, file1.blocks[0].lines.length); - - var file2 = result[1]; - assert.equal(1, file2.addedLines); - assert.equal(1, file2.deletedLines); - assert.equal('src/test-bar.js', file2.oldName); - assert.equal('src/test-baz.js', file2.newName); - assert.equal(1, file2.blocks.length); - assert.equal(5, file2.blocks[0].lines.length); - var linesContent = file2.blocks[0].lines.map(function(line) { - return line.content; - }); - assert.deepEqual(linesContent, - [' function foo() {', '-var bar = "Whoops!";', '+var baz = "Whoops!";', ' }', ' ']); - }); - }); -}); diff --git a/test/hogan-cache-tests.js b/test/hogan-cache-tests.js deleted file mode 100644 index a34839c..0000000 --- a/test/hogan-cache-tests.js +++ /dev/null @@ -1,70 +0,0 @@ -var assert = require('assert'); - -var HoganJsUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)(); -var diffParser = require('../src/diff-parser.js').DiffParser; - -describe('HoganJsUtils', function() { - describe('render', function() { - var emptyDiffHtml = - '\n' + - ' \n' + - '
    \n' + - ' File without changes\n' + - '
    \n' + - ' \n' + - ''; - - it('should render view', function() { - var result = HoganJsUtils.render('generic', 'empty-diff', { - contentClass: 'd2h-code-line', - diffParser: diffParser - }); - assert.equal(emptyDiffHtml, result); - }); - - it('should render view without cache', function() { - var result = HoganJsUtils.render('generic', 'empty-diff', { - contentClass: 'd2h-code-line', - diffParser: diffParser - }, {noCache: true}); - assert.equal(emptyDiffHtml, result); - }); - - it('should return null if template is missing', function() { - var hoganUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)({noCache: true}); - var result = hoganUtils.render('generic', 'missing-template', {}); - assert.equal(null, result); - }); - - it('should allow templates to be overridden with compiled templates', function() { - var emptyDiffTemplate = HoganJsUtils.compile('

    {{myName}}

    '); - - var config = {templates: {'generic-empty-diff': emptyDiffTemplate}}; - var hoganUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)(config); - var result = hoganUtils.render('generic', 'empty-diff', {myName: 'Rodrigo Fernandes'}); - assert.equal('

    Rodrigo Fernandes

    ', result); - }); - - it('should allow templates to be overridden with uncompiled templates', function() { - var emptyDiffTemplate = '

    {{myName}}

    '; - - var config = {rawTemplates: {'generic-empty-diff': emptyDiffTemplate}}; - var hoganUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)(config); - var result = hoganUtils.render('generic', 'empty-diff', {myName: 'Rodrigo Fernandes'}); - assert.equal('

    Rodrigo Fernandes

    ', result); - }); - - it('should allow templates to be overridden giving priority to compiled templates', function() { - var emptyDiffTemplate = HoganJsUtils.compile('

    {{myName}}

    '); - var emptyDiffTemplateUncompiled = '

    Not used!

    '; - - var config = { - templates: {'generic-empty-diff': emptyDiffTemplate}, - rawTemplates: {'generic-empty-diff': emptyDiffTemplateUncompiled} - }; - var hoganUtils = new (require('../src/hoganjs-utils.js').HoganJsUtils)(config); - var result = hoganUtils.render('generic', 'empty-diff', {myName: 'Rodrigo Fernandes'}); - assert.equal('

    Rodrigo Fernandes

    ', result); - }); - }); -}); diff --git a/test/printer-utils-tests.js b/test/printer-utils-tests.js deleted file mode 100644 index b3c8213..0000000 --- a/test/printer-utils-tests.js +++ /dev/null @@ -1,140 +0,0 @@ -var assert = require('assert'); - -var PrinterUtils = require('../src/printer-utils.js').PrinterUtils; - -describe('Utils', function() { - describe('getHtmlId', function() { - it('should generate file unique id', function() { - var result = PrinterUtils.getHtmlId({ - oldName: 'sample.js', - newName: 'sample.js' - }); - assert.equal('d2h-960013', result); - }); - it('should generate file unique id for empty hashes', function() { - var result = PrinterUtils.getHtmlId({ - oldName: 'sample.js', - newName: 'sample.js' - }); - assert.equal('d2h-960013', result); - }); - }); - - describe('getDiffName', function() { - it('should generate the file name for a changed file', function() { - var result = PrinterUtils.getDiffName({ - oldName: 'sample.js', - newName: 'sample.js' - }); - assert.equal('sample.js', result); - }); - it('should generate the file name for a changed file and full rename', function() { - var result = PrinterUtils.getDiffName({ - oldName: 'sample1.js', - newName: 'sample2.js' - }); - assert.equal('sample1.js → sample2.js', result); - }); - it('should generate the file name for a changed file and prefix rename', function() { - var result = PrinterUtils.getDiffName({ - oldName: 'src/path/sample.js', - newName: 'source/path/sample.js' - }); - assert.equal('{src → source}/path/sample.js', result); - }); - it('should generate the file name for a changed file and suffix rename', function() { - var result = PrinterUtils.getDiffName({ - oldName: 'src/path/sample1.js', - newName: 'src/path/sample2.js' - }); - assert.equal('src/path/{sample1.js → sample2.js}', result); - }); - it('should generate the file name for a changed file and middle rename', function() { - var result = PrinterUtils.getDiffName({ - oldName: 'src/really/big/path/sample.js', - newName: 'src/small/path/sample.js' - }); - assert.equal('src/{really/big → small}/path/sample.js', result); - }); - it('should generate the file name for a deleted file', function() { - var result = PrinterUtils.getDiffName({ - oldName: 'src/my/file.js', - newName: '/dev/null' - }); - assert.equal('src/my/file.js', result); - }); - it('should generate the file name for a new file', function() { - var result = PrinterUtils.getDiffName({ - oldName: '/dev/null', - newName: 'src/my/file.js' - }); - assert.equal('src/my/file.js', result); - }); - it('should generate handle undefined filename', function() { - var result = PrinterUtils.getDiffName({}); - assert.equal('unknown/file/path', result); - }); - }); - - describe('diffHighlight', function() { - it('should highlight two lines', function() { - var result = PrinterUtils.diffHighlight( - '-var myVar = 2;', - '+var myVariable = 3;', - {matching: 'words'} - ); - - assert.deepEqual({ - first: { - prefix: '-', - line: 'var myVar = 2;' - }, - second: { - prefix: '+', - line: 'var myVariable = 3;' - } - }, result); - }); - it('should highlight two lines char by char', function() { - var result = PrinterUtils.diffHighlight( - '-var myVar = 2;', - '+var myVariable = 3;', - { diffStyle: 'char' } - ); - - assert.deepEqual({ - first: { - prefix: '-', - line: 'var myVar = 2;' - }, - second: { - prefix: '+', - line: 'var myVariable = 3;' - } - }, result); - }); - it('should highlight combined diff lines', function() { - var result = PrinterUtils.diffHighlight( - ' -var myVar = 2;', - ' +var myVariable = 3;', - { - diffStyle: 'word', - isCombined: true, - matching: 'words', - matchWordsThreshold: 1.00 - } - ); - - assert.deepEqual({ - first: { - prefix: ' -', - line: 'var myVar = 2;' - }, - second: { - prefix: ' +', - line: 'var myVariable = 3;' - } - }, result); - }); - }); -}); diff --git a/test/utils-tests.js b/test/utils-tests.js deleted file mode 100644 index fec64a9..0000000 --- a/test/utils-tests.js +++ /dev/null @@ -1,25 +0,0 @@ -var assert = require('assert'); - -var Utils = require('../src/utils.js').Utils; - -describe('Utils', function() { - describe('escape', function() { - it('should escape & with &', function() { - var result = Utils.escape('&'); - assert.equal('&', result); - }); - it('should escape < with <', function() { - var result = Utils.escape('<'); - assert.equal('<', result); - }); - it('should escape > with >', function() { - var result = Utils.escape('>'); - assert.equal('>', result); - }); - it('should escape a string with multiple problematic characters', function() { - var result = Utils.escape('\tlink text'); - var expected = '<a href="#">\tlink text</a>'; - assert.equal(expected, result); - }); - }); -}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ead2b45 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "outDir": "./build/commonjs-node", + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + // TODO: Change to true after migration to TS is complete + "allowJs": true, + "declaration": false, + "declarationMap": false, + ///////////////////////////////////////////////////////// + "strictNullChecks": true, + "removeComments": true, + "preserveConstEnums": true, + "sourceMap": true, + "alwaysStrict": true, + "strict": true, + "noImplicitAny": true, + "noImplicitThis": true, + "noUnusedParameters": true, + "noUnusedLocals": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["./src/**/*"], + "exclude": ["node_modules", "./src/__tests__/*"] +} diff --git a/website/templates/pages/demo/demo.js b/website/templates/pages/demo/demo.js index f2b1326..ff96e78 100644 --- a/website/templates/pages/demo/demo.js +++ b/website/templates/pages/demo/demo.js @@ -15,20 +15,20 @@ $(document).ready(function() { // Improves browser compatibility - require('whatwg-fetch'); + require("whatwg-fetch"); - var searchParam = 'diff'; + const searchParam = "diff"; - var $container = $('.container'); - var $url = $('#url'); - var $outputFormat = $('#diff-url-options-output-format'); - var $showFiles = $('#diff-url-options-show-files'); - var $matching = $('#diff-url-options-matching'); - var $wordsThreshold = $('#diff-url-options-match-words-threshold'); - var $matchingMaxComparisons = $('#diff-url-options-matching-max-comparisons'); + const $container = $(".container"); + const $url = $("#url"); + const $outputFormat = $("#diff-url-options-output-format"); + const $showFiles = $("#diff-url-options-show-files"); + const $matching = $("#diff-url-options-matching"); + const $wordsThreshold = $("#diff-url-options-match-words-threshold"); + const $matchingMaxComparisons = $("#diff-url-options-matching-max-comparisons"); if (window.location.search) { - var url = getUrlFromSearch(window.location.search); + const url = getUrlFromSearch(window.location.search); $url.val(url); smartDraw(url); } @@ -41,99 +41,99 @@ $(document).ready(function() { .add($wordsThreshold) .add($matchingMaxComparisons) .change(function(e) { - console.log(''); + console.log(""); console.log(e); - console.log(''); + console.log(""); smartDraw(null, true); }); function getUrlFromSearch(search) { try { return search - .split('?')[1] - .split(searchParam + '=')[1] - .split('&')[0]; - } catch (_ignore) { - } + .split("?")[1] + .split(searchParam + "=")[1] + .split("&")[0]; + } catch (_ignore) {} return null; } function getParamsFromSearch(search) { - var map = {}; + const map = {}; try { search - .split('?')[1] - .split('&') + .split("?")[1] + .split("&") .map(function(e) { - var values = e.split('='); + const values = e.split("="); map[values[0]] = values[1]; }); - } catch (_ignore) { - } + } catch (_ignore) {} return map; } function bind() { - $('#url-btn').click(function(e) { + $("#url-btn").click(function(e) { e.preventDefault(); - var url = $url.val(); + const url = $url.val(); smartDraw(url); }); - $url.on('paste', function(e) { - var url = e.originalEvent.clipboardData.getData('Text'); + $url.on("paste", function(e) { + const url = e.originalEvent.clipboardData.getData("Text"); smartDraw(url); }); } function prepareUrl(url) { - var fetchUrl; - var headers = new Headers(); + let fetchUrl; + const headers = new Headers(); - var githubCommitUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/; - var githubPrUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/pull\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/; + const githubCommitUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/; + const githubPrUrl = /^https?:\/\/(?:www\.)?github\.com\/(.*?)\/(.*?)\/pull\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/; - var gitlabCommitUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/; - var gitlabPrUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/merge_requests\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/; + const gitlabCommitUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/commit\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/; + const gitlabPrUrl = /^https?:\/\/(?:www\.)?gitlab\.com\/(.*?)\/(.*?)\/merge_requests\/(.*?)(?:\.diff)?(?:\.patch)?(?:\/.*)?$/; - var bitbucketCommitUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/commits\/(.*?)(?:\/raw)?(?:\/.*)?$/; - var bitbucketPrUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/pull-requests\/(.*?)(?:\/.*)?$/; + const bitbucketCommitUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/commits\/(.*?)(?:\/raw)?(?:\/.*)?$/; + const bitbucketPrUrl = /^https?:\/\/(?:www\.)?bitbucket\.org\/(.*?)\/(.*?)\/pull-requests\/(.*?)(?:\/.*)?$/; function gitLabUrlGen(userName, projectName, type, value) { - return 'https://crossorigin.me/https://gitlab.com/' + userName + '/' + projectName + '/' + type + '/' + value + '.diff'; + return ( + "https://crossorigin.me/https://gitlab.com/" + userName + "/" + projectName + "/" + type + "/" + value + ".diff" + ); } function gitHubUrlGen(userName, projectName, type, value) { - headers.append('Accept', 'application/vnd.github.v3.diff'); - return 'https://api.github.com/repos/' + userName + '/' + projectName + '/' + type + '/' + value; + headers.append("Accept", "application/vnd.github.v3.diff"); + return "https://api.github.com/repos/" + userName + "/" + projectName + "/" + type + "/" + value; } function bitbucketUrlGen(userName, projectName, type, value) { - var baseUrl = 'https://bitbucket.org/api/2.0/repositories/'; - if (type === 'pullrequests') { - return baseUrl + userName + '/' + projectName + '/pullrequests/' + value + '/diff'; + const baseUrl = "https://bitbucket.org/api/2.0/repositories/"; + if (type === "pullrequests") { + return baseUrl + userName + "/" + projectName + "/pullrequests/" + value + "/diff"; } - return baseUrl + userName + '/' + projectName + '/diff/' + value; + return baseUrl + userName + "/" + projectName + "/diff/" + value; } - var values; + let values; if ((values = githubCommitUrl.exec(url))) { - fetchUrl = gitHubUrlGen(values[1], values[2], 'commits', values[3]); + fetchUrl = gitHubUrlGen(values[1], values[2], "commits", values[3]); } else if ((values = githubPrUrl.exec(url))) { - fetchUrl = gitHubUrlGen(values[1], values[2], 'pulls', values[3]); + fetchUrl = gitHubUrlGen(values[1], values[2], "pulls", values[3]); } else if ((values = gitlabCommitUrl.exec(url))) { - fetchUrl = gitLabUrlGen(values[1], values[2], 'commit', values[3]); + fetchUrl = gitLabUrlGen(values[1], values[2], "commit", values[3]); } else if ((values = gitlabPrUrl.exec(url))) { - fetchUrl = gitLabUrlGen(values[1], values[2], 'merge_requests', values[3]); + fetchUrl = gitLabUrlGen(values[1], values[2], "merge_requests", values[3]); } else if ((values = bitbucketCommitUrl.exec(url))) { - fetchUrl = bitbucketUrlGen(values[1], values[2], 'commit', values[3]); + fetchUrl = bitbucketUrlGen(values[1], values[2], "commit", values[3]); } else if ((values = bitbucketPrUrl.exec(url))) { - fetchUrl = bitbucketUrlGen(values[1], values[2], 'pullrequests', values[3]); + fetchUrl = bitbucketUrlGen(values[1], values[2], "pullrequests", values[3]); } else { - console.info('Could not parse url, using the provided url.'); - fetchUrl = 'https://crossorigin.me/' + url; + console.info("Could not parse url, using the provided url."); + fetchUrl = "https://crossorigin.me/" + url; } return { @@ -144,90 +144,96 @@ $(document).ready(function() { } function smartDraw(urlOpt, forced) { - var url = urlOpt || $url.val(); - var req = prepareUrl(url); + const url = urlOpt || $url.val(); + const req = prepareUrl(url); draw(req, forced); } function draw(req, forced) { if (!validateUrl(req.url)) { - console.error('Invalid url provided!'); + console.error("Invalid url provided!"); return; } if (validateUrl(req.originalUrl)) updateUrl(req.originalUrl); - var outputFormat = $outputFormat.val(); - var showFiles = $showFiles.is(':checked'); - var matching = $matching.val(); - var wordsThreshold = $wordsThreshold.val(); - var matchingMaxComparisons = $matchingMaxComparisons.val(); + const outputFormat = $outputFormat.val(); + const showFiles = $showFiles.is(":checked"); + const matching = $matching.val(); + const wordsThreshold = $wordsThreshold.val(); + const matchingMaxComparisons = $matchingMaxComparisons.val(); fetch(req.url, { - method: 'GET', + method: "GET", headers: req.headers, - mode: 'cors', - cache: 'default' + mode: "cors", + cache: "default" }) .then(function(res) { return res.text(); }) .then(function(data) { - var container = '#url-diff-container'; - var diff2htmlUi = new Diff2HtmlUI({diff: data}); + const container = "#url-diff-container"; + const diff2htmlUi = new Diff2HtmlUI({ diff: data }); - if (outputFormat === 'side-by-side') { - $container.css({'width': '100%'}); + if (outputFormat === "side-by-side") { + $container.css({ width: "100%" }); } else { - $container.css({'width': ''}); + $container.css({ width: "" }); } - var params = getParamsFromSearch(window.location.search); + const params = getParamsFromSearch(window.location.search); delete params[searchParam]; if (forced) { - params['outputFormat'] = outputFormat; - params['showFiles'] = showFiles; - params['matching'] = matching; - params['wordsThreshold'] = wordsThreshold; - params['matchingMaxComparisons'] = matchingMaxComparisons; + params.outputFormat = outputFormat; + params.showFiles = showFiles; + params.matching = matching; + params.wordsThreshold = wordsThreshold; + params.matchingMaxComparisons = matchingMaxComparisons; } else { - params['outputFormat'] = params['outputFormat'] || outputFormat; - params['showFiles'] = String(params['showFiles']) !== 'false' || (params['showFiles'] === null && showFiles); - params['matching'] = params['matching'] || matching; - params['wordsThreshold'] = params['wordsThreshold'] || wordsThreshold; - params['matchingMaxComparisons'] = params['matchingMaxComparisons'] || matchingMaxComparisons; + params.outputFormat = params.outputFormat || outputFormat; + params.showFiles = String(params.showFiles) !== "false" || (params.showFiles === null && showFiles); + params.matching = params.matching || matching; + params.wordsThreshold = params.wordsThreshold || wordsThreshold; + params.matchingMaxComparisons = params.matchingMaxComparisons || matchingMaxComparisons; - $outputFormat.val(params['outputFormat']); - $showFiles.prop('checked', params['showFiles']); - $matching.val(params['matching']); - $wordsThreshold.val(params['wordsThreshold']); - $matchingMaxComparisons.val(params['matchingMaxComparisons']); + $outputFormat.val(params.outputFormat); + $showFiles.prop("checked", params.showFiles); + $matching.val(params.matching); + $wordsThreshold.val(params.wordsThreshold); + $matchingMaxComparisons.val(params.matchingMaxComparisons); } - params['synchronisedScroll'] = params['synchronisedScroll'] || true; + params.synchronisedScroll = params.synchronisedScroll || true; diff2htmlUi.draw(container, params); - diff2htmlUi.fileListCloseable(container, params['fileListCloseable'] || false); - if (params['highlight'] === undefined || params['highlight']) { + diff2htmlUi.fileListCloseable(container, params.fileListCloseable || false); + if (params.highlight === undefined || params.highlight) { diff2htmlUi.highlightCode(container); } }); } function validateUrl(url) { - return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(url); + return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( + url + ); } function updateUrl(url) { - var params = getParamsFromSearch(window.location.search); + const params = getParamsFromSearch(window.location.search); if (params[searchParam] === url) return; params[searchParam] = url; - var paramString = Object.keys(params).map(function(k) { return k + '=' + params[k]; }).join('&'); + const paramString = Object.keys(params) + .map(function(k) { + return k + "=" + params[k]; + }) + .join("&"); - window.location = 'demo.html?' + paramString; + window.location = "demo.html?" + paramString; } }); diff --git a/yarn.lock b/yarn.lock index 0f6e710..1c76a08 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,13 +2,80 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" - integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" + integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== dependencies: "@babel/highlight" "^7.0.0" +"@babel/core@^7.1.0": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.2.tgz#069a776e8d5e9eefff76236bc8845566bd31dd91" + integrity sha512-l8zto/fuoZIbncm+01p8zPSDZu/VuuJhAfA7d/AbzM09WR7iVhavvfNDYCNpo1VvLk6E6xgAoP9P+/EMJHuRkQ== + dependencies: + "@babel/code-frame" "^7.5.5" + "@babel/generator" "^7.6.2" + "@babel/helpers" "^7.6.2" + "@babel/parser" "^7.6.2" + "@babel/template" "^7.6.0" + "@babel/traverse" "^7.6.2" + "@babel/types" "^7.6.0" + convert-source-map "^1.1.0" + debug "^4.1.0" + json5 "^2.1.0" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.4.0", "@babel/generator@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.2.tgz#dac8a3c2df118334c2a29ff3446da1636a8f8c03" + integrity sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ== + dependencies: + "@babel/types" "^7.6.0" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/helper-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" + integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== + dependencies: + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-get-function-arity@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" + integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-plugin-utils@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" + integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== + +"@babel/helper-split-export-declaration@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" + integrity sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q== + dependencies: + "@babel/types" "^7.4.4" + +"@babel/helpers@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.6.2.tgz#681ffe489ea4dcc55f23ce469e58e59c1c045153" + integrity sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA== + dependencies: + "@babel/template" "^7.6.0" + "@babel/traverse" "^7.6.2" + "@babel/types" "^7.6.0" + "@babel/highlight@^7.0.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" @@ -18,6 +85,207 @@ esutils "^2.0.2" js-tokens "^4.0.0" +"@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0", "@babel/parser@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.2.tgz#205e9c95e16ba3b8b96090677a67c9d6075b70a1" + integrity sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg== + +"@babel/plugin-syntax-object-rest-spread@^7.0.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" + integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.6.0.tgz#7f0159c7f5012230dad64cca42ec9bdb5c9536e6" + integrity sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.6.0" + "@babel/types" "^7.6.0" + +"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.2.tgz#b0e2bfd401d339ce0e6c05690206d1e11502ce2c" + integrity sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ== + dependencies: + "@babel/code-frame" "^7.5.5" + "@babel/generator" "^7.6.2" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/parser" "^7.6.2" + "@babel/types" "^7.6.0" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.6.0": + version "7.6.1" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.1.tgz#53abf3308add3ac2a2884d539151c57c4b3ac648" + integrity sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g== + dependencies: + esutils "^2.0.2" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@cnakazawa/watch@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" + integrity sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA== + dependencies: + exec-sh "^0.3.2" + minimist "^1.2.0" + +"@jest/console@^24.7.1", "@jest/console@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" + integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== + dependencies: + "@jest/source-map" "^24.9.0" + chalk "^2.0.1" + slash "^2.0.0" + +"@jest/core@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" + integrity sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A== + dependencies: + "@jest/console" "^24.7.1" + "@jest/reporters" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + graceful-fs "^4.1.15" + jest-changed-files "^24.9.0" + jest-config "^24.9.0" + jest-haste-map "^24.9.0" + jest-message-util "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-resolve-dependencies "^24.9.0" + jest-runner "^24.9.0" + jest-runtime "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + jest-watcher "^24.9.0" + micromatch "^3.1.10" + p-each-series "^1.0.0" + realpath-native "^1.1.0" + rimraf "^2.5.4" + slash "^2.0.0" + strip-ansi "^5.0.0" + +"@jest/environment@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" + integrity sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ== + dependencies: + "@jest/fake-timers" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + +"@jest/fake-timers@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" + integrity sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A== + dependencies: + "@jest/types" "^24.9.0" + jest-message-util "^24.9.0" + jest-mock "^24.9.0" + +"@jest/reporters@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" + integrity sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + istanbul-lib-coverage "^2.0.2" + istanbul-lib-instrument "^3.0.1" + istanbul-lib-report "^2.0.4" + istanbul-lib-source-maps "^3.0.1" + istanbul-reports "^2.2.6" + jest-haste-map "^24.9.0" + jest-resolve "^24.9.0" + jest-runtime "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.6.0" + node-notifier "^5.4.2" + slash "^2.0.0" + source-map "^0.6.0" + string-length "^2.0.0" + +"@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" + integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.1.15" + source-map "^0.6.0" + +"@jest/test-result@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" + integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA== + dependencies: + "@jest/console" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/istanbul-lib-coverage" "^2.0.0" + +"@jest/test-sequencer@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" + integrity sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A== + dependencies: + "@jest/test-result" "^24.9.0" + jest-haste-map "^24.9.0" + jest-runner "^24.9.0" + jest-runtime "^24.9.0" + +"@jest/transform@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" + integrity sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^24.9.0" + babel-plugin-istanbul "^5.1.0" + chalk "^2.0.1" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.1.15" + jest-haste-map "^24.9.0" + jest-regex-util "^24.9.0" + jest-util "^24.9.0" + micromatch "^3.1.10" + pirates "^4.0.1" + realpath-native "^1.1.0" + slash "^2.0.0" + source-map "^0.6.1" + write-file-atomic "2.4.1" + +"@jest/types@^24.9.0": + version "24.9.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" + integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^13.0.0" + "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" @@ -31,6 +299,44 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== +"@types/babel__core@^7.1.0": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30" + integrity sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.0.tgz#f1ec1c104d1bb463556ecb724018ab788d0c172a" + integrity sha512-c1mZUu4up5cp9KROs/QAw0gTeHrw/x7m52LcnvMxxOZ03DmLwPV0MlGmlgzV3cnSdjhJOZsj7E7FHeioai+egw== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307" + integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.0.7" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.7.tgz#2496e9ff56196cc1429c72034e07eab6121b6f3f" + integrity sha512-CeBpmX1J8kWLcDEnI3Cl2Eo6RfbGvzUctA+CjZUhOKDFbLfcr7fc4usEqLNWetrlJd7RhAkyYe2czXop4fICpw== + dependencies: + "@babel/types" "^7.3.0" + +"@types/eslint-visitor-keys@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" + integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== + "@types/events@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" @@ -45,15 +351,124 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" + integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg== + +"@types/istanbul-lib-report@*": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#e5471e7fa33c61358dd38426189c037a58433b8c" + integrity sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a" + integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA== + dependencies: + "@types/istanbul-lib-coverage" "*" + "@types/istanbul-lib-report" "*" + +"@types/jest-diff@*": + version "20.0.1" + resolved "https://registry.yarnpkg.com/@types/jest-diff/-/jest-diff-20.0.1.tgz#35cc15b9c4f30a18ef21852e255fdb02f6d59b89" + integrity sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA== + +"@types/jest@24.0.18": + version "24.0.18" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.0.18.tgz#9c7858d450c59e2164a8a9df0905fc5091944498" + integrity sha512-jcDDXdjTcrQzdN06+TSVsPPqxvsZA/5QkYfIZlq1JMw7FdP5AZylbOc+6B/cuDurctRe+MziUMtQ3xQdrbjqyQ== + dependencies: + "@types/jest-diff" "*" + +"@types/json-schema@^7.0.3": + version "7.0.3" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" + integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A== + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== -"@types/node@*": - version "12.6.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.2.tgz#a5ccec6abb6060d5f20d256fb03ed743e9774999" - integrity sha512-gojym4tX0FWeV2gsW4Xmzo5wxGjXGm550oVUII7f7G5o4BV6c7DBdiG1RRQd+y1bvqRyYtPfMK85UM95vsapqQ== +"@types/node@*", "@types/node@^12.7.2": + version "12.7.11" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.11.tgz#be879b52031cfb5d295b047f5462d8ef1a716446" + integrity sha512-Otxmr2rrZLKRYIybtdG/sgeO+tHY20GxeDjcGmUnmmlCWyEnv2a2x1ZXBo3BTec4OiTXMQCiazB8NMBf0iRlFw== + +"@types/stack-utils@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" + integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== + +"@types/yargs-parser@*": + version "13.1.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" + integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg== + +"@types/yargs@^13.0.0": + version "13.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.3.tgz#76482af3981d4412d65371a318f992d33464a380" + integrity sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ== + dependencies: + "@types/yargs-parser" "*" + +"@typescript-eslint/eslint-plugin@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.0.0.tgz#609a5d7b00ce21a6f94d7ef282eba9da57ca1e42" + integrity sha512-Mo45nxTTELODdl7CgpZKJISvLb+Fu64OOO2ZFc2x8sYSnUpFrBUW3H+H/ZGYmEkfnL6VkdtOSxgdt+Av79j0sA== + dependencies: + "@typescript-eslint/experimental-utils" "2.0.0" + eslint-utils "^1.4.0" + functional-red-black-tree "^1.0.1" + regexpp "^2.0.1" + tsutils "^3.14.0" + +"@typescript-eslint/experimental-utils@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.0.0.tgz#f3d298bb411357f35c4184e24280b256b6321949" + integrity sha512-XGJG6GNBXIEx/mN4eTRypN/EUmsd0VhVGQ1AG+WTgdvjHl0G8vHhVBHrd/5oI6RRYBRnedNymSYWW1HAdivtmg== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/typescript-estree" "2.0.0" + eslint-scope "^4.0.0" + +"@typescript-eslint/experimental-utils@^1.13.0": + version "1.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz#b08c60d780c0067de2fb44b04b432f540138301e" + integrity sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/typescript-estree" "1.13.0" + eslint-scope "^4.0.0" + +"@typescript-eslint/parser@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.0.0.tgz#4273bb19d03489daf8372cdaccbc8042e098178f" + integrity sha512-ibyMBMr0383ZKserIsp67+WnNVoM402HKkxqXGlxEZsXtnGGurbnY90pBO3e0nBUM7chEEOcxUhgw9aPq7fEBA== + dependencies: + "@types/eslint-visitor-keys" "^1.0.0" + "@typescript-eslint/experimental-utils" "2.0.0" + "@typescript-eslint/typescript-estree" "2.0.0" + eslint-visitor-keys "^1.0.0" + +"@typescript-eslint/typescript-estree@1.13.0": + version "1.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz#8140f17d0f60c03619798f1d628b8434913dc32e" + integrity sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw== + dependencies: + lodash.unescape "4.0.1" + semver "5.5.0" + +"@typescript-eslint/typescript-estree@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.0.0.tgz#c9f6c0efd1b11475540d6a55dc973cc5b9a67e77" + integrity sha512-NXbmzA3vWrSgavymlzMWNecgNOuiMMp62MO3kI7awZRLRcsA1QrYWo6q08m++uuAGVbXH/prZi2y1AWuhSu63w== + dependencies: + lodash.unescape "4.0.1" + semver "^6.2.0" JSONStream@^1.0.3: version "1.3.5" @@ -63,62 +478,74 @@ JSONStream@^1.0.3: jsonparse "^1.2.0" through ">=2.2.7 <3" +abab@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.2.tgz#a2fba1b122c69a85caa02d10f9270c7219709a9d" + integrity sha512-2scffjvioEmNz0OyDSLGWDfKCVwaKc6l9Pm9kOIREU13ClXZvHpg/nRL5xyjSSSLhOnXqft2HpsAzNEEA8cFFg== + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -abbrev@1.0.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" - integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= +acorn-globals@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" + integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== + dependencies: + acorn "^6.0.1" + acorn-walk "^6.0.1" -acorn-dynamic-import@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz#482210140582a36b83c3e342e1cfebcaa9240948" - integrity sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw== - -acorn-jsx@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" - integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== +acorn-jsx@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f" + integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw== acorn-node@^1.2.0, acorn-node@^1.3.0, acorn-node@^1.5.2, acorn-node@^1.6.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.7.0.tgz#aac6a559d27af6176b076ab6fb13c5974c213e3b" - integrity sha512-XhahLSsCB6X6CJbe+uNu3Mn9sJBNFxtBN9NLgAOQovfS6Kh0lDUtmlclhjn9CvEK7A7YyRU13PXlNcpSiLI9Yw== + version "1.8.2" + resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8" + integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A== dependencies: - acorn "^6.1.1" - acorn-dynamic-import "^4.0.0" - acorn-walk "^6.1.1" - xtend "^4.0.1" + acorn "^7.0.0" + acorn-walk "^7.0.0" + xtend "^4.0.2" -acorn-walk@^6.1.1: +acorn-walk@^6.0.1: version "6.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== -acorn@^6.0.7, acorn@^6.1.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.0.tgz#67f0da2fc339d6cfb5d6fb244fd449f33cd8bbe3" - integrity sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw== +acorn-walk@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.0.0.tgz#c8ba6f0f1aac4b0a9e32d1f0af12be769528f36b" + integrity sha512-7Bv1We7ZGuU79zZbb6rRqcpxo3OY+zrdtloZWoyD8fmGX+FeXRjE+iuGkZjSXLVovLzrsvMGMy0EkwA0E0umxg== -ajv@^6.5.5, ajv@^6.9.1: - version "6.10.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.1.tgz#ebf8d3af22552df9dd049bfbe50cc2390e823593" - integrity sha512-w1YQaVGNC6t2UCPjEawK/vo/dG8OOrVtUmhBT1uJJYxbl5kU2Tj3v6LGqBcsysN1yhuCStJCCA3GqdvKY8sqXQ== +acorn@^5.5.3: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== + +acorn@^6.0.1: + version "6.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e" + integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA== + +acorn@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c" + integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ== + +ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: + version "6.10.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" + integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== dependencies: fast-deep-equal "^2.0.1" fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.4.1" uri-js "^4.2.2" -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= - -ansi-escapes@^3.2.0: +ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== @@ -133,7 +560,7 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= -ansi-regex@^4.1.0: +ansi-regex@^4.0.0, ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== @@ -193,20 +620,18 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= -array-filter@~0.0.0: - version "0.0.1" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" - integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= -array-map@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" - integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= - -array-reduce@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" - integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= +array-includes@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" + integrity sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" array-union@^1.0.2: version "1.0.2" @@ -269,10 +694,10 @@ async-each@^1.0.1: resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== -async@1.x: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== asynckit@^0.4.0: version "0.4.0" @@ -285,17 +710,17 @@ atob@^2.1.1: integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== autoprefixer@^9.6.0: - version "9.6.1" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.6.1.tgz#51967a02d2d2300bb01866c1611ec8348d355a47" - integrity sha512-aVo5WxR3VyvyJxcJC3h4FKfwCQvQWb1tSI5VHNibddCVWrcD1NvlxEweg3TSgiPztMnWfjpy2FURKA2kvDE+Tw== + version "9.6.4" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.6.4.tgz#e6453be47af316b2923eaeaed87860f52ad4b7eb" + integrity sha512-Koz2cJU9dKOxG8P1f8uVaBntOv9lP4yz9ffWvWaicv9gHBPhpQB22nGijwd8gqW9CNT+UdkbQOQNLVI8jN1ZfQ== dependencies: - browserslist "^4.6.3" - caniuse-lite "^1.0.30000980" + browserslist "^4.7.0" + caniuse-lite "^1.0.30000998" chalk "^2.4.2" normalize-range "^0.1.2" num2fraction "^1.2.2" - postcss "^7.0.17" - postcss-value-parser "^4.0.0" + postcss "^7.0.18" + postcss-value-parser "^4.0.2" aws-sign2@~0.7.0: version "0.7.0" @@ -307,15 +732,53 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== +babel-jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54" + integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw== + dependencies: + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/babel__core" "^7.1.0" + babel-plugin-istanbul "^5.1.0" + babel-preset-jest "^24.9.0" + chalk "^2.4.2" + slash "^2.0.0" + +babel-plugin-istanbul@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854" + integrity sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + find-up "^3.0.0" + istanbul-lib-instrument "^3.3.0" + test-exclude "^5.2.3" + +babel-plugin-jest-hoist@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756" + integrity sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw== + dependencies: + "@types/babel__traverse" "^7.0.6" + +babel-preset-jest@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc" + integrity sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg== + dependencies: + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + babel-plugin-jest-hoist "^24.9.0" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base64-js@^1.0.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" - integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== base@^0.11.1: version "0.11.2" @@ -343,9 +806,9 @@ binary-extensions@^1.0.0: integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== bluebird@^3.5.0, bluebird@^3.5.x: - version "3.5.5" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f" - integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w== + version "3.7.0" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.0.tgz#56a6a886e03f6ae577cffedeb524f8f2450293cf" + integrity sha512-aBQ1FxIa7kSWCcmKHlcHFlT2jt6J/l4FzC7KcPELkOJOsPOb/bccdhmIrKDfXhwFrmc7vDoDrrepFvGqjyXGJg== bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.8" @@ -393,7 +856,12 @@ browser-pack@^6.0.1: through2 "^2.0.0" umd "^3.0.0" -browser-resolve@^1.11.0, browser-resolve@^1.7.0: +browser-process-hrtime@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" + integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw== + +browser-resolve@^1.11.0, browser-resolve@^1.11.3, browser-resolve@^1.7.0: version "1.11.3" resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== @@ -464,10 +932,10 @@ browserify-zlib@~0.2.0: dependencies: pako "~1.0.5" -browserify@^16.2.3: - version "16.3.0" - resolved "https://registry.yarnpkg.com/browserify/-/browserify-16.3.0.tgz#4d414466e0b07492fff493a009ea883a9f2db230" - integrity sha512-BWaaD7alyGZVEBBwSTYx4iJF5DswIGzK17o8ai9w4iKRbYpk3EOiprRHMRRA8DCZFmFeOdx7A385w2XdFvxWmg== +browserify@^16.5.0: + version "16.5.0" + resolved "https://registry.yarnpkg.com/browserify/-/browserify-16.5.0.tgz#a1c2bc0431bec11fd29151941582e3f645ede881" + integrity sha512-6bfI3cl76YLAnCZ75AGu/XPOsqUhRyc0F/olGIJeCxtfxF2HvPKEcmjU9M8oAPxl4uBY1U7Nry33Q6koV3f2iw== dependencies: JSONStream "^1.0.3" assert "^1.4.0" @@ -506,7 +974,7 @@ browserify@^16.2.3: shasum "^1.0.0" shell-quote "^1.6.1" stream-browserify "^2.0.0" - stream-http "^2.0.0" + stream-http "^3.0.0" string_decoder "^1.1.1" subarg "^1.0.0" syntax-error "^1.1.1" @@ -518,16 +986,30 @@ browserify@^16.2.3: vm-browserify "^1.0.0" xtend "^4.0.0" -browserslist@^4.6.3: - version "4.6.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.4.tgz#fd0638b3f8867fec2c604ed0ed9300379f8ec7c2" - integrity sha512-ErJT8qGfRt/VWHSr1HeqZzz50DvxHtr1fVL1m5wf20aGrG8e1ce8fpZ2EjZEfs09DDZYSvtRaDlMpWslBf8Low== +browserslist@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.0.tgz#9ee89225ffc07db03409f2fee524dc8227458a17" + integrity sha512-9rGNDtnj+HaahxiVV38Gn8n8Lr8REKsel68v1sPFfIGEK6uSXTY3h9acgiT1dZVtOOUtifo/Dn8daDQ5dUgVsA== dependencies: - caniuse-lite "^1.0.30000981" - electron-to-chromium "^1.3.188" - node-releases "^1.1.25" + caniuse-lite "^1.0.30000989" + electron-to-chromium "^1.3.247" + node-releases "^1.1.29" -buffer-from@^1.0.0: +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.0.tgz#65fc784bf7f87c009b973c12db6546902fa9c7b5" + integrity sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg== + dependencies: + node-int64 "^0.4.0" + +buffer-from@1.x, buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== @@ -538,9 +1020,9 @@ buffer-xor@^1.0.3: integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= buffer@^5.0.2: - version "5.2.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" - integrity sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg== + version "5.4.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" + integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A== dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -599,15 +1081,27 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camelcase@^5.0.0: +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981: - version "1.0.30000983" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000983.tgz#ab3c70061ca2a3467182a10ac75109b199b647f8" - integrity sha512-/llD1bZ6qwNkt41AsvjsmwNOoA4ZB+8iqmf5LVyeSXuBODT/hAMFNVOh84NdUzoiYiSKqo5vQ3ZzeYHSi/olDQ== +caniuse-lite@^1.0.30000989, caniuse-lite@^1.0.30000998: + version "1.0.30000999" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000999.tgz#427253a69ad7bea4aa8d8345687b8eec51ca0e43" + integrity sha512-1CUyKyecPeksKwXZvYw0tEoaMCo/RwBlXmEtN5vVnabvO0KPd9RQLcaAuR9/1F+KDMv6esmOFWlsXuzDk+8rxg== + +capture-exit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" + integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== + dependencies: + rsvp "^4.8.4" caseless@~0.12.0: version "0.12.0" @@ -629,9 +1123,9 @@ chardet@^0.7.0: integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== chokidar@^2.0.0: - version "2.1.6" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5" - integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g== + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== dependencies: anymatch "^2.0.0" async-each "^1.0.1" @@ -648,9 +1142,14 @@ chokidar@^2.0.0: fsevents "^1.2.7" chownr@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6" - integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A== + version "1.1.3" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" + integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" @@ -707,6 +1206,20 @@ cliui@^4.0.0: strip-ansi "^4.0.0" wrap-ansi "^2.0.0" +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + codacy-coverage@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/codacy-coverage/-/codacy-coverage-3.4.0.tgz#196af70844c4e4179718f7a7f9d96b921b4b3a67" @@ -769,10 +1282,10 @@ commander@2.15.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== -commander@2.x, commander@^2.x, commander@~2.20.0: - version "2.20.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" - integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== +commander@2.x, commander@^2.20.0, commander@^2.x, commander@~2.20.0: + version "2.20.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.1.tgz#3863ce3ca92d0831dcf2a102f5fb4b5926afd0f9" + integrity sha512-cCuLsMhJeWQ/ZpsFTbE765kvVfoeSddc4nU3up4fV+fDBcfUXnbITJ+JzhkdjzOqhURjZgujxaioam4RM9yGUg== component-emitter@^1.2.1: version "1.3.0" @@ -811,6 +1324,18 @@ constants-browserify@~1.0.0: resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + +convert-source-map@^1.1.0, convert-source-map@^1.4.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" + convert-source-map@~1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860" @@ -895,6 +1420,18 @@ crypto-browserify@^3.0.0: randombytes "^2.0.0" randomfill "^1.0.3" +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" + integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== + dependencies: + cssom "0.3.x" + dash-ast@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/dash-ast/-/dash-ast-1.0.0.tgz#12029ba5fb2f8aa6f0a861795b23c1b4b6c27d37" @@ -907,6 +1444,15 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +data-urls@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" + integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.2.0" + whatwg-url "^7.0.0" + date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" @@ -919,7 +1465,7 @@ debug@3.1.0: dependencies: ms "2.0.0" -debug@^2.2.0, debug@^2.3.3: +debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -933,7 +1479,7 @@ debug@^3.2.6: dependencies: ms "^2.1.1" -debug@^4.0.1: +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -960,6 +1506,13 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" @@ -1025,6 +1578,11 @@ detect-libc@^1.0.2: resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= + detective@^5.0.2: version "5.2.0" resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.0.tgz#feb2a77e85b904ecdea459ad897cc90a99bd2a7b" @@ -1034,6 +1592,11 @@ detective@^5.0.2: defined "^1.0.0" minimist "^1.1.1" +diff-sequences@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" + integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== + diff@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -1060,6 +1623,14 @@ dir-glob@^2.2.2: dependencies: path-type "^3.0.0" +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + doctrine@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" @@ -1072,6 +1643,13 @@ domain-browser@^1.2.0: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== + dependencies: + webidl-conversions "^4.0.2" + duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" @@ -1087,15 +1665,15 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -electron-to-chromium@^1.3.188: - version "1.3.190" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.190.tgz#5bf599519983bfffd9d4387817039a3ed7ca085f" - integrity sha512-cs9WnTnGBGnYYVFMCtLmr9jXNTOkdp95RLz5VhwzDn7dErg1Lnt9o4d01gEH69XlmRKWUr91Yu1hA+Hi8qW0PA== +electron-to-chromium@^1.3.247: + version "1.3.275" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.275.tgz#19a38436e34216f51820fa2f4326d5ce141fa36f" + integrity sha512-/YWtW/VapMnuYA1lNOaa1F4GhR1LBf+CUTp60lzDPEEh0XOzyOAyULyYZVF9vziZ3qSbTqCwmKwsyRXp66STbw== elliptic@^6.0.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.0.tgz#2b8ed4c891b7de3200e14412a5b8248c7af505ca" - integrity sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg== + version "6.5.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.1.tgz#c380f5f909bf1b9b4428d028cd18d3b0efd6b52b" + integrity sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg== dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -1111,9 +1689,9 @@ emoji-regex@^7.0.1: integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== end-of-stream@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" @@ -1122,41 +1700,145 @@ entities@^1.1.1: resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== -error-ex@^1.3.1: +error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" +es-abstract@^1.12.0, es-abstract@^1.5.1, es-abstract@^1.7.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.15.0.tgz#8884928ec7e40a79e3c9bc812d37d10c8b24cc57" + integrity sha512-bhkEqWJ2t2lMeaJDuk7okMkJWI/yqgH/EoGwpcvv0XW9RWQsRspI4wt6xuyuvMvvQE3gg/D9HXppgk21w78GyQ== + dependencies: + es-to-primitive "^1.2.0" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.0" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-inspect "^1.6.0" + object-keys "^1.1.1" + string.prototype.trimleft "^2.1.0" + string.prototype.trimright "^2.1.0" + +es-to-primitive@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -escodegen@1.8.x: - version "1.8.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" - integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= +escodegen@^1.9.1: + version "1.12.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.12.0.tgz#f763daf840af172bb3a2b6dd7219c0e17f7ff541" + integrity sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg== dependencies: - esprima "^2.7.1" - estraverse "^1.9.1" + esprima "^3.1.3" + estraverse "^4.2.0" esutils "^2.0.2" optionator "^0.8.1" optionalDependencies: - source-map "~0.2.0" + source-map "~0.6.1" -eslint-plugin-promise@^4.1.1: +eslint-config-prettier@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.1.0.tgz#e6f678ba367fbd1273998d5510f76f004e9dce7b" + integrity sha512-k9fny9sPjIBQ2ftFTesJV21Rg4R/7a7t7LCtZVrYQiHEp8Nnuk3EGaDmsKSAnsPj0BYcgB2zxzHa2NTkIxcOLg== + dependencies: + get-stdin "^6.0.0" + +eslint-config-standard@14.0.1: + version "14.0.1" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-14.0.1.tgz#375c3636fb4bd453cb95321d873de12e4eef790b" + integrity sha512-1RWsAKTDTZgA8bIM6PSC9aTGDAUlKqNkYNJlTZ5xYD/HYkIM6GlcefFvgcJ8xi0SWG5203rttKYX28zW+rKNOg== + +eslint-import-resolver-node@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== + dependencies: + debug "^2.6.9" + resolve "^1.5.0" + +eslint-module-utils@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz#7b4675875bf96b0dbf1b21977456e5bb1f5e018c" + integrity sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw== + dependencies: + debug "^2.6.8" + pkg-dir "^2.0.0" + +eslint-plugin-es@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-1.4.1.tgz#12acae0f4953e76ba444bfd1b2271081ac620998" + integrity sha512-5fa/gR2yR3NxQf+UXkeLeP8FBBl6tSgdrAz1+cF84v1FMM4twGwQoqTnn+QxFLcPOrF4pdKEJKDB/q9GoyJrCA== + dependencies: + eslint-utils "^1.4.2" + regexpp "^2.0.1" + +eslint-plugin-import@2.18.2: + version "2.18.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz#02f1180b90b077b33d447a17a2326ceb400aceb6" + integrity sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ== + dependencies: + array-includes "^3.0.3" + contains-path "^0.1.0" + debug "^2.6.9" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.2" + eslint-module-utils "^2.4.0" + has "^1.0.3" + minimatch "^3.0.4" + object.values "^1.1.0" + read-pkg-up "^2.0.0" + resolve "^1.11.0" + +eslint-plugin-jest@22.15.2: + version "22.15.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.15.2.tgz#e3c10d9391f787744e31566f69ebb70c3a98e398" + integrity sha512-p4NME9TgXIt+KgpxcXyNBvO30ZKxwFAO1dJZBc2OGfDnXVEtPwEyNs95GSr6RIE3xLHdjd8ngDdE2icRRXrbxg== + dependencies: + "@typescript-eslint/experimental-utils" "^1.13.0" + +eslint-plugin-node@9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-9.1.0.tgz#f2fd88509a31ec69db6e9606d76dabc5adc1b91a" + integrity sha512-ZwQYGm6EoV2cfLpE1wxJWsfnKUIXfM/KM09/TlorkukgCAwmkgajEJnPCmyzoFPQQkmvo5DrW/nyKutNIw36Mw== + dependencies: + eslint-plugin-es "^1.4.0" + eslint-utils "^1.3.1" + ignore "^5.1.1" + minimatch "^3.0.4" + resolve "^1.10.1" + semver "^6.1.0" + +eslint-plugin-prettier@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.0.tgz#8695188f95daa93b0dc54b249347ca3b79c4686d" + integrity sha512-XWX2yVuwVNLOUhQijAkXz+rMPPoCr7WFiAl8ig6I7Xn+pPVhDhzg4DxHpmbeb0iqjO9UronEA3Tb09ChnFVHHA== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-plugin-promise@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== -eslint-plugin-standard@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz#f845b45109c99cd90e77796940a344546c8f6b5c" - integrity sha512-OwxJkR6TQiYMmt1EsNRMe5qG3GsbjlcOhbGUBY4LtavF9DsLaTcoR+j2Tdjqi23oUwKNUqX7qcn5fPStafMdlA== +eslint-plugin-standard@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4" + integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ== -eslint-scope@^4.0.3: +eslint-scope@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== @@ -1164,73 +1846,82 @@ eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-utils@^1.3.1: +eslint-scope@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" + integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.1, eslint-utils@^1.4.0, eslint-utils@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab" integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q== dependencies: eslint-visitor-keys "^1.0.0" -eslint-visitor-keys@^1.0.0: +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== -eslint@^5.16.0: - version "5.16.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" - integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== +eslint@6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.2.2.tgz#03298280e7750d81fcd31431f3d333e43d93f24f" + integrity sha512-mf0elOkxHbdyGX1IJEUsNBzCDdyoUgljF3rRlgfyYh0pwGnreLc0jjD6ZuleOibjmnUWZLY2eXwSooeOgGJ2jw== dependencies: "@babel/code-frame" "^7.0.0" - ajv "^6.9.1" + ajv "^6.10.0" chalk "^2.1.0" cross-spawn "^6.0.5" debug "^4.0.1" doctrine "^3.0.0" - eslint-scope "^4.0.3" - eslint-utils "^1.3.1" - eslint-visitor-keys "^1.0.0" - espree "^5.0.1" + eslint-scope "^5.0.0" + eslint-utils "^1.4.2" + eslint-visitor-keys "^1.1.0" + espree "^6.1.1" esquery "^1.0.1" esutils "^2.0.2" file-entry-cache "^5.0.1" functional-red-black-tree "^1.0.1" - glob "^7.1.2" + glob-parent "^5.0.0" globals "^11.7.0" ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" - inquirer "^6.2.2" - js-yaml "^3.13.0" + inquirer "^6.4.1" + is-glob "^4.0.0" + js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" - lodash "^4.17.11" + lodash "^4.17.14" minimatch "^3.0.4" mkdirp "^0.5.1" natural-compare "^1.4.0" optionator "^0.8.2" - path-is-inside "^1.0.2" progress "^2.0.0" regexpp "^2.0.1" - semver "^5.5.1" - strip-ansi "^4.0.0" - strip-json-comments "^2.0.1" + semver "^6.1.2" + strip-ansi "^5.2.0" + strip-json-comments "^3.0.1" table "^5.2.3" text-table "^0.2.0" + v8-compile-cache "^2.0.3" -espree@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" - integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== +espree@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.1.tgz#7f80e5f7257fc47db450022d723e356daeb1e5de" + integrity sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ== dependencies: - acorn "^6.0.7" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" + acorn "^7.0.0" + acorn-jsx "^5.0.2" + eslint-visitor-keys "^1.1.0" -esprima@2.7.x, esprima@^2.7.1: - version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" - integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= +esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= esprima@^4.0.0: version "4.0.1" @@ -1251,20 +1942,15 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" -estraverse@^1.9.1: - version "1.9.3" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" - integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= - -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== events@^2.0.0: version "2.1.0" @@ -1279,6 +1965,11 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" +exec-sh@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b" + integrity sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg== + execa@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" @@ -1292,6 +1983,11 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -1305,6 +2001,18 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expect@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-24.9.0.tgz#b75165b4817074fa4a157794f46fe9f1ba15b6ca" + integrity sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q== + dependencies: + "@jest/types" "^24.9.0" + ansi-styles "^3.2.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-regex-util "^24.9.0" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -1363,6 +2071,11 @@ fast-deep-equal@^2.0.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + fast-glob@^2.2.6: version "2.2.7" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" @@ -1383,7 +2096,7 @@ fast-html-parser@^1.0.1: apollojs "^1.3.0" entities "^1.1.1" -fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= @@ -1393,6 +2106,13 @@ fast-levenshtein@~2.0.4: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fb-watchman@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" + integrity sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg= + dependencies: + bser "^2.0.0" + figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -1417,6 +2137,13 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -1474,11 +2201,11 @@ fs-extra@^7.0.0: universalify "^0.1.0" fs-minipass@^1.2.5: - version "1.2.6" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" - integrity sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ== + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== dependencies: - minipass "^2.2.1" + minipass "^2.6.0" fs.realpath@^1.0.0: version "1.0.0" @@ -1527,6 +2254,11 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + get-stdin@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" @@ -1559,6 +2291,13 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" +glob-parent@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2" + integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw== + dependencies: + is-glob "^4.0.1" + glob-to-regexp@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" @@ -1576,7 +2315,7 @@ glob@7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" -glob@7.x, glob@^7.1.0, glob@^7.1.2, glob@^7.1.3: +glob@7.x, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: version "7.1.4" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== @@ -1588,18 +2327,7 @@ glob@7.x, glob@^7.1.0, glob@^7.1.2, glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^5.0.15: - version "5.0.15" - resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" - integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.7.0: +globals@^11.1.0, globals@^11.7.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== @@ -1618,20 +2346,25 @@ globby@^9.0.0: pify "^4.0.1" slash "^2.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: - version "4.2.0" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" - integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.2.2" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" + integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q== growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== -handlebars@^4.0.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" - integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw== +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= + +handlebars@^4.1.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.4.2.tgz#8810a9821a9d6d52cb2f57d326d6ce7c3dfe741d" + integrity sha512-cIv17+GhL8pHHnRJzGu2wwcthL5sb8uDKBHvZ2Dtu5s1YNt0ljbzKbamnc+gr69y7bzwQiBdr5+hOpRd5pnOdg== dependencies: neo-async "^2.6.0" optimist "^0.6.1" @@ -1652,16 +2385,16 @@ har-validator@~5.1.0: ajv "^6.5.5" har-schema "^2.0.0" -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -1698,7 +2431,7 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.0: +has@^1.0.0, has@^1.0.1, has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== @@ -1753,6 +2486,18 @@ hogan.js@^3.0.2: mkdirp "0.3.0" nopt "1.0.10" +hosted-git-info@^2.1.4: + version "2.8.4" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.4.tgz#44119abaf4bc64692a16ace34700fed9c03e2546" + integrity sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ== + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== + dependencies: + whatwg-encoding "^1.0.1" + htmlescape@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/htmlescape/-/htmlescape-1.1.1.tgz#3a03edc2214bca3b66424a3e7959349509cb0351" @@ -1772,7 +2517,7 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -iconv-lite@^0.4.24, iconv-lite@^0.4.4: +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -1785,9 +2530,9 @@ ieee754@^1.1.4: integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + version "3.0.2" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.2.tgz#99d83a246c196ea5c93ef9315ad7b0819c35069b" + integrity sha512-EXyErtpHbn75ZTsOADsfx6J/FPo6/5cjev46PXrcTpd8z3BoRkXgYu9/JVqrI7tusjmwCZutGeRJeU0Wo1e4Cw== dependencies: minimatch "^3.0.4" @@ -1796,6 +2541,11 @@ ignore@^4.0.3, ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +ignore@^5.1.1: + version "5.1.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" + integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== + import-cwd@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" @@ -1826,6 +2576,14 @@ import-from@^2.1.0: dependencies: resolve-from "^3.0.0" +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -1866,10 +2624,10 @@ inline-source-map@~0.6.0: dependencies: source-map "~0.5.3" -inquirer@^6.2.2: - version "6.5.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.0.tgz#2303317efc9a4ea7ec2e2df6f86569b734accf42" - integrity sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA== +inquirer@^6.4.1: + version "6.5.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" + integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ== dependencies: ansi-escapes "^3.2.0" chalk "^2.4.2" @@ -1901,6 +2659,13 @@ insert-module-globals@^7.0.0: undeclared-identifiers "^1.1.2" xtend "^4.0.0" +invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + invert-kv@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" @@ -1937,6 +2702,18 @@ is-buffer@^1.1.0, is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -1951,6 +2728,11 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -2003,6 +2785,11 @@ is-fullwidth-code-point@^2.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" @@ -2010,7 +2797,7 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" -is-glob@^4.0.0: +is-glob@^4.0.0, is-glob@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== @@ -2036,11 +2823,25 @@ is-promise@^2.1.0: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= + dependencies: + has "^1.0.1" + is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" + is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -2051,7 +2852,12 @@ is-windows@^1.0.2: resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== -isarray@1.0.0, isarray@~1.0.0: +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= @@ -2085,25 +2891,50 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -istanbul@^0.4.5: - version "0.4.5" - resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" - integrity sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs= +istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" + integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== + +istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" + integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== dependencies: - abbrev "1.0.x" - async "1.x" - escodegen "1.8.x" - esprima "2.7.x" - glob "^5.0.15" - handlebars "^4.0.1" - js-yaml "3.x" - mkdirp "0.5.x" - nopt "3.x" - once "1.x" - resolve "1.1.x" - supports-color "^3.1.0" - which "^1.1.1" - wordwrap "^1.0.0" + "@babel/generator" "^7.4.0" + "@babel/parser" "^7.4.3" + "@babel/template" "^7.4.0" + "@babel/traverse" "^7.4.3" + "@babel/types" "^7.4.0" + istanbul-lib-coverage "^2.0.5" + semver "^6.0.0" + +istanbul-lib-report@^2.0.4: + version "2.0.8" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" + integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== + dependencies: + istanbul-lib-coverage "^2.0.5" + make-dir "^2.1.0" + supports-color "^6.1.0" + +istanbul-lib-source-maps@^3.0.1: + version "3.0.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" + integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^2.0.5" + make-dir "^2.1.0" + rimraf "^2.6.3" + source-map "^0.6.1" + +istanbul-reports@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.6.tgz#7b4f2660d82b29303a8fe6091f8ca4bf058da1af" + integrity sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA== + dependencies: + handlebars "^4.1.2" jacoco-parse@^2.x: version "2.0.1" @@ -2113,6 +2944,360 @@ jacoco-parse@^2.x: mocha "^5.2.0" xml2js "^0.4.9" +jest-changed-files@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" + integrity sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg== + dependencies: + "@jest/types" "^24.9.0" + execa "^1.0.0" + throat "^4.0.0" + +jest-cli@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" + integrity sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg== + dependencies: + "@jest/core" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + exit "^0.1.2" + import-local "^2.0.0" + is-ci "^2.0.0" + jest-config "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + prompts "^2.0.1" + realpath-native "^1.1.0" + yargs "^13.3.0" + +jest-config@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" + integrity sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ== + dependencies: + "@babel/core" "^7.1.0" + "@jest/test-sequencer" "^24.9.0" + "@jest/types" "^24.9.0" + babel-jest "^24.9.0" + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^24.9.0" + jest-environment-node "^24.9.0" + jest-get-type "^24.9.0" + jest-jasmine2 "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + micromatch "^3.1.10" + pretty-format "^24.9.0" + realpath-native "^1.1.0" + +jest-diff@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" + integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== + dependencies: + chalk "^2.0.1" + diff-sequences "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + +jest-docblock@^24.3.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" + integrity sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA== + dependencies: + detect-newline "^2.1.0" + +jest-each@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" + integrity sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog== + dependencies: + "@jest/types" "^24.9.0" + chalk "^2.0.1" + jest-get-type "^24.9.0" + jest-util "^24.9.0" + pretty-format "^24.9.0" + +jest-environment-jsdom@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz#4b0806c7fc94f95edb369a69cc2778eec2b7375b" + integrity sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + jest-util "^24.9.0" + jsdom "^11.5.1" + +jest-environment-node@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" + integrity sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA== + dependencies: + "@jest/environment" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/types" "^24.9.0" + jest-mock "^24.9.0" + jest-util "^24.9.0" + +jest-get-type@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" + integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== + +jest-haste-map@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" + integrity sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ== + dependencies: + "@jest/types" "^24.9.0" + anymatch "^2.0.0" + fb-watchman "^2.0.0" + graceful-fs "^4.1.15" + invariant "^2.2.4" + jest-serializer "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.9.0" + micromatch "^3.1.10" + sane "^4.0.3" + walker "^1.0.7" + optionalDependencies: + fsevents "^1.2.7" + +jest-jasmine2@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" + integrity sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw== + dependencies: + "@babel/traverse" "^7.1.0" + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + co "^4.6.0" + expect "^24.9.0" + is-generator-fn "^2.0.0" + jest-each "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-runtime "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + pretty-format "^24.9.0" + throat "^4.0.0" + +jest-leak-detector@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" + integrity sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA== + dependencies: + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + +jest-matcher-utils@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" + integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== + dependencies: + chalk "^2.0.1" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + pretty-format "^24.9.0" + +jest-message-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" + integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/stack-utils" "^1.0.1" + chalk "^2.0.1" + micromatch "^3.1.10" + slash "^2.0.0" + stack-utils "^1.0.1" + +jest-mock@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" + integrity sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w== + dependencies: + "@jest/types" "^24.9.0" + +jest-pnp-resolver@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" + integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== + +jest-regex-util@^24.3.0, jest-regex-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" + integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== + +jest-resolve-dependencies@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" + integrity sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g== + dependencies: + "@jest/types" "^24.9.0" + jest-regex-util "^24.3.0" + jest-snapshot "^24.9.0" + +jest-resolve@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" + integrity sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ== + dependencies: + "@jest/types" "^24.9.0" + browser-resolve "^1.11.3" + chalk "^2.0.1" + jest-pnp-resolver "^1.2.1" + realpath-native "^1.1.0" + +jest-runner@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" + integrity sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg== + dependencies: + "@jest/console" "^24.7.1" + "@jest/environment" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + chalk "^2.4.2" + exit "^0.1.2" + graceful-fs "^4.1.15" + jest-config "^24.9.0" + jest-docblock "^24.3.0" + jest-haste-map "^24.9.0" + jest-jasmine2 "^24.9.0" + jest-leak-detector "^24.9.0" + jest-message-util "^24.9.0" + jest-resolve "^24.9.0" + jest-runtime "^24.9.0" + jest-util "^24.9.0" + jest-worker "^24.6.0" + source-map-support "^0.5.6" + throat "^4.0.0" + +jest-runtime@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" + integrity sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw== + dependencies: + "@jest/console" "^24.7.1" + "@jest/environment" "^24.9.0" + "@jest/source-map" "^24.3.0" + "@jest/transform" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/yargs" "^13.0.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.1.15" + jest-config "^24.9.0" + jest-haste-map "^24.9.0" + jest-message-util "^24.9.0" + jest-mock "^24.9.0" + jest-regex-util "^24.3.0" + jest-resolve "^24.9.0" + jest-snapshot "^24.9.0" + jest-util "^24.9.0" + jest-validate "^24.9.0" + realpath-native "^1.1.0" + slash "^2.0.0" + strip-bom "^3.0.0" + yargs "^13.3.0" + +jest-serializer@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" + integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== + +jest-snapshot@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" + integrity sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew== + dependencies: + "@babel/types" "^7.0.0" + "@jest/types" "^24.9.0" + chalk "^2.0.1" + expect "^24.9.0" + jest-diff "^24.9.0" + jest-get-type "^24.9.0" + jest-matcher-utils "^24.9.0" + jest-message-util "^24.9.0" + jest-resolve "^24.9.0" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^24.9.0" + semver "^6.2.0" + +jest-util@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" + integrity sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg== + dependencies: + "@jest/console" "^24.9.0" + "@jest/fake-timers" "^24.9.0" + "@jest/source-map" "^24.9.0" + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + callsites "^3.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.15" + is-ci "^2.0.0" + mkdirp "^0.5.1" + slash "^2.0.0" + source-map "^0.6.0" + +jest-validate@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" + integrity sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ== + dependencies: + "@jest/types" "^24.9.0" + camelcase "^5.3.1" + chalk "^2.0.1" + jest-get-type "^24.9.0" + leven "^3.1.0" + pretty-format "^24.9.0" + +jest-watcher@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.9.0.tgz#4b56e5d1ceff005f5b88e528dc9afc8dd4ed2b3b" + integrity sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw== + dependencies: + "@jest/test-result" "^24.9.0" + "@jest/types" "^24.9.0" + "@types/yargs" "^13.0.0" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + jest-util "^24.9.0" + string-length "^2.0.0" + +jest-worker@^24.6.0, jest-worker@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" + integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== + dependencies: + merge-stream "^2.0.0" + supports-color "^6.1.0" + +jest@24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" + integrity sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw== + dependencies: + import-local "^2.0.0" + jest-cli "^24.9.0" + joi@^13.x: version "13.7.0" resolved "https://registry.yarnpkg.com/joi/-/joi-13.7.0.tgz#cfd85ebfe67e8a1900432400b4d03bbd93fb879f" @@ -2122,12 +3307,12 @@ joi@^13.x: isemail "3.x.x" topo "3.x.x" -js-tokens@^4.0.0: +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@3.x, js-yaml@^3.13.0, js-yaml@^3.13.1: +js-yaml@^3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -2140,6 +3325,43 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= +jsdom@^11.5.1: + version "11.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" + integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== + dependencies: + abab "^2.0.0" + acorn "^5.5.3" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle "^1.0.0" + data-urls "^1.0.0" + domexception "^1.0.1" + escodegen "^1.9.1" + html-encoding-sniffer "^1.0.2" + left-pad "^1.3.0" + nwsapi "^2.0.7" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.87.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.4" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^5.2.0" + xml-name-validator "^3.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -2172,6 +3394,13 @@ json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= +json5@2.x, json5@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6" + integrity sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ== + dependencies: + minimist "^1.2.0" + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -2223,6 +3452,11 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + labeled-stream-splicer@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz#42a41a16abcd46fd046306cf4f2c3576fffb1c21" @@ -2243,6 +3477,16 @@ lcov-parse@^1.x: resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-1.0.0.tgz#eb0d46b54111ebc561acb4c408ef9363bdc8f7e0" integrity sha1-6w1GtUER68VhrLTECO+TY73I9+A= +left-pad@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -2251,6 +3495,34 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -2264,10 +3536,20 @@ lodash.memoize@~3.0.3: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" integrity sha1-LcvSwofLwKVcxCMovQxzYVDVPj8= -lodash@4.17.14, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.4: - version "4.17.14" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" - integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash.unescape@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" + integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= + +lodash@4.17.15, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.4: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== log-driver@^1.x: version "1.2.7" @@ -2281,6 +3563,33 @@ log-symbols@^2.2.0: dependencies: chalk "^2.0.1" +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-error@1.x: + version "1.3.5" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" + integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= + dependencies: + tmpl "1.0.x" + map-age-cleaner@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" @@ -2318,10 +3627,15 @@ mem@^4.0.0: mimic-fn "^2.0.0" p-is-promise "^2.0.0" +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + merge2@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" - integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" + integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== merge@^1.2.1: version "1.2.1" @@ -2387,7 +3701,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4: +minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -2409,20 +3723,20 @@ minimist@~0.0.1: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= -minipass@^2.2.1, minipass@^2.3.5: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== +minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== dependencies: safe-buffer "^5.1.2" yallist "^3.0.0" minizlib@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" - integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== dependencies: - minipass "^2.2.1" + minipass "^2.9.0" mixin-deep@^1.2.0: version "1.3.2" @@ -2437,14 +3751,14 @@ mkdirp@0.3.0: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" integrity sha1-G79asbqCevI1dRQ0kEJkVfSB/h4= -mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1: +mkdirp@0.5.1, mkdirp@0.x, mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" -mocha@5.2.0, mocha@^5.2.0: +mocha@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== @@ -2543,6 +3857,27 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + +node-modules-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" + integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= + +node-notifier@^5.4.2: + version "5.4.3" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" + integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== + dependencies: + growly "^1.3.0" + is-wsl "^1.1.0" + semver "^5.5.0" + shellwords "^0.1.1" + which "^1.3.0" + node-pre-gyp@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" @@ -2559,12 +3894,12 @@ node-pre-gyp@^0.12.0: semver "^5.3.0" tar "^4" -node-releases@^1.1.25: - version "1.1.25" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.25.tgz#0c2d7dbc7fed30fbe02a9ee3007b8c90bf0133d3" - integrity sha512-fI5BXuk83lKEoZDdH3gRhtsNgh05/wZacuXkgbiYkceE7+QIMXOg98n9ZV7mz27B+kFHnqHcUpscZZlGRSmTpQ== +node-releases@^1.1.29: + version "1.1.34" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.34.tgz#ced4655ee1ba9c3a2c5dcbac385e19434155fd40" + integrity sha512-fNn12JTEfniTuCqo0r9jXgl44+KxRH/huV7zM/KAGOKxDKrHr6EbT7SSs4B+DNxyBE2mks28AD+Jw6PkfY5uwA== dependencies: - semver "^5.3.0" + semver "^6.3.0" nopt@1.0.10: version "1.0.10" @@ -2573,13 +3908,6 @@ nopt@1.0.10: dependencies: abbrev "1" -nopt@3.x: - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= - dependencies: - abbrev "1" - nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" @@ -2588,6 +3916,16 @@ nopt@^4.0.1: abbrev "1" osenv "^0.1.4" +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -2645,6 +3983,11 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= +nwsapi@^2.0.7: + version "2.1.4" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.1.4.tgz#e006a878db23636f8e8a67d33ca0e4edf61a842f" + integrity sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw== + oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -2664,6 +4007,16 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-inspect@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" + integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" @@ -2671,6 +4024,14 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -2678,7 +4039,17 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: +object.values@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.0.tgz#bf6810ef5da3e5325790eaaa2be213ea84624da9" + integrity sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.12.0" + function-bind "^1.1.1" + has "^1.0.3" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -2749,6 +4120,13 @@ p-defer@^1.0.0: resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= +p-each-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" + integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= + dependencies: + p-reduce "^1.0.0" + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -2759,13 +4137,27 @@ p-is-promise@^2.0.0: resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + p-limit@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" - integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== + version "2.2.1" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" + integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== dependencies: p-try "^2.0.0" +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + p-locate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" @@ -2773,6 +4165,16 @@ p-locate@^3.0.0: dependencies: p-limit "^2.0.0" +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -2798,9 +4200,9 @@ parents@^1.0.0, parents@^1.0.1: path-platform "~0.11.15" parse-asn1@^5.0.0: - version "5.1.4" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.4.tgz#37f6628f823fbdeb2273b4d540434a22f3ef1fcc" - integrity sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw== + version "5.1.5" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" + integrity sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ== dependencies: asn1.js "^4.0.0" browserify-aes "^1.0.0" @@ -2809,6 +4211,13 @@ parse-asn1@^5.0.0: pbkdf2 "^3.0.3" safe-buffer "^5.1.1" +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -2817,6 +4226,11 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== + pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" @@ -2842,11 +4256,6 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" @@ -2862,6 +4271,13 @@ path-platform@~0.11.15: resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2" integrity sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I= +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -2885,7 +4301,7 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -pify@^2.3.0: +pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= @@ -2900,12 +4316,38 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== +pirates@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" + integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== + dependencies: + node-modules-regexp "^1.0.0" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -postcss-cli@^6.1.2: +postcss-cli@^6.1.3: version "6.1.3" resolved "https://registry.yarnpkg.com/postcss-cli/-/postcss-cli-6.1.3.tgz#a9eec3e9cde4aaa90170546baf706f8af6f8ecec" integrity sha512-eieqJU+OR1OFc/lQqMsDmROTJpoMZFvoAQ+82utBQ8/8qGMTfH9bBSPsTdsagYA8uvNzxHw2I2cNSSJkLAGhvw== @@ -2941,15 +4383,15 @@ postcss-reporter@^6.0.0: log-symbols "^2.2.0" postcss "^7.0.7" -postcss-value-parser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.0.tgz#99a983d365f7b2ad8d0f9b8c3094926eab4b936d" - integrity sha512-ESPktioptiSUchCKgggAkzdmkgzKfmp0EU8jXH+5kbIUB+unr0Y4CY9SRMvibuvYUBjNh1ACLbxqYNpdTQOteQ== +postcss-value-parser@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz#482282c09a42706d1fc9a069b73f44ec08391dc9" + integrity sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ== -postcss@^7.0.0, postcss@^7.0.17, postcss@^7.0.7: - version "7.0.17" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.17.tgz#4da1bdff5322d4a0acaab4d87f3e782436bad31f" - integrity sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ== +postcss@^7.0.0, postcss@^7.0.18, postcss@^7.0.7: + version "7.0.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.18.tgz#4b9cda95ae6c069c67a4d933029eddd4838ac233" + integrity sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g== dependencies: chalk "^2.4.2" source-map "^0.6.1" @@ -2960,6 +4402,28 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@1.18.2: + version "1.18.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea" + integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw== + +pretty-format@^24.9.0: + version "24.9.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" + integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== + dependencies: + "@jest/types" "^24.9.0" + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" + react-is "^16.8.4" + pretty-hrtime@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" @@ -2980,10 +4444,18 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== +prompts@^2.0.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.2.1.tgz#f901dd2a2dfee080359c0e20059b24188d75ad35" + integrity sha512-VObPvJiWPhpZI6C5m60XOzTfnYg/xc/an+r9VYymj9WJW3B/DIH+REzjpAACPf8brwPeP+7vz3bIim3S+AaMjw== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.3" + psl@^1.1.24, psl@^1.1.28: - version "1.2.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.2.0.tgz#df12b5b1b3a30f51c329eacbdef98f3a6e136dc6" - integrity sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA== + version "1.4.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.4.0.tgz#5dd26156cdb69fa1fdb8ab1991667d3f80ced7c2" + integrity sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw== public-encrypt@^4.0.0: version "4.0.3" @@ -3060,6 +4532,11 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-is@^16.8.4: + version "16.10.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.10.2.tgz#984120fd4d16800e9a738208ab1fba422d23b5ab" + integrity sha512-INBT1QEgtcCCgvccr5/86CfD71fw9EPmDxgiJX4I2Ddr6ZsV6iFXsuby+qWJPtmNuMY0zByTsG4468P7nHuNWA== + read-cache@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" @@ -3074,7 +4551,41 @@ read-only-stream@^2.0.0: dependencies: readable-stream "^2.0.2" -readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.3.6, readable-stream@~2.3.6: +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg-up@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" + integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== + dependencies: + find-up "^3.0.0" + read-pkg "^3.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -3087,6 +4598,15 @@ readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@^3.0.6: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" + integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -3096,6 +4616,13 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" +realpath-native@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" + integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== + dependencies: + util.promisify "^1.0.0" + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -3131,6 +4658,15 @@ request-promise-core@1.1.2: dependencies: lodash "^4.17.11" +request-promise-native@^1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.7.tgz#a49868a624bdea5069f1251d0a836e0d89aa2c59" + integrity sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w== + dependencies: + request-promise-core "1.1.2" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + request-promise@^4.x: version "4.2.4" resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-4.2.4.tgz#1c5ed0d71441e38ad58c7ce4ea4ea5b06d54b310" @@ -3141,7 +4677,7 @@ request-promise@^4.x: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.88.0: +request@^2.87.0, request@^2.88.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== @@ -3177,6 +4713,18 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" @@ -3192,15 +4740,15 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@1.1.7, resolve@1.1.x: +resolve@1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.4, resolve@^1.4.0: - version "1.11.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" - integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== +resolve@1.x, resolve@^1.1.4, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6" + integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w== dependencies: path-parse "^1.0.6" @@ -3217,13 +4765,20 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -rimraf@2.6.3, rimraf@^2.6.1: +rimraf@2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== dependencies: glob "^7.1.3" +rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -3232,6 +4787,11 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" +rsvp@^4.8.4: + version "4.8.5" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" + integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== + run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" @@ -3240,13 +4800,13 @@ run-async@^2.2.0: is-promise "^2.1.0" rxjs@^6.4.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.2.tgz#2e35ce815cd46d84d02a209fb4e5921e051dbec7" - integrity sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg== + version "6.5.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" + integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== dependencies: tslib "^1.9.0" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== @@ -3268,15 +4828,40 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sane@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" + integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== + dependencies: + "@cnakazawa/watch" "^1.0.3" + anymatch "^2.0.0" + capture-exit "^2.0.0" + exec-sh "^0.3.2" + execa "^1.0.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + sax@>=0.6.0, sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -semver@^5.3.0, semver@^5.5.0, semver@^5.5.1: - version "5.7.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" - integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== + +semver@^6.0.0, semver@^6.1.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" @@ -3322,14 +4907,14 @@ shebang-regex@^1.0.0: integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= shell-quote@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" - integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= - dependencies: - array-filter "~0.0.0" - array-map "~0.0.0" - array-reduce "~0.0.0" - jsonify "~0.0.0" + version "1.7.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" @@ -3341,6 +4926,11 @@ simple-concat@^1.0.0: resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= +sisteransi@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.3.tgz#98168d62b79e3a5e758e27ae63c4a053d748f4eb" + integrity sha512-SbEG75TzH8G7eVXFSN5f9EExILKfly7SUvVY5DhhYLvfhKqhDFY0OzevWa/zwak0RLRfWS5AvfMWpd9gJvr5Yg== + slash@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" @@ -3396,27 +4986,54 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" +source-map-support@^0.5.6, source-map-support@~0.5.12: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= -source-map@^0.5.6, source-map@~0.5.3: +source-map@^0.5.0, source-map@^0.5.6, source-map@~0.5.3: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" - integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== dependencies: - amdefine ">=0.0.4" + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" + integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -3445,6 +5062,11 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" +stack-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" + integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -3474,15 +5096,14 @@ stream-combiner2@^1.1.1: duplexer2 "~0.1.0" readable-stream "^2.0.2" -stream-http@^2.0.0: - version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== +stream-http@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.1.0.tgz#22fb33fe9b4056b4eccf58bd8f400c4b993ffe57" + integrity sha512-cuB6RgO7BqC4FBYzmnvhob5Do3wIdIsXAgGycHJnW+981gHqoYcYz9lqjJrk8WXRddbwPuqPYRl+bag6mYv4lw== dependencies: builtin-status-codes "^3.0.0" inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" + readable-stream "^3.0.6" xtend "^4.0.0" stream-splicer@^2.0.0: @@ -3493,6 +5114,14 @@ stream-splicer@^2.0.0: inherits "^2.0.1" readable-stream "^2.0.2" +string-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" + integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= + dependencies: + astral-regex "^1.0.0" + strip-ansi "^4.0.0" + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -3510,7 +5139,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string-width@^3.0.0: +string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== @@ -3519,12 +5148,28 @@ string-width@^3.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string_decoder@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" - integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== +string.prototype.trimleft@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" + integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== dependencies: - safe-buffer "~5.1.0" + define-properties "^1.1.3" + function-bind "^1.1.1" + +string.prototype.trimright@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" + integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" string_decoder@~1.1.1: version "1.1.1" @@ -3547,19 +5192,29 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^5.1.0: +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== dependencies: ansi-regex "^4.1.0" +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= -strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: +strip-json-comments@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" + integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== + +strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= @@ -3578,13 +5233,6 @@ supports-color@5.4.0: dependencies: has-flag "^3.0.0" -supports-color@^3.1.0: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= - dependencies: - has-flag "^1.0.0" - supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -3599,6 +5247,11 @@ supports-color@^6.1.0: dependencies: has-flag "^3.0.0" +symbol-tree@^3.2.2: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + syntax-error@^1.1.1: version "1.4.0" resolved "https://registry.yarnpkg.com/syntax-error/-/syntax-error-1.4.0.tgz#2d9d4ff5c064acb711594a3e3b95054ad51d907c" @@ -3607,33 +5260,57 @@ syntax-error@^1.1.1: acorn-node "^1.2.0" table@^5.2.3: - version "5.4.1" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.1.tgz#0691ae2ebe8259858efb63e550b6d5f9300171e8" - integrity sha512-E6CK1/pZe2N75rGZQotFOdmzWQ1AILtgYbMAbAjvms0S1l5IDB47zG3nCnFGB/w+7nB3vKofbLXCH7HPBo864w== + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== dependencies: - ajv "^6.9.1" - lodash "^4.17.11" + ajv "^6.10.2" + lodash "^4.17.14" slice-ansi "^2.1.0" string-width "^3.0.0" tar@^4: - version "4.4.10" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" - integrity sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA== + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== dependencies: chownr "^1.1.1" fs-minipass "^1.2.5" - minipass "^2.3.5" + minipass "^2.8.6" minizlib "^1.2.1" mkdirp "^0.5.0" safe-buffer "^5.1.2" yallist "^3.0.3" +terser@^4.3.8: + version "4.3.8" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.3.8.tgz#707f05f3f4c1c70c840e626addfdb1c158a17136" + integrity sha512-otmIRlRVmLChAWsnSFNO0Bfk6YySuBp6G9qrHiJwlLDd4mxe2ta4sjI7TzIR+W1nBMjilzrMcPOz9pSusgx3hQ== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +test-exclude@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" + integrity sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g== + dependencies: + glob "^7.1.3" + minimatch "^3.0.4" + read-pkg-up "^4.0.0" + require-main-filename "^2.0.0" + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= + through2@^2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -3661,10 +5338,15 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" -to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= to-object-path@^0.3.0: version "0.3.0" @@ -3698,7 +5380,7 @@ topo@3.x.x: dependencies: hoek "6.x.x" -tough-cookie@^2.3.3: +tough-cookie@^2.3.3, tough-cookie@^2.3.4: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -3714,11 +5396,40 @@ tough-cookie@~2.4.3: psl "^1.1.24" punycode "^1.4.1" -tslib@^1.9.0: +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +ts-jest@24.0.2: + version "24.0.2" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.0.2.tgz#8dde6cece97c31c03e80e474c749753ffd27194d" + integrity sha512-h6ZCZiA1EQgjczxq+uGLXQlNgeg02WWJBbeT8j6nyIBRQdglqbvzDoHahTEIiS6Eor6x8mK6PfZ7brQ9Q6tzHw== + dependencies: + bs-logger "0.x" + buffer-from "1.x" + fast-json-stable-stringify "2.x" + json5 "2.x" + make-error "1.x" + mkdirp "0.x" + resolve "1.x" + semver "^5.5" + yargs-parser "10.x" + +tslib@^1.8.1, tslib@^1.9.0: version "1.10.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== +tsutils@^3.14.0: + version "3.17.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" + integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== + dependencies: + tslib "^1.8.1" + tty-browserify@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811" @@ -3748,7 +5459,12 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -uglify-js@^3.1.4, uglify-js@^3.6.0: +typescript@^3.6.3: + version "3.6.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.3.tgz#fea942fabb20f7e1ca7164ff626f1a9f3f70b4da" + integrity sha512-N7bceJL1CtRQ2RiG0AQME13ksR7DiuQh/QehubYcghzv20tnh+MQnQIuJddTmsbqYj+dztchykemz0zFzlvdQw== + +uglify-js@^3.1.4: version "3.6.0" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5" integrity sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg== @@ -3796,9 +5512,9 @@ unset-value@^1.0.0: isobject "^3.0.0" upath@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" - integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== uri-js@^4.2.2: version "4.2.2" @@ -3825,11 +5541,19 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +util.promisify@^1.0.0, util.promisify@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" @@ -3845,9 +5569,22 @@ util@~0.10.1: inherits "2.0.3" uuid@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + version "3.3.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" + integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== + +v8-compile-cache@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" + integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" verror@1.10.0: version "1.10.0" @@ -3863,17 +5600,66 @@ vm-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019" integrity sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw== +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU= + dependencies: + browser-process-hrtime "^0.1.2" + +walker@^1.0.7, walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + dependencies: + makeerror "1.0.x" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + whatwg-fetch@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== +whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +whatwg-url@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" + integrity sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.1.1, which@^1.2.9: +which@^1.2.9, which@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -3887,16 +5673,16 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -wordwrap@^1.0.0, wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - wordwrap@~0.0.2: version "0.0.3" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" @@ -3905,11 +5691,29 @@ wrap-ansi@^2.0.0: string-width "^1.0.1" strip-ansi "^3.0.1" +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +write-file-atomic@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" + integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + write@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" @@ -3917,33 +5721,53 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" +ws@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" + integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== + dependencies: + async-limiter "~1.0.0" + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + xml2js@^0.4.9: - version "0.4.19" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" - integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== + version "0.4.22" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.22.tgz#4fa2d846ec803237de86f30aa9b5f70b6600de02" + integrity sha512-MWTbxAQqclRSTnehWWe5nMKzI3VmJ8ltiJEco8akcC6j3miOhjjfzKum5sId+CWhfxdOs/1xauYr8/ZDBtQiRw== dependencies: sax ">=0.6.0" - xmlbuilder "~9.0.1" + util.promisify "~1.0.0" + xmlbuilder "~11.0.0" -xmlbuilder@~9.0.1: - version "9.0.7" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" - integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: +xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== -"y18n@^3.2.1 || ^4.0.0": +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== yallist@^3.0.0, yallist@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" - integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yargs-parser@10.x: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== + dependencies: + camelcase "^4.1.0" yargs-parser@^11.1.1: version "11.1.1" @@ -3953,6 +5777,14 @@ yargs-parser@^11.1.1: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-parser@^13.1.1: + version "13.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" + integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + yargs@^12.0.1: version "12.0.5" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" @@ -3970,3 +5802,19 @@ yargs@^12.0.1: which-module "^2.0.0" y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" + +yargs@^13.3.0: + version "13.3.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" + integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.1"

    3+>If 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 diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index b6cea50..0000000 --- a/docs/index.html +++ /dev/null @@ -1,433 +0,0 @@ - - - - - - - - - - - - diff2html - - - - - - - - - - - - - - - - - - - - - - -