From 915178d28a11ad6574c1f3dff6b51c928f5b963c Mon Sep 17 00:00:00 2001 From: Levi Olson Date: Wed, 27 Jan 2021 14:42:49 -0600 Subject: [PATCH] Better Search; JSONEditor; Vertical View; Minor Fixes --- .gitignore | 1 + Makefile | 23 + package-lock.json | 233 + unpacked/manifest.json | 2 +- unpacked/panel/assets/javascripts/app.js | 34 +- unpacked/panel/assets/javascripts/panel.js | 388 +- unpacked/panel/assets/stylesheets/panel.css | 685 +- .../panel/assets/stylesheets/panel.css.map | 1 + unpacked/panel/assets/stylesheets/panel.scss | 424 + unpacked/panel/panel.html | 473 +- .../javascripts/img/jsoneditor-icons.svg | 749 + .../vendor/assets/javascripts/jsoneditor.js | 52682 ++++++++++++++++ .../stylesheets/img/jsoneditor-icons.svg | 749 + .../vendor/assets/stylesheets/jsoneditor.css | 2004 + 14 files changed, 57726 insertions(+), 722 deletions(-) create mode 100644 Makefile create mode 100644 package-lock.json create mode 100644 unpacked/panel/assets/stylesheets/panel.css.map create mode 100755 unpacked/panel/assets/stylesheets/panel.scss create mode 100644 unpacked/panel/vendor/assets/javascripts/img/jsoneditor-icons.svg create mode 100644 unpacked/panel/vendor/assets/javascripts/jsoneditor.js create mode 100644 unpacked/panel/vendor/assets/stylesheets/img/jsoneditor-icons.svg create mode 100644 unpacked/panel/vendor/assets/stylesheets/jsoneditor.css diff --git a/.gitignore b/.gitignore index c4c4ffc..6f63d2c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.zip +node_modules \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0738583 --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +COMMAND_COLOR = \033[36m +DESC_COLOR = \033[32m +CLEAR_COLOR = \033[0m + +.PHONY: help +help: ## prints this message ## + @echo ""; \ + echo "Usage: make "; \ + echo ""; \ + echo "where is one of the following:"; \ + echo ""; \ + grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ + perl -nle '/(.*?): ## (.*?) ## (.*$$)/; if ($$3 eq "") { printf ( "$(COMMAND_COLOR)%-20s$(DESC_COLOR)%s$(CLEAR_COLOR)\n\n", $$1, $$2) } else { printf ( "$(COMMAND_COLOR)%-20s$(DESC_COLOR)%s$(CLEAR_COLOR)\n%-20s%s\n\n", $$1, $$2, " ", $$3) }'; + +.PHONY: install +install: ## Install npm packages ## + @echo "Installing Dependencies..."; \ + npm install; + +.PHONY: sass +sass: ## sass --watch input.scss output.css ## + @echo "Compiling Sass..."; \ + ./node_modules/.bin/sass --watch unpacked/panel/assets/stylesheets/panel.scss unpacked/panel/assets/stylesheets/panel.css; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d175640 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,233 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@sphinxxxx/color-conversion": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@sphinxxxx/color-conversion/-/color-conversion-2.2.2.tgz", + "integrity": "sha512-XExJS3cLqgrmNBIP3bBw6+1oQ1ksGjFh0+oClDKFYpCCqx/hlqwWO5KO/S63fzUo67SxI9dMrF0y5T/Ey7h8Zw==" + }, + "ace-builds": { + "version": "1.4.12", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.4.12.tgz", + "integrity": "sha512-G+chJctFPiiLGvs3+/Mly3apXTcfgE45dT5yp12BcWZ1kUs+gm0qd3/fv4gsz6fVag4mM0moHVpjHDIgph6Psg==" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.1.tgz", + "integrity": "sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==", + "optional": true + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=" + }, + "jmespath": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" + }, + "jquery": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz", + "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/json-source-map/-/json-source-map-0.6.1.tgz", + "integrity": "sha512-1QoztHPsMQqhDq0hlXY5ZqcEdUzxQEIxgFkKl4WUp2pgShObl+9ovi4kRh2TfvAfxAoHOJ9vIMEqk3k4iex7tg==" + }, + "jsoneditor": { + "version": "9.1.8", + "resolved": "https://registry.npmjs.org/jsoneditor/-/jsoneditor-9.1.8.tgz", + "integrity": "sha512-T7iZjrYdtFqVuUFelwni9UKp6jXklYa0O0VmohMhYjBBx356h9S7qHZnxoVenXBSmLrYA4SthIt8cY+4zKvFRQ==", + "requires": { + "ace-builds": "^1.4.12", + "ajv": "^6.12.6", + "javascript-natural-sort": "^0.7.1", + "jmespath": "^0.15.0", + "json-source-map": "^0.6.1", + "jsonrepair": "^2.0.0", + "mobius1-selectr": "^2.4.13", + "picomodal": "^3.0.0", + "vanilla-picker": "^2.11.0" + } + }, + "jsonrepair": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jsonrepair/-/jsonrepair-2.0.0.tgz", + "integrity": "sha512-beGD14VPmrQNt/Sspi12sCGT+N3w7FWM1T2UJx7biEMfGIUUpqBBPjHq8ETKA992+JS+fSnrSHxKHq7AIgdgcA==" + }, + "mobius1-selectr": { + "version": "2.4.13", + "resolved": "https://registry.npmjs.org/mobius1-selectr/-/mobius1-selectr-2.4.13.tgz", + "integrity": "sha512-Mk9qDrvU44UUL0EBhbAA1phfQZ7aMZPjwtL7wkpiBzGh8dETGqfsh50mWoX9EkjDlkONlErWXArHCKfoxVg0Bw==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + }, + "picomodal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/picomodal/-/picomodal-3.0.0.tgz", + "integrity": "sha1-+s0w9PvzSoCcHgTqUl8ATzmcC4I=" + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "sass": { + "version": "1.32.5", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.5.tgz", + "integrity": "sha512-kU1yJ5zUAmPxr7f3q0YXTAd1oZjSR1g3tYyv+xu0HZSl5JiNOaE987eiz7wCUvbm4I9fGWGU2TgApTtcP4GMNQ==", + "requires": { + "chokidar": ">=2.0.0 <4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "vanilla-picker": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/vanilla-picker/-/vanilla-picker-2.11.0.tgz", + "integrity": "sha512-MsTAyROQRN3yoUdToiQtfnW752wC9DpnXbOhAMGJgBi+TMDZ0IUfbmIVB5u3P1ltBDlqy8TjY59a4lOioSlgZw==", + "requires": { + "@sphinxxxx/color-conversion": "^2.2.2" + } + } + } +} diff --git a/unpacked/manifest.json b/unpacked/manifest.json index e83e96a..b518560 100644 --- a/unpacked/manifest.json +++ b/unpacked/manifest.json @@ -1,6 +1,6 @@ { "name": "Better Network Panel", - "version": "0.9.1", + "version": "1.0.0", "minimum_chrome_version": "44.0", "description": "Extends the Developer Tools, adding a new Network Panel in the Developer Tools window with better searching and response previews.", "devtools_page": "devtools.html", diff --git a/unpacked/panel/assets/javascripts/app.js b/unpacked/panel/assets/javascripts/app.js index c2c7a66..18b98ac 100755 --- a/unpacked/panel/assets/javascripts/app.js +++ b/unpacked/panel/assets/javascripts/app.js @@ -63,12 +63,6 @@ var BNPChrome = angular } else if (typeof data === "string" && (data[0] === "{" || data[0] === "[")) { $el = $("
");
 					data = JSON.stringify(parse(data, 0), null, 4);
-                    // try {
-                    //     data = JSON.stringify(JSON.parse(data), null, 4);
-                    //     // $el.text()
-                    // } catch (e) {
-                    //     console.debug("Error parsing", data);
-                    // }
                 } else if (typeof data === "string") {
                     // i.e. a string but not a JSON stringified string
                     data = $("
").text(data).html(); @@ -110,6 +104,12 @@ var BNPChrome = angular $target.data("resizableColumns").syncHandleWidths(); $target.data("resizableColumns").saveColumnWidths(); }); + // $(window).on("resize", function () { + // // console.log('resize event'); + // // var $target = $($(element).data("resizable-columns-sync")); + // // $target.data("resizableColumns").refreshHeaders(); + // // $(element).resizableColumns(options); + // }) } $(element).resizableColumns(options); @@ -125,4 +125,26 @@ var BNPChrome = angular $container.scrollTop($parent.height()); } }; + }).directive('onSearch', function () { + return function (scope, element, attrs) { + element.bind("keypress", function (event) { + if((event.shiftKey && event.which === 220) || event.which === 13 || event.which === 44 || event.which === 124) { + scope.$apply(function (){ + scope.$eval(attrs.onSearch); + }); + + event.preventDefault(); + } + }); + }; + }).directive('ngRightClick', function($parse) { + return function(scope, element, attrs) { + element.bind('contextmenu', function(event) { + scope.$apply(function() { + scope.$eval(attrs.ngRightClick); + }); + + event.preventDefault(); + }); + }; }); diff --git a/unpacked/panel/assets/javascripts/panel.js b/unpacked/panel/assets/javascripts/panel.js index 0b282ab..46c28ce 100755 --- a/unpacked/panel/assets/javascripts/panel.js +++ b/unpacked/panel/assets/javascripts/panel.js @@ -28,18 +28,39 @@ Console.addMessage = function (type, format, args) { } })(); -BNPChrome.controller("PanelController", function PanelController($scope, toolbar, parse) { - $scope.uniqueid = 1000000; +BNPChrome.controller("PanelController", function PanelController($scope, toolbar, parse, $timeout) { + + const LOCALSTORAGE = window.localStorage; + const MAXBODYSIZE = 20000; + const HOST = "http://localhost:3000" // "https://leviolson.com" + const CHANGELOG = { + "What's New": { + "v1.0.0:": { + "Improved Search": HOST + "/posts/bnp-changelog#improved-search", + "JSON Editor BUILT IN": HOST + "/posts/bnp-changelog#json-editor-built-in", + "Vertical Chrome Panel": HOST + "/posts/bnp-changelog#vertical-chrome-panel", + "Download JSON": HOST + "/posts/bnp-changelog#download-json" + } + } + } + + $scope.search = ""; + $scope.searchTerms = []; + $scope.oldSearchTerms = []; + $scope.andFilter = true; + $scope.uniqueId = 100000; $scope.activeId = null; $scope.requests = {}; $scope.masterRequests = []; $scope.filteredRequests = []; $scope.showAll = true; - $scope.limitNetworkRequests = true; + $scope.limitNetworkRequests = false; $scope.showOriginal = false; $scope.currentDetailTab = "tab-response"; - + $scope.showIncomingRequests = true; $scope.myResponseCodeMirror = null; + $scope.filter = ""; + $scope.editor = null; $scope.activeCookies = []; $scope.activeHeaders = []; @@ -50,19 +71,60 @@ BNPChrome.controller("PanelController", function PanelController($scope, toolbar $scope.activeResponseHeaders = []; $scope.activeCode = null; - $scope.filter = ""; - - $scope.showIncomingRequests = true; - $scope.init = function (type) { $("#tabs").tabs(); $scope.initChrome(); - this.createToolbar(); + $scope.createToolbar(); + + const options = { + mode: 'view', + modes: ['code', 'view'], + onEditable: function (node) { + if (!node.path) { + // In modes code and text, node is empty: no path, field, or value + // returning false makes the text area read-only + return false; + } + return true + } + } + const response = document.getElementById('response-jsoneditor') + const request = document.getElementById('request-jsoneditor') + $scope.responseJsonEditor = new JSONEditor(response, options) + $scope.requestJsonEditor = new JSONEditor(request, options) + + $timeout(() => { + $scope.responseJsonEditor.set(CHANGELOG); + $scope.responseJsonEditor.expandAll(); + }) }; $scope.initChrome = function () { + try { + let oldSearchTerms = JSON.parse(LOCALSTORAGE.getItem('bnp-oldsearchterms')); + $scope.oldSearchTerms = oldSearchTerms || []; + } catch (e) { + $scope.oldSearchTerms = []; + } + + try { + let searchTerms = JSON.parse(LOCALSTORAGE.getItem('bnp-searchterms')); + $scope.searchTerms = searchTerms || []; + } catch (e) { + $scope.searchTerms = []; + } + + try { + let andFilter = JSON.parse(LOCALSTORAGE.getItem('bnp-andfilter')); + $scope.andFilter = andFilter || false; + } catch (e) { + $scope.andFilter = false; + } + + console.debug('Retrieving', $scope.andFilter, $scope.searchTerms, $scope.oldSearchTerms); + chrome.devtools.network.onRequestFinished.addListener(function (request) { // do not show requests to chrome extension resources if (request.request.url.startsWith("chrome-extension://")) { @@ -70,30 +132,109 @@ BNPChrome.controller("PanelController", function PanelController($scope, toolbar } $scope.handleRequest(request); }); + + chrome.devtools.network.onNavigated.addListener(function (event) { + console.log("Event", event); + $scope.masterRequests.push({ + id: $scope.uniqueId, + separator: true, + event: event + }); + $scope.uniqueId++; + $scope.cleanRequests(); + }); }; $scope.filterRequests = function () { - const searchString = $scope.filter.toLowerCase(); - if (!searchString) $scope.filteredRequests = $scope.masterRequests; + if (!$scope.searchTerms || $scope.searchTerms.length === 0) { + $scope.filteredRequests = $scope.masterRequests; + return; + } + // console.log("Filtering for: ", $scope.searchTerms); + + let negTerms = []; + let posTerms = []; + for (let term of $scope.searchTerms) { + term = term.toLowerCase(); + if (term && term[0] === '-') negTerms.push(term.substring(1)); + else posTerms.push(term); + } $scope.filteredRequests = $scope.masterRequests.filter(function (x) { - if (x && x.searchIndex && x.searchIndex.includes(searchString)) return true; + if (x.separator) return true; + for (let term of negTerms) { + // if neg + if (x && x.searchIndex && x.searchIndex.includes(term)) return false; + } + + if ($scope.andFilter) { + // AND condition + for (let term of posTerms) { + // if pos + if (x && x.searchIndex && !x.searchIndex.includes(term)) { + return false; + } + } + return true; + } else { + // OR condition + for (let term of posTerms) { + // if pos + if (x && x.searchIndex && x.searchIndex.includes(term)) { + return true; + } + } + return false; + } }); }; + $scope.toggleSearchType = function() { + $scope.andFilter = !$scope.andFilter; + _setLocalStorage(); + $scope.filterRequests(); + }; + + $scope.customSearch = function() { + if (!$scope.searchTerms.includes($scope.search)) { + $scope.searchTerms.push($scope.search); + $scope.search = ""; + _setLocalStorage(); + $scope.filterRequests() + } + }; + + _setLocalStorage = function() { + // do some sort of comparison to searchTerms and oldSearchTerms to make sure there is only one. + // although, now that I think about it... this comparison shouldn't be necessary... /shrug + LOCALSTORAGE.setItem('bnp-andfilter', JSON.stringify($scope.andFilter)); + LOCALSTORAGE.setItem('bnp-searchterms', JSON.stringify($scope.searchTerms)); + LOCALSTORAGE.setItem('bnp-oldsearchterms', JSON.stringify($scope.oldSearchTerms)); + console.debug('Saving', $scope.andFilter, $scope.searchTerms, $scope.oldSearchTerms); + } + + $scope.addSearchTerm = function(index) { + $scope.searchTerms.push($scope.oldSearchTerms.splice(index, 1)[0]); + _setLocalStorage(); + $scope.filterRequests(); + }; + + $scope.removeSearchTerm = function(index) { + $scope.oldSearchTerms.push($scope.searchTerms.splice(index, 1)[0]); + _setLocalStorage(); + $scope.filterRequests(); + }; + + $scope.deleteSearchTerm = function(index) { + $scope.oldSearchTerms.splice(index, 1); + _setLocalStorage(); + }; + $scope.handleRequest = function (har_entry) { $scope.addRequest(har_entry, har_entry.request.method, har_entry.request.url, har_entry.response.status, null); }; $scope.createToolbar = function () { - toolbar.createButton("search", "Search Code", false, function () { - // ga('send', 'event', 'button', 'click', 'Search Code'); - $scope.$apply(function () { - if ($scope.myResponseCodeMirror) { - $scope.myResponseCodeMirror.execCommand("find"); - } - }); - }); toolbar.createToggleButton( "embed", "JSON Parsing", @@ -111,28 +252,21 @@ BNPChrome.controller("PanelController", function PanelController($scope, toolbar toolbar.createButton("download3", "Download", false, function () { // ga('send', 'event', 'button', 'click', 'Download'); $scope.$apply(function () { - var blob = new Blob([JSON.stringify($scope.requests)], { type: "application/json;charset=utf-8" }); - saveAs(blob, "BNPChromeExport.json"); - }); - }); - toolbar.createButton("upload3", "Import", true, function () { - // ga('send', 'event', 'button', 'click', 'Import'); - $scope.$apply(function () { - $("#ImportInput").click(); + const panel = $scope.currentDetailTab; + if (panel === "tab-response") { + var blob = new Blob([JSON.parse(JSON.stringify($scope.activeCode, null, 4))], { type: "application/json;charset=utf-8" }); + saveAs(blob, "export_response.json"); + } else { + try { + var blob = new Blob([JSON.stringify($scope.activePostData)], { type: "application/json;charset=utf-8" }); + saveAs(blob, "export_request.json"); + } catch (e) { + console.log(e) + } + + } }); }); - toolbar.createToggleButton( - "meter", - "Limit network requests to 500", - false, - function () { - // ga('send', 'event', 'button', 'click', 'Toggle Limit Network Request'); - $scope.$apply(function () { - $scope.limitNetworkRequests = !$scope.limitNetworkRequests; - }); - }, - true - ); toolbar.createButton("blocked", "Clear", false, function () { // ga('send', 'event', 'button', 'click', 'Clear'); $scope.$apply(function () { @@ -141,40 +275,12 @@ BNPChrome.controller("PanelController", function PanelController($scope, toolbar }); $(".toolbar").replaceWith(toolbar.render()); - - //clears the input value so you can reload the same file - document.getElementById("ImportInput").addEventListener( - "click", - function () { - this.value = null; - }, - false - ); - document.getElementById("ImportInput").addEventListener("change", readFile, false); - function readFile(evt) { - const files = evt.target.files; - const file = files[0]; - const reader = new FileReader(); - reader.onload = function () { - $scope.importFile(this.result); - }; - reader.readAsText(file); - } - }; - - $scope.importFile = function (data) { - $scope.$apply(function () { - const importHar = JSON.parse(data); - for (i in importHar) { - $scope.handleRequest(importHar[i]); - } - }); }; $scope.addRequest = function (data, request_method, request_url, response_status) { $scope.$apply(function () { - const requestId = $scope.uniqueid; - $scope.uniqueid = $scope.uniqueid + 1; + const requestId = data.id || $scope.uniqueId; + $scope.uniqueId++ if (data.request != null) { data["request_data"] = $scope.createKeypairs(data.request); @@ -202,35 +308,25 @@ BNPChrome.controller("PanelController", function PanelController($scope, toolbar data["request_method"] = request_method; if (request_url.includes("apexremote")) { try { - let text = - data && data.request && data.request.postData && data.request.postData.text - ? JSON.parse(data.request.postData.text) - : ""; - data["request_apex_type"] = - text.data && typeof text.data[1] === "string" ? text.data[1] : JSON.stringify(text.data); + let text = data && data.request && data.request.postData && data.request.postData.text ? JSON.parse(data.request.postData.text) : ""; + data["request_apex_type"] = text.data && typeof text.data[1] === "string" ? text.data[1] : JSON.stringify(text.data); data["request_apex_method"] = text.method || ""; } catch (e) { console.debug("Error", e); } } - data["request_url"] = request_url; - data["response_status"] = response_status; - data["id"] = requestId; + data.request_url = request_url; + data.response_status = response_status; + data['id'] = requestId; + let ctObj = data.response_headers.find(x => x.name == "Content-Type") + data.content_type = ctObj && ctObj.value || null; $scope.requests[requestId] = data; // master - data.searchIndex = JSON.stringify(data).toLowerCase(); - // console.debug('SearchIndex', data.searchIndex) + data.searchIndex = JSON.stringify(data.request).toLowerCase(); $scope.masterRequests.push(data); - $scope.filteredRequests.push(data); data.getContent(function (content, encoding) { - try { - $scope.requests[requestId].response_data.response_body = JSON.stringify( - JSON.parse(content), - null, - 4 - ); - } catch (e) {} + $scope.requests[requestId].response_data.response_body = content; }); $scope.cleanRequests(); @@ -286,13 +382,19 @@ BNPChrome.controller("PanelController", function PanelController($scope, toolbar $scope.activeCode = $scope.requests[requestId].response_data.response_body; }; - $scope.getClass = function (requestId) { + $scope.getClass = function (requestId, separator) { + if (separator) return "separator" if (requestId === $scope.activeId) { return "selected"; } else { return ""; } }; + $scope.titleIfSeparator = function(separator) { + if (separator) + return "Page reloaded here" + return "" + }; $scope.createKeypairs = function (data) { let keypairs = []; @@ -330,8 +432,12 @@ BNPChrome.controller("PanelController", function PanelController($scope, toolbar }; $scope.$watch("activeCode", function (newVal, oldVal) { - $scope.displayCode("tab-response-codemirror", $scope.activeCode, "myResponseCodeMirror", 3); - $scope.displayCode("tab-request-codemirror", $scope.flatten($scope.activePostData), "myRequestCodeMirror", 6); + if (newVal === null) { + $scope.responseJsonEditor.set(null) + $scope.requestJsonEditor.set(null) + } + $scope.displayCode("responseJsonEditor", $scope.activeCode, 3); + $scope.displayCode("requestJsonEditor", $scope.activePostData, 6); }); $scope.selectDetailTab = function (tabId, external) { @@ -339,73 +445,55 @@ BNPChrome.controller("PanelController", function PanelController($scope, toolbar if (external) { $("#tabs a[href='#" + tabId + "']").trigger("click"); } - if (tabId === "tab-response") - $scope.displayCode("tab-response-codemirror", $scope.activeCode, "myResponseCodeMirror", 3); - if (tabId === "tab-request") - $scope.displayCode( - "tab-request-codemirror", - $scope.flatten($scope.activePostData), - "myRequestCodeMirror", - 6 - ); - }; - - $scope.flatten = function (input) { - if (input && typeof input === "object") - return input.map(function (x) { - var tmp = {}; - tmp[x.name] = x.value; - return tmp; - }); + if (tabId === "tab-response") { + $scope.displayCode("responseJsonEditor", $scope.activeCode, 3); + } + if (tabId === "tab-request") { + $scope.displayCode("requestJsonEditor", $scope.activePostData, 6); + } }; - $scope.displayCode = function (elementId, input, scopeVar, depth) { - if (input != null) { - document.getElementById(elementId).style.visibility = "visible"; - + $scope.displayCode = function (elementId, input, depth) { + if (input) { let content; if ($scope.showOriginal) { - content = JSON.stringify(parse(input, 0, 1), null, 4); + content = parse(input, 0, 1); } else { - content = JSON.stringify(parse(input, 0, depth), null, 4); + content = parse(input, 0, depth); } - if ($scope[scopeVar]) { - $scope[scopeVar].getDoc().setValue(content); - - $scope[scopeVar].refresh(); - return; + if (typeof input === 'object' || Array.isArray(input)) { + // JSON + $scope[elementId].setMode("view"); + $scope[elementId].set(content); + } else { + // Something else + try { + let json = JSON.parse(input) + $scope[elementId].setMode("view"); + $scope[elementId].set(content); + } catch (e) { + $scope[elementId].setMode("code"); + $scope[elementId].set(content); + } } - document.getElementById(elementId).innerHTML = ""; - const codeMirror = CodeMirror(document.getElementById(elementId), { - value: content, - mode: "application/json", - theme: "neat", - lineNumbers: true, - lineWrapping: false, - readOnly: true, - foldGutter: true, - gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"] - }); - $scope[scopeVar] = codeMirror; + if (elementId === "responseJsonEditor") { + var bodySize = $scope.activeResponseData.find(x => x.name === "bodySize"); + if (bodySize && bodySize.value < MAXBODYSIZE) { // an arbitrary number that I picked so there is HUGE lag + if ($scope[elementId].getMode() === 'tree' || $scope[elementId].getMode() === 'view') + $scope[elementId].expandAll(); + } + } else if (elementId === "requestJsonEditor") { + var bodySize = $scope.activeRequest.find(x => x.name === "bodySize"); + if (bodySize && bodySize.value < MAXBODYSIZE) { + if ($scope[elementId].getMode() === 'tree' || $scope[elementId].getMode() === 'view') + $scope[elementId].expandAll(); + } + } + } else { + $scope[elementId].set(null); + $scope[elementId].expandAll(); } }; - - $scope.getPretty = function (source) { - let code = JSON.stringify(parse(source, 0, 1), null, 4); - return code; - - const options = { - source: code, - mode: "beautify", // beautify, diff, minify, parse - lang: "auto", - inchar: " " // indent character - }; - const pd = prettydiff(options); // returns and array: [beautified, report] - - const pretty = pd[0]; - - return pretty; - }; }); diff --git a/unpacked/panel/assets/stylesheets/panel.css b/unpacked/panel/assets/stylesheets/panel.css index c648ea7..0ea3d84 100755 --- a/unpacked/panel/assets/stylesheets/panel.css +++ b/unpacked/panel/assets/stylesheets/panel.css @@ -1,426 +1,439 @@ +[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { + display: none !important; +} + * { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } body { - background: #fff; + background: #fff; + margin: 0; + position: relative; } -th, td { - text-align: left; +div.wrap { + margin: 0px; + background-color: #EFEFEF; } - -.toolbar { - padding: 2px 4px; - text-align: right; +div.wrap input { + border: 1px solid darkgray; + width: 260px; + border-radius: 0px; + margin: 0; + padding: 2px 8px; } - -.toolbar a { - color: rgb(105, 105, 105); - cursor: default; - font-size: 15px; - padding: 0 5px; - text-decoration: none; +div.wrap span.label { + margin: 0 10px; } - -.toolbar a:hover { - color: rgb(59, 59, 59); - text-decoration: none; +div.wrap span.searchterm { + background-color: #8aff75; + border-radius: 3px; + padding: 3px 6px; + margin: 1px 0; + display: inline-block; } - -.toolbar a.selected { - color: rgb(62, 130, 240); - text-decoration: none; -} - -.toolbar a.selected:hover { - color: rgb(25, 108, 251); - text-decoration: none; -} - -.split-view { - bottom: 0; - left: 0; - overflow: hidden; - position: absolute; - right: 0; - top: 0; +div.wrap span.searchterm.neg { + background-color: #ec7b79; } - -.split-view-contents { - bottom: 0; - cursor: default; - overflow: auto; - position: absolute; - top: 0; +div.wrap span.operator { + font: normal normal bold 11px/25px sans-serif; + cursor: pointer; + display: inline-block; + width: 25px; + text-align: center; } - -@media screen and (max-width: 900px) { - .split-view-contents-requests { - bottom: 50%; - width: 100%; - } - - .split-view-contents-details { - top: 50%; - width: 100%; - } +div.wrap span.recent { + padding-left: 75px; } - -@media screen and (min-width: 900px) { - .split-view-contents-requests { - width: 50%; - } - - .split-view-contents-details { - left: 50%; - right: 0; - } +div.wrap div#recent-searches { + display: inline; } - -.data-grid { - border: none; - bottom: 0; - left: 0; - position: absolute; - right: 0; - top: 0; +div.wrap span.recents { + background-color: #a8ff99; + border-radius: 3px; + padding: 3px 6px; + margin: 1px 10px 2px 0px; + display: inline-block; + color: gray; } - -.data-grid table { - border-collapse: collapse; - border-spacing: 0; - font-size: 11px; - table-layout: fixed; - width: 100%; +div.wrap span.recents.neg { + background-color: #ffbdbd; } -.data-grid th { - border-bottom: 1px solid rgb(205, 205, 205); - border-right: 1px solid rgb(205, 205, 205); - height: 25px; - padding: 0 4px; - white-space: nowrap; +table.styled th, +table.styled td { + text-align: left; } -.data-grid td { - border-right: 1px solid rgb(205, 205, 205); - overflow: hidden; - padding: 0px 5px; - vertical-align: middle; - white-space: nowrap; +.toolbar { + padding: 2px 4px; + text-align: right; } - -.data-grid tr:first-child td { - border-top: 1px solid rgb(205, 205, 205); +.toolbar a { + color: dimgray; + cursor: default; + font-size: 15px; + padding: 0 5px; + text-decoration: none; } - -/* requests list */ - -.data-container { - bottom: 0; - left: 0; - overflow-x: hidden; - overflow-y: overlay; - position: absolute; - right: 0; - top: 25px; +.toolbar a:hover { + color: #3b3b3b; + text-decoration: none; } - -.data-container table { - height: 100%; +.toolbar a.selected { + color: #3e82f0; + text-decoration: none; } - -.data-container tr { - height: 20px; +.toolbar a.selected:hover { + color: #196cfb; + text-decoration: none; } -.data-container tr.sizing { - height: 0; +.top-border { + border-top: 1px solid #ddd; } -.data-container tr.sizing td { - padding: 0; +.split-view { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; } - -.data-container tr.filler { - display: table-row !important; - height: auto !important; +.split-view-contents { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; +} +.split-view-contents-details { + top: 34%; +} + +@media screen and (max-width: 1200px) { + div.wrap span.recent { + display: inline-block; + padding: 0px 10px 0 273px; + margin: 8px 0 0 0; + } + + .split-view-contents-requests { + bottom: 66%; + } +} +@media screen and (min-width: 1200px) { + .split-view-contents { + width: 50%; + } + .split-view-contents-requests { + right: unset; + } + .split-view-contents-details { + top: 0; + left: unset; + border-left: 1px solid #555; + } + + br.mobile { + display: none; + } } - -.data-container tr.filler td { - padding: 0; +.data-grid { + border: none; + height: 100%; +} +.data-grid table.styled { + border-collapse: collapse; + border-spacing: 0; + font-size: 11px; + table-layout: fixed; + width: 100%; +} +.data-grid table.styled th { + border-bottom: 1px solid #cdcdcd; + border-right: 1px solid #cdcdcd; + height: 25px; + padding: 0 4px; + white-space: nowrap; +} +.data-grid table.styled td { + border-right: 1px solid #cdcdcd; + overflow: hidden; + padding: 0px 5px; + vertical-align: middle; + white-space: nowrap; +} +.data-grid table.styled tr:first-child td { + border-top: 1px solid #cdcdcd; } - .data-grid-requests { - cursor: unset; -} -.clickable { - cursor: pointer; + cursor: unset; +} +.data-grid-requests table.styled { + line-height: 1.4; +} +.data-grid-requests table.styled th { + font-weight: normal; + overflow: hidden; +} +.data-grid-requests table.styled td.duration { + text-align: right; +} +.data-grid-requests table.styled td.method, +.data-grid-requests table.styled td.time, +.data-grid-requests table.styled td.datetime, +.data-grid-requests table.styled td.format, +.data-grid-requests table.styled td.status, +.data-grid-requests table.styled td.duration { + background: #f1f1f1; +} +.data-grid-requests table.styled tr:nth-child(even):not(.filler) { + background: #f3f3f3; +} +.data-grid-requests table.styled tr:nth-child(even) td.method, +.data-grid-requests table.styled tr:nth-child(even) td.time, +.data-grid-requests table.styled tr:nth-child(even) td.datetime, +.data-grid-requests table.styled tr:nth-child(even) td.format, +.data-grid-requests table.styled tr:nth-child(even) td.status, +.data-grid-requests table.styled tr:nth-child(even) td.duration { + background: #f1f1f1; +} +.data-grid-requests table.styled tr.selected td { + background: #3883fa !important; + color: white; +} +.data-grid-requests table.styled tr.selected td small { + color: white; +} +.data-grid-requests table.styled tr.separator { + cursor: pointer; + max-height: 6px; + height: 6px; + line-height: 6px; +} +.data-grid-requests table.styled tr.separator td { + background-color: #d6e6ff !important; + color: #d6e6ff !important; + border-right: 1px solid #d6e6ff !important; } -.data-grid-requests table { - line-height: 1.4; -} - -.data-grid-requests th { - font-weight: normal; - overflow: hidden; -} - .data-grid-requests small { - color: rgb(128, 128, 128); - font-size: 100%; -} - -.data-grid-requests .selected td { - background: #3879D9 !important; - color: white; -} - -.data-grid-requests .selected td small { - color: white; + color: gray; + font-size: 100%; } - .data-grid-requests .apextype { - width: 170px; + width: 15%; } .data-grid-requests .apexmethod { - width: 130px; + width: 12%; } .data-grid-requests .method, .data-grid-requests .time, .data-grid-requests .format, .data-grid-requests .status { - text-align: center; - width: 50px; + text-align: center; + width: 6%; +} +.data-grid-requests .datetime { + text-align: center; + width: 9%; } - .data-grid-requests .duration { - width: 80px; + width: 80px; } - -.data-grid-requests td.duration { - text-align: right; +.data-grid-requests .notificationsCount { + background: rgba(255, 255, 255, 0.8); + float: right; + height: 100%; + letter-spacing: -0.5px; + line-height: 29px; + padding-left: 4px; + padding-right: 4px; + position: relative; + right: -4px; } - -.data-grid-requests td.method, -.data-grid-requests td.time, -.data-grid-requests td.format, -.data-grid-requests td.status, -.data-grid-requests td.duration { - background: rgb(237, 237, 237); +.data-grid-requests .notificationsCount .errorsCount i { + color: #cd492e; + margin-left: 2px; } - -.data-grid-requests tr:nth-child(even):not(.filler) { - background: rgb(243, 243, 243); +.data-grid-requests .notificationsCount .warningsCount i { + color: #f4bd00; + margin-left: 2px; } - -.data-grid-requests tr:nth-child(even) td.method, -.data-grid-requests tr:nth-child(even) td.time, -.data-grid-requests tr:nth-child(even) td.format, -.data-grid-requests tr:nth-child(even) td.status, -.data-grid-requests tr:nth-child(even) td.duration { - background: rgb(225, 225, 225); +.data-grid-requests .selected .notificationsCount { + background: inherit; } - -.data-grid-requests .notificationsCount { - background: rgba(255, 255, 255, 0.8); - float: right; - height: 100%; - letter-spacing: -0.5px; - line-height: 29px; - padding-left: 4px; - padding-right: 4px; - position: relative; - right: -4px; +.data-grid-requests .selected .notificationsCount .errorsCount i { + color: #fff; } - -.data-grid-requests .selected .notificationsCount { - background: inherit; +.data-grid-requests .selected .notificationsCount .warningsCount i { + color: #fff; +} +.data-grid-requests .data .saml { + font-weight: bold; +} +.data-grid-details table.styled { + font-size: 12px; + margin-bottom: 6px; + table-layout: fixed; + border: 1px solid #cdcdcd; +} +.data-grid-details table.styled tr:nth-child(even) { + background: #eaf3ff; +} +.data-grid-details table.styled th { + border-bottom: none; + border-right: none; + font-size: 12px; + font-weight: bold; + height: 18px; + padding: 0 4px; + white-space: nowrap; +} +.data-grid-details table.styled td { + border-right: 1px solid #e5e5e5; + border-top: 1px solid #e5e5e5; + height: auto; + line-height: 16px; + vertical-align: top; + white-space: normal; + word-wrap: break-word; +} +.data-grid-details table.styled th:last-child, +.data-grid-details table.styled td:last-child { + border-right: none; } - -.data-grid-requests .notificationsCount .errorsCount i { - color: rgb(205, 73, 46); - margin-left: 2px; +.data-grid-details .key { + font-size: 12px; + font-weight: bold; + white-space: nowrap; } -.data-grid-requests .selected .notificationsCount .errorsCount i { - color: #fff; +.data-container { + overflow-x: hidden; + overflow-y: overlay; + height: calc(100% - 25px); } - -.data-grid-requests .notificationsCount .warningsCount i { - color: rgb(244, 189, 0); - margin-left: 2px; +.data-container table.styled { + height: 100%; } - -.data-grid-requests .selected .notificationsCount .warningsCount i { - color: #fff; +.data-container table.styled tr { + height: 20px; } - -.data-grid-requests .data-container .data .saml { - font-weight: bold; +.data-container table.styled tr.sizing { + height: 0; +} +.data-container table.styled tr.sizing td { + padding: 0; +} +.data-container table.styled tr.filler { + display: table-row; + height: auto; +} +.data-container table.styled tr.filler td { + padding: 0; +} +.data-container .data .saml { + font-weight: bold; } -/* request details */ +.clickable { + cursor: pointer; +} .tabbed-pane { - -webkit-box-orient: vertical; - -moz-box-orient: vertical; - -ms-box-orient: vertical; - box-orient: vertical; - display: -webkit-box; - display: -moz-box; - display: -ms-box; - display: box; - height: 100%; - width: 100%; + -webkit-box-orient: vertical; + -moz-box-orient: vertical; + -ms-box-orient: vertical; + box-orient: vertical; + display: -webkit-box; + display: -moz-box; + display: -ms-box; + display: box; + height: 100%; + width: 100%; } - .tabbed-pane-header { - border-bottom: 1px solid rgb(205, 205, 205); - padding-left: 0; - padding-top: 1px; - white-space: nowrap; + border-bottom: 1px solid #cdcdcd; + padding-left: 0; + padding-top: 1px; + white-space: nowrap; + height: 26px; + background: #efefef; } - .tabbed-pane-header-contents { - margin: 0 10px; + margin: 0 10px; } - .tabbed-pane-header-tabs { - margin: 0; - min-width: 300px; - padding: 0; - position: relative; - top: 1px; + margin: 0; + min-width: 300px; + padding: 0; + position: relative; + top: 1px; } - .tabbed-pane-header-tab { - border: 1px solid transparent; - border-bottom: none; - float: left; - font-size: 11px; - height: 21px; - margin-top: 2px; - overflow: hidden; - padding: 1px 6px 1px 6px; - text-overflow: ellipsis; - vertical-align: middle; - white-space: nowrap; + border: 1px solid transparent; + border-bottom: none; + float: left; + font-size: 11px; + height: 21px; + margin-top: 2px; + overflow: hidden; + padding: 1px 6px 1px 6px; + text-overflow: ellipsis; + vertical-align: middle; + white-space: nowrap; } - .tabbed-pane-header-tab-title { - color: #000; - display: block; - font-size: 12px; - min-width: 40px; - text-align: center; - text-decoration: none; - white-space: nowrap; + color: #000; + display: block; + font-size: 12px; + min-width: 40px; + text-align: center; + text-decoration: none; + white-space: nowrap; } - .tabbed-pane-header .ui-tabs-active { - background-color: white; - border: 1px solid rgb(205, 205, 205); - border-bottom: none; + background-color: white; + border: 1px solid #cdcdcd; + border-bottom: none; } - .tabbed-pane-header-tab, .tabbed-pane-header-tab a, .tabbed-pane-header-tab a:active { - outline: none; + outline: none; } - .tabbed-pane-content { - -webkit-box-flex: 1; - -moz-box-flex: 1; - -ms-box-flex: 1; - box-flex: 1; - overflow: auto; - padding: 0px; - position: relative; + -webkit-box-flex: 1; + -moz-box-flex: 1; + -ms-box-flex: 1; + box-flex: 1; + overflow: auto; + padding: 0px; + position: relative; + height: calc(100% - 24px); } + #tab-request-stats, #tab-response-stats { - padding: 10px; -} - -.data-grid-details table { - /*font-size: 12px;*/ - margin-bottom: 6px; - table-layout: fixed; - border: 1px solid rgb(205, 205, 205); -} - -.data-grid-details table tr:nth-child(even) { - background: rgb(234, 243, 255); -} - -.data-grid-details th { - border-bottom: none; - border-right: none; - font-size: 12px; - font-weight: bold; - height: 18px; - padding: 0 4px; - white-space: nowrap; -} - -.data-grid-details td { - border-right: 1px solid #e5e5e5; - border-top: 1px solid #e5e5e5; - height: auto; - line-height: 16px; - vertical-align: top; - white-space: normal; - word-wrap: break-word; + padding: 10px; } -.data-grid-details th:last-child, -.data-grid-details td:last-child { - border-right: none; -} - -.data-grid-details .key { - /*font-size: 12px;*/ - font-weight: bold; - white-space: nowrap; -} - -/* request details - request */ th.request { - position:relative; -} - - -#tab-request table { - margin-bottom: 20px; -} - -#tab-response table { - margin-bottom: 20px; + position: relative; } -#tab-saml { - bottom: 0px; - left: 0px; - overflow-x: hidden; - overflow-y: overlay; - position: absolute; - right: 0px; - top: 0px; - padding: 1px; - font-size: 12px; +#tab-response table.styled { + margin-bottom: 20px; } -#tab-saml-codemirror { - height: 100%; -} - -input[type="file"] { - display: none; +input[type=file] { + display: none; } .CodeMirror { - height: calc(100% - 26px) !important; + height: calc(100% - 26px); } + +/*# sourceMappingURL=panel.css.map */ diff --git a/unpacked/panel/assets/stylesheets/panel.css.map b/unpacked/panel/assets/stylesheets/panel.css.map new file mode 100644 index 0000000..8bdc331 --- /dev/null +++ b/unpacked/panel/assets/stylesheets/panel.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["panel.scss"],"names":[],"mappings":"AAAA;EACI;;;AAGJ;EACI;EACA;EACA;;;AAEJ;EACI;EACA;EACA;;;AAEJ;EACI;EACA;;AACA;EACF;EACA;EACA;EACA;EACA;;AAED;EACC;;AAEE;EACI;EACA;EACA;EACA;EACN;;AACA;EACC;;AAGF;EACC;EACA;EACA;EACA;EACA;;AAEE;EACF;;AAEE;EACI;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACN;;AACA;EACC;;;AAIH;AAAA;EAEI;;;AAEJ;EACI;EACA;;AACA;EACI;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;;AAEJ;EACI;EACA;;AACA;EACI;EACA;;;AAKhB;EACI;;;AAEJ;EACI;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;EACA;EACA;;AACA;EACI;;;AAIZ;EAEQ;IACI;IACA;IACA;;;EAGR;IACI;;;AAGR;EACI;IACI;;EACA;IACI;;EAEJ;IACI;IACA;IACA;;;EAGR;IACI;;;AAGR;EACI;EACA;;AACA;EACI;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;;AAEJ;EACI;;AAGR;EACI;;AACA;EACI;;AACA;EACI;EACA;;AAEJ;EACI;;AAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;EAMI;;AAEJ;EACI;;AAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;EAMI;;AAEb;EACC;EACA;;AACA;EACC;;AAGO;EACI;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;;AAIZ;EACI;EACA;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;AAAA;AAAA;AAAA;EAII;EACA;;AAEJ;EACI;EACA;;AAEJ;EACI;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;;AAEJ;EACI;EACA;;AAGR;EACI;;AACA;EACI;;AAEJ;EACI;;AAGR;EACI;;AAGR;EACI;EACA;EACA;EACA;;AACA;EACI;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAEJ;AAAA;EAEI;;AAGR;EACI;EACA;EACA;;;AAGR;EACI;EACA;EACA;;AACA;EACI;;AACA;EACI;;AACA;EACI;;AACA;EACI;;AAGR;EACI;EACA;;AACA;EACI;;AAKhB;EACI;;;AAGR;EACI;;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;;AAEJ;EACI;EACA;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAGR;EACI;EACA;EACA;;AAEJ;EAGI;;AAGR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGR;AAAA;EAEI;;;AAEJ;EACI;;;AAEJ;EACI;;;AAEJ;EACI;;;AAEJ;EACI","file":"panel.css"} \ No newline at end of file diff --git a/unpacked/panel/assets/stylesheets/panel.scss b/unpacked/panel/assets/stylesheets/panel.scss new file mode 100755 index 0000000..b5de1ba --- /dev/null +++ b/unpacked/panel/assets/stylesheets/panel.scss @@ -0,0 +1,424 @@ +[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { + display: none !important; +} + +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +body { + background: #fff; + margin: 0; + position: relative; +} +div.wrap { + margin: 0px; + background-color: #EFEFEF; + input { + border: 1px solid darkgray; + width: 260px; + border-radius: 0px; + margin: 0; + padding: 2px 8px; + } + span.label { + margin: 0 10px; + } + span.searchterm { + background-color: hsl(111, 100%, 73%); // #bfb; + border-radius: 3px; + padding: 3px 6px; + margin: 1px 0; + display: inline-block; + &.neg { + background-color: hsl(1, 75%, 70%); + } + } + span.operator { + font: normal normal bold 11px/25px sans-serif; + cursor: pointer; + display: inline-block; + width: 25px; + text-align: center; + } + span.recent { + padding-left: 75px; + } + div#recent-searches { + display: inline; + } + span.recents { + background-color: hsl(111, 100%, 80%); // #efe; + border-radius: 3px; + padding: 3px 6px; + margin: 1px 10px 2px 0px; + display: inline-block; + color: hsl(1, 0%, 50%); + &.neg { + background-color: hsl(0, 100%, 87%); + } + } +} +table.styled th, +table.styled td { + text-align: left; +} +.toolbar { + padding: 2px 4px; + text-align: right; + a { + color: rgb(105, 105, 105); + cursor: default; + font-size: 15px; + padding: 0 5px; + text-decoration: none; + &:hover { + color: rgb(59, 59, 59); + text-decoration: none; + } + &.selected { + color: rgb(62, 130, 240); + text-decoration: none; + &:hover { + color: rgb(25, 108, 251); + text-decoration: none; + } + } + } +} +.top-border { + border-top: 1px solid #ddd; +} +.split-view { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + &-contents { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + &-details { + top: 34%; + } + } +} +@media screen and (max-width: 1200px) { + div.wrap { + span.recent { + display: inline-block; + padding: 0px 10px 0 273px; + margin: 8px 0 0 0; + } + } + .split-view-contents-requests { + bottom: 66%; + } +} +@media screen and (min-width: 1200px) { + .split-view-contents { + width: 50%; + &-requests { + right: unset; + } + &-details { + top: 0; + left: unset; + border-left: 1px solid #555; + } + } + br.mobile { + display: none; + } +} +.data-grid { + border: none; + height: 100%; + table.styled { + border-collapse: collapse; + border-spacing: 0; + font-size: 11px; + table-layout: fixed; + width: 100%; + th { + border-bottom: 1px solid rgb(205, 205, 205); + border-right: 1px solid rgb(205, 205, 205); + height: 25px; + padding: 0 4px; + white-space: nowrap; + } + td { + border-right: 1px solid rgb(205, 205, 205); + overflow: hidden; + padding: 0px 5px; + vertical-align: middle; + white-space: nowrap; + } + tr:first-child td { + border-top: 1px solid rgb(205, 205, 205); + } + } + &-requests { + cursor: unset; + table.styled { + line-height: 1.4; + th { + font-weight: normal; + overflow: hidden; + } + td.duration { + text-align: right; + } + td.method, + td.time, + td.datetime, + td.format, + td.status, + td.duration { + background: rgb(241, 241, 241); + } + tr:nth-child(even):not(.filler) { + background: rgb(243, 243, 243); + } + tr:nth-child(even) td.method, + tr:nth-child(even) td.time, + tr:nth-child(even) td.datetime, + tr:nth-child(even) td.format, + tr:nth-child(even) td.status, + tr:nth-child(even) td.duration { + background: rgb(241, 241, 241); + } + tr.selected td { + background: #3883fa !important; + color: white; + small { + color: white; + } + } + tr.separator { + cursor: pointer; + max-height: 6px; + height: 6px; + line-height: 6px; + td { + background-color: hsl(217, 100%, 92%) !important; + color: hsl(217, 100%, 92%) !important; + border-right: 1px solid hsl(217, 100%, 92%) !important; + } + } + } + small { + color: rgb(128, 128, 128); + font-size: 100%; + } + .apextype { + width: 15%; + } + .apexmethod { + width: 12%; + } + .method, + .time, + .format, + .status { + text-align: center; + width: 6%; + } + .datetime { + text-align: center; + width: 9%; + } + .duration { + width: 80px; + } + .notificationsCount { + background: rgba(255, 255, 255, 0.8); + float: right; + height: 100%; + letter-spacing: -0.5px; + line-height: 29px; + padding-left: 4px; + padding-right: 4px; + position: relative; + right: -4px; + .errorsCount i { + color: rgb(205, 73, 46); + margin-left: 2px; + } + .warningsCount i { + color: rgb(244, 189, 0); + margin-left: 2px; + } + } + .selected .notificationsCount { + background: inherit; + .errorsCount i { + color: #fff; + } + .warningsCount i { + color: #fff; + } + } + .data .saml { + font-weight: bold; + } + } + &-details table.styled { + font-size: 12px; + margin-bottom: 6px; + table-layout: fixed; + border: 1px solid rgb(205, 205, 205); + tr:nth-child(even) { + background: rgb(234, 243, 255); + } + th { + border-bottom: none; + border-right: none; + font-size: 12px; + font-weight: bold; + height: 18px; + padding: 0 4px; + white-space: nowrap; + } + td { + border-right: 1px solid #e5e5e5; + border-top: 1px solid #e5e5e5; + height: auto; + line-height: 16px; + vertical-align: top; + white-space: normal; + word-wrap: break-word; + } + th:last-child, + td:last-child { + border-right: none; + } + } + &-details .key { + font-size: 12px; + font-weight: bold; + white-space: nowrap; + } +} +.data-container { + overflow-x: hidden; + overflow-y: overlay; + height: calc(100% - 25px); + table.styled { + height: 100%; + tr { + height: 20px; + &.sizing { + height: 0; + td { + padding: 0; + } + } + &.filler { + display: table-row; + height: auto; + td { + padding: 0; + } + } + } + } + .data .saml { + font-weight: bold; + } +} +.clickable { + cursor: pointer; +} +.tabbed-pane { + -webkit-box-orient: vertical; + -moz-box-orient: vertical; + -ms-box-orient: vertical; + box-orient: vertical; + display: -webkit-box; + display: -moz-box; + display: -ms-box; + display: box; + height: 100%; + width: 100%; + &-header { + border-bottom: 1px solid rgb(205, 205, 205); + padding-left: 0; + padding-top: 1px; + white-space: nowrap; + height: 26px; + background: #efefef; + &-contents { + margin: 0 10px; + } + &-tabs { + margin: 0; + min-width: 300px; + padding: 0; + position: relative; + top: 1px; + } + &-tab { + border: 1px solid transparent; + border-bottom: none; + float: left; + font-size: 11px; + height: 21px; + margin-top: 2px; + overflow: hidden; + padding: 1px 6px 1px 6px; + text-overflow: ellipsis; + vertical-align: middle; + white-space: nowrap; + &-title { + color: #000; + display: block; + font-size: 12px; + min-width: 40px; + text-align: center; + text-decoration: none; + white-space: nowrap; + } + } + .ui-tabs-active { + background-color: white; + border: 1px solid rgb(205, 205, 205); + border-bottom: none; + } + &-tab, + &-tab a, + &-tab a:active { + outline: none; + } + } + &-content { + -webkit-box-flex: 1; + -moz-box-flex: 1; + -ms-box-flex: 1; + box-flex: 1; + overflow: auto; + padding: 0px; + position: relative; + height: calc(100% - 24px); + } +} +#tab-request-stats, +#tab-response-stats { + padding: 10px; +} +th.request { + position: relative; +} +#tab-response table.styled { + margin-bottom: 20px; +} +input[type="file"] { + display: none; +} +.CodeMirror { + height: calc(100% - 26px); +} diff --git a/unpacked/panel/panel.html b/unpacked/panel/panel.html index e0e8996..2b021e3 100644 --- a/unpacked/panel/panel.html +++ b/unpacked/panel/panel.html @@ -1,22 +1,15 @@ + - + + + - - - - - - - - - - + - @@ -25,248 +18,270 @@ - - - - - - - - - - - - - - - - - - - - - -
-
-
- - - - - - - - - - - -
- Path - - - - - Apex Type - - Apex Method - - Method - - Status - - Time -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
{{request.request_url}}{{request.request_apex_type}}{{request.request_apex_method}}{{request.request_method}}{{request.response_status}}{{ request.time / 1000 | number : 2 }} s
-
-
-
- -
-
-
- -
+ +
+
+
+ + + Filtering for: + + {{term}} + {{ andFilter && 'and' || 'or' }} + +
+
+ Recent searches: + {{term}} +
- -
- -
- - +
+
+ - + + + + + + + - - - - - + +
Request POST Data + Path + + Apex Type + + Apex Method + + Method + + Status + + Time + + Started +
{{param.name}}
+
+ + + + + + + + + - -
- - - - - + + + + + + + + + - - - - - + + + + + + + + -
Request Data
{{request.request_url}}{{request.request_apex_type}}{{request.request_apex_method}}{{request.request_method}}{{request.response_status}}{{ request.time / 1000 | number : 2 }} s{{ request.startedDateTime | date: "mediumTime" }}
{{param.name}}
+
+
+
- - - - - - - - - - - - -
Request Headers
{{param.name}}
+
+
+
+ + +
- - - - - - - - - - - - -
Request Cookies
{{param.name}}
-
- - - - - - - - - - - - -
Response Data
{{param.name}}
+
- - - - - - - - - - - - -
Response Headers
{{param.name}}
- - - - - - - - - - - - -
Response Cookies
{{param.name}}
-
+
+ + + + + + + + + + + + +
Request POST Data
{{param.name}} + +
+ + + + + + + + + + + + + +
Request Data
{{param.name}} + +
+ + + + + + + + + + + + +
Request Headers
{{param.name}} + +
-
-
+ + + + + + + + + + + + +
Request Cookies
{{param.name}} + +
-
-
-
+
+ + + + + + + + + + + + +
Response Data
{{param.name}} + +
+ + + + + + + + + + + + + +
Response Headers
{{param.name}} + +
+ + + + + + + + + + + + +
Response Cookies
{{param.name}} + +
-
- +
+
+ +
+ +
+
+ +
+ + + + + +
-
- + + \ No newline at end of file diff --git a/unpacked/panel/vendor/assets/javascripts/img/jsoneditor-icons.svg b/unpacked/panel/vendor/assets/javascripts/img/jsoneditor-icons.svg new file mode 100644 index 0000000..c2c2765 --- /dev/null +++ b/unpacked/panel/vendor/assets/javascripts/img/jsoneditor-icons.svg @@ -0,0 +1,749 @@ + + + JSON Editor Icons + + + + image/svg+xml + + JSON Editor Icons + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/unpacked/panel/vendor/assets/javascripts/jsoneditor.js b/unpacked/panel/vendor/assets/javascripts/jsoneditor.js new file mode 100644 index 0000000..0011ba9 --- /dev/null +++ b/unpacked/panel/vendor/assets/javascripts/jsoneditor.js @@ -0,0 +1,52682 @@ +/*! + * jsoneditor.js + * + * @brief + * JSONEditor is a web-based tool to view, edit, format, and validate JSON. + * It has various modes such as a tree editor, a code editor, and a plain text + * editor. + * + * Supported browsers: Chrome, Firefox, Safari, Opera, Internet Explorer 8+ + * + * @license + * 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. + * + * Copyright (c) 2011-2021 Jos de Jong, http://jsoneditoronline.org + * + * @author Jos de Jong, + * @version 9.1.8 + * @date 2021-01-16 + */ + +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["JSONEditor"] = factory(); + else + root["JSONEditor"] = factory(); +})(self, function() { +return /******/ (function() { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ 6835: +/***/ (function(module) { + +"use strict"; +module.exports = JSON.parse("{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"$id\":\"https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#\",\"description\":\"Meta-schema for $data reference (JSON Schema extension proposal)\",\"type\":\"object\",\"required\":[\"$data\"],\"properties\":{\"$data\":{\"type\":\"string\",\"anyOf\":[{\"format\":\"relative-json-pointer\"},{\"format\":\"json-pointer\"}]}},\"additionalProperties\":false}"); + +/***/ }), + +/***/ 2689: +/***/ (function(module) { + +"use strict"; +module.exports = JSON.parse("{\"id\":\"http://json-schema.org/draft-04/schema#\",\"$schema\":\"http://json-schema.org/draft-04/schema#\",\"description\":\"Core schema meta-schema\",\"definitions\":{\"schemaArray\":{\"type\":\"array\",\"minItems\":1,\"items\":{\"$ref\":\"#\"}},\"positiveInteger\":{\"type\":\"integer\",\"minimum\":0},\"positiveIntegerDefault0\":{\"allOf\":[{\"$ref\":\"#/definitions/positiveInteger\"},{\"default\":0}]},\"simpleTypes\":{\"enum\":[\"array\",\"boolean\",\"integer\",\"null\",\"number\",\"object\",\"string\"]},\"stringArray\":{\"type\":\"array\",\"items\":{\"type\":\"string\"},\"minItems\":1,\"uniqueItems\":true}},\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"string\"},\"$schema\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"default\":{},\"multipleOf\":{\"type\":\"number\",\"minimum\":0,\"exclusiveMinimum\":true},\"maximum\":{\"type\":\"number\"},\"exclusiveMaximum\":{\"type\":\"boolean\",\"default\":false},\"minimum\":{\"type\":\"number\"},\"exclusiveMinimum\":{\"type\":\"boolean\",\"default\":false},\"maxLength\":{\"$ref\":\"#/definitions/positiveInteger\"},\"minLength\":{\"$ref\":\"#/definitions/positiveIntegerDefault0\"},\"pattern\":{\"type\":\"string\",\"format\":\"regex\"},\"additionalItems\":{\"anyOf\":[{\"type\":\"boolean\"},{\"$ref\":\"#\"}],\"default\":{}},\"items\":{\"anyOf\":[{\"$ref\":\"#\"},{\"$ref\":\"#/definitions/schemaArray\"}],\"default\":{}},\"maxItems\":{\"$ref\":\"#/definitions/positiveInteger\"},\"minItems\":{\"$ref\":\"#/definitions/positiveIntegerDefault0\"},\"uniqueItems\":{\"type\":\"boolean\",\"default\":false},\"maxProperties\":{\"$ref\":\"#/definitions/positiveInteger\"},\"minProperties\":{\"$ref\":\"#/definitions/positiveIntegerDefault0\"},\"required\":{\"$ref\":\"#/definitions/stringArray\"},\"additionalProperties\":{\"anyOf\":[{\"type\":\"boolean\"},{\"$ref\":\"#\"}],\"default\":{}},\"definitions\":{\"type\":\"object\",\"additionalProperties\":{\"$ref\":\"#\"},\"default\":{}},\"properties\":{\"type\":\"object\",\"additionalProperties\":{\"$ref\":\"#\"},\"default\":{}},\"patternProperties\":{\"type\":\"object\",\"additionalProperties\":{\"$ref\":\"#\"},\"default\":{}},\"dependencies\":{\"type\":\"object\",\"additionalProperties\":{\"anyOf\":[{\"$ref\":\"#\"},{\"$ref\":\"#/definitions/stringArray\"}]}},\"enum\":{\"type\":\"array\",\"minItems\":1,\"uniqueItems\":true},\"type\":{\"anyOf\":[{\"$ref\":\"#/definitions/simpleTypes\"},{\"type\":\"array\",\"items\":{\"$ref\":\"#/definitions/simpleTypes\"},\"minItems\":1,\"uniqueItems\":true}]},\"format\":{\"type\":\"string\"},\"allOf\":{\"$ref\":\"#/definitions/schemaArray\"},\"anyOf\":{\"$ref\":\"#/definitions/schemaArray\"},\"oneOf\":{\"$ref\":\"#/definitions/schemaArray\"},\"not\":{\"$ref\":\"#\"}},\"dependencies\":{\"exclusiveMaximum\":[\"maximum\"],\"exclusiveMinimum\":[\"minimum\"]},\"default\":{}}"); + +/***/ }), + +/***/ 1030: +/***/ (function(module) { + +"use strict"; +module.exports = JSON.parse("{\"$schema\":\"http://json-schema.org/draft-06/schema#\",\"$id\":\"http://json-schema.org/draft-06/schema#\",\"title\":\"Core schema meta-schema\",\"definitions\":{\"schemaArray\":{\"type\":\"array\",\"minItems\":1,\"items\":{\"$ref\":\"#\"}},\"nonNegativeInteger\":{\"type\":\"integer\",\"minimum\":0},\"nonNegativeIntegerDefault0\":{\"allOf\":[{\"$ref\":\"#/definitions/nonNegativeInteger\"},{\"default\":0}]},\"simpleTypes\":{\"enum\":[\"array\",\"boolean\",\"integer\",\"null\",\"number\",\"object\",\"string\"]},\"stringArray\":{\"type\":\"array\",\"items\":{\"type\":\"string\"},\"uniqueItems\":true,\"default\":[]}},\"type\":[\"object\",\"boolean\"],\"properties\":{\"$id\":{\"type\":\"string\",\"format\":\"uri-reference\"},\"$schema\":{\"type\":\"string\",\"format\":\"uri\"},\"$ref\":{\"type\":\"string\",\"format\":\"uri-reference\"},\"title\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"default\":{},\"examples\":{\"type\":\"array\",\"items\":{}},\"multipleOf\":{\"type\":\"number\",\"exclusiveMinimum\":0},\"maximum\":{\"type\":\"number\"},\"exclusiveMaximum\":{\"type\":\"number\"},\"minimum\":{\"type\":\"number\"},\"exclusiveMinimum\":{\"type\":\"number\"},\"maxLength\":{\"$ref\":\"#/definitions/nonNegativeInteger\"},\"minLength\":{\"$ref\":\"#/definitions/nonNegativeIntegerDefault0\"},\"pattern\":{\"type\":\"string\",\"format\":\"regex\"},\"additionalItems\":{\"$ref\":\"#\"},\"items\":{\"anyOf\":[{\"$ref\":\"#\"},{\"$ref\":\"#/definitions/schemaArray\"}],\"default\":{}},\"maxItems\":{\"$ref\":\"#/definitions/nonNegativeInteger\"},\"minItems\":{\"$ref\":\"#/definitions/nonNegativeIntegerDefault0\"},\"uniqueItems\":{\"type\":\"boolean\",\"default\":false},\"contains\":{\"$ref\":\"#\"},\"maxProperties\":{\"$ref\":\"#/definitions/nonNegativeInteger\"},\"minProperties\":{\"$ref\":\"#/definitions/nonNegativeIntegerDefault0\"},\"required\":{\"$ref\":\"#/definitions/stringArray\"},\"additionalProperties\":{\"$ref\":\"#\"},\"definitions\":{\"type\":\"object\",\"additionalProperties\":{\"$ref\":\"#\"},\"default\":{}},\"properties\":{\"type\":\"object\",\"additionalProperties\":{\"$ref\":\"#\"},\"default\":{}},\"patternProperties\":{\"type\":\"object\",\"additionalProperties\":{\"$ref\":\"#\"},\"default\":{}},\"dependencies\":{\"type\":\"object\",\"additionalProperties\":{\"anyOf\":[{\"$ref\":\"#\"},{\"$ref\":\"#/definitions/stringArray\"}]}},\"propertyNames\":{\"$ref\":\"#\"},\"const\":{},\"enum\":{\"type\":\"array\",\"minItems\":1,\"uniqueItems\":true},\"type\":{\"anyOf\":[{\"$ref\":\"#/definitions/simpleTypes\"},{\"type\":\"array\",\"items\":{\"$ref\":\"#/definitions/simpleTypes\"},\"minItems\":1,\"uniqueItems\":true}]},\"format\":{\"type\":\"string\"},\"allOf\":{\"$ref\":\"#/definitions/schemaArray\"},\"anyOf\":{\"$ref\":\"#/definitions/schemaArray\"},\"oneOf\":{\"$ref\":\"#/definitions/schemaArray\"},\"not\":{\"$ref\":\"#\"}},\"default\":{}}"); + +/***/ }), + +/***/ 38: +/***/ (function(module) { + +"use strict"; +module.exports = JSON.parse("{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"$id\":\"http://json-schema.org/draft-07/schema#\",\"title\":\"Core schema meta-schema\",\"definitions\":{\"schemaArray\":{\"type\":\"array\",\"minItems\":1,\"items\":{\"$ref\":\"#\"}},\"nonNegativeInteger\":{\"type\":\"integer\",\"minimum\":0},\"nonNegativeIntegerDefault0\":{\"allOf\":[{\"$ref\":\"#/definitions/nonNegativeInteger\"},{\"default\":0}]},\"simpleTypes\":{\"enum\":[\"array\",\"boolean\",\"integer\",\"null\",\"number\",\"object\",\"string\"]},\"stringArray\":{\"type\":\"array\",\"items\":{\"type\":\"string\"},\"uniqueItems\":true,\"default\":[]}},\"type\":[\"object\",\"boolean\"],\"properties\":{\"$id\":{\"type\":\"string\",\"format\":\"uri-reference\"},\"$schema\":{\"type\":\"string\",\"format\":\"uri\"},\"$ref\":{\"type\":\"string\",\"format\":\"uri-reference\"},\"$comment\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"default\":true,\"readOnly\":{\"type\":\"boolean\",\"default\":false},\"examples\":{\"type\":\"array\",\"items\":true},\"multipleOf\":{\"type\":\"number\",\"exclusiveMinimum\":0},\"maximum\":{\"type\":\"number\"},\"exclusiveMaximum\":{\"type\":\"number\"},\"minimum\":{\"type\":\"number\"},\"exclusiveMinimum\":{\"type\":\"number\"},\"maxLength\":{\"$ref\":\"#/definitions/nonNegativeInteger\"},\"minLength\":{\"$ref\":\"#/definitions/nonNegativeIntegerDefault0\"},\"pattern\":{\"type\":\"string\",\"format\":\"regex\"},\"additionalItems\":{\"$ref\":\"#\"},\"items\":{\"anyOf\":[{\"$ref\":\"#\"},{\"$ref\":\"#/definitions/schemaArray\"}],\"default\":true},\"maxItems\":{\"$ref\":\"#/definitions/nonNegativeInteger\"},\"minItems\":{\"$ref\":\"#/definitions/nonNegativeIntegerDefault0\"},\"uniqueItems\":{\"type\":\"boolean\",\"default\":false},\"contains\":{\"$ref\":\"#\"},\"maxProperties\":{\"$ref\":\"#/definitions/nonNegativeInteger\"},\"minProperties\":{\"$ref\":\"#/definitions/nonNegativeIntegerDefault0\"},\"required\":{\"$ref\":\"#/definitions/stringArray\"},\"additionalProperties\":{\"$ref\":\"#\"},\"definitions\":{\"type\":\"object\",\"additionalProperties\":{\"$ref\":\"#\"},\"default\":{}},\"properties\":{\"type\":\"object\",\"additionalProperties\":{\"$ref\":\"#\"},\"default\":{}},\"patternProperties\":{\"type\":\"object\",\"additionalProperties\":{\"$ref\":\"#\"},\"propertyNames\":{\"format\":\"regex\"},\"default\":{}},\"dependencies\":{\"type\":\"object\",\"additionalProperties\":{\"anyOf\":[{\"$ref\":\"#\"},{\"$ref\":\"#/definitions/stringArray\"}]}},\"propertyNames\":{\"$ref\":\"#\"},\"const\":true,\"enum\":{\"type\":\"array\",\"items\":true,\"minItems\":1,\"uniqueItems\":true},\"type\":{\"anyOf\":[{\"$ref\":\"#/definitions/simpleTypes\"},{\"type\":\"array\",\"items\":{\"$ref\":\"#/definitions/simpleTypes\"},\"minItems\":1,\"uniqueItems\":true}]},\"format\":{\"type\":\"string\"},\"contentMediaType\":{\"type\":\"string\"},\"contentEncoding\":{\"type\":\"string\"},\"if\":{\"$ref\":\"#\"},\"then\":{\"$ref\":\"#\"},\"else\":{\"$ref\":\"#\"},\"allOf\":{\"$ref\":\"#/definitions/schemaArray\"},\"anyOf\":{\"$ref\":\"#/definitions/schemaArray\"},\"oneOf\":{\"$ref\":\"#/definitions/schemaArray\"},\"not\":{\"$ref\":\"#\"}},\"default\":true}"); + +/***/ }), + +/***/ 897: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "x": function() { return /* binding */ ContextMenu; } +/* harmony export */ }); +/* harmony import */ var _createAbsoluteAnchor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2602); +/* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9791); +/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7907); + + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + + + + +/** + * A context menu + * @param {Object[]} items Array containing the menu structure + * TODO: describe structure + * @param {Object} [options] Object with options. Available options: + * {function} close Callback called when the + * context menu is being closed. + * {boolean} limitHeight Whether ContextMenu height should be + * limited or not. + * @constructor + */ + +var ContextMenu = /*#__PURE__*/function () { + function ContextMenu(items, options) { + _classCallCheck(this, ContextMenu); + + this.dom = {}; + var me = this; + var dom = this.dom; + this.anchor = undefined; + this.items = items; + this.eventListeners = {}; + this.selection = undefined; // holds the selection before the menu was opened + + this.onClose = options ? options.close : undefined; + this.limitHeight = options ? options.limitHeight : false; // create root element + + var root = document.createElement('div'); + root.className = 'jsoneditor-contextmenu-root'; + dom.root = root; // create a container element + + var menu = document.createElement('div'); + menu.className = 'jsoneditor-contextmenu'; + dom.menu = menu; + root.appendChild(menu); // create a list to hold the menu items + + var list = document.createElement('ul'); + list.className = 'jsoneditor-menu'; + menu.appendChild(list); + dom.list = list; + dom.items = []; // list with all buttons + // create a (non-visible) button to set the focus to the menu + + var focusButton = document.createElement('button'); + focusButton.type = 'button'; + dom.focusButton = focusButton; + var li = document.createElement('li'); + li.style.overflow = 'hidden'; + li.style.height = '0'; + li.appendChild(focusButton); + list.appendChild(li); + + function createMenuItems(list, domItems, items) { + items.forEach(function (item) { + if (item.type === 'separator') { + // create a separator + var separator = document.createElement('div'); + separator.className = 'jsoneditor-separator'; + + var _li = document.createElement('li'); + + _li.appendChild(separator); + + list.appendChild(_li); + } else { + var domItem = {}; // create a menu item + + var _li2 = document.createElement('li'); + + list.appendChild(_li2); // create a button in the menu item + + var button = document.createElement('button'); + button.type = 'button'; + button.className = item.className; + domItem.button = button; + + if (item.title) { + button.title = item.title; + } + + if (item.click) { + button.onclick = function (event) { + event.preventDefault(); + me.hide(); + item.click(); + }; + } + + _li2.appendChild(button); // create the contents of the button + + + if (item.submenu) { + // add the icon to the button + var divIcon = document.createElement('div'); + divIcon.className = 'jsoneditor-icon'; + button.appendChild(divIcon); + var divText = document.createElement('div'); + divText.className = 'jsoneditor-text' + (item.click ? '' : ' jsoneditor-right-margin'); + divText.appendChild(document.createTextNode(item.text)); + button.appendChild(divText); + var buttonSubmenu; + + if (item.click) { + // submenu and a button with a click handler + button.className += ' jsoneditor-default'; + var buttonExpand = document.createElement('button'); + buttonExpand.type = 'button'; + domItem.buttonExpand = buttonExpand; + buttonExpand.className = 'jsoneditor-expand'; + var buttonExpandInner = document.createElement('div'); + buttonExpandInner.className = 'jsoneditor-expand'; + buttonExpand.appendChild(buttonExpandInner); + + _li2.appendChild(buttonExpand); + + if (item.submenuTitle) { + buttonExpand.title = item.submenuTitle; + } + + buttonSubmenu = buttonExpand; + } else { + // submenu and a button without a click handler + var divExpand = document.createElement('div'); + divExpand.className = 'jsoneditor-expand'; + button.appendChild(divExpand); + buttonSubmenu = button; + } // attach a handler to expand/collapse the submenu + + + buttonSubmenu.onclick = function (event) { + event.preventDefault(); + + me._onExpandItem(domItem); + + buttonSubmenu.focus(); + }; // create the submenu + + + var domSubItems = []; + domItem.subItems = domSubItems; + var ul = document.createElement('ul'); + domItem.ul = ul; + ul.className = 'jsoneditor-menu'; + ul.style.height = '0'; + + _li2.appendChild(ul); + + createMenuItems(ul, domSubItems, item.submenu); + } else { + // no submenu, just a button with clickhandler + var icon = document.createElement('div'); + icon.className = 'jsoneditor-icon'; + button.appendChild(icon); + var text = document.createElement('div'); + text.className = 'jsoneditor-text'; + text.appendChild(document.createTextNode((0,_i18n__WEBPACK_IMPORTED_MODULE_2__/* .translate */ .Iu)(item.text))); + button.appendChild(text); + } + + domItems.push(domItem); + } + }); + } + + createMenuItems(list, this.dom.items, items); // TODO: when the editor is small, show the submenu on the right instead of inline? + // calculate the max height of the menu with one submenu expanded + + this.maxHeight = 0; // height in pixels + + items.forEach(function (item) { + var height = (items.length + (item.submenu ? item.submenu.length : 0)) * 24; + me.maxHeight = Math.max(me.maxHeight, height); + }); + } + /** + * Get the currently visible buttons + * @return {Array.} buttons + * @private + */ + + + _createClass(ContextMenu, [{ + key: "_getVisibleButtons", + value: function _getVisibleButtons() { + var buttons = []; + var me = this; + this.dom.items.forEach(function (item) { + buttons.push(item.button); + + if (item.buttonExpand) { + buttons.push(item.buttonExpand); + } + + if (item.subItems && item === me.expandedItem) { + item.subItems.forEach(function (subItem) { + buttons.push(subItem.button); + + if (subItem.buttonExpand) { + buttons.push(subItem.buttonExpand); + } // TODO: change to fully recursive method + + }); + } + }); + return buttons; + } + /** + * Attach the menu to an anchor + * @param {HTMLElement} anchor Anchor where the menu will be attached as sibling. + * @param {HTMLElement} frame The root of the JSONEditor window + * @param {Boolean=} ignoreParent ignore anchor parent in regard to the calculation of the position, needed when the parent position is absolute + */ + + }, { + key: "show", + value: function show(anchor, frame, ignoreParent) { + this.hide(); // determine whether to display the menu below or above the anchor + + var showBelow = true; + var parent = anchor.parentNode; + var anchorRect = anchor.getBoundingClientRect(); + var parentRect = parent.getBoundingClientRect(); + var frameRect = frame.getBoundingClientRect(); + var me = this; + this.dom.absoluteAnchor = (0,_createAbsoluteAnchor__WEBPACK_IMPORTED_MODULE_0__/* .createAbsoluteAnchor */ .w)(anchor, frame, function () { + me.hide(); + }); + + if (anchorRect.bottom + this.maxHeight < frameRect.bottom) {// fits below -> show below + } else if (anchorRect.top - this.maxHeight > frameRect.top) { + // fits above -> show above + showBelow = false; + } else {// doesn't fit above nor below -> show below + } + + var topGap = ignoreParent ? 0 : anchorRect.top - parentRect.top; // position the menu + + if (showBelow) { + // display the menu below the anchor + var anchorHeight = anchor.offsetHeight; + this.dom.menu.style.left = '0'; + this.dom.menu.style.top = topGap + anchorHeight + 'px'; + this.dom.menu.style.bottom = ''; + } else { + // display the menu above the anchor + this.dom.menu.style.left = '0'; + this.dom.menu.style.top = ''; + this.dom.menu.style.bottom = '0px'; + } + + if (this.limitHeight) { + var margin = 10; // make sure there is a little margin left + + var maxPossibleMenuHeight = showBelow ? frameRect.bottom - anchorRect.bottom - margin : anchorRect.top - frameRect.top - margin; + this.dom.list.style.maxHeight = maxPossibleMenuHeight + 'px'; + this.dom.list.style.overflowY = 'auto'; + } // attach the menu to the temporary, absolute anchor + // parent.insertBefore(this.dom.root, anchor); + + + this.dom.absoluteAnchor.appendChild(this.dom.root); // move focus to the first button in the context menu + + this.selection = (0,_util__WEBPACK_IMPORTED_MODULE_1__.getSelection)(); + this.anchor = anchor; + setTimeout(function () { + me.dom.focusButton.focus(); + }, 0); + + if (ContextMenu.visibleMenu) { + ContextMenu.visibleMenu.hide(); + } + + ContextMenu.visibleMenu = this; + } + /** + * Hide the context menu if visible + */ + + }, { + key: "hide", + value: function hide() { + // remove temporary absolutely positioned anchor + if (this.dom.absoluteAnchor) { + this.dom.absoluteAnchor.destroy(); + delete this.dom.absoluteAnchor; + } // remove the menu from the DOM + + + if (this.dom.root.parentNode) { + this.dom.root.parentNode.removeChild(this.dom.root); + + if (this.onClose) { + this.onClose(); + } + } + + if (ContextMenu.visibleMenu === this) { + ContextMenu.visibleMenu = undefined; + } + } + /** + * Expand a submenu + * Any currently expanded submenu will be hided. + * @param {Object} domItem + * @private + */ + + }, { + key: "_onExpandItem", + value: function _onExpandItem(domItem) { + var me = this; + var alreadyVisible = domItem === this.expandedItem; // hide the currently visible submenu + + var expandedItem = this.expandedItem; + + if (expandedItem) { + // var ul = expandedItem.ul; + expandedItem.ul.style.height = '0'; + expandedItem.ul.style.padding = ''; + setTimeout(function () { + if (me.expandedItem !== expandedItem) { + expandedItem.ul.style.display = ''; + (0,_util__WEBPACK_IMPORTED_MODULE_1__.removeClassName)(expandedItem.ul.parentNode, 'jsoneditor-selected'); + } + }, 300); // timeout duration must match the css transition duration + + this.expandedItem = undefined; + } + + if (!alreadyVisible) { + var ul = domItem.ul; + ul.style.display = 'block'; // eslint-disable-next-line no-unused-expressions + + ul.clientHeight; // force a reflow in Firefox + + setTimeout(function () { + if (me.expandedItem === domItem) { + var childsHeight = 0; + + for (var i = 0; i < ul.childNodes.length; i++) { + childsHeight += ul.childNodes[i].clientHeight; + } + + ul.style.height = childsHeight + 'px'; + ul.style.padding = '5px 10px'; + } + }, 0); + (0,_util__WEBPACK_IMPORTED_MODULE_1__.addClassName)(ul.parentNode, 'jsoneditor-selected'); + this.expandedItem = domItem; + } + } + /** + * Handle onkeydown event + * @param {Event} event + * @private + */ + + }, { + key: "_onKeyDown", + value: function _onKeyDown(event) { + var target = event.target; + var keynum = event.which; + var handled = false; + var buttons, targetIndex, prevButton, nextButton; + + if (keynum === 27) { + // ESC + // hide the menu on ESC key + // restore previous selection and focus + if (this.selection) { + (0,_util__WEBPACK_IMPORTED_MODULE_1__.setSelection)(this.selection); + } + + if (this.anchor) { + this.anchor.focus(); + } + + this.hide(); + handled = true; + } else if (keynum === 9) { + // Tab + if (!event.shiftKey) { + // Tab + buttons = this._getVisibleButtons(); + targetIndex = buttons.indexOf(target); + + if (targetIndex === buttons.length - 1) { + // move to first button + buttons[0].focus(); + handled = true; + } + } else { + // Shift+Tab + buttons = this._getVisibleButtons(); + targetIndex = buttons.indexOf(target); + + if (targetIndex === 0) { + // move to last button + buttons[buttons.length - 1].focus(); + handled = true; + } + } + } else if (keynum === 37) { + // Arrow Left + if (target.className === 'jsoneditor-expand') { + buttons = this._getVisibleButtons(); + targetIndex = buttons.indexOf(target); + prevButton = buttons[targetIndex - 1]; + + if (prevButton) { + prevButton.focus(); + } + } + + handled = true; + } else if (keynum === 38) { + // Arrow Up + buttons = this._getVisibleButtons(); + targetIndex = buttons.indexOf(target); + prevButton = buttons[targetIndex - 1]; + + if (prevButton && prevButton.className === 'jsoneditor-expand') { + // skip expand button + prevButton = buttons[targetIndex - 2]; + } + + if (!prevButton) { + // move to last button + prevButton = buttons[buttons.length - 1]; + } + + if (prevButton) { + prevButton.focus(); + } + + handled = true; + } else if (keynum === 39) { + // Arrow Right + buttons = this._getVisibleButtons(); + targetIndex = buttons.indexOf(target); + nextButton = buttons[targetIndex + 1]; + + if (nextButton && nextButton.className === 'jsoneditor-expand') { + nextButton.focus(); + } + + handled = true; + } else if (keynum === 40) { + // Arrow Down + buttons = this._getVisibleButtons(); + targetIndex = buttons.indexOf(target); + nextButton = buttons[targetIndex + 1]; + + if (nextButton && nextButton.className === 'jsoneditor-expand') { + // skip expand button + nextButton = buttons[targetIndex + 2]; + } + + if (!nextButton) { + // move to first button + nextButton = buttons[0]; + } + + if (nextButton) { + nextButton.focus(); + handled = true; + } + + handled = true; + } // TODO: arrow left and right + + + if (handled) { + event.stopPropagation(); + event.preventDefault(); + } + } + }]); + + return ContextMenu; +}(); // currently displayed context menu, a singleton. We may only have one visible context menu + +ContextMenu.visibleMenu = undefined; + +/***/ }), + +/***/ 6436: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Q": function() { return /* binding */ ErrorTable; } +/* harmony export */ }); +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +/** + * Show errors and schema warnings in a clickable table view + * @param {Object} config + * @property {boolean} errorTableVisible + * @property {function (boolean) : void} onToggleVisibility + * @property {function (number)} [onFocusLine] + * @property {function (number)} onChangeHeight + * @constructor + */ +var ErrorTable = /*#__PURE__*/function () { + function ErrorTable(config) { + _classCallCheck(this, ErrorTable); + + this.errorTableVisible = config.errorTableVisible; + this.onToggleVisibility = config.onToggleVisibility; + + this.onFocusLine = config.onFocusLine || function () {}; + + this.onChangeHeight = config.onChangeHeight; + this.dom = {}; + var validationErrorsContainer = document.createElement('div'); + validationErrorsContainer.className = 'jsoneditor-validation-errors-container'; + this.dom.validationErrorsContainer = validationErrorsContainer; + var additionalErrorsIndication = document.createElement('div'); + additionalErrorsIndication.style.display = 'none'; + additionalErrorsIndication.className = 'jsoneditor-additional-errors fadein'; + additionalErrorsIndication.textContent = "Scroll for more \u25BF"; + this.dom.additionalErrorsIndication = additionalErrorsIndication; + validationErrorsContainer.appendChild(additionalErrorsIndication); + var validationErrorIcon = document.createElement('span'); + validationErrorIcon.className = 'jsoneditor-validation-error-icon'; + validationErrorIcon.style.display = 'none'; + this.dom.validationErrorIcon = validationErrorIcon; + var validationErrorCount = document.createElement('span'); + validationErrorCount.className = 'jsoneditor-validation-error-count'; + validationErrorCount.style.display = 'none'; + this.dom.validationErrorCount = validationErrorCount; + this.dom.parseErrorIndication = document.createElement('span'); + this.dom.parseErrorIndication.className = 'jsoneditor-parse-error-icon'; + this.dom.parseErrorIndication.style.display = 'none'; + } + + _createClass(ErrorTable, [{ + key: "getErrorTable", + value: function getErrorTable() { + return this.dom.validationErrorsContainer; + } + }, { + key: "getErrorCounter", + value: function getErrorCounter() { + return this.dom.validationErrorCount; + } + }, { + key: "getWarningIcon", + value: function getWarningIcon() { + return this.dom.validationErrorIcon; + } + }, { + key: "getErrorIcon", + value: function getErrorIcon() { + return this.dom.parseErrorIndication; + } + }, { + key: "toggleTableVisibility", + value: function toggleTableVisibility() { + this.errorTableVisible = !this.errorTableVisible; + this.onToggleVisibility(this.errorTableVisible); + } + }, { + key: "setErrors", + value: function setErrors(errors, errorLocations) { + var _this = this; + + // clear any previous errors + if (this.dom.validationErrors) { + this.dom.validationErrors.parentNode.removeChild(this.dom.validationErrors); + this.dom.validationErrors = null; + this.dom.additionalErrorsIndication.style.display = 'none'; + } // create the table with errors + // keep default behavior for parse errors + + + if (this.errorTableVisible && errors.length > 0) { + var validationErrors = document.createElement('div'); + validationErrors.className = 'jsoneditor-validation-errors'; + var table = document.createElement('table'); + table.className = 'jsoneditor-text-errors'; + validationErrors.appendChild(table); + var tbody = document.createElement('tbody'); + table.appendChild(tbody); + errors.forEach(function (error) { + var line; + + if (!isNaN(error.line)) { + line = error.line; + } else if (error.dataPath) { + var errLoc = errorLocations.find(function (loc) { + return loc.path === error.dataPath; + }); + + if (errLoc) { + line = errLoc.line + 1; + } + } + + var trEl = document.createElement('tr'); + trEl.className = !isNaN(line) ? 'jump-to-line' : ''; + + if (error.type === 'error') { + trEl.className += ' parse-error'; + } else { + trEl.className += ' validation-error'; + } + + var td1 = document.createElement('td'); + var button = document.createElement('button'); + button.className = 'jsoneditor-schema-error'; + td1.appendChild(button); + trEl.appendChild(td1); + var td2 = document.createElement('td'); + td2.style = 'white-space: nowrap;'; + td2.textContent = !isNaN(line) ? 'Ln ' + line : ''; + trEl.appendChild(td2); + + if (typeof error === 'string') { + var td34 = document.createElement('td'); + td34.colSpan = 2; + var pre = document.createElement('pre'); + pre.appendChild(document.createTextNode(error)); + td34.appendChild(pre); + trEl.appendChild(td34); + } else { + var td3 = document.createElement('td'); + td3.appendChild(document.createTextNode(error.dataPath || '')); + trEl.appendChild(td3); + var td4 = document.createElement('td'); + + var _pre = document.createElement('pre'); + + _pre.appendChild(document.createTextNode(error.message)); + + td4.appendChild(_pre); + trEl.appendChild(td4); + } + + trEl.onclick = function () { + _this.onFocusLine(line); + }; + + tbody.appendChild(trEl); + }); + this.dom.validationErrors = validationErrors; + this.dom.validationErrorsContainer.appendChild(validationErrors); + this.dom.additionalErrorsIndication.title = errors.length + ' errors total'; + + if (this.dom.validationErrorsContainer.clientHeight < this.dom.validationErrorsContainer.scrollHeight) { + this.dom.additionalErrorsIndication.style.display = 'block'; + + this.dom.validationErrorsContainer.onscroll = function () { + _this.dom.additionalErrorsIndication.style.display = _this.dom.validationErrorsContainer.clientHeight > 0 && _this.dom.validationErrorsContainer.scrollTop === 0 ? 'block' : 'none'; + }; + } else { + this.dom.validationErrorsContainer.onscroll = undefined; + } + + var height = this.dom.validationErrorsContainer.clientHeight + (this.dom.statusBar ? this.dom.statusBar.clientHeight : 0); // this.content.style.marginBottom = (-height) + 'px'; + // this.content.style.paddingBottom = height + 'px'; + + this.onChangeHeight(height); + } else { + this.onChangeHeight(0); + } // update the status bar + + + var validationErrorsCount = errors.filter(function (error) { + return error.type !== 'error'; + }).length; + + if (validationErrorsCount > 0) { + this.dom.validationErrorCount.style.display = 'inline'; + this.dom.validationErrorCount.innerText = validationErrorsCount; + this.dom.validationErrorCount.onclick = this.toggleTableVisibility.bind(this); + this.dom.validationErrorIcon.style.display = 'inline'; + this.dom.validationErrorIcon.title = validationErrorsCount + ' schema validation error(s) found'; + this.dom.validationErrorIcon.onclick = this.toggleTableVisibility.bind(this); + } else { + this.dom.validationErrorCount.style.display = 'none'; + this.dom.validationErrorIcon.style.display = 'none'; + } // update the parse error icon + + + var hasParseErrors = errors.some(function (error) { + return error.type === 'error'; + }); + + if (hasParseErrors) { + var line = errors[0].line; + this.dom.parseErrorIndication.style.display = 'block'; + this.dom.parseErrorIndication.title = !isNaN(line) ? 'parse error on line ' + line : 'parse error - check that the json is valid'; + this.dom.parseErrorIndication.onclick = this.toggleTableVisibility.bind(this); + } else { + this.dom.parseErrorIndication.style.display = 'none'; + } + } + }]); + + return ErrorTable; +}(); + +/***/ }), + +/***/ 2474: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "R": function() { return /* binding */ FocusTracker; } +/* harmony export */ }); + +/** + * @constructor FocusTracker + * A custom focus tracker for a DOM element with complex internal DOM structure + * @param {[Object]} config A set of configurations for the FocusTracker + * {DOM Object} target * The DOM object to track (required) + * {Function} onFocus onFocus callback + * {Function} onBlur onBlur callback + * + * @return + */ + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +var FocusTracker = /*#__PURE__*/function () { + function FocusTracker(config) { + _classCallCheck(this, FocusTracker); + + this.target = config.target || null; + + if (!this.target) { + throw new Error('FocusTracker constructor called without a "target" to track.'); + } + + this.onFocus = typeof config.onFocus === 'function' ? config.onFocus : null; + this.onBlur = typeof config.onBlur === 'function' ? config.onBlur : null; + this._onClick = this._onEvent.bind(this); + + this._onKeyUp = function (event) { + if (event.which === 9 || event.keyCode === 9) { + this._onEvent(event); + } + }.bind(this); + + this.focusFlag = false; + this.firstEventFlag = true; + /* + Adds required (click and keyup) event listeners to the 'document' object + to track the focus of the given 'target' + */ + + if (this.onFocus || this.onBlur) { + document.addEventListener('click', this._onClick); + document.addEventListener('keyup', this._onKeyUp); + } + } + /** + * Removes the event listeners on the 'document' object + * that were added to track the focus of the given 'target' + */ + + + _createClass(FocusTracker, [{ + key: "destroy", + value: function destroy() { + document.removeEventListener('click', this._onClick); + document.removeEventListener('keyup', this._onKeyUp); + + this._onEvent({ + target: document.body + }); // calling _onEvent with body element in the hope that the FocusTracker is added to an element inside the body tag + + } + /** + * Tracks the focus of the target and calls the onFocus and onBlur + * event callbacks if available. + * @param {Event} [event] The 'click' or 'keyup' event object, + * from the respective events set on + * document object + * @private + */ + + }, { + key: "_onEvent", + value: function _onEvent(event) { + var target = event.target; + var focusFlag; + + if (target === this.target) { + focusFlag = true; + } else if (this.target.contains(target) || this.target.contains(document.activeElement)) { + focusFlag = true; + } else { + focusFlag = false; + } + + if (focusFlag) { + if (!this.focusFlag) { + // trigger the onFocus callback + if (this.onFocus) { + this.onFocus({ + type: 'focus', + target: this.target + }); + } + + this.focusFlag = true; + } + } else { + if (this.focusFlag || this.firstEventFlag) { + // trigger the onBlur callback + if (this.onBlur) { + this.onBlur({ + type: 'blur', + target: this.target + }); + } + + this.focusFlag = false; + /* + When switching from one mode to another in the editor, the FocusTracker gets recreated. + At that time, this.focusFlag will be init to 'false' and will fail the above if condition, when blur occurs + this.firstEventFlag is added to overcome that issue + */ + + if (this.firstEventFlag) { + this.firstEventFlag = false; + } + } + } + } + }]); + + return FocusTracker; +}(); + +/***/ }), + +/***/ 3161: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +"use strict"; + + +var ace = __webpack_require__(8170); // may be undefined in case of minimalist bundle + + +var VanillaPicker = __webpack_require__(8037); // may be undefined in case of minimalist bundle + + +var _require = __webpack_require__(8038), + treeModeMixins = _require.treeModeMixins; + +var _require2 = __webpack_require__(5956), + textModeMixins = _require2.textModeMixins; + +var _require3 = __webpack_require__(341), + previewModeMixins = _require3.previewModeMixins; + +var _require4 = __webpack_require__(9791), + clear = _require4.clear, + extend = _require4.extend, + getInnerText = _require4.getInnerText, + getInternetExplorerVersion = _require4.getInternetExplorerVersion, + parse = _require4.parse; + +var _require5 = __webpack_require__(2744), + tryRequireAjv = _require5.tryRequireAjv; + +var _require6 = __webpack_require__(2558), + showTransformModal = _require6.showTransformModal; + +var _require7 = __webpack_require__(6210), + showSortModal = _require7.showSortModal; + +var Ajv = tryRequireAjv(); + +if (typeof Promise === 'undefined') { + console.error('Promise undefined. Please load a Promise polyfill in the browser in order to use JSONEditor'); +} +/** + * @constructor JSONEditor + * @param {Element} container Container element + * @param {Object} [options] Object with options. available options: + * {String} mode Editor mode. Available values: + * 'tree' (default), 'view', + * 'form', 'text', and 'code'. + * {function} onChange Callback method, triggered + * on change of contents. + * Does not pass the contents itself. + * See also `onChangeJSON` and + * `onChangeText`. + * {function} onChangeJSON Callback method, triggered + * in modes on change of contents, + * passing the changed contents + * as JSON. + * Only applicable for modes + * 'tree', 'view', and 'form'. + * {function} onChangeText Callback method, triggered + * in modes on change of contents, + * passing the changed contents + * as stringified JSON. + * {function} onError Callback method, triggered + * when an error occurs + * {Boolean} search Enable search box. + * True by default + * Only applicable for modes + * 'tree', 'view', and 'form' + * {Boolean} history Enable history (undo/redo). + * True by default + * Only applicable for modes + * 'tree', 'view', and 'form' + * {String} name Field name for the root node. + * Only applicable for modes + * 'tree', 'view', and 'form' + * {Number} indentation Number of indentation + * spaces. 4 by default. + * Only applicable for + * modes 'text' and 'code' + * {boolean} escapeUnicode If true, unicode + * characters are escaped. + * false by default. + * {boolean} sortObjectKeys If true, object keys are + * sorted before display. + * false by default. + * {function} onSelectionChange Callback method, + * triggered on node selection change + * Only applicable for modes + * 'tree', 'view', and 'form' + * {function} onTextSelectionChange Callback method, + * triggered on text selection change + * Only applicable for modes + * {HTMLElement} modalAnchor The anchor element to apply an + * overlay and display the modals in a + * centered location. + * Defaults to document.body + * 'text' and 'code' + * {function} onEvent Callback method, triggered + * when an event occurs in + * a JSON field or value. + * Only applicable for + * modes 'form', 'tree' and + * 'view' + * {function} onFocus Callback method, triggered + * when the editor comes into focus, + * passing an object {type, target}, + * Applicable for all modes + * {function} onBlur Callback method, triggered + * when the editor goes out of focus, + * passing an object {type, target}, + * Applicable for all modes + * {function} onClassName Callback method, triggered + * when a Node DOM is rendered. Function returns + * a css class name to be set on a node. + * Only applicable for + * modes 'form', 'tree' and + * 'view' + * {Number} maxVisibleChilds Number of children allowed for a node + * in 'tree', 'view', or 'form' mode before + * the "show more/show all" buttons appear. + * 100 by default. + * + * @param {Object | undefined} json JSON object + */ + + +function JSONEditor(container, options, json) { + if (!(this instanceof JSONEditor)) { + throw new Error('JSONEditor constructor called without "new".'); + } // check for unsupported browser (IE8 and older) + + + var ieVersion = getInternetExplorerVersion(); + + if (ieVersion !== -1 && ieVersion < 9) { + throw new Error('Unsupported browser, IE9 or newer required. ' + 'Please install the newest version of your browser.'); + } + + if (options) { + // check for deprecated options + if (options.error) { + console.warn('Option "error" has been renamed to "onError"'); + options.onError = options.error; + delete options.error; + } + + if (options.change) { + console.warn('Option "change" has been renamed to "onChange"'); + options.onChange = options.change; + delete options.change; + } + + if (options.editable) { + console.warn('Option "editable" has been renamed to "onEditable"'); + options.onEditable = options.editable; + delete options.editable; + } // warn if onChangeJSON is used when mode can be `text` or `code` + + + if (options.onChangeJSON) { + if (options.mode === 'text' || options.mode === 'code' || options.modes && (options.modes.indexOf('text') !== -1 || options.modes.indexOf('code') !== -1)) { + console.warn('Option "onChangeJSON" is not applicable to modes "text" and "code". ' + 'Use "onChangeText" or "onChange" instead.'); + } + } // validate options + + + if (options) { + Object.keys(options).forEach(function (option) { + if (JSONEditor.VALID_OPTIONS.indexOf(option) === -1) { + console.warn('Unknown option "' + option + '". This option will be ignored'); + } + }); + } + } + + if (arguments.length) { + this._create(container, options, json); + } +} +/** + * Configuration for all registered modes. Example: + * { + * tree: { + * mixin: TreeEditor, + * data: 'json' + * }, + * text: { + * mixin: TextEditor, + * data: 'text' + * } + * } + * + * @type { Object. } + */ + + +JSONEditor.modes = {}; // debounce interval for JSON schema validation in milliseconds + +JSONEditor.prototype.DEBOUNCE_INTERVAL = 150; +JSONEditor.VALID_OPTIONS = ['ajv', 'schema', 'schemaRefs', 'templates', 'ace', 'theme', 'autocomplete', 'onChange', 'onChangeJSON', 'onChangeText', 'onEditable', 'onError', 'onEvent', 'onModeChange', 'onNodeName', 'onValidate', 'onCreateMenu', 'onSelectionChange', 'onTextSelectionChange', 'onClassName', 'onFocus', 'onBlur', 'colorPicker', 'onColorPicker', 'timestampTag', 'timestampFormat', 'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation', 'sortObjectKeys', 'navigationBar', 'statusBar', 'mainMenuBar', 'languages', 'language', 'enableSort', 'enableTransform', 'limitDragging', 'maxVisibleChilds', 'onValidationError', 'modalAnchor', 'popupAnchor', 'createQuery', 'executeQuery', 'queryDescription']; +/** + * Create the JSONEditor + * @param {Element} container Container element + * @param {Object} [options] See description in constructor + * @param {Object | undefined} json JSON object + * @private + */ + +JSONEditor.prototype._create = function (container, options, json) { + this.container = container; + this.options = options || {}; + this.json = json || {}; + var mode = this.options.mode || this.options.modes && this.options.modes[0] || 'tree'; + this.setMode(mode); +}; +/** + * Destroy the editor. Clean up DOM, event listeners, and web workers. + */ + + +JSONEditor.prototype.destroy = function () {}; +/** + * Set JSON object in editor + * @param {Object | undefined} json JSON data + */ + + +JSONEditor.prototype.set = function (json) { + this.json = json; +}; +/** + * Get JSON from the editor + * @returns {Object} json + */ + + +JSONEditor.prototype.get = function () { + return this.json; +}; +/** + * Set string containing JSON for the editor + * @param {String | undefined} jsonText + */ + + +JSONEditor.prototype.setText = function (jsonText) { + this.json = parse(jsonText); +}; +/** + * Get stringified JSON contents from the editor + * @returns {String} jsonText + */ + + +JSONEditor.prototype.getText = function () { + return JSON.stringify(this.json); +}; +/** + * Set a field name for the root node. + * @param {String | undefined} name + */ + + +JSONEditor.prototype.setName = function (name) { + if (!this.options) { + this.options = {}; + } + + this.options.name = name; +}; +/** + * Get the field name for the root node. + * @return {String | undefined} name + */ + + +JSONEditor.prototype.getName = function () { + return this.options && this.options.name; +}; +/** + * Change the mode of the editor. + * JSONEditor will be extended with all methods needed for the chosen mode. + * @param {String} mode Available modes: 'tree' (default), 'view', 'form', + * 'text', and 'code'. + */ + + +JSONEditor.prototype.setMode = function (mode) { + // if the mode is the same as current mode (and it's not the first time), do nothing. + if (mode === this.options.mode && this.create) { + return; + } + + var container = this.container; + var options = extend({}, this.options); + var oldMode = options.mode; + var data; + var name; + options.mode = mode; + var config = JSONEditor.modes[mode]; + + if (config) { + try { + var asText = config.data === 'text'; + name = this.getName(); + data = this[asText ? 'getText' : 'get'](); // get text or json + + this.destroy(); + clear(this); + extend(this, config.mixin); + this.create(container, options); + this.setName(name); + this[asText ? 'setText' : 'set'](data); // set text or json + + if (typeof config.load === 'function') { + try { + config.load.call(this); + } catch (err) { + console.error(err); + } + } + + if (typeof options.onModeChange === 'function' && mode !== oldMode) { + try { + options.onModeChange(mode, oldMode); + } catch (err) { + console.error(err); + } + } + } catch (err) { + this._onError(err); + } + } else { + throw new Error('Unknown mode "' + options.mode + '"'); + } +}; +/** + * Get the current mode + * @return {string} + */ + + +JSONEditor.prototype.getMode = function () { + return this.options.mode; +}; +/** + * Throw an error. If an error callback is configured in options.error, this + * callback will be invoked. Else, a regular error is thrown. + * @param {Error} err + * @private + */ + + +JSONEditor.prototype._onError = function (err) { + if (this.options && typeof this.options.onError === 'function') { + this.options.onError(err); + } else { + throw err; + } +}; +/** + * Set a JSON schema for validation of the JSON object. + * To remove the schema, call JSONEditor.setSchema(null) + * @param {Object | null} schema + * @param {Object.=} schemaRefs Schemas that are referenced using the `$ref` property from the JSON schema that are set in the `schema` option, + + the object structure in the form of `{reference_key: schemaObject}` + */ + + +JSONEditor.prototype.setSchema = function (schema, schemaRefs) { + // compile a JSON schema validator if a JSON schema is provided + if (schema) { + var ajv; + + try { + // grab ajv from options if provided, else create a new instance + if (this.options.ajv) { + ajv = this.options.ajv; + } else { + ajv = Ajv({ + allErrors: true, + verbose: true, + schemaId: 'auto', + $data: true + }); // support both draft-04 and draft-06 alongside the latest draft-07 + + ajv.addMetaSchema(__webpack_require__(2689)); + ajv.addMetaSchema(__webpack_require__(1030)); + } + } catch (err) { + console.warn('Failed to create an instance of Ajv, JSON Schema validation is not available. Please use a JSONEditor bundle including Ajv, or pass an instance of Ajv as via the configuration option `ajv`.'); + } + + if (ajv) { + if (schemaRefs) { + for (var ref in schemaRefs) { + ajv.removeSchema(ref); // When updating a schema - old refs has to be removed first + + if (schemaRefs[ref]) { + ajv.addSchema(schemaRefs[ref], ref); + } + } + + this.options.schemaRefs = schemaRefs; + } + + this.validateSchema = ajv.compile(schema); // add schema to the options, so that when switching to an other mode, + // the set schema is not lost + + this.options.schema = schema; // validate now + + this.validate(); + } + + this.refresh(); // update DOM + } else { + // remove current schema + this.validateSchema = null; + this.options.schema = null; + this.options.schemaRefs = null; + this.validate(); // to clear current error messages + + this.refresh(); // update DOM + } +}; +/** + * Validate current JSON object against the configured JSON schema + * Throws an exception when no JSON schema is configured + */ + + +JSONEditor.prototype.validate = function () {// must be implemented by treemode and textmode +}; +/** + * Refresh the rendered contents + */ + + +JSONEditor.prototype.refresh = function () {// can be implemented by treemode and textmode +}; +/** + * Register a plugin with one ore multiple modes for the JSON Editor. + * + * A mode is described as an object with properties: + * + * - `mode: String` The name of the mode. + * - `mixin: Object` An object containing the mixin functions which + * will be added to the JSONEditor. Must contain functions + * create, get, getText, set, and setText. May have + * additional functions. + * When the JSONEditor switches to a mixin, all mixin + * functions are added to the JSONEditor, and then + * the function `create(container, options)` is executed. + * - `data: 'text' | 'json'` The type of data that will be used to load the mixin. + * - `[load: function]` An optional function called after the mixin + * has been loaded. + * + * @param {Object | Array} mode A mode object or an array with multiple mode objects. + */ + + +JSONEditor.registerMode = function (mode) { + var i, prop; + + if (Array.isArray(mode)) { + // multiple modes + for (i = 0; i < mode.length; i++) { + JSONEditor.registerMode(mode[i]); + } + } else { + // validate the new mode + if (!('mode' in mode)) throw new Error('Property "mode" missing'); + if (!('mixin' in mode)) throw new Error('Property "mixin" missing'); + if (!('data' in mode)) throw new Error('Property "data" missing'); + var name = mode.mode; + + if (name in JSONEditor.modes) { + throw new Error('Mode "' + name + '" already registered'); + } // validate the mixin + + + if (typeof mode.mixin.create !== 'function') { + throw new Error('Required function "create" missing on mixin'); + } + + var reserved = ['setMode', 'registerMode', 'modes']; + + for (i = 0; i < reserved.length; i++) { + prop = reserved[i]; + + if (prop in mode.mixin) { + throw new Error('Reserved property "' + prop + '" not allowed in mixin'); + } + } + + JSONEditor.modes[name] = mode; + } +}; // register tree, text, and preview modes + + +JSONEditor.registerMode(treeModeMixins); +JSONEditor.registerMode(textModeMixins); +JSONEditor.registerMode(previewModeMixins); // expose some of the libraries that can be used customized + +JSONEditor.ace = ace; +JSONEditor.Ajv = Ajv; +JSONEditor.VanillaPicker = VanillaPicker; // expose some utils (this is undocumented, unofficial) + +JSONEditor.showTransformModal = showTransformModal; +JSONEditor.showSortModal = showSortModal; +JSONEditor.getInnerText = getInnerText; // default export for TypeScript ES6 projects + +JSONEditor["default"] = JSONEditor; +module.exports = JSONEditor; + +/***/ }), + +/***/ 6617: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "x": function() { return /* binding */ ModeSwitcher; } +/* harmony export */ }); +/* harmony import */ var _ContextMenu__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(897); +/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7907); + + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + + + +/** + * Create a select box to be used in the editor menu's, which allows to switch mode + * @param {HTMLElement} container + * @param {String[]} modes Available modes: 'code', 'form', 'text', 'tree', 'view', 'preview' + * @param {String} current Available modes: 'code', 'form', 'text', 'tree', 'view', 'preview' + * @param {function(mode: string)} onSwitch Callback invoked on switch + * @constructor + */ + +var ModeSwitcher = /*#__PURE__*/function () { + function ModeSwitcher(container, modes, current, onSwitch) { + _classCallCheck(this, ModeSwitcher); + + // available modes + var availableModes = { + code: { + text: (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('modeCodeText'), + title: (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('modeCodeTitle'), + click: function click() { + onSwitch('code'); + } + }, + form: { + text: (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('modeFormText'), + title: (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('modeFormTitle'), + click: function click() { + onSwitch('form'); + } + }, + text: { + text: (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('modeTextText'), + title: (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('modeTextTitle'), + click: function click() { + onSwitch('text'); + } + }, + tree: { + text: (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('modeTreeText'), + title: (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('modeTreeTitle'), + click: function click() { + onSwitch('tree'); + } + }, + view: { + text: (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('modeViewText'), + title: (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('modeViewTitle'), + click: function click() { + onSwitch('view'); + } + }, + preview: { + text: (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('modePreviewText'), + title: (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('modePreviewTitle'), + click: function click() { + onSwitch('preview'); + } + } + }; // list the selected modes + + var items = []; + + for (var i = 0; i < modes.length; i++) { + var mode = modes[i]; + var item = availableModes[mode]; + + if (!item) { + throw new Error('Unknown mode "' + mode + '"'); + } + + item.className = 'jsoneditor-type-modes' + (current === mode ? ' jsoneditor-selected' : ''); + items.push(item); + } // retrieve the title of current mode + + + var currentMode = availableModes[current]; + + if (!currentMode) { + throw new Error('Unknown mode "' + current + '"'); + } + + var currentTitle = currentMode.text; // create the html element + + var box = document.createElement('button'); + box.type = 'button'; + box.className = 'jsoneditor-modes jsoneditor-separator'; + box.textContent = currentTitle + " \u25BE"; + box.title = (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('modeEditorTitle'); + + box.onclick = function () { + var menu = new _ContextMenu__WEBPACK_IMPORTED_MODULE_0__/* .ContextMenu */ .x(items); + menu.show(box, container); + }; + + var frame = document.createElement('div'); + frame.className = 'jsoneditor-modes'; + frame.style.position = 'relative'; + frame.appendChild(box); + container.appendChild(frame); + this.dom = { + container: container, + box: box, + frame: frame + }; + } + /** + * Set focus to switcher + */ + + + _createClass(ModeSwitcher, [{ + key: "focus", + value: function focus() { + this.dom.box.focus(); + } + /** + * Destroy the ModeSwitcher, remove from DOM + */ + + }, { + key: "destroy", + value: function destroy() { + if (this.dom && this.dom.frame && this.dom.frame.parentNode) { + this.dom.frame.parentNode.removeChild(this.dom.frame); + } + + this.dom = null; + } + }]); + + return ModeSwitcher; +}(); + +/***/ }), + +/***/ 8170: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +var ace; + +if (window.ace) { + // use the already loaded instance of Ace + ace = window.ace; +} else { + try { + // load Ace editor + ace = __webpack_require__(6225); // load required Ace plugins + + __webpack_require__(4091); + + __webpack_require__(3330); // embed Ace json worker + // https://github.com/ajaxorg/ace/issues/3913 + + + var jsonWorkerDataUrl = __webpack_require__(7923); + + ace.config.setModuleUrl('ace/mode/json_worker', jsonWorkerDataUrl); + } catch (err) {// failed to load Ace (can be minimalist bundle). + // No worries, the editor will fall back to plain text if needed. + } +} + +module.exports = ace; + +/***/ }), + +/***/ 4864: +/***/ (function() { + +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use 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 Ajax.org B.V. 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 AJAX.ORG B.V. 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. + * + * ***** END LICENSE BLOCK ***** */ +window.ace.define('ace/theme/jsoneditor', ['require', 'exports', 'module', 'ace/lib/dom'], function (acequire, exports, module) { + exports.isDark = false; + exports.cssClass = 'ace-jsoneditor'; + exports.cssText = ".ace-jsoneditor .ace_gutter {\nbackground: #ebebeb;\ncolor: #333\n}\n\n.ace-jsoneditor.ace_editor {\nfont-family: \"dejavu sans mono\", \"droid sans mono\", consolas, monaco, \"lucida console\", \"courier new\", courier, monospace, sans-serif;\nline-height: 1.3;\nbackground-color: #fff;\n}\n.ace-jsoneditor .ace_print-margin {\nwidth: 1px;\nbackground: #e8e8e8\n}\n.ace-jsoneditor .ace_scroller {\nbackground-color: #FFFFFF\n}\n.ace-jsoneditor .ace_text-layer {\ncolor: gray\n}\n.ace-jsoneditor .ace_variable {\ncolor: #1a1a1a\n}\n.ace-jsoneditor .ace_cursor {\nborder-left: 2px solid #000000\n}\n.ace-jsoneditor .ace_overwrite-cursors .ace_cursor {\nborder-left: 0px;\nborder-bottom: 1px solid #000000\n}\n.ace-jsoneditor .ace_marker-layer .ace_selection {\nbackground: lightgray\n}\n.ace-jsoneditor.ace_multiselect .ace_selection.ace_start {\nbox-shadow: 0 0 3px 0px #FFFFFF;\nborder-radius: 2px\n}\n.ace-jsoneditor .ace_marker-layer .ace_step {\nbackground: rgb(255, 255, 0)\n}\n.ace-jsoneditor .ace_marker-layer .ace_bracket {\nmargin: -1px 0 0 -1px;\nborder: 1px solid #BFBFBF\n}\n.ace-jsoneditor .ace_marker-layer .ace_active-line {\nbackground: #FFFBD1\n}\n.ace-jsoneditor .ace_gutter-active-line {\nbackground-color : #dcdcdc\n}\n.ace-jsoneditor .ace_marker-layer .ace_selected-word {\nborder: 1px solid lightgray\n}\n.ace-jsoneditor .ace_invisible {\ncolor: #BFBFBF\n}\n.ace-jsoneditor .ace_keyword,\n.ace-jsoneditor .ace_meta,\n.ace-jsoneditor .ace_support.ace_constant.ace_property-value {\ncolor: #AF956F\n}\n.ace-jsoneditor .ace_keyword.ace_operator {\ncolor: #484848\n}\n.ace-jsoneditor .ace_keyword.ace_other.ace_unit {\ncolor: #96DC5F\n}\n.ace-jsoneditor .ace_constant.ace_language {\ncolor: darkorange\n}\n.ace-jsoneditor .ace_constant.ace_numeric {\ncolor: red\n}\n.ace-jsoneditor .ace_constant.ace_character.ace_entity {\ncolor: #BF78CC\n}\n.ace-jsoneditor .ace_invalid {\ncolor: #FFFFFF;\nbackground-color: #FF002A;\n}\n.ace-jsoneditor .ace_fold {\nbackground-color: #AF956F;\nborder-color: #000000\n}\n.ace-jsoneditor .ace_storage,\n.ace-jsoneditor .ace_support.ace_class,\n.ace-jsoneditor .ace_support.ace_function,\n.ace-jsoneditor .ace_support.ace_other,\n.ace-jsoneditor .ace_support.ace_type {\ncolor: #C52727\n}\n.ace-jsoneditor .ace_string {\ncolor: green\n}\n.ace-jsoneditor .ace_comment {\ncolor: #BCC8BA\n}\n.ace-jsoneditor .ace_entity.ace_name.ace_tag,\n.ace-jsoneditor .ace_entity.ace_other.ace_attribute-name {\ncolor: #606060\n}\n.ace-jsoneditor .ace_markup.ace_underline {\ntext-decoration: underline\n}\n.ace-jsoneditor .ace_indent-guide {\nbackground: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y\n}"; + var dom = acequire('../lib/dom'); + dom.importCssString(exports.cssText, exports.cssClass); +}); + +/***/ }), + +/***/ 6589: +/***/ (function(__unused_webpack_module, exports) { + +/* Jison generated parser */ +var jsonlint = function () { + var parser = { + trace: function trace() {}, + yy: {}, + symbols_: { + "error": 2, + "JSONString": 3, + "STRING": 4, + "JSONNumber": 5, + "NUMBER": 6, + "JSONNullLiteral": 7, + "NULL": 8, + "JSONBooleanLiteral": 9, + "TRUE": 10, + "FALSE": 11, + "JSONText": 12, + "JSONValue": 13, + "EOF": 14, + "JSONObject": 15, + "JSONArray": 16, + "{": 17, + "}": 18, + "JSONMemberList": 19, + "JSONMember": 20, + ":": 21, + ",": 22, + "[": 23, + "]": 24, + "JSONElementList": 25, + "$accept": 0, + "$end": 1 + }, + terminals_: { + 2: "error", + 4: "STRING", + 6: "NUMBER", + 8: "NULL", + 10: "TRUE", + 11: "FALSE", + 14: "EOF", + 17: "{", + 18: "}", + 21: ":", + 22: ",", + 23: "[", + 24: "]" + }, + productions_: [0, [3, 1], [5, 1], [7, 1], [9, 1], [9, 1], [12, 2], [13, 1], [13, 1], [13, 1], [13, 1], [13, 1], [13, 1], [15, 2], [15, 3], [20, 3], [19, 1], [19, 3], [16, 2], [16, 3], [25, 1], [25, 3]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + + switch (yystate) { + case 1: + // replace escaped characters with actual character + this.$ = yytext.replace(/\\(\\|")/g, "$" + "1").replace(/\\n/g, '\n').replace(/\\r/g, '\r').replace(/\\t/g, '\t').replace(/\\v/g, '\v').replace(/\\f/g, '\f').replace(/\\b/g, '\b'); + break; + + case 2: + this.$ = Number(yytext); + break; + + case 3: + this.$ = null; + break; + + case 4: + this.$ = true; + break; + + case 5: + this.$ = false; + break; + + case 6: + return this.$ = $$[$0 - 1]; + break; + + case 13: + this.$ = {}; + break; + + case 14: + this.$ = $$[$0 - 1]; + break; + + case 15: + this.$ = [$$[$0 - 2], $$[$0]]; + break; + + case 16: + this.$ = {}; + this.$[$$[$0][0]] = $$[$0][1]; + break; + + case 17: + this.$ = $$[$0 - 2]; + $$[$0 - 2][$$[$0][0]] = $$[$0][1]; + break; + + case 18: + this.$ = []; + break; + + case 19: + this.$ = $$[$0 - 1]; + break; + + case 20: + this.$ = [$$[$0]]; + break; + + case 21: + this.$ = $$[$0 - 2]; + $$[$0 - 2].push($$[$0]); + break; + } + }, + table: [{ + 3: 5, + 4: [1, 12], + 5: 6, + 6: [1, 13], + 7: 3, + 8: [1, 9], + 9: 4, + 10: [1, 10], + 11: [1, 11], + 12: 1, + 13: 2, + 15: 7, + 16: 8, + 17: [1, 14], + 23: [1, 15] + }, { + 1: [3] + }, { + 14: [1, 16] + }, { + 14: [2, 7], + 18: [2, 7], + 22: [2, 7], + 24: [2, 7] + }, { + 14: [2, 8], + 18: [2, 8], + 22: [2, 8], + 24: [2, 8] + }, { + 14: [2, 9], + 18: [2, 9], + 22: [2, 9], + 24: [2, 9] + }, { + 14: [2, 10], + 18: [2, 10], + 22: [2, 10], + 24: [2, 10] + }, { + 14: [2, 11], + 18: [2, 11], + 22: [2, 11], + 24: [2, 11] + }, { + 14: [2, 12], + 18: [2, 12], + 22: [2, 12], + 24: [2, 12] + }, { + 14: [2, 3], + 18: [2, 3], + 22: [2, 3], + 24: [2, 3] + }, { + 14: [2, 4], + 18: [2, 4], + 22: [2, 4], + 24: [2, 4] + }, { + 14: [2, 5], + 18: [2, 5], + 22: [2, 5], + 24: [2, 5] + }, { + 14: [2, 1], + 18: [2, 1], + 21: [2, 1], + 22: [2, 1], + 24: [2, 1] + }, { + 14: [2, 2], + 18: [2, 2], + 22: [2, 2], + 24: [2, 2] + }, { + 3: 20, + 4: [1, 12], + 18: [1, 17], + 19: 18, + 20: 19 + }, { + 3: 5, + 4: [1, 12], + 5: 6, + 6: [1, 13], + 7: 3, + 8: [1, 9], + 9: 4, + 10: [1, 10], + 11: [1, 11], + 13: 23, + 15: 7, + 16: 8, + 17: [1, 14], + 23: [1, 15], + 24: [1, 21], + 25: 22 + }, { + 1: [2, 6] + }, { + 14: [2, 13], + 18: [2, 13], + 22: [2, 13], + 24: [2, 13] + }, { + 18: [1, 24], + 22: [1, 25] + }, { + 18: [2, 16], + 22: [2, 16] + }, { + 21: [1, 26] + }, { + 14: [2, 18], + 18: [2, 18], + 22: [2, 18], + 24: [2, 18] + }, { + 22: [1, 28], + 24: [1, 27] + }, { + 22: [2, 20], + 24: [2, 20] + }, { + 14: [2, 14], + 18: [2, 14], + 22: [2, 14], + 24: [2, 14] + }, { + 3: 20, + 4: [1, 12], + 20: 29 + }, { + 3: 5, + 4: [1, 12], + 5: 6, + 6: [1, 13], + 7: 3, + 8: [1, 9], + 9: 4, + 10: [1, 10], + 11: [1, 11], + 13: 30, + 15: 7, + 16: 8, + 17: [1, 14], + 23: [1, 15] + }, { + 14: [2, 19], + 18: [2, 19], + 22: [2, 19], + 24: [2, 19] + }, { + 3: 5, + 4: [1, 12], + 5: 6, + 6: [1, 13], + 7: 3, + 8: [1, 9], + 9: 4, + 10: [1, 10], + 11: [1, 11], + 13: 31, + 15: 7, + 16: 8, + 17: [1, 14], + 23: [1, 15] + }, { + 18: [2, 17], + 22: [2, 17] + }, { + 18: [2, 15], + 22: [2, 15] + }, { + 22: [2, 21], + 24: [2, 21] + }], + defaultActions: { + 16: [2, 6] + }, + parseError: function parseError(str, hash) { + throw new Error(str); + }, + parse: function parse(input) { + var self = this, + stack = [0], + vstack = [null], + // semantic value stack + lstack = [], + // location stack + table = this.table, + yytext = '', + yylineno = 0, + yyleng = 0, + recovering = 0, + TERROR = 2, + EOF = 1; //this.reductionCount = this.shiftCount = 0; + + this.lexer.setInput(input); + this.lexer.yy = this.yy; + this.yy.lexer = this.lexer; + if (typeof this.lexer.yylloc == 'undefined') this.lexer.yylloc = {}; + var yyloc = this.lexer.yylloc; + lstack.push(yyloc); + if (typeof this.yy.parseError === 'function') this.parseError = this.yy.parseError; + + function popStack(n) { + stack.length = stack.length - 2 * n; + vstack.length = vstack.length - n; + lstack.length = lstack.length - n; + } + + function lex() { + var token; + token = self.lexer.lex() || 1; // $end = 1 + // if token isn't its numeric value, convert + + if (typeof token !== 'number') { + token = self.symbols_[token] || token; + } + + return token; + } + + var symbol, + preErrorSymbol, + state, + action, + a, + r, + yyval = {}, + p, + len, + newState, + expected; + + while (true) { + // retreive state number from top of stack + state = stack[stack.length - 1]; // use default actions if available + + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol == null) symbol = lex(); // read action for current state and first input + + action = table[state] && table[state][symbol]; + } // handle parse error + + + _handle_error: if (typeof action === 'undefined' || !action.length || !action[0]) { + if (!recovering) { + // Report error + expected = []; + + for (p in table[state]) { + if (this.terminals_[p] && p > 2) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + + var errStr = ''; + + if (this.lexer.showPosition) { + errStr = 'Parse error on line ' + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(', ') + ", got '" + this.terminals_[symbol] + "'"; + } else { + errStr = 'Parse error on line ' + (yylineno + 1) + ": Unexpected " + (symbol == 1 + /*EOF*/ + ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + + this.parseError(errStr, { + text: this.lexer.match, + token: this.terminals_[symbol] || symbol, + line: this.lexer.yylineno, + loc: yyloc, + expected: expected + }); + } // just recovered from another error + + + if (recovering == 3) { + if (symbol == EOF) { + throw new Error(errStr || 'Parsing halted.'); + } // discard current lookahead and grab another + + + yyleng = this.lexer.yyleng; + yytext = this.lexer.yytext; + yylineno = this.lexer.yylineno; + yyloc = this.lexer.yylloc; + symbol = lex(); + } // try to recover from error + + + while (1) { + // check for error recovery rule in this state + if (TERROR.toString() in table[state]) { + break; + } + + if (state == 0) { + throw new Error(errStr || 'Parsing halted.'); + } + + popStack(1); + state = stack[stack.length - 1]; + } + + preErrorSymbol = symbol; // save the lookahead token + + symbol = TERROR; // insert generic error symbol as new lookahead + + state = stack[stack.length - 1]; + action = table[state] && table[state][TERROR]; + recovering = 3; // allow 3 real symbols to be shifted before reporting a new error + } // this shouldn't happen, unless resolve defaults are off + + + if (action[0] instanceof Array && action.length > 1) { + throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol); + } + + switch (action[0]) { + case 1: + // shift + //this.shiftCount++; + stack.push(symbol); + vstack.push(this.lexer.yytext); + lstack.push(this.lexer.yylloc); + stack.push(action[1]); // push state + + symbol = null; + + if (!preErrorSymbol) { + // normal execution/no error + yyleng = this.lexer.yyleng; + yytext = this.lexer.yytext; + yylineno = this.lexer.yylineno; + yyloc = this.lexer.yylloc; + if (recovering > 0) recovering--; + } else { + // error just occurred, resume old lookahead f/ before error + symbol = preErrorSymbol; + preErrorSymbol = null; + } + + break; + + case 2: + // reduce + //this.reductionCount++; + len = this.productions_[action[1]][1]; // perform semantic action + + yyval.$ = vstack[vstack.length - len]; // default to $$ = $1 + // default location, uses first token for firsts, last for lasts + + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack); + + if (typeof r !== 'undefined') { + return r; + } // pop off stack + + + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + + stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce) + + vstack.push(yyval.$); + lstack.push(yyval._$); // goto new state = table[STATE][NONTERMINAL] + + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + + case 3: + // accept + return true; + } + } + + return true; + } + }; + /* Jison generated lexer */ + + var lexer = function () { + var lexer = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parseError) { + this.yy.parseError(str, hash); + } else { + throw new Error(str); + } + }, + setInput: function setInput(input) { + this._input = input; + this._more = this._less = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ''; + this.conditionStack = ['INITIAL']; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + return this; + }, + input: function input() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/\n/); + if (lines) this.yylineno++; + this._input = this._input.slice(1); + return ch; + }, + unput: function unput(ch) { + this._input = ch + this._input; + return this; + }, + more: function more() { + this._more = true; + return this; + }, + less: function less(n) { + this._input = this.match.slice(n) + this._input; + }, + pastInput: function pastInput() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, ""); + }, + upcomingInput: function upcomingInput() { + var next = this.match; + + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + + return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); + }, + showPosition: function showPosition() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + next: function next() { + if (this.done) { + return this.EOF; + } + + if (!this._input) this.done = true; + var token, match, tempMatch, index, col, lines; + + if (!this._more) { + this.yytext = ''; + this.match = ''; + } + + var rules = this._currentRules(); + + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (!this.options.flex) break; + } + } + + if (match) { + lines = match[0].match(/\n.*/g); + if (lines) this.yylineno += lines.length; + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - 1 : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.yyleng = this.yytext.length; + this._more = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, rules[index], this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) this.done = false; + if (token) return token;else return; + } + + if (this._input === "") { + return this.EOF; + } else { + this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + lex: function lex() { + var r = this.next(); + + if (typeof r !== 'undefined') { + return r; + } else { + return this.lex(); + } + }, + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + popState: function popState() { + return this.conditionStack.pop(); + }, + _currentRules: function _currentRules() { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + }, + topState: function topState() { + return this.conditionStack[this.conditionStack.length - 2]; + }, + pushState: function begin(condition) { + this.begin(condition); + } + }; + lexer.options = {}; + + lexer.performAction = function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + var YYSTATE = YY_START; + + switch ($avoiding_name_collisions) { + case 0: + /* skip whitespace */ + break; + + case 1: + return 6; + break; + + case 2: + yy_.yytext = yy_.yytext.substr(1, yy_.yyleng - 2); + return 4; + break; + + case 3: + return 17; + break; + + case 4: + return 18; + break; + + case 5: + return 23; + break; + + case 6: + return 24; + break; + + case 7: + return 22; + break; + + case 8: + return 21; + break; + + case 9: + return 10; + break; + + case 10: + return 11; + break; + + case 11: + return 8; + break; + + case 12: + return 14; + break; + + case 13: + return 'INVALID'; + break; + } + }; + + lexer.rules = [/^(?:\s+)/, /^(?:(-?([0-9]|[1-9][0-9]+))(\.[0-9]+)?([eE][-+]?[0-9]+)?\b)/, /^(?:"(?:\\[\\"bfnrt/]|\\u[a-fA-F0-9]{4}|[^\\\0-\x09\x0a-\x1f"])*")/, /^(?:\{)/, /^(?:\})/, /^(?:\[)/, /^(?:\])/, /^(?:,)/, /^(?::)/, /^(?:true\b)/, /^(?:false\b)/, /^(?:null\b)/, /^(?:$)/, /^(?:.)/]; + lexer.conditions = { + "INITIAL": { + "rules": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], + "inclusive": true + } + }; + ; + return lexer; + }(); + + parser.lexer = lexer; + return parser; +}(); + +if (true) { + exports.parser = jsonlint; + exports.parse = jsonlint.parse.bind(jsonlint); +} + +/***/ }), + +/***/ 3879: +/***/ (function(module) { + +"use strict"; +/*! + * Selectr 2.4.0 + * https://github.com/Mobius1/Selectr + * + * Released under the MIT license + */ + +/** + * Default configuration options + * @type {Object} + */ + +var defaultConfig = { + /** + * Emulates browser behaviour by selecting the first option by default + * @type {Boolean} + */ + defaultSelected: true, + + /** + * Sets the width of the container + * @type {String} + */ + width: "auto", + + /** + * Enables/ disables the container + * @type {Boolean} + */ + disabled: false, + + /** + * Enables / disables the search function + * @type {Boolean} + */ + searchable: true, + + /** + * Enable disable the clear button + * @type {Boolean} + */ + clearable: false, + + /** + * Sort the tags / multiselect options + * @type {Boolean} + */ + sortSelected: false, + + /** + * Allow deselecting of select-one options + * @type {Boolean} + */ + allowDeselect: false, + + /** + * Close the dropdown when scrolling (@AlexanderReiswich, #11) + * @type {Boolean} + */ + closeOnScroll: false, + + /** + * Allow the use of the native dropdown (@jonnyscholes, #14) + * @type {Boolean} + */ + nativeDropdown: false, + + /** + * Set the main placeholder + * @type {String} + */ + placeholder: "Select an option...", + + /** + * Allow the tagging feature + * @type {Boolean} + */ + taggable: false, + + /** + * Set the tag input placeholder (@labikmartin, #21, #22) + * @type {String} + */ + tagPlaceholder: "Enter a tag..." +}; +/** + * Event Emitter + */ + +var Events = function Events() {}; +/** + * Event Prototype + * @type {Object} + */ + + +Events.prototype = { + /** + * Add custom event listener + * @param {String} event Event type + * @param {Function} func Callback + * @return {Void} + */ + on: function on(event, func) { + this._events = this._events || {}; + this._events[event] = this._events[event] || []; + + this._events[event].push(func); + }, + + /** + * Remove custom event listener + * @param {String} event Event type + * @param {Function} func Callback + * @return {Void} + */ + off: function off(event, func) { + this._events = this._events || {}; + if (event in this._events === false) return; + + this._events[event].splice(this._events[event].indexOf(func), 1); + }, + + /** + * Fire a custom event + * @param {String} event Event type + * @return {Void} + */ + emit: function emit(event + /* , args... */ + ) { + this._events = this._events || {}; + if (event in this._events === false) return; + + for (var i = 0; i < this._events[event].length; i++) { + this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1)); + } + } +}; +/** + * Event mixin + * @param {Object} obj + * @return {Object} + */ + +Events.mixin = function (obj) { + var props = ['on', 'off', 'emit']; + + for (var i = 0; i < props.length; i++) { + if (typeof obj === 'function') { + obj.prototype[props[i]] = Events.prototype[props[i]]; + } else { + obj[props[i]] = Events.prototype[props[i]]; + } + } + + return obj; +}; +/** + * Helpers + * @type {Object} + */ + + +var util = { + extend: function extend(src, props) { + props = props || {}; + var p; + + for (p in src) { + if (src.hasOwnProperty(p)) { + if (!props.hasOwnProperty(p)) { + props[p] = src[p]; + } + } + } + + return props; + }, + each: function each(a, b, c) { + if ("[object Object]" === Object.prototype.toString.call(a)) { + for (var d in a) { + if (Object.prototype.hasOwnProperty.call(a, d)) { + b.call(c, d, a[d], a); + } + } + } else { + for (var e = 0, f = a.length; e < f; e++) { + b.call(c, e, a[e], a); + } + } + }, + createElement: function createElement(e, a) { + var d = document, + el = d.createElement(e); + + if (a && "[object Object]" === Object.prototype.toString.call(a)) { + var i; + + for (i in a) { + if (i in el) el[i] = a[i];else if ("html" === i) el.textContent = a[i];else if ("text" === i) { + var t = d.createTextNode(a[i]); + el.appendChild(t); + } else el.setAttribute(i, a[i]); + } + } + + return el; + }, + hasClass: function hasClass(a, b) { + if (a) return a.classList ? a.classList.contains(b) : !!a.className && !!a.className.match(new RegExp("(\\s|^)" + b + "(\\s|$)")); + }, + addClass: function addClass(a, b) { + if (!util.hasClass(a, b)) { + if (a.classList) { + a.classList.add(b); + } else { + a.className = a.className.trim() + " " + b; + } + } + }, + removeClass: function removeClass(a, b) { + if (util.hasClass(a, b)) { + if (a.classList) { + a.classList.remove(b); + } else { + a.className = a.className.replace(new RegExp("(^|\\s)" + b.split(" ").join("|") + "(\\s|$)", "gi"), " "); + } + } + }, + closest: function closest(el, fn) { + return el && el !== document.body && (fn(el) ? el : util.closest(el.parentNode, fn)); + }, + isInt: function isInt(val) { + return typeof val === 'number' && isFinite(val) && Math.floor(val) === val; + }, + debounce: function debounce(a, b, c) { + var d; + return function () { + var e = this, + f = arguments, + g = function g() { + d = null; + if (!c) a.apply(e, f); + }, + h = c && !d; + + clearTimeout(d); + d = setTimeout(g, b); + + if (h) { + a.apply(e, f); + } + }; + }, + rect: function rect(el, abs) { + var w = window; + var r = el.getBoundingClientRect(); + var x = abs ? w.pageXOffset : 0; + var y = abs ? w.pageYOffset : 0; + return { + bottom: r.bottom + y, + height: r.height, + left: r.left + x, + right: r.right + x, + top: r.top + y, + width: r.width + }; + }, + includes: function includes(a, b) { + return a.indexOf(b) > -1; + }, + truncate: function truncate(el) { + while (el.firstChild) { + el.removeChild(el.firstChild); + } + } +}; + +function isset(obj, prop) { + return obj.hasOwnProperty(prop) && (obj[prop] === true || obj[prop].length); +} +/** + * Append an item to the list + * @param {Object} item + * @param {Object} custom + * @return {Void} + */ + + +function appendItem(item, parent, custom) { + if (item.parentNode) { + if (!item.parentNode.parentNode) { + parent.appendChild(item.parentNode); + } + } else { + parent.appendChild(item); + } + + util.removeClass(item, "excluded"); + + if (!custom) { + item.textContent = item.textContent + ''; // clear highlighting + } +} +/** + * Render the item list + * @return {Void} + */ + + +var render = function render() { + if (this.items.length) { + var f = document.createDocumentFragment(); + + if (this.config.pagination) { + var pages = this.pages.slice(0, this.pageIndex); + util.each(pages, function (i, items) { + util.each(items, function (j, item) { + appendItem(item, f, this.customOption); + }, this); + }, this); + } else { + util.each(this.items, function (i, item) { + appendItem(item, f, this.customOption); + }, this); + } + + if (f.childElementCount) { + util.removeClass(this.items[this.navIndex], "active"); + this.navIndex = f.querySelector(".selectr-option").idx; + util.addClass(this.items[this.navIndex], "active"); + } + + this.tree.appendChild(f); + } +}; +/** + * Dismiss / close the dropdown + * @param {obj} e + * @return {void} + */ + + +var dismiss = function dismiss(e) { + var target = e.target; + + if (!this.container.contains(target) && (this.opened || util.hasClass(this.container, "notice"))) { + this.close(); + } +}; +/** + * Build a list item from the HTMLOptionElement + * @param {int} i HTMLOptionElement index + * @param {HTMLOptionElement} option + * @param {bool} group Has parent optgroup + * @return {void} + */ + + +var createItem = function createItem(option, data) { + data = data || option; + var content = this.customOption ? this.config.renderOption(data) : option.textContent; + var opt = util.createElement("li", { + "class": "selectr-option", + html: content, + role: "treeitem", + "aria-selected": false + }); + opt.idx = option.idx; + this.items.push(opt); + + if (option.defaultSelected) { + this.defaultSelected.push(option.idx); + } + + if (option.disabled) { + opt.disabled = true; + util.addClass(opt, "disabled"); + } + + return opt; +}; +/** + * Build the container + * @return {Void} + */ + + +var build = function build() { + this.requiresPagination = this.config.pagination && this.config.pagination > 0; // Set width + + if (isset(this.config, "width")) { + if (util.isInt(this.config.width)) { + this.width = this.config.width + "px"; + } else { + if (this.config.width === "auto") { + this.width = "100%"; + } else if (util.includes(this.config.width, "%")) { + this.width = this.config.width; + } + } + } + + this.container = util.createElement("div", { + "class": "selectr-container" + }); // Custom className + + if (this.config.customClass) { + util.addClass(this.container, this.config.customClass); + } // Mobile device + + + if (this.mobileDevice) { + util.addClass(this.container, "selectr-mobile"); + } else { + util.addClass(this.container, "selectr-desktop"); + } // Hide the HTMLSelectElement and prevent focus + + + this.el.tabIndex = -1; // Native dropdown + + if (this.config.nativeDropdown || this.mobileDevice) { + util.addClass(this.el, "selectr-visible"); + } else { + util.addClass(this.el, "selectr-hidden"); + } + + this.selected = util.createElement("div", { + "class": "selectr-selected", + disabled: this.disabled, + tabIndex: 1, + // enable tabIndex (#9) + "aria-expanded": false + }); + this.label = util.createElement(this.el.multiple ? "ul" : "span", { + "class": "selectr-label" + }); + var dropdown = util.createElement("div", { + "class": "selectr-options-container" + }); + this.tree = util.createElement("ul", { + "class": "selectr-options", + role: "tree", + "aria-hidden": true, + "aria-expanded": false + }); + this.notice = util.createElement("div", { + "class": "selectr-notice" + }); + this.el.setAttribute("aria-hidden", true); + + if (this.disabled) { + this.el.disabled = true; + } + + if (this.el.multiple) { + util.addClass(this.label, "selectr-tags"); + util.addClass(this.container, "multiple"); // Collection of tags + + this.tags = []; // Collection of selected values + + this.selectedValues = this.getSelectedProperties('value'); // Collection of selected indexes + + this.selectedIndexes = this.getSelectedProperties('idx'); + } + + this.selected.appendChild(this.label); + + if (this.config.clearable) { + this.selectClear = util.createElement("button", { + "class": "selectr-clear", + type: "button" + }); + this.container.appendChild(this.selectClear); + util.addClass(this.container, "clearable"); + } + + if (this.config.taggable) { + var li = util.createElement('li', { + "class": 'input-tag' + }); + this.input = util.createElement("input", { + "class": "selectr-tag-input", + placeholder: this.config.tagPlaceholder, + tagIndex: 0, + autocomplete: "off", + autocorrect: "off", + autocapitalize: "off", + spellcheck: "false", + role: "textbox", + type: "search" + }); + li.appendChild(this.input); + this.label.appendChild(li); + util.addClass(this.container, "taggable"); + this.tagSeperators = [","]; + + if (this.config.tagSeperators) { + this.tagSeperators = this.tagSeperators.concat(this.config.tagSeperators); + } + } + + if (this.config.searchable) { + this.input = util.createElement("input", { + "class": "selectr-input", + tagIndex: -1, + autocomplete: "off", + autocorrect: "off", + autocapitalize: "off", + spellcheck: "false", + role: "textbox", + type: "search" + }); + this.inputClear = util.createElement("button", { + "class": "selectr-input-clear", + type: "button" + }); + this.inputContainer = util.createElement("div", { + "class": "selectr-input-container" + }); + this.inputContainer.appendChild(this.input); + this.inputContainer.appendChild(this.inputClear); + dropdown.appendChild(this.inputContainer); + } + + dropdown.appendChild(this.notice); + dropdown.appendChild(this.tree); // List of items for the dropdown + + this.items = []; // Establish options + + this.options = []; // Check for options in the element + + if (this.el.options.length) { + this.options = [].slice.call(this.el.options); + } // Element may have optgroups so + // iterate element.children instead of element.options + + + var group = false, + j = 0; + + if (this.el.children.length) { + util.each(this.el.children, function (i, element) { + if (element.nodeName === "OPTGROUP") { + group = util.createElement("ul", { + "class": "selectr-optgroup", + role: "group", + html: "
  • " + element.label + "
  • " + }); + util.each(element.children, function (x, el) { + el.idx = j; + group.appendChild(createItem.call(this, el, group)); + j++; + }, this); + } else { + element.idx = j; + createItem.call(this, element); + j++; + } + }, this); + } // Options defined by the data option + + + if (this.config.data && Array.isArray(this.config.data)) { + this.data = []; + var optgroup = false, + option; + group = false; + j = 0; + util.each(this.config.data, function (i, opt) { + // Check for group options + if (isset(opt, "children")) { + optgroup = util.createElement("optgroup", { + label: opt.text + }); + group = util.createElement("ul", { + "class": "selectr-optgroup", + role: "group", + html: "
  • " + opt.text + "
  • " + }); + util.each(opt.children, function (x, data) { + option = new Option(data.text, data.value, false, data.hasOwnProperty("selected") && data.selected === true); + option.disabled = isset(data, "disabled"); + this.options.push(option); + optgroup.appendChild(option); + option.idx = j; + group.appendChild(createItem.call(this, option, data)); + this.data[j] = data; + j++; + }, this); + } else { + option = new Option(opt.text, opt.value, false, opt.hasOwnProperty("selected") && opt.selected === true); + option.disabled = isset(opt, "disabled"); + this.options.push(option); + option.idx = j; + createItem.call(this, option, opt); + this.data[j] = opt; + j++; + } + }, this); + } + + this.setSelected(true); + var first; + this.navIndex = 0; + + for (var i = 0; i < this.items.length; i++) { + first = this.items[i]; + + if (!util.hasClass(first, "disabled")) { + util.addClass(first, "active"); + this.navIndex = i; + break; + } + } // Check for pagination / infinite scroll + + + if (this.requiresPagination) { + this.pageIndex = 1; // Create the pages + + this.paginate(); + } + + this.container.appendChild(this.selected); + this.container.appendChild(dropdown); + this.placeEl = util.createElement("div", { + "class": "selectr-placeholder" + }); // Set the placeholder + + this.setPlaceholder(); + this.selected.appendChild(this.placeEl); // Disable if required + + if (this.disabled) { + this.disable(); + } + + this.el.parentNode.insertBefore(this.container, this.el); + this.container.appendChild(this.el); +}; +/** + * Navigate through the dropdown + * @param {obj} e + * @return {void} + */ + + +var navigate = function navigate(e) { + e = e || window.event; // Filter out the keys we don"t want + + if (!this.items.length || !this.opened || !util.includes([13, 38, 40], e.which)) { + this.navigating = false; + return; + } + + e.preventDefault(); + + if (e.which === 13) { + if (this.config.taggable && this.input.value.length > 0) { + return false; + } + + return this.change(this.navIndex); + } + + var direction, + prevEl = this.items[this.navIndex]; + + switch (e.which) { + case 38: + direction = 0; + + if (this.navIndex > 0) { + this.navIndex--; + } + + break; + + case 40: + direction = 1; + + if (this.navIndex < this.items.length - 1) { + this.navIndex++; + } + + } + + this.navigating = true; // Instead of wasting memory holding a copy of this.items + // with disabled / excluded options omitted, skip them instead + + while (util.hasClass(this.items[this.navIndex], "disabled") || util.hasClass(this.items[this.navIndex], "excluded")) { + if (direction) { + this.navIndex++; + } else { + this.navIndex--; + } + + if (this.searching) { + if (this.navIndex > this.tree.lastElementChild.idx) { + this.navIndex = this.tree.lastElementChild.idx; + break; + } else if (this.navIndex < this.tree.firstElementChild.idx) { + this.navIndex = this.tree.firstElementChild.idx; + break; + } + } + } // Autoscroll the dropdown during navigation + + + var r = util.rect(this.items[this.navIndex]); + + if (!direction) { + if (this.navIndex === 0) { + this.tree.scrollTop = 0; + } else if (r.top - this.optsRect.top < 0) { + this.tree.scrollTop = this.tree.scrollTop + (r.top - this.optsRect.top); + } + } else { + if (this.navIndex === 0) { + this.tree.scrollTop = 0; + } else if (r.top + r.height > this.optsRect.top + this.optsRect.height) { + this.tree.scrollTop = this.tree.scrollTop + (r.top + r.height - (this.optsRect.top + this.optsRect.height)); + } // Load another page if needed + + + if (this.navIndex === this.tree.childElementCount - 1 && this.requiresPagination) { + load.call(this); + } + } + + if (prevEl) { + util.removeClass(prevEl, "active"); + } + + util.addClass(this.items[this.navIndex], "active"); +}; +/** + * Add a tag + * @param {HTMLElement} item + */ + + +var addTag = function addTag(item) { + var that = this, + r; + var docFrag = document.createDocumentFragment(); + var option = this.options[item.idx]; + var data = this.data ? this.data[item.idx] : option; + var content = this.customSelected ? this.config.renderSelection(data) : option.textContent; + var tag = util.createElement("li", { + "class": "selectr-tag", + html: content + }); + var btn = util.createElement("button", { + "class": "selectr-tag-remove", + type: "button" + }); + tag.appendChild(btn); // Set property to check against later + + tag.idx = item.idx; + tag.tag = option.value; + this.tags.push(tag); + + if (this.config.sortSelected) { + var tags = this.tags.slice(); // Deal with values that contain numbers + + r = function r(val, arr) { + val.replace(/(\d+)|(\D+)/g, function (that, $1, $2) { + arr.push([$1 || Infinity, $2 || ""]); + }); + }; + + tags.sort(function (a, b) { + var x = [], + y = [], + ac, + bc; + + if (that.config.sortSelected === true) { + ac = a.tag; + bc = b.tag; + } else if (that.config.sortSelected === 'text') { + ac = a.textContent; + bc = b.textContent; + } + + r(ac, x); + r(bc, y); + + while (x.length && y.length) { + var ax = x.shift(); + var by = y.shift(); + var nn = ax[0] - by[0] || ax[1].localeCompare(by[1]); + if (nn) return nn; + } + + return x.length - y.length; + }); + util.each(tags, function (i, tg) { + docFrag.appendChild(tg); + }); + this.label.textContent = ""; + } else { + docFrag.appendChild(tag); + } + + if (this.config.taggable) { + this.label.insertBefore(docFrag, this.input.parentNode); + } else { + this.label.appendChild(docFrag); + } +}; +/** + * Remove a tag + * @param {HTMLElement} item + * @return {void} + */ + + +var removeTag = function removeTag(item) { + var tag = false; + util.each(this.tags, function (i, t) { + if (t.idx === item.idx) { + tag = t; + } + }, this); + + if (tag) { + this.label.removeChild(tag); + this.tags.splice(this.tags.indexOf(tag), 1); + } +}; +/** + * Load the next page of items + * @return {void} + */ + + +var load = function load() { + var tree = this.tree; + var scrollTop = tree.scrollTop; + var scrollHeight = tree.scrollHeight; + var offsetHeight = tree.offsetHeight; + var atBottom = scrollTop >= scrollHeight - offsetHeight; + + if (atBottom && this.pageIndex < this.pages.length) { + var f = document.createDocumentFragment(); + util.each(this.pages[this.pageIndex], function (i, item) { + appendItem(item, f, this.customOption); + }, this); + tree.appendChild(f); + this.pageIndex++; + this.emit("selectr.paginate", { + items: this.items.length, + total: this.data.length, + page: this.pageIndex, + pages: this.pages.length + }); + } +}; +/** + * Clear a search + * @return {void} + */ + + +var clearSearch = function clearSearch() { + if (this.config.searchable || this.config.taggable) { + this.input.value = null; + this.searching = false; + + if (this.config.searchable) { + util.removeClass(this.inputContainer, "active"); + } + + if (util.hasClass(this.container, "notice")) { + util.removeClass(this.container, "notice"); + util.addClass(this.container, "open"); + this.input.focus(); + } + + util.each(this.items, function (i, item) { + // Items that didn't match need the class + // removing to make them visible again + util.removeClass(item, "excluded"); // Remove the span element for underlining matched items + + if (!this.customOption) { + item.textContent = item.textContent + ''; // clear highlighting + } + }, this); + } +}; +/** + * Query matching for searches + * @param {string} query + * @param {string} text + */ + + +var match = function match(query, text) { + var result = new RegExp(query, "i").exec(text); + + if (result) { + var start = result.index; + var end = result.index + result[0].length; + return { + before: text.substring(0, start), + match: text.substring(start, end), + after: text.substring(end) + }; + } + + return null; +}; // Main Lib + + +var Selectr = function Selectr(el, config) { + config = config || {}; + + if (!el) { + throw new Error("You must supply either a HTMLSelectElement or a CSS3 selector string."); + } + + this.el = el; // CSS3 selector string + + if (typeof el === "string") { + this.el = document.querySelector(el); + } + + if (this.el === null) { + throw new Error("The element you passed to Selectr can not be found."); + } + + if (this.el.nodeName.toLowerCase() !== "select") { + throw new Error("The element you passed to Selectr is not a HTMLSelectElement."); + } + + this.render(config); +}; +/** + * Render the instance + * @param {object} config + * @return {void} + */ + + +Selectr.prototype.render = function (config) { + if (this.rendered) return; // Merge defaults with user set config + + this.config = util.extend(defaultConfig, config); // Store type + + this.originalType = this.el.type; // Store tabIndex + + this.originalIndex = this.el.tabIndex; // Store defaultSelected options for form reset + + this.defaultSelected = []; // Store the original option count + + this.originalOptionCount = this.el.options.length; + + if (this.config.multiple || this.config.taggable) { + this.el.multiple = true; + } // Disabled? + + + this.disabled = isset(this.config, "disabled"); + this.opened = false; + + if (this.config.taggable) { + this.config.searchable = false; + } + + this.navigating = false; + this.mobileDevice = false; + + if (/Android|webOS|iPhone|iPad|BlackBerry|Windows Phone|Opera Mini|IEMobile|Mobile/i.test(navigator.userAgent)) { + this.mobileDevice = true; + } + + this.customOption = this.config.hasOwnProperty("renderOption") && typeof this.config.renderOption === "function"; + this.customSelected = this.config.hasOwnProperty("renderSelection") && typeof this.config.renderSelection === "function"; // Enable event emitter + + Events.mixin(this); + build.call(this); + this.bindEvents(); + this.update(); + this.optsRect = util.rect(this.tree); + this.rendered = true; // Fixes macOS Safari bug #28 + + if (!this.el.multiple) { + this.el.selectedIndex = this.selectedIndex; + } + + var that = this; + setTimeout(function () { + that.emit("selectr.init"); + }, 20); +}; + +Selectr.prototype.getSelected = function () { + var selected = this.el.querySelectorAll('option:checked'); + return selected; +}; + +Selectr.prototype.getSelectedProperties = function (prop) { + var selected = this.getSelected(); + var values = [].slice.call(selected).map(function (option) { + return option[prop]; + }).filter(function (i) { + return i !== null && i !== undefined; + }); + return values; +}; +/** + * Attach the required event listeners + */ + + +Selectr.prototype.bindEvents = function () { + var that = this; + this.events = {}; + this.events.dismiss = dismiss.bind(this); + this.events.navigate = navigate.bind(this); + this.events.reset = this.reset.bind(this); + + if (this.config.nativeDropdown || this.mobileDevice) { + this.container.addEventListener("touchstart", function (e) { + if (e.changedTouches[0].target === that.el) { + that.toggle(); + } + }); + + if (this.config.nativeDropdown || this.mobileDevice) { + this.container.addEventListener("click", function (e) { + e.preventDefault(); // Jos: Added to prevent emitting clear directly after select + + e.stopPropagation(); // Jos: Added to prevent emitting clear directly after select + + if (e.target === that.el) { + that.toggle(); + } + }); + } + + var getChangedOptions = function getChangedOptions(last, current) { + var added = [], + removed = last.slice(0); + var idx; + + for (var i = 0; i < current.length; i++) { + idx = removed.indexOf(current[i]); + if (idx > -1) removed.splice(idx, 1);else added.push(current[i]); + } + + return [added, removed]; + }; // Listen for the change on the native select + // and update accordingly + + + this.el.addEventListener("change", function (e) { + if (that.el.multiple) { + var indexes = that.getSelectedProperties('idx'); + var changes = getChangedOptions(that.selectedIndexes, indexes); + util.each(changes[0], function (i, idx) { + that.select(idx); + }, that); + util.each(changes[1], function (i, idx) { + that.deselect(idx); + }, that); + } else { + if (that.el.selectedIndex > -1) { + that.select(that.el.selectedIndex); + } + } + }); + } // Open the dropdown with Enter key if focused + + + if (this.config.nativeDropdown) { + this.container.addEventListener("keydown", function (e) { + if (e.key === "Enter" && that.selected === document.activeElement) { + // Show the native + that.toggle(); // Focus on the native multiselect + + setTimeout(function () { + that.el.focus(); + }, 200); + } + }); + } // Non-native dropdown + + + this.selected.addEventListener("click", function (e) { + if (!that.disabled) { + that.toggle(); + } + + e.preventDefault(); + e.stopPropagation(); // Jos: Added to prevent emitting clear directly after select + }); // Remove tag + + this.label.addEventListener("click", function (e) { + if (util.hasClass(e.target, "selectr-tag-remove")) { + that.deselect(e.target.parentNode.idx); + } + }); // Clear input + + if (this.selectClear) { + this.selectClear.addEventListener("click", this.clear.bind(this)); + } // Prevent text selection + + + this.tree.addEventListener("mousedown", function (e) { + e.preventDefault(); + }); // Select / deselect items + + this.tree.addEventListener("click", function (e) { + e.preventDefault(); // Jos: Added to prevent emitting clear directly after select + + e.stopPropagation(); // Jos: Added to prevent emitting clear directly after select + + var item = util.closest(e.target, function (el) { + return el && util.hasClass(el, "selectr-option"); + }); + + if (item) { + if (!util.hasClass(item, "disabled")) { + if (util.hasClass(item, "selected")) { + if (that.el.multiple || !that.el.multiple && that.config.allowDeselect) { + that.deselect(item.idx); + } + } else { + that.select(item.idx); + } + + if (that.opened && !that.el.multiple) { + that.close(); + } + } + } + }); // Mouseover list items + + this.tree.addEventListener("mouseover", function (e) { + if (util.hasClass(e.target, "selectr-option")) { + if (!util.hasClass(e.target, "disabled")) { + util.removeClass(that.items[that.navIndex], "active"); + util.addClass(e.target, "active"); + that.navIndex = [].slice.call(that.items).indexOf(e.target); + } + } + }); // Searchable + + if (this.config.searchable) { + // Show / hide the search input clear button + this.input.addEventListener("focus", function (e) { + that.searching = true; + }); + this.input.addEventListener("blur", function (e) { + that.searching = false; + }); + this.input.addEventListener("keyup", function (e) { + that.search(); + + if (!that.config.taggable) { + // Show / hide the search input clear button + if (this.value.length) { + util.addClass(this.parentNode, "active"); + } else { + util.removeClass(this.parentNode, "active"); + } + } + }); // Clear the search input + + this.inputClear.addEventListener("click", function (e) { + that.input.value = null; + clearSearch.call(that); + + if (!that.tree.childElementCount) { + render.call(that); + } + }); + } + + if (this.config.taggable) { + this.input.addEventListener("keyup", function (e) { + that.search(); + + if (that.config.taggable && this.value.length) { + var val = this.value.trim(); + + if (e.which === 13 || util.includes(that.tagSeperators, e.key)) { + util.each(that.tagSeperators, function (i, k) { + val = val.replace(k, ''); + }); + var option = that.add({ + value: val, + text: val, + selected: true + }, true); + + if (!option) { + this.value = ''; + that.setMessage('That tag is already in use.'); + } else { + that.close(); + clearSearch.call(that); + } + } + } + }); + } + + this.update = util.debounce(function () { + // Optionally close dropdown on scroll / resize (#11) + if (that.opened && that.config.closeOnScroll) { + that.close(); + } + + if (that.width) { + that.container.style.width = that.width; + } + + that.invert(); + }, 50); + + if (this.requiresPagination) { + this.paginateItems = util.debounce(function () { + load.call(this); + }, 50); + this.tree.addEventListener("scroll", this.paginateItems.bind(this)); + } // Dismiss when clicking outside the container + + + document.addEventListener("click", this.events.dismiss); + window.addEventListener("keydown", this.events.navigate); + window.addEventListener("resize", this.update); + window.addEventListener("scroll", this.update); // Listen for form.reset() (@ambrooks, #13) + + if (this.el.form) { + this.el.form.addEventListener("reset", this.events.reset); + } +}; +/** + * Check for selected options + * @param {bool} reset + */ + + +Selectr.prototype.setSelected = function (reset) { + // Select first option as with a native select-one element - #21, #24 + if (!this.config.data && !this.el.multiple && this.el.options.length) { + // Browser has selected the first option by default + if (this.el.selectedIndex === 0) { + if (!this.el.options[0].defaultSelected && !this.config.defaultSelected) { + this.el.selectedIndex = -1; + } + } + + this.selectedIndex = this.el.selectedIndex; + + if (this.selectedIndex > -1) { + this.select(this.selectedIndex); + } + } // If we're changing a select-one to select-multiple via the config + // and there are no selected options, the first option will be selected by the browser + // Let's prevent that here. + + + if (this.config.multiple && this.originalType === "select-one" && !this.config.data) { + if (this.el.options[0].selected && !this.el.options[0].defaultSelected) { + this.el.options[0].selected = false; + } + } + + util.each(this.options, function (i, option) { + if (option.selected && option.defaultSelected) { + this.select(option.idx); + } + }, this); + + if (this.config.selectedValue) { + this.setValue(this.config.selectedValue); + } + + if (this.config.data) { + if (!this.el.multiple && this.config.defaultSelected && this.el.selectedIndex < 0) { + this.select(0); + } + + var j = 0; + util.each(this.config.data, function (i, opt) { + // Check for group options + if (isset(opt, "children")) { + util.each(opt.children, function (x, item) { + if (item.hasOwnProperty("selected") && item.selected === true) { + this.select(j); + } + + j++; + }, this); + } else { + if (opt.hasOwnProperty("selected") && opt.selected === true) { + this.select(j); + } + + j++; + } + }, this); + } +}; +/** + * Destroy the instance + * @return {void} + */ + + +Selectr.prototype.destroy = function () { + if (!this.rendered) return; + this.emit("selectr.destroy"); // Revert to select-single if programtically set to multiple + + if (this.originalType === 'select-one') { + this.el.multiple = false; + } + + if (this.config.data) { + this.el.textContent = ""; + } // Remove the className from select element + + + util.removeClass(this.el, 'selectr-hidden'); // Remove reset listener from parent form + + if (this.el.form) { + util.off(this.el.form, "reset", this.events.reset); + } // Remove event listeners attached to doc and win + + + util.off(document, "click", this.events.dismiss); + util.off(document, "keydown", this.events.navigate); + util.off(window, "resize", this.update); + util.off(window, "scroll", this.update); // Replace the container with the original select element + + this.container.parentNode.replaceChild(this.el, this.container); + this.rendered = false; +}; +/** + * Change an options state + * @param {Number} index + * @return {void} + */ + + +Selectr.prototype.change = function (index) { + var item = this.items[index], + option = this.options[index]; + + if (option.disabled) { + return; + } + + if (option.selected && util.hasClass(item, "selected")) { + this.deselect(index); + } else { + this.select(index); + } + + if (this.opened && !this.el.multiple) { + this.close(); + } +}; +/** + * Select an option + * @param {Number} index + * @return {void} + */ + + +Selectr.prototype.select = function (index) { + var item = this.items[index], + options = [].slice.call(this.el.options), + option = this.options[index]; + + if (this.el.multiple) { + if (util.includes(this.selectedIndexes, index)) { + return false; + } + + if (this.config.maxSelections && this.tags.length === this.config.maxSelections) { + this.setMessage("A maximum of " + this.config.maxSelections + " items can be selected.", true); + return false; + } + + this.selectedValues.push(option.value); + this.selectedIndexes.push(index); + addTag.call(this, item); + } else { + var data = this.data ? this.data[index] : option; + this.label.textContent = this.customSelected ? this.config.renderSelection(data) : option.textContent; + this.selectedValue = option.value; + this.selectedIndex = index; + util.each(this.options, function (i, o) { + var opt = this.items[i]; + + if (i !== index) { + if (opt) { + util.removeClass(opt, "selected"); + } + + o.selected = false; + o.removeAttribute("selected"); + } + }, this); + } + + if (!util.includes(options, option)) { + this.el.add(option); + } + + item.setAttribute("aria-selected", true); + util.addClass(item, "selected"); + util.addClass(this.container, "has-selected"); + option.selected = true; + option.setAttribute("selected", ""); + this.emit("selectr.change", option); + this.emit("selectr.select", option); +}; +/** + * Deselect an option + * @param {Number} index + * @return {void} + */ + + +Selectr.prototype.deselect = function (index, force) { + var item = this.items[index], + option = this.options[index]; + + if (this.el.multiple) { + var selIndex = this.selectedIndexes.indexOf(index); + this.selectedIndexes.splice(selIndex, 1); + var valIndex = this.selectedValues.indexOf(option.value); + this.selectedValues.splice(valIndex, 1); + removeTag.call(this, item); + + if (!this.tags.length) { + util.removeClass(this.container, "has-selected"); + } + } else { + if (!force && !this.config.clearable && !this.config.allowDeselect) { + return false; + } + + this.label.textContent = ""; + this.selectedValue = null; + this.el.selectedIndex = this.selectedIndex = -1; + util.removeClass(this.container, "has-selected"); + } + + this.items[index].setAttribute("aria-selected", false); + util.removeClass(this.items[index], "selected"); + option.selected = false; + option.removeAttribute("selected"); + this.emit("selectr.change", null); + this.emit("selectr.deselect", option); +}; +/** + * Programmatically set selected values + * @param {String|Array} value - A string or an array of strings + */ + + +Selectr.prototype.setValue = function (value) { + var isArray = Array.isArray(value); + + if (!isArray) { + value = value.toString().trim(); + } // Can't pass array to select-one + + + if (!this.el.multiple && isArray) { + return false; + } + + util.each(this.options, function (i, option) { + if (isArray && util.includes(value.toString(), option.value) || option.value === value) { + this.change(option.idx); + } + }, this); +}; +/** + * Set the selected value(s) + * @param {bool} toObject Return only the raw values or an object + * @param {bool} toJson Return the object as a JSON string + * @return {mixed} Array or String + */ + + +Selectr.prototype.getValue = function (toObject, toJson) { + var value; + + if (this.el.multiple) { + if (toObject) { + if (this.selectedIndexes.length) { + value = {}; + value.values = []; + util.each(this.selectedIndexes, function (i, index) { + var option = this.options[index]; + value.values[i] = { + value: option.value, + text: option.textContent + }; + }, this); + } + } else { + value = this.selectedValues.slice(); + } + } else { + if (toObject) { + var option = this.options[this.selectedIndex]; + value = { + value: option.value, + text: option.textContent + }; + } else { + value = this.selectedValue; + } + } + + if (toObject && toJson) { + value = JSON.stringify(value); + } + + return value; +}; +/** + * Add a new option or options + * @param {object} data + */ + + +Selectr.prototype.add = function (data, checkDuplicate) { + if (data) { + this.data = this.data || []; + this.items = this.items || []; + this.options = this.options || []; + + if (Array.isArray(data)) { + // We have an array on items + util.each(data, function (i, obj) { + this.add(obj, checkDuplicate); + }, this); + } // User passed a single object to the method + // or Selectr passed an object from an array + else if ("[object Object]" === Object.prototype.toString.call(data)) { + if (checkDuplicate) { + var dupe = false; + util.each(this.options, function (i, option) { + if (option.value.toLowerCase() === data.value.toLowerCase()) { + dupe = true; + } + }); + + if (dupe) { + return false; + } + } + + var option = util.createElement('option', data); + this.data.push(data); // Add the new option to the list + + this.options.push(option); // Add the index for later use + + option.idx = this.options.length > 0 ? this.options.length - 1 : 0; // Create a new item + + createItem.call(this, option); // Select the item if required + + if (data.selected) { + this.select(option.idx); + } + + return option; + } // We may have had an empty select so update + // the placeholder to reflect the changes. + + + this.setPlaceholder(); // Recount the pages + + if (this.config.pagination) { + this.paginate(); + } + + return true; + } +}; +/** + * Remove an option or options + * @param {Mixed} o Array, integer (index) or string (value) + * @return {Void} + */ + + +Selectr.prototype.remove = function (o) { + var options = []; + + if (Array.isArray(o)) { + util.each(o, function (i, opt) { + if (util.isInt(opt)) { + options.push(this.getOptionByIndex(opt)); + } else if (typeof o === "string") { + options.push(this.getOptionByValue(opt)); + } + }, this); + } else if (util.isInt(o)) { + options.push(this.getOptionByIndex(o)); + } else if (typeof o === "string") { + options.push(this.getOptionByValue(o)); + } + + if (options.length) { + var index; + util.each(options, function (i, option) { + index = option.idx; // Remove the HTMLOptionElement + + this.el.remove(option); // Remove the reference from the option array + + this.options.splice(index, 1); // If the item has a parentNode (group element) it needs to be removed + // otherwise the render function will still append it to the dropdown + + var parentNode = this.items[index].parentNode; + + if (parentNode) { + parentNode.removeChild(this.items[index]); + } // Remove reference from the items array + + + this.items.splice(index, 1); // Reset the indexes + + util.each(this.options, function (i, opt) { + opt.idx = i; + this.items[i].idx = i; + }, this); + }, this); // We may have had an empty select now so update + // the placeholder to reflect the changes. + + this.setPlaceholder(); // Recount the pages + + if (this.config.pagination) { + this.paginate(); + } + } +}; +/** + * Remove all options + */ + + +Selectr.prototype.removeAll = function () { + // Clear any selected options + this.clear(true); // Remove the HTMLOptionElements + + util.each(this.el.options, function (i, option) { + this.el.remove(option); + }, this); // Empty the dropdown + + util.truncate(this.tree); // Reset variables + + this.items = []; + this.options = []; + this.data = []; + this.navIndex = 0; + + if (this.requiresPagination) { + this.requiresPagination = false; + this.pageIndex = 1; + this.pages = []; + } // Update the placeholder + + + this.setPlaceholder(); +}; +/** + * Perform a search + * @param {string} query The query string + */ + + +Selectr.prototype.search = function (string) { + if (this.navigating) return; + string = string || this.input.value; + var f = document.createDocumentFragment(); // Remove message + + this.removeMessage(); // Clear the dropdown + + util.truncate(this.tree); + + if (string.length > 1) { + // Check the options for the matching string + util.each(this.options, function (i, option) { + var item = this.items[option.idx]; + var includes = util.includes(option.textContent.toLowerCase(), string.toLowerCase()); + + if (includes && !option.disabled) { + appendItem(item, f, this.customOption); + util.removeClass(item, "excluded"); // Underline the matching results + + if (!this.customOption) { + item.textContent = ''; + var result = match(string, option.textContent); + + if (result) { + item.appendChild(document.createTextNode(result.before)); + var highlight = document.createElement('span'); + highlight.className = 'selectr-match'; + highlight.appendChild(document.createTextNode(result.match)); + item.appendChild(highlight); + item.appendChild(document.createTextNode(result.after)); + } + } + } else { + util.addClass(item, "excluded"); + } + }, this); + + if (!f.childElementCount) { + if (!this.config.taggable) { + this.setMessage("no results."); + } + } else { + // Highlight top result (@binary-koan #26) + var prevEl = this.items[this.navIndex]; + var firstEl = f.firstElementChild; + util.removeClass(prevEl, "active"); + this.navIndex = firstEl.idx; + util.addClass(firstEl, "active"); + } + } else { + render.call(this); + } + + this.tree.appendChild(f); +}; +/** + * Toggle the dropdown + * @return {void} + */ + + +Selectr.prototype.toggle = function () { + if (!this.disabled) { + if (this.opened) { + this.close(); + } else { + this.open(); + } + } +}; +/** + * Open the dropdown + * @return {void} + */ + + +Selectr.prototype.open = function () { + var that = this; + + if (!this.options.length) { + return false; + } + + if (!this.opened) { + this.emit("selectr.open"); + } + + this.opened = true; + + if (this.mobileDevice || this.config.nativeDropdown) { + util.addClass(this.container, "native-open"); + + if (this.config.data) { + // Dump the options into the select + // otherwise the native dropdown will be empty + util.each(this.options, function (i, option) { + this.el.add(option); + }, this); + } + + return; + } + + util.addClass(this.container, "open"); + render.call(this); + this.invert(); + this.tree.scrollTop = 0; + util.removeClass(this.container, "notice"); + this.selected.setAttribute("aria-expanded", true); + this.tree.setAttribute("aria-hidden", false); + this.tree.setAttribute("aria-expanded", true); + + if (this.config.searchable && !this.config.taggable) { + setTimeout(function () { + that.input.focus(); // Allow tab focus + + that.input.tabIndex = 0; + }, 10); + } +}; +/** + * Close the dropdown + * @return {void} + */ + + +Selectr.prototype.close = function () { + if (this.opened) { + this.emit("selectr.close"); + } + + this.opened = false; + + if (this.mobileDevice || this.config.nativeDropdown) { + util.removeClass(this.container, "native-open"); + return; + } + + var notice = util.hasClass(this.container, "notice"); + + if (this.config.searchable && !notice) { + this.input.blur(); // Disable tab focus + + this.input.tabIndex = -1; + this.searching = false; + } + + if (notice) { + util.removeClass(this.container, "notice"); + this.notice.textContent = ""; + } + + util.removeClass(this.container, "open"); + util.removeClass(this.container, "native-open"); + this.selected.setAttribute("aria-expanded", false); + this.tree.setAttribute("aria-hidden", true); + this.tree.setAttribute("aria-expanded", false); + util.truncate(this.tree); + clearSearch.call(this); +}; +/** + * Enable the element + * @return {void} + */ + + +Selectr.prototype.enable = function () { + this.disabled = false; + this.el.disabled = false; + this.selected.tabIndex = this.originalIndex; + + if (this.el.multiple) { + util.each(this.tags, function (i, t) { + t.lastElementChild.tabIndex = 0; + }); + } + + util.removeClass(this.container, "selectr-disabled"); +}; +/** + * Disable the element + * @param {boolean} container Disable the container only (allow value submit with form) + * @return {void} + */ + + +Selectr.prototype.disable = function (container) { + if (!container) { + this.el.disabled = true; + } + + this.selected.tabIndex = -1; + + if (this.el.multiple) { + util.each(this.tags, function (i, t) { + t.lastElementChild.tabIndex = -1; + }); + } + + this.disabled = true; + util.addClass(this.container, "selectr-disabled"); +}; +/** + * Reset to initial state + * @return {void} + */ + + +Selectr.prototype.reset = function () { + if (!this.disabled) { + this.clear(); + this.setSelected(true); + util.each(this.defaultSelected, function (i, idx) { + this.select(idx); + }, this); + this.emit("selectr.reset"); + } +}; +/** + * Clear all selections + * @return {void} + */ + + +Selectr.prototype.clear = function (force) { + if (this.el.multiple) { + // Loop over the selectedIndexes so we don't have to loop over all the options + // which can be costly if there are a lot of them + if (this.selectedIndexes.length) { + // Copy the array or we'll get an error + var indexes = this.selectedIndexes.slice(); + util.each(indexes, function (i, idx) { + this.deselect(idx); + }, this); + } + } else { + if (this.selectedIndex > -1) { + this.deselect(this.selectedIndex, force); + } + } + + this.emit("selectr.clear"); +}; +/** + * Return serialised data + * @param {boolean} toJson + * @return {mixed} Returns either an object or JSON string + */ + + +Selectr.prototype.serialise = function (toJson) { + var data = []; + util.each(this.options, function (i, option) { + var obj = { + value: option.value, + text: option.textContent + }; + + if (option.selected) { + obj.selected = true; + } + + if (option.disabled) { + obj.disabled = true; + } + + data[i] = obj; + }); + return toJson ? JSON.stringify(data) : data; +}; +/** + * Localised version of serialise() method + */ + + +Selectr.prototype.serialize = function (toJson) { + return this.serialise(toJson); +}; +/** + * Sets the placeholder + * @param {String} placeholder + */ + + +Selectr.prototype.setPlaceholder = function (placeholder) { + // Set the placeholder + placeholder = placeholder || this.config.placeholder || this.el.getAttribute("placeholder"); + + if (!this.options.length) { + placeholder = "No options available"; + } + + this.placeEl.textContent = placeholder; +}; +/** + * Paginate the option list + * @return {Array} + */ + + +Selectr.prototype.paginate = function () { + if (this.items.length) { + var that = this; + this.pages = this.items.map(function (v, i) { + return i % that.config.pagination === 0 ? that.items.slice(i, i + that.config.pagination) : null; + }).filter(function (pages) { + return pages; + }); + return this.pages; + } +}; +/** + * Display a message + * @param {String} message The message + */ + + +Selectr.prototype.setMessage = function (message, close) { + if (close) { + this.close(); + } + + util.addClass(this.container, "notice"); + this.notice.textContent = message; +}; +/** + * Dismiss the current message + */ + + +Selectr.prototype.removeMessage = function () { + util.removeClass(this.container, "notice"); + this.notice.textContent = ""; +}; +/** + * Keep the dropdown within the window + * @return {void} + */ + + +Selectr.prototype.invert = function () { + var rt = util.rect(this.selected), + oh = this.tree.parentNode.offsetHeight, + wh = window.innerHeight, + doInvert = rt.top + rt.height + oh > wh; + + if (doInvert) { + util.addClass(this.container, "inverted"); + this.isInverted = true; + } else { + util.removeClass(this.container, "inverted"); + this.isInverted = false; + } + + this.optsRect = util.rect(this.tree); +}; +/** + * Get an option via it's index + * @param {Integer} index The index of the HTMLOptionElement required + * @return {HTMLOptionElement} + */ + + +Selectr.prototype.getOptionByIndex = function (index) { + return this.options[index]; +}; +/** + * Get an option via it's value + * @param {String} value The value of the HTMLOptionElement required + * @return {HTMLOptionElement} + */ + + +Selectr.prototype.getOptionByValue = function (value) { + var option = false; + + for (var i = 0, l = this.options.length; i < l; i++) { + if (this.options[i].value.trim() === value.toString().trim()) { + option = this.options[i]; + break; + } + } + + return option; +}; + +module.exports = Selectr; + +/***/ }), + +/***/ 4188: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "qD": function() { return /* binding */ DEFAULT_MODAL_ANCHOR; }, +/* harmony export */ "EX": function() { return /* binding */ SIZE_LARGE; }, +/* harmony export */ "WF": function() { return /* binding */ MAX_PREVIEW_CHARACTERS; }, +/* harmony export */ "oW": function() { return /* binding */ PREVIEW_HISTORY_LIMIT; } +/* harmony export */ }); +var DEFAULT_MODAL_ANCHOR = document.body; +var SIZE_LARGE = 10 * 1024 * 1024; // 10 MB + +var MAX_PREVIEW_CHARACTERS = 20000; +var PREVIEW_HISTORY_LIMIT = 2 * 1024 * 1024 * 1024; // 2 GB + +/***/ }), + +/***/ 2602: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "w": function() { return /* binding */ createAbsoluteAnchor; } +/* harmony export */ }); +/* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9791); + +/** + * Create an anchor element absolutely positioned in the `parent` + * element. + * @param {HTMLElement} anchor + * @param {HTMLElement} parent + * @param {function(HTMLElement)} [onDestroy] Callback when the anchor is destroyed + * @param {boolean} [destroyOnMouseOut=false] If true, anchor will be removed on mouse out + * @returns {HTMLElement} + */ + +function createAbsoluteAnchor(anchor, parent, onDestroy) { + var destroyOnMouseOut = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + var root = getRootNode(anchor); + var eventListeners = {}; + var anchorRect = anchor.getBoundingClientRect(); + var parentRect = parent.getBoundingClientRect(); + var absoluteAnchor = document.createElement('div'); + absoluteAnchor.className = 'jsoneditor-anchor'; + absoluteAnchor.style.position = 'absolute'; + absoluteAnchor.style.left = anchorRect.left - parentRect.left + 'px'; + absoluteAnchor.style.top = anchorRect.top - parentRect.top + 'px'; + absoluteAnchor.style.width = anchorRect.width - 2 + 'px'; + absoluteAnchor.style.height = anchorRect.height - 2 + 'px'; + absoluteAnchor.style.boxSizing = 'border-box'; + parent.appendChild(absoluteAnchor); + + function destroy() { + // remove temporary absolutely positioned anchor + if (absoluteAnchor && absoluteAnchor.parentNode) { + absoluteAnchor.parentNode.removeChild(absoluteAnchor); // remove all event listeners + // all event listeners are supposed to be attached to document. + + for (var name in eventListeners) { + if (hasOwnProperty(eventListeners, name)) { + var fn = eventListeners[name]; + + if (fn) { + (0,_util__WEBPACK_IMPORTED_MODULE_0__.removeEventListener)(root, name, fn); + } + + delete eventListeners[name]; + } + } + + if (typeof onDestroy === 'function') { + onDestroy(anchor); + } + } + } + + function isOutside(target) { + return target !== absoluteAnchor && !(0,_util__WEBPACK_IMPORTED_MODULE_0__.isChildOf)(target, absoluteAnchor); + } // create and attach event listeners + + + function destroyIfOutside(event) { + if (isOutside(event.target)) { + destroy(); + } + } + + eventListeners.mousedown = (0,_util__WEBPACK_IMPORTED_MODULE_0__.addEventListener)(root, 'mousedown', destroyIfOutside); + eventListeners.mousewheel = (0,_util__WEBPACK_IMPORTED_MODULE_0__.addEventListener)(root, 'mousewheel', destroyIfOutside); + + if (destroyOnMouseOut) { + var destroyTimer = null; + + absoluteAnchor.onmouseover = function () { + clearTimeout(destroyTimer); + destroyTimer = null; + }; + + absoluteAnchor.onmouseout = function () { + if (!destroyTimer) { + destroyTimer = setTimeout(destroy, 200); + } + }; + } + + absoluteAnchor.destroy = destroy; + return absoluteAnchor; +} +/** + * Node.getRootNode shim + * @param {HTMLElement} node node to check + * @return {HTMLElement} node's rootNode or `window` if there is ShadowDOM is not supported. + */ + +function getRootNode(node) { + return typeof node.getRootNode === 'function' ? node.getRootNode() : window; +} + +function hasOwnProperty(object, key) { + return Object.prototype.hasOwnProperty.call(object, key); +} + +/***/ }), + +/***/ 7923: +/***/ (function(module) { + +module.exports = 'data:application/javascript;base64,Im5vIHVzZSBzdHJpY3QiOwohKGZ1bmN0aW9uKHdpbmRvdykgewppZiAodHlwZW9mIHdpbmRvdy53aW5kb3cgIT0gInVuZGVmaW5lZCIgJiYgd2luZG93LmRvY3VtZW50KQogICAgcmV0dXJuOwppZiAod2luZG93LnJlcXVpcmUgJiYgd2luZG93LmRlZmluZSkKICAgIHJldHVybjsKCmlmICghd2luZG93LmNvbnNvbGUpIHsKICAgIHdpbmRvdy5jb25zb2xlID0gZnVuY3Rpb24oKSB7CiAgICAgICAgdmFyIG1zZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApOwogICAgICAgIHBvc3RNZXNzYWdlKHt0eXBlOiAibG9nIiwgZGF0YTogbXNnc30pOwogICAgfTsKICAgIHdpbmRvdy5jb25zb2xlLmVycm9yID0KICAgIHdpbmRvdy5jb25zb2xlLndhcm4gPSAKICAgIHdpbmRvdy5jb25zb2xlLmxvZyA9CiAgICB3aW5kb3cuY29uc29sZS50cmFjZSA9IHdpbmRvdy5jb25zb2xlOwp9CndpbmRvdy53aW5kb3cgPSB3aW5kb3c7CndpbmRvdy5hY2UgPSB3aW5kb3c7Cgp3aW5kb3cub25lcnJvciA9IGZ1bmN0aW9uKG1lc3NhZ2UsIGZpbGUsIGxpbmUsIGNvbCwgZXJyKSB7CiAgICBwb3N0TWVzc2FnZSh7dHlwZTogImVycm9yIiwgZGF0YTogewogICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsCiAgICAgICAgZGF0YTogZXJyLmRhdGEsCiAgICAgICAgZmlsZTogZmlsZSwKICAgICAgICBsaW5lOiBsaW5lLCAKICAgICAgICBjb2w6IGNvbCwKICAgICAgICBzdGFjazogZXJyLnN0YWNrCiAgICB9fSk7Cn07Cgp3aW5kb3cubm9ybWFsaXplTW9kdWxlID0gZnVuY3Rpb24ocGFyZW50SWQsIG1vZHVsZU5hbWUpIHsKICAgIC8vIG5vcm1hbGl6ZSBwbHVnaW4gcmVxdWlyZXMKICAgIGlmIChtb2R1bGVOYW1lLmluZGV4T2YoIiEiKSAhPT0gLTEpIHsKICAgICAgICB2YXIgY2h1bmtzID0gbW9kdWxlTmFtZS5zcGxpdCgiISIpOwogICAgICAgIHJldHVybiB3aW5kb3cubm9ybWFsaXplTW9kdWxlKHBhcmVudElkLCBjaHVua3NbMF0pICsgIiEiICsgd2luZG93Lm5vcm1hbGl6ZU1vZHVsZShwYXJlbnRJZCwgY2h1bmtzWzFdKTsKICAgIH0KICAgIC8vIG5vcm1hbGl6ZSByZWxhdGl2ZSByZXF1aXJlcwogICAgaWYgKG1vZHVsZU5hbWUuY2hhckF0KDApID09ICIuIikgewogICAgICAgIHZhciBiYXNlID0gcGFyZW50SWQuc3BsaXQoIi8iKS5zbGljZSgwLCAtMSkuam9pbigiLyIpOwogICAgICAgIG1vZHVsZU5hbWUgPSAoYmFzZSA/IGJhc2UgKyAiLyIgOiAiIikgKyBtb2R1bGVOYW1lOwogICAgICAgIAogICAgICAgIHdoaWxlIChtb2R1bGVOYW1lLmluZGV4T2YoIi4iKSAhPT0gLTEgJiYgcHJldmlvdXMgIT0gbW9kdWxlTmFtZSkgewogICAgICAgICAgICB2YXIgcHJldmlvdXMgPSBtb2R1bGVOYW1lOwogICAgICAgICAgICBtb2R1bGVOYW1lID0gbW9kdWxlTmFtZS5yZXBsYWNlKC9eXC5cLy8sICIiKS5yZXBsYWNlKC9cL1wuXC8vLCAiLyIpLnJlcGxhY2UoL1teXC9dK1wvXC5cLlwvLywgIiIpOwogICAgICAgIH0KICAgIH0KICAgIAogICAgcmV0dXJuIG1vZHVsZU5hbWU7Cn07Cgp3aW5kb3cucmVxdWlyZSA9IGZ1bmN0aW9uIHJlcXVpcmUocGFyZW50SWQsIGlkKSB7CiAgICBpZiAoIWlkKSB7CiAgICAgICAgaWQgPSBwYXJlbnRJZDsKICAgICAgICBwYXJlbnRJZCA9IG51bGw7CiAgICB9CiAgICBpZiAoIWlkLmNoYXJBdCkKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIndvcmtlci5qcyByZXF1aXJlKCkgYWNjZXB0cyBvbmx5IChwYXJlbnRJZCwgaWQpIGFzIGFyZ3VtZW50cyIpOwoKICAgIGlkID0gd2luZG93Lm5vcm1hbGl6ZU1vZHVsZShwYXJlbnRJZCwgaWQpOwoKICAgIHZhciBtb2R1bGUgPSB3aW5kb3cucmVxdWlyZS5tb2R1bGVzW2lkXTsKICAgIGlmIChtb2R1bGUpIHsKICAgICAgICBpZiAoIW1vZHVsZS5pbml0aWFsaXplZCkgewogICAgICAgICAgICBtb2R1bGUuaW5pdGlhbGl6ZWQgPSB0cnVlOwogICAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IG1vZHVsZS5mYWN0b3J5KCkuZXhwb3J0czsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG1vZHVsZS5leHBvcnRzOwogICAgfQogICAKICAgIGlmICghd2luZG93LnJlcXVpcmUudGxucykKICAgICAgICByZXR1cm4gY29uc29sZS5sb2coInVuYWJsZSB0byBsb2FkICIgKyBpZCk7CiAgICAKICAgIHZhciBwYXRoID0gcmVzb2x2ZU1vZHVsZUlkKGlkLCB3aW5kb3cucmVxdWlyZS50bG5zKTsKICAgIGlmIChwYXRoLnNsaWNlKC0zKSAhPSAiLmpzIikgcGF0aCArPSAiLmpzIjsKICAgIAogICAgd2luZG93LnJlcXVpcmUuaWQgPSBpZDsKICAgIHdpbmRvdy5yZXF1aXJlLm1vZHVsZXNbaWRdID0ge307IC8vIHByZXZlbnQgaW5maW5pdGUgbG9vcCBvbiBicm9rZW4gbW9kdWxlcwogICAgaW1wb3J0U2NyaXB0cyhwYXRoKTsKICAgIHJldHVybiB3aW5kb3cucmVxdWlyZShwYXJlbnRJZCwgaWQpOwp9OwpmdW5jdGlvbiByZXNvbHZlTW9kdWxlSWQoaWQsIHBhdGhzKSB7CiAgICB2YXIgdGVzdFBhdGggPSBpZCwgdGFpbCA9ICIiOwogICAgd2hpbGUgKHRlc3RQYXRoKSB7CiAgICAgICAgdmFyIGFsaWFzID0gcGF0aHNbdGVzdFBhdGhdOwogICAgICAgIGlmICh0eXBlb2YgYWxpYXMgPT0gInN0cmluZyIpIHsKICAgICAgICAgICAgcmV0dXJuIGFsaWFzICsgdGFpbDsKICAgICAgICB9IGVsc2UgaWYgKGFsaWFzKSB7CiAgICAgICAgICAgIHJldHVybiAgYWxpYXMubG9jYXRpb24ucmVwbGFjZSgvXC8qJC8sICIvIikgKyAodGFpbCB8fCBhbGlhcy5tYWluIHx8IGFsaWFzLm5hbWUpOwogICAgICAgIH0gZWxzZSBpZiAoYWxpYXMgPT09IGZhbHNlKSB7CiAgICAgICAgICAgIHJldHVybiAiIjsKICAgICAgICB9CiAgICAgICAgdmFyIGkgPSB0ZXN0UGF0aC5sYXN0SW5kZXhPZigiLyIpOwogICAgICAgIGlmIChpID09PSAtMSkgYnJlYWs7CiAgICAgICAgdGFpbCA9IHRlc3RQYXRoLnN1YnN0cihpKSArIHRhaWw7CiAgICAgICAgdGVzdFBhdGggPSB0ZXN0UGF0aC5zbGljZSgwLCBpKTsKICAgIH0KICAgIHJldHVybiBpZDsKfQp3aW5kb3cucmVxdWlyZS5tb2R1bGVzID0ge307CndpbmRvdy5yZXF1aXJlLnRsbnMgPSB7fTsKCndpbmRvdy5kZWZpbmUgPSBmdW5jdGlvbihpZCwgZGVwcywgZmFjdG9yeSkgewogICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMikgewogICAgICAgIGZhY3RvcnkgPSBkZXBzOwogICAgICAgIGlmICh0eXBlb2YgaWQgIT0gInN0cmluZyIpIHsKICAgICAgICAgICAgZGVwcyA9IGlkOwogICAgICAgICAgICBpZCA9IHdpbmRvdy5yZXF1aXJlLmlkOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAxKSB7CiAgICAgICAgZmFjdG9yeSA9IGlkOwogICAgICAgIGRlcHMgPSBbXTsKICAgICAgICBpZCA9IHdpbmRvdy5yZXF1aXJlLmlkOwogICAgfQogICAgCiAgICBpZiAodHlwZW9mIGZhY3RvcnkgIT0gImZ1bmN0aW9uIikgewogICAgICAgIHdpbmRvdy5yZXF1aXJlLm1vZHVsZXNbaWRdID0gewogICAgICAgICAgICBleHBvcnRzOiBmYWN0b3J5LAogICAgICAgICAgICBpbml0aWFsaXplZDogdHJ1ZQogICAgICAgIH07CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmICghZGVwcy5sZW5ndGgpCiAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gZGVwZW5kZW5jaWVzLCB3ZSBpbmplY3QgInJlcXVpcmUiLCAiZXhwb3J0cyIgYW5kCiAgICAgICAgLy8gIm1vZHVsZSIgYXMgZGVwZW5kZW5jaWVzLCB0byBwcm92aWRlIENvbW1vbkpTIGNvbXBhdGliaWxpdHkuCiAgICAgICAgZGVwcyA9IFsicmVxdWlyZSIsICJleHBvcnRzIiwgIm1vZHVsZSJdOwoKICAgIHZhciByZXEgPSBmdW5jdGlvbihjaGlsZElkKSB7CiAgICAgICAgcmV0dXJuIHdpbmRvdy5yZXF1aXJlKGlkLCBjaGlsZElkKTsKICAgIH07CgogICAgd2luZG93LnJlcXVpcmUubW9kdWxlc1tpZF0gPSB7CiAgICAgICAgZXhwb3J0czoge30sCiAgICAgICAgZmFjdG9yeTogZnVuY3Rpb24oKSB7CiAgICAgICAgICAgIHZhciBtb2R1bGUgPSB0aGlzOwogICAgICAgICAgICB2YXIgcmV0dXJuRXhwb3J0cyA9IGZhY3RvcnkuYXBwbHkodGhpcywgZGVwcy5zbGljZSgwLCBmYWN0b3J5Lmxlbmd0aCkubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICAgICAgICAgICAgc3dpdGNoIChkZXApIHsKICAgICAgICAgICAgICAgICAgICAvLyBCZWNhdXNlICJyZXF1aXJlIiwgImV4cG9ydHMiIGFuZCAibW9kdWxlIiBhcmVuJ3QgYWN0dWFsCiAgICAgICAgICAgICAgICAgICAgLy8gZGVwZW5kZW5jaWVzLCB3ZSBtdXN0IGhhbmRsZSB0aGVtIHNlcGVyYXRlbHkuCiAgICAgICAgICAgICAgICAgICAgY2FzZSAicmVxdWlyZSI6IHJldHVybiByZXE7CiAgICAgICAgICAgICAgICAgICAgY2FzZSAiZXhwb3J0cyI6IHJldHVybiBtb2R1bGUuZXhwb3J0czsKICAgICAgICAgICAgICAgICAgICBjYXNlICJtb2R1bGUiOiAgcmV0dXJuIG1vZHVsZTsKICAgICAgICAgICAgICAgICAgICAvLyBCdXQgZm9yIGFsbCBvdGhlciBkZXBlbmRlbmNpZXMsIHdlIGNhbiBqdXN0IGdvIGFoZWFkIGFuZAogICAgICAgICAgICAgICAgICAgIC8vIHJlcXVpcmUgdGhlbS4KICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiAgICAgICAgcmV0dXJuIHJlcShkZXApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KSk7CiAgICAgICAgICAgIGlmIChyZXR1cm5FeHBvcnRzKQogICAgICAgICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSByZXR1cm5FeHBvcnRzOwogICAgICAgICAgICByZXR1cm4gbW9kdWxlOwogICAgICAgIH0KICAgIH07Cn07CndpbmRvdy5kZWZpbmUuYW1kID0ge307CnJlcXVpcmUudGxucyA9IHt9Owp3aW5kb3cuaW5pdEJhc2VVcmxzICA9IGZ1bmN0aW9uIGluaXRCYXNlVXJscyh0b3BMZXZlbE5hbWVzcGFjZXMpIHsKICAgIGZvciAodmFyIGkgaW4gdG9wTGV2ZWxOYW1lc3BhY2VzKQogICAgICAgIHJlcXVpcmUudGxuc1tpXSA9IHRvcExldmVsTmFtZXNwYWNlc1tpXTsKfTsKCndpbmRvdy5pbml0U2VuZGVyID0gZnVuY3Rpb24gaW5pdFNlbmRlcigpIHsKCiAgICB2YXIgRXZlbnRFbWl0dGVyID0gd2luZG93LnJlcXVpcmUoImFjZS9saWIvZXZlbnRfZW1pdHRlciIpLkV2ZW50RW1pdHRlcjsKICAgIHZhciBvb3AgPSB3aW5kb3cucmVxdWlyZSgiYWNlL2xpYi9vb3AiKTsKICAgIAogICAgdmFyIFNlbmRlciA9IGZ1bmN0aW9uKCkge307CiAgICAKICAgIChmdW5jdGlvbigpIHsKICAgICAgICAKICAgICAgICBvb3AuaW1wbGVtZW50KHRoaXMsIEV2ZW50RW1pdHRlcik7CiAgICAgICAgICAgICAgICAKICAgICAgICB0aGlzLmNhbGxiYWNrID0gZnVuY3Rpb24oZGF0YSwgY2FsbGJhY2tJZCkgewogICAgICAgICAgICBwb3N0TWVzc2FnZSh7CiAgICAgICAgICAgICAgICB0eXBlOiAiY2FsbCIsCiAgICAgICAgICAgICAgICBpZDogY2FsbGJhY2tJZCwKICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEKICAgICAgICAgICAgfSk7CiAgICAgICAgfTsKICAgIAogICAgICAgIHRoaXMuZW1pdCA9IGZ1bmN0aW9uKG5hbWUsIGRhdGEpIHsKICAgICAgICAgICAgcG9zdE1lc3NhZ2UoewogICAgICAgICAgICAgICAgdHlwZTogImV2ZW50IiwKICAgICAgICAgICAgICAgIG5hbWU6IG5hbWUsCiAgICAgICAgICAgICAgICBkYXRhOiBkYXRhCiAgICAgICAgICAgIH0pOwogICAgICAgIH07CiAgICAgICAgCiAgICB9KS5jYWxsKFNlbmRlci5wcm90b3R5cGUpOwogICAgCiAgICByZXR1cm4gbmV3IFNlbmRlcigpOwp9OwoKdmFyIG1haW4gPSB3aW5kb3cubWFpbiA9IG51bGw7CnZhciBzZW5kZXIgPSB3aW5kb3cuc2VuZGVyID0gbnVsbDsKCndpbmRvdy5vbm1lc3NhZ2UgPSBmdW5jdGlvbihlKSB7CiAgICB2YXIgbXNnID0gZS5kYXRhOwogICAgaWYgKG1zZy5ldmVudCAmJiBzZW5kZXIpIHsKICAgICAgICBzZW5kZXIuX3NpZ25hbChtc2cuZXZlbnQsIG1zZy5kYXRhKTsKICAgIH0KICAgIGVsc2UgaWYgKG1zZy5jb21tYW5kKSB7CiAgICAgICAgaWYgKG1haW5bbXNnLmNvbW1hbmRdKQogICAgICAgICAgICBtYWluW21zZy5jb21tYW5kXS5hcHBseShtYWluLCBtc2cuYXJncyk7CiAgICAgICAgZWxzZSBpZiAod2luZG93W21zZy5jb21tYW5kXSkKICAgICAgICAgICAgd2luZG93W21zZy5jb21tYW5kXS5hcHBseSh3aW5kb3csIG1zZy5hcmdzKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiVW5rbm93biBjb21tYW5kOiIgKyBtc2cuY29tbWFuZCk7CiAgICB9CiAgICBlbHNlIGlmIChtc2cuaW5pdCkgewogICAgICAgIHdpbmRvdy5pbml0QmFzZVVybHMobXNnLnRsbnMpOwogICAgICAgIHNlbmRlciA9IHdpbmRvdy5zZW5kZXIgPSB3aW5kb3cuaW5pdFNlbmRlcigpOwogICAgICAgIHZhciBjbGF6eiA9IHJlcXVpcmUobXNnLm1vZHVsZSlbbXNnLmNsYXNzbmFtZV07CiAgICAgICAgbWFpbiA9IHdpbmRvdy5tYWluID0gbmV3IGNsYXp6KHNlbmRlcik7CiAgICB9Cn07Cn0pKHRoaXMpOwoKYWNlLmRlZmluZSgiYWNlL2xpYi9vb3AiLFtdLCBmdW5jdGlvbihyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpIHsKInVzZSBzdHJpY3QiOwoKZXhwb3J0cy5pbmhlcml0cyA9IGZ1bmN0aW9uKGN0b3IsIHN1cGVyQ3RvcikgewogICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3I7CiAgICBjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwgewogICAgICAgIGNvbnN0cnVjdG9yOiB7CiAgICAgICAgICAgIHZhbHVlOiBjdG9yLAogICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSwKICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsCiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogICAgICAgIH0KICAgIH0pOwp9OwoKZXhwb3J0cy5taXhpbiA9IGZ1bmN0aW9uKG9iaiwgbWl4aW4pIHsKICAgIGZvciAodmFyIGtleSBpbiBtaXhpbikgewogICAgICAgIG9ialtrZXldID0gbWl4aW5ba2V5XTsKICAgIH0KICAgIHJldHVybiBvYmo7Cn07CgpleHBvcnRzLmltcGxlbWVudCA9IGZ1bmN0aW9uKHByb3RvLCBtaXhpbikgewogICAgZXhwb3J0cy5taXhpbihwcm90bywgbWl4aW4pOwp9OwoKfSk7CgphY2UuZGVmaW5lKCJhY2UvcmFuZ2UiLFtdLCBmdW5jdGlvbihyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpIHsKInVzZSBzdHJpY3QiOwp2YXIgY29tcGFyZVBvaW50cyA9IGZ1bmN0aW9uKHAxLCBwMikgewogICAgcmV0dXJuIHAxLnJvdyAtIHAyLnJvdyB8fCBwMS5jb2x1bW4gLSBwMi5jb2x1bW47Cn07CnZhciBSYW5nZSA9IGZ1bmN0aW9uKHN0YXJ0Um93LCBzdGFydENvbHVtbiwgZW5kUm93LCBlbmRDb2x1bW4pIHsKICAgIHRoaXMuc3RhcnQgPSB7CiAgICAgICAgcm93OiBzdGFydFJvdywKICAgICAgICBjb2x1bW46IHN0YXJ0Q29sdW1uCiAgICB9OwoKICAgIHRoaXMuZW5kID0gewogICAgICAgIHJvdzogZW5kUm93LAogICAgICAgIGNvbHVtbjogZW5kQ29sdW1uCiAgICB9Owp9OwoKKGZ1bmN0aW9uKCkgewogICAgdGhpcy5pc0VxdWFsID0gZnVuY3Rpb24ocmFuZ2UpIHsKICAgICAgICByZXR1cm4gdGhpcy5zdGFydC5yb3cgPT09IHJhbmdlLnN0YXJ0LnJvdyAmJgogICAgICAgICAgICB0aGlzLmVuZC5yb3cgPT09IHJhbmdlLmVuZC5yb3cgJiYKICAgICAgICAgICAgdGhpcy5zdGFydC5jb2x1bW4gPT09IHJhbmdlLnN0YXJ0LmNvbHVtbiAmJgogICAgICAgICAgICB0aGlzLmVuZC5jb2x1bW4gPT09IHJhbmdlLmVuZC5jb2x1bW47CiAgICB9OwogICAgdGhpcy50b1N0cmluZyA9IGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiAoIlJhbmdlOiBbIiArIHRoaXMuc3RhcnQucm93ICsgIi8iICsgdGhpcy5zdGFydC5jb2x1bW4gKwogICAgICAgICAgICAiXSAtPiBbIiArIHRoaXMuZW5kLnJvdyArICIvIiArIHRoaXMuZW5kLmNvbHVtbiArICJdIik7CiAgICB9OwoKICAgIHRoaXMuY29udGFpbnMgPSBmdW5jdGlvbihyb3csIGNvbHVtbikgewogICAgICAgIHJldHVybiB0aGlzLmNvbXBhcmUocm93LCBjb2x1bW4pID09IDA7CiAgICB9OwogICAgdGhpcy5jb21wYXJlUmFuZ2UgPSBmdW5jdGlvbihyYW5nZSkgewogICAgICAgIHZhciBjbXAsCiAgICAgICAgICAgIGVuZCA9IHJhbmdlLmVuZCwKICAgICAgICAgICAgc3RhcnQgPSByYW5nZS5zdGFydDsKCiAgICAgICAgY21wID0gdGhpcy5jb21wYXJlKGVuZC5yb3csIGVuZC5jb2x1bW4pOwogICAgICAgIGlmIChjbXAgPT0gMSkgewogICAgICAgICAgICBjbXAgPSB0aGlzLmNvbXBhcmUoc3RhcnQucm93LCBzdGFydC5jb2x1bW4pOwogICAgICAgICAgICBpZiAoY21wID09IDEpIHsKICAgICAgICAgICAgICAgIHJldHVybiAyOwogICAgICAgICAgICB9IGVsc2UgaWYgKGNtcCA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjbXAgPT0gLTEpIHsKICAgICAgICAgICAgcmV0dXJuIC0yOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGNtcCA9IHRoaXMuY29tcGFyZShzdGFydC5yb3csIHN0YXJ0LmNvbHVtbik7CiAgICAgICAgICAgIGlmIChjbXAgPT0gLTEpIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfSBlbHNlIGlmIChjbXAgPT0gMSkgewogICAgICAgICAgICAgICAgcmV0dXJuIDQyOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwogICAgdGhpcy5jb21wYXJlUG9pbnQgPSBmdW5jdGlvbihwKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZShwLnJvdywgcC5jb2x1bW4pOwogICAgfTsKICAgIHRoaXMuY29udGFpbnNSYW5nZSA9IGZ1bmN0aW9uKHJhbmdlKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuY29tcGFyZVBvaW50KHJhbmdlLnN0YXJ0KSA9PSAwICYmIHRoaXMuY29tcGFyZVBvaW50KHJhbmdlLmVuZCkgPT0gMDsKICAgIH07CiAgICB0aGlzLmludGVyc2VjdHMgPSBmdW5jdGlvbihyYW5nZSkgewogICAgICAgIHZhciBjbXAgPSB0aGlzLmNvbXBhcmVSYW5nZShyYW5nZSk7CiAgICAgICAgcmV0dXJuIChjbXAgPT0gLTEgfHwgY21wID09IDAgfHwgY21wID09IDEpOwogICAgfTsKICAgIHRoaXMuaXNFbmQgPSBmdW5jdGlvbihyb3csIGNvbHVtbikgewogICAgICAgIHJldHVybiB0aGlzLmVuZC5yb3cgPT0gcm93ICYmIHRoaXMuZW5kLmNvbHVtbiA9PSBjb2x1bW47CiAgICB9OwogICAgdGhpcy5pc1N0YXJ0ID0gZnVuY3Rpb24ocm93LCBjb2x1bW4pIHsKICAgICAgICByZXR1cm4gdGhpcy5zdGFydC5yb3cgPT0gcm93ICYmIHRoaXMuc3RhcnQuY29sdW1uID09IGNvbHVtbjsKICAgIH07CiAgICB0aGlzLnNldFN0YXJ0ID0gZnVuY3Rpb24ocm93LCBjb2x1bW4pIHsKICAgICAgICBpZiAodHlwZW9mIHJvdyA9PSAib2JqZWN0IikgewogICAgICAgICAgICB0aGlzLnN0YXJ0LmNvbHVtbiA9IHJvdy5jb2x1bW47CiAgICAgICAgICAgIHRoaXMuc3RhcnQucm93ID0gcm93LnJvdzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aGlzLnN0YXJ0LnJvdyA9IHJvdzsKICAgICAgICAgICAgdGhpcy5zdGFydC5jb2x1bW4gPSBjb2x1bW47CiAgICAgICAgfQogICAgfTsKICAgIHRoaXMuc2V0RW5kID0gZnVuY3Rpb24ocm93LCBjb2x1bW4pIHsKICAgICAgICBpZiAodHlwZW9mIHJvdyA9PSAib2JqZWN0IikgewogICAgICAgICAgICB0aGlzLmVuZC5jb2x1bW4gPSByb3cuY29sdW1uOwogICAgICAgICAgICB0aGlzLmVuZC5yb3cgPSByb3cucm93OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRoaXMuZW5kLnJvdyA9IHJvdzsKICAgICAgICAgICAgdGhpcy5lbmQuY29sdW1uID0gY29sdW1uOwogICAgICAgIH0KICAgIH07CiAgICB0aGlzLmluc2lkZSA9IGZ1bmN0aW9uKHJvdywgY29sdW1uKSB7CiAgICAgICAgaWYgKHRoaXMuY29tcGFyZShyb3csIGNvbHVtbikgPT0gMCkgewogICAgICAgICAgICBpZiAodGhpcy5pc0VuZChyb3csIGNvbHVtbikgfHwgdGhpcy5pc1N0YXJ0KHJvdywgY29sdW1uKSkgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfTsKICAgIHRoaXMuaW5zaWRlU3RhcnQgPSBmdW5jdGlvbihyb3csIGNvbHVtbikgewogICAgICAgIGlmICh0aGlzLmNvbXBhcmUocm93LCBjb2x1bW4pID09IDApIHsKICAgICAgICAgICAgaWYgKHRoaXMuaXNFbmQocm93LCBjb2x1bW4pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9OwogICAgdGhpcy5pbnNpZGVFbmQgPSBmdW5jdGlvbihyb3csIGNvbHVtbikgewogICAgICAgIGlmICh0aGlzLmNvbXBhcmUocm93LCBjb2x1bW4pID09IDApIHsKICAgICAgICAgICAgaWYgKHRoaXMuaXNTdGFydChyb3csIGNvbHVtbikpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH07CiAgICB0aGlzLmNvbXBhcmUgPSBmdW5jdGlvbihyb3csIGNvbHVtbikgewogICAgICAgIGlmICghdGhpcy5pc011bHRpTGluZSgpKSB7CiAgICAgICAgICAgIGlmIChyb3cgPT09IHRoaXMuc3RhcnQucm93KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gY29sdW1uIDwgdGhpcy5zdGFydC5jb2x1bW4gPyAtMSA6IChjb2x1bW4gPiB0aGlzLmVuZC5jb2x1bW4gPyAxIDogMCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChyb3cgPCB0aGlzLnN0YXJ0LnJvdykKICAgICAgICAgICAgcmV0dXJuIC0xOwoKICAgICAgICBpZiAocm93ID4gdGhpcy5lbmQucm93KQogICAgICAgICAgICByZXR1cm4gMTsKCiAgICAgICAgaWYgKHRoaXMuc3RhcnQucm93ID09PSByb3cpCiAgICAgICAgICAgIHJldHVybiBjb2x1bW4gPj0gdGhpcy5zdGFydC5jb2x1bW4gPyAwIDogLTE7CgogICAgICAgIGlmICh0aGlzLmVuZC5yb3cgPT09IHJvdykKICAgICAgICAgICAgcmV0dXJuIGNvbHVtbiA8PSB0aGlzLmVuZC5jb2x1bW4gPyAwIDogMTsKCiAgICAgICAgcmV0dXJuIDA7CiAgICB9OwogICAgdGhpcy5jb21wYXJlU3RhcnQgPSBmdW5jdGlvbihyb3csIGNvbHVtbikgewogICAgICAgIGlmICh0aGlzLnN0YXJ0LnJvdyA9PSByb3cgJiYgdGhpcy5zdGFydC5jb2x1bW4gPT0gY29sdW1uKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gdGhpcy5jb21wYXJlKHJvdywgY29sdW1uKTsKICAgICAgICB9CiAgICB9OwogICAgdGhpcy5jb21wYXJlRW5kID0gZnVuY3Rpb24ocm93LCBjb2x1bW4pIHsKICAgICAgICBpZiAodGhpcy5lbmQucm93ID09IHJvdyAmJiB0aGlzLmVuZC5jb2x1bW4gPT0gY29sdW1uKSB7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbXBhcmUocm93LCBjb2x1bW4pOwogICAgICAgIH0KICAgIH07CiAgICB0aGlzLmNvbXBhcmVJbnNpZGUgPSBmdW5jdGlvbihyb3csIGNvbHVtbikgewogICAgICAgIGlmICh0aGlzLmVuZC5yb3cgPT0gcm93ICYmIHRoaXMuZW5kLmNvbHVtbiA9PSBjb2x1bW4pIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXJ0LnJvdyA9PSByb3cgJiYgdGhpcy5zdGFydC5jb2x1bW4gPT0gY29sdW1uKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gdGhpcy5jb21wYXJlKHJvdywgY29sdW1uKTsKICAgICAgICB9CiAgICB9OwogICAgdGhpcy5jbGlwUm93cyA9IGZ1bmN0aW9uKGZpcnN0Um93LCBsYXN0Um93KSB7CiAgICAgICAgaWYgKHRoaXMuZW5kLnJvdyA+IGxhc3RSb3cpCiAgICAgICAgICAgIHZhciBlbmQgPSB7cm93OiBsYXN0Um93ICsgMSwgY29sdW1uOiAwfTsKICAgICAgICBlbHNlIGlmICh0aGlzLmVuZC5yb3cgPCBmaXJzdFJvdykKICAgICAgICAgICAgdmFyIGVuZCA9IHtyb3c6IGZpcnN0Um93LCBjb2x1bW46IDB9OwoKICAgICAgICBpZiAodGhpcy5zdGFydC5yb3cgPiBsYXN0Um93KQogICAgICAgICAgICB2YXIgc3RhcnQgPSB7cm93OiBsYXN0Um93ICsgMSwgY29sdW1uOiAwfTsKICAgICAgICBlbHNlIGlmICh0aGlzLnN0YXJ0LnJvdyA8IGZpcnN0Um93KQogICAgICAgICAgICB2YXIgc3RhcnQgPSB7cm93OiBmaXJzdFJvdywgY29sdW1uOiAwfTsKCiAgICAgICAgcmV0dXJuIFJhbmdlLmZyb21Qb2ludHMoc3RhcnQgfHwgdGhpcy5zdGFydCwgZW5kIHx8IHRoaXMuZW5kKTsKICAgIH07CiAgICB0aGlzLmV4dGVuZCA9IGZ1bmN0aW9uKHJvdywgY29sdW1uKSB7CiAgICAgICAgdmFyIGNtcCA9IHRoaXMuY29tcGFyZShyb3csIGNvbHVtbik7CgogICAgICAgIGlmIChjbXAgPT0gMCkKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgZWxzZSBpZiAoY21wID09IC0xKQogICAgICAgICAgICB2YXIgc3RhcnQgPSB7cm93OiByb3csIGNvbHVtbjogY29sdW1ufTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHZhciBlbmQgPSB7cm93OiByb3csIGNvbHVtbjogY29sdW1ufTsKCiAgICAgICAgcmV0dXJuIFJhbmdlLmZyb21Qb2ludHMoc3RhcnQgfHwgdGhpcy5zdGFydCwgZW5kIHx8IHRoaXMuZW5kKTsKICAgIH07CgogICAgdGhpcy5pc0VtcHR5ID0gZnVuY3Rpb24oKSB7CiAgICAgICAgcmV0dXJuICh0aGlzLnN0YXJ0LnJvdyA9PT0gdGhpcy5lbmQucm93ICYmIHRoaXMuc3RhcnQuY29sdW1uID09PSB0aGlzLmVuZC5jb2x1bW4pOwogICAgfTsKICAgIHRoaXMuaXNNdWx0aUxpbmUgPSBmdW5jdGlvbigpIHsKICAgICAgICByZXR1cm4gKHRoaXMuc3RhcnQucm93ICE9PSB0aGlzLmVuZC5yb3cpOwogICAgfTsKICAgIHRoaXMuY2xvbmUgPSBmdW5jdGlvbigpIHsKICAgICAgICByZXR1cm4gUmFuZ2UuZnJvbVBvaW50cyh0aGlzLnN0YXJ0LCB0aGlzLmVuZCk7CiAgICB9OwogICAgdGhpcy5jb2xsYXBzZVJvd3MgPSBmdW5jdGlvbigpIHsKICAgICAgICBpZiAodGhpcy5lbmQuY29sdW1uID09IDApCiAgICAgICAgICAgIHJldHVybiBuZXcgUmFuZ2UodGhpcy5zdGFydC5yb3csIDAsIE1hdGgubWF4KHRoaXMuc3RhcnQucm93LCB0aGlzLmVuZC5yb3ctMSksIDApOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmV0dXJuIG5ldyBSYW5nZSh0aGlzLnN0YXJ0LnJvdywgMCwgdGhpcy5lbmQucm93LCAwKTsKICAgIH07CiAgICB0aGlzLnRvU2NyZWVuUmFuZ2UgPSBmdW5jdGlvbihzZXNzaW9uKSB7CiAgICAgICAgdmFyIHNjcmVlblBvc1N0YXJ0ID0gc2Vzc2lvbi5kb2N1bWVudFRvU2NyZWVuUG9zaXRpb24odGhpcy5zdGFydCk7CiAgICAgICAgdmFyIHNjcmVlblBvc0VuZCA9IHNlc3Npb24uZG9jdW1lbnRUb1NjcmVlblBvc2l0aW9uKHRoaXMuZW5kKTsKCiAgICAgICAgcmV0dXJuIG5ldyBSYW5nZSgKICAgICAgICAgICAgc2NyZWVuUG9zU3RhcnQucm93LCBzY3JlZW5Qb3NTdGFydC5jb2x1bW4sCiAgICAgICAgICAgIHNjcmVlblBvc0VuZC5yb3csIHNjcmVlblBvc0VuZC5jb2x1bW4KICAgICAgICApOwogICAgfTsKICAgIHRoaXMubW92ZUJ5ID0gZnVuY3Rpb24ocm93LCBjb2x1bW4pIHsKICAgICAgICB0aGlzLnN0YXJ0LnJvdyArPSByb3c7CiAgICAgICAgdGhpcy5zdGFydC5jb2x1bW4gKz0gY29sdW1uOwogICAgICAgIHRoaXMuZW5kLnJvdyArPSByb3c7CiAgICAgICAgdGhpcy5lbmQuY29sdW1uICs9IGNvbHVtbjsKICAgIH07Cgp9KS5jYWxsKFJhbmdlLnByb3RvdHlwZSk7ClJhbmdlLmZyb21Qb2ludHMgPSBmdW5jdGlvbihzdGFydCwgZW5kKSB7CiAgICByZXR1cm4gbmV3IFJhbmdlKHN0YXJ0LnJvdywgc3RhcnQuY29sdW1uLCBlbmQucm93LCBlbmQuY29sdW1uKTsKfTsKUmFuZ2UuY29tcGFyZVBvaW50cyA9IGNvbXBhcmVQb2ludHM7CgpSYW5nZS5jb21wYXJlUG9pbnRzID0gZnVuY3Rpb24ocDEsIHAyKSB7CiAgICByZXR1cm4gcDEucm93IC0gcDIucm93IHx8IHAxLmNvbHVtbiAtIHAyLmNvbHVtbjsKfTsKCgpleHBvcnRzLlJhbmdlID0gUmFuZ2U7Cn0pOwoKYWNlLmRlZmluZSgiYWNlL2FwcGx5X2RlbHRhIixbXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKSB7CiJ1c2Ugc3RyaWN0IjsKCmZ1bmN0aW9uIHRocm93RGVsdGFFcnJvcihkZWx0YSwgZXJyb3JUZXh0KXsKICAgIGNvbnNvbGUubG9nKCJJbnZhbGlkIERlbHRhOiIsIGRlbHRhKTsKICAgIHRocm93ICJJbnZhbGlkIERlbHRhOiAiICsgZXJyb3JUZXh0Owp9CgpmdW5jdGlvbiBwb3NpdGlvbkluRG9jdW1lbnQoZG9jTGluZXMsIHBvc2l0aW9uKSB7CiAgICByZXR1cm4gcG9zaXRpb24ucm93ICAgID49IDAgJiYgcG9zaXRpb24ucm93ICAgIDwgIGRvY0xpbmVzLmxlbmd0aCAmJgogICAgICAgICAgIHBvc2l0aW9uLmNvbHVtbiA+PSAwICYmIHBvc2l0aW9uLmNvbHVtbiA8PSBkb2NMaW5lc1twb3NpdGlvbi5yb3ddLmxlbmd0aDsKfQoKZnVuY3Rpb24gdmFsaWRhdGVEZWx0YShkb2NMaW5lcywgZGVsdGEpIHsKICAgIGlmIChkZWx0YS5hY3Rpb24gIT0gImluc2VydCIgJiYgZGVsdGEuYWN0aW9uICE9ICJyZW1vdmUiKQogICAgICAgIHRocm93RGVsdGFFcnJvcihkZWx0YSwgImRlbHRhLmFjdGlvbiBtdXN0IGJlICdpbnNlcnQnIG9yICdyZW1vdmUnIik7CiAgICBpZiAoIShkZWx0YS5saW5lcyBpbnN0YW5jZW9mIEFycmF5KSkKICAgICAgICB0aHJvd0RlbHRhRXJyb3IoZGVsdGEsICJkZWx0YS5saW5lcyBtdXN0IGJlIGFuIEFycmF5Iik7CiAgICBpZiAoIWRlbHRhLnN0YXJ0IHx8ICFkZWx0YS5lbmQpCiAgICAgICB0aHJvd0RlbHRhRXJyb3IoZGVsdGEsICJkZWx0YS5zdGFydC9lbmQgbXVzdCBiZSBhbiBwcmVzZW50Iik7CiAgICB2YXIgc3RhcnQgPSBkZWx0YS5zdGFydDsKICAgIGlmICghcG9zaXRpb25JbkRvY3VtZW50KGRvY0xpbmVzLCBkZWx0YS5zdGFydCkpCiAgICAgICAgdGhyb3dEZWx0YUVycm9yKGRlbHRhLCAiZGVsdGEuc3RhcnQgbXVzdCBiZSBjb250YWluZWQgaW4gZG9jdW1lbnQiKTsKICAgIHZhciBlbmQgPSBkZWx0YS5lbmQ7CiAgICBpZiAoZGVsdGEuYWN0aW9uID09ICJyZW1vdmUiICYmICFwb3NpdGlvbkluRG9jdW1lbnQoZG9jTGluZXMsIGVuZCkpCiAgICAgICAgdGhyb3dEZWx0YUVycm9yKGRlbHRhLCAiZGVsdGEuZW5kIG11c3QgY29udGFpbmVkIGluIGRvY3VtZW50IGZvciAncmVtb3ZlJyBhY3Rpb25zIik7CiAgICB2YXIgbnVtUmFuZ2VSb3dzID0gZW5kLnJvdyAtIHN0YXJ0LnJvdzsKICAgIHZhciBudW1SYW5nZUxhc3RMaW5lQ2hhcnMgPSAoZW5kLmNvbHVtbiAtIChudW1SYW5nZVJvd3MgPT0gMCA/IHN0YXJ0LmNvbHVtbiA6IDApKTsKICAgIGlmIChudW1SYW5nZVJvd3MgIT0gZGVsdGEubGluZXMubGVuZ3RoIC0gMSB8fCBkZWx0YS5saW5lc1tudW1SYW5nZVJvd3NdLmxlbmd0aCAhPSBudW1SYW5nZUxhc3RMaW5lQ2hhcnMpCiAgICAgICAgdGhyb3dEZWx0YUVycm9yKGRlbHRhLCAiZGVsdGEucmFuZ2UgbXVzdCBtYXRjaCBkZWx0YSBsaW5lcyIpOwp9CgpleHBvcnRzLmFwcGx5RGVsdGEgPSBmdW5jdGlvbihkb2NMaW5lcywgZGVsdGEsIGRvTm90VmFsaWRhdGUpIHsKICAgIAogICAgdmFyIHJvdyA9IGRlbHRhLnN0YXJ0LnJvdzsKICAgIHZhciBzdGFydENvbHVtbiA9IGRlbHRhLnN0YXJ0LmNvbHVtbjsKICAgIHZhciBsaW5lID0gZG9jTGluZXNbcm93XSB8fCAiIjsKICAgIHN3aXRjaCAoZGVsdGEuYWN0aW9uKSB7CiAgICAgICAgY2FzZSAiaW5zZXJ0IjoKICAgICAgICAgICAgdmFyIGxpbmVzID0gZGVsdGEubGluZXM7CiAgICAgICAgICAgIGlmIChsaW5lcy5sZW5ndGggPT09IDEpIHsKICAgICAgICAgICAgICAgIGRvY0xpbmVzW3Jvd10gPSBsaW5lLnN1YnN0cmluZygwLCBzdGFydENvbHVtbikgKyBkZWx0YS5saW5lc1swXSArIGxpbmUuc3Vic3RyaW5nKHN0YXJ0Q29sdW1uKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHZhciBhcmdzID0gW3JvdywgMV0uY29uY2F0KGRlbHRhLmxpbmVzKTsKICAgICAgICAgICAgICAgIGRvY0xpbmVzLnNwbGljZS5hcHBseShkb2NMaW5lcywgYXJncyk7CiAgICAgICAgICAgICAgICBkb2NMaW5lc1tyb3ddID0gbGluZS5zdWJzdHJpbmcoMCwgc3RhcnRDb2x1bW4pICsgZG9jTGluZXNbcm93XTsKICAgICAgICAgICAgICAgIGRvY0xpbmVzW3JvdyArIGRlbHRhLmxpbmVzLmxlbmd0aCAtIDFdICs9IGxpbmUuc3Vic3RyaW5nKHN0YXJ0Q29sdW1uKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICJyZW1vdmUiOgogICAgICAgICAgICB2YXIgZW5kQ29sdW1uID0gZGVsdGEuZW5kLmNvbHVtbjsKICAgICAgICAgICAgdmFyIGVuZFJvdyA9IGRlbHRhLmVuZC5yb3c7CiAgICAgICAgICAgIGlmIChyb3cgPT09IGVuZFJvdykgewogICAgICAgICAgICAgICAgZG9jTGluZXNbcm93XSA9IGxpbmUuc3Vic3RyaW5nKDAsIHN0YXJ0Q29sdW1uKSArIGxpbmUuc3Vic3RyaW5nKGVuZENvbHVtbik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBkb2NMaW5lcy5zcGxpY2UoCiAgICAgICAgICAgICAgICAgICAgcm93LCBlbmRSb3cgLSByb3cgKyAxLAogICAgICAgICAgICAgICAgICAgIGxpbmUuc3Vic3RyaW5nKDAsIHN0YXJ0Q29sdW1uKSArIGRvY0xpbmVzW2VuZFJvd10uc3Vic3RyaW5nKGVuZENvbHVtbikKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICB9Cn07Cn0pOwoKYWNlLmRlZmluZSgiYWNlL2xpYi9ldmVudF9lbWl0dGVyIixbXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKSB7CiJ1c2Ugc3RyaWN0IjsKCnZhciBFdmVudEVtaXR0ZXIgPSB7fTsKdmFyIHN0b3BQcm9wYWdhdGlvbiA9IGZ1bmN0aW9uKCkgeyB0aGlzLnByb3BhZ2F0aW9uU3RvcHBlZCA9IHRydWU7IH07CnZhciBwcmV2ZW50RGVmYXVsdCA9IGZ1bmN0aW9uKCkgeyB0aGlzLmRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlOyB9OwoKRXZlbnRFbWl0dGVyLl9lbWl0ID0KRXZlbnRFbWl0dGVyLl9kaXNwYXRjaEV2ZW50ID0gZnVuY3Rpb24oZXZlbnROYW1lLCBlKSB7CiAgICB0aGlzLl9ldmVudFJlZ2lzdHJ5IHx8ICh0aGlzLl9ldmVudFJlZ2lzdHJ5ID0ge30pOwogICAgdGhpcy5fZGVmYXVsdEhhbmRsZXJzIHx8ICh0aGlzLl9kZWZhdWx0SGFuZGxlcnMgPSB7fSk7CgogICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50UmVnaXN0cnlbZXZlbnROYW1lXSB8fCBbXTsKICAgIHZhciBkZWZhdWx0SGFuZGxlciA9IHRoaXMuX2RlZmF1bHRIYW5kbGVyc1tldmVudE5hbWVdOwogICAgaWYgKCFsaXN0ZW5lcnMubGVuZ3RoICYmICFkZWZhdWx0SGFuZGxlcikKICAgICAgICByZXR1cm47CgogICAgaWYgKHR5cGVvZiBlICE9ICJvYmplY3QiIHx8ICFlKQogICAgICAgIGUgPSB7fTsKCiAgICBpZiAoIWUudHlwZSkKICAgICAgICBlLnR5cGUgPSBldmVudE5hbWU7CiAgICBpZiAoIWUuc3RvcFByb3BhZ2F0aW9uKQogICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uID0gc3RvcFByb3BhZ2F0aW9uOwogICAgaWYgKCFlLnByZXZlbnREZWZhdWx0KQogICAgICAgIGUucHJldmVudERlZmF1bHQgPSBwcmV2ZW50RGVmYXVsdDsKCiAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMuc2xpY2UoKTsKICAgIGZvciAodmFyIGk9MDsgaTxsaXN0ZW5lcnMubGVuZ3RoOyBpKyspIHsKICAgICAgICBsaXN0ZW5lcnNbaV0oZSwgdGhpcyk7CiAgICAgICAgaWYgKGUucHJvcGFnYXRpb25TdG9wcGVkKQogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIAogICAgaWYgKGRlZmF1bHRIYW5kbGVyICYmICFlLmRlZmF1bHRQcmV2ZW50ZWQpCiAgICAgICAgcmV0dXJuIGRlZmF1bHRIYW5kbGVyKGUsIHRoaXMpOwp9OwoKCkV2ZW50RW1pdHRlci5fc2lnbmFsID0gZnVuY3Rpb24oZXZlbnROYW1lLCBlKSB7CiAgICB2YXIgbGlzdGVuZXJzID0gKHRoaXMuX2V2ZW50UmVnaXN0cnkgfHwge30pW2V2ZW50TmFtZV07CiAgICBpZiAoIWxpc3RlbmVycykKICAgICAgICByZXR1cm47CiAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMuc2xpY2UoKTsKICAgIGZvciAodmFyIGk9MDsgaTxsaXN0ZW5lcnMubGVuZ3RoOyBpKyspCiAgICAgICAgbGlzdGVuZXJzW2ldKGUsIHRoaXMpOwp9OwoKRXZlbnRFbWl0dGVyLm9uY2UgPSBmdW5jdGlvbihldmVudE5hbWUsIGNhbGxiYWNrKSB7CiAgICB2YXIgX3NlbGYgPSB0aGlzOwogICAgdGhpcy5vbihldmVudE5hbWUsIGZ1bmN0aW9uIG5ld0NhbGxiYWNrKCkgewogICAgICAgIF9zZWxmLm9mZihldmVudE5hbWUsIG5ld0NhbGxiYWNrKTsKICAgICAgICBjYWxsYmFjay5hcHBseShudWxsLCBhcmd1bWVudHMpOwogICAgfSk7CiAgICBpZiAoIWNhbGxiYWNrKSB7CiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUpIHsKICAgICAgICAgICAgY2FsbGJhY2sgPSByZXNvbHZlOwogICAgICAgIH0pOwogICAgfQp9OwoKCkV2ZW50RW1pdHRlci5zZXREZWZhdWx0SGFuZGxlciA9IGZ1bmN0aW9uKGV2ZW50TmFtZSwgY2FsbGJhY2spIHsKICAgIHZhciBoYW5kbGVycyA9IHRoaXMuX2RlZmF1bHRIYW5kbGVyczsKICAgIGlmICghaGFuZGxlcnMpCiAgICAgICAgaGFuZGxlcnMgPSB0aGlzLl9kZWZhdWx0SGFuZGxlcnMgPSB7X2Rpc2FibGVkXzoge319OwogICAgCiAgICBpZiAoaGFuZGxlcnNbZXZlbnROYW1lXSkgewogICAgICAgIHZhciBvbGQgPSBoYW5kbGVyc1tldmVudE5hbWVdOwogICAgICAgIHZhciBkaXNhYmxlZCA9IGhhbmRsZXJzLl9kaXNhYmxlZF9bZXZlbnROYW1lXTsKICAgICAgICBpZiAoIWRpc2FibGVkKQogICAgICAgICAgICBoYW5kbGVycy5fZGlzYWJsZWRfW2V2ZW50TmFtZV0gPSBkaXNhYmxlZCA9IFtdOwogICAgICAgIGRpc2FibGVkLnB1c2gob2xkKTsKICAgICAgICB2YXIgaSA9IGRpc2FibGVkLmluZGV4T2YoY2FsbGJhY2spOwogICAgICAgIGlmIChpICE9IC0xKSAKICAgICAgICAgICAgZGlzYWJsZWQuc3BsaWNlKGksIDEpOwogICAgfQogICAgaGFuZGxlcnNbZXZlbnROYW1lXSA9IGNhbGxiYWNrOwp9OwpFdmVudEVtaXR0ZXIucmVtb3ZlRGVmYXVsdEhhbmRsZXIgPSBmdW5jdGlvbihldmVudE5hbWUsIGNhbGxiYWNrKSB7CiAgICB2YXIgaGFuZGxlcnMgPSB0aGlzLl9kZWZhdWx0SGFuZGxlcnM7CiAgICBpZiAoIWhhbmRsZXJzKQogICAgICAgIHJldHVybjsKICAgIHZhciBkaXNhYmxlZCA9IGhhbmRsZXJzLl9kaXNhYmxlZF9bZXZlbnROYW1lXTsKICAgIAogICAgaWYgKGhhbmRsZXJzW2V2ZW50TmFtZV0gPT0gY2FsbGJhY2spIHsKICAgICAgICBpZiAoZGlzYWJsZWQpCiAgICAgICAgICAgIHRoaXMuc2V0RGVmYXVsdEhhbmRsZXIoZXZlbnROYW1lLCBkaXNhYmxlZC5wb3AoKSk7CiAgICB9IGVsc2UgaWYgKGRpc2FibGVkKSB7CiAgICAgICAgdmFyIGkgPSBkaXNhYmxlZC5pbmRleE9mKGNhbGxiYWNrKTsKICAgICAgICBpZiAoaSAhPSAtMSkKICAgICAgICAgICAgZGlzYWJsZWQuc3BsaWNlKGksIDEpOwogICAgfQp9OwoKRXZlbnRFbWl0dGVyLm9uID0KRXZlbnRFbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbihldmVudE5hbWUsIGNhbGxiYWNrLCBjYXB0dXJpbmcpIHsKICAgIHRoaXMuX2V2ZW50UmVnaXN0cnkgPSB0aGlzLl9ldmVudFJlZ2lzdHJ5IHx8IHt9OwoKICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudFJlZ2lzdHJ5W2V2ZW50TmFtZV07CiAgICBpZiAoIWxpc3RlbmVycykKICAgICAgICBsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudFJlZ2lzdHJ5W2V2ZW50TmFtZV0gPSBbXTsKCiAgICBpZiAobGlzdGVuZXJzLmluZGV4T2YoY2FsbGJhY2spID09IC0xKQogICAgICAgIGxpc3RlbmVyc1tjYXB0dXJpbmcgPyAidW5zaGlmdCIgOiAicHVzaCJdKGNhbGxiYWNrKTsKICAgIHJldHVybiBjYWxsYmFjazsKfTsKCkV2ZW50RW1pdHRlci5vZmYgPQpFdmVudEVtaXR0ZXIucmVtb3ZlTGlzdGVuZXIgPQpFdmVudEVtaXR0ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50TmFtZSwgY2FsbGJhY2spIHsKICAgIHRoaXMuX2V2ZW50UmVnaXN0cnkgPSB0aGlzLl9ldmVudFJlZ2lzdHJ5IHx8IHt9OwoKICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudFJlZ2lzdHJ5W2V2ZW50TmFtZV07CiAgICBpZiAoIWxpc3RlbmVycykKICAgICAgICByZXR1cm47CgogICAgdmFyIGluZGV4ID0gbGlzdGVuZXJzLmluZGV4T2YoY2FsbGJhY2spOwogICAgaWYgKGluZGV4ICE9PSAtMSkKICAgICAgICBsaXN0ZW5lcnMuc3BsaWNlKGluZGV4LCAxKTsKfTsKCkV2ZW50RW1pdHRlci5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbihldmVudE5hbWUpIHsKICAgIGlmICghZXZlbnROYW1lKSB0aGlzLl9ldmVudFJlZ2lzdHJ5ID0gdGhpcy5fZGVmYXVsdEhhbmRsZXJzID0gdW5kZWZpbmVkOwogICAgaWYgKHRoaXMuX2V2ZW50UmVnaXN0cnkpIHRoaXMuX2V2ZW50UmVnaXN0cnlbZXZlbnROYW1lXSA9IHVuZGVmaW5lZDsKICAgIGlmICh0aGlzLl9kZWZhdWx0SGFuZGxlcnMpIHRoaXMuX2RlZmF1bHRIYW5kbGVyc1tldmVudE5hbWVdID0gdW5kZWZpbmVkOwp9OwoKZXhwb3J0cy5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9hbmNob3IiLFtdLCBmdW5jdGlvbihyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpIHsKInVzZSBzdHJpY3QiOwoKdmFyIG9vcCA9IHJlcXVpcmUoIi4vbGliL29vcCIpOwp2YXIgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgiLi9saWIvZXZlbnRfZW1pdHRlciIpLkV2ZW50RW1pdHRlcjsKCnZhciBBbmNob3IgPSBleHBvcnRzLkFuY2hvciA9IGZ1bmN0aW9uKGRvYywgcm93LCBjb2x1bW4pIHsKICAgIHRoaXMuJG9uQ2hhbmdlID0gdGhpcy5vbkNoYW5nZS5iaW5kKHRoaXMpOwogICAgdGhpcy5hdHRhY2goZG9jKTsKICAgIAogICAgaWYgKHR5cGVvZiBjb2x1bW4gPT0gInVuZGVmaW5lZCIpCiAgICAgICAgdGhpcy5zZXRQb3NpdGlvbihyb3cucm93LCByb3cuY29sdW1uKTsKICAgIGVsc2UKICAgICAgICB0aGlzLnNldFBvc2l0aW9uKHJvdywgY29sdW1uKTsKfTsKCihmdW5jdGlvbigpIHsKCiAgICBvb3AuaW1wbGVtZW50KHRoaXMsIEV2ZW50RW1pdHRlcik7CiAgICB0aGlzLmdldFBvc2l0aW9uID0gZnVuY3Rpb24oKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJGNsaXBQb3NpdGlvblRvRG9jdW1lbnQodGhpcy5yb3csIHRoaXMuY29sdW1uKTsKICAgIH07CiAgICB0aGlzLmdldERvY3VtZW50ID0gZnVuY3Rpb24oKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuZG9jdW1lbnQ7CiAgICB9OwogICAgdGhpcy4kaW5zZXJ0UmlnaHQgPSBmYWxzZTsKICAgIHRoaXMub25DaGFuZ2UgPSBmdW5jdGlvbihkZWx0YSkgewogICAgICAgIGlmIChkZWx0YS5zdGFydC5yb3cgPT0gZGVsdGEuZW5kLnJvdyAmJiBkZWx0YS5zdGFydC5yb3cgIT0gdGhpcy5yb3cpCiAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgaWYgKGRlbHRhLnN0YXJ0LnJvdyA+IHRoaXMucm93KQogICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIAogICAgICAgIHZhciBwb2ludCA9ICRnZXRUcmFuc2Zvcm1lZFBvaW50KGRlbHRhLCB7cm93OiB0aGlzLnJvdywgY29sdW1uOiB0aGlzLmNvbHVtbn0sIHRoaXMuJGluc2VydFJpZ2h0KTsKICAgICAgICB0aGlzLnNldFBvc2l0aW9uKHBvaW50LnJvdywgcG9pbnQuY29sdW1uLCB0cnVlKTsKICAgIH07CiAgICAKICAgIGZ1bmN0aW9uICRwb2ludHNJbk9yZGVyKHBvaW50MSwgcG9pbnQyLCBlcXVhbFBvaW50c0luT3JkZXIpIHsKICAgICAgICB2YXIgYkNvbElzQWZ0ZXIgPSBlcXVhbFBvaW50c0luT3JkZXIgPyBwb2ludDEuY29sdW1uIDw9IHBvaW50Mi5jb2x1bW4gOiBwb2ludDEuY29sdW1uIDwgcG9pbnQyLmNvbHVtbjsKICAgICAgICByZXR1cm4gKHBvaW50MS5yb3cgPCBwb2ludDIucm93KSB8fCAocG9pbnQxLnJvdyA9PSBwb2ludDIucm93ICYmIGJDb2xJc0FmdGVyKTsKICAgIH0KICAgICAgICAgICAgCiAgICBmdW5jdGlvbiAkZ2V0VHJhbnNmb3JtZWRQb2ludChkZWx0YSwgcG9pbnQsIG1vdmVJZkVxdWFsKSB7CiAgICAgICAgdmFyIGRlbHRhSXNJbnNlcnQgPSBkZWx0YS5hY3Rpb24gPT0gImluc2VydCI7CiAgICAgICAgdmFyIGRlbHRhUm93U2hpZnQgPSAoZGVsdGFJc0luc2VydCA/IDEgOiAtMSkgKiAoZGVsdGEuZW5kLnJvdyAgICAtIGRlbHRhLnN0YXJ0LnJvdyk7CiAgICAgICAgdmFyIGRlbHRhQ29sU2hpZnQgPSAoZGVsdGFJc0luc2VydCA/IDEgOiAtMSkgKiAoZGVsdGEuZW5kLmNvbHVtbiAtIGRlbHRhLnN0YXJ0LmNvbHVtbik7CiAgICAgICAgdmFyIGRlbHRhU3RhcnQgPSBkZWx0YS5zdGFydDsKICAgICAgICB2YXIgZGVsdGFFbmQgPSBkZWx0YUlzSW5zZXJ0ID8gZGVsdGFTdGFydCA6IGRlbHRhLmVuZDsgLy8gQ29sbGFwc2UgaW5zZXJ0IHJhbmdlLgogICAgICAgIGlmICgkcG9pbnRzSW5PcmRlcihwb2ludCwgZGVsdGFTdGFydCwgbW92ZUlmRXF1YWwpKSB7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICByb3c6IHBvaW50LnJvdywKICAgICAgICAgICAgICAgIGNvbHVtbjogcG9pbnQuY29sdW1uCiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGlmICgkcG9pbnRzSW5PcmRlcihkZWx0YUVuZCwgcG9pbnQsICFtb3ZlSWZFcXVhbCkpIHsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgIHJvdzogcG9pbnQucm93ICsgZGVsdGFSb3dTaGlmdCwKICAgICAgICAgICAgICAgIGNvbHVtbjogcG9pbnQuY29sdW1uICsgKHBvaW50LnJvdyA9PSBkZWx0YUVuZC5yb3cgPyBkZWx0YUNvbFNoaWZ0IDogMCkKICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgcm93OiBkZWx0YVN0YXJ0LnJvdywKICAgICAgICAgICAgY29sdW1uOiBkZWx0YVN0YXJ0LmNvbHVtbgogICAgICAgIH07CiAgICB9CiAgICB0aGlzLnNldFBvc2l0aW9uID0gZnVuY3Rpb24ocm93LCBjb2x1bW4sIG5vQ2xpcCkgewogICAgICAgIHZhciBwb3M7CiAgICAgICAgaWYgKG5vQ2xpcCkgewogICAgICAgICAgICBwb3MgPSB7CiAgICAgICAgICAgICAgICByb3c6IHJvdywKICAgICAgICAgICAgICAgIGNvbHVtbjogY29sdW1uCiAgICAgICAgICAgIH07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcG9zID0gdGhpcy4kY2xpcFBvc2l0aW9uVG9Eb2N1bWVudChyb3csIGNvbHVtbik7CiAgICAgICAgfQoKICAgICAgICBpZiAodGhpcy5yb3cgPT0gcG9zLnJvdyAmJiB0aGlzLmNvbHVtbiA9PSBwb3MuY29sdW1uKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgIHZhciBvbGQgPSB7CiAgICAgICAgICAgIHJvdzogdGhpcy5yb3csCiAgICAgICAgICAgIGNvbHVtbjogdGhpcy5jb2x1bW4KICAgICAgICB9OwoKICAgICAgICB0aGlzLnJvdyA9IHBvcy5yb3c7CiAgICAgICAgdGhpcy5jb2x1bW4gPSBwb3MuY29sdW1uOwogICAgICAgIHRoaXMuX3NpZ25hbCgiY2hhbmdlIiwgewogICAgICAgICAgICBvbGQ6IG9sZCwKICAgICAgICAgICAgdmFsdWU6IHBvcwogICAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuZGV0YWNoID0gZnVuY3Rpb24oKSB7CiAgICAgICAgdGhpcy5kb2N1bWVudC5vZmYoImNoYW5nZSIsIHRoaXMuJG9uQ2hhbmdlKTsKICAgIH07CiAgICB0aGlzLmF0dGFjaCA9IGZ1bmN0aW9uKGRvYykgewogICAgICAgIHRoaXMuZG9jdW1lbnQgPSBkb2MgfHwgdGhpcy5kb2N1bWVudDsKICAgICAgICB0aGlzLmRvY3VtZW50Lm9uKCJjaGFuZ2UiLCB0aGlzLiRvbkNoYW5nZSk7CiAgICB9OwogICAgdGhpcy4kY2xpcFBvc2l0aW9uVG9Eb2N1bWVudCA9IGZ1bmN0aW9uKHJvdywgY29sdW1uKSB7CiAgICAgICAgdmFyIHBvcyA9IHt9OwoKICAgICAgICBpZiAocm93ID49IHRoaXMuZG9jdW1lbnQuZ2V0TGVuZ3RoKCkpIHsKICAgICAgICAgICAgcG9zLnJvdyA9IE1hdGgubWF4KDAsIHRoaXMuZG9jdW1lbnQuZ2V0TGVuZ3RoKCkgLSAxKTsKICAgICAgICAgICAgcG9zLmNvbHVtbiA9IHRoaXMuZG9jdW1lbnQuZ2V0TGluZShwb3Mucm93KS5sZW5ndGg7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHJvdyA8IDApIHsKICAgICAgICAgICAgcG9zLnJvdyA9IDA7CiAgICAgICAgICAgIHBvcy5jb2x1bW4gPSAwOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgcG9zLnJvdyA9IHJvdzsKICAgICAgICAgICAgcG9zLmNvbHVtbiA9IE1hdGgubWluKHRoaXMuZG9jdW1lbnQuZ2V0TGluZShwb3Mucm93KS5sZW5ndGgsIE1hdGgubWF4KDAsIGNvbHVtbikpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGNvbHVtbiA8IDApCiAgICAgICAgICAgIHBvcy5jb2x1bW4gPSAwOwoKICAgICAgICByZXR1cm4gcG9zOwogICAgfTsKCn0pLmNhbGwoQW5jaG9yLnByb3RvdHlwZSk7Cgp9KTsKCmFjZS5kZWZpbmUoImFjZS9kb2N1bWVudCIsW10sIGZ1bmN0aW9uKHJlcXVpcmUsIGV4cG9ydHMsIG1vZHVsZSkgewoidXNlIHN0cmljdCI7Cgp2YXIgb29wID0gcmVxdWlyZSgiLi9saWIvb29wIik7CnZhciBhcHBseURlbHRhID0gcmVxdWlyZSgiLi9hcHBseV9kZWx0YSIpLmFwcGx5RGVsdGE7CnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCIuL2xpYi9ldmVudF9lbWl0dGVyIikuRXZlbnRFbWl0dGVyOwp2YXIgUmFuZ2UgPSByZXF1aXJlKCIuL3JhbmdlIikuUmFuZ2U7CnZhciBBbmNob3IgPSByZXF1aXJlKCIuL2FuY2hvciIpLkFuY2hvcjsKCnZhciBEb2N1bWVudCA9IGZ1bmN0aW9uKHRleHRPckxpbmVzKSB7CiAgICB0aGlzLiRsaW5lcyA9IFsiIl07CiAgICBpZiAodGV4dE9yTGluZXMubGVuZ3RoID09PSAwKSB7CiAgICAgICAgdGhpcy4kbGluZXMgPSBbIiJdOwogICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHRleHRPckxpbmVzKSkgewogICAgICAgIHRoaXMuaW5zZXJ0TWVyZ2VkTGluZXMoe3JvdzogMCwgY29sdW1uOiAwfSwgdGV4dE9yTGluZXMpOwogICAgfSBlbHNlIHsKICAgICAgICB0aGlzLmluc2VydCh7cm93OiAwLCBjb2x1bW46MH0sIHRleHRPckxpbmVzKTsKICAgIH0KfTsKCihmdW5jdGlvbigpIHsKCiAgICBvb3AuaW1wbGVtZW50KHRoaXMsIEV2ZW50RW1pdHRlcik7CiAgICB0aGlzLnNldFZhbHVlID0gZnVuY3Rpb24odGV4dCkgewogICAgICAgIHZhciBsZW4gPSB0aGlzLmdldExlbmd0aCgpIC0gMTsKICAgICAgICB0aGlzLnJlbW92ZShuZXcgUmFuZ2UoMCwgMCwgbGVuLCB0aGlzLmdldExpbmUobGVuKS5sZW5ndGgpKTsKICAgICAgICB0aGlzLmluc2VydCh7cm93OiAwLCBjb2x1bW46IDB9LCB0ZXh0KTsKICAgIH07CiAgICB0aGlzLmdldFZhbHVlID0gZnVuY3Rpb24oKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QWxsTGluZXMoKS5qb2luKHRoaXMuZ2V0TmV3TGluZUNoYXJhY3RlcigpKTsKICAgIH07CiAgICB0aGlzLmNyZWF0ZUFuY2hvciA9IGZ1bmN0aW9uKHJvdywgY29sdW1uKSB7CiAgICAgICAgcmV0dXJuIG5ldyBBbmNob3IodGhpcywgcm93LCBjb2x1bW4pOwogICAgfTsKICAgIGlmICgiYWFhIi5zcGxpdCgvYS8pLmxlbmd0aCA9PT0gMCkgewogICAgICAgIHRoaXMuJHNwbGl0ID0gZnVuY3Rpb24odGV4dCkgewogICAgICAgICAgICByZXR1cm4gdGV4dC5yZXBsYWNlKC9cclxufFxyL2csICJcbiIpLnNwbGl0KCJcbiIpOwogICAgICAgIH07CiAgICB9IGVsc2UgewogICAgICAgIHRoaXMuJHNwbGl0ID0gZnVuY3Rpb24odGV4dCkgewogICAgICAgICAgICByZXR1cm4gdGV4dC5zcGxpdCgvXHJcbnxccnxcbi8pOwogICAgICAgIH07CiAgICB9CgoKICAgIHRoaXMuJGRldGVjdE5ld0xpbmUgPSBmdW5jdGlvbih0ZXh0KSB7CiAgICAgICAgdmFyIG1hdGNoID0gdGV4dC5tYXRjaCgvXi4qPyhcclxufFxyfFxuKS9tKTsKICAgICAgICB0aGlzLiRhdXRvTmV3TGluZSA9IG1hdGNoID8gbWF0Y2hbMV0gOiAiXG4iOwogICAgICAgIHRoaXMuX3NpZ25hbCgiY2hhbmdlTmV3TGluZU1vZGUiKTsKICAgIH07CiAgICB0aGlzLmdldE5ld0xpbmVDaGFyYWN0ZXIgPSBmdW5jdGlvbigpIHsKICAgICAgICBzd2l0Y2ggKHRoaXMuJG5ld0xpbmVNb2RlKSB7CiAgICAgICAgICBjYXNlICJ3aW5kb3dzIjoKICAgICAgICAgICAgcmV0dXJuICJcclxuIjsKICAgICAgICAgIGNhc2UgInVuaXgiOgogICAgICAgICAgICByZXR1cm4gIlxuIjsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiB0aGlzLiRhdXRvTmV3TGluZSB8fCAiXG4iOwogICAgICAgIH0KICAgIH07CgogICAgdGhpcy4kYXV0b05ld0xpbmUgPSAiIjsKICAgIHRoaXMuJG5ld0xpbmVNb2RlID0gImF1dG8iOwogICAgdGhpcy5zZXROZXdMaW5lTW9kZSA9IGZ1bmN0aW9uKG5ld0xpbmVNb2RlKSB7CiAgICAgICAgaWYgKHRoaXMuJG5ld0xpbmVNb2RlID09PSBuZXdMaW5lTW9kZSkKICAgICAgICAgICAgcmV0dXJuOwoKICAgICAgICB0aGlzLiRuZXdMaW5lTW9kZSA9IG5ld0xpbmVNb2RlOwogICAgICAgIHRoaXMuX3NpZ25hbCgiY2hhbmdlTmV3TGluZU1vZGUiKTsKICAgIH07CiAgICB0aGlzLmdldE5ld0xpbmVNb2RlID0gZnVuY3Rpb24oKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJG5ld0xpbmVNb2RlOwogICAgfTsKICAgIHRoaXMuaXNOZXdMaW5lID0gZnVuY3Rpb24odGV4dCkgewogICAgICAgIHJldHVybiAodGV4dCA9PSAiXHJcbiIgfHwgdGV4dCA9PSAiXHIiIHx8IHRleHQgPT0gIlxuIik7CiAgICB9OwogICAgdGhpcy5nZXRMaW5lID0gZnVuY3Rpb24ocm93KSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJGxpbmVzW3Jvd10gfHwgIiI7CiAgICB9OwogICAgdGhpcy5nZXRMaW5lcyA9IGZ1bmN0aW9uKGZpcnN0Um93LCBsYXN0Um93KSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJGxpbmVzLnNsaWNlKGZpcnN0Um93LCBsYXN0Um93ICsgMSk7CiAgICB9OwogICAgdGhpcy5nZXRBbGxMaW5lcyA9IGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiB0aGlzLmdldExpbmVzKDAsIHRoaXMuZ2V0TGVuZ3RoKCkpOwogICAgfTsKICAgIHRoaXMuZ2V0TGVuZ3RoID0gZnVuY3Rpb24oKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuJGxpbmVzLmxlbmd0aDsKICAgIH07CiAgICB0aGlzLmdldFRleHRSYW5nZSA9IGZ1bmN0aW9uKHJhbmdlKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TGluZXNGb3JSYW5nZShyYW5nZSkuam9pbih0aGlzLmdldE5ld0xpbmVDaGFyYWN0ZXIoKSk7CiAgICB9OwogICAgdGhpcy5nZXRMaW5lc0ZvclJhbmdlID0gZnVuY3Rpb24ocmFuZ2UpIHsKICAgICAgICB2YXIgbGluZXM7CiAgICAgICAgaWYgKHJhbmdlLnN0YXJ0LnJvdyA9PT0gcmFuZ2UuZW5kLnJvdykgewogICAgICAgICAgICBsaW5lcyA9IFt0aGlzLmdldExpbmUocmFuZ2Uuc3RhcnQucm93KS5zdWJzdHJpbmcocmFuZ2Uuc3RhcnQuY29sdW1uLCByYW5nZS5lbmQuY29sdW1uKV07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGluZXMgPSB0aGlzLmdldExpbmVzKHJhbmdlLnN0YXJ0LnJvdywgcmFuZ2UuZW5kLnJvdyk7CiAgICAgICAgICAgIGxpbmVzWzBdID0gKGxpbmVzWzBdIHx8ICIiKS5zdWJzdHJpbmcocmFuZ2Uuc3RhcnQuY29sdW1uKTsKICAgICAgICAgICAgdmFyIGwgPSBsaW5lcy5sZW5ndGggLSAxOwogICAgICAgICAgICBpZiAocmFuZ2UuZW5kLnJvdyAtIHJhbmdlLnN0YXJ0LnJvdyA9PSBsKQogICAgICAgICAgICAgICAgbGluZXNbbF0gPSBsaW5lc1tsXS5zdWJzdHJpbmcoMCwgcmFuZ2UuZW5kLmNvbHVtbik7CiAgICAgICAgfQogICAgICAgIHJldHVybiBsaW5lczsKICAgIH07CiAgICB0aGlzLmluc2VydExpbmVzID0gZnVuY3Rpb24ocm93LCBsaW5lcykgewogICAgICAgIGNvbnNvbGUud2FybigiVXNlIG9mIGRvY3VtZW50Lmluc2VydExpbmVzIGlzIGRlcHJlY2F0ZWQuIFVzZSB0aGUgaW5zZXJ0RnVsbExpbmVzIG1ldGhvZCBpbnN0ZWFkLiIpOwogICAgICAgIHJldHVybiB0aGlzLmluc2VydEZ1bGxMaW5lcyhyb3csIGxpbmVzKTsKICAgIH07CiAgICB0aGlzLnJlbW92ZUxpbmVzID0gZnVuY3Rpb24oZmlyc3RSb3csIGxhc3RSb3cpIHsKICAgICAgICBjb25zb2xlLndhcm4oIlVzZSBvZiBkb2N1bWVudC5yZW1vdmVMaW5lcyBpcyBkZXByZWNhdGVkLiBVc2UgdGhlIHJlbW92ZUZ1bGxMaW5lcyBtZXRob2QgaW5zdGVhZC4iKTsKICAgICAgICByZXR1cm4gdGhpcy5yZW1vdmVGdWxsTGluZXMoZmlyc3RSb3csIGxhc3RSb3cpOwogICAgfTsKICAgIHRoaXMuaW5zZXJ0TmV3TGluZSA9IGZ1bmN0aW9uKHBvc2l0aW9uKSB7CiAgICAgICAgY29uc29sZS53YXJuKCJVc2Ugb2YgZG9jdW1lbnQuaW5zZXJ0TmV3TGluZSBpcyBkZXByZWNhdGVkLiBVc2UgaW5zZXJ0TWVyZ2VkTGluZXMocG9zaXRpb24sIFsnJywgJyddKSBpbnN0ZWFkLiIpOwogICAgICAgIHJldHVybiB0aGlzLmluc2VydE1lcmdlZExpbmVzKHBvc2l0aW9uLCBbIiIsICIiXSk7CiAgICB9OwogICAgdGhpcy5pbnNlcnQgPSBmdW5jdGlvbihwb3NpdGlvbiwgdGV4dCkgewogICAgICAgIGlmICh0aGlzLmdldExlbmd0aCgpIDw9IDEpCiAgICAgICAgICAgIHRoaXMuJGRldGVjdE5ld0xpbmUodGV4dCk7CiAgICAgICAgCiAgICAgICAgcmV0dXJuIHRoaXMuaW5zZXJ0TWVyZ2VkTGluZXMocG9zaXRpb24sIHRoaXMuJHNwbGl0KHRleHQpKTsKICAgIH07CiAgICB0aGlzLmluc2VydEluTGluZSA9IGZ1bmN0aW9uKHBvc2l0aW9uLCB0ZXh0KSB7CiAgICAgICAgdmFyIHN0YXJ0ID0gdGhpcy5jbGlwcGVkUG9zKHBvc2l0aW9uLnJvdywgcG9zaXRpb24uY29sdW1uKTsKICAgICAgICB2YXIgZW5kID0gdGhpcy5wb3MocG9zaXRpb24ucm93LCBwb3NpdGlvbi5jb2x1bW4gKyB0ZXh0Lmxlbmd0aCk7CiAgICAgICAgCiAgICAgICAgdGhpcy5hcHBseURlbHRhKHsKICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0LAogICAgICAgICAgICBlbmQ6IGVuZCwKICAgICAgICAgICAgYWN0aW9uOiAiaW5zZXJ0IiwKICAgICAgICAgICAgbGluZXM6IFt0ZXh0XQogICAgICAgIH0sIHRydWUpOwogICAgICAgIAogICAgICAgIHJldHVybiB0aGlzLmNsb25lUG9zKGVuZCk7CiAgICB9OwogICAgCiAgICB0aGlzLmNsaXBwZWRQb3MgPSBmdW5jdGlvbihyb3csIGNvbHVtbikgewogICAgICAgIHZhciBsZW5ndGggPSB0aGlzLmdldExlbmd0aCgpOwogICAgICAgIGlmIChyb3cgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICByb3cgPSBsZW5ndGg7CiAgICAgICAgfSBlbHNlIGlmIChyb3cgPCAwKSB7CiAgICAgICAgICAgIHJvdyA9IDA7CiAgICAgICAgfSBlbHNlIGlmIChyb3cgPj0gbGVuZ3RoKSB7CiAgICAgICAgICAgIHJvdyA9IGxlbmd0aCAtIDE7CiAgICAgICAgICAgIGNvbHVtbiA9IHVuZGVmaW5lZDsKICAgICAgICB9CiAgICAgICAgdmFyIGxpbmUgPSB0aGlzLmdldExpbmUocm93KTsKICAgICAgICBpZiAoY29sdW1uID09IHVuZGVmaW5lZCkKICAgICAgICAgICAgY29sdW1uID0gbGluZS5sZW5ndGg7CiAgICAgICAgY29sdW1uID0gTWF0aC5taW4oTWF0aC5tYXgoY29sdW1uLCAwKSwgbGluZS5sZW5ndGgpOwogICAgICAgIHJldHVybiB7cm93OiByb3csIGNvbHVtbjogY29sdW1ufTsKICAgIH07CiAgICAKICAgIHRoaXMuY2xvbmVQb3MgPSBmdW5jdGlvbihwb3MpIHsKICAgICAgICByZXR1cm4ge3JvdzogcG9zLnJvdywgY29sdW1uOiBwb3MuY29sdW1ufTsKICAgIH07CiAgICAKICAgIHRoaXMucG9zID0gZnVuY3Rpb24ocm93LCBjb2x1bW4pIHsKICAgICAgICByZXR1cm4ge3Jvdzogcm93LCBjb2x1bW46IGNvbHVtbn07CiAgICB9OwogICAgCiAgICB0aGlzLiRjbGlwUG9zaXRpb24gPSBmdW5jdGlvbihwb3NpdGlvbikgewogICAgICAgIHZhciBsZW5ndGggPSB0aGlzLmdldExlbmd0aCgpOwogICAgICAgIGlmIChwb3NpdGlvbi5yb3cgPj0gbGVuZ3RoKSB7CiAgICAgICAgICAgIHBvc2l0aW9uLnJvdyA9IE1hdGgubWF4KDAsIGxlbmd0aCAtIDEpOwogICAgICAgICAgICBwb3NpdGlvbi5jb2x1bW4gPSB0aGlzLmdldExpbmUobGVuZ3RoIC0gMSkubGVuZ3RoOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHBvc2l0aW9uLnJvdyA9IE1hdGgubWF4KDAsIHBvc2l0aW9uLnJvdyk7CiAgICAgICAgICAgIHBvc2l0aW9uLmNvbHVtbiA9IE1hdGgubWluKE1hdGgubWF4KHBvc2l0aW9uLmNvbHVtbiwgMCksIHRoaXMuZ2V0TGluZShwb3NpdGlvbi5yb3cpLmxlbmd0aCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwb3NpdGlvbjsKICAgIH07CiAgICB0aGlzLmluc2VydEZ1bGxMaW5lcyA9IGZ1bmN0aW9uKHJvdywgbGluZXMpIHsKICAgICAgICByb3cgPSBNYXRoLm1pbihNYXRoLm1heChyb3csIDApLCB0aGlzLmdldExlbmd0aCgpKTsKICAgICAgICB2YXIgY29sdW1uID0gMDsKICAgICAgICBpZiAocm93IDwgdGhpcy5nZXRMZW5ndGgoKSkgewogICAgICAgICAgICBsaW5lcyA9IGxpbmVzLmNvbmNhdChbIiJdKTsKICAgICAgICAgICAgY29sdW1uID0gMDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBsaW5lcyA9IFsiIl0uY29uY2F0KGxpbmVzKTsKICAgICAgICAgICAgcm93LS07CiAgICAgICAgICAgIGNvbHVtbiA9IHRoaXMuJGxpbmVzW3Jvd10ubGVuZ3RoOwogICAgICAgIH0KICAgICAgICB0aGlzLmluc2VydE1lcmdlZExpbmVzKHtyb3c6IHJvdywgY29sdW1uOiBjb2x1bW59LCBsaW5lcyk7CiAgICB9OyAgICAKICAgIHRoaXMuaW5zZXJ0TWVyZ2VkTGluZXMgPSBmdW5jdGlvbihwb3NpdGlvbiwgbGluZXMpIHsKICAgICAgICB2YXIgc3RhcnQgPSB0aGlzLmNsaXBwZWRQb3MocG9zaXRpb24ucm93LCBwb3NpdGlvbi5jb2x1bW4pOwogICAgICAgIHZhciBlbmQgPSB7CiAgICAgICAgICAgIHJvdzogc3RhcnQucm93ICsgbGluZXMubGVuZ3RoIC0gMSwKICAgICAgICAgICAgY29sdW1uOiAobGluZXMubGVuZ3RoID09IDEgPyBzdGFydC5jb2x1bW4gOiAwKSArIGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdLmxlbmd0aAogICAgICAgIH07CiAgICAgICAgCiAgICAgICAgdGhpcy5hcHBseURlbHRhKHsKICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0LAogICAgICAgICAgICBlbmQ6IGVuZCwKICAgICAgICAgICAgYWN0aW9uOiAiaW5zZXJ0IiwKICAgICAgICAgICAgbGluZXM6IGxpbmVzCiAgICAgICAgfSk7CiAgICAgICAgCiAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmVQb3MoZW5kKTsKICAgIH07CiAgICB0aGlzLnJlbW92ZSA9IGZ1bmN0aW9uKHJhbmdlKSB7CiAgICAgICAgdmFyIHN0YXJ0ID0gdGhpcy5jbGlwcGVkUG9zKHJhbmdlLnN0YXJ0LnJvdywgcmFuZ2Uuc3RhcnQuY29sdW1uKTsKICAgICAgICB2YXIgZW5kID0gdGhpcy5jbGlwcGVkUG9zKHJhbmdlLmVuZC5yb3csIHJhbmdlLmVuZC5jb2x1bW4pOwogICAgICAgIHRoaXMuYXBwbHlEZWx0YSh7CiAgICAgICAgICAgIHN0YXJ0OiBzdGFydCwKICAgICAgICAgICAgZW5kOiBlbmQsCiAgICAgICAgICAgIGFjdGlvbjogInJlbW92ZSIsCiAgICAgICAgICAgIGxpbmVzOiB0aGlzLmdldExpbmVzRm9yUmFuZ2Uoe3N0YXJ0OiBzdGFydCwgZW5kOiBlbmR9KQogICAgICAgIH0pOwogICAgICAgIHJldHVybiB0aGlzLmNsb25lUG9zKHN0YXJ0KTsKICAgIH07CiAgICB0aGlzLnJlbW92ZUluTGluZSA9IGZ1bmN0aW9uKHJvdywgc3RhcnRDb2x1bW4sIGVuZENvbHVtbikgewogICAgICAgIHZhciBzdGFydCA9IHRoaXMuY2xpcHBlZFBvcyhyb3csIHN0YXJ0Q29sdW1uKTsKICAgICAgICB2YXIgZW5kID0gdGhpcy5jbGlwcGVkUG9zKHJvdywgZW5kQ29sdW1uKTsKICAgICAgICAKICAgICAgICB0aGlzLmFwcGx5RGVsdGEoewogICAgICAgICAgICBzdGFydDogc3RhcnQsCiAgICAgICAgICAgIGVuZDogZW5kLAogICAgICAgICAgICBhY3Rpb246ICJyZW1vdmUiLAogICAgICAgICAgICBsaW5lczogdGhpcy5nZXRMaW5lc0ZvclJhbmdlKHtzdGFydDogc3RhcnQsIGVuZDogZW5kfSkKICAgICAgICB9LCB0cnVlKTsKICAgICAgICAKICAgICAgICByZXR1cm4gdGhpcy5jbG9uZVBvcyhzdGFydCk7CiAgICB9OwogICAgdGhpcy5yZW1vdmVGdWxsTGluZXMgPSBmdW5jdGlvbihmaXJzdFJvdywgbGFzdFJvdykgewogICAgICAgIGZpcnN0Um93ID0gTWF0aC5taW4oTWF0aC5tYXgoMCwgZmlyc3RSb3cpLCB0aGlzLmdldExlbmd0aCgpIC0gMSk7CiAgICAgICAgbGFzdFJvdyAgPSBNYXRoLm1pbihNYXRoLm1heCgwLCBsYXN0Um93ICksIHRoaXMuZ2V0TGVuZ3RoKCkgLSAxKTsKICAgICAgICB2YXIgZGVsZXRlRmlyc3ROZXdMaW5lID0gbGFzdFJvdyA9PSB0aGlzLmdldExlbmd0aCgpIC0gMSAmJiBmaXJzdFJvdyA+IDA7CiAgICAgICAgdmFyIGRlbGV0ZUxhc3ROZXdMaW5lICA9IGxhc3RSb3cgIDwgdGhpcy5nZXRMZW5ndGgoKSAtIDE7CiAgICAgICAgdmFyIHN0YXJ0Um93ID0gKCBkZWxldGVGaXJzdE5ld0xpbmUgPyBmaXJzdFJvdyAtIDEgICAgICAgICAgICAgICAgICA6IGZpcnN0Um93ICAgICAgICAgICAgICAgICAgICApOwogICAgICAgIHZhciBzdGFydENvbCA9ICggZGVsZXRlRmlyc3ROZXdMaW5lID8gdGhpcy5nZXRMaW5lKHN0YXJ0Um93KS5sZW5ndGggOiAwICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICB2YXIgZW5kUm93ICAgPSAoIGRlbGV0ZUxhc3ROZXdMaW5lICA/IGxhc3RSb3cgKyAxICAgICAgICAgICAgICAgICAgIDogbGFzdFJvdyAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgdmFyIGVuZENvbCAgID0gKCBkZWxldGVMYXN0TmV3TGluZSAgPyAwICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRoaXMuZ2V0TGluZShlbmRSb3cpLmxlbmd0aCApOyAKICAgICAgICB2YXIgcmFuZ2UgPSBuZXcgUmFuZ2Uoc3RhcnRSb3csIHN0YXJ0Q29sLCBlbmRSb3csIGVuZENvbCk7CiAgICAgICAgdmFyIGRlbGV0ZWRMaW5lcyA9IHRoaXMuJGxpbmVzLnNsaWNlKGZpcnN0Um93LCBsYXN0Um93ICsgMSk7CiAgICAgICAgCiAgICAgICAgdGhpcy5hcHBseURlbHRhKHsKICAgICAgICAgICAgc3RhcnQ6IHJhbmdlLnN0YXJ0LAogICAgICAgICAgICBlbmQ6IHJhbmdlLmVuZCwKICAgICAgICAgICAgYWN0aW9uOiAicmVtb3ZlIiwKICAgICAgICAgICAgbGluZXM6IHRoaXMuZ2V0TGluZXNGb3JSYW5nZShyYW5nZSkKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gZGVsZXRlZExpbmVzOwogICAgfTsKICAgIHRoaXMucmVtb3ZlTmV3TGluZSA9IGZ1bmN0aW9uKHJvdykgewogICAgICAgIGlmIChyb3cgPCB0aGlzLmdldExlbmd0aCgpIC0gMSAmJiByb3cgPj0gMCkgewogICAgICAgICAgICB0aGlzLmFwcGx5RGVsdGEoewogICAgICAgICAgICAgICAgc3RhcnQ6IHRoaXMucG9zKHJvdywgdGhpcy5nZXRMaW5lKHJvdykubGVuZ3RoKSwKICAgICAgICAgICAgICAgIGVuZDogdGhpcy5wb3Mocm93ICsgMSwgMCksCiAgICAgICAgICAgICAgICBhY3Rpb246ICJyZW1vdmUiLAogICAgICAgICAgICAgICAgbGluZXM6IFsiIiwgIiJdCiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH07CiAgICB0aGlzLnJlcGxhY2UgPSBmdW5jdGlvbihyYW5nZSwgdGV4dCkgewogICAgICAgIGlmICghKHJhbmdlIGluc3RhbmNlb2YgUmFuZ2UpKQogICAgICAgICAgICByYW5nZSA9IFJhbmdlLmZyb21Qb2ludHMocmFuZ2Uuc3RhcnQsIHJhbmdlLmVuZCk7CiAgICAgICAgaWYgKHRleHQubGVuZ3RoID09PSAwICYmIHJhbmdlLmlzRW1wdHkoKSkKICAgICAgICAgICAgcmV0dXJuIHJhbmdlLnN0YXJ0OwogICAgICAgIGlmICh0ZXh0ID09IHRoaXMuZ2V0VGV4dFJhbmdlKHJhbmdlKSkKICAgICAgICAgICAgcmV0dXJuIHJhbmdlLmVuZDsKCiAgICAgICAgdGhpcy5yZW1vdmUocmFuZ2UpOwogICAgICAgIHZhciBlbmQ7CiAgICAgICAgaWYgKHRleHQpIHsKICAgICAgICAgICAgZW5kID0gdGhpcy5pbnNlcnQocmFuZ2Uuc3RhcnQsIHRleHQpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgZW5kID0gcmFuZ2Uuc3RhcnQ7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBlbmQ7CiAgICB9OwogICAgdGhpcy5hcHBseURlbHRhcyA9IGZ1bmN0aW9uKGRlbHRhcykgewogICAgICAgIGZvciAodmFyIGk9MDsgaTxkZWx0YXMubGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgdGhpcy5hcHBseURlbHRhKGRlbHRhc1tpXSk7CiAgICAgICAgfQogICAgfTsKICAgIHRoaXMucmV2ZXJ0RGVsdGFzID0gZnVuY3Rpb24oZGVsdGFzKSB7CiAgICAgICAgZm9yICh2YXIgaT1kZWx0YXMubGVuZ3RoLTE7IGk+PTA7IGktLSkgewogICAgICAgICAgICB0aGlzLnJldmVydERlbHRhKGRlbHRhc1tpXSk7CiAgICAgICAgfQogICAgfTsKICAgIHRoaXMuYXBwbHlEZWx0YSA9IGZ1bmN0aW9uKGRlbHRhLCBkb05vdFZhbGlkYXRlKSB7CiAgICAgICAgdmFyIGlzSW5zZXJ0ID0gZGVsdGEuYWN0aW9uID09ICJpbnNlcnQiOwogICAgICAgIGlmIChpc0luc2VydCA/IGRlbHRhLmxpbmVzLmxlbmd0aCA8PSAxICYmICFkZWx0YS5saW5lc1swXQogICAgICAgICAgICA6ICFSYW5nZS5jb21wYXJlUG9pbnRzKGRlbHRhLnN0YXJ0LCBkZWx0YS5lbmQpKSB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKGlzSW5zZXJ0ICYmIGRlbHRhLmxpbmVzLmxlbmd0aCA+IDIwMDAwKSB7CiAgICAgICAgICAgIHRoaXMuJHNwbGl0QW5kYXBwbHlMYXJnZURlbHRhKGRlbHRhLCAyMDAwMCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBhcHBseURlbHRhKHRoaXMuJGxpbmVzLCBkZWx0YSwgZG9Ob3RWYWxpZGF0ZSk7CiAgICAgICAgICAgIHRoaXMuX3NpZ25hbCgiY2hhbmdlIiwgZGVsdGEpOwogICAgICAgIH0KICAgIH07CiAgICAKICAgIHRoaXMuJHNhZmVBcHBseURlbHRhID0gZnVuY3Rpb24oZGVsdGEpIHsKICAgICAgICB2YXIgZG9jTGVuZ3RoID0gdGhpcy4kbGluZXMubGVuZ3RoOwogICAgICAgIGlmICgKICAgICAgICAgICAgZGVsdGEuYWN0aW9uID09ICJyZW1vdmUiICYmIGRlbHRhLnN0YXJ0LnJvdyA8IGRvY0xlbmd0aCAmJiBkZWx0YS5lbmQucm93IDwgZG9jTGVuZ3RoCiAgICAgICAgICAgIHx8IGRlbHRhLmFjdGlvbiA9PSAiaW5zZXJ0IiAmJiBkZWx0YS5zdGFydC5yb3cgPD0gZG9jTGVuZ3RoCiAgICAgICAgKSB7CiAgICAgICAgICAgIHRoaXMuYXBwbHlEZWx0YShkZWx0YSk7CiAgICAgICAgfQogICAgfTsKICAgIAogICAgdGhpcy4kc3BsaXRBbmRhcHBseUxhcmdlRGVsdGEgPSBmdW5jdGlvbihkZWx0YSwgTUFYKSB7CiAgICAgICAgdmFyIGxpbmVzID0gZGVsdGEubGluZXM7CiAgICAgICAgdmFyIGwgPSBsaW5lcy5sZW5ndGggLSBNQVggKyAxOwogICAgICAgIHZhciByb3cgPSBkZWx0YS5zdGFydC5yb3c7IAogICAgICAgIHZhciBjb2x1bW4gPSBkZWx0YS5zdGFydC5jb2x1bW47CiAgICAgICAgZm9yICh2YXIgZnJvbSA9IDAsIHRvID0gMDsgZnJvbSA8IGw7IGZyb20gPSB0bykgewogICAgICAgICAgICB0byArPSBNQVggLSAxOwogICAgICAgICAgICB2YXIgY2h1bmsgPSBsaW5lcy5zbGljZShmcm9tLCB0byk7CiAgICAgICAgICAgIGNodW5rLnB1c2goIiIpOwogICAgICAgICAgICB0aGlzLmFwcGx5RGVsdGEoewogICAgICAgICAgICAgICAgc3RhcnQ6IHRoaXMucG9zKHJvdyArIGZyb20sIGNvbHVtbiksCiAgICAgICAgICAgICAgICBlbmQ6IHRoaXMucG9zKHJvdyArIHRvLCBjb2x1bW4gPSAwKSwKICAgICAgICAgICAgICAgIGFjdGlvbjogZGVsdGEuYWN0aW9uLAogICAgICAgICAgICAgICAgbGluZXM6IGNodW5rCiAgICAgICAgICAgIH0sIHRydWUpOwogICAgICAgIH0KICAgICAgICBkZWx0YS5saW5lcyA9IGxpbmVzLnNsaWNlKGZyb20pOwogICAgICAgIGRlbHRhLnN0YXJ0LnJvdyA9IHJvdyArIGZyb207CiAgICAgICAgZGVsdGEuc3RhcnQuY29sdW1uID0gY29sdW1uOwogICAgICAgIHRoaXMuYXBwbHlEZWx0YShkZWx0YSwgdHJ1ZSk7CiAgICB9OwogICAgdGhpcy5yZXZlcnREZWx0YSA9IGZ1bmN0aW9uKGRlbHRhKSB7CiAgICAgICAgdGhpcy4kc2FmZUFwcGx5RGVsdGEoewogICAgICAgICAgICBzdGFydDogdGhpcy5jbG9uZVBvcyhkZWx0YS5zdGFydCksCiAgICAgICAgICAgIGVuZDogdGhpcy5jbG9uZVBvcyhkZWx0YS5lbmQpLAogICAgICAgICAgICBhY3Rpb246IChkZWx0YS5hY3Rpb24gPT0gImluc2VydCIgPyAicmVtb3ZlIiA6ICJpbnNlcnQiKSwKICAgICAgICAgICAgbGluZXM6IGRlbHRhLmxpbmVzLnNsaWNlKCkKICAgICAgICB9KTsKICAgIH07CiAgICB0aGlzLmluZGV4VG9Qb3NpdGlvbiA9IGZ1bmN0aW9uKGluZGV4LCBzdGFydFJvdykgewogICAgICAgIHZhciBsaW5lcyA9IHRoaXMuJGxpbmVzIHx8IHRoaXMuZ2V0QWxsTGluZXMoKTsKICAgICAgICB2YXIgbmV3bGluZUxlbmd0aCA9IHRoaXMuZ2V0TmV3TGluZUNoYXJhY3RlcigpLmxlbmd0aDsKICAgICAgICBmb3IgKHZhciBpID0gc3RhcnRSb3cgfHwgMCwgbCA9IGxpbmVzLmxlbmd0aDsgaSA8IGw7IGkrKykgewogICAgICAgICAgICBpbmRleCAtPSBsaW5lc1tpXS5sZW5ndGggKyBuZXdsaW5lTGVuZ3RoOwogICAgICAgICAgICBpZiAoaW5kZXggPCAwKQogICAgICAgICAgICAgICAgcmV0dXJuIHtyb3c6IGksIGNvbHVtbjogaW5kZXggKyBsaW5lc1tpXS5sZW5ndGggKyBuZXdsaW5lTGVuZ3RofTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHtyb3c6IGwtMSwgY29sdW1uOiBpbmRleCArIGxpbmVzW2wtMV0ubGVuZ3RoICsgbmV3bGluZUxlbmd0aH07CiAgICB9OwogICAgdGhpcy5wb3NpdGlvblRvSW5kZXggPSBmdW5jdGlvbihwb3MsIHN0YXJ0Um93KSB7CiAgICAgICAgdmFyIGxpbmVzID0gdGhpcy4kbGluZXMgfHwgdGhpcy5nZXRBbGxMaW5lcygpOwogICAgICAgIHZhciBuZXdsaW5lTGVuZ3RoID0gdGhpcy5nZXROZXdMaW5lQ2hhcmFjdGVyKCkubGVuZ3RoOwogICAgICAgIHZhciBpbmRleCA9IDA7CiAgICAgICAgdmFyIHJvdyA9IE1hdGgubWluKHBvcy5yb3csIGxpbmVzLmxlbmd0aCk7CiAgICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0Um93IHx8IDA7IGkgPCByb3c7ICsraSkKICAgICAgICAgICAgaW5kZXggKz0gbGluZXNbaV0ubGVuZ3RoICsgbmV3bGluZUxlbmd0aDsKCiAgICAgICAgcmV0dXJuIGluZGV4ICsgcG9zLmNvbHVtbjsKICAgIH07Cgp9KS5jYWxsKERvY3VtZW50LnByb3RvdHlwZSk7CgpleHBvcnRzLkRvY3VtZW50ID0gRG9jdW1lbnQ7Cn0pOwoKYWNlLmRlZmluZSgiYWNlL2xpYi9sYW5nIixbXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKSB7CiJ1c2Ugc3RyaWN0IjsKCmV4cG9ydHMubGFzdCA9IGZ1bmN0aW9uKGEpIHsKICAgIHJldHVybiBhW2EubGVuZ3RoIC0gMV07Cn07CgpleHBvcnRzLnN0cmluZ1JldmVyc2UgPSBmdW5jdGlvbihzdHJpbmcpIHsKICAgIHJldHVybiBzdHJpbmcuc3BsaXQoIiIpLnJldmVyc2UoKS5qb2luKCIiKTsKfTsKCmV4cG9ydHMuc3RyaW5nUmVwZWF0ID0gZnVuY3Rpb24gKHN0cmluZywgY291bnQpIHsKICAgIHZhciByZXN1bHQgPSAnJzsKICAgIHdoaWxlIChjb3VudCA+IDApIHsKICAgICAgICBpZiAoY291bnQgJiAxKQogICAgICAgICAgICByZXN1bHQgKz0gc3RyaW5nOwoKICAgICAgICBpZiAoY291bnQgPj49IDEpCiAgICAgICAgICAgIHN0cmluZyArPSBzdHJpbmc7CiAgICB9CiAgICByZXR1cm4gcmVzdWx0Owp9OwoKdmFyIHRyaW1CZWdpblJlZ2V4cCA9IC9eXHNccyovOwp2YXIgdHJpbUVuZFJlZ2V4cCA9IC9cc1xzKiQvOwoKZXhwb3J0cy5zdHJpbmdUcmltTGVmdCA9IGZ1bmN0aW9uIChzdHJpbmcpIHsKICAgIHJldHVybiBzdHJpbmcucmVwbGFjZSh0cmltQmVnaW5SZWdleHAsICcnKTsKfTsKCmV4cG9ydHMuc3RyaW5nVHJpbVJpZ2h0ID0gZnVuY3Rpb24gKHN0cmluZykgewogICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKHRyaW1FbmRSZWdleHAsICcnKTsKfTsKCmV4cG9ydHMuY29weU9iamVjdCA9IGZ1bmN0aW9uKG9iaikgewogICAgdmFyIGNvcHkgPSB7fTsKICAgIGZvciAodmFyIGtleSBpbiBvYmopIHsKICAgICAgICBjb3B5W2tleV0gPSBvYmpba2V5XTsKICAgIH0KICAgIHJldHVybiBjb3B5Owp9OwoKZXhwb3J0cy5jb3B5QXJyYXkgPSBmdW5jdGlvbihhcnJheSl7CiAgICB2YXIgY29weSA9IFtdOwogICAgZm9yICh2YXIgaT0wLCBsPWFycmF5Lmxlbmd0aDsgaTxsOyBpKyspIHsKICAgICAgICBpZiAoYXJyYXlbaV0gJiYgdHlwZW9mIGFycmF5W2ldID09ICJvYmplY3QiKQogICAgICAgICAgICBjb3B5W2ldID0gdGhpcy5jb3B5T2JqZWN0KGFycmF5W2ldKTsKICAgICAgICBlbHNlIAogICAgICAgICAgICBjb3B5W2ldID0gYXJyYXlbaV07CiAgICB9CiAgICByZXR1cm4gY29weTsKfTsKCmV4cG9ydHMuZGVlcENvcHkgPSBmdW5jdGlvbiBkZWVwQ29weShvYmopIHsKICAgIGlmICh0eXBlb2Ygb2JqICE9PSAib2JqZWN0IiB8fCAhb2JqKQogICAgICAgIHJldHVybiBvYmo7CiAgICB2YXIgY29weTsKICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHsKICAgICAgICBjb3B5ID0gW107CiAgICAgICAgZm9yICh2YXIga2V5ID0gMDsga2V5IDwgb2JqLmxlbmd0aDsga2V5KyspIHsKICAgICAgICAgICAgY29weVtrZXldID0gZGVlcENvcHkob2JqW2tleV0pOwogICAgICAgIH0KICAgICAgICByZXR1cm4gY29weTsKICAgIH0KICAgIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKSAhPT0gIltvYmplY3QgT2JqZWN0XSIpCiAgICAgICAgcmV0dXJuIG9iajsKICAgIAogICAgY29weSA9IHt9OwogICAgZm9yICh2YXIga2V5IGluIG9iaikKICAgICAgICBjb3B5W2tleV0gPSBkZWVwQ29weShvYmpba2V5XSk7CiAgICByZXR1cm4gY29weTsKfTsKCmV4cG9ydHMuYXJyYXlUb01hcCA9IGZ1bmN0aW9uKGFycikgewogICAgdmFyIG1hcCA9IHt9OwogICAgZm9yICh2YXIgaT0wOyBpPGFyci5sZW5ndGg7IGkrKykgewogICAgICAgIG1hcFthcnJbaV1dID0gMTsKICAgIH0KICAgIHJldHVybiBtYXA7Cgp9OwoKZXhwb3J0cy5jcmVhdGVNYXAgPSBmdW5jdGlvbihwcm9wcykgewogICAgdmFyIG1hcCA9IE9iamVjdC5jcmVhdGUobnVsbCk7CiAgICBmb3IgKHZhciBpIGluIHByb3BzKSB7CiAgICAgICAgbWFwW2ldID0gcHJvcHNbaV07CiAgICB9CiAgICByZXR1cm4gbWFwOwp9OwpleHBvcnRzLmFycmF5UmVtb3ZlID0gZnVuY3Rpb24oYXJyYXksIHZhbHVlKSB7CiAgZm9yICh2YXIgaSA9IDA7IGkgPD0gYXJyYXkubGVuZ3RoOyBpKyspIHsKICAgIGlmICh2YWx1ZSA9PT0gYXJyYXlbaV0pIHsKICAgICAgYXJyYXkuc3BsaWNlKGksIDEpOwogICAgfQogIH0KfTsKCmV4cG9ydHMuZXNjYXBlUmVnRXhwID0gZnVuY3Rpb24oc3RyKSB7CiAgICByZXR1cm4gc3RyLnJlcGxhY2UoLyhbLiorP14ke30oKXxbXF1cL1xcXSkvZywgJ1xcJDEnKTsKfTsKCmV4cG9ydHMuZXNjYXBlSFRNTCA9IGZ1bmN0aW9uKHN0cikgewogICAgcmV0dXJuICgiIiArIHN0cikucmVwbGFjZSgvJi9nLCAiJiMzODsiKS5yZXBsYWNlKC8iL2csICImIzM0OyIpLnJlcGxhY2UoLycvZywgIiYjMzk7IikucmVwbGFjZSgvPC9nLCAiJiM2MDsiKTsKfTsKCmV4cG9ydHMuZ2V0TWF0Y2hPZmZzZXRzID0gZnVuY3Rpb24oc3RyaW5nLCByZWdFeHApIHsKICAgIHZhciBtYXRjaGVzID0gW107CgogICAgc3RyaW5nLnJlcGxhY2UocmVnRXhwLCBmdW5jdGlvbihzdHIpIHsKICAgICAgICBtYXRjaGVzLnB1c2goewogICAgICAgICAgICBvZmZzZXQ6IGFyZ3VtZW50c1thcmd1bWVudHMubGVuZ3RoLTJdLAogICAgICAgICAgICBsZW5ndGg6IHN0ci5sZW5ndGgKICAgICAgICB9KTsKICAgIH0pOwoKICAgIHJldHVybiBtYXRjaGVzOwp9OwpleHBvcnRzLmRlZmVycmVkQ2FsbCA9IGZ1bmN0aW9uKGZjbikgewogICAgdmFyIHRpbWVyID0gbnVsbDsKICAgIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uKCkgewogICAgICAgIHRpbWVyID0gbnVsbDsKICAgICAgICBmY24oKTsKICAgIH07CgogICAgdmFyIGRlZmVycmVkID0gZnVuY3Rpb24odGltZW91dCkgewogICAgICAgIGRlZmVycmVkLmNhbmNlbCgpOwogICAgICAgIHRpbWVyID0gc2V0VGltZW91dChjYWxsYmFjaywgdGltZW91dCB8fCAwKTsKICAgICAgICByZXR1cm4gZGVmZXJyZWQ7CiAgICB9OwoKICAgIGRlZmVycmVkLnNjaGVkdWxlID0gZGVmZXJyZWQ7CgogICAgZGVmZXJyZWQuY2FsbCA9IGZ1bmN0aW9uKCkgewogICAgICAgIHRoaXMuY2FuY2VsKCk7CiAgICAgICAgZmNuKCk7CiAgICAgICAgcmV0dXJuIGRlZmVycmVkOwogICAgfTsKCiAgICBkZWZlcnJlZC5jYW5jZWwgPSBmdW5jdGlvbigpIHsKICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpOwogICAgICAgIHRpbWVyID0gbnVsbDsKICAgICAgICByZXR1cm4gZGVmZXJyZWQ7CiAgICB9OwogICAgCiAgICBkZWZlcnJlZC5pc1BlbmRpbmcgPSBmdW5jdGlvbigpIHsKICAgICAgICByZXR1cm4gdGltZXI7CiAgICB9OwoKICAgIHJldHVybiBkZWZlcnJlZDsKfTsKCgpleHBvcnRzLmRlbGF5ZWRDYWxsID0gZnVuY3Rpb24oZmNuLCBkZWZhdWx0VGltZW91dCkgewogICAgdmFyIHRpbWVyID0gbnVsbDsKICAgIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uKCkgewogICAgICAgIHRpbWVyID0gbnVsbDsKICAgICAgICBmY24oKTsKICAgIH07CgogICAgdmFyIF9zZWxmID0gZnVuY3Rpb24odGltZW91dCkgewogICAgICAgIGlmICh0aW1lciA9PSBudWxsKQogICAgICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQoY2FsbGJhY2ssIHRpbWVvdXQgfHwgZGVmYXVsdFRpbWVvdXQpOwogICAgfTsKCiAgICBfc2VsZi5kZWxheSA9IGZ1bmN0aW9uKHRpbWVvdXQpIHsKICAgICAgICB0aW1lciAmJiBjbGVhclRpbWVvdXQodGltZXIpOwogICAgICAgIHRpbWVyID0gc2V0VGltZW91dChjYWxsYmFjaywgdGltZW91dCB8fCBkZWZhdWx0VGltZW91dCk7CiAgICB9OwogICAgX3NlbGYuc2NoZWR1bGUgPSBfc2VsZjsKCiAgICBfc2VsZi5jYWxsID0gZnVuY3Rpb24oKSB7CiAgICAgICAgdGhpcy5jYW5jZWwoKTsKICAgICAgICBmY24oKTsKICAgIH07CgogICAgX3NlbGYuY2FuY2VsID0gZnVuY3Rpb24oKSB7CiAgICAgICAgdGltZXIgJiYgY2xlYXJUaW1lb3V0KHRpbWVyKTsKICAgICAgICB0aW1lciA9IG51bGw7CiAgICB9OwoKICAgIF9zZWxmLmlzUGVuZGluZyA9IGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiB0aW1lcjsKICAgIH07CgogICAgcmV0dXJuIF9zZWxmOwp9Owp9KTsKCmFjZS5kZWZpbmUoImFjZS93b3JrZXIvbWlycm9yIixbXSwgZnVuY3Rpb24ocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKSB7CiJ1c2Ugc3RyaWN0IjsKCnZhciBSYW5nZSA9IHJlcXVpcmUoIi4uL3JhbmdlIikuUmFuZ2U7CnZhciBEb2N1bWVudCA9IHJlcXVpcmUoIi4uL2RvY3VtZW50IikuRG9jdW1lbnQ7CnZhciBsYW5nID0gcmVxdWlyZSgiLi4vbGliL2xhbmciKTsKICAgIAp2YXIgTWlycm9yID0gZXhwb3J0cy5NaXJyb3IgPSBmdW5jdGlvbihzZW5kZXIpIHsKICAgIHRoaXMuc2VuZGVyID0gc2VuZGVyOwogICAgdmFyIGRvYyA9IHRoaXMuZG9jID0gbmV3IERvY3VtZW50KCIiKTsKICAgIAogICAgdmFyIGRlZmVycmVkVXBkYXRlID0gdGhpcy5kZWZlcnJlZFVwZGF0ZSA9IGxhbmcuZGVsYXllZENhbGwodGhpcy5vblVwZGF0ZS5iaW5kKHRoaXMpKTsKICAgIAogICAgdmFyIF9zZWxmID0gdGhpczsKICAgIHNlbmRlci5vbigiY2hhbmdlIiwgZnVuY3Rpb24oZSkgewogICAgICAgIHZhciBkYXRhID0gZS5kYXRhOwogICAgICAgIGlmIChkYXRhWzBdLnN0YXJ0KSB7CiAgICAgICAgICAgIGRvYy5hcHBseURlbHRhcyhkYXRhKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpICs9IDIpIHsKICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGFbaSsxXSkpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZCA9IHthY3Rpb246ICJpbnNlcnQiLCBzdGFydDogZGF0YVtpXSwgbGluZXM6IGRhdGFbaSsxXX07CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHZhciBkID0ge2FjdGlvbjogInJlbW92ZSIsIHN0YXJ0OiBkYXRhW2ldLCBlbmQ6IGRhdGFbaSsxXX07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkb2MuYXBwbHlEZWx0YShkLCB0cnVlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoX3NlbGYuJHRpbWVvdXQpCiAgICAgICAgICAgIHJldHVybiBkZWZlcnJlZFVwZGF0ZS5zY2hlZHVsZShfc2VsZi4kdGltZW91dCk7CiAgICAgICAgX3NlbGYub25VcGRhdGUoKTsKICAgIH0pOwp9OwoKKGZ1bmN0aW9uKCkgewogICAgCiAgICB0aGlzLiR0aW1lb3V0ID0gNTAwOwogICAgCiAgICB0aGlzLnNldFRpbWVvdXQgPSBmdW5jdGlvbih0aW1lb3V0KSB7CiAgICAgICAgdGhpcy4kdGltZW91dCA9IHRpbWVvdXQ7CiAgICB9OwogICAgCiAgICB0aGlzLnNldFZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICB0aGlzLmRvYy5zZXRWYWx1ZSh2YWx1ZSk7CiAgICAgICAgdGhpcy5kZWZlcnJlZFVwZGF0ZS5zY2hlZHVsZSh0aGlzLiR0aW1lb3V0KTsKICAgIH07CiAgICAKICAgIHRoaXMuZ2V0VmFsdWUgPSBmdW5jdGlvbihjYWxsYmFja0lkKSB7CiAgICAgICAgdGhpcy5zZW5kZXIuY2FsbGJhY2sodGhpcy5kb2MuZ2V0VmFsdWUoKSwgY2FsbGJhY2tJZCk7CiAgICB9OwogICAgCiAgICB0aGlzLm9uVXBkYXRlID0gZnVuY3Rpb24oKSB7CiAgICB9OwogICAgCiAgICB0aGlzLmlzUGVuZGluZyA9IGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiB0aGlzLmRlZmVycmVkVXBkYXRlLmlzUGVuZGluZygpOwogICAgfTsKICAgIAp9KS5jYWxsKE1pcnJvci5wcm90b3R5cGUpOwoKfSk7CgphY2UuZGVmaW5lKCJhY2UvbW9kZS9qc29uL2pzb25fcGFyc2UiLFtdLCBmdW5jdGlvbihyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpIHsKInVzZSBzdHJpY3QiOwoKICAgIHZhciBhdCwgICAgIC8vIFRoZSBpbmRleCBvZiB0aGUgY3VycmVudCBjaGFyYWN0ZXIKICAgICAgICBjaCwgICAgIC8vIFRoZSBjdXJyZW50IGNoYXJhY3RlcgogICAgICAgIGVzY2FwZWUgPSB7CiAgICAgICAgICAgICciJzogICciJywKICAgICAgICAgICAgJ1xcJzogJ1xcJywKICAgICAgICAgICAgJy8nOiAgJy8nLAogICAgICAgICAgICBiOiAgICAnXGInLAogICAgICAgICAgICBmOiAgICAnXGYnLAogICAgICAgICAgICBuOiAgICAnXG4nLAogICAgICAgICAgICByOiAgICAnXHInLAogICAgICAgICAgICB0OiAgICAnXHQnCiAgICAgICAgfSwKICAgICAgICB0ZXh0LAoKICAgICAgICBlcnJvciA9IGZ1bmN0aW9uIChtKSB7CgogICAgICAgICAgICB0aHJvdyB7CiAgICAgICAgICAgICAgICBuYW1lOiAgICAnU3ludGF4RXJyb3InLAogICAgICAgICAgICAgICAgbWVzc2FnZTogbSwKICAgICAgICAgICAgICAgIGF0OiAgICAgIGF0LAogICAgICAgICAgICAgICAgdGV4dDogICAgdGV4dAogICAgICAgICAgICB9OwogICAgICAgIH0sCgogICAgICAgIG5leHQgPSBmdW5jdGlvbiAoYykgewoKICAgICAgICAgICAgaWYgKGMgJiYgYyAhPT0gY2gpIHsKICAgICAgICAgICAgICAgIGVycm9yKCJFeHBlY3RlZCAnIiArIGMgKyAiJyBpbnN0ZWFkIG9mICciICsgY2ggKyAiJyIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBjaCA9IHRleHQuY2hhckF0KGF0KTsKICAgICAgICAgICAgYXQgKz0gMTsKICAgICAgICAgICAgcmV0dXJuIGNoOwogICAgICAgIH0sCgogICAgICAgIG51bWJlciA9IGZ1bmN0aW9uICgpIHsKCiAgICAgICAgICAgIHZhciBudW1iZXIsCiAgICAgICAgICAgICAgICBzdHJpbmcgPSAnJzsKCiAgICAgICAgICAgIGlmIChjaCA9PT0gJy0nKSB7CiAgICAgICAgICAgICAgICBzdHJpbmcgPSAnLSc7CiAgICAgICAgICAgICAgICBuZXh0KCctJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgd2hpbGUgKGNoID49ICcwJyAmJiBjaCA8PSAnOScpIHsKICAgICAgICAgICAgICAgIHN0cmluZyArPSBjaDsKICAgICAgICAgICAgICAgIG5leHQoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY2ggPT09ICcuJykgewogICAgICAgICAgICAgICAgc3RyaW5nICs9ICcuJzsKICAgICAgICAgICAgICAgIHdoaWxlIChuZXh0KCkgJiYgY2ggPj0gJzAnICYmIGNoIDw9ICc5JykgewogICAgICAgICAgICAgICAgICAgIHN0cmluZyArPSBjaDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY2ggPT09ICdlJyB8fCBjaCA9PT0gJ0UnKSB7CiAgICAgICAgICAgICAgICBzdHJpbmcgKz0gY2g7CiAgICAgICAgICAgICAgICBuZXh0KCk7CiAgICAgICAgICAgICAgICBpZiAoY2ggPT09ICctJyB8fCBjaCA9PT0gJysnKSB7CiAgICAgICAgICAgICAgICAgICAgc3RyaW5nICs9IGNoOwogICAgICAgICAgICAgICAgICAgIG5leHQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHdoaWxlIChjaCA+PSAnMCcgJiYgY2ggPD0gJzknKSB7CiAgICAgICAgICAgICAgICAgICAgc3RyaW5nICs9IGNoOwogICAgICAgICAgICAgICAgICAgIG5leHQoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBudW1iZXIgPSArc3RyaW5nOwogICAgICAgICAgICBpZiAoaXNOYU4obnVtYmVyKSkgewogICAgICAgICAgICAgICAgZXJyb3IoIkJhZCBudW1iZXIiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBudW1iZXI7CiAgICAgICAgICAgIH0KICAgICAgICB9LAoKICAgICAgICBzdHJpbmcgPSBmdW5jdGlvbiAoKSB7CgogICAgICAgICAgICB2YXIgaGV4LAogICAgICAgICAgICAgICAgaSwKICAgICAgICAgICAgICAgIHN0cmluZyA9ICcnLAogICAgICAgICAgICAgICAgdWZmZmY7CgogICAgICAgICAgICBpZiAoY2ggPT09ICciJykgewogICAgICAgICAgICAgICAgd2hpbGUgKG5leHQoKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PT0gJyInKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0cmluZzsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoID09PSAnXFwnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoID09PSAndScpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVmZmZmID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCA0OyBpICs9IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZXggPSBwYXJzZUludChuZXh0KCksIDE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzRmluaXRlKGhleCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVmZmZmID0gdWZmZmYgKiAxNiArIGhleDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHVmZmZmKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZXNjYXBlZVtjaF0gPT09ICdzdHJpbmcnKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgKz0gZXNjYXBlZVtjaF07CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2ggPT0gIlxuIiB8fCBjaCA9PSAiXHIiKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyArPSBjaDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZXJyb3IoIkJhZCBzdHJpbmciKTsKICAgICAgICB9LAoKICAgICAgICB3aGl0ZSA9IGZ1bmN0aW9uICgpIHsKCiAgICAgICAgICAgIHdoaWxlIChjaCAmJiBjaCA8PSAnICcpIHsKICAgICAgICAgICAgICAgIG5leHQoKTsKICAgICAgICAgICAgfQogICAgICAgIH0sCgogICAgICAgIHdvcmQgPSBmdW5jdGlvbiAoKSB7CgogICAgICAgICAgICBzd2l0Y2ggKGNoKSB7CiAgICAgICAgICAgIGNhc2UgJ3QnOgogICAgICAgICAgICAgICAgbmV4dCgndCcpOwogICAgICAgICAgICAgICAgbmV4dCgncicpOwogICAgICAgICAgICAgICAgbmV4dCgndScpOwogICAgICAgICAgICAgICAgbmV4dCgnZScpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGNhc2UgJ2YnOgogICAgICAgICAgICAgICAgbmV4dCgnZicpOwogICAgICAgICAgICAgICAgbmV4dCgnYScpOwogICAgICAgICAgICAgICAgbmV4dCgnbCcpOwogICAgICAgICAgICAgICAgbmV4dCgncycpOwogICAgICAgICAgICAgICAgbmV4dCgnZScpOwogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICBjYXNlICduJzoKICAgICAgICAgICAgICAgIG5leHQoJ24nKTsKICAgICAgICAgICAgICAgIG5leHQoJ3UnKTsKICAgICAgICAgICAgICAgIG5leHQoJ2wnKTsKICAgICAgICAgICAgICAgIG5leHQoJ2wnKTsKICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVycm9yKCJVbmV4cGVjdGVkICciICsgY2ggKyAiJyIpOwogICAgICAgIH0sCgogICAgICAgIHZhbHVlLCAgLy8gUGxhY2UgaG9sZGVyIGZvciB0aGUgdmFsdWUgZnVuY3Rpb24uCgogICAgICAgIGFycmF5ID0gZnVuY3Rpb24gKCkgewoKICAgICAgICAgICAgdmFyIGFycmF5ID0gW107CgogICAgICAgICAgICBpZiAoY2ggPT09ICdbJykgewogICAgICAgICAgICAgICAgbmV4dCgnWycpOwogICAgICAgICAgICAgICAgd2hpdGUoKTsKICAgICAgICAgICAgICAgIGlmIChjaCA9PT0gJ10nKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dCgnXScpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBhcnJheTsgICAvLyBlbXB0eSBhcnJheQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgd2hpbGUgKGNoKSB7CiAgICAgICAgICAgICAgICAgICAgYXJyYXkucHVzaCh2YWx1ZSgpKTsKICAgICAgICAgICAgICAgICAgICB3aGl0ZSgpOwogICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PT0gJ10nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQoJ10nKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBuZXh0KCcsJyk7CiAgICAgICAgICAgICAgICAgICAgd2hpdGUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlcnJvcigiQmFkIGFycmF5Iik7CiAgICAgICAgfSwKCiAgICAgICAgb2JqZWN0ID0gZnVuY3Rpb24gKCkgewoKICAgICAgICAgICAgdmFyIGtleSwKICAgICAgICAgICAgICAgIG9iamVjdCA9IHt9OwoKICAgICAgICAgICAgaWYgKGNoID09PSAneycpIHsKICAgICAgICAgICAgICAgIG5leHQoJ3snKTsKICAgICAgICAgICAgICAgIHdoaXRlKCk7CiAgICAgICAgICAgICAgICBpZiAoY2ggPT09ICd9JykgewogICAgICAgICAgICAgICAgICAgIG5leHQoJ30nKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0OyAgIC8vIGVtcHR5IG9iamVjdAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgd2hpbGUgKGNoKSB7CiAgICAgICAgICAgICAgICAgICAga2V5ID0gc3RyaW5nKCk7CiAgICAgICAgICAgICAgICAgICAgd2hpdGUoKTsKICAgICAgICAgICAgICAgICAgICBuZXh0KCc6Jyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkgewogICAgICAgICAgICAgICAgICAgICAgICBlcnJvcignRHVwbGljYXRlIGtleSAiJyArIGtleSArICciJyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG9iamVjdFtrZXldID0gdmFsdWUoKTsKICAgICAgICAgICAgICAgICAgICB3aGl0ZSgpOwogICAgICAgICAgICAgICAgICAgIGlmIChjaCA9PT0gJ30nKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQoJ30nKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgbmV4dCgnLCcpOwogICAgICAgICAgICAgICAgICAgIHdoaXRlKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZXJyb3IoIkJhZCBvYmplY3QiKTsKICAgICAgICB9OwoKICAgIHZhbHVlID0gZnVuY3Rpb24gKCkgewoKICAgICAgICB3aGl0ZSgpOwogICAgICAgIHN3aXRjaCAoY2gpIHsKICAgICAgICBjYXNlICd7JzoKICAgICAgICAgICAgcmV0dXJuIG9iamVjdCgpOwogICAgICAgIGNhc2UgJ1snOgogICAgICAgICAgICByZXR1cm4gYXJyYXkoKTsKICAgICAgICBjYXNlICciJzoKICAgICAgICAgICAgcmV0dXJuIHN0cmluZygpOwogICAgICAgIGNhc2UgJy0nOgogICAgICAgICAgICByZXR1cm4gbnVtYmVyKCk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIGNoID49ICcwJyAmJiBjaCA8PSAnOScgPyBudW1iZXIoKSA6IHdvcmQoKTsKICAgICAgICB9CiAgICB9OwoKICAgIHJldHVybiBmdW5jdGlvbiAoc291cmNlLCByZXZpdmVyKSB7CiAgICAgICAgdmFyIHJlc3VsdDsKCiAgICAgICAgdGV4dCA9IHNvdXJjZTsKICAgICAgICBhdCA9IDA7CiAgICAgICAgY2ggPSAnICc7CiAgICAgICAgcmVzdWx0ID0gdmFsdWUoKTsKICAgICAgICB3aGl0ZSgpOwogICAgICAgIGlmIChjaCkgewogICAgICAgICAgICBlcnJvcigiU3ludGF4IGVycm9yIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdHlwZW9mIHJldml2ZXIgPT09ICdmdW5jdGlvbicgPyBmdW5jdGlvbiB3YWxrKGhvbGRlciwga2V5KSB7CiAgICAgICAgICAgIHZhciBrLCB2LCB2YWx1ZSA9IGhvbGRlcltrZXldOwogICAgICAgICAgICBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JykgewogICAgICAgICAgICAgICAgZm9yIChrIGluIHZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCBrKSkgewogICAgICAgICAgICAgICAgICAgICAgICB2ID0gd2Fsayh2YWx1ZSwgayk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2ICE9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlW2tdID0gdjsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB2YWx1ZVtrXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmV2aXZlci5jYWxsKGhvbGRlciwga2V5LCB2YWx1ZSk7CiAgICAgICAgfSh7Jyc6IHJlc3VsdH0sICcnKSA6IHJlc3VsdDsKICAgIH07Cn0pOwoKYWNlLmRlZmluZSgiYWNlL21vZGUvanNvbl93b3JrZXIiLFtdLCBmdW5jdGlvbihyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpIHsKInVzZSBzdHJpY3QiOwoKdmFyIG9vcCA9IHJlcXVpcmUoIi4uL2xpYi9vb3AiKTsKdmFyIE1pcnJvciA9IHJlcXVpcmUoIi4uL3dvcmtlci9taXJyb3IiKS5NaXJyb3I7CnZhciBwYXJzZSA9IHJlcXVpcmUoIi4vanNvbi9qc29uX3BhcnNlIik7Cgp2YXIgSnNvbldvcmtlciA9IGV4cG9ydHMuSnNvbldvcmtlciA9IGZ1bmN0aW9uKHNlbmRlcikgewogICAgTWlycm9yLmNhbGwodGhpcywgc2VuZGVyKTsKICAgIHRoaXMuc2V0VGltZW91dCgyMDApOwp9OwoKb29wLmluaGVyaXRzKEpzb25Xb3JrZXIsIE1pcnJvcik7CgooZnVuY3Rpb24oKSB7CgogICAgdGhpcy5vblVwZGF0ZSA9IGZ1bmN0aW9uKCkgewogICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuZG9jLmdldFZhbHVlKCk7CiAgICAgICAgdmFyIGVycm9ycyA9IFtdOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSkKICAgICAgICAgICAgICAgIHBhcnNlKHZhbHVlKTsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgIHZhciBwb3MgPSB0aGlzLmRvYy5pbmRleFRvUG9zaXRpb24oZS5hdC0xKTsKICAgICAgICAgICAgZXJyb3JzLnB1c2goewogICAgICAgICAgICAgICAgcm93OiBwb3Mucm93LAogICAgICAgICAgICAgICAgY29sdW1uOiBwb3MuY29sdW1uLAogICAgICAgICAgICAgICAgdGV4dDogZS5tZXNzYWdlLAogICAgICAgICAgICAgICAgdHlwZTogImVycm9yIgogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgICAgdGhpcy5zZW5kZXIuZW1pdCgiYW5ub3RhdGUiLCBlcnJvcnMpOwogICAgfTsKCn0pLmNhbGwoSnNvbldvcmtlci5wcm90b3R5cGUpOwoKfSk7Cg=='; + +/***/ }), + +/***/ 7907: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "m0": function() { return /* binding */ setLanguage; }, +/* harmony export */ "cC": function() { return /* binding */ setLanguages; }, +/* harmony export */ "Iu": function() { return /* binding */ translate; } +/* harmony export */ }); +/* harmony import */ var _polyfills__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4987); +/* harmony import */ var _polyfills__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_polyfills__WEBPACK_IMPORTED_MODULE_0__); + +/* eslint-disable no-template-curly-in-string */ + + +var _locales = ['en', 'pt-BR', 'zh-CN', 'tr', 'ja', 'fr-FR', 'de']; +var _defs = { + en: { + array: 'Array', + auto: 'Auto', + appendText: 'Append', + appendTitle: 'Append a new field with type \'auto\' after this field (Ctrl+Shift+Ins)', + appendSubmenuTitle: 'Select the type of the field to be appended', + appendTitleAuto: 'Append a new field with type \'auto\' (Ctrl+Shift+Ins)', + ascending: 'Ascending', + ascendingTitle: 'Sort the childs of this ${type} in ascending order', + actionsMenu: 'Click to open the actions menu (Ctrl+M)', + cannotParseFieldError: 'Cannot parse field into JSON', + cannotParseValueError: 'Cannot parse value into JSON', + collapseAll: 'Collapse all fields', + compactTitle: 'Compact JSON data, remove all whitespaces (Ctrl+Shift+\\)', + descending: 'Descending', + descendingTitle: 'Sort the childs of this ${type} in descending order', + drag: 'Drag to move this field (Alt+Shift+Arrows)', + duplicateKey: 'duplicate key', + duplicateText: 'Duplicate', + duplicateTitle: 'Duplicate selected fields (Ctrl+D)', + duplicateField: 'Duplicate this field (Ctrl+D)', + duplicateFieldError: 'Duplicate field name', + empty: 'empty', + expandAll: 'Expand all fields', + expandTitle: 'Click to expand/collapse this field (Ctrl+E). \n' + 'Ctrl+Click to expand/collapse including all childs.', + formatTitle: 'Format JSON data, with proper indentation and line feeds (Ctrl+\\)', + insert: 'Insert', + insertTitle: 'Insert a new field with type \'auto\' before this field (Ctrl+Ins)', + insertSub: 'Select the type of the field to be inserted', + object: 'Object', + ok: 'Ok', + redo: 'Redo (Ctrl+Shift+Z)', + removeText: 'Remove', + removeTitle: 'Remove selected fields (Ctrl+Del)', + removeField: 'Remove this field (Ctrl+Del)', + repairTitle: 'Repair JSON: fix quotes and escape characters, remove comments and JSONP notation, turn JavaScript objects into JSON.', + searchTitle: 'Search fields and values', + searchNextResultTitle: 'Next result (Enter)', + searchPreviousResultTitle: 'Previous result (Shift + Enter)', + selectNode: 'Select a node...', + showAll: 'show all', + showMore: 'show more', + showMoreStatus: 'displaying ${visibleChilds} of ${totalChilds} items.', + sort: 'Sort', + sortTitle: 'Sort the childs of this ${type}', + sortTitleShort: 'Sort contents', + sortFieldLabel: 'Field:', + sortDirectionLabel: 'Direction:', + sortFieldTitle: 'Select the nested field by which to sort the array or object', + sortAscending: 'Ascending', + sortAscendingTitle: 'Sort the selected field in ascending order', + sortDescending: 'Descending', + sortDescendingTitle: 'Sort the selected field in descending order', + string: 'String', + transform: 'Transform', + transformTitle: 'Filter, sort, or transform the childs of this ${type}', + transformTitleShort: 'Filter, sort, or transform contents', + extract: 'Extract', + extractTitle: 'Extract this ${type}', + transformQueryTitle: 'Enter a JMESPath query', + transformWizardLabel: 'Wizard', + transformWizardFilter: 'Filter', + transformWizardSortBy: 'Sort by', + transformWizardSelectFields: 'Select fields', + transformQueryLabel: 'Query', + transformPreviewLabel: 'Preview', + type: 'Type', + typeTitle: 'Change the type of this field', + openUrl: 'Ctrl+Click or Ctrl+Enter to open url in new window', + undo: 'Undo last action (Ctrl+Z)', + validationCannotMove: 'Cannot move a field into a child of itself', + autoType: 'Field type "auto". ' + 'The field type is automatically determined from the value ' + 'and can be a string, number, boolean, or null.', + objectType: 'Field type "object". ' + 'An object contains an unordered set of key/value pairs.', + arrayType: 'Field type "array". ' + 'An array contains an ordered collection of values.', + stringType: 'Field type "string". ' + 'Field type is not determined from the value, ' + 'but always returned as string.', + modeEditorTitle: 'Switch Editor Mode', + modeCodeText: 'Code', + modeCodeTitle: 'Switch to code highlighter', + modeFormText: 'Form', + modeFormTitle: 'Switch to form editor', + modeTextText: 'Text', + modeTextTitle: 'Switch to plain text editor', + modeTreeText: 'Tree', + modeTreeTitle: 'Switch to tree editor', + modeViewText: 'View', + modeViewTitle: 'Switch to tree view', + modePreviewText: 'Preview', + modePreviewTitle: 'Switch to preview mode', + examples: 'Examples', + "default": 'Default', + containsInvalidProperties: 'Contains invalid properties', + containsInvalidItems: 'Contains invalid items' + }, + 'zh-CN': { + array: '数组', + auto: '自动', + appendText: '追加', + appendTitle: '在此字段后追加一个类型为“auto”的新字段 (Ctrl+Shift+Ins)', + appendSubmenuTitle: '选择要追加的字段类型', + appendTitleAuto: '追加类型为“auto”的新字段 (Ctrl+Shift+Ins)', + ascending: '升序', + ascendingTitle: '升序排列${type}的子节点', + actionsMenu: '点击打开动作菜单(Ctrl+M)', + cannotParseFieldError: '无法将字段解析为JSON', + cannotParseValueError: '无法将值解析为JSON', + collapseAll: '缩进所有字段', + compactTitle: '压缩JSON数据,删除所有空格 (Ctrl+Shift+\\)', + descending: '降序', + descendingTitle: '降序排列${type}的子节点', + drag: '拖拽移动该节点(Alt+Shift+Arrows)', + duplicateKey: '重复键', + duplicateText: '复制', + duplicateTitle: '复制选中字段(Ctrl+D)', + duplicateField: '复制该字段(Ctrl+D)', + duplicateFieldError: '重复的字段名称', + empty: '清空', + expandAll: '展开所有字段', + expandTitle: '点击 展开/收缩 该字段(Ctrl+E). \n' + 'Ctrl+Click 展开/收缩 包含所有子节点.', + formatTitle: '使用适当的缩进和换行符格式化JSON数据 (Ctrl+\\)', + insert: '插入', + insertTitle: '在此字段前插入类型为“auto”的新字段 (Ctrl+Ins)', + insertSub: '选择要插入的字段类型', + object: '对象', + ok: 'Ok', + redo: '重做 (Ctrl+Shift+Z)', + removeText: '移除', + removeTitle: '移除选中字段 (Ctrl+Del)', + removeField: '移除该字段 (Ctrl+Del)', + repairTitle: '修复JSON:修复引号和转义符,删除注释和JSONP表示法,将JavaScript对象转换为JSON。', + selectNode: '选择一个节点...', + showAll: '展示全部', + showMore: '展示更多', + showMoreStatus: '显示${totalChilds}的${visibleChilds}项目.', + sort: '排序', + sortTitle: '排序${type}的子节点', + sortTitleShort: '内容排序', + sortFieldLabel: '字段:', + sortDirectionLabel: '方向:', + sortFieldTitle: '选择用于对数组或对象排序的嵌套字段', + sortAscending: '升序排序', + sortAscendingTitle: '按照该字段升序排序', + sortDescending: '降序排序', + sortDescendingTitle: '按照该字段降序排序', + string: '字符串', + transform: '变换', + transformTitle: '筛选,排序,或者转换${type}的子节点', + transformTitleShort: '筛选,排序,或者转换内容', + extract: '提取', + extractTitle: '提取这个 ${type}', + transformQueryTitle: '输入JMESPath查询', + transformWizardLabel: '向导', + transformWizardFilter: '筛选', + transformWizardSortBy: '排序', + transformWizardSelectFields: '选择字段', + transformQueryLabel: '查询', + transformPreviewLabel: '预览', + type: '类型', + typeTitle: '更改字段类型', + openUrl: 'Ctrl+Click 或者 Ctrl+Enter 在新窗口打开链接', + undo: '撤销上次动作 (Ctrl+Z)', + validationCannotMove: '无法将字段移入其子节点', + autoType: '字段类型 "auto". ' + '字段类型由值自动确定 ' + '可以为 string,number,boolean,或者 null.', + objectType: '字段类型 "object". ' + '对象包含一组无序的键/值对.', + arrayType: '字段类型 "array". ' + '数组包含值的有序集合.', + stringType: '字段类型 "string". ' + '字段类型由值自动确定,' + '但始终作为字符串返回.', + modeCodeText: '代码', + modeCodeTitle: '切换至代码高亮', + modeFormText: '表单', + modeFormTitle: '切换至表单编辑', + modeTextText: '文本', + modeTextTitle: '切换至文本编辑', + modeTreeText: '树', + modeTreeTitle: '切换至树编辑', + modeViewText: '视图', + modeViewTitle: '切换至树视图', + modePreviewText: '预览', + modePreviewTitle: '切换至预览模式', + examples: '例子', + "default": '缺省', + containsInvalidProperties: '包含无效的属性', + containsInvalidItems: '包含无效项目' + }, + 'pt-BR': { + array: 'Lista', + auto: 'Automatico', + appendText: 'Adicionar', + appendTitle: 'Adicionar novo campo com tipo \'auto\' depois deste campo (Ctrl+Shift+Ins)', + appendSubmenuTitle: 'Selecione o tipo do campo a ser adicionado', + appendTitleAuto: 'Adicionar novo campo com tipo \'auto\' (Ctrl+Shift+Ins)', + ascending: 'Ascendente', + ascendingTitle: 'Organizar filhor do tipo ${type} em crescente', + actionsMenu: 'Clique para abrir o menu de ações (Ctrl+M)', + cannotParseFieldError: 'Não é possível analisar o campo no JSON', + cannotParseValueError: 'Não é possível analisar o valor em JSON', + collapseAll: 'Fechar todos campos', + compactTitle: 'Dados JSON compactos, remova todos os espaços em branco (Ctrl+Shift+\\)', + descending: 'Descendente', + descendingTitle: 'Organizar o filhos do tipo ${type} em decrescente', + duplicateKey: 'chave duplicada', + drag: 'Arraste para mover este campo (Alt+Shift+Arrows)', + duplicateText: 'Duplicar', + duplicateTitle: 'Duplicar campos selecionados (Ctrl+D)', + duplicateField: 'Duplicar este campo (Ctrl+D)', + duplicateFieldError: 'Nome do campo duplicado', + empty: 'vazio', + expandAll: 'Expandir todos campos', + expandTitle: 'Clique para expandir/encolher este campo (Ctrl+E). \n' + 'Ctrl+Click para expandir/encolher incluindo todos os filhos.', + formatTitle: 'Formate dados JSON, com recuo e feeds de linha adequados (Ctrl+\\)', + insert: 'Inserir', + insertTitle: 'Inserir um novo campo do tipo \'auto\' antes deste campo (Ctrl+Ins)', + insertSub: 'Selecionar o tipo de campo a ser inserido', + object: 'Objeto', + ok: 'Ok', + redo: 'Refazer (Ctrl+Shift+Z)', + removeText: 'Remover', + removeTitle: 'Remover campos selecionados (Ctrl+Del)', + removeField: 'Remover este campo (Ctrl+Del)', + repairTitle: 'Repare JSON: corrija aspas e caracteres de escape, remova comentários e notação JSONP, transforme objetos JavaScript em JSON.', + selectNode: 'Selecione um nódulo...', + showAll: 'mostrar todos', + showMore: 'mostrar mais', + showMoreStatus: 'exibindo ${visibleChilds} de ${totalChilds} itens.', + sort: 'Organizar', + sortTitle: 'Organizar os filhos deste ${type}', + sortTitleShort: 'Organizar os filhos', + sortFieldLabel: 'Campo:', + sortDirectionLabel: 'Direção:', + sortFieldTitle: 'Selecione um campo filho pelo qual ordenar o array ou objeto', + sortAscending: 'Ascendente', + sortAscendingTitle: 'Ordenar o campo selecionado por ordem ascendente', + sortDescending: 'Descendente', + sortDescendingTitle: 'Ordenar o campo selecionado por ordem descendente', + string: 'Texto', + transform: 'Transformar', + transformTitle: 'Filtrar, ordenar ou transformar os filhos deste ${type}', + transformTitleShort: 'Filtrar, ordenar ou transformar conteúdos', + transformQueryTitle: 'Insira uma expressão JMESPath', + transformWizardLabel: 'Assistente', + transformWizardFilter: 'Filtro', + transformWizardSortBy: 'Ordenar por', + transformWizardSelectFields: 'Selecionar campos', + transformQueryLabel: 'Expressão', + transformPreviewLabel: 'Visualizar', + type: 'Tipo', + typeTitle: 'Mudar o tipo deste campo', + openUrl: 'Ctrl+Click ou Ctrl+Enter para abrir link em nova janela', + undo: 'Desfazer último ação (Ctrl+Z)', + validationCannotMove: 'Não pode mover um campo como filho dele mesmo', + autoType: 'Campo do tipo "auto". ' + 'O tipo do campo é determinao automaticamente a partir do seu valor ' + 'e pode ser texto, número, verdade/falso ou nulo.', + objectType: 'Campo do tipo "objeto". ' + 'Um objeto contém uma lista de pares com chave e valor.', + arrayType: 'Campo do tipo "lista". ' + 'Uma lista contem uma coleção de valores ordenados.', + stringType: 'Campo do tipo "string". ' + 'Campo do tipo nao é determinado através do seu valor, ' + 'mas sempre retornara um texto.', + examples: 'Exemplos', + "default": 'Revelia', + containsInvalidProperties: 'Contém propriedades inválidas', + containsInvalidItems: 'Contém itens inválidos' + }, + tr: { + array: 'Dizin', + auto: 'Otomatik', + appendText: 'Ekle', + appendTitle: 'Bu alanın altına \'otomatik\' tipinde yeni bir alan ekle (Ctrl+Shift+Ins)', + appendSubmenuTitle: 'Eklenecek alanın tipini seç', + appendTitleAuto: '\'Otomatik\' tipinde yeni bir alan ekle (Ctrl+Shift+Ins)', + ascending: 'Artan', + ascendingTitle: '${type}\'ın alt tiplerini artan düzende sırala', + actionsMenu: 'Aksiyon menüsünü açmak için tıklayın (Ctrl+M)', + collapseAll: 'Tüm alanları kapat', + descending: 'Azalan', + descendingTitle: '${type}\'ın alt tiplerini azalan düzende sırala', + drag: 'Bu alanı taşımak için sürükleyin (Alt+Shift+Arrows)', + duplicateKey: 'Var olan anahtar', + duplicateText: 'Aşağıya kopyala', + duplicateTitle: 'Seçili alanlardan bir daha oluştur (Ctrl+D)', + duplicateField: 'Bu alandan bir daha oluştur (Ctrl+D)', + duplicateFieldError: 'Duplicate field name', + cannotParseFieldError: 'Alan JSON\'a ayrıştırılamıyor', + cannotParseValueError: 'JSON\'a değer ayrıştırılamıyor', + empty: 'boş', + expandAll: 'Tüm alanları aç', + expandTitle: 'Bu alanı açmak/kapatmak için tıkla (Ctrl+E). \n' + 'Alt alanlarda dahil tüm alanları açmak için Ctrl+Click ', + insert: 'Ekle', + insertTitle: 'Bu alanın üstüne \'otomatik\' tipinde yeni bir alan ekle (Ctrl+Ins)', + insertSub: 'Araya eklenecek alanın tipini seç', + object: 'Nesne', + ok: 'Tamam', + redo: 'Yeniden yap (Ctrl+Shift+Z)', + removeText: 'Kaldır', + removeTitle: 'Seçilen alanları kaldır (Ctrl+Del)', + removeField: 'Bu alanı kaldır (Ctrl+Del)', + selectNode: 'Bir nesne seç...', + showAll: 'tümünü göster', + showMore: 'daha fazla göster', + showMoreStatus: '${totalChilds} alanın ${visibleChilds} alt alanları gösteriliyor', + sort: 'Sırala', + sortTitle: '${type}\'ın alt alanlarını sırala', + sortTitleShort: 'İçerikleri sırala', + sortFieldLabel: 'Alan:', + sortDirectionLabel: 'Yön:', + sortFieldTitle: 'Diziyi veya nesneyi sıralamak için iç içe geçmiş alanı seçin', + sortAscending: 'Artan', + sortAscendingTitle: 'Seçili alanı artan düzende sırala', + sortDescending: 'Azalan', + sortDescendingTitle: 'Seçili alanı azalan düzende sırala', + string: 'Karakter Dizisi', + transform: 'Dönüştür', + transformTitle: '${type}\'ın alt alanlarını filtrele, sırala veya dönüştür', + transformTitleShort: 'İçerikleri filterele, sırala veya dönüştür', + transformQueryTitle: 'JMESPath sorgusu gir', + transformWizardLabel: 'Sihirbaz', + transformWizardFilter: 'Filtre', + transformWizardSortBy: 'Sırala', + transformWizardSelectFields: 'Alanları seç', + transformQueryLabel: 'Sorgu', + transformPreviewLabel: 'Önizleme', + type: 'Tip', + typeTitle: 'Bu alanın tipini değiştir', + openUrl: 'URL\'i yeni bir pencerede açmak için Ctrl+Click veya Ctrl+Enter', + undo: 'Son değişikliği geri al (Ctrl+Z)', + validationCannotMove: 'Alt alan olarak taşınamıyor', + autoType: 'Alan tipi "otomatik". ' + 'Alan türü otomatik olarak değerden belirlenir' + 've bir dize, sayı, boolean veya null olabilir.', + objectType: 'Alan tipi "nesne". ' + 'Bir nesne, sıralanmamış bir anahtar / değer çifti kümesi içerir.', + arrayType: 'Alan tipi "dizi". ' + 'Bir dizi, düzenli değerler koleksiyonu içerir.', + stringType: 'Alan tipi "karakter dizisi". ' + 'Alan türü değerden belirlenmez,' + 'ancak her zaman karakter dizisi olarak döndürülür.', + modeCodeText: 'Kod', + modeCodeTitle: 'Kod vurgulayıcıya geç', + modeFormText: 'Form', + modeFormTitle: 'Form düzenleyiciye geç', + modeTextText: 'Metin', + modeTextTitle: 'Düz metin düzenleyiciye geç', + modeTreeText: 'Ağaç', + modeTreeTitle: 'Ağaç düzenleyiciye geç', + modeViewText: 'Görünüm', + modeViewTitle: 'Ağaç görünümüne geç', + examples: 'Örnekler', + "default": 'Varsayılan', + containsInvalidProperties: 'Geçersiz özellikler içeriyor', + containsInvalidItems: 'Geçersiz öğeler içeriyor' + }, + ja: { + array: '配列', + auto: 'オート', + appendText: '追加', + appendTitle: '次のフィールドに"オート"のフィールドを追加 (Ctrl+Shift+Ins)', + appendSubmenuTitle: '追加するフィールドの型を選択してください', + appendTitleAuto: '"オート"のフィールドを追加 (Ctrl+Shift+Ins)', + ascending: '昇順', + ascendingTitle: '${type}の子要素を昇順に並べ替え', + actionsMenu: 'クリックしてアクションメニューを開く (Ctrl+M)', + collapseAll: 'すべてを折りたたむ', + descending: '降順', + descendingTitle: '${type}の子要素を降順に並べ替え', + drag: 'ドラッグして選択中のフィールドを移動 (Alt+Shift+Arrows)', + duplicateKey: '複製キー', + duplicateText: '複製', + duplicateTitle: '選択中のフィールドを複製 (Ctrl+D)', + duplicateField: '選択中のフィールドを複製 (Ctrl+D)', + duplicateFieldError: 'フィールド名が重複しています', + cannotParseFieldError: 'JSONのフィールドを解析できません', + cannotParseValueError: 'JSONの値を解析できません', + empty: '空', + expandAll: 'すべてを展開', + expandTitle: 'クリックしてフィールドを展開/折りたたむ (Ctrl+E). \n' + 'Ctrl+Click ですべての子要素を展開/折りたたむ', + insert: '挿入', + insertTitle: '選択中のフィールドの前に新しいフィールドを挿入 (Ctrl+Ins)', + insertSub: '挿入するフィールドの型を選択', + object: 'オブジェクト', + ok: '実行', + redo: 'やり直す (Ctrl+Shift+Z)', + removeText: '削除', + removeTitle: '選択中のフィールドを削除 (Ctrl+Del)', + removeField: '選択中のフィールドを削除 (Ctrl+Del)', + selectNode: 'ノードを選択...', + showAll: 'すべてを表示', + showMore: 'もっと見る', + showMoreStatus: '${totalChilds}個のアイテムのうち ${visibleChilds}個を表示しています。', + sort: '並べ替え', + sortTitle: '${type}の子要素を並べ替え', + sortTitleShort: '並べ替え', + sortFieldLabel: 'フィールド:', + sortDirectionLabel: '順序:', + sortFieldTitle: '配列またはオブジェクトを並び替えるためのフィールドを選択', + sortAscending: '昇順', + sortAscendingTitle: '選択中のフィールドを昇順に並び替え', + sortDescending: '降順', + sortDescendingTitle: '選択中のフィールドを降順に並び替え', + string: '文字列', + transform: '変換', + transformTitle: '${type}の子要素をフィルター・並び替え・変換する', + transformTitleShort: '内容をフィルター・並び替え・変換する', + extract: '抽出', + extractTitle: '${type}を抽出', + transformQueryTitle: 'JMESPathクエリを入力', + transformWizardLabel: 'ウィザード', + transformWizardFilter: 'フィルター', + transformWizardSortBy: '並び替え', + transformWizardSelectFields: 'フィールドを選択', + transformQueryLabel: 'クエリ', + transformPreviewLabel: 'プレビュー', + type: '型', + typeTitle: '選択中のフィールドの型を変更', + openUrl: 'Ctrl+Click または Ctrl+Enter で 新規ウィンドウでURLを開く', + undo: '元に戻す (Ctrl+Z)', + validationCannotMove: '子要素に移動できません ', + autoType: 'オート: ' + 'フィールドの型は値から自動的に決定されます。 ' + '(文字列・数値・ブール・null)', + objectType: 'オブジェクト: ' + 'オブジェクトは順序が決まっていないキーと値のペア組み合わせです。', + arrayType: '配列: ' + '配列は順序が決まっている値の集合体です。', + stringType: '文字列: ' + 'フィールド型は値から決定されませんが、' + '常に文字列として返されます。', + modeCodeText: 'コードモード', + modeCodeTitle: 'ハイライトモードに切り替え', + modeFormText: 'フォームモード', + modeFormTitle: 'フォームモードに切り替え', + modeTextText: 'テキストモード', + modeTextTitle: 'テキストモードに切り替え', + modeTreeText: 'ツリーモード', + modeTreeTitle: 'ツリーモードに切り替え', + modeViewText: 'ビューモード', + modeViewTitle: 'ビューモードに切り替え', + modePreviewText: 'プレビュー', + modePreviewTitle: 'プレビューに切り替え', + examples: '例', + "default": 'デフォルト', + containsInvalidProperties: '無効なプロパティが含まれています', + containsInvalidItems: '無効なアイテムが含まれています' + }, + 'fr-FR': { + array: 'Liste', + auto: 'Auto', + appendText: 'Ajouter', + appendTitle: 'Ajouter un champ de type \'auto\' après ce champ (Ctrl+Shift+Ins)', + appendSubmenuTitle: 'Sélectionner le type du champ à ajouter', + appendTitleAuto: 'Ajouter un champ de type \'auto\' (Ctrl+Shift+Ins)', + ascending: 'Ascendant', + ascendingTitle: 'Trier les enfants de ce ${type} par ordre ascendant', + actionsMenu: 'Ouvrir le menu des actions (Ctrl+M)', + collapseAll: 'Regrouper', + descending: 'Descendant', + descendingTitle: 'Trier les enfants de ce ${type} par ordre descendant', + drag: 'Déplacer (Alt+Shift+Arrows)', + duplicateKey: 'Dupliquer la clé', + duplicateText: 'Dupliquer', + duplicateTitle: 'Dupliquer les champs sélectionnés (Ctrl+D)', + duplicateField: 'Dupliquer ce champ (Ctrl+D)', + duplicateFieldError: 'Dupliquer le nom de champ', + cannotParseFieldError: 'Champ impossible à parser en JSON', + cannotParseValueError: 'Valeur impossible à parser en JSON', + empty: 'vide', + expandAll: 'Étendre', + expandTitle: 'Étendre/regrouper ce champ (Ctrl+E). \n' + 'Ctrl+Click pour étendre/regrouper avec tous les champs.', + insert: 'Insérer', + insertTitle: 'Insérer un champ de type \'auto\' avant ce champ (Ctrl+Ins)', + insertSub: 'Sélectionner le type de champ à insérer', + object: 'Objet', + ok: 'Ok', + redo: 'Rejouer (Ctrl+Shift+Z)', + removeText: 'Supprimer', + removeTitle: 'Supprimer les champs sélectionnés (Ctrl+Del)', + removeField: 'Supprimer ce champ (Ctrl+Del)', + searchTitle: 'Rechercher champs et valeurs', + searchNextResultTitle: 'Résultat suivant (Enter)', + searchPreviousResultTitle: 'Résultat précédent (Shift + Enter)', + selectNode: 'Sélectionner un nœud...', + showAll: 'voir tout', + showMore: 'voir plus', + showMoreStatus: '${visibleChilds} éléments affichés de ${totalChilds}.', + sort: 'Trier', + sortTitle: 'Trier les champs de ce ${type}', + sortTitleShort: 'Trier', + sortFieldLabel: 'Champ:', + sortDirectionLabel: 'Direction:', + sortFieldTitle: 'Sélectionner les champs permettant de trier les listes et objet', + sortAscending: 'Ascendant', + sortAscendingTitle: 'Trier les champs sélectionnés par ordre ascendant', + sortDescending: 'Descendant', + sortDescendingTitle: 'Trier les champs sélectionnés par ordre descendant', + string: 'Chaîne', + transform: 'Transformer', + transformTitle: 'Filtrer, trier, or transformer les enfants de ce ${type}', + transformTitleShort: 'Filtrer, trier ou transformer le contenu', + extract: 'Extraire', + extractTitle: 'Extraire ce ${type}', + transformQueryTitle: 'Saisir une requête JMESPath', + transformWizardLabel: 'Assistant', + transformWizardFilter: 'Filtrer', + transformWizardSortBy: 'Trier par', + transformWizardSelectFields: 'Sélectionner les champs', + transformQueryLabel: 'Requête', + transformPreviewLabel: 'Prévisualisation', + type: 'Type', + typeTitle: 'Changer le type de ce champ', + openUrl: 'Ctrl+Click ou Ctrl+Enter pour ouvrir l\'url dans une autre fenêtre', + undo: 'Annuler la dernière action (Ctrl+Z)', + validationCannotMove: 'Cannot move a field into a child of itself', + autoType: 'Champe de type "auto". ' + 'Ce type de champ est automatiquement déterminé en fonction de la valeur ' + 'et peut être de type "chaîne", "nombre", "booléen" ou null.', + objectType: 'Champ de type "objet". ' + 'Un objet contient un ensemble non ordonné de paires clé/valeur.', + arrayType: 'Champ de type "liste". ' + 'Une liste contient une collection ordonnée de valeurs.', + stringType: 'Champ de type "chaîne". ' + 'Ce type de champ n\'est pas déterminé en fonction de la valeur, ' + 'mais retourne systématiquement une chaîne de caractères.', + modeEditorTitle: 'Changer mode d\'édition', + modeCodeText: 'Code', + modeCodeTitle: 'Activer surlignage code', + modeFormText: 'Formulaire', + modeFormTitle: 'Activer formulaire', + modeTextText: 'Texte', + modeTextTitle: 'Activer éditeur texte', + modeTreeText: 'Arbre', + modeTreeTitle: 'Activer éditeur arbre', + modeViewText: 'Lecture seule', + modeViewTitle: 'Activer vue arbre', + modePreviewText: 'Prévisualisation', + modePreviewTitle: 'Activer mode prévisualiser', + examples: 'Exemples', + "default": 'Défaut', + containsInvalidProperties: 'Contient des propriétés non valides', + containsInvalidItems: 'Contient des éléments invalides' + }, + de: { + array: 'Auflistung', + auto: 'Auto', + appendText: 'anhängen', + appendTitle: 'Fügen Sie nach diesem Feld ein neues Feld mit dem Typ \'auto\' ein (Strg+Umschalt+Ein)', + appendSubmenuTitle: 'Wählen Sie den Typ des neuen Feldes', + appendTitleAuto: 'Ein neues Feld vom Typ \'auto\' hinzufügen (Strg+Umschalt+Ein)', + ascending: 'Aufsteigend', + ascendingTitle: 'Sortieren Sie die Elemente dieses ${type} in aufsteigender Reihenfolge', + actionsMenu: 'Klicken Sie zum Öffnen des Aktionsmenüs (Strg+M)', + cannotParseFieldError: 'Feld kann nicht in JSON geparst werden', + cannotParseValueError: 'Wert kann nicht in JSON geparst werden', + collapseAll: 'Alle Felder zuklappen', + compactTitle: 'JSON-Daten verdichten, alle Leerzeichen entfernen (Strg+Umschalt+\\)', + descending: 'Absteigend', + descendingTitle: 'Sortieren Sie die Elemente dieses ${type} in absteigender Reihenfolge', + drag: 'Ziehen, um dieses Feld zu verschieben (Alt+Umschalt+Pfeile)', + duplicateKey: 'Doppelter Schlüssel', + duplicateText: 'Duplikat', + duplicateTitle: 'Ausgewählte Felder duplizieren (Strg+D)', + duplicateField: 'Dieses Feld duplizieren (Strg+D)', + duplicateFieldError: 'Doppelter Feldname', + empty: 'leer', + expandAll: 'Alle Felder anzeigen', + expandTitle: 'Klicken Sie, um dieses Feld zu erweitern/zu kollabieren (Strg+E). \nStrg+Klicken Sie, um dieses Feld einschließlich aller Elemente zu erweitern/zu kollabieren.', + formatTitle: 'JSON-Daten mit korrekter Einrückung und Zeilenvorschüben formatieren (Strg+\\)', + insert: 'einfügen', + insertTitle: 'Fügen Sie vor diesem Feld ein neues Feld mit dem Typ \'auto\' ein (Strg+Einfg)', + insertSub: 'Wählen Sie den Typ des neuen Feldes', + object: 'Objekt', + ok: 'Ok', + redo: 'Wiederholen (Strg+Umschalt+Z)', + removeText: 'entfernen', + removeTitle: 'Ausgewählte Felder entfernen (Strg+Entf)', + removeField: 'Dieses Feld entfernen (Strg+Entf)', + repairTitle: 'JSON reparieren: Anführungszeichen und Escape-Zeichen korrigieren, Kommentare und JSONP-Notation entfernen, JavaScript-Objekte in JSON umwandeln.', + searchTitle: 'Suchfelder und Werte', + searchNextResultTitle: 'Nächstes Ergebnis (Enter)', + searchPreviousResultTitle: 'Vorheriges Ergebnis (Umschalt + Eingabe)', + selectNode: 'Wählen Sie einen Knoten aus...', + showAll: 'alle anzeigen', + showMore: 'mehr anzeigen', + showMoreStatus: 'Anzeige von ${visibleChilds} von ${totalChilds}-Elementen.', + sort: 'Sortieren', + sortTitle: 'Sortieren Sie die Elemente dieses ${type}', + sortTitleShort: 'Inhalt sortieren', + sortFieldLabel: 'Feld:', + sortDirectionLabel: 'Richtung:', + sortFieldTitle: 'Wählen Sie das verschachtelte Feld, nach dem das Array oder Objekt sortiert werden soll.', + sortAscending: 'Aufsteigend', + sortAscendingTitle: 'Sortieren Sie das ausgewählte Feld in aufsteigender Reihenfolge', + sortDescending: 'Absteigend', + sortDescendingTitle: 'Sortieren Sie das ausgewählte Feld in absteigender Reihenfolge', + string: 'Zeichenfolge', + transform: 'Verwandeln', + transformTitle: 'Die Elemente dieses ${type} filtern, sortieren oder transformieren', + transformTitleShort: 'Inhalte filtern, sortieren oder transformieren', + extract: 'Auszug', + extractTitle: 'Extrahieren Sie diesen ${type}', + transformQueryTitle: 'Eine JMESPath-Abfrage eingeben', + transformWizardLabel: 'Zauberer', + transformWizardFilter: 'Filter', + transformWizardSortBy: 'Sortieren nach', + transformWizardSelectFields: 'Felder auswählen', + transformQueryLabel: 'Anfrage', + transformPreviewLabel: 'Vorschau', + type: 'Geben Sie ein.', + typeTitle: 'Ändern Sie den Typ dieses Feldes', + openUrl: 'Strg+Klicken oder Strg+Eingabe, um die URL in einem neuen Fenster zu öffnen', + undo: 'Letzte Aktion rückgängig machen (Strg+Z)', + validationCannotMove: 'Kann ein Feld nicht in ein Kind seiner selbst verschieben', + autoType: 'Feldtyp "auto". Der Feldtyp wird automatisch aus dem Wert bestimmt und kann ein String, eine Zahl, boolesch oder null sein.', + objectType: 'Feldtyp "Objekt". Ein Objekt enthält eine ungeordnete Menge von Schlüssel/Wert-Paaren.', + arrayType: 'Feldtyp "Array". Ein Array enthält eine geordnete Sammlung von Werten.', + stringType: 'Feldtyp "Zeichenfolge". Der Feldtyp wird nicht aus dem Wert bestimmt, sondern immer als Zeichenfolge zurückgegeben.', + modeEditorTitle: 'Editor-Modus umschalten', + modeCodeText: 'Code', + modeCodeTitle: 'Umschalten auf Code-Highlighter', + modeFormText: 'Formular', + modeFormTitle: 'Zum Formular-Editor wechseln', + modeTextText: 'Text', + modeTextTitle: 'Zum Editor für einfachen Text wechseln', + modeTreeText: 'Baum', + modeTreeTitle: 'Zum Baum-Editor wechseln', + modeViewText: 'Siehe', + modeViewTitle: 'Zur Baumansicht wechseln', + modePreviewText: 'Vorschau', + modePreviewTitle: 'In den Vorschau-Modus wechseln', + examples: 'Beispiele', + "default": 'Standardmäßig', + containsInvalidProperties: 'Enthält ungültige Eigenschaften', + containsInvalidItems: 'Enthält ungültige Elemente' + } +}; +var _defaultLang = 'en'; +var userLang = typeof navigator !== 'undefined' ? navigator.language || navigator.userLanguage : undefined; + +var _lang = _locales.find(function (l) { + return l === userLang; +}) || _defaultLang; + +function setLanguage(lang) { + if (!lang) { + return; + } + + var langFound = _locales.find(function (l) { + return l === lang; + }); + + if (langFound) { + _lang = langFound; + } else { + console.error('Language not found'); + } +} +function setLanguages(languages) { + if (!languages) { + return; + } + + var _loop = function _loop(language) { + var langFound = _locales.find(function (l) { + return l === language; + }); + + if (!langFound) { + _locales.push(language); + } + + _defs[language] = Object.assign({}, _defs[_defaultLang], _defs[language], languages[language]); + }; + + for (var language in languages) { + _loop(language); + } +} +function translate(key, data, lang) { + if (!lang) { + lang = _lang; + } + + var text = _defs[lang][key] || _defs[_defaultLang][key] || key; + + if (data) { + for (var dataKey in data) { + text = text.replace('${' + dataKey + '}', data[dataKey]); + } + } + + return text; +} + +/***/ }), + +/***/ 6056: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "r": function() { return /* binding */ createQuery; }, +/* harmony export */ "J": function() { return /* binding */ executeQuery; } +/* harmony export */ }); +/* harmony import */ var jmespath__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5156); +/* harmony import */ var jmespath__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jmespath__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9791); + + +/** + * Build a JMESPath query based on query options coming from the wizard + * @param {JSON} json The JSON document for which to build the query. + * Used for context information like determining + * the type of values (string or number) + * @param {QueryOptions} queryOptions + * @return {string} Returns a query (as string) + */ + +function createQuery(json, queryOptions) { + var sort = queryOptions.sort, + filter = queryOptions.filter, + projection = queryOptions.projection; + var query = ''; + + if (filter) { + var examplePath = filter.field !== '@' ? ['0'].concat((0,_util__WEBPACK_IMPORTED_MODULE_1__.parsePath)('.' + filter.field)) : ['0']; + var exampleValue = (0,_util__WEBPACK_IMPORTED_MODULE_1__.get)(json, examplePath); + var value1 = typeof exampleValue === 'string' ? filter.value : (0,_util__WEBPACK_IMPORTED_MODULE_1__.parseString)(filter.value); + query += '[? ' + filter.field + ' ' + filter.relation + ' ' + '`' + JSON.stringify(value1) + '`' + ']'; + } else { + query += Array.isArray(json) ? '[*]' : '@'; + } + + if (sort) { + if (sort.direction === 'desc') { + query += ' | reverse(sort_by(@, &' + sort.field + '))'; + } else { + query += ' | sort_by(@, &' + sort.field + ')'; + } + } + + if (projection) { + if (query[query.length - 1] !== ']') { + query += ' | [*]'; + } + + if (projection.fields.length === 1) { + query += '.' + projection.fields[0]; + } else if (projection.fields.length > 1) { + query += '.{' + projection.fields.map(function (value) { + var parts = value.split('.'); + var last = parts[parts.length - 1]; + return last + ': ' + value; + }).join(', ') + '}'; + } else {// values.length === 0 + // ignore + } + } + + return query; +} +/** + * Execute a JMESPath query + * @param {JSON} json + * @param {string} query + * @return {JSON} Returns the transformed JSON + */ + +function executeQuery(json, query) { + return jmespath__WEBPACK_IMPORTED_MODULE_0___default().search(json, query); +} + +/***/ }), + +/***/ 4987: +/***/ (function() { + +if (typeof Element !== 'undefined') { + // Polyfill for array remove + (function () { + function polyfill(item) { + if ('remove' in item) { + return; + } + + Object.defineProperty(item, 'remove', { + configurable: true, + enumerable: true, + writable: true, + value: function remove() { + if (this.parentNode !== undefined) { + this.parentNode.removeChild(this); + } + } + }); + } + + if (typeof window.Element !== 'undefined') { + polyfill(window.Element.prototype); + } + + if (typeof window.CharacterData !== 'undefined') { + polyfill(window.CharacterData.prototype); + } + + if (typeof window.DocumentType !== 'undefined') { + polyfill(window.DocumentType.prototype); + } + })(); +} // simple polyfill for Array.findIndex + + +if (!Array.prototype.findIndex) { + // eslint-disable-next-line no-extend-native + Object.defineProperty(Array.prototype, 'findIndex', { + value: function value(predicate) { + for (var i = 0; i < this.length; i++) { + var element = this[i]; + + if (predicate.call(this, element, i, this)) { + return i; + } + } + + return -1; + }, + configurable: true, + writable: true + }); +} // Polyfill for Array.find + + +if (!Array.prototype.find) { + // eslint-disable-next-line no-extend-native + Object.defineProperty(Array.prototype, 'find', { + value: function value(predicate) { + var i = this.findIndex(predicate); + return this[i]; + }, + configurable: true, + writable: true + }); +} // Polyfill for String.trim + + +if (!String.prototype.trim) { + // eslint-disable-next-line no-extend-native + String.prototype.trim = function () { + return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + }; +} + +/***/ }), + +/***/ 341: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +// ESM COMPAT FLAG +__webpack_require__.r(__webpack_exports__); + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "previewModeMixins": function() { return /* binding */ previewModeMixins; } +}); + +// EXTERNAL MODULE: ./node_modules/jsonrepair/lib/cjs/index-commonjs.js +var index_commonjs = __webpack_require__(8909); +var index_commonjs_default = /*#__PURE__*/__webpack_require__.n(index_commonjs); +// EXTERNAL MODULE: ./src/js/constants.js +var constants = __webpack_require__(4188); +// EXTERNAL MODULE: ./src/js/ErrorTable.js +var ErrorTable = __webpack_require__(6436); +// EXTERNAL MODULE: ./src/js/FocusTracker.js +var FocusTracker = __webpack_require__(2474); +;// CONCATENATED MODULE: ./src/js/History.js +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +/** + * Keep track on any history, be able + * @param {function} onChange + * @param {function} calculateItemSize + * @param {number} limit Maximum size of all items in history + * @constructor + */ +var History = /*#__PURE__*/function () { + function History(onChange, calculateItemSize, limit) { + _classCallCheck(this, History); + + this.onChange = onChange; + + this.calculateItemSize = calculateItemSize || function () { + return 1; + }; + + this.limit = limit; + this.items = []; + this.index = -1; + } + + _createClass(History, [{ + key: "add", + value: function add(item) { + // limit number of items in history so that the total size doesn't + // always keep at least one item in memory + while (this._calculateHistorySize() > this.limit && this.items.length > 1) { + this.items.shift(); + this.index--; + } // cleanup any redo action that are not valid anymore + + + this.items = this.items.slice(0, this.index + 1); + this.items.push(item); + this.index++; + this.onChange(); + } + }, { + key: "_calculateHistorySize", + value: function _calculateHistorySize() { + var calculateItemSize = this.calculateItemSize; + var totalSize = 0; + this.items.forEach(function (item) { + totalSize += calculateItemSize(item); + }); + return totalSize; + } + }, { + key: "undo", + value: function undo() { + if (!this.canUndo()) { + return; + } + + this.index--; + this.onChange(); + return this.items[this.index]; + } + }, { + key: "redo", + value: function redo() { + if (!this.canRedo()) { + return; + } + + this.index++; + this.onChange(); + return this.items[this.index]; + } + }, { + key: "canUndo", + value: function canUndo() { + return this.index > 0; + } + }, { + key: "canRedo", + value: function canRedo() { + return this.index < this.items.length - 1; + } + }, { + key: "clear", + value: function clear() { + this.items = []; + this.index = -1; + this.onChange(); + } + }]); + + return History; +}(); +// EXTERNAL MODULE: ./src/js/i18n.js +var i18n = __webpack_require__(7907); +// EXTERNAL MODULE: ./src/js/jmespathQuery.js +var jmespathQuery = __webpack_require__(6056); +// EXTERNAL MODULE: ./src/js/ModeSwitcher.js +var ModeSwitcher = __webpack_require__(6617); +// EXTERNAL MODULE: ./src/js/showSortModal.js +var showSortModal = __webpack_require__(6210); +// EXTERNAL MODULE: ./src/js/showTransformModal.js + 1 modules +var showTransformModal = __webpack_require__(2558); +// EXTERNAL MODULE: ./src/js/textmode.js + 1 modules +var textmode = __webpack_require__(5956); +// EXTERNAL MODULE: ./src/js/util.js +var util = __webpack_require__(9791); +;// CONCATENATED MODULE: ./src/js/previewmode.js + + + + + + + + + + + + + + +var previewmode_textmode = textmode.textModeMixins[0].mixin; // create a mixin with the functions for text mode + +var previewmode = {}; +/** + * Create a JSON document preview, suitable for processing of large documents + * @param {Element} container + * @param {Object} [options] Object with options. See docs for details. + * @private + */ + +previewmode.create = function (container) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (typeof options.statusBar === 'undefined') { + options.statusBar = true; + } // setting default for previewmode + + + options.mainMenuBar = options.mainMenuBar !== false; + options.enableSort = options.enableSort !== false; + options.enableTransform = options.enableTransform !== false; + options.createQuery = options.createQuery || jmespathQuery/* createQuery */.r; + options.executeQuery = options.executeQuery || jmespathQuery/* executeQuery */.J; + this.options = options; // indentation + + if (typeof options.indentation === 'number') { + this.indentation = Number(options.indentation); + } else { + this.indentation = 2; // number of spaces + } // language + + + (0,i18n/* setLanguages */.cC)(this.options.languages); + (0,i18n/* setLanguage */.m0)(this.options.language); // determine mode + + this.mode = 'preview'; + var me = this; + this.container = container; + this.dom = {}; + this.json = undefined; + this.text = ''; // TODO: JSON Schema support + // create a debounced validate function + + this._debouncedValidate = (0,util.debounce)(this.validate.bind(this), this.DEBOUNCE_INTERVAL); + this.width = container.clientWidth; + this.height = container.clientHeight; + this.frame = document.createElement('div'); + this.frame.className = 'jsoneditor jsoneditor-mode-preview'; + + this.frame.onclick = function (event) { + // prevent default submit action when the editor is located inside a form + event.preventDefault(); + }; // setting the FocusTracker on 'this.frame' to track the editor's focus event + + + var focusTrackerConfig = { + target: this.frame, + onFocus: this.options.onFocus || null, + onBlur: this.options.onBlur || null + }; + this.frameFocusTracker = new FocusTracker/* FocusTracker */.R(focusTrackerConfig); + this.content = document.createElement('div'); + this.content.className = 'jsoneditor-outer'; + this.dom.busy = document.createElement('div'); + this.dom.busy.className = 'jsoneditor-busy'; + this.dom.busyContent = document.createElement('span'); + this.dom.busyContent.textContent = 'busy...'; + this.dom.busy.appendChild(this.dom.busyContent); + this.content.appendChild(this.dom.busy); + this.dom.previewContent = document.createElement('pre'); + this.dom.previewContent.className = 'jsoneditor-preview'; + this.dom.previewText = document.createTextNode(''); + this.dom.previewContent.appendChild(this.dom.previewText); + this.content.appendChild(this.dom.previewContent); + + if (this.options.mainMenuBar) { + (0,util.addClassName)(this.content, 'has-main-menu-bar'); // create menu + + this.menu = document.createElement('div'); + this.menu.className = 'jsoneditor-menu'; + this.frame.appendChild(this.menu); // create format button + + var buttonFormat = document.createElement('button'); + buttonFormat.type = 'button'; + buttonFormat.className = 'jsoneditor-format'; + buttonFormat.title = (0,i18n/* translate */.Iu)('formatTitle'); + this.menu.appendChild(buttonFormat); + + buttonFormat.onclick = function handleFormat() { + me.executeWithBusyMessage(function () { + try { + me.format(); + } catch (err) { + me._onError(err); + } + }, 'formatting...'); + }; // create compact button + + + var buttonCompact = document.createElement('button'); + buttonCompact.type = 'button'; + buttonCompact.className = 'jsoneditor-compact'; + buttonCompact.title = (0,i18n/* translate */.Iu)('compactTitle'); + this.menu.appendChild(buttonCompact); + + buttonCompact.onclick = function handleCompact() { + me.executeWithBusyMessage(function () { + try { + me.compact(); + } catch (err) { + me._onError(err); + } + }, 'compacting...'); + }; // create sort button + + + if (this.options.enableSort) { + var _sort = document.createElement('button'); + + _sort.type = 'button'; + _sort.className = 'jsoneditor-sort'; + _sort.title = (0,i18n/* translate */.Iu)('sortTitleShort'); + + _sort.onclick = function () { + me._showSortModal(); + }; + + this.menu.appendChild(_sort); + } // create transform button + + + if (this.options.enableTransform) { + var transform = document.createElement('button'); + transform.type = 'button'; + transform.title = (0,i18n/* translate */.Iu)('transformTitleShort'); + transform.className = 'jsoneditor-transform'; + + transform.onclick = function () { + me._showTransformModal(); + }; + + this.dom.transform = transform; + this.menu.appendChild(transform); + } // create repair button + + + var buttonRepair = document.createElement('button'); + buttonRepair.type = 'button'; + buttonRepair.className = 'jsoneditor-repair'; + buttonRepair.title = (0,i18n/* translate */.Iu)('repairTitle'); + this.menu.appendChild(buttonRepair); + + buttonRepair.onclick = function () { + if (me.json === undefined) { + // only repair if we don't have valid JSON + me.executeWithBusyMessage(function () { + try { + me.repair(); + } catch (err) { + me._onError(err); + } + }, 'repairing...'); + } + }; // create history and undo/redo buttons + + + if (this.options.history !== false) { + // default option value is true + var onHistoryChange = function onHistoryChange() { + me.dom.undo.disabled = !me.history.canUndo(); + me.dom.redo.disabled = !me.history.canRedo(); + }; + + var calculateItemSize = function calculateItemSize(item) { + return (// times two to account for the json object + item.text.length * 2 + ); + }; + + this.history = new History(onHistoryChange, calculateItemSize, constants/* PREVIEW_HISTORY_LIMIT */.oW); // create undo button + + var undo = document.createElement('button'); + undo.type = 'button'; + undo.className = 'jsoneditor-undo jsoneditor-separator'; + undo.title = (0,i18n/* translate */.Iu)('undo'); + + undo.onclick = function () { + var action = me.history.undo(); + + if (action) { + me._applyHistory(action); + } + }; + + this.menu.appendChild(undo); + this.dom.undo = undo; // create redo button + + var redo = document.createElement('button'); + redo.type = 'button'; + redo.className = 'jsoneditor-redo'; + redo.title = (0,i18n/* translate */.Iu)('redo'); + + redo.onclick = function () { + var action = me.history.redo(); + + if (action) { + me._applyHistory(action); + } + }; + + this.menu.appendChild(redo); + this.dom.redo = redo; // force enabling/disabling the undo/redo button + + this.history.onChange(); + } // create mode box + + + if (this.options && this.options.modes && this.options.modes.length) { + this.modeSwitcher = new ModeSwitcher/* ModeSwitcher */.x(this.menu, this.options.modes, this.options.mode, function onSwitch(mode) { + // switch mode and restore focus + me.setMode(mode); + me.modeSwitcher.focus(); + }); + } + } + + this.errorTable = new ErrorTable/* ErrorTable */.Q({ + errorTableVisible: true, + onToggleVisibility: function onToggleVisibility() { + me.validate(); + }, + onFocusLine: null, + onChangeHeight: function onChangeHeight(height) { + // TODO: change CSS to using flex box, remove setting height using JavaScript + var statusBarHeight = me.dom.statusBar ? me.dom.statusBar.clientHeight : 0; + var totalHeight = height + statusBarHeight + 1; + me.content.style.marginBottom = -totalHeight + 'px'; + me.content.style.paddingBottom = totalHeight + 'px'; + } + }); + this.frame.appendChild(this.content); + this.frame.appendChild(this.errorTable.getErrorTable()); + this.container.appendChild(this.frame); + + if (options.statusBar) { + (0,util.addClassName)(this.content, 'has-status-bar'); + var statusBar = document.createElement('div'); + this.dom.statusBar = statusBar; + statusBar.className = 'jsoneditor-statusbar'; + this.frame.appendChild(statusBar); + this.dom.fileSizeInfo = document.createElement('span'); + this.dom.fileSizeInfo.className = 'jsoneditor-size-info'; + this.dom.fileSizeInfo.innerText = ''; + statusBar.appendChild(this.dom.fileSizeInfo); + this.dom.arrayInfo = document.createElement('span'); + this.dom.arrayInfo.className = 'jsoneditor-size-info'; + this.dom.arrayInfo.innerText = ''; + statusBar.appendChild(this.dom.arrayInfo); + statusBar.appendChild(this.errorTable.getErrorCounter()); + statusBar.appendChild(this.errorTable.getWarningIcon()); + statusBar.appendChild(this.errorTable.getErrorIcon()); + } + + this._renderPreview(); + + this.setSchema(this.options.schema, this.options.schemaRefs); +}; + +previewmode._renderPreview = function () { + var text = this.getText(); + this.dom.previewText.nodeValue = (0,util.limitCharacters)(text, constants/* MAX_PREVIEW_CHARACTERS */.WF); + + if (this.dom.fileSizeInfo) { + this.dom.fileSizeInfo.innerText = 'Size: ' + (0,util.formatSize)(text.length); + } + + if (this.dom.arrayInfo) { + if (Array.isArray(this.json)) { + this.dom.arrayInfo.innerText = 'Array: ' + this.json.length + ' items'; + } else { + this.dom.arrayInfo.innerText = ''; + } + } +}; +/** + * Handle a change: + * - Validate JSON schema + * - Send a callback to the onChange listener if provided + * @private + */ + + +previewmode._onChange = function () { + // validate JSON schema (if configured) + this._debouncedValidate(); // trigger the onChange callback + + + if (this.options.onChange) { + try { + this.options.onChange(); + } catch (err) { + console.error('Error in onChange callback: ', err); + } + } // trigger the onChangeJSON callback + + + if (this.options.onChangeJSON) { + try { + this.options.onChangeJSON(this.get()); + } catch (err) { + console.error('Error in onChangeJSON callback: ', err); + } + } // trigger the onChangeText callback + + + if (this.options.onChangeText) { + try { + this.options.onChangeText(this.getText()); + } catch (err) { + console.error('Error in onChangeText callback: ', err); + } + } +}; +/** + * Open a sort modal + * @private + */ + + +previewmode._showSortModal = function () { + var me = this; + + function onSort(json, sortedBy) { + if (Array.isArray(json)) { + var sortedArray = (0,util.sort)(json, sortedBy.path, sortedBy.direction); + me.sortedBy = sortedBy; + + me._setAndFireOnChange(sortedArray); + } + + if ((0,util.isObject)(json)) { + var sortedObject = (0,util.sortObjectKeys)(json, sortedBy.direction); + me.sortedBy = sortedBy; + + me._setAndFireOnChange(sortedObject); + } + } + + this.executeWithBusyMessage(function () { + var container = me.options.modalAnchor || constants/* DEFAULT_MODAL_ANCHOR */.qD; + var json = me.get(); + + me._renderPreview(); // update array count + + + (0,showSortModal.showSortModal)(container, json, function (sortedBy) { + me.executeWithBusyMessage(function () { + onSort(json, sortedBy); + }, 'sorting...'); + }, me.sortedBy); + }, 'parsing...'); +}; +/** + * Open a transform modal + * @private + */ + + +previewmode._showTransformModal = function () { + var _this = this; + + this.executeWithBusyMessage(function () { + var _this$options = _this.options, + createQuery = _this$options.createQuery, + executeQuery = _this$options.executeQuery, + modalAnchor = _this$options.modalAnchor, + queryDescription = _this$options.queryDescription; + + var json = _this.get(); + + _this._renderPreview(); // update array count + + + (0,showTransformModal.showTransformModal)({ + container: modalAnchor || constants/* DEFAULT_MODAL_ANCHOR */.qD, + json: json, + queryDescription: queryDescription, + // can be undefined + createQuery: createQuery, + executeQuery: executeQuery, + onTransform: function onTransform(query) { + _this.executeWithBusyMessage(function () { + var updatedJson = executeQuery(json, query); + + _this._setAndFireOnChange(updatedJson); + }, 'transforming...'); + } + }); + }, 'parsing...'); +}; +/** + * Destroy the editor. Clean up DOM, event listeners, and web workers. + */ + + +previewmode.destroy = function () { + if (this.frame && this.container && this.frame.parentNode === this.container) { + this.container.removeChild(this.frame); + } + + if (this.modeSwitcher) { + this.modeSwitcher.destroy(); + this.modeSwitcher = null; + } + + this._debouncedValidate = null; + + if (this.history) { + this.history.clear(); + this.history = null; + } // Removing the FocusTracker set to track the editor's focus event + + + this.frameFocusTracker.destroy(); +}; +/** + * Compact the code in the text editor + */ + + +previewmode.compact = function () { + var json = this.get(); + var text = JSON.stringify(json); // we know that in this case the json is still the same, so we pass json too + + this._setTextAndFireOnChange(text, json); +}; +/** + * Format the code in the text editor + */ + + +previewmode.format = function () { + var json = this.get(); + var text = JSON.stringify(json, null, this.indentation); // we know that in this case the json is still the same, so we pass json too + + this._setTextAndFireOnChange(text, json); +}; +/** + * Repair the code in the text editor + */ + + +previewmode.repair = function () { + var text = this.getText(); + + try { + var repairedText = index_commonjs_default()(text); + + this._setTextAndFireOnChange(repairedText); + } catch (err) {// repair was not successful, do nothing + } +}; +/** + * Set focus to the editor + */ + + +previewmode.focus = function () { + // we don't really have a place to focus, + // let's focus on the transform button + this.dom.transform.focus(); +}; +/** + * Set json data in the editor + * @param {*} json + */ + + +previewmode.set = function (json) { + if (this.history) { + this.history.clear(); + } + + this._set(json); +}; +/** + * Update data. Same as calling `set` in text/code mode. + * @param {*} json + */ + + +previewmode.update = function (json) { + this._set(json); +}; +/** + * Set json data + * @param {*} json + */ + + +previewmode._set = function (json) { + this.text = undefined; + this.json = json; + + this._renderPreview(); + + this._pushHistory(); // validate JSON schema + + + this._debouncedValidate(); +}; + +previewmode._setAndFireOnChange = function (json) { + this._set(json); + + this._onChange(); +}; +/** + * Get json data + * @return {*} json + */ + + +previewmode.get = function () { + if (this.json === undefined) { + var text = this.getText(); + this.json = (0,util.parse)(text); // this can throw an error + } + + return this.json; +}; +/** + * Get the text contents of the editor + * @return {String} jsonText + */ + + +previewmode.getText = function () { + if (this.text === undefined) { + this.text = JSON.stringify(this.json, null, this.indentation); + + if (this.options.escapeUnicode === true) { + this.text = (0,util.escapeUnicodeChars)(this.text); + } + } + + return this.text; +}; +/** + * Set the text contents of the editor + * @param {String} jsonText + */ + + +previewmode.setText = function (jsonText) { + if (this.history) { + this.history.clear(); + } + + this._setText(jsonText); +}; +/** + * Update the text contents + * @param {string} jsonText + */ + + +previewmode.updateText = function (jsonText) { + // don't update if there are no changes + if (this.getText() === jsonText) { + return; + } + + this._setText(jsonText); +}; +/** + * Set the text contents of the editor + * @param {string} jsonText + * @param {*} [json] Optional JSON instance of the text + * @private + */ + + +previewmode._setText = function (jsonText, json) { + if (this.options.escapeUnicode === true) { + this.text = (0,util.escapeUnicodeChars)(jsonText); + } else { + this.text = jsonText; + } + + this.json = json; + + this._renderPreview(); + + if (this.json === undefined) { + var me = this; + this.executeWithBusyMessage(function () { + try { + // force parsing the json now, else it will be done in validate without feedback + me.json = me.get(); + + me._renderPreview(); + + me._pushHistory(); + } catch (err) {// no need to throw an error, validation will show an error + } + }, 'parsing...'); + } else { + this._pushHistory(); + } + + this._debouncedValidate(); +}; +/** + * Set text and fire onChange callback + * @param {string} jsonText + * @param {*} [json] Optional JSON instance of the text + * @private + */ + + +previewmode._setTextAndFireOnChange = function (jsonText, json) { + this._setText(jsonText, json); + + this._onChange(); +}; +/** + * Apply history to the current state + * @param {{json?: JSON, text?: string}} action + * @private + */ + + +previewmode._applyHistory = function (action) { + this.json = action.json; + this.text = action.text; + + this._renderPreview(); + + this._debouncedValidate(); +}; +/** + * Push the current state to history + * @private + */ + + +previewmode._pushHistory = function () { + if (!this.history) { + return; + } + + var action = { + text: this.text, + json: this.json + }; + this.history.add(action); +}; +/** + * Execute a heavy, blocking action. + * Before starting the action, show a message on screen like "parsing..." + * @param {function} fn + * @param {string} message + */ + + +previewmode.executeWithBusyMessage = function (fn, message) { + var size = this.getText().length; + + if (size > constants/* SIZE_LARGE */.EX) { + var me = this; + (0,util.addClassName)(me.frame, 'busy'); + me.dom.busyContent.innerText = message; + setTimeout(function () { + fn(); + (0,util.removeClassName)(me.frame, 'busy'); + me.dom.busyContent.innerText = ''; + }, 100); + } else { + fn(); + } +}; // TODO: refactor into composable functions instead of this shaky mixin-like structure + + +previewmode.validate = previewmode_textmode.validate; +previewmode._renderErrors = previewmode_textmode._renderErrors; // define modes + +var previewModeMixins = [{ + mode: 'preview', + mixin: previewmode, + data: 'json' +}]; + +/***/ }), + +/***/ 6210: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "showSortModal": function() { return /* binding */ showSortModal; } +/* harmony export */ }); +/* harmony import */ var picomodal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(483); +/* harmony import */ var picomodal__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(picomodal__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7907); +/* harmony import */ var _util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9791); + + + +/** + * Show advanced sorting modal + * @param {HTMLElement} container The container where to center + * the modal and create an overlay + * @param {JSON} json The JSON data to be sorted. + * @param {function} onSort Callback function, invoked with + * an object containing the selected + * path and direction + * @param {Object} options + * Available options: + * - {string} path The selected path + * - {'asc' | 'desc'} direction The selected direction + */ + +function showSortModal(container, json, onSort, options) { + var paths = Array.isArray(json) ? (0,_util__WEBPACK_IMPORTED_MODULE_2__.getChildPaths)(json) : ['']; + var selectedPath = options && options.path && (0,_util__WEBPACK_IMPORTED_MODULE_2__.contains)(paths, options.path) ? options.path : paths[0]; + var selectedDirection = options && options.direction || 'asc'; + var content = '
    ' + '
    ' + (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('sort') + '
    ' + '
    ' + '' + '' + '' + ' ' + ' ' + '' + '' + ' ' + ' ' + '' + '' + '' + '' + '' + '
    ' + (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('sortFieldLabel') + ' ' + '
    ' + ' ' + '
    ' + '
    ' + (0,_i18n__WEBPACK_IMPORTED_MODULE_1__/* .translate */ .Iu)('sortDirectionLabel') + ' ' + '
    ' + '' + '' + '
    ' + '
    ' + ' ' + '
    ' + '
    ' + '
    '; + picomodal__WEBPACK_IMPORTED_MODULE_0___default()({ + parent: container, + content: content, + overlayClass: 'jsoneditor-modal-overlay', + overlayStyles: { + backgroundColor: 'rgb(1,1,1)', + opacity: 0.3 + }, + modalClass: 'jsoneditor-modal jsoneditor-modal-sort' + }).afterCreate(function (modal) { + var form = modal.modalElem().querySelector('form'); + var ok = modal.modalElem().querySelector('#ok'); + var field = modal.modalElem().querySelector('#field'); + var direction = modal.modalElem().querySelector('#direction'); + + function preprocessPath(path) { + return path === '' ? '@' : path[0] === '.' ? path.slice(1) : path; + } + + paths.forEach(function (path) { + var option = document.createElement('option'); + option.text = preprocessPath(path); + option.value = path; + field.appendChild(option); + }); + + function setDirection(value) { + direction.value = value; + direction.className = 'jsoneditor-button-group jsoneditor-button-group-value-' + direction.value; + } + + field.value = selectedPath || paths[0]; + setDirection(selectedDirection || 'asc'); + + direction.onclick = function (event) { + setDirection(event.target.getAttribute('data-value')); + }; + + ok.onclick = function (event) { + event.preventDefault(); + event.stopPropagation(); + modal.close(); + onSort({ + path: field.value, + direction: direction.value + }); + }; + + if (form) { + // form is not available when JSONEditor is created inside a form + form.onsubmit = ok.onclick; + } + }).afterClose(function (modal) { + modal.destroy(); + }).show(); +} + +/***/ }), + +/***/ 2558: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +// ESM COMPAT FLAG +__webpack_require__.r(__webpack_exports__); + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "showTransformModal": function() { return /* binding */ showTransformModal; } +}); + +// EXTERNAL MODULE: ./node_modules/picomodal/src/picoModal.js +var picoModal = __webpack_require__(483); +var picoModal_default = /*#__PURE__*/__webpack_require__.n(picoModal); +// EXTERNAL MODULE: ./src/js/assets/selectr/selectr.js +var selectr = __webpack_require__(3879); +var selectr_default = /*#__PURE__*/__webpack_require__.n(selectr); +// EXTERNAL MODULE: ./src/js/i18n.js +var i18n = __webpack_require__(7907); +;// CONCATENATED MODULE: ./src/js/jsonUtils.js + +/** + * Convert part of a JSON object to a JSON string. + * Use case is to stringify a small part of a large JSON object so you can see + * a preview. + * + * @param {*} value + * The value to convert to a JSON string. + * + * @param {number | string | null} [space] + * A String or Number object that's used to insert white space into the output + * JSON string for readability purposes. If this is a Number, it indicates the + * number of space characters to use as white space; this number is capped at 10 + * if it's larger than that. Values less than 1 indicate that no space should be + * used. If this is a String, the string (or the first 10 characters of the string, + * if it's longer than that) is used as white space. If this parameter is not + * provided (or is null), no white space is used. + * + * @param {number} [limit] Maximum size of the string output. + * + * @returns {string | undefined} Returns the string representation of the JSON object. + */ + +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + +function stringifyPartial(value, space, limit) { + var _space; // undefined by default + + + if (typeof space === 'number') { + if (space > 10) { + _space = repeat(' ', 10); + } else if (space >= 1) { + _space = repeat(' ', space); + } // else ignore + + } else if (typeof space === 'string' && space !== '') { + _space = space; + } + + var output = stringifyValue(value, _space, '', limit); + return output.length > limit ? slice(output, limit) + '...' : output; +} +/** + * Stringify a value + * @param {*} value + * @param {string} space + * @param {string} indent + * @param {number} limit + * @return {string | undefined} + */ + +function stringifyValue(value, space, indent, limit) { + // boolean, null, number, string, or date + if (typeof value === 'boolean' || value instanceof Boolean || value === null || typeof value === 'number' || value instanceof Number || typeof value === 'string' || value instanceof String || value instanceof Date) { + return JSON.stringify(value); + } // array + + + if (Array.isArray(value)) { + return stringifyArray(value, space, indent, limit); + } // object (test lastly!) + + + if (value && _typeof(value) === 'object') { + return stringifyObject(value, space, indent, limit); + } + + return undefined; +} +/** + * Stringify an array + * @param {Array} array + * @param {string} space + * @param {string} indent + * @param {number} limit + * @return {string} + */ + + +function stringifyArray(array, space, indent, limit) { + var childIndent = space ? indent + space : undefined; + var str = space ? '[\n' : '['; + + for (var i = 0; i < array.length; i++) { + var item = array[i]; + + if (space) { + str += childIndent; + } + + if (typeof item !== 'undefined' && typeof item !== 'function') { + str += stringifyValue(item, space, childIndent, limit); + } else { + str += 'null'; + } + + if (i < array.length - 1) { + str += space ? ',\n' : ','; + } // stop as soon as we're exceeding the limit + + + if (str.length > limit) { + return str + '...'; + } + } + + str += space ? '\n' + indent + ']' : ']'; + return str; +} +/** + * Stringify an object + * @param {Object} object + * @param {string} space + * @param {string} indent + * @param {number} limit + * @return {string} + */ + + +function stringifyObject(object, space, indent, limit) { + var childIndent = space ? indent + space : undefined; + var first = true; + var str = space ? '{\n' : '{'; + + if (typeof object.toJSON === 'function') { + return stringifyValue(object.toJSON(), space, indent, limit); + } + + for (var key in object) { + if (jsonUtils_hasOwnProperty(object, key)) { + var value = object[key]; + + if (first) { + first = false; + } else { + str += space ? ',\n' : ','; + } + + str += space ? childIndent + '"' + key + '": ' : '"' + key + '":'; + str += stringifyValue(value, space, childIndent, limit); // stop as soon as we're exceeding the limit + + if (str.length > limit) { + return str + '...'; + } + } + } + + str += space ? '\n' + indent + '}' : '}'; + return str; +} +/** + * Repeat a string a number of times. + * Simple linear solution, we only need up to 10 iterations in practice + * @param {string} text + * @param {number} times + * @return {string} + */ + + +function repeat(text, times) { + var res = ''; + + while (times-- > 0) { + res += text; + } + + return res; +} +/** + * Limit the length of text + * @param {string} text + * @param {number} [limit] + * @return {string} + */ + + +function slice(text, limit) { + return typeof limit === 'number' ? text.slice(0, limit) : text; +} +/** + * Test whether some text contains a JSON array, i.e. the first + * non-white space character is a [ + * @param {string} jsonText + * @return {boolean} + */ + + +function containsArray(jsonText) { + return /^\s*\[/.test(jsonText); +} + +function jsonUtils_hasOwnProperty(object, key) { + return Object.prototype.hasOwnProperty.call(object, key); +} +// EXTERNAL MODULE: ./src/js/util.js +var util = __webpack_require__(9791); +// EXTERNAL MODULE: ./src/js/constants.js +var constants = __webpack_require__(4188); +;// CONCATENATED MODULE: ./src/js/showTransformModal.js + + + + + + +var DEFAULT_DESCRIPTION = 'Enter a JMESPath query to filter, sort, or transform the JSON data.
    ' + 'To learn JMESPath, go to the interactive tutorial.'; +/** + * Show advanced filter and transform modal using JMESPath + * @param {Object} params + * @property {HTMLElement} container The container where to center + * the modal and create an overlay + * @property {JSON} json The json data to be transformed + * @property {string} [queryDescription] Optional custom description explaining + * the transform functionality + * @property {function} createQuery Function called to create a query + * from the wizard form + * @property {function} executeQuery Execute a query for the preview pane + * @property {function} onTransform Callback invoked with the created + * query as callback + */ + +function showTransformModal(_ref) { + var container = _ref.container, + json = _ref.json, + _ref$queryDescription = _ref.queryDescription, + queryDescription = _ref$queryDescription === void 0 ? DEFAULT_DESCRIPTION : _ref$queryDescription, + createQuery = _ref.createQuery, + executeQuery = _ref.executeQuery, + onTransform = _ref.onTransform; + var value = json; + var content = '
    '; + picoModal_default()({ + parent: container, + content: content, + overlayClass: 'jsoneditor-modal-overlay', + overlayStyles: { + backgroundColor: 'rgb(1,1,1)', + opacity: 0.3 + }, + modalClass: 'jsoneditor-modal jsoneditor-modal-transform', + focus: false + }).afterCreate(function (modal) { + var elem = modal.modalElem(); + var wizard = elem.querySelector('#wizard'); + var ok = elem.querySelector('#ok'); + var filterField = elem.querySelector('#filterField'); + var filterRelation = elem.querySelector('#filterRelation'); + var filterValue = elem.querySelector('#filterValue'); + var sortField = elem.querySelector('#sortField'); + var sortOrder = elem.querySelector('#sortOrder'); + var selectFields = elem.querySelector('#selectFields'); + var query = elem.querySelector('#query'); + var preview = elem.querySelector('#preview'); + + if (!Array.isArray(value)) { + wizard.style.fontStyle = 'italic'; + wizard.textContent = '(wizard not available for objects, only for arrays)'; + } + + var sortablePaths = (0,util.getChildPaths)(json); + sortablePaths.forEach(function (path) { + var formattedPath = preprocessPath(path); + var filterOption = document.createElement('option'); + filterOption.text = formattedPath; + filterOption.value = formattedPath; + filterField.appendChild(filterOption); + var sortOption = document.createElement('option'); + sortOption.text = formattedPath; + sortOption.value = formattedPath; + sortField.appendChild(sortOption); + }); + var selectablePaths = (0,util.getChildPaths)(json, true).filter(function (path) { + return path !== ''; + }); + + if (selectablePaths.length > 0) { + selectablePaths.forEach(function (path) { + var formattedPath = preprocessPath(path); + var option = document.createElement('option'); + option.text = formattedPath; + option.value = formattedPath; + selectFields.appendChild(option); + }); + } else { + var selectFieldsPart = elem.querySelector('#selectFieldsPart'); + + if (selectFieldsPart) { + selectFieldsPart.style.display = 'none'; + } + } + + var selectrFilterField = new (selectr_default())(filterField, { + defaultSelected: false, + clearable: true, + allowDeselect: true, + placeholder: 'field...' + }); + var selectrFilterRelation = new (selectr_default())(filterRelation, { + defaultSelected: false, + clearable: true, + allowDeselect: true, + placeholder: 'compare...' + }); + var selectrSortField = new (selectr_default())(sortField, { + defaultSelected: false, + clearable: true, + allowDeselect: true, + placeholder: 'field...' + }); + var selectrSortOrder = new (selectr_default())(sortOrder, { + defaultSelected: false, + clearable: true, + allowDeselect: true, + placeholder: 'order...' + }); + var selectrSelectFields = new (selectr_default())(selectFields, { + multiple: true, + clearable: true, + defaultSelected: false, + placeholder: 'select fields...' + }); + selectrFilterField.on('selectr.change', generateQueryFromWizard); + selectrFilterRelation.on('selectr.change', generateQueryFromWizard); + filterValue.oninput = generateQueryFromWizard; + selectrSortField.on('selectr.change', generateQueryFromWizard); + selectrSortOrder.on('selectr.change', generateQueryFromWizard); + selectrSelectFields.on('selectr.change', generateQueryFromWizard); + + elem.querySelector('.pico-modal-contents').onclick = function (event) { + // prevent the first clear button (in any select box) from getting + // focus when clicking anywhere in the modal. Only allow clicking links. + if (event.target.nodeName !== 'A') { + event.preventDefault(); + } + }; + + function preprocessPath(path) { + return path === '' ? '@' : path[0] === '.' ? path.slice(1) : path; + } + + function updatePreview() { + try { + var transformed = executeQuery(value, query.value); + preview.className = 'jsoneditor-transform-preview'; + preview.value = stringifyPartial(transformed, 2, constants/* MAX_PREVIEW_CHARACTERS */.WF); + ok.disabled = false; + } catch (err) { + preview.className = 'jsoneditor-transform-preview jsoneditor-error'; + preview.value = err.toString(); + ok.disabled = true; + } + } + + var debouncedUpdatePreview = (0,util.debounce)(updatePreview, 300); + + function tryCreateQuery(json, queryOptions) { + try { + query.value = createQuery(json, queryOptions); + ok.disabled = false; + debouncedUpdatePreview(); + } catch (err) { + var message = 'Error: an error happened when executing "createQuery": ' + (err.message || err.toString()); + query.value = ''; + ok.disabled = true; + preview.className = 'jsoneditor-transform-preview jsoneditor-error'; + preview.value = message; + } + } + + function generateQueryFromWizard() { + var queryOptions = {}; + + if (filterField.value && filterRelation.value && filterValue.value) { + queryOptions.filter = { + field: filterField.value, + relation: filterRelation.value, + value: filterValue.value + }; + } + + if (sortField.value && sortOrder.value) { + queryOptions.sort = { + field: sortField.value, + direction: sortOrder.value + }; + } + + if (selectFields.value) { + var fields = []; + + for (var i = 0; i < selectFields.options.length; i++) { + if (selectFields.options[i].selected) { + var selectedField = selectFields.options[i].value; + fields.push(selectedField); + } + } + + queryOptions.projection = { + fields: fields + }; + } + + tryCreateQuery(json, queryOptions); + } + + query.oninput = debouncedUpdatePreview; + + ok.onclick = function (event) { + event.preventDefault(); + event.stopPropagation(); + modal.close(); + onTransform(query.value); + }; // initialize with empty query + + + tryCreateQuery(json, {}); + setTimeout(function () { + query.select(); + query.focus(); + query.selectionStart = 3; + query.selectionEnd = 3; + }); + }).afterClose(function (modal) { + modal.destroy(); + }).show(); +} + +/***/ }), + +/***/ 5956: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +// ESM COMPAT FLAG +__webpack_require__.r(__webpack_exports__); + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "textModeMixins": function() { return /* binding */ textModeMixins; } +}); + +// EXTERNAL MODULE: ./node_modules/jsonrepair/lib/cjs/index-commonjs.js +var index_commonjs = __webpack_require__(8909); +var index_commonjs_default = /*#__PURE__*/__webpack_require__.n(index_commonjs); +// EXTERNAL MODULE: ./src/js/ace/index.js +var ace = __webpack_require__(8170); +var ace_default = /*#__PURE__*/__webpack_require__.n(ace); +// EXTERNAL MODULE: ./src/js/constants.js +var constants = __webpack_require__(4188); +// EXTERNAL MODULE: ./src/js/ErrorTable.js +var ErrorTable = __webpack_require__(6436); +// EXTERNAL MODULE: ./src/js/FocusTracker.js +var FocusTracker = __webpack_require__(2474); +// EXTERNAL MODULE: ./src/js/i18n.js +var i18n = __webpack_require__(7907); +// EXTERNAL MODULE: ./src/js/jmespathQuery.js +var jmespathQuery = __webpack_require__(6056); +// EXTERNAL MODULE: ./src/js/ModeSwitcher.js +var ModeSwitcher = __webpack_require__(6617); +// EXTERNAL MODULE: ./src/js/showSortModal.js +var showSortModal = __webpack_require__(6210); +// EXTERNAL MODULE: ./src/js/showTransformModal.js + 1 modules +var showTransformModal = __webpack_require__(2558); +// EXTERNAL MODULE: ./src/js/tryRequireThemeJsonEditor.js +var tryRequireThemeJsonEditor = __webpack_require__(9125); +// EXTERNAL MODULE: ./src/js/util.js +var util = __webpack_require__(9791); +;// CONCATENATED MODULE: ./src/js/validationUtils.js + +/** + * Execute custom validation if configured. + * + * Returns a promise resolving with the custom errors (or an empty array). + */ + +function validateCustom(json, onValidate) { + if (!onValidate) { + return Promise.resolve([]); + } + + try { + var customValidateResults = onValidate(json); + var resultPromise = (0,util.isPromise)(customValidateResults) ? customValidateResults : Promise.resolve(customValidateResults); + return resultPromise.then(function (customValidationPathErrors) { + if (Array.isArray(customValidationPathErrors)) { + return customValidationPathErrors.filter(function (error) { + var valid = (0,util.isValidValidationError)(error); + + if (!valid) { + console.warn('Ignoring a custom validation error with invalid structure. ' + 'Expected structure: {path: [...], message: "..."}. ' + 'Actual error:', error); + } + + return valid; + }).map(function (error) { + return (// change data structure into the structure matching the JSON schema errors + { + dataPath: (0,util.stringifyPath)(error.path), + message: error.message, + type: 'customValidation' + } + ); + }); + } else { + return []; + } + }); + } catch (err) { + return Promise.reject(err); + } +} +;// CONCATENATED MODULE: ./src/js/textmode.js + + +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + + + + + + + + + + + + + + // create a mixin with the functions for text mode + +var textmode = {}; +var DEFAULT_THEME = 'ace/theme/jsoneditor'; +/** + * Create a text editor + * @param {Element} container + * @param {Object} [options] Object with options. See docs for details. + * @private + */ + +textmode.create = function (container) { + var _this = this; + + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + if (typeof options.statusBar === 'undefined') { + options.statusBar = true; + } // setting default for textmode + + + options.mainMenuBar = options.mainMenuBar !== false; + options.enableSort = options.enableSort !== false; + options.enableTransform = options.enableTransform !== false; + options.createQuery = options.createQuery || jmespathQuery/* createQuery */.r; + options.executeQuery = options.executeQuery || jmespathQuery/* executeQuery */.J; + this.options = options; // indentation + + if (typeof options.indentation === 'number') { + this.indentation = Number(options.indentation); + } else { + this.indentation = 2; // number of spaces + } // language + + + (0,i18n/* setLanguages */.cC)(this.options.languages); + (0,i18n/* setLanguage */.m0)(this.options.language); // grab ace from options if provided + + var _ace = options.ace ? options.ace : (ace_default()); // TODO: make the option options.ace deprecated, it's not needed anymore (see #309) + // determine mode + + + this.mode = options.mode === 'code' ? 'code' : 'text'; + + if (this.mode === 'code') { + // verify whether Ace editor is available and supported + if (typeof _ace === 'undefined') { + this.mode = 'text'; + console.warn('Failed to load Ace editor, falling back to plain text mode. Please use a JSONEditor bundle including Ace, or pass Ace as via the configuration option `ace`.'); + } + } // determine theme + + + this.theme = options.theme || DEFAULT_THEME; + + if (this.theme === DEFAULT_THEME && _ace) { + (0,tryRequireThemeJsonEditor/* tryRequireThemeJsonEditor */.O)(); + } + + if (options.onTextSelectionChange) { + this.onTextSelectionChange(options.onTextSelectionChange); + } + + var me = this; + this.container = container; + this.dom = {}; + this.aceEditor = undefined; // ace code editor + + this.textarea = undefined; // plain text editor (fallback when Ace is not available) + + this.validateSchema = null; + this.annotations = []; + this.lastSchemaErrors = undefined; // create a debounced validate function + + this._debouncedValidate = (0,util.debounce)(this.validate.bind(this), this.DEBOUNCE_INTERVAL); + this.width = container.clientWidth; + this.height = container.clientHeight; + this.frame = document.createElement('div'); + this.frame.className = 'jsoneditor jsoneditor-mode-' + this.options.mode; + + this.frame.onclick = function (event) { + // prevent default submit action when the editor is located inside a form + event.preventDefault(); + }; + + this.frame.onkeydown = function (event) { + me._onKeyDown(event); + }; // setting the FocusTracker on 'this.frame' to track the editor's focus event + + + var focusTrackerConfig = { + target: this.frame, + onFocus: this.options.onFocus || null, + onBlur: this.options.onBlur || null + }; + this.frameFocusTracker = new FocusTracker/* FocusTracker */.R(focusTrackerConfig); + this.content = document.createElement('div'); + this.content.className = 'jsoneditor-outer'; + + if (this.options.mainMenuBar) { + (0,util.addClassName)(this.content, 'has-main-menu-bar'); // create menu + + this.menu = document.createElement('div'); + this.menu.className = 'jsoneditor-menu'; + this.frame.appendChild(this.menu); // create format button + + var buttonFormat = document.createElement('button'); + buttonFormat.type = 'button'; + buttonFormat.className = 'jsoneditor-format'; + buttonFormat.title = (0,i18n/* translate */.Iu)('formatTitle'); + this.menu.appendChild(buttonFormat); + + buttonFormat.onclick = function () { + try { + me.format(); + + me._onChange(); + } catch (err) { + me._onError(err); + } + }; // create compact button + + + var buttonCompact = document.createElement('button'); + buttonCompact.type = 'button'; + buttonCompact.className = 'jsoneditor-compact'; + buttonCompact.title = (0,i18n/* translate */.Iu)('compactTitle'); + this.menu.appendChild(buttonCompact); + + buttonCompact.onclick = function () { + try { + me.compact(); + + me._onChange(); + } catch (err) { + me._onError(err); + } + }; // create sort button + + + if (this.options.enableSort) { + var _sort = document.createElement('button'); + + _sort.type = 'button'; + _sort.className = 'jsoneditor-sort'; + _sort.title = (0,i18n/* translate */.Iu)('sortTitleShort'); + + _sort.onclick = function () { + me._showSortModal(); + }; + + this.menu.appendChild(_sort); + } // create transform button + + + if (this.options.enableTransform) { + var transform = document.createElement('button'); + transform.type = 'button'; + transform.title = (0,i18n/* translate */.Iu)('transformTitleShort'); + transform.className = 'jsoneditor-transform'; + + transform.onclick = function () { + me._showTransformModal(); + }; + + this.menu.appendChild(transform); + } // create repair button + + + var buttonRepair = document.createElement('button'); + buttonRepair.type = 'button'; + buttonRepair.className = 'jsoneditor-repair'; + buttonRepair.title = (0,i18n/* translate */.Iu)('repairTitle'); + this.menu.appendChild(buttonRepair); + + buttonRepair.onclick = function () { + try { + me.repair(); + + me._onChange(); + } catch (err) { + me._onError(err); + } + }; // create undo/redo buttons + + + if (this.mode === 'code') { + // create undo button + var undo = document.createElement('button'); + undo.type = 'button'; + undo.className = 'jsoneditor-undo jsoneditor-separator'; + undo.title = (0,i18n/* translate */.Iu)('undo'); + + undo.onclick = function () { + _this.aceEditor.getSession().getUndoManager().undo(); + }; + + this.menu.appendChild(undo); + this.dom.undo = undo; // create redo button + + var redo = document.createElement('button'); + redo.type = 'button'; + redo.className = 'jsoneditor-redo'; + redo.title = (0,i18n/* translate */.Iu)('redo'); + + redo.onclick = function () { + _this.aceEditor.getSession().getUndoManager().redo(); + }; + + this.menu.appendChild(redo); + this.dom.redo = redo; + } // create mode box + + + if (this.options && this.options.modes && this.options.modes.length) { + this.modeSwitcher = new ModeSwitcher/* ModeSwitcher */.x(this.menu, this.options.modes, this.options.mode, function onSwitch(mode) { + // switch mode and restore focus + me.setMode(mode); + me.modeSwitcher.focus(); + }); + } + + if (this.mode === 'code') { + var poweredBy = document.createElement('a'); + poweredBy.appendChild(document.createTextNode('powered by ace')); + poweredBy.href = 'https://ace.c9.io/'; + poweredBy.target = '_blank'; + poweredBy.className = 'jsoneditor-poweredBy'; + + poweredBy.onclick = function () { + // TODO: this anchor falls below the margin of the content, + // therefore the normal a.href does not work. We use a click event + // for now, but this should be fixed. + window.open(poweredBy.href, poweredBy.target, 'noopener'); + }; + + this.menu.appendChild(poweredBy); + } + } + + var emptyNode = {}; + var isReadOnly = this.options.onEditable && _typeof(this.options.onEditable === 'function') && !this.options.onEditable(emptyNode); + this.frame.appendChild(this.content); + this.container.appendChild(this.frame); + + if (this.mode === 'code') { + this.editorDom = document.createElement('div'); + this.editorDom.style.height = '100%'; // TODO: move to css + + this.editorDom.style.width = '100%'; // TODO: move to css + + this.content.appendChild(this.editorDom); + + var aceEditor = _ace.edit(this.editorDom); + + var aceSession = aceEditor.getSession(); + aceEditor.$blockScrolling = Infinity; + aceEditor.setTheme(this.theme); + aceEditor.setOptions({ + readOnly: isReadOnly + }); + aceEditor.setShowPrintMargin(false); + aceEditor.setFontSize('13px'); + aceSession.setMode('ace/mode/json'); + aceSession.setTabSize(this.indentation); + aceSession.setUseSoftTabs(true); + aceSession.setUseWrapMode(true); // replace ace setAnnotations with custom function that also covers jsoneditor annotations + + var originalSetAnnotations = aceSession.setAnnotations; + + aceSession.setAnnotations = function (annotations) { + originalSetAnnotations.call(this, annotations && annotations.length ? annotations : me.annotations); + }; // disable Ctrl+L quickkey of Ace (is used by the browser to select the address bar) + + + aceEditor.commands.bindKey('Ctrl-L', null); + aceEditor.commands.bindKey('Command-L', null); // disable the quickkeys we want to use for Format and Compact + + aceEditor.commands.bindKey('Ctrl-\\', null); + aceEditor.commands.bindKey('Command-\\', null); + aceEditor.commands.bindKey('Ctrl-Shift-\\', null); + aceEditor.commands.bindKey('Command-Shift-\\', null); + this.aceEditor = aceEditor; // register onchange event + + aceEditor.on('change', this._onChange.bind(this)); + aceEditor.on('changeSelection', this._onSelect.bind(this)); + } else { + // load a plain text textarea + var textarea = document.createElement('textarea'); + textarea.className = 'jsoneditor-text'; + textarea.spellcheck = false; + this.content.appendChild(textarea); + this.textarea = textarea; + this.textarea.readOnly = isReadOnly; // register onchange event + + if (this.textarea.oninput === null) { + this.textarea.oninput = this._onChange.bind(this); + } else { + // oninput is undefined. For IE8- + this.textarea.onchange = this._onChange.bind(this); + } + + textarea.onselect = this._onSelect.bind(this); + textarea.onmousedown = this._onMouseDown.bind(this); + textarea.onblur = this._onBlur.bind(this); + } + + this._updateHistoryButtons(); + + this.errorTable = new ErrorTable/* ErrorTable */.Q({ + errorTableVisible: this.mode === 'text', + onToggleVisibility: function onToggleVisibility() { + me.validate(); + }, + onFocusLine: function onFocusLine(line) { + me.isFocused = true; + + if (!isNaN(line)) { + me.setTextSelection({ + row: line, + column: 1 + }, { + row: line, + column: 1000 + }); + } + }, + onChangeHeight: function onChangeHeight(height) { + // TODO: change CSS to using flex box, remove setting height using JavaScript + var statusBarHeight = me.dom.statusBar ? me.dom.statusBar.clientHeight : 0; + var totalHeight = height + statusBarHeight + 1; + me.content.style.marginBottom = -totalHeight + 'px'; + me.content.style.paddingBottom = totalHeight + 'px'; + } + }); + this.frame.appendChild(this.errorTable.getErrorTable()); + + if (options.statusBar) { + (0,util.addClassName)(this.content, 'has-status-bar'); + this.curserInfoElements = {}; + var statusBar = document.createElement('div'); + this.dom.statusBar = statusBar; + statusBar.className = 'jsoneditor-statusbar'; + this.frame.appendChild(statusBar); + var lnLabel = document.createElement('span'); + lnLabel.className = 'jsoneditor-curserinfo-label'; + lnLabel.innerText = 'Ln:'; + var lnVal = document.createElement('span'); + lnVal.className = 'jsoneditor-curserinfo-val'; + lnVal.innerText = '1'; + statusBar.appendChild(lnLabel); + statusBar.appendChild(lnVal); + var colLabel = document.createElement('span'); + colLabel.className = 'jsoneditor-curserinfo-label'; + colLabel.innerText = 'Col:'; + var colVal = document.createElement('span'); + colVal.className = 'jsoneditor-curserinfo-val'; + colVal.innerText = '1'; + statusBar.appendChild(colLabel); + statusBar.appendChild(colVal); + this.curserInfoElements.colVal = colVal; + this.curserInfoElements.lnVal = lnVal; + var countLabel = document.createElement('span'); + countLabel.className = 'jsoneditor-curserinfo-label'; + countLabel.innerText = 'characters selected'; + countLabel.style.display = 'none'; + var countVal = document.createElement('span'); + countVal.className = 'jsoneditor-curserinfo-count'; + countVal.innerText = '0'; + countVal.style.display = 'none'; + this.curserInfoElements.countLabel = countLabel; + this.curserInfoElements.countVal = countVal; + statusBar.appendChild(countVal); + statusBar.appendChild(countLabel); + statusBar.appendChild(this.errorTable.getErrorCounter()); + statusBar.appendChild(this.errorTable.getWarningIcon()); + statusBar.appendChild(this.errorTable.getErrorIcon()); + } + + this.setSchema(this.options.schema, this.options.schemaRefs); +}; +/** + * Handle a change: + * - Validate JSON schema + * - Send a callback to the onChange listener if provided + * @private + */ + + +textmode._onChange = function () { + var _this2 = this; + + if (this.onChangeDisabled) { + return; + } // enable/disable undo/redo buttons + + + setTimeout(function () { + return _this2._updateHistoryButtons(); + }); // validate JSON schema (if configured) + + this._debouncedValidate(); // trigger the onChange callback + + + if (this.options.onChange) { + try { + this.options.onChange(); + } catch (err) { + console.error('Error in onChange callback: ', err); + } + } // trigger the onChangeText callback + + + if (this.options.onChangeText) { + try { + this.options.onChangeText(this.getText()); + } catch (err) { + console.error('Error in onChangeText callback: ', err); + } + } +}; + +textmode._updateHistoryButtons = function () { + if (this.aceEditor && this.dom.undo && this.dom.redo) { + var undoManager = this.aceEditor.getSession().getUndoManager(); + + if (undoManager && undoManager.hasUndo && undoManager.hasRedo) { + this.dom.undo.disabled = !undoManager.hasUndo(); + this.dom.redo.disabled = !undoManager.hasRedo(); + } + } +}; +/** + * Open a sort modal + * @private + */ + + +textmode._showSortModal = function () { + var me = this; + var container = this.options.modalAnchor || constants/* DEFAULT_MODAL_ANCHOR */.qD; + var json = this.get(); + + function onSort(sortedBy) { + if (Array.isArray(json)) { + var sortedJson = (0,util.sort)(json, sortedBy.path, sortedBy.direction); + me.sortedBy = sortedBy; + me.update(sortedJson); + } + + if ((0,util.isObject)(json)) { + var _sortedJson = (0,util.sortObjectKeys)(json, sortedBy.direction); + + me.sortedBy = sortedBy; + me.update(_sortedJson); + } + } + + (0,showSortModal.showSortModal)(container, json, onSort, me.sortedBy); +}; +/** + * Open a transform modal + * @private + */ + + +textmode._showTransformModal = function () { + var _this3 = this; + + var _this$options = this.options, + modalAnchor = _this$options.modalAnchor, + createQuery = _this$options.createQuery, + executeQuery = _this$options.executeQuery, + queryDescription = _this$options.queryDescription; + var json = this.get(); + (0,showTransformModal.showTransformModal)({ + container: modalAnchor || constants/* DEFAULT_MODAL_ANCHOR */.qD, + json: json, + queryDescription: queryDescription, + // can be undefined + createQuery: createQuery, + executeQuery: executeQuery, + onTransform: function onTransform(query) { + var updatedJson = executeQuery(json, query); + + _this3.update(updatedJson); + } + }); +}; +/** + * Handle text selection + * Calculates the cursor position and selection range and updates menu + * @private + */ + + +textmode._onSelect = function () { + this._updateCursorInfo(); + + this._emitSelectionChange(); +}; +/** + * Event handler for keydown. Handles shortcut keys + * @param {Event} event + * @private + */ + + +textmode._onKeyDown = function (event) { + var keynum = event.which || event.keyCode; + var handled = false; + + if (keynum === 220 && event.ctrlKey) { + if (event.shiftKey) { + // Ctrl+Shift+\ + this.compact(); + + this._onChange(); + } else { + // Ctrl+\ + this.format(); + + this._onChange(); + } + + handled = true; + } + + if (handled) { + event.preventDefault(); + event.stopPropagation(); + } + + this._updateCursorInfo(); + + this._emitSelectionChange(); +}; +/** + * Event handler for mousedown. + * @private + */ + + +textmode._onMouseDown = function () { + this._updateCursorInfo(); + + this._emitSelectionChange(); +}; +/** + * Event handler for blur. + * @private + */ + + +textmode._onBlur = function () { + var me = this; // this allows to avoid blur when clicking inner elements (like the errors panel) + // just make sure to set the isFocused to true on the inner element onclick callback + + setTimeout(function () { + if (!me.isFocused) { + me._updateCursorInfo(); + + me._emitSelectionChange(); + } + + me.isFocused = false; + }); +}; +/** + * Update the cursor info and the status bar, if presented + */ + + +textmode._updateCursorInfo = function () { + var me = this; + var line, col, count; + + if (this.textarea) { + setTimeout(function () { + // this to verify we get the most updated textarea cursor selection + var selectionRange = (0,util.getInputSelection)(me.textarea); + + if (selectionRange.startIndex !== selectionRange.endIndex) { + count = selectionRange.endIndex - selectionRange.startIndex; + } + + if (count && me.cursorInfo && me.cursorInfo.line === selectionRange.end.row && me.cursorInfo.column === selectionRange.end.column) { + line = selectionRange.start.row; + col = selectionRange.start.column; + } else { + line = selectionRange.end.row; + col = selectionRange.end.column; + } + + me.cursorInfo = { + line: line, + column: col, + count: count + }; + + if (me.options.statusBar) { + updateDisplay(); + } + }, 0); + } else if (this.aceEditor && this.curserInfoElements) { + var curserPos = this.aceEditor.getCursorPosition(); + var selectedText = this.aceEditor.getSelectedText(); + line = curserPos.row + 1; + col = curserPos.column + 1; + count = selectedText.length; + me.cursorInfo = { + line: line, + column: col, + count: count + }; + + if (this.options.statusBar) { + updateDisplay(); + } + } + + function updateDisplay() { + if (me.curserInfoElements.countVal.innerText !== count) { + me.curserInfoElements.countVal.innerText = count; + me.curserInfoElements.countVal.style.display = count ? 'inline' : 'none'; + me.curserInfoElements.countLabel.style.display = count ? 'inline' : 'none'; + } + + me.curserInfoElements.lnVal.innerText = line; + me.curserInfoElements.colVal.innerText = col; + } +}; +/** + * emits selection change callback, if given + * @private + */ + + +textmode._emitSelectionChange = function () { + if (this._selectionChangedHandler) { + var currentSelection = this.getTextSelection(); + + this._selectionChangedHandler(currentSelection.start, currentSelection.end, currentSelection.text); + } +}; +/** + * refresh ERROR annotations state + * error annotations are handled by the ace json mode (ace/mode/json) + * validation annotations are handled by this mode + * therefore in order to refresh we send only the annotations of error type in order to maintain its state + * @private + */ + + +textmode._refreshAnnotations = function () { + var session = this.aceEditor && this.aceEditor.getSession(); + + if (session) { + var errEnnotations = session.getAnnotations().filter(function (annotation) { + return annotation.type === 'error'; + }); + session.setAnnotations(errEnnotations); + } +}; +/** + * Destroy the editor. Clean up DOM, event listeners, and web workers. + */ + + +textmode.destroy = function () { + // remove old ace editor + if (this.aceEditor) { + this.aceEditor.destroy(); + this.aceEditor = null; + } + + if (this.frame && this.container && this.frame.parentNode === this.container) { + this.container.removeChild(this.frame); + } + + if (this.modeSwitcher) { + this.modeSwitcher.destroy(); + this.modeSwitcher = null; + } + + this.textarea = null; + this._debouncedValidate = null; // Removing the FocusTracker set to track the editor's focus event + + this.frameFocusTracker.destroy(); +}; +/** + * Compact the code in the text editor + */ + + +textmode.compact = function () { + var json = this.get(); + var text = JSON.stringify(json); + this.updateText(text); +}; +/** + * Format the code in the text editor + */ + + +textmode.format = function () { + var json = this.get(); + var text = JSON.stringify(json, null, this.indentation); + this.updateText(text); +}; +/** + * Repair the code in the text editor + */ + + +textmode.repair = function () { + var text = this.getText(); + + try { + var repairedText = index_commonjs_default()(text); + this.updateText(repairedText); + } catch (err) {// repair was not successful, do nothing + } +}; +/** + * Set focus to the formatter + */ + + +textmode.focus = function () { + if (this.textarea) { + this.textarea.focus(); + } + + if (this.aceEditor) { + this.aceEditor.focus(); + } +}; +/** + * Resize the formatter + */ + + +textmode.resize = function () { + if (this.aceEditor) { + var force = false; + this.aceEditor.resize(force); + } +}; +/** + * Set json data in the formatter + * @param {*} json + */ + + +textmode.set = function (json) { + this.setText(JSON.stringify(json, null, this.indentation)); +}; +/** + * Update data. Same as calling `set` in text/code mode. + * @param {*} json + */ + + +textmode.update = function (json) { + this.updateText(JSON.stringify(json, null, this.indentation)); +}; +/** + * Get json data from the formatter + * @return {*} json + */ + + +textmode.get = function () { + var text = this.getText(); + return (0,util.parse)(text); // this can throw an error +}; +/** + * Get the text contents of the editor + * @return {String} jsonText + */ + + +textmode.getText = function () { + if (this.textarea) { + return this.textarea.value; + } + + if (this.aceEditor) { + return this.aceEditor.getValue(); + } + + return ''; +}; +/** + * Set the text contents of the editor and optionally clear the history + * @param {String} jsonText + * @param {boolean} clearHistory Only applicable for mode 'code' + * @private + */ + + +textmode._setText = function (jsonText, clearHistory) { + var _this4 = this; + + var text = this.options.escapeUnicode === true ? (0,util.escapeUnicodeChars)(jsonText) : jsonText; + + if (this.textarea) { + this.textarea.value = text; + } + + if (this.aceEditor) { + // prevent emitting onChange events while setting new text + this.onChangeDisabled = true; + this.aceEditor.setValue(text, -1); + this.onChangeDisabled = false; + + if (clearHistory) { + // prevent initial undo action clearing the initial contents + var me = this; + setTimeout(function () { + if (me.aceEditor) { + me.aceEditor.session.getUndoManager().reset(); + } + }); + } + + setTimeout(function () { + return _this4._updateHistoryButtons(); + }); + } // validate JSON schema + + + this._debouncedValidate(); +}; +/** + * Set the text contents of the editor + * @param {String} jsonText + */ + + +textmode.setText = function (jsonText) { + this._setText(jsonText, true); +}; +/** + * Update the text contents + * @param {string} jsonText + */ + + +textmode.updateText = function (jsonText) { + // don't update if there are no changes + if (this.getText() === jsonText) { + return; + } + + this._setText(jsonText, false); +}; +/** + * Validate current JSON object against the configured JSON schema + * Throws an exception when no JSON schema is configured + */ + + +textmode.validate = function () { + var _this5 = this; + + var schemaErrors = []; + var parseErrors = []; + var json; + + try { + json = this.get(); // this can fail when there is no valid json + // execute JSON schema validation (ajv) + + if (this.validateSchema) { + var valid = this.validateSchema(json); + + if (!valid) { + schemaErrors = this.validateSchema.errors.map(function (error) { + error.type = 'validation'; + return (0,util.improveSchemaError)(error); + }); + } + } // execute custom validation and after than merge and render all errors + // TODO: implement a better mechanism for only using the last validation action + + + this.validationSequence = (this.validationSequence || 0) + 1; + var me = this; + var seq = this.validationSequence; + validateCustom(json, this.options.onValidate).then(function (customValidationErrors) { + // only apply when there was no other validation started whilst resolving async results + if (seq === me.validationSequence) { + var errors = schemaErrors.concat(parseErrors).concat(customValidationErrors); + + me._renderErrors(errors); + + if (typeof _this5.options.onValidationError === 'function') { + if ((0,util.isValidationErrorChanged)(errors, _this5.lastSchemaErrors)) { + _this5.options.onValidationError.call(_this5, errors); + } + + _this5.lastSchemaErrors = errors; + } + } + })["catch"](function (err) { + console.error('Custom validation function did throw an error', err); + }); + } catch (err) { + if (this.getText()) { + // try to extract the line number from the jsonlint error message + var match = /\w*line\s*(\d+)\w*/g.exec(err.message); + var line; + + if (match) { + line = +match[1]; + } + + parseErrors = [{ + type: 'error', + message: err.message.replace(/\n/g, '
    '), + line: line + }]; + } + + this._renderErrors(parseErrors); + + if (typeof this.options.onValidationError === 'function') { + if ((0,util.isValidationErrorChanged)(parseErrors, this.lastSchemaErrors)) { + this.options.onValidationError.call(this, parseErrors); + } + + this.lastSchemaErrors = parseErrors; + } + } +}; + +textmode._renderErrors = function (errors) { + var jsonText = this.getText(); + var errorPaths = []; + errors.reduce(function (acc, curr) { + if (typeof curr.dataPath === 'string' && acc.indexOf(curr.dataPath) === -1) { + acc.push(curr.dataPath); + } + + return acc; + }, errorPaths); + var errorLocations = (0,util.getPositionForPath)(jsonText, errorPaths); // render annotations in Ace Editor (if any) + + if (this.aceEditor) { + this.annotations = errorLocations.map(function (errLoc) { + var validationErrors = errors.filter(function (err) { + return err.dataPath === errLoc.path; + }); + var message = validationErrors.map(function (err) { + return err.message; + }).join('\n'); + + if (message) { + return { + row: errLoc.line, + column: errLoc.column, + text: 'Schema validation error' + (validationErrors.length !== 1 ? 's' : '') + ': \n' + message, + type: 'warning', + source: 'jsoneditor' + }; + } + + return {}; + }); + + this._refreshAnnotations(); + } // render errors in the errors table (if any) + + + this.errorTable.setErrors(errors, errorLocations); // update the height of the ace editor + + if (this.aceEditor) { + var force = false; + this.aceEditor.resize(force); + } +}; +/** + * Get the selection details + * @returns {{start:{row:Number, column:Number},end:{row:Number, column:Number},text:String}} + */ + + +textmode.getTextSelection = function () { + var selection = {}; + + if (this.textarea) { + var selectionRange = (0,util.getInputSelection)(this.textarea); + + if (this.cursorInfo && this.cursorInfo.line === selectionRange.end.row && this.cursorInfo.column === selectionRange.end.column) { + // selection direction is bottom => up + selection.start = selectionRange.end; + selection.end = selectionRange.start; + } else { + selection = selectionRange; + } + + return { + start: selection.start, + end: selection.end, + text: this.textarea.value.substring(selectionRange.startIndex, selectionRange.endIndex) + }; + } + + if (this.aceEditor) { + var aceSelection = this.aceEditor.getSelection(); + var selectedText = this.aceEditor.getSelectedText(); + var range = aceSelection.getRange(); + var lead = aceSelection.getSelectionLead(); + + if (lead.row === range.end.row && lead.column === range.end.column) { + selection = range; + } else { + // selection direction is bottom => up + selection.start = range.end; + selection.end = range.start; + } + + return { + start: { + row: selection.start.row + 1, + column: selection.start.column + 1 + }, + end: { + row: selection.end.row + 1, + column: selection.end.column + 1 + }, + text: selectedText + }; + } +}; +/** + * Callback registration for selection change + * @param {selectionCallback} callback + * + * @callback selectionCallback + */ + + +textmode.onTextSelectionChange = function (callback) { + if (typeof callback === 'function') { + this._selectionChangedHandler = (0,util.debounce)(callback, this.DEBOUNCE_INTERVAL); + } +}; +/** + * Set selection on editor's text + * @param {{row:Number, column:Number}} startPos selection start position + * @param {{row:Number, column:Number}} endPos selected end position + */ + + +textmode.setTextSelection = function (startPos, endPos) { + if (!startPos || !endPos) return; + + if (this.textarea) { + var startIndex = (0,util.getIndexForPosition)(this.textarea, startPos.row, startPos.column); + var endIndex = (0,util.getIndexForPosition)(this.textarea, endPos.row, endPos.column); + + if (startIndex > -1 && endIndex > -1) { + if (this.textarea.setSelectionRange) { + this.textarea.focus(); + this.textarea.setSelectionRange(startIndex, endIndex); + } else if (this.textarea.createTextRange) { + // IE < 9 + var range = this.textarea.createTextRange(); + range.collapse(true); + range.moveEnd('character', endIndex); + range.moveStart('character', startIndex); + range.select(); + } + + var rows = (this.textarea.value.match(/\n/g) || []).length + 1; + var lineHeight = this.textarea.scrollHeight / rows; + var selectionScrollPos = startPos.row * lineHeight; + this.textarea.scrollTop = selectionScrollPos > this.textarea.clientHeight ? selectionScrollPos - this.textarea.clientHeight / 2 : 0; + } + } else if (this.aceEditor) { + var _range = { + start: { + row: startPos.row - 1, + column: startPos.column - 1 + }, + end: { + row: endPos.row - 1, + column: endPos.column - 1 + } + }; + this.aceEditor.selection.setRange(_range); + this.aceEditor.scrollToLine(startPos.row - 1, true); + } +}; + +function load() { + try { + this.format(); + } catch (err) {// in case of an error, just move on, failing formatting is not a big deal + } +} // define modes + + +var textModeMixins = [{ + mode: 'text', + mixin: textmode, + data: 'text', + load: load +}, { + mode: 'code', + mixin: textmode, + data: 'text', + load: load +}]; + +/***/ }), + +/***/ 8038: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +// ESM COMPAT FLAG +__webpack_require__.r(__webpack_exports__); + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "treeModeMixins": function() { return /* binding */ treeModeMixins; } +}); + +;// CONCATENATED MODULE: ./src/js/autocomplete.js + + +var defaultFilterFunction = { + start: function start(token, match, config) { + return match.indexOf(token) === 0; + }, + contain: function contain(token, match, config) { + return match.indexOf(token) > -1; + } +}; +function autocomplete(config) { + config = config || {}; + config.filter = config.filter || 'start'; + config.trigger = config.trigger || 'keydown'; + config.confirmKeys = config.confirmKeys || [39, 35, 9]; // right, end, tab + + config.caseSensitive = config.caseSensitive || false; // autocomplete case sensitive + + var fontSize = ''; + var fontFamily = ''; + var wrapper = document.createElement('div'); + wrapper.style.position = 'relative'; + wrapper.style.outline = '0'; + wrapper.style.border = '0'; + wrapper.style.margin = '0'; + wrapper.style.padding = '0'; + var dropDown = document.createElement('div'); + dropDown.className = 'autocomplete dropdown'; + dropDown.style.position = 'absolute'; + dropDown.style.visibility = 'hidden'; + var spacer; + var leftSide; // <-- it will contain the leftSide part of the textfield (the bit that was already autocompleted) + + var createDropDownController = function createDropDownController(elem, rs) { + var rows = []; + var ix = 0; + var oldIndex = -1; // TODO: move this styling in JS to SCSS + + var onMouseOver = function onMouseOver() { + this.style.backgroundColor = '#ddd'; + }; + + var onMouseOut = function onMouseOut() { + this.style.backgroundColor = ''; + }; + + var onMouseDown = function onMouseDown() { + p.hide(); + p.onmouseselection(this.__hint, p.rs); + }; + + var p = { + rs: rs, + hide: function hide() { + elem.style.visibility = 'hidden'; // rs.hideDropDown(); + }, + refresh: function refresh(token, array) { + elem.style.visibility = 'hidden'; + ix = 0; + elem.textContent = ''; + var vph = window.innerHeight || document.documentElement.clientHeight; + var rect = elem.parentNode.getBoundingClientRect(); + var distanceToTop = rect.top - 6; // heuristic give 6px + + var distanceToBottom = vph - rect.bottom - 6; // distance from the browser border. + + rows = []; + var filterFn = typeof config.filter === 'function' ? config.filter : defaultFilterFunction[config.filter]; + var filtered = !filterFn ? [] : array.filter(function (match) { + return filterFn(config.caseSensitive ? token : token.toLowerCase(), config.caseSensitive ? match : match.toLowerCase(), config); + }); + rows = filtered.map(function (row) { + var divRow = document.createElement('div'); + divRow.className = 'item'; // divRow.style.color = config.color; + + divRow.onmouseover = onMouseOver; + divRow.onmouseout = onMouseOut; + divRow.onmousedown = onMouseDown; + divRow.__hint = row; + divRow.textContent = ''; + divRow.appendChild(document.createTextNode(row.substring(0, token.length))); + var b = document.createElement('b'); + b.appendChild(document.createTextNode(row.substring(token.length))); + divRow.appendChild(b); + elem.appendChild(divRow); + return divRow; + }); + + if (rows.length === 0) { + return; // nothing to show. + } + + if (rows.length === 1 && (token.toLowerCase() === rows[0].__hint.toLowerCase() && !config.caseSensitive || token === rows[0].__hint && config.caseSensitive)) { + return; // do not show the dropDown if it has only one element which matches what we have just displayed. + } + + if (rows.length < 2) return; + p.highlight(0); + + if (distanceToTop > distanceToBottom * 3) { + // Heuristic (only when the distance to the to top is 4 times more than distance to the bottom + elem.style.maxHeight = distanceToTop + 'px'; // we display the dropDown on the top of the input text + + elem.style.top = ''; + elem.style.bottom = '100%'; + } else { + elem.style.top = '100%'; + elem.style.bottom = ''; + elem.style.maxHeight = distanceToBottom + 'px'; + } + + elem.style.visibility = 'visible'; + }, + highlight: function highlight(index) { + if (oldIndex !== -1 && rows[oldIndex]) { + rows[oldIndex].className = 'item'; + } + + rows[index].className = 'item hover'; + oldIndex = index; + }, + move: function move(step) { + // moves the selection either up or down (unless it's not possible) step is either +1 or -1. + if (elem.style.visibility === 'hidden') return ''; // nothing to move if there is no dropDown. (this happens if the user hits escape and then down or up) + + if (ix + step === -1 || ix + step === rows.length) return rows[ix].__hint; // NO CIRCULAR SCROLLING. + + ix += step; + p.highlight(ix); + return rows[ix].__hint; // txtShadow.value = uRows[uIndex].__hint ; + }, + onmouseselection: function onmouseselection() {} // it will be overwritten. + + }; + return p; + }; + + function setEndOfContenteditable(contentEditableElement) { + var range, selection; + + if (document.createRange) { + // Firefox, Chrome, Opera, Safari, IE 9+ + range = document.createRange(); // Create a range (a range is a like the selection but invisible) + + range.selectNodeContents(contentEditableElement); // Select the entire contents of the element with the range + + range.collapse(false); // collapse the range to the end point. false means collapse to end rather than the start + + selection = window.getSelection(); // get the selection object (allows you to change selection) + + selection.removeAllRanges(); // remove any selections already made + + selection.addRange(range); // make the range you have just created the visible selection + } else if (document.selection) { + // IE 8 and lower + range = document.body.createTextRange(); // Create a range (a range is a like the selection but invisible) + + range.moveToElementText(contentEditableElement); // Select the entire contents of the element with the range + + range.collapse(false); // collapse the range to the end point. false means collapse to end rather than the start + + range.select(); // Select the range (make it the visible selection + } + } + + function calculateWidthForText(text) { + if (spacer === undefined) { + // on first call only. + spacer = document.createElement('span'); + spacer.style.visibility = 'hidden'; + spacer.style.position = 'fixed'; + spacer.style.outline = '0'; + spacer.style.margin = '0'; + spacer.style.padding = '0'; + spacer.style.border = '0'; + spacer.style.left = '0'; + spacer.style.whiteSpace = 'pre'; + spacer.style.fontSize = fontSize; + spacer.style.fontFamily = fontFamily; + spacer.style.fontWeight = 'normal'; + document.body.appendChild(spacer); + } + + spacer.textContent = text; + return spacer.getBoundingClientRect().right; + } + + var rs = { + onArrowDown: function onArrowDown() {}, + // defaults to no action. + onArrowUp: function onArrowUp() {}, + // defaults to no action. + onEnter: function onEnter() {}, + // defaults to no action. + onTab: function onTab() {}, + // defaults to no action. + startFrom: 0, + options: [], + element: null, + elementHint: null, + elementStyle: null, + wrapper: wrapper, + // Only to allow easy access to the HTML elements to the final user (possibly for minor customizations) + show: function show(element, startPos, options) { + var _this = this; + + this.startFrom = startPos; + this.wrapper.remove(); + + if (this.elementHint) { + this.elementHint.remove(); + this.elementHint = null; + } + + if (fontSize === '') { + fontSize = window.getComputedStyle(element).getPropertyValue('font-size'); + } + + if (fontFamily === '') { + fontFamily = window.getComputedStyle(element).getPropertyValue('font-family'); + } + + dropDown.style.marginLeft = '0'; + dropDown.style.marginTop = element.getBoundingClientRect().height + 'px'; + this.options = options.map(String); + + if (this.element !== element) { + this.element = element; + this.elementStyle = { + zIndex: this.element.style.zIndex, + position: this.element.style.position, + backgroundColor: this.element.style.backgroundColor, + borderColor: this.element.style.borderColor + }; + } + + this.element.style.zIndex = 3; + this.element.style.position = 'relative'; + this.element.style.backgroundColor = 'transparent'; + this.element.style.borderColor = 'transparent'; + this.elementHint = element.cloneNode(); + this.elementHint.className = 'autocomplete hint'; + this.elementHint.style.zIndex = 2; + this.elementHint.style.position = 'absolute'; + + this.elementHint.onfocus = function () { + _this.element.focus(); + }; + + if (this.element.addEventListener) { + this.element.removeEventListener('keydown', keyDownHandler); + this.element.addEventListener('keydown', keyDownHandler, false); + this.element.removeEventListener('blur', onBlurHandler); + this.element.addEventListener('blur', onBlurHandler, false); + } + + wrapper.appendChild(this.elementHint); + wrapper.appendChild(dropDown); + element.parentElement.appendChild(wrapper); + this.repaint(element); + }, + setText: function setText(text) { + this.element.innerText = text; + }, + getText: function getText() { + return this.element.innerText; + }, + hideDropDown: function hideDropDown() { + this.wrapper.remove(); + + if (this.elementHint) { + this.elementHint.remove(); + this.elementHint = null; + dropDownController.hide(); + this.element.style.zIndex = this.elementStyle.zIndex; + this.element.style.position = this.elementStyle.position; + this.element.style.backgroundColor = this.elementStyle.backgroundColor; + this.element.style.borderColor = this.elementStyle.borderColor; + } + }, + repaint: function repaint(element) { + var text = element.innerText; + text = text.replace('\n', ''); + var optionsLength = this.options.length; // breaking text in leftSide and token. + + var token = text.substring(this.startFrom); + leftSide = text.substring(0, this.startFrom); + + for (var i = 0; i < optionsLength; i++) { + var opt = this.options[i]; + + if (!config.caseSensitive && opt.toLowerCase().indexOf(token.toLowerCase()) === 0 || config.caseSensitive && opt.indexOf(token) === 0) { + // <-- how about upperCase vs. lowercase + this.elementHint.innerText = leftSide + token + opt.substring(token.length); + this.elementHint.realInnerText = leftSide + opt; + break; + } + } // moving the dropDown and refreshing it. + + + dropDown.style.left = calculateWidthForText(leftSide) + 'px'; + dropDownController.refresh(token, this.options); + this.elementHint.style.width = calculateWidthForText(this.elementHint.innerText) + 10 + 'px'; + var wasDropDownHidden = dropDown.style.visibility === 'hidden'; + + if (!wasDropDownHidden) { + this.elementHint.style.width = calculateWidthForText(this.elementHint.innerText) + dropDown.clientWidth + 'px'; + } + } + }; + var dropDownController = createDropDownController(dropDown, rs); + + var keyDownHandler = function (e) { + // console.log("Keydown:" + e.keyCode); + e = e || window.event; + var keyCode = e.keyCode; + if (this.elementHint == null) return; + + if (keyCode === 33) { + return; + } // page up (do nothing) + + + if (keyCode === 34) { + return; + } // page down (do nothing); + + + if (keyCode === 27) { + // escape + rs.hideDropDown(); + rs.element.focus(); + e.preventDefault(); + e.stopPropagation(); + return; + } + + var text = this.element.innerText; + text = text.replace('\n', ''); + + if (config.confirmKeys.indexOf(keyCode) >= 0) { + // (autocomplete triggered) + if (keyCode === 9) { + if (this.elementHint.innerText.length === 0) { + rs.onTab(); + } + } + + if (this.elementHint.innerText.length > 0) { + // if there is a hint + if (this.element.innerText !== this.elementHint.realInnerText) { + this.element.innerText = this.elementHint.realInnerText; + rs.hideDropDown(); + setEndOfContenteditable(this.element); + + if (keyCode === 9) { + rs.element.focus(); + e.preventDefault(); + e.stopPropagation(); + } + } + } + + return; + } + + if (keyCode === 13) { + // enter (autocomplete triggered) + if (this.elementHint.innerText.length === 0) { + // if there is a hint + rs.onEnter(); + } else { + var wasDropDownHidden = dropDown.style.visibility === 'hidden'; + dropDownController.hide(); + + if (wasDropDownHidden) { + rs.hideDropDown(); + rs.element.focus(); + rs.onEnter(); + return; + } + + this.element.innerText = this.elementHint.realInnerText; + rs.hideDropDown(); + setEndOfContenteditable(this.element); + e.preventDefault(); + e.stopPropagation(); + } + + return; + } + + if (keyCode === 40) { + // down + var token = text.substring(this.startFrom); + var m = dropDownController.move(+1); + + if (m === '') { + rs.onArrowDown(); + } + + this.elementHint.innerText = leftSide + token + m.substring(token.length); + this.elementHint.realInnerText = leftSide + m; + e.preventDefault(); + e.stopPropagation(); + return; + } + + if (keyCode === 38) { + // up + var _token = text.substring(this.startFrom); + + var _m = dropDownController.move(-1); + + if (_m === '') { + rs.onArrowUp(); + } + + this.elementHint.innerText = leftSide + _token + _m.substring(_token.length); + this.elementHint.realInnerText = leftSide + _m; + e.preventDefault(); + e.stopPropagation(); + } + }.bind(rs); + + var onBlurHandler = function onBlurHandler(e) { + rs.hideDropDown(); // console.log("Lost focus."); + }; + + dropDownController.onmouseselection = function (text, rs) { + rs.element.innerText = rs.elementHint.innerText = leftSide + text; + rs.hideDropDown(); + window.setTimeout(function () { + rs.element.focus(); + setEndOfContenteditable(rs.element); + }, 1); + }; + + return rs; +} +// EXTERNAL MODULE: ./src/js/ContextMenu.js +var ContextMenu = __webpack_require__(897); +// EXTERNAL MODULE: ./src/js/FocusTracker.js +var FocusTracker = __webpack_require__(2474); +;// CONCATENATED MODULE: ./src/js/Highlighter.js + +/** + * The highlighter can highlight/unhighlight a node, and + * animate the visibility of a context menu. + * @constructor Highlighter + */ + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +var Highlighter = /*#__PURE__*/function () { + function Highlighter() { + _classCallCheck(this, Highlighter); + + this.locked = false; + } + /** + * Hightlight given node and its childs + * @param {Node} node + */ + + + _createClass(Highlighter, [{ + key: "highlight", + value: function highlight(node) { + if (this.locked) { + return; + } + + if (this.node !== node) { + // unhighlight current node + if (this.node) { + this.node.setHighlight(false); + } // highlight new node + + + this.node = node; + this.node.setHighlight(true); + } // cancel any current timeout + + + this._cancelUnhighlight(); + } + /** + * Unhighlight currently highlighted node. + * Will be done after a delay + */ + + }, { + key: "unhighlight", + value: function unhighlight() { + if (this.locked) { + return; + } + + var me = this; + + if (this.node) { + this._cancelUnhighlight(); // do the unhighlighting after a small delay, to prevent re-highlighting + // the same node when moving from the drag-icon to the contextmenu-icon + // or vice versa. + + + this.unhighlightTimer = setTimeout(function () { + me.node.setHighlight(false); + me.node = undefined; + me.unhighlightTimer = undefined; + }, 0); + } + } + /** + * Cancel an unhighlight action (if before the timeout of the unhighlight action) + * @private + */ + + }, { + key: "_cancelUnhighlight", + value: function _cancelUnhighlight() { + if (this.unhighlightTimer) { + clearTimeout(this.unhighlightTimer); + this.unhighlightTimer = undefined; + } + } + /** + * Lock highlighting or unhighlighting nodes. + * methods highlight and unhighlight do not work while locked. + */ + + }, { + key: "lock", + value: function lock() { + this.locked = true; + } + /** + * Unlock highlighting or unhighlighting nodes + */ + + }, { + key: "unlock", + value: function unlock() { + this.locked = false; + } + }]); + + return Highlighter; +}(); +// EXTERNAL MODULE: ./src/js/i18n.js +var i18n = __webpack_require__(7907); +// EXTERNAL MODULE: ./src/js/jmespathQuery.js +var jmespathQuery = __webpack_require__(6056); +// EXTERNAL MODULE: ./src/js/ModeSwitcher.js +var ModeSwitcher = __webpack_require__(6617); +// EXTERNAL MODULE: ./node_modules/javascript-natural-sort/naturalSort.js +var naturalSort = __webpack_require__(233); +var naturalSort_default = /*#__PURE__*/__webpack_require__.n(naturalSort); +// EXTERNAL MODULE: ./src/js/createAbsoluteAnchor.js +var createAbsoluteAnchor = __webpack_require__(2602); +// EXTERNAL MODULE: ./src/js/util.js +var util = __webpack_require__(9791); +;// CONCATENATED MODULE: ./src/js/appendNodeFactory.js + + + + + +/** + * A factory function to create an AppendNode, which depends on a Node + * @param {Node} Node + */ + +function appendNodeFactory(Node) { + /** + * @constructor AppendNode + * @extends Node + * @param {TreeEditor} editor + * Create a new AppendNode. This is a special node which is created at the + * end of the list with childs for an object or array + */ + function AppendNode(editor) { + /** @type {TreeEditor} */ + this.editor = editor; + this.dom = {}; + } + + AppendNode.prototype = new Node(); + /** + * Return a table row with an append button. + * @return {Element} dom TR element + */ + + AppendNode.prototype.getDom = function () { + // TODO: implement a new solution for the append node + var dom = this.dom; + + if (dom.tr) { + return dom.tr; + } + + this._updateEditability(); // a row for the append button + + + var trAppend = document.createElement('tr'); + trAppend.className = 'jsoneditor-append'; + trAppend.node = this; + dom.tr = trAppend; // TODO: consistent naming + + if (this.editor.options.mode === 'tree') { + // a cell for the dragarea column + dom.tdDrag = document.createElement('td'); // create context menu + + var tdMenu = document.createElement('td'); + dom.tdMenu = tdMenu; + var menu = document.createElement('button'); + menu.type = 'button'; + menu.className = 'jsoneditor-button jsoneditor-contextmenu-button'; + menu.title = 'Click to open the actions menu (Ctrl+M)'; + dom.menu = menu; + tdMenu.appendChild(dom.menu); + } // a cell for the contents (showing text 'empty') + + + var tdAppend = document.createElement('td'); + var domText = document.createElement('div'); + domText.appendChild(document.createTextNode('(' + (0,i18n/* translate */.Iu)('empty') + ')')); + domText.className = 'jsoneditor-readonly'; + tdAppend.appendChild(domText); + dom.td = tdAppend; + dom.text = domText; + this.updateDom(); + return trAppend; + }; + /** + * Append node doesn't have a path + * @returns {null} + */ + + + AppendNode.prototype.getPath = function () { + return null; + }; + /** + * Append node doesn't have an index + * @returns {null} + */ + + + AppendNode.prototype.getIndex = function () { + return null; + }; + /** + * Update the HTML dom of the Node + */ + + + AppendNode.prototype.updateDom = function (options) { + var dom = this.dom; + var tdAppend = dom.td; + + if (tdAppend) { + tdAppend.style.paddingLeft = this.getLevel() * 24 + 26 + 'px'; // TODO: not so nice hard coded offset + } + + var domText = dom.text; + + if (domText) { + domText.firstChild.nodeValue = '(' + (0,i18n/* translate */.Iu)('empty') + ' ' + this.parent.type + ')'; + } // attach or detach the contents of the append node: + // hide when the parent has childs, show when the parent has no childs + + + var trAppend = dom.tr; + + if (!this.isVisible()) { + if (dom.tr.firstChild) { + if (dom.tdDrag) { + trAppend.removeChild(dom.tdDrag); + } + + if (dom.tdMenu) { + trAppend.removeChild(dom.tdMenu); + } + + trAppend.removeChild(tdAppend); + } + } else { + if (!dom.tr.firstChild) { + if (dom.tdDrag) { + trAppend.appendChild(dom.tdDrag); + } + + if (dom.tdMenu) { + trAppend.appendChild(dom.tdMenu); + } + + trAppend.appendChild(tdAppend); + } + } + }; + /** + * Check whether the AppendNode is currently visible. + * the AppendNode is visible when its parent has no childs (i.e. is empty). + * @return {boolean} isVisible + */ + + + AppendNode.prototype.isVisible = function () { + return this.parent.childs.length === 0; + }; + /** + * Show a contextmenu for this node + * @param {HTMLElement} anchor The element to attach the menu to. + * @param {function} [onClose] Callback method called when the context menu + * is being closed. + */ + + + AppendNode.prototype.showContextMenu = function (anchor, onClose) { + var node = this; + var appendSubmenu = [{ + text: (0,i18n/* translate */.Iu)('auto'), + className: 'jsoneditor-type-auto', + title: (0,i18n/* translate */.Iu)('autoType'), + click: function click() { + node._onAppend('', '', 'auto'); + } + }, { + text: (0,i18n/* translate */.Iu)('array'), + className: 'jsoneditor-type-array', + title: (0,i18n/* translate */.Iu)('arrayType'), + click: function click() { + node._onAppend('', []); + } + }, { + text: (0,i18n/* translate */.Iu)('object'), + className: 'jsoneditor-type-object', + title: (0,i18n/* translate */.Iu)('objectType'), + click: function click() { + node._onAppend('', {}); + } + }, { + text: (0,i18n/* translate */.Iu)('string'), + className: 'jsoneditor-type-string', + title: (0,i18n/* translate */.Iu)('stringType'), + click: function click() { + node._onAppend('', '', 'string'); + } + }]; + node.addTemplates(appendSubmenu, true); + var items = [// create append button + { + text: (0,i18n/* translate */.Iu)('appendText'), + title: (0,i18n/* translate */.Iu)('appendTitleAuto'), + submenuTitle: (0,i18n/* translate */.Iu)('appendSubmenuTitle'), + className: 'jsoneditor-insert', + click: function click() { + node._onAppend('', '', 'auto'); + }, + submenu: appendSubmenu + }]; + + if (this.editor.options.onCreateMenu) { + var path = node.parent.getPath(); + items = this.editor.options.onCreateMenu(items, { + type: 'append', + path: path, + paths: [path] + }); + } + + var menu = new ContextMenu/* ContextMenu */.x(items, { + close: onClose + }); + menu.show(anchor, this.editor.getPopupAnchor()); + }; + /** + * Handle an event. The event is caught centrally by the editor + * @param {Event} event + */ + + + AppendNode.prototype.onEvent = function (event) { + var type = event.type; + var target = event.target || event.srcElement; + var dom = this.dom; // highlight the append nodes parent + + var menu = dom.menu; + + if (target === menu) { + if (type === 'mouseover') { + this.editor.highlighter.highlight(this.parent); + } else if (type === 'mouseout') { + this.editor.highlighter.unhighlight(); + } + } // context menu events + + + if (type === 'click' && target === dom.menu) { + var highlighter = this.editor.highlighter; + highlighter.highlight(this.parent); + highlighter.lock(); + (0,util.addClassName)(dom.menu, 'jsoneditor-selected'); + this.showContextMenu(dom.menu, function () { + (0,util.removeClassName)(dom.menu, 'jsoneditor-selected'); + highlighter.unlock(); + highlighter.unhighlight(); + }); + } + + if (type === 'keydown') { + this.onKeyDown(event); + } + }; + + return AppendNode; +} +;// CONCATENATED MODULE: ./src/js/showMoreNodeFactory.js + + + +/** + * A factory function to create an ShowMoreNode, which depends on a Node + * @param {function} Node + */ + +function showMoreNodeFactory(Node) { + /** + * @constructor ShowMoreNode + * @extends Node + * @param {TreeEditor} editor + * @param {Node} parent + * Create a new ShowMoreNode. This is a special node which is created + * for arrays or objects having more than 100 items + */ + function ShowMoreNode(editor, parent) { + /** @type {TreeEditor} */ + this.editor = editor; + this.parent = parent; + this.dom = {}; + } + + ShowMoreNode.prototype = new Node(); + /** + * Return a table row with an append button. + * @return {Element} dom TR element + */ + + ShowMoreNode.prototype.getDom = function () { + if (this.dom.tr) { + return this.dom.tr; + } + + this._updateEditability(); // display "show more" + + + if (!this.dom.tr) { + var me = this; + var parent = this.parent; + var showMoreButton = document.createElement('a'); + showMoreButton.appendChild(document.createTextNode((0,i18n/* translate */.Iu)('showMore'))); + showMoreButton.href = '#'; + + showMoreButton.onclick = function (event) { + // TODO: use callback instead of accessing a method of the parent + parent.visibleChilds = Math.floor(parent.visibleChilds / parent.getMaxVisibleChilds() + 1) * parent.getMaxVisibleChilds(); + me.updateDom(); + parent.showChilds(); + event.preventDefault(); + return false; + }; + + var showAllButton = document.createElement('a'); + showAllButton.appendChild(document.createTextNode((0,i18n/* translate */.Iu)('showAll'))); + showAllButton.href = '#'; + + showAllButton.onclick = function (event) { + // TODO: use callback instead of accessing a method of the parent + parent.visibleChilds = Infinity; + me.updateDom(); + parent.showChilds(); + event.preventDefault(); + return false; + }; + + var moreContents = document.createElement('div'); + var moreText = document.createTextNode(this._getShowMoreText()); + moreContents.className = 'jsoneditor-show-more'; + moreContents.appendChild(moreText); + moreContents.appendChild(showMoreButton); + moreContents.appendChild(document.createTextNode('. ')); + moreContents.appendChild(showAllButton); + moreContents.appendChild(document.createTextNode('. ')); + var tdContents = document.createElement('td'); + tdContents.appendChild(moreContents); + var moreTr = document.createElement('tr'); + + if (this.editor.options.mode === 'tree') { + moreTr.appendChild(document.createElement('td')); + moreTr.appendChild(document.createElement('td')); + } + + moreTr.appendChild(tdContents); + moreTr.className = 'jsoneditor-show-more'; + this.dom.tr = moreTr; + this.dom.moreContents = moreContents; + this.dom.moreText = moreText; + } + + this.updateDom(); + return this.dom.tr; + }; + /** + * Update the HTML dom of the Node + */ + + + ShowMoreNode.prototype.updateDom = function (options) { + if (this.isVisible()) { + // attach to the right child node (the first non-visible child) + this.dom.tr.node = this.parent.childs[this.parent.visibleChilds]; + + if (!this.dom.tr.parentNode) { + var nextTr = this.parent._getNextTr(); + + if (nextTr) { + nextTr.parentNode.insertBefore(this.dom.tr, nextTr); + } + } // update the counts in the text + + + this.dom.moreText.nodeValue = this._getShowMoreText(); // update left margin + + this.dom.moreContents.style.marginLeft = (this.getLevel() + 1) * 24 + 'px'; + } else { + if (this.dom.tr && this.dom.tr.parentNode) { + this.dom.tr.parentNode.removeChild(this.dom.tr); + } + } + }; + + ShowMoreNode.prototype._getShowMoreText = function () { + return (0,i18n/* translate */.Iu)('showMoreStatus', { + visibleChilds: this.parent.visibleChilds, + totalChilds: this.parent.childs.length + }) + ' '; + }; + /** + * Check whether the ShowMoreNode is currently visible. + * the ShowMoreNode is visible when it's parent has more childs than + * the current visibleChilds + * @return {boolean} isVisible + */ + + + ShowMoreNode.prototype.isVisible = function () { + return this.parent.expanded && this.parent.childs.length > this.parent.visibleChilds; + }; + /** + * Handle an event. The event is caught centrally by the editor + * @param {Event} event + */ + + + ShowMoreNode.prototype.onEvent = function (event) { + var type = event.type; + + if (type === 'keydown') { + this.onKeyDown(event); + } + }; + + return ShowMoreNode; +} +// EXTERNAL MODULE: ./src/js/showSortModal.js +var js_showSortModal = __webpack_require__(6210); +// EXTERNAL MODULE: ./src/js/showTransformModal.js + 1 modules +var js_showTransformModal = __webpack_require__(2558); +// EXTERNAL MODULE: ./src/js/constants.js +var constants = __webpack_require__(4188); +;// CONCATENATED MODULE: ./src/js/Node.js + + +function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + +function Node_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function Node_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function Node_createClass(Constructor, protoProps, staticProps) { if (protoProps) Node_defineProperties(Constructor.prototype, protoProps); if (staticProps) Node_defineProperties(Constructor, staticProps); return Constructor; } + + + + + + + + + + + +/** + * @constructor Node + * Create a new Node + * @param {./treemode} editor + * @param {Object} [params] Can contain parameters: + * {string} field + * {boolean} fieldEditable + * {*} value + * {String} type Can have values 'auto', 'array', + * 'object', or 'string'. + */ + +var Node = /*#__PURE__*/function () { + function Node(editor, params) { + Node_classCallCheck(this, Node); + + /** @type {./treemode} */ + this.editor = editor; + this.dom = {}; + this.expanded = false; + + if (params && params instanceof Object) { + this.setField(params.field, params.fieldEditable); + + if ('value' in params) { + this.setValue(params.value, params.type); + } + + if ('internalValue' in params) { + this.setInternalValue(params.internalValue); + } + } else { + this.setField(''); + this.setValue(null); + } + + this._debouncedOnChangeValue = (0,util.debounce)(this._onChangeValue.bind(this), Node.prototype.DEBOUNCE_INTERVAL); + this._debouncedOnChangeField = (0,util.debounce)(this._onChangeField.bind(this), Node.prototype.DEBOUNCE_INTERVAL); // starting value for visible children + + this.visibleChilds = this.getMaxVisibleChilds(); + } + + Node_createClass(Node, [{ + key: "getMaxVisibleChilds", + value: function getMaxVisibleChilds() { + return this.editor && this.editor.options && this.editor.options.maxVisibleChilds ? this.editor.options.maxVisibleChilds : DEFAULT_MAX_VISIBLE_CHILDS; + } + /** + * Determine whether the field and/or value of this node are editable + * @private + */ + + }, { + key: "_updateEditability", + value: function _updateEditability() { + this.editable = { + field: true, + value: true + }; + + if (this.editor) { + this.editable.field = this.editor.options.mode === 'tree'; + this.editable.value = this.editor.options.mode !== 'view'; + + if ((this.editor.options.mode === 'tree' || this.editor.options.mode === 'form') && typeof this.editor.options.onEditable === 'function') { + var editable = this.editor.options.onEditable({ + field: this.field, + value: this.value, + path: this.getPath() + }); + + if (typeof editable === 'boolean') { + this.editable.field = editable; + this.editable.value = editable; + } else if (_typeof(editable) === 'object' && editable !== null) { + if (typeof editable.field === 'boolean') this.editable.field = editable.field; + if (typeof editable.value === 'boolean') this.editable.value = editable.value; + } else { + console.error('Invalid return value for function onEditable.', 'Actual value:', editable, '.', 'Either a boolean or object { field: boolean, value: boolean } expected.'); + this.editable.field = false; + this.editable.value = false; + } + } + } + } + /** + * Get the path of this node + * @return {{string|number}[]} Array containing the path to this node. + * Element is a number if is the index of an array, a string otherwise. + */ + + }, { + key: "getPath", + value: function getPath() { + var node = this; + var path = []; + + while (node) { + var field = node.getName(); + + if (field !== undefined) { + path.unshift(field); + } + + node = node.parent; + } + + return path; + } + /** + * Get the internal path of this node, a list with the child indexes. + * @return {String[]} Array containing the internal path to this node + */ + + }, { + key: "getInternalPath", + value: function getInternalPath() { + var node = this; + var internalPath = []; + + while (node) { + if (node.parent) { + internalPath.unshift(node.getIndex()); + } + + node = node.parent; + } + + return internalPath; + } + /** + * Get node serializable name + * @returns {String|Number} + */ + + }, { + key: "getName", + value: function getName() { + return !this.parent ? undefined // do not add an (optional) field name of the root node + : this.parent.type !== 'array' ? this.field : this.index; + } + /** + * Find child node by serializable path + * @param {Array} path + */ + + }, { + key: "findNodeByPath", + value: function findNodeByPath(path) { + if (!path) { + return; + } + + if (path.length === 0) { + return this; + } + + if (path.length && this.childs && this.childs.length) { + for (var i = 0; i < this.childs.length; ++i) { + if ('' + path[0] === '' + this.childs[i].getName()) { + return this.childs[i].findNodeByPath(path.slice(1)); + } + } + } + } + /** + * Find child node by an internal path: the indexes of the childs nodes + * @param {Array} internalPath + * @return {Node | undefined} Returns the node if the path exists. + * Returns undefined otherwise. + */ + + }, { + key: "findNodeByInternalPath", + value: function findNodeByInternalPath(internalPath) { + if (!internalPath) { + return undefined; + } + + var node = this; + + for (var i = 0; i < internalPath.length && node; i++) { + var childIndex = internalPath[i]; + node = node.childs[childIndex]; + } + + return node; + } + /** + * @typedef {{value: String|Object|Number|Boolean, path: Array.}} SerializableNode + * + * Returns serializable representation for the node + * @return {SerializableNode} + */ + + }, { + key: "serialize", + value: function serialize() { + return { + value: this.getValue(), + path: this.getPath() + }; + } + /** + * Find a Node from a JSON path like '.items[3].name' + * @param {string} jsonPath + * @return {Node | null} Returns the Node when found, returns null if not found + */ + + }, { + key: "findNode", + value: function findNode(jsonPath) { + var path = (0,util.parsePath)(jsonPath); + var node = this; + + var _loop = function _loop() { + var prop = path.shift(); + + if (typeof prop === 'number') { + if (node.type !== 'array') { + throw new Error('Cannot get child node at index ' + prop + ': node is no array'); + } + + node = node.childs[prop]; + } else { + // string + if (node.type !== 'object') { + throw new Error('Cannot get child node ' + prop + ': node is no object'); + } + + node = node.childs.filter(function (child) { + return child.field === prop; + })[0]; + } + }; + + while (node && path.length > 0) { + _loop(); + } + + return node; + } + /** + * Find all parents of this node. The parents are ordered from root node towards + * the original node. + * @return {Array.} + */ + + }, { + key: "findParents", + value: function findParents() { + var parents = []; + var parent = this.parent; + + while (parent) { + parents.unshift(parent); + parent = parent.parent; + } + + return parents; + } + /** + * + * @param {{dataPath: string, keyword: string, message: string, params: Object, schemaPath: string} | null} error + * @param {Node} [child] When this is the error of a parent node, pointing + * to an invalid child node, the child node itself + * can be provided. If provided, clicking the error + * icon will set focus to the invalid child node. + */ + + }, { + key: "setError", + value: function setError(error, child) { + this.error = error; + this.errorChild = child; + + if (this.dom && this.dom.tr) { + this.updateError(); + } + } + /** + * Render the error + */ + + }, { + key: "updateError", + value: function updateError() { + var _this = this; + + var error = this.fieldError || this.valueError || this.error; + var tdError = this.dom.tdError; + + if (error && this.dom && this.dom.tr) { + (0,util.addClassName)(this.dom.tr, 'jsoneditor-validation-error'); + + if (!tdError) { + tdError = document.createElement('td'); + this.dom.tdError = tdError; + this.dom.tdValue.parentNode.appendChild(tdError); + } + + var button = document.createElement('button'); + button.type = 'button'; + button.className = 'jsoneditor-button jsoneditor-schema-error'; + + var destroy = function destroy() { + if (_this.dom.popupAnchor) { + _this.dom.popupAnchor.destroy(); // this will trigger the onDestroy callback + + } + }; + + var onDestroy = function onDestroy() { + delete _this.dom.popupAnchor; + }; + + var createPopup = function createPopup(destroyOnMouseOut) { + var frame = _this.editor.frame; + _this.dom.popupAnchor = (0,createAbsoluteAnchor/* createAbsoluteAnchor */.w)(button, _this.editor.getPopupAnchor(), onDestroy, destroyOnMouseOut); + var popupWidth = 200; // must correspond to what's configured in the CSS + + var buttonRect = button.getBoundingClientRect(); + var frameRect = frame.getBoundingClientRect(); + var position = frameRect.width - buttonRect.x > popupWidth / 2 + 20 ? 'jsoneditor-above' : 'jsoneditor-left'; + var popover = document.createElement('div'); + popover.className = 'jsoneditor-popover ' + position; + popover.appendChild(document.createTextNode(error.message)); + + _this.dom.popupAnchor.appendChild(popover); + }; + + button.onmouseover = function () { + if (!_this.dom.popupAnchor) { + createPopup(true); + } + }; + + button.onfocus = function () { + destroy(); + createPopup(false); + }; + + button.onblur = function () { + destroy(); + }; // when clicking the error icon, expand all nodes towards the invalid + // child node, and set focus to the child node + + + var child = this.errorChild; + + if (child) { + button.onclick = function showInvalidNode() { + child.findParents().forEach(function (parent) { + parent.expand(false); + }); + child.scrollTo(function () { + child.focus(); + }); + }; + } // apply the error message to the node + + + while (tdError.firstChild) { + tdError.removeChild(tdError.firstChild); + } + + tdError.appendChild(button); + } else { + if (this.dom.tr) { + (0,util.removeClassName)(this.dom.tr, 'jsoneditor-validation-error'); + } + + if (tdError) { + this.dom.tdError.parentNode.removeChild(this.dom.tdError); + delete this.dom.tdError; + } + } + } + /** + * Get the index of this node: the index in the list of childs where this + * node is part of + * @return {number | null} Returns the index, or null if this is the root node + */ + + }, { + key: "getIndex", + value: function getIndex() { + if (this.parent) { + var index = this.parent.childs.indexOf(this); + return index !== -1 ? index : null; + } else { + return -1; + } + } + /** + * Set parent node + * @param {Node} parent + */ + + }, { + key: "setParent", + value: function setParent(parent) { + this.parent = parent; + } + /** + * Set field + * @param {String} field + * @param {boolean} [fieldEditable] + */ + + }, { + key: "setField", + value: function setField(field, fieldEditable) { + this.field = field; + this.previousField = field; + this.fieldEditable = fieldEditable === true; + } + /** + * Get field + * @return {String} + */ + + }, { + key: "getField", + value: function getField() { + if (this.field === undefined) { + this._getDomField(); + } + + return this.field; + } + /** + * Set value. Value is a JSON structure or an element String, Boolean, etc. + * @param {*} value + * @param {String} [type] Specify the type of the value. Can be 'auto', + * 'array', 'object', or 'string' + */ + + }, { + key: "setValue", + value: function setValue(value, type) { + var childValue, child; + var i, j; + var updateDom = false; + var previousChilds = this.childs; + this.type = this._getType(value); // check if type corresponds with the provided type + + if (type && type !== this.type) { + if (type === 'string' && this.type === 'auto') { + this.type = type; + } else { + throw new Error('Type mismatch: ' + 'cannot cast value of type "' + this.type + ' to the specified type "' + type + '"'); + } + } + + if (this.type === 'array') { + // array + if (!this.childs) { + this.childs = []; + } + + for (i = 0; i < value.length; i++) { + childValue = value[i]; + + if (childValue !== undefined && !(childValue instanceof Function)) { + if (i < this.childs.length) { + // reuse existing child, keep its state + child = this.childs[i]; + child.fieldEditable = false; + child.index = i; + child.setValue(childValue); + } else { + // create a new child + child = new Node(this.editor, { + value: childValue + }); + var visible = i < this.getMaxVisibleChilds(); + this.appendChild(child, visible, updateDom); + } + } + } // cleanup redundant childs + // we loop backward to prevent issues with shifting index numbers + + + for (j = this.childs.length; j >= value.length; j--) { + this.removeChild(this.childs[j], updateDom); + } + } else if (this.type === 'object') { + // object + if (!this.childs) { + this.childs = []; + } // cleanup redundant childs + // we loop backward to prevent issues with shifting index numbers + + + for (j = this.childs.length - 1; j >= 0; j--) { + if (!Node_hasOwnProperty(value, this.childs[j].field)) { + this.removeChild(this.childs[j], updateDom); + } + } + + i = 0; + + for (var childField in value) { + if (Node_hasOwnProperty(value, childField)) { + childValue = value[childField]; + + if (childValue !== undefined && !(childValue instanceof Function)) { + var _child = this.findChildByProperty(childField); + + if (_child) { + // reuse existing child, keep its state + _child.setField(childField, true); + + _child.setValue(childValue); + } else { + // create a new child, append to the end + var newChild = new Node(this.editor, { + field: childField, + value: childValue + }); + + var _visible = i < this.getMaxVisibleChilds(); + + this.appendChild(newChild, _visible, updateDom); + } + } + + i++; + } + } + + this.value = ''; // sort object keys during initialization. Must not trigger an onChange action + + if (this.editor.options.sortObjectKeys === true) { + var triggerAction = false; + this.sort([], 'asc', triggerAction); + } + } else { + // value + this.hideChilds(); + delete this.append; + delete this.showMore; + delete this.expanded; + delete this.childs; + this.value = value; + } // recreate the DOM if switching from an object/array to auto/string or vice versa + // needed to recreated the expand button for example + + + if (Array.isArray(previousChilds) !== Array.isArray(this.childs)) { + this.recreateDom(); + } + + this.updateDom({ + updateIndexes: true + }); + this.previousValue = this.value; // used only to check for changes in DOM vs JS model + } + /** + * Set internal value + * @param {*} internalValue Internal value structure keeping type, + * order and duplicates in objects + */ + + }, { + key: "setInternalValue", + value: function setInternalValue(internalValue) { + var childValue, child, visible; + var i, j; + var notUpdateDom = false; + var previousChilds = this.childs; + this.type = internalValue.type; + + if (internalValue.type === 'array') { + // array + if (!this.childs) { + this.childs = []; + } + + for (i = 0; i < internalValue.childs.length; i++) { + childValue = internalValue.childs[i]; + + if (childValue !== undefined && !(childValue instanceof Function)) { + if (i < this.childs.length) { + // reuse existing child, keep its state + child = this.childs[i]; + child.fieldEditable = false; + child.index = i; + child.setInternalValue(childValue); + } else { + // create a new child + child = new Node(this.editor, { + internalValue: childValue + }); + visible = i < this.getMaxVisibleChilds(); + this.appendChild(child, visible, notUpdateDom); + } + } + } // cleanup redundant childs + // we loop backward to prevent issues with shifting index numbers + + + for (j = this.childs.length; j >= internalValue.childs.length; j--) { + this.removeChild(this.childs[j], notUpdateDom); + } + } else if (internalValue.type === 'object') { + // object + if (!this.childs) { + this.childs = []; + } + + for (i = 0; i < internalValue.childs.length; i++) { + childValue = internalValue.childs[i]; + + if (childValue !== undefined && !(childValue instanceof Function)) { + if (i < this.childs.length) { + // reuse existing child, keep its state + child = this.childs[i]; + delete child.index; + child.setField(childValue.field, true); + child.setInternalValue(childValue.value); + } else { + // create a new child + child = new Node(this.editor, { + field: childValue.field, + internalValue: childValue.value + }); + visible = i < this.getMaxVisibleChilds(); + this.appendChild(child, visible, notUpdateDom); + } + } + } // cleanup redundant childs + // we loop backward to prevent issues with shifting index numbers + + + for (j = this.childs.length; j >= internalValue.childs.length; j--) { + this.removeChild(this.childs[j], notUpdateDom); + } + } else { + // value + this.hideChilds(); + delete this.append; + delete this.showMore; + delete this.expanded; + delete this.childs; + this.value = internalValue.value; + } // recreate the DOM if switching from an object/array to auto/string or vice versa + // needed to recreated the expand button for example + + + if (Array.isArray(previousChilds) !== Array.isArray(this.childs)) { + this.recreateDom(); + } + + this.updateDom({ + updateIndexes: true + }); + this.previousValue = this.value; // used only to check for changes in DOM vs JS model + } + /** + * Remove the DOM of this node and it's childs and recreate it again + */ + + }, { + key: "recreateDom", + value: function recreateDom() { + if (this.dom && this.dom.tr && this.dom.tr.parentNode) { + var domAnchor = this._detachFromDom(); + + this.clearDom(); + + this._attachToDom(domAnchor); + } else { + this.clearDom(); + } + } + /** + * Get value. Value is a JSON structure + * @return {*} value + */ + + }, { + key: "getValue", + value: function getValue() { + if (this.type === 'array') { + var arr = []; + this.childs.forEach(function (child) { + arr.push(child.getValue()); + }); + return arr; + } else if (this.type === 'object') { + var obj = {}; + this.childs.forEach(function (child) { + obj[child.getField()] = child.getValue(); + }); + return obj; + } else { + if (this.value === undefined) { + this._getDomValue(); + } + + return this.value; + } + } + /** + * Get internal value, a structure which maintains ordering and duplicates in objects + * @return {*} value + */ + + }, { + key: "getInternalValue", + value: function getInternalValue() { + if (this.type === 'array') { + return { + type: this.type, + childs: this.childs.map(function (child) { + return child.getInternalValue(); + }) + }; + } else if (this.type === 'object') { + return { + type: this.type, + childs: this.childs.map(function (child) { + return { + field: child.getField(), + value: child.getInternalValue() + }; + }) + }; + } else { + if (this.value === undefined) { + this._getDomValue(); + } + + return { + type: this.type, + value: this.value + }; + } + } + /** + * Get the nesting level of this node + * @return {Number} level + */ + + }, { + key: "getLevel", + value: function getLevel() { + return this.parent ? this.parent.getLevel() + 1 : 0; + } + /** + * Get jsonpath of the current node + * @return {Node[]} Returns an array with nodes + */ + + }, { + key: "getNodePath", + value: function getNodePath() { + var path = this.parent ? this.parent.getNodePath() : []; + path.push(this); + return path; + } + /** + * Create a clone of a node + * The complete state of a clone is copied, including whether it is expanded or + * not. The DOM elements are not cloned. + * @return {Node} clone + */ + + }, { + key: "clone", + value: function clone() { + var clone = new Node(this.editor); + clone.type = this.type; + clone.field = this.field; + clone.fieldInnerText = this.fieldInnerText; + clone.fieldEditable = this.fieldEditable; + clone.previousField = this.previousField; + clone.value = this.value; + clone.valueInnerText = this.valueInnerText; + clone.previousValue = this.previousValue; + clone.expanded = this.expanded; + clone.visibleChilds = this.visibleChilds; + + if (this.childs) { + // an object or array + var cloneChilds = []; + this.childs.forEach(function (child) { + var childClone = child.clone(); + childClone.setParent(clone); + cloneChilds.push(childClone); + }); + clone.childs = cloneChilds; + } else { + // a value + clone.childs = undefined; + } + + return clone; + } + /** + * Expand this node and optionally its childs. + * @param {boolean} [recurse] Optional recursion, true by default. When + * true, all childs will be expanded recursively + */ + + }, { + key: "expand", + value: function expand(recurse) { + if (!this.childs) { + return; + } // set this node expanded + + + this.expanded = true; + + if (this.dom.expand) { + this.dom.expand.className = 'jsoneditor-button jsoneditor-expanded'; + } + + this.showChilds(); + + if (recurse !== false) { + this.childs.forEach(function (child) { + child.expand(recurse); + }); + } // update the css classes of table row, and fire onClassName etc + + + this.updateDom({ + recurse: false + }); + } + /** + * Collapse this node and optionally its childs. + * @param {boolean} [recurse] Optional recursion, true by default. When + * true, all childs will be collapsed recursively + */ + + }, { + key: "collapse", + value: function collapse(recurse) { + if (!this.childs) { + return; + } + + this.hideChilds(); // collapse childs in case of recurse + + if (recurse !== false) { + this.childs.forEach(function (child) { + child.collapse(recurse); + }); + } // make this node collapsed + + + if (this.dom.expand) { + this.dom.expand.className = 'jsoneditor-button jsoneditor-collapsed'; + } + + this.expanded = false; // update the css classes of table row, and fire onClassName etc + + this.updateDom({ + recurse: false + }); + } + /** + * Recursively show all childs when they are expanded + */ + + }, { + key: "showChilds", + value: function showChilds() { + var childs = this.childs; + + if (!childs) { + return; + } + + if (!this.expanded) { + return; + } + + var tr = this.dom.tr; + var nextTr; + var table = tr ? tr.parentNode : undefined; + + if (table) { + // show row with append button + var append = this.getAppendDom(); + + if (!append.parentNode) { + nextTr = tr.nextSibling; + + if (nextTr) { + table.insertBefore(append, nextTr); + } else { + table.appendChild(append); + } + } // show childs + + + var iMax = Math.min(this.childs.length, this.visibleChilds); + nextTr = this._getNextTr(); + + for (var i = 0; i < iMax; i++) { + var child = this.childs[i]; + + if (!child.getDom().parentNode) { + table.insertBefore(child.getDom(), nextTr); + } + + child.showChilds(); + } // show "show more childs" if limited + + + var showMore = this.getShowMoreDom(); + nextTr = this._getNextTr(); + + if (!showMore.parentNode) { + table.insertBefore(showMore, nextTr); + } + + this.showMore.updateDom(); // to update the counter + } + } + }, { + key: "_getNextTr", + value: function _getNextTr() { + if (this.showMore && this.showMore.getDom().parentNode) { + return this.showMore.getDom(); + } + + if (this.append && this.append.getDom().parentNode) { + return this.append.getDom(); + } + } + /** + * Hide the node with all its childs + * @param {{resetVisibleChilds: boolean}} [options] + */ + + }, { + key: "hide", + value: function hide(options) { + var tr = this.dom.tr; + var table = tr ? tr.parentNode : undefined; + + if (table) { + table.removeChild(tr); + } + + if (this.dom.popupAnchor) { + this.dom.popupAnchor.destroy(); + } + + this.hideChilds(options); + } + /** + * Recursively hide all childs + * @param {{resetVisibleChilds: boolean}} [options] + */ + + }, { + key: "hideChilds", + value: function hideChilds(options) { + var childs = this.childs; + + if (!childs) { + return; + } + + if (!this.expanded) { + return; + } // hide append row + + + var append = this.getAppendDom(); + + if (append.parentNode) { + append.parentNode.removeChild(append); + } // hide childs + + + this.childs.forEach(function (child) { + child.hide(); + }); // hide "show more" row + + var showMore = this.getShowMoreDom(); + + if (showMore.parentNode) { + showMore.parentNode.removeChild(showMore); + } // reset max visible childs + + + if (!options || options.resetVisibleChilds) { + this.visibleChilds = this.getMaxVisibleChilds(); + } + } + /** + * set custom css classes on a node + */ + + }, { + key: "_updateCssClassName", + value: function _updateCssClassName() { + if (this.dom.field && this.editor && this.editor.options && typeof this.editor.options.onClassName === 'function' && this.dom.tree) { + (0,util.removeAllClassNames)(this.dom.tree); + var addClasses = this.editor.options.onClassName({ + path: this.getPath(), + field: this.field, + value: this.value + }) || ''; + (0,util.addClassName)(this.dom.tree, 'jsoneditor-values ' + addClasses); + } + } + }, { + key: "recursivelyUpdateCssClassesOnNodes", + value: function recursivelyUpdateCssClassesOnNodes() { + this._updateCssClassName(); + + if (Array.isArray(this.childs)) { + for (var i = 0; i < this.childs.length; i++) { + this.childs[i].recursivelyUpdateCssClassesOnNodes(); + } + } + } + /** + * Goes through the path from the node to the root and ensures that it is expanded + */ + + }, { + key: "expandTo", + value: function expandTo() { + var currentNode = this.parent; + + while (currentNode) { + if (!currentNode.expanded) { + currentNode.expand(); + } + + currentNode = currentNode.parent; + } + } + /** + * Add a new child to the node. + * Only applicable when Node value is of type array or object + * @param {Node} node + * @param {boolean} [visible] If true (default), the child will be rendered + * @param {boolean} [updateDom] If true (default), the DOM of both parent + * node and appended node will be updated + * (child count, indexes) + */ + + }, { + key: "appendChild", + value: function appendChild(node, visible, updateDom) { + if (this._hasChilds()) { + // adjust the link to the parent + node.setParent(this); + node.fieldEditable = this.type === 'object'; + + if (this.type === 'array') { + node.index = this.childs.length; + } + + if (this.type === 'object' && node.field === undefined) { + // initialize field value if needed + node.setField(''); + } + + this.childs.push(node); + + if (this.expanded && visible !== false) { + // insert into the DOM, before the appendRow + var newTr = node.getDom(); + + var nextTr = this._getNextTr(); + + var table = nextTr ? nextTr.parentNode : undefined; + + if (nextTr && table) { + table.insertBefore(newTr, nextTr); + } + + node.showChilds(); + this.visibleChilds++; + } + + if (updateDom !== false) { + this.updateDom({ + updateIndexes: true + }); + node.updateDom({ + recurse: true + }); + } + } + } + /** + * Move a node from its current parent to this node + * Only applicable when Node value is of type array or object + * @param {Node} node + * @param {Node} beforeNode + * @param {boolean} [updateDom] If true (default), the DOM of both parent + * node and appended node will be updated + * (child count, indexes) + */ + + }, { + key: "moveBefore", + value: function moveBefore(node, beforeNode, updateDom) { + if (this._hasChilds()) { + // create a temporary row, to prevent the scroll position from jumping + // when removing the node + var tbody = this.dom.tr ? this.dom.tr.parentNode : undefined; + var trTemp; + + if (tbody) { + trTemp = document.createElement('tr'); + trTemp.style.height = tbody.clientHeight + 'px'; + tbody.appendChild(trTemp); + } + + if (node.parent) { + node.parent.removeChild(node); + } + + if (beforeNode instanceof AppendNode || !beforeNode) { + // the this.childs.length + 1 is to reckon with the node that we're about to add + if (this.childs.length + 1 > this.visibleChilds) { + var lastVisibleNode = this.childs[this.visibleChilds - 1]; + this.insertBefore(node, lastVisibleNode, updateDom); + } else { + var visible = true; + this.appendChild(node, visible, updateDom); + } + } else { + this.insertBefore(node, beforeNode, updateDom); + } + + if (tbody && trTemp) { + tbody.removeChild(trTemp); + } + } + } + /** + * Insert a new child before a given node + * Only applicable when Node value is of type array or object + * @param {Node} node + * @param {Node} beforeNode + * @param {boolean} [updateDom] If true (default), the DOM of both parent + * node and appended node will be updated + * (child count, indexes) + */ + + }, { + key: "insertBefore", + value: function insertBefore(node, beforeNode, updateDom) { + if (this._hasChilds()) { + this.visibleChilds++; // initialize field value if needed + + if (this.type === 'object' && node.field === undefined) { + node.setField(''); + } + + if (beforeNode === this.append) { + // append to the child nodes + // adjust the link to the parent + node.setParent(this); + node.fieldEditable = this.type === 'object'; + this.childs.push(node); + } else { + // insert before a child node + var index = this.childs.indexOf(beforeNode); + + if (index === -1) { + throw new Error('Node not found'); + } // adjust the link to the parent + + + node.setParent(this); + node.fieldEditable = this.type === 'object'; + this.childs.splice(index, 0, node); + } + + if (this.expanded) { + // insert into the DOM + var newTr = node.getDom(); + var nextTr = beforeNode.getDom(); + var table = nextTr ? nextTr.parentNode : undefined; + + if (nextTr && table) { + table.insertBefore(newTr, nextTr); + } + + node.showChilds(); + this.showChilds(); + } + + if (updateDom !== false) { + this.updateDom({ + updateIndexes: true + }); + node.updateDom({ + recurse: true + }); + } + } + } + /** + * Insert a new child before a given node + * Only applicable when Node value is of type array or object + * @param {Node} node + * @param {Node} afterNode + */ + + }, { + key: "insertAfter", + value: function insertAfter(node, afterNode) { + if (this._hasChilds()) { + var index = this.childs.indexOf(afterNode); + var beforeNode = this.childs[index + 1]; + + if (beforeNode) { + this.insertBefore(node, beforeNode); + } else { + this.appendChild(node); + } + } + } + /** + * Search in this node + * Searches are case insensitive. + * @param {String} text + * @param {Node[]} [results] Array where search results will be added + * used to count and limit the results whilst iterating + * @return {Node[]} results Array with nodes containing the search text + */ + + }, { + key: "search", + value: function search(text, results) { + if (!Array.isArray(results)) { + results = []; + } + + var index; + var search = text ? text.toLowerCase() : undefined; // delete old search data + + delete this.searchField; + delete this.searchValue; // search in field + + if (this.field !== undefined && results.length <= this.MAX_SEARCH_RESULTS) { + var field = String(this.field).toLowerCase(); + index = field.indexOf(search); + + if (index !== -1) { + this.searchField = true; + results.push({ + node: this, + elem: 'field' + }); + } // update dom + + + this._updateDomField(); + } // search in value + + + if (this._hasChilds()) { + // array, object + // search the nodes childs + if (this.childs) { + this.childs.forEach(function (child) { + child.search(text, results); + }); + } + } else { + // string, auto + if (this.value !== undefined && results.length <= this.MAX_SEARCH_RESULTS) { + var value = String(this.value).toLowerCase(); + index = value.indexOf(search); + + if (index !== -1) { + this.searchValue = true; + results.push({ + node: this, + elem: 'value' + }); + } // update dom + + + this._updateDomValue(); + } + } + + return results; + } + /** + * Move the scroll position such that this node is in the visible area. + * The node will not get the focus + * @param {function(boolean)} [callback] + */ + + }, { + key: "scrollTo", + value: function scrollTo(callback) { + this.expandPathToNode(); + + if (this.dom.tr && this.dom.tr.parentNode) { + this.editor.scrollTo(this.dom.tr.offsetTop, callback); + } + } + /** + * if the node is not visible, expand its parents + */ + + }, { + key: "expandPathToNode", + value: function expandPathToNode() { + var node = this; + var recurse = false; + + while (node && node.parent) { + // expand visible childs of the parent if needed + var index = node.parent.type === 'array' ? node.index : node.parent.childs.indexOf(node); + + while (node.parent.visibleChilds < index + 1) { + node.parent.visibleChilds += this.getMaxVisibleChilds(); + } // expand the parent itself + + + node.parent.expand(recurse); + node = node.parent; + } + } + /** + * Set focus to this node + * @param {String} [elementName] The field name of the element to get the + * focus available values: 'drag', 'menu', + * 'expand', 'field', 'value' (default) + */ + + }, { + key: "focus", + value: function focus(elementName) { + Node.focusElement = elementName; + + if (this.dom.tr && this.dom.tr.parentNode) { + var dom = this.dom; + + switch (elementName) { + case 'drag': + if (dom.drag) { + dom.drag.focus(); + } else { + dom.menu.focus(); + } + + break; + + case 'menu': + dom.menu.focus(); + break; + + case 'expand': + if (this._hasChilds()) { + dom.expand.focus(); + } else if (dom.field && this.fieldEditable) { + dom.field.focus(); + (0,util.selectContentEditable)(dom.field); + } else if (dom.value && !this._hasChilds()) { + dom.value.focus(); + (0,util.selectContentEditable)(dom.value); + } else { + dom.menu.focus(); + } + + break; + + case 'field': + if (dom.field && this.fieldEditable) { + dom.field.focus(); + (0,util.selectContentEditable)(dom.field); + } else if (dom.value && !this._hasChilds()) { + dom.value.focus(); + (0,util.selectContentEditable)(dom.value); + } else if (this._hasChilds()) { + dom.expand.focus(); + } else { + dom.menu.focus(); + } + + break; + + case 'value': + default: + if (dom.select) { + // enum select box + dom.select.focus(); + } else if (dom.value && !this._hasChilds()) { + dom.value.focus(); + (0,util.selectContentEditable)(dom.value); + } else if (dom.field && this.fieldEditable) { + dom.field.focus(); + (0,util.selectContentEditable)(dom.field); + } else if (this._hasChilds()) { + dom.expand.focus(); + } else { + dom.menu.focus(); + } + + break; + } + } + } + /** + * Check if given node is a child. The method will check recursively to find + * this node. + * @param {Node} node + * @return {boolean} containsNode + */ + + }, { + key: "containsNode", + value: function containsNode(node) { + if (this === node) { + return true; + } + + var childs = this.childs; + + if (childs) { + // TODO: use the js5 Array.some() here? + for (var i = 0, iMax = childs.length; i < iMax; i++) { + if (childs[i].containsNode(node)) { + return true; + } + } + } + + return false; + } + /** + * Remove a child from the node. + * Only applicable when Node value is of type array or object + * @param {Node} node The child node to be removed; + * @param {boolean} [updateDom] If true (default), the DOM of the parent + * node will be updated (like child count) + * @return {Node | undefined} node The removed node on success, + * else undefined + */ + + }, { + key: "removeChild", + value: function removeChild(node, updateDom) { + if (this.childs) { + var index = this.childs.indexOf(node); + + if (index !== -1) { + if (index < this.visibleChilds && this.expanded) { + this.visibleChilds--; + } + + node.hide(); // delete old search results + + delete node.searchField; + delete node.searchValue; + var removedNode = this.childs.splice(index, 1)[0]; + removedNode.parent = null; + + if (updateDom !== false) { + this.updateDom({ + updateIndexes: true + }); + } + + return removedNode; + } + } + + return undefined; + } + /** + * Remove a child node node from this node + * This method is equal to Node.removeChild, except that _remove fire an + * onChange event. + * @param {Node} node + * @private + */ + + }, { + key: "_remove", + value: function _remove(node) { + this.removeChild(node); + } + /** + * Change the type of the value of this Node + * @param {String} newType + */ + + }, { + key: "changeType", + value: function changeType(newType) { + var oldType = this.type; + + if (oldType === newType) { + // type is not changed + return; + } + + if ((newType === 'string' || newType === 'auto') && (oldType === 'string' || oldType === 'auto')) { + // this is an easy change + this.type = newType; + } else { + // change from array to object, or from string/auto to object/array + var domAnchor = this._detachFromDom(); // delete the old DOM + + + this.clearDom(); // adjust the field and the value + + this.type = newType; // adjust childs + + if (newType === 'object') { + if (!this.childs) { + this.childs = []; + } + + this.childs.forEach(function (child) { + child.clearDom(); + delete child.index; + child.fieldEditable = true; + + if (child.field === undefined) { + child.field = ''; + } + }); + + if (oldType === 'string' || oldType === 'auto') { + this.expanded = true; + } + } else if (newType === 'array') { + if (!this.childs) { + this.childs = []; + } + + this.childs.forEach(function (child, index) { + child.clearDom(); + child.fieldEditable = false; + child.index = index; + }); + + if (oldType === 'string' || oldType === 'auto') { + this.expanded = true; + } + } else { + this.expanded = false; + } + + this._attachToDom(domAnchor); + } + + if (newType === 'auto' || newType === 'string') { + // cast value to the correct type + if (newType === 'string') { + this.value = String(this.value); + } else { + this.value = (0,util.parseString)(String(this.value)); + } + + this.focus(); + } + + this.updateDom({ + updateIndexes: true + }); + } + /** + * Test whether the JSON contents of this node are deep equal to provided JSON object. + * @param {*} json + */ + + }, { + key: "deepEqual", + value: function deepEqual(json) { + var i; + + if (this.type === 'array') { + if (!Array.isArray(json)) { + return false; + } + + if (this.childs.length !== json.length) { + return false; + } + + for (i = 0; i < this.childs.length; i++) { + if (!this.childs[i].deepEqual(json[i])) { + return false; + } + } + } else if (this.type === 'object') { + if (_typeof(json) !== 'object' || !json) { + return false; + } // we reckon with the order of the properties too. + + + var props = Object.keys(json); + + if (this.childs.length !== props.length) { + return false; + } + + for (i = 0; i < props.length; i++) { + var child = this.childs[i]; + + if (child.field !== props[i] || !child.deepEqual(json[child.field])) { + return false; + } + } + } else { + if (this.value !== json) { + return false; + } + } + + return true; + } + /** + * Retrieve value from DOM + * @private + */ + + }, { + key: "_getDomValue", + value: function _getDomValue() { + this._clearValueError(); + + if (this.dom.value && this.type !== 'array' && this.type !== 'object') { + this.valueInnerText = (0,util.getInnerText)(this.dom.value); + + if (this.valueInnerText === '' && this.dom.value.innerHTML !== '') { + // When clearing the contents, often a
    remains, messing up the + // styling of the empty text box. Therefore we remove the
    + this.dom.value.textContent = ''; + } + } + + if (this.valueInnerText !== undefined) { + try { + // retrieve the value + var value; + + if (this.type === 'string') { + value = this._unescapeHTML(this.valueInnerText); + } else { + var str = this._unescapeHTML(this.valueInnerText); + + value = (0,util.parseString)(str); + } + + if (value !== this.value) { + this.value = value; + + this._debouncedOnChangeValue(); + } + } catch (err) { + // keep the previous value + this._setValueError((0,i18n/* translate */.Iu)('cannotParseValueError')); + } + } + } + /** + * Show a local error in case of invalid value + * @param {string} message + * @private + */ + + }, { + key: "_setValueError", + value: function _setValueError(message) { + this.valueError = { + message: message + }; + this.updateError(); + } + }, { + key: "_clearValueError", + value: function _clearValueError() { + if (this.valueError) { + this.valueError = null; + this.updateError(); + } + } + /** + * Show a local error in case of invalid or duplicate field + * @param {string} message + * @private + */ + + }, { + key: "_setFieldError", + value: function _setFieldError(message) { + this.fieldError = { + message: message + }; + this.updateError(); + } + }, { + key: "_clearFieldError", + value: function _clearFieldError() { + if (this.fieldError) { + this.fieldError = null; + this.updateError(); + } + } + /** + * Handle a changed value + * @private + */ + + }, { + key: "_onChangeValue", + value: function _onChangeValue() { + // get current selection, then override the range such that we can select + // the added/removed text on undo/redo + var oldSelection = this.editor.getDomSelection(); + + if (oldSelection.range) { + var undoDiff = (0,util.textDiff)(String(this.value), String(this.previousValue)); + oldSelection.range.startOffset = undoDiff.start; + oldSelection.range.endOffset = undoDiff.end; + } + + var newSelection = this.editor.getDomSelection(); + + if (newSelection.range) { + var redoDiff = (0,util.textDiff)(String(this.previousValue), String(this.value)); + newSelection.range.startOffset = redoDiff.start; + newSelection.range.endOffset = redoDiff.end; + } + + this.editor._onAction('editValue', { + path: this.getInternalPath(), + oldValue: this.previousValue, + newValue: this.value, + oldSelection: oldSelection, + newSelection: newSelection + }); + + this.previousValue = this.value; + } + /** + * Handle a changed field + * @private + */ + + }, { + key: "_onChangeField", + value: function _onChangeField() { + // get current selection, then override the range such that we can select + // the added/removed text on undo/redo + var oldSelection = this.editor.getDomSelection(); + var previous = this.previousField || ''; + + if (oldSelection.range) { + var undoDiff = (0,util.textDiff)(this.field, previous); + oldSelection.range.startOffset = undoDiff.start; + oldSelection.range.endOffset = undoDiff.end; + } + + var newSelection = this.editor.getDomSelection(); + + if (newSelection.range) { + var redoDiff = (0,util.textDiff)(previous, this.field); + newSelection.range.startOffset = redoDiff.start; + newSelection.range.endOffset = redoDiff.end; + } + + this.editor._onAction('editField', { + parentPath: this.parent.getInternalPath(), + index: this.getIndex(), + oldValue: this.previousField, + newValue: this.field, + oldSelection: oldSelection, + newSelection: newSelection + }); + + this.previousField = this.field; + } + /** + * Update dom value: + * - the text color of the value, depending on the type of the value + * - the height of the field, depending on the width + * - background color in case it is empty + * @private + */ + + }, { + key: "_updateDomValue", + value: function _updateDomValue() { + var domValue = this.dom.value; + + if (domValue) { + var classNames = ['jsoneditor-value']; // set text color depending on value type + + var value = this.value; + var valueType = this.type === 'auto' ? (0,util.getType)(value) : this.type; + var valueIsUrl = valueType === 'string' && (0,util.isUrl)(value); + classNames.push('jsoneditor-' + valueType); + + if (valueIsUrl) { + classNames.push('jsoneditor-url'); + } // visual styling when empty + + + var isEmpty = String(this.value) === '' && this.type !== 'array' && this.type !== 'object'; + + if (isEmpty) { + classNames.push('jsoneditor-empty'); + } // highlight when there is a search result + + + if (this.searchValueActive) { + classNames.push('jsoneditor-highlight-active'); + } + + if (this.searchValue) { + classNames.push('jsoneditor-highlight'); + } + + domValue.className = classNames.join(' '); // update title + + if (valueType === 'array' || valueType === 'object') { + var count = this.childs ? this.childs.length : 0; + domValue.title = this.type + ' containing ' + count + ' items'; + } else if (valueIsUrl && this.editable.value) { + domValue.title = (0,i18n/* translate */.Iu)('openUrl'); + } else { + domValue.title = ''; + } // show checkbox when the value is a boolean + + + if (valueType === 'boolean' && this.editable.value) { + if (!this.dom.checkbox) { + this.dom.checkbox = document.createElement('input'); + this.dom.checkbox.type = 'checkbox'; + this.dom.tdCheckbox = document.createElement('td'); + this.dom.tdCheckbox.className = 'jsoneditor-tree'; + this.dom.tdCheckbox.appendChild(this.dom.checkbox); + this.dom.tdValue.parentNode.insertBefore(this.dom.tdCheckbox, this.dom.tdValue); + } + + this.dom.checkbox.checked = this.value; + } else { + // cleanup checkbox when displayed + if (this.dom.tdCheckbox) { + this.dom.tdCheckbox.parentNode.removeChild(this.dom.tdCheckbox); + delete this.dom.tdCheckbox; + delete this.dom.checkbox; + } + } // create select box when this node has an enum object + + + if (this["enum"] && this.editable.value) { + if (!this.dom.select) { + this.dom.select = document.createElement('select'); + this.id = this.field + '_' + new Date().getUTCMilliseconds(); + this.dom.select.id = this.id; + this.dom.select.name = this.dom.select.id; // Create the default empty option + + var defaultOption = document.createElement('option'); + defaultOption.value = ''; + defaultOption.textContent = '--'; + this.dom.select.appendChild(defaultOption); // Iterate all enum values and add them as options + + for (var i = 0; i < this["enum"].length; i++) { + var option = document.createElement('option'); + option.value = this["enum"][i]; + option.textContent = this["enum"][i]; + this.dom.select.appendChild(option); + } + + this.dom.tdSelect = document.createElement('td'); + this.dom.tdSelect.className = 'jsoneditor-tree'; + this.dom.tdSelect.appendChild(this.dom.select); + this.dom.tdValue.parentNode.insertBefore(this.dom.tdSelect, this.dom.tdValue); + } // Select the matching value + + + this.dom.select.value = this["enum"].indexOf(this.value) !== -1 ? this.value : ''; // default + // If the enum is inside a composite type display + // both the simple input and the dropdown field + + if (this.schema && !Node_hasOwnProperty(this.schema, 'oneOf') && !Node_hasOwnProperty(this.schema, 'anyOf') && !Node_hasOwnProperty(this.schema, 'allOf')) { + this.valueFieldHTML = this.dom.tdValue.innerHTML; + this.dom.tdValue.style.visibility = 'hidden'; + this.dom.tdValue.textContent = ''; + } else { + delete this.valueFieldHTML; + } + } else { + // cleanup select box when displayed + if (this.dom.tdSelect) { + this.dom.tdSelect.parentNode.removeChild(this.dom.tdSelect); + delete this.dom.tdSelect; + delete this.dom.select; + this.dom.tdValue.innerHTML = this.valueFieldHTML; + this.dom.tdValue.style.visibility = ''; + delete this.valueFieldHTML; + } + } // show color picker when value is a color + + + if (this.editable.value && this.editor.options.colorPicker && typeof value === 'string' && (0,util.isValidColor)(value)) { + if (!this.dom.color) { + this.dom.color = document.createElement('div'); + this.dom.color.className = 'jsoneditor-color'; + this.dom.tdColor = document.createElement('td'); + this.dom.tdColor.className = 'jsoneditor-tree'; + this.dom.tdColor.appendChild(this.dom.color); + this.dom.tdValue.parentNode.insertBefore(this.dom.tdColor, this.dom.tdValue); + } // update styling of value and color background + + + (0,util.addClassName)(this.dom.value, 'jsoneditor-color-value'); + this.dom.color.style.backgroundColor = value; + } else { + // cleanup color picker when displayed + this._deleteDomColor(); + } // show date tag when value is a timestamp in milliseconds + + + if (this._showTimestampTag()) { + if (!this.dom.date) { + this.dom.date = document.createElement('div'); + this.dom.date.className = 'jsoneditor-date'; + this.dom.value.parentNode.appendChild(this.dom.date); + } + + var title = null; + + if (typeof this.editor.options.timestampFormat === 'function') { + title = this.editor.options.timestampFormat({ + field: this.field, + value: this.value, + path: this.getPath() + }); + } + + if (!title) { + this.dom.date.textContent = new Date(value).toISOString(); + } else { + while (this.dom.date.firstChild) { + this.dom.date.removeChild(this.dom.date.firstChild); + } + + this.dom.date.appendChild(document.createTextNode(title)); + } + + this.dom.date.title = new Date(value).toString(); + } else { + // cleanup date tag + if (this.dom.date) { + this.dom.date.parentNode.removeChild(this.dom.date); + delete this.dom.date; + } + } // strip formatting from the contents of the editable div + + + (0,util.stripFormatting)(domValue); + + this._updateDomDefault(); + } + } + }, { + key: "_deleteDomColor", + value: function _deleteDomColor() { + if (this.dom.color) { + this.dom.tdColor.parentNode.removeChild(this.dom.tdColor); + delete this.dom.tdColor; + delete this.dom.color; + (0,util.removeClassName)(this.dom.value, 'jsoneditor-color-value'); + } + } + /** + * Update dom field: + * - the text color of the field, depending on the text + * - the height of the field, depending on the width + * - background color in case it is empty + * @private + */ + + }, { + key: "_updateDomField", + value: function _updateDomField() { + var domField = this.dom.field; + + if (domField) { + var tooltip = (0,util.makeFieldTooltip)(this.schema, this.editor.options.language); + + if (tooltip) { + domField.title = tooltip; + } // make background color lightgray when empty + + + var isEmpty = String(this.field) === '' && this.parent && this.parent.type !== 'array'; + + if (isEmpty) { + (0,util.addClassName)(domField, 'jsoneditor-empty'); + } else { + (0,util.removeClassName)(domField, 'jsoneditor-empty'); + } // highlight when there is a search result + + + if (this.searchFieldActive) { + (0,util.addClassName)(domField, 'jsoneditor-highlight-active'); + } else { + (0,util.removeClassName)(domField, 'jsoneditor-highlight-active'); + } + + if (this.searchField) { + (0,util.addClassName)(domField, 'jsoneditor-highlight'); + } else { + (0,util.removeClassName)(domField, 'jsoneditor-highlight'); + } // strip formatting from the contents of the editable div + + + (0,util.stripFormatting)(domField); + } + } + /** + * Retrieve field from DOM + * @param {boolean} [forceUnique] If true, the field name will be changed + * into a unique name in case it is a duplicate. + * @private + */ + + }, { + key: "_getDomField", + value: function _getDomField(forceUnique) { + this._clearFieldError(); + + if (this.dom.field && this.fieldEditable) { + this.fieldInnerText = (0,util.getInnerText)(this.dom.field); + + if (this.fieldInnerText === '' && this.dom.field.innerHTML !== '') { + // When clearing the contents, often a
    remains, messing up the + // styling of the empty text box. Therefore we remove the
    + this.dom.field.textContent = ''; + } + } + + if (this.fieldInnerText !== undefined) { + try { + var field = this._unescapeHTML(this.fieldInnerText); + + var existingFieldNames = this.parent.getFieldNames(this); + var isDuplicate = existingFieldNames.indexOf(field) !== -1; + + if (!isDuplicate) { + if (field !== this.field) { + this.field = field; + + this._debouncedOnChangeField(); + } + } else { + if (forceUnique) { + // fix duplicate field: change it into a unique name + field = (0,util.findUniqueName)(field, existingFieldNames); + + if (field !== this.field) { + this.field = field; // TODO: don't debounce but resolve right away, and cancel current debounce + + this._debouncedOnChangeField(); + } + } else { + this._setFieldError((0,i18n/* translate */.Iu)('duplicateFieldError')); + } + } + } catch (err) { + // keep the previous field value + this._setFieldError((0,i18n/* translate */.Iu)('cannotParseFieldError')); + } + } + } + /** + * Update the value of the schema default element in the DOM. + * @private + * @returns {undefined} + */ + + }, { + key: "_updateDomDefault", + value: function _updateDomDefault() { + // Short-circuit if schema is missing, has no default, or if Node has children + if (!this.schema || this.schema["default"] === undefined || this._hasChilds()) { + return; + } // select either enum dropdown (select) or input value + + + var inputElement = this.dom.select ? this.dom.select : this.dom.value; + + if (!inputElement) { + return; + } + + if (this.value === this.schema["default"]) { + inputElement.title = (0,i18n/* translate */.Iu)('default'); + (0,util.addClassName)(inputElement, 'jsoneditor-is-default'); + (0,util.removeClassName)(inputElement, 'jsoneditor-is-not-default'); + } else { + inputElement.removeAttribute('title'); + (0,util.removeClassName)(inputElement, 'jsoneditor-is-default'); + (0,util.addClassName)(inputElement, 'jsoneditor-is-not-default'); + } + } + /** + * Test whether to show a timestamp tag or not + * @return {boolean} Returns true when the value is a timestamp + */ + + }, { + key: "_showTimestampTag", + value: function _showTimestampTag() { + if (typeof this.value !== 'number') { + return false; + } + + var timestampTag = this.editor.options.timestampTag; + + if (typeof timestampTag === 'function') { + var result = timestampTag({ + field: this.field, + value: this.value, + path: this.getPath() + }); + + if (typeof result === 'boolean') { + return result; + } else { + return (0,util.isTimestamp)(this.field, this.value); + } + } else if (timestampTag === true) { + return (0,util.isTimestamp)(this.field, this.value); + } else { + return false; + } + } + /** + * Clear the dom of the node + */ + + }, { + key: "clearDom", + value: function clearDom() { + // TODO: hide the node first? + // this.hide(); + // TODO: recursively clear dom? + this.dom = {}; + } + /** + * Get the HTML DOM TR element of the node. + * The dom will be generated when not yet created + * @return {Element} tr HTML DOM TR Element + */ + + }, { + key: "getDom", + value: function getDom() { + var dom = this.dom; + + if (dom.tr) { + return dom.tr; + } + + this._updateEditability(); // create row + + + dom.tr = document.createElement('tr'); + dom.tr.node = this; + + if (this.editor.options.mode === 'tree') { + // note: we take here the global setting + var tdDrag = document.createElement('td'); + + if (this.editable.field) { + // create draggable area + if (this.parent) { + var domDrag = document.createElement('button'); + domDrag.type = 'button'; + dom.drag = domDrag; + domDrag.className = 'jsoneditor-button jsoneditor-dragarea'; + domDrag.title = (0,i18n/* translate */.Iu)('drag'); + tdDrag.appendChild(domDrag); + } + } + + dom.tr.appendChild(tdDrag); // create context menu + + var tdMenu = document.createElement('td'); + var menu = document.createElement('button'); + menu.type = 'button'; + dom.menu = menu; + menu.className = 'jsoneditor-button jsoneditor-contextmenu-button'; + menu.title = (0,i18n/* translate */.Iu)('actionsMenu'); + tdMenu.appendChild(dom.menu); + dom.tr.appendChild(tdMenu); + } // create tree and field + + + var tdField = document.createElement('td'); + dom.tr.appendChild(tdField); + dom.tree = this._createDomTree(); + tdField.appendChild(dom.tree); + this.updateDom({ + updateIndexes: true + }); + return dom.tr; + } + /** + * Test whether a Node is rendered and visible + * @returns {boolean} + */ + + }, { + key: "isVisible", + value: function isVisible() { + return this.dom && this.dom.tr && this.dom.tr.parentNode || false; + } + /** + * Test if this node is a sescendant of an other node + * @param {Node} node + * @return {boolean} isDescendant + * @private + */ + + }, { + key: "isDescendantOf", + value: function isDescendantOf(node) { + var n = this.parent; + + while (n) { + if (n === node) { + return true; + } + + n = n.parent; + } + + return false; + } + /** + * Create an editable field + * @return {Element} domField + * @private + */ + + }, { + key: "_createDomField", + value: function _createDomField() { + return document.createElement('div'); + } + /** + * Set highlighting for this node and all its childs. + * Only applied to the currently visible (expanded childs) + * @param {boolean} highlight + */ + + }, { + key: "setHighlight", + value: function setHighlight(highlight) { + if (this.dom.tr) { + if (highlight) { + (0,util.addClassName)(this.dom.tr, 'jsoneditor-highlight'); + } else { + (0,util.removeClassName)(this.dom.tr, 'jsoneditor-highlight'); + } + + if (this.append) { + this.append.setHighlight(highlight); + } + + if (this.childs) { + this.childs.forEach(function (child) { + child.setHighlight(highlight); + }); + } + } + } + /** + * Select or deselect a node + * @param {boolean} selected + * @param {boolean} [isFirst] + */ + + }, { + key: "setSelected", + value: function setSelected(selected, isFirst) { + this.selected = selected; + + if (this.dom.tr) { + if (selected) { + (0,util.addClassName)(this.dom.tr, 'jsoneditor-selected'); + } else { + (0,util.removeClassName)(this.dom.tr, 'jsoneditor-selected'); + } + + if (isFirst) { + (0,util.addClassName)(this.dom.tr, 'jsoneditor-first'); + } else { + (0,util.removeClassName)(this.dom.tr, 'jsoneditor-first'); + } + + if (this.append) { + this.append.setSelected(selected); + } + + if (this.showMore) { + this.showMore.setSelected(selected); + } + + if (this.childs) { + this.childs.forEach(function (child) { + child.setSelected(selected); + }); + } + } + } + /** + * Update the value of the node. Only primitive types are allowed, no Object + * or Array is allowed. + * @param {String | Number | Boolean | null} value + */ + + }, { + key: "updateValue", + value: function updateValue(value) { + this.value = value; + this.previousValue = value; + this.valueError = undefined; + this.updateDom(); + } + /** + * Update the field of the node. + * @param {String} field + */ + + }, { + key: "updateField", + value: function updateField(field) { + this.field = field; + this.previousField = field; + this.fieldError = undefined; + this.updateDom(); + } + /** + * Update the HTML DOM, optionally recursing through the childs + * @param {Object} [options] Available parameters: + * {boolean} [recurse] If true, the + * DOM of the childs will be updated recursively. + * False by default. + * {boolean} [updateIndexes] If true, the childs + * indexes of the node will be updated too. False by + * default. + */ + + }, { + key: "updateDom", + value: function updateDom(options) { + // update level indentation + var domTree = this.dom.tree; + + if (domTree) { + domTree.style.marginLeft = this.getLevel() * 24 + 'px'; + } // apply field to DOM + + + var domField = this.dom.field; + + if (domField) { + if (this.fieldEditable) { + // parent is an object + domField.contentEditable = this.editable.field; + domField.spellcheck = false; + domField.className = 'jsoneditor-field'; + } else { + // parent is an array this is the root node + domField.contentEditable = false; + domField.className = 'jsoneditor-readonly'; + } + + var fieldText; + + if (this.index !== undefined) { + fieldText = this.index; + } else if (this.field !== undefined) { + fieldText = this.field; + } else { + var schema = this.editor.options.schema ? Node._findSchema(this.editor.options.schema, this.editor.options.schemaRefs || {}, this.getPath()) : undefined; + + if (schema && schema.title) { + fieldText = schema.title; + } else if (this._hasChilds()) { + fieldText = this.type; + } else { + fieldText = ''; + } + } + + var escapedField = this._escapeHTML(fieldText); + + if (document.activeElement !== domField || escapedField !== this._unescapeHTML((0,util.getInnerText)(domField))) { + // only update if it not has the focus or when there is an actual change, + // else you would needlessly loose the caret position when changing tabs + // or whilst typing + domField.innerHTML = escapedField; + } + + this._updateSchema(); + } // apply value to DOM + + + var domValue = this.dom.value; + + if (domValue) { + if (this.type === 'array' || this.type === 'object') { + this.updateNodeName(); + } else { + var escapedValue = this._escapeHTML(this.value); + + if (document.activeElement !== domValue || escapedValue !== this._unescapeHTML((0,util.getInnerText)(domValue))) { + // only update if it not has the focus or when there is an actual change, + // else you would needlessly loose the caret position when changing tabs + // or whilst typing + domValue.innerHTML = escapedValue; + } + } + } // apply styling to the table row + + + var tr = this.dom.tr; + + if (tr) { + if (this.type === 'array' || this.type === 'object') { + (0,util.addClassName)(tr, 'jsoneditor-expandable'); + + if (this.expanded) { + (0,util.addClassName)(tr, 'jsoneditor-expanded'); + (0,util.removeClassName)(tr, 'jsoneditor-collapsed'); + } else { + (0,util.addClassName)(tr, 'jsoneditor-collapsed'); + (0,util.removeClassName)(tr, 'jsoneditor-expanded'); + } + } else { + (0,util.removeClassName)(tr, 'jsoneditor-expandable'); + (0,util.removeClassName)(tr, 'jsoneditor-expanded'); + (0,util.removeClassName)(tr, 'jsoneditor-collapsed'); + } + } // update field and value + + + this._updateDomField(); + + this._updateDomValue(); // update childs indexes + + + if (options && options.updateIndexes === true) { + // updateIndexes is true or undefined + this._updateDomIndexes(); + } // update childs recursively + + + if (options && options.recurse === true) { + if (this.childs) { + this.childs.forEach(function (child) { + child.updateDom(options); + }); + } + } // update rendering of error + + + if (this.error) { + this.updateError(); + } // update row with append button + + + if (this.append) { + this.append.updateDom(); + } // update "show more" text at the bottom of large arrays + + + if (this.showMore) { + this.showMore.updateDom(); + } // fire onClassName + + + this._updateCssClassName(); + } + /** + * Locate the JSON schema of the node and check for any enum type + * @private + */ + + }, { + key: "_updateSchema", + value: function _updateSchema() { + // Locating the schema of the node and checking for any enum type + if (this.editor && this.editor.options) { + // find the part of the json schema matching this nodes path + this.schema = this.editor.options.schema // fix childSchema with $ref, and not display the select element on the child schema because of not found enum + ? Node._findSchema(this.editor.options.schema, this.editor.options.schemaRefs || {}, this.getPath()) : null; + + if (this.schema) { + this["enum"] = Node._findEnum(this.schema); + } else { + delete this["enum"]; + } + } + } + /** + * Update the DOM of the childs of a node: update indexes and undefined field + * names. + * Only applicable when structure is an array or object + * @private + */ + + }, { + key: "_updateDomIndexes", + value: function _updateDomIndexes() { + var domValue = this.dom.value; + var childs = this.childs; + + if (domValue && childs) { + if (this.type === 'array') { + childs.forEach(function (child, index) { + child.index = index; + var childField = child.dom.field; + + if (childField) { + childField.textContent = index; + } + }); + } else if (this.type === 'object') { + childs.forEach(function (child) { + if (child.index !== undefined) { + delete child.index; + + if (child.field === undefined) { + child.field = ''; + } + } + }); + } + } + } + /** + * Create an editable value + * @private + */ + + }, { + key: "_createDomValue", + value: function _createDomValue() { + var domValue; + + if (this.type === 'array') { + domValue = document.createElement('div'); + domValue.textContent = '[...]'; + } else if (this.type === 'object') { + domValue = document.createElement('div'); + domValue.textContent = '{...}'; + } else { + if (!this.editable.value && (0,util.isUrl)(this.value)) { + // create a link in case of read-only editor and value containing an url + domValue = document.createElement('a'); + domValue.href = this.value; + domValue.target = "_blank"; + domValue.innerHTML = this._escapeHTML(this.value); + } else { + // create an editable or read-only div + domValue = document.createElement('div'); + domValue.contentEditable = this.editable.value; + domValue.spellcheck = false; + domValue.innerHTML = this._escapeHTML(this.value); + } + } + + return domValue; + } + /** + * Create an expand/collapse button + * @return {Element} expand + * @private + */ + + }, { + key: "_createDomExpandButton", + value: function _createDomExpandButton() { + // create expand button + var expand = document.createElement('button'); + expand.type = 'button'; + + if (this._hasChilds()) { + expand.className = this.expanded ? 'jsoneditor-button jsoneditor-expanded' : 'jsoneditor-button jsoneditor-collapsed'; + expand.title = (0,i18n/* translate */.Iu)('expandTitle'); + } else { + expand.className = 'jsoneditor-button jsoneditor-invisible'; + expand.title = ''; + } + + return expand; + } + /** + * Create a DOM tree element, containing the expand/collapse button + * @return {Element} domTree + * @private + */ + + }, { + key: "_createDomTree", + value: function _createDomTree() { + var dom = this.dom; + var domTree = document.createElement('table'); + var tbody = document.createElement('tbody'); + domTree.style.borderCollapse = 'collapse'; // TODO: put in css + + domTree.className = 'jsoneditor-values'; + domTree.appendChild(tbody); + var tr = document.createElement('tr'); + tbody.appendChild(tr); // create expand button + + var tdExpand = document.createElement('td'); + tdExpand.className = 'jsoneditor-tree'; + tr.appendChild(tdExpand); + dom.expand = this._createDomExpandButton(); + tdExpand.appendChild(dom.expand); + dom.tdExpand = tdExpand; // create the field + + var tdField = document.createElement('td'); + tdField.className = 'jsoneditor-tree'; + tr.appendChild(tdField); + dom.field = this._createDomField(); + tdField.appendChild(dom.field); + dom.tdField = tdField; // create a separator + + var tdSeparator = document.createElement('td'); + tdSeparator.className = 'jsoneditor-tree'; + tr.appendChild(tdSeparator); + + if (this.type !== 'object' && this.type !== 'array') { + tdSeparator.appendChild(document.createTextNode(':')); + tdSeparator.className = 'jsoneditor-separator'; + } + + dom.tdSeparator = tdSeparator; // create the value + + var tdValue = document.createElement('td'); + tdValue.className = 'jsoneditor-tree'; + tr.appendChild(tdValue); + dom.value = this._createDomValue(); + tdValue.appendChild(dom.value); + dom.tdValue = tdValue; + return domTree; + } + /** + * Handle an event. The event is caught centrally by the editor + * @param {Event} event + */ + + }, { + key: "onEvent", + value: function onEvent(event) { + var type = event.type; + var target = event.target || event.srcElement; + var dom = this.dom; + var node = this; + + var expandable = this._hasChilds(); // check if mouse is on menu or on dragarea. + // If so, highlight current row and its childs + + + if (target === dom.drag || target === dom.menu) { + if (type === 'mouseover') { + this.editor.highlighter.highlight(this); + } else if (type === 'mouseout') { + this.editor.highlighter.unhighlight(); + } + } // context menu events + + + if (type === 'click' && target === dom.menu) { + var highlighter = node.editor.highlighter; + highlighter.highlight(node); + highlighter.lock(); + (0,util.addClassName)(dom.menu, 'jsoneditor-selected'); + this.showContextMenu(dom.menu, function () { + (0,util.removeClassName)(dom.menu, 'jsoneditor-selected'); + highlighter.unlock(); + highlighter.unhighlight(); + }); + } // expand events + + + if (type === 'click') { + if (target === dom.expand) { + if (expandable) { + var recurse = event.ctrlKey; // with ctrl-key, expand/collapse all + + this._onExpand(recurse); + } + } + } + + if (type === 'click' && (event.target === node.dom.tdColor || event.target === node.dom.color)) { + this._showColorPicker(); + } // swap the value of a boolean when the checkbox displayed left is clicked + + + if (type === 'change' && target === dom.checkbox) { + this.dom.value.textContent = String(!this.value); + + this._getDomValue(); + + this._updateDomDefault(); + } // update the value of the node based on the selected option + + + if (type === 'change' && target === dom.select) { + this.dom.value.innerHTML = this._escapeHTML(dom.select.value); + + this._getDomValue(); + + this._updateDomValue(); + } // value events + + + var domValue = dom.value; + + if (target === domValue) { + // noinspection FallthroughInSwitchStatementJS + switch (type) { + case 'blur': + case 'change': + { + this._getDomValue(); + + this._clearValueError(); + + this._updateDomValue(); + + var escapedValue = this._escapeHTML(this.value); + + if (escapedValue !== this._unescapeHTML((0,util.getInnerText)(domValue))) { + // only update when there is an actual change, else you loose the + // caret position when changing tabs or whilst typing + domValue.innerHTML = escapedValue; + } + + break; + } + + case 'input': + // this._debouncedGetDomValue(true); // TODO + this._getDomValue(); + + this._updateDomValue(); + + break; + + case 'keydown': + case 'mousedown': + // TODO: cleanup + this.editor.selection = this.editor.getDomSelection(); + break; + + case 'click': + if (event.ctrlKey && this.editable.value) { + // if read-only, we use the regular click behavior of an anchor + if ((0,util.isUrl)(this.value)) { + event.preventDefault(); + window.open(this.value, '_blank', 'noopener'); + } + } + + break; + + case 'keyup': + // this._debouncedGetDomValue(true); // TODO + this._getDomValue(); + + this._updateDomValue(); + + break; + + case 'cut': + case 'paste': + setTimeout(function () { + node._getDomValue(); + + node._updateDomValue(); + }, 1); + break; + } + } // field events + + + var domField = dom.field; + + if (target === domField) { + switch (type) { + case 'blur': + { + this._getDomField(true); + + this._updateDomField(); + + var escapedField = this._escapeHTML(this.field); + + if (escapedField !== this._unescapeHTML((0,util.getInnerText)(domField))) { + // only update when there is an actual change, else you loose the + // caret position when changing tabs or whilst typing + domField.innerHTML = escapedField; + } + + break; + } + + case 'input': + this._getDomField(); + + this._updateSchema(); + + this._updateDomField(); + + this._updateDomValue(); + + break; + + case 'keydown': + case 'mousedown': + this.editor.selection = this.editor.getDomSelection(); + break; + + case 'keyup': + this._getDomField(); + + this._updateDomField(); + + break; + + case 'cut': + case 'paste': + setTimeout(function () { + node._getDomField(); + + node._updateDomField(); + }, 1); + break; + } + } // focus + // when clicked in whitespace left or right from the field or value, set focus + + + var domTree = dom.tree; + + if (domTree && target === domTree.parentNode && type === 'click' && !event.hasMoved) { + var left = event.offsetX !== undefined ? event.offsetX < (this.getLevel() + 1) * 24 : event.pageX < (0,util.getAbsoluteLeft)(dom.tdSeparator); // for FF + + if (left || expandable) { + // node is expandable when it is an object or array + if (domField) { + (0,util.setEndOfContentEditable)(domField); + domField.focus(); + } + } else { + if (domValue && !this["enum"]) { + (0,util.setEndOfContentEditable)(domValue); + domValue.focus(); + } + } + } + + if ((target === dom.tdExpand && !expandable || target === dom.tdField || target === dom.tdSeparator) && type === 'click' && !event.hasMoved) { + if (domField) { + (0,util.setEndOfContentEditable)(domField); + domField.focus(); + } + } + + if (type === 'keydown') { + this.onKeyDown(event); + } // fire after applying for example a change by clicking a checkbox + + + if (typeof this.editor.options.onEvent === 'function') { + this._onEvent(event); + } + } + /** + * Trigger external onEvent provided in options if node is a JSON field or + * value. + * Information provided depends on the element, value is only included if + * event occurs in a JSON value: + * {field: string, path: {string|number}[] [, value: string]} + * @param {Event} event + * @private + */ + + }, { + key: "_onEvent", + value: function _onEvent(event) { + var element = event.target; + var isField = element === this.dom.field; + var isValue = element === this.dom.value || element === this.dom.checkbox || element === this.dom.select; + + if (isField || isValue) { + var info = { + field: this.getField(), + path: this.getPath() + }; // For leaf values, include value + + if (isValue && !this._hasChilds()) { + info.value = this.getValue(); + } + + this.editor.options.onEvent(info, event); + } + } + /** + * Key down event handler + * @param {Event} event + */ + + }, { + key: "onKeyDown", + value: function onKeyDown(event) { + var keynum = event.which || event.keyCode; + var target = event.target || event.srcElement; + var ctrlKey = event.ctrlKey; + var shiftKey = event.shiftKey; + var altKey = event.altKey; + var handled = false; + var prevNode, nextNode, nextDom, nextDom2; + var editable = this.editor.options.mode === 'tree'; + var oldSelection; + var oldNextNode; + var oldParent; + var oldIndexRedo; + var newIndexRedo; + var oldParentPathRedo; + var newParentPathRedo; + var nodes; + var multiselection; + var selectedNodes = this.editor.multiselection.nodes.length > 0 ? this.editor.multiselection.nodes : [this]; + var firstNode = selectedNodes[0]; + var lastNode = selectedNodes[selectedNodes.length - 1]; // console.log(ctrlKey, keynum, event.charCode); // TODO: cleanup + + if (keynum === 13) { + // Enter + if (target === this.dom.value) { + if (!this.editable.value || event.ctrlKey) { + if ((0,util.isUrl)(this.value)) { + window.open(this.value, '_blank', 'noopener'); + handled = true; + } + } + } else if (target === this.dom.expand) { + var expandable = this._hasChilds(); + + if (expandable) { + var recurse = event.ctrlKey; // with ctrl-key, expand/collapse all + + this._onExpand(recurse); + + target.focus(); + handled = true; + } + } + } else if (keynum === 68) { + // D + if (ctrlKey && editable) { + // Ctrl+D + Node.onDuplicate(selectedNodes); + handled = true; + } + } else if (keynum === 69) { + // E + if (ctrlKey) { + // Ctrl+E and Ctrl+Shift+E + this._onExpand(shiftKey); // recurse = shiftKey + + + target.focus(); // TODO: should restore focus in case of recursing expand (which takes DOM offline) + + handled = true; + } + } else if (keynum === 77 && editable) { + // M + if (ctrlKey) { + // Ctrl+M + this.showContextMenu(target); + handled = true; + } + } else if (keynum === 46 && editable) { + // Del + if (ctrlKey) { + // Ctrl+Del + Node.onRemove(selectedNodes); + handled = true; + } + } else if (keynum === 45 && editable) { + // Ins + if (ctrlKey && !shiftKey) { + // Ctrl+Ins + this._onInsertBefore(); + + handled = true; + } else if (ctrlKey && shiftKey) { + // Ctrl+Shift+Ins + this._onInsertAfter(); + + handled = true; + } + } else if (keynum === 35) { + // End + if (altKey) { + // Alt+End + // find the last node + var endNode = this._lastNode(); + + if (endNode) { + endNode.focus(Node.focusElement || this._getElementName(target)); + } + + handled = true; + } + } else if (keynum === 36) { + // Home + if (altKey) { + // Alt+Home + // find the first node + var homeNode = this._firstNode(); + + if (homeNode) { + homeNode.focus(Node.focusElement || this._getElementName(target)); + } + + handled = true; + } + } else if (keynum === 37) { + // Arrow Left + if (altKey && !shiftKey) { + // Alt + Arrow Left + // move to left element + var prevElement = this._previousElement(target); + + if (prevElement) { + this.focus(this._getElementName(prevElement)); + } + + handled = true; + } else if (altKey && shiftKey && editable) { + // Alt + Shift + Arrow left + if (lastNode.expanded) { + var appendDom = lastNode.getAppendDom(); + nextDom = appendDom ? appendDom.nextSibling : undefined; + } else { + var dom = lastNode.getDom(); + nextDom = dom.nextSibling; + } + + if (nextDom) { + nextNode = Node.getNodeFromTarget(nextDom); + nextDom2 = nextDom.nextSibling; + var nextNode2 = Node.getNodeFromTarget(nextDom2); + + if (nextNode && nextNode instanceof AppendNode && !(lastNode.parent.childs.length === 1) && nextNode2 && nextNode2.parent) { + oldSelection = this.editor.getDomSelection(); + oldParent = firstNode.parent; + oldNextNode = oldParent.childs[lastNode.getIndex() + 1] || oldParent.append; + oldIndexRedo = firstNode.getIndex(); + newIndexRedo = nextNode2.getIndex(); + oldParentPathRedo = oldParent.getInternalPath(); + newParentPathRedo = nextNode2.parent.getInternalPath(); + selectedNodes.forEach(function (node) { + nextNode2.parent.moveBefore(node, nextNode2); + }); + this.focus(Node.focusElement || this._getElementName(target)); + + this.editor._onAction('moveNodes', { + count: selectedNodes.length, + fieldNames: selectedNodes.map(getField), + oldParentPath: oldParent.getInternalPath(), + newParentPath: firstNode.parent.getInternalPath(), + oldIndex: oldNextNode.getIndex(), + newIndex: firstNode.getIndex(), + oldIndexRedo: oldIndexRedo, + newIndexRedo: newIndexRedo, + oldParentPathRedo: oldParentPathRedo, + newParentPathRedo: newParentPathRedo, + oldSelection: oldSelection, + newSelection: this.editor.getDomSelection() + }); + } + } + } + } else if (keynum === 38) { + // Arrow Up + if (altKey && !shiftKey) { + // Alt + Arrow Up + // find the previous node + prevNode = this._previousNode(); + + if (prevNode) { + this.editor.deselect(true); + prevNode.focus(Node.focusElement || this._getElementName(target)); + } + + handled = true; + } else if (!altKey && ctrlKey && shiftKey && editable) { + // Ctrl + Shift + Arrow Up + // select multiple nodes + prevNode = this._previousNode(); + + if (prevNode) { + multiselection = this.editor.multiselection; + multiselection.start = multiselection.start || this; + multiselection.end = prevNode; + nodes = this.editor._findTopLevelNodes(multiselection.start, multiselection.end); + this.editor.select(nodes); + prevNode.focus('field'); // select field as we know this always exists + } + + handled = true; + } else if (altKey && shiftKey && editable) { + // Alt + Shift + Arrow Up + // find the previous node + prevNode = firstNode._previousNode(); + + if (prevNode && prevNode.parent) { + oldSelection = this.editor.getDomSelection(); + oldParent = firstNode.parent; + oldNextNode = oldParent.childs[lastNode.getIndex() + 1] || oldParent.append; + oldIndexRedo = firstNode.getIndex(); + newIndexRedo = prevNode.getIndex(); + oldParentPathRedo = oldParent.getInternalPath(); + newParentPathRedo = prevNode.parent.getInternalPath(); + selectedNodes.forEach(function (node) { + prevNode.parent.moveBefore(node, prevNode); + }); + this.focus(Node.focusElement || this._getElementName(target)); + + this.editor._onAction('moveNodes', { + count: selectedNodes.length, + fieldNames: selectedNodes.map(getField), + oldParentPath: oldParent.getInternalPath(), + newParentPath: firstNode.parent.getInternalPath(), + oldIndex: oldNextNode.getIndex(), + newIndex: firstNode.getIndex(), + oldIndexRedo: oldIndexRedo, + newIndexRedo: newIndexRedo, + oldParentPathRedo: oldParentPathRedo, + newParentPathRedo: newParentPathRedo, + oldSelection: oldSelection, + newSelection: this.editor.getDomSelection() + }); + } + + handled = true; + } + } else if (keynum === 39) { + // Arrow Right + if (altKey && !shiftKey) { + // Alt + Arrow Right + // move to right element + var nextElement = this._nextElement(target); + + if (nextElement) { + this.focus(this._getElementName(nextElement)); + } + + handled = true; + } else if (altKey && shiftKey && editable) { + // Alt + Shift + Arrow Right + var _dom = firstNode.getDom(); + + var prevDom = _dom.previousSibling; + + if (prevDom) { + prevNode = Node.getNodeFromTarget(prevDom); + + if (prevNode && prevNode.parent && !prevNode.isVisible()) { + oldSelection = this.editor.getDomSelection(); + oldParent = firstNode.parent; + oldNextNode = oldParent.childs[lastNode.getIndex() + 1] || oldParent.append; + oldIndexRedo = firstNode.getIndex(); + newIndexRedo = prevNode.getIndex(); + oldParentPathRedo = oldParent.getInternalPath(); + newParentPathRedo = prevNode.parent.getInternalPath(); + selectedNodes.forEach(function (node) { + prevNode.parent.moveBefore(node, prevNode); + }); + this.focus(Node.focusElement || this._getElementName(target)); + + this.editor._onAction('moveNodes', { + count: selectedNodes.length, + fieldNames: selectedNodes.map(getField), + oldParentPath: oldParent.getInternalPath(), + newParentPath: firstNode.parent.getInternalPath(), + oldIndex: oldNextNode.getIndex(), + newIndex: firstNode.getIndex(), + oldIndexRedo: oldIndexRedo, + newIndexRedo: newIndexRedo, + oldParentPathRedo: oldParentPathRedo, + newParentPathRedo: newParentPathRedo, + oldSelection: oldSelection, + newSelection: this.editor.getDomSelection() + }); + } + } + } + } else if (keynum === 40) { + // Arrow Down + if (altKey && !shiftKey) { + // Alt + Arrow Down + // find the next node + nextNode = this._nextNode(); + + if (nextNode) { + this.editor.deselect(true); + nextNode.focus(Node.focusElement || this._getElementName(target)); + } + + handled = true; + } else if (!altKey && ctrlKey && shiftKey && editable) { + // Ctrl + Shift + Arrow Down + // select multiple nodes + nextNode = this._nextNode(); + + if (nextNode) { + multiselection = this.editor.multiselection; + multiselection.start = multiselection.start || this; + multiselection.end = nextNode; + nodes = this.editor._findTopLevelNodes(multiselection.start, multiselection.end); + this.editor.select(nodes); + nextNode.focus('field'); // select field as we know this always exists + } + + handled = true; + } else if (altKey && shiftKey && editable) { + // Alt + Shift + Arrow Down + // find the 2nd next node and move before that one + if (lastNode.expanded) { + nextNode = lastNode.append ? lastNode.append._nextNode() : undefined; + } else { + nextNode = lastNode._nextNode(); + } // when the next node is not visible, we've reached the "showMore" buttons + + + if (nextNode && !nextNode.isVisible()) { + nextNode = nextNode.parent.showMore; + } + + if (nextNode && nextNode instanceof AppendNode) { + nextNode = lastNode; + } + + var _nextNode2 = nextNode && (nextNode._nextNode() || nextNode.parent.append); + + if (_nextNode2 && _nextNode2.parent) { + oldSelection = this.editor.getDomSelection(); + oldParent = firstNode.parent; + oldNextNode = oldParent.childs[lastNode.getIndex() + 1] || oldParent.append; + oldIndexRedo = firstNode.getIndex(); + newIndexRedo = _nextNode2.getIndex(); + oldParentPathRedo = oldParent.getInternalPath(); + newParentPathRedo = _nextNode2.parent.getInternalPath(); + selectedNodes.forEach(function (node) { + _nextNode2.parent.moveBefore(node, _nextNode2); + }); + this.focus(Node.focusElement || this._getElementName(target)); + + this.editor._onAction('moveNodes', { + count: selectedNodes.length, + fieldNames: selectedNodes.map(getField), + oldParentPath: oldParent.getInternalPath(), + newParentPath: firstNode.parent.getInternalPath(), + oldParentPathRedo: oldParentPathRedo, + newParentPathRedo: newParentPathRedo, + oldIndexRedo: oldIndexRedo, + newIndexRedo: newIndexRedo, + oldIndex: oldNextNode.getIndex(), + newIndex: firstNode.getIndex(), + oldSelection: oldSelection, + newSelection: this.editor.getDomSelection() + }); + } + + handled = true; + } + } + + if (handled) { + event.preventDefault(); + event.stopPropagation(); + } + } + /** + * Handle the expand event, when clicked on the expand button + * @param {boolean} recurse If true, child nodes will be expanded too + * @private + */ + + }, { + key: "_onExpand", + value: function _onExpand(recurse) { + var table; + var frame; + var scrollTop; + + if (recurse) { + // Take the table offline + table = this.dom.tr.parentNode; // TODO: not nice to access the main table like this + + frame = table.parentNode; + scrollTop = frame.scrollTop; + frame.removeChild(table); + } + + if (this.expanded) { + this.collapse(recurse); + } else { + this.expand(recurse); + } + + if (recurse) { + // Put the table online again + frame.appendChild(table); + frame.scrollTop = scrollTop; + } + } + /** + * Open a color picker to select a new color + * @private + */ + + }, { + key: "_showColorPicker", + value: function _showColorPicker() { + if (typeof this.editor.options.onColorPicker === 'function' && this.dom.color) { + var node = this; // force deleting current color picker (if any) + + node._deleteDomColor(); + + node.updateDom(); + var colorAnchor = (0,createAbsoluteAnchor/* createAbsoluteAnchor */.w)(this.dom.color, this.editor.getPopupAnchor()); + this.editor.options.onColorPicker(colorAnchor, this.value, function onChange(value) { + if (typeof value === 'string' && value !== node.value) { + // force recreating the color block, to cleanup any attached color picker + node._deleteDomColor(); + + node.value = value; + node.updateDom(); + + node._debouncedOnChangeValue(); + } + }); + } + } + /** + * Get all field names of an object + * @param {Node} [excludeNode] Optional node to be excluded from the returned field names + * @return {string[]} + */ + + }, { + key: "getFieldNames", + value: function getFieldNames(excludeNode) { + if (this.type === 'object') { + return this.childs.filter(function (child) { + return child !== excludeNode; + }).map(function (child) { + return child.field; + }); + } + + return []; + } + /** + * Handle insert before event + * @param {String} [field] + * @param {*} [value] + * @param {String} [type] Can be 'auto', 'array', 'object', or 'string' + * @private + */ + + }, { + key: "_onInsertBefore", + value: function _onInsertBefore(field, value, type) { + var oldSelection = this.editor.getDomSelection(); + var newNode = new Node(this.editor, { + field: field !== undefined ? field : '', + value: value !== undefined ? value : '', + type: type + }); + newNode.expand(true); + var beforePath = this.getInternalPath(); + this.parent.insertBefore(newNode, this); + this.editor.highlighter.unhighlight(); + newNode.focus('field'); + var newSelection = this.editor.getDomSelection(); + + this.editor._onAction('insertBeforeNodes', { + nodes: [newNode], + paths: [newNode.getInternalPath()], + beforePath: beforePath, + parentPath: this.parent.getInternalPath(), + oldSelection: oldSelection, + newSelection: newSelection + }); + } + /** + * Handle insert after event + * @param {String} [field] + * @param {*} [value] + * @param {String} [type] Can be 'auto', 'array', 'object', or 'string' + * @private + */ + + }, { + key: "_onInsertAfter", + value: function _onInsertAfter(field, value, type) { + var oldSelection = this.editor.getDomSelection(); + var newNode = new Node(this.editor, { + field: field !== undefined ? field : '', + value: value !== undefined ? value : '', + type: type + }); + newNode.expand(true); + this.parent.insertAfter(newNode, this); + this.editor.highlighter.unhighlight(); + newNode.focus('field'); + var newSelection = this.editor.getDomSelection(); + + this.editor._onAction('insertAfterNodes', { + nodes: [newNode], + paths: [newNode.getInternalPath()], + afterPath: this.getInternalPath(), + parentPath: this.parent.getInternalPath(), + oldSelection: oldSelection, + newSelection: newSelection + }); + } + /** + * Handle append event + * @param {String} [field] + * @param {*} [value] + * @param {String} [type] Can be 'auto', 'array', 'object', or 'string' + * @private + */ + + }, { + key: "_onAppend", + value: function _onAppend(field, value, type) { + var oldSelection = this.editor.getDomSelection(); + var newNode = new Node(this.editor, { + field: field !== undefined ? field : '', + value: value !== undefined ? value : '', + type: type + }); + newNode.expand(true); + this.parent.appendChild(newNode); + this.editor.highlighter.unhighlight(); + newNode.focus('field'); + var newSelection = this.editor.getDomSelection(); + + this.editor._onAction('appendNodes', { + nodes: [newNode], + paths: [newNode.getInternalPath()], + parentPath: this.parent.getInternalPath(), + oldSelection: oldSelection, + newSelection: newSelection + }); + } + /** + * Change the type of the node's value + * @param {String} newType + * @private + */ + + }, { + key: "_onChangeType", + value: function _onChangeType(newType) { + var oldType = this.type; + + if (newType !== oldType) { + var oldSelection = this.editor.getDomSelection(); + this.changeType(newType); + var newSelection = this.editor.getDomSelection(); + + this.editor._onAction('changeType', { + path: this.getInternalPath(), + oldType: oldType, + newType: newType, + oldSelection: oldSelection, + newSelection: newSelection + }); + } + } + /** + * Sort the child's of the node. Only applicable when the node has type 'object' + * or 'array'. + * @param {String[] | string} path Path of the child value to be compared + * @param {String} direction Sorting direction. Available values: "asc", "desc" + * @param {boolean} [triggerAction=true] If true (default), a user action will be + * triggered, creating an entry in history + * and invoking onChange. + * @private + */ + + }, { + key: "sort", + value: function sort(path, direction) { + var triggerAction = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + + if (typeof path === 'string') { + path = (0,util.parsePath)(path); + } + + if (!this._hasChilds()) { + return; + } + + this.hideChilds(); // sorting is faster when the childs are not attached to the dom + // copy the childs array (the old one will be kept for an undo action + + var oldChilds = this.childs; + this.childs = this.childs.concat(); // sort the childs array + + var order = direction === 'desc' ? -1 : 1; + + if (this.type === 'object') { + this.childs.sort(function (a, b) { + return order * naturalSort_default()(a.field, b.field); + }); + } else { + // this.type === 'array' + this.childs.sort(function (a, b) { + var nodeA = a.getNestedChild(path); + var nodeB = b.getNestedChild(path); + + if (!nodeA) { + return order; + } + + if (!nodeB) { + return -order; + } + + var valueA = nodeA.value; + var valueB = nodeB.value; + + if (typeof valueA !== 'string' && typeof valueB !== 'string') { + // both values are a number, boolean, or null -> use simple, fast sorting + return valueA > valueB ? order : valueA < valueB ? -order : 0; + } + + return order * naturalSort_default()(valueA, valueB); + }); + } // update the index numbering + + + this._updateDomIndexes(); + + this.showChilds(); + + if (triggerAction === true) { + this.editor._onAction('sort', { + path: this.getInternalPath(), + oldChilds: oldChilds, + newChilds: this.childs + }); + } + } + /** + * Replace the value of the node, keep it's state + * @param {*} newValue + */ + + }, { + key: "update", + value: function update(newValue) { + var oldValue = this.getInternalValue(); + this.setValue(newValue); + + this.editor._onAction('transform', { + path: this.getInternalPath(), + oldValue: oldValue, + newValue: this.getInternalValue() + }); + } + /** + * Remove this node from the DOM + * @returns {{table: Element, nextTr?: Element}} + * Returns the DOM elements that which be used to attach the node + * to the DOM again, see _attachToDom. + * @private + */ + + }, { + key: "_detachFromDom", + value: function _detachFromDom() { + var table = this.dom.tr ? this.dom.tr.parentNode : undefined; + var lastTr; + + if (this.expanded) { + lastTr = this.getAppendDom(); + } else { + lastTr = this.getDom(); + } + + var nextTr = lastTr && lastTr.parentNode ? lastTr.nextSibling : undefined; + this.hide({ + resetVisibleChilds: false + }); + return { + table: table, + nextTr: nextTr + }; + } + /** + * Attach this node to the DOM again + * @param {{table: Element, nextTr?: Element}} domAnchor + * The DOM elements returned by _detachFromDom. + * @private + */ + + }, { + key: "_attachToDom", + value: function _attachToDom(domAnchor) { + if (domAnchor.table) { + if (domAnchor.nextTr) { + domAnchor.table.insertBefore(this.getDom(), domAnchor.nextTr); + } else { + domAnchor.table.appendChild(this.getDom()); + } + } + + if (this.expanded) { + this.showChilds(); + } + } + /** + * Transform the node given a JMESPath query. + * @param {String} query JMESPath query to apply + * @private + */ + + }, { + key: "transform", + value: function transform(query) { + if (!this._hasChilds()) { + return; + } + + this.hideChilds(); // sorting is faster when the childs are not attached to the dom + + try { + var oldInternalValue = this.getInternalValue(); // apply the JMESPath query + + var oldValue = this.getValue(); + var newValue = this.editor.options.executeQuery(oldValue, query); + this.setValue(newValue); + var newInternalValue = this.getInternalValue(); + + this.editor._onAction('transform', { + path: this.getInternalPath(), + oldValue: oldInternalValue, + newValue: newInternalValue + }); + + this.showChilds(); + } catch (err) { + this.showChilds(); + + this.editor._onError(err); + } + } + /** + * Make this object the root object of the ditor + */ + + }, { + key: "extract", + value: function extract() { + this.editor.node.hideChilds(); + this.hideChilds(); + + try { + var oldInternalValue = this.editor.node.getInternalValue(); + + this.editor._setRoot(this); + + var newInternalValue = this.editor.node.getInternalValue(); + + this.editor._onAction('transform', { + path: this.editor.node.getInternalPath(), + oldValue: oldInternalValue, + newValue: newInternalValue + }); + } catch (err) { + this.editor._onError(err); + } finally { + this.updateDom({ + recurse: true + }); + this.showChilds(); + } + } + /** + * Get a nested child given a path with properties + * @param {String[]} path + * @returns {Node} + */ + + }, { + key: "getNestedChild", + value: function getNestedChild(path) { + var i = 0; + var child = this; + + while (child && i < path.length) { + child = child.findChildByProperty(path[i]); + i++; + } + + return child; + } + /** + * Find a child by property name + * @param {string} prop + * @return {Node | undefined} Returns the child node when found, or undefined otherwise + */ + + }, { + key: "findChildByProperty", + value: function findChildByProperty(prop) { + if (this.type !== 'object') { + return undefined; + } + + return this.childs.find(function (child) { + return child.field === prop; + }); + } + /** + * Create a table row with an append button. + * @return {HTMLElement | undefined} tr with the AppendNode contents + */ + + }, { + key: "getAppendDom", + value: function getAppendDom() { + if (!this.append) { + this.append = new AppendNode(this.editor); + this.append.setParent(this); + } + + return this.append.getDom(); + } + /** + * Create a table row with an showMore button and text + * @return {HTMLElement | undefined} tr with the AppendNode contents + */ + + }, { + key: "getShowMoreDom", + value: function getShowMoreDom() { + if (!this.showMore) { + this.showMore = new ShowMoreNode(this.editor, this); + } + + return this.showMore.getDom(); + } + /** + * Get the next sibling of current node + * @return {Node} nextSibling + */ + + }, { + key: "nextSibling", + value: function nextSibling() { + var index = this.parent.childs.indexOf(this); + return this.parent.childs[index + 1] || this.parent.append; + } + /** + * Get the previously rendered node + * @return {Node | null} previousNode + */ + + }, { + key: "_previousNode", + value: function _previousNode() { + var prevNode = null; + var dom = this.getDom(); + + if (dom && dom.parentNode) { + // find the previous field + var prevDom = dom; + + do { + prevDom = prevDom.previousSibling; + prevNode = Node.getNodeFromTarget(prevDom); + } while (prevDom && prevNode && prevNode instanceof AppendNode && !prevNode.isVisible()); + } + + return prevNode; + } + /** + * Get the next rendered node + * @return {Node | null} nextNode + * @private + */ + + }, { + key: "_nextNode", + value: function _nextNode() { + var nextNode = null; + var dom = this.getDom(); + + if (dom && dom.parentNode) { + // find the previous field + var nextDom = dom; + + do { + nextDom = nextDom.nextSibling; + nextNode = Node.getNodeFromTarget(nextDom); + } while (nextDom && nextNode && nextNode instanceof AppendNode && !nextNode.isVisible()); + } + + return nextNode; + } + /** + * Get the first rendered node + * @return {Node | null} firstNode + * @private + */ + + }, { + key: "_firstNode", + value: function _firstNode() { + var firstNode = null; + var dom = this.getDom(); + + if (dom && dom.parentNode) { + var firstDom = dom.parentNode.firstChild; + firstNode = Node.getNodeFromTarget(firstDom); + } + + return firstNode; + } + /** + * Get the last rendered node + * @return {Node | null} lastNode + * @private + */ + + }, { + key: "_lastNode", + value: function _lastNode() { + var lastNode = null; + var dom = this.getDom(); + + if (dom && dom.parentNode) { + var lastDom = dom.parentNode.lastChild; + lastNode = Node.getNodeFromTarget(lastDom); + + while (lastDom && lastNode && !lastNode.isVisible()) { + lastDom = lastDom.previousSibling; + lastNode = Node.getNodeFromTarget(lastDom); + } + } + + return lastNode; + } + /** + * Get the next element which can have focus. + * @param {Element} elem + * @return {Element | null} nextElem + * @private + */ + + }, { + key: "_previousElement", + value: function _previousElement(elem) { + var dom = this.dom; // noinspection FallthroughInSwitchStatementJS + + switch (elem) { + case dom.value: + if (this.fieldEditable) { + return dom.field; + } + + // intentional fall through + + case dom.field: + if (this._hasChilds()) { + return dom.expand; + } + + // intentional fall through + + case dom.expand: + return dom.menu; + + case dom.menu: + if (dom.drag) { + return dom.drag; + } + + // intentional fall through + + default: + return null; + } + } + /** + * Get the next element which can have focus. + * @param {Element} elem + * @return {Element | null} nextElem + * @private + */ + + }, { + key: "_nextElement", + value: function _nextElement(elem) { + var dom = this.dom; // noinspection FallthroughInSwitchStatementJS + + switch (elem) { + case dom.drag: + return dom.menu; + + case dom.menu: + if (this._hasChilds()) { + return dom.expand; + } + + // intentional fall through + + case dom.expand: + if (this.fieldEditable) { + return dom.field; + } + + // intentional fall through + + case dom.field: + if (!this._hasChilds()) { + return dom.value; + } + + // intentional fall through + + default: + return null; + } + } + /** + * Get the dom name of given element. returns null if not found. + * For example when element === dom.field, "field" is returned. + * @param {Element} element + * @return {String | null} elementName Available elements with name: 'drag', + * 'menu', 'expand', 'field', 'value' + * @private + */ + + }, { + key: "_getElementName", + value: function _getElementName(element) { + var _this2 = this; + + return Object.keys(this.dom).find(function (name) { + return _this2.dom[name] === element; + }); + } + /** + * Test if this node has childs. This is the case when the node is an object + * or array. + * @return {boolean} hasChilds + * @private + */ + + }, { + key: "_hasChilds", + value: function _hasChilds() { + return this.type === 'array' || this.type === 'object'; + } + }, { + key: "addTemplates", + value: function addTemplates(menu, append) { + var node = this; + var templates = node.editor.options.templates; + if (templates == null) return; + + if (templates.length) { + // create a separator + menu.push({ + type: 'separator' + }); + } + + var appendData = function appendData(name, data) { + node._onAppend(name, data); + }; + + var insertData = function insertData(name, data) { + node._onInsertBefore(name, data); + }; + + templates.forEach(function (template) { + menu.push({ + text: template.text, + className: template.className || 'jsoneditor-type-object', + title: template.title, + click: append ? appendData.bind(this, template.field, template.value) : insertData.bind(this, template.field, template.value) + }); + }); + } + /** + * Show a contextmenu for this node + * @param {HTMLElement} anchor Anchor element to attach the context menu to + * as sibling. + * @param {function} [onClose] Callback method called when the context menu + * is being closed. + */ + + }, { + key: "showContextMenu", + value: function showContextMenu(anchor, onClose) { + var node = this; + var items = []; + + if (this.editable.value) { + items.push({ + text: (0,i18n/* translate */.Iu)('type'), + title: (0,i18n/* translate */.Iu)('typeTitle'), + className: 'jsoneditor-type-' + this.type, + submenu: [{ + text: (0,i18n/* translate */.Iu)('auto'), + className: 'jsoneditor-type-auto' + (this.type === 'auto' ? ' jsoneditor-selected' : ''), + title: (0,i18n/* translate */.Iu)('autoType'), + click: function click() { + node._onChangeType('auto'); + } + }, { + text: (0,i18n/* translate */.Iu)('array'), + className: 'jsoneditor-type-array' + (this.type === 'array' ? ' jsoneditor-selected' : ''), + title: (0,i18n/* translate */.Iu)('arrayType'), + click: function click() { + node._onChangeType('array'); + } + }, { + text: (0,i18n/* translate */.Iu)('object'), + className: 'jsoneditor-type-object' + (this.type === 'object' ? ' jsoneditor-selected' : ''), + title: (0,i18n/* translate */.Iu)('objectType'), + click: function click() { + node._onChangeType('object'); + } + }, { + text: (0,i18n/* translate */.Iu)('string'), + className: 'jsoneditor-type-string' + (this.type === 'string' ? ' jsoneditor-selected' : ''), + title: (0,i18n/* translate */.Iu)('stringType'), + click: function click() { + node._onChangeType('string'); + } + }] + }); + } + + if (this._hasChilds()) { + if (this.editor.options.enableSort) { + items.push({ + text: (0,i18n/* translate */.Iu)('sort'), + title: (0,i18n/* translate */.Iu)('sortTitle', { + type: this.type + }), + className: 'jsoneditor-sort-asc', + click: function click() { + node.showSortModal(); + } + }); + } + + if (this.editor.options.enableTransform) { + items.push({ + text: (0,i18n/* translate */.Iu)('transform'), + title: (0,i18n/* translate */.Iu)('transformTitle', { + type: this.type + }), + className: 'jsoneditor-transform', + click: function click() { + node.showTransformModal(); + } + }); + } + + if (this.parent) { + items.push({ + text: (0,i18n/* translate */.Iu)('extract'), + title: (0,i18n/* translate */.Iu)('extractTitle', { + type: this.type + }), + className: 'jsoneditor-extract', + click: function click() { + node.extract(); + } + }); + } + } + + if (this.parent && this.parent._hasChilds()) { + if (items.length) { + // create a separator + items.push({ + type: 'separator' + }); + } // create append button (for last child node only) + + + var childs = node.parent.childs; + + if (node === childs[childs.length - 1]) { + var appendSubmenu = [{ + text: (0,i18n/* translate */.Iu)('auto'), + className: 'jsoneditor-type-auto', + title: (0,i18n/* translate */.Iu)('autoType'), + click: function click() { + node._onAppend('', '', 'auto'); + } + }, { + text: (0,i18n/* translate */.Iu)('array'), + className: 'jsoneditor-type-array', + title: (0,i18n/* translate */.Iu)('arrayType'), + click: function click() { + node._onAppend('', []); + } + }, { + text: (0,i18n/* translate */.Iu)('object'), + className: 'jsoneditor-type-object', + title: (0,i18n/* translate */.Iu)('objectType'), + click: function click() { + node._onAppend('', {}); + } + }, { + text: (0,i18n/* translate */.Iu)('string'), + className: 'jsoneditor-type-string', + title: (0,i18n/* translate */.Iu)('stringType'), + click: function click() { + node._onAppend('', '', 'string'); + } + }]; + node.addTemplates(appendSubmenu, true); + items.push({ + text: (0,i18n/* translate */.Iu)('appendText'), + title: (0,i18n/* translate */.Iu)('appendTitle'), + submenuTitle: (0,i18n/* translate */.Iu)('appendSubmenuTitle'), + className: 'jsoneditor-append', + click: function click() { + node._onAppend('', '', 'auto'); + }, + submenu: appendSubmenu + }); + } // create insert button + + + var insertSubmenu = [{ + text: (0,i18n/* translate */.Iu)('auto'), + className: 'jsoneditor-type-auto', + title: (0,i18n/* translate */.Iu)('autoType'), + click: function click() { + node._onInsertBefore('', '', 'auto'); + } + }, { + text: (0,i18n/* translate */.Iu)('array'), + className: 'jsoneditor-type-array', + title: (0,i18n/* translate */.Iu)('arrayType'), + click: function click() { + node._onInsertBefore('', []); + } + }, { + text: (0,i18n/* translate */.Iu)('object'), + className: 'jsoneditor-type-object', + title: (0,i18n/* translate */.Iu)('objectType'), + click: function click() { + node._onInsertBefore('', {}); + } + }, { + text: (0,i18n/* translate */.Iu)('string'), + className: 'jsoneditor-type-string', + title: (0,i18n/* translate */.Iu)('stringType'), + click: function click() { + node._onInsertBefore('', '', 'string'); + } + }]; + node.addTemplates(insertSubmenu, false); + items.push({ + text: (0,i18n/* translate */.Iu)('insert'), + title: (0,i18n/* translate */.Iu)('insertTitle'), + submenuTitle: (0,i18n/* translate */.Iu)('insertSub'), + className: 'jsoneditor-insert', + click: function click() { + node._onInsertBefore('', '', 'auto'); + }, + submenu: insertSubmenu + }); + + if (this.editable.field) { + // create duplicate button + items.push({ + text: (0,i18n/* translate */.Iu)('duplicateText'), + title: (0,i18n/* translate */.Iu)('duplicateField'), + className: 'jsoneditor-duplicate', + click: function click() { + Node.onDuplicate(node); + } + }); // create remove button + + items.push({ + text: (0,i18n/* translate */.Iu)('removeText'), + title: (0,i18n/* translate */.Iu)('removeField'), + className: 'jsoneditor-remove', + click: function click() { + Node.onRemove(node); + } + }); + } + } + + if (this.editor.options.onCreateMenu) { + var path = node.getPath(); + items = this.editor.options.onCreateMenu(items, { + type: 'single', + path: path, + paths: [path] + }); + } + + var menu = new ContextMenu/* ContextMenu */.x(items, { + close: onClose + }); + menu.show(anchor, this.editor.getPopupAnchor()); + } + /** + * Show sorting modal + */ + + }, { + key: "showSortModal", + value: function showSortModal() { + var node = this; + var container = this.editor.options.modalAnchor || constants/* DEFAULT_MODAL_ANCHOR */.qD; + var json = this.getValue(); + + function onSort(sortedBy) { + var path = sortedBy.path; + var pathArray = (0,util.parsePath)(path); + node.sortedBy = sortedBy; + node.sort(pathArray, sortedBy.direction); + } + + (0,js_showSortModal.showSortModal)(container, json, onSort, node.sortedBy); + } + /** + * Show transform modal + */ + + }, { + key: "showTransformModal", + value: function showTransformModal() { + var _this3 = this; + + var _this$editor$options = this.editor.options, + modalAnchor = _this$editor$options.modalAnchor, + createQuery = _this$editor$options.createQuery, + executeQuery = _this$editor$options.executeQuery, + queryDescription = _this$editor$options.queryDescription; + var json = this.getValue(); + + (0,js_showTransformModal.showTransformModal)({ + container: modalAnchor || constants/* DEFAULT_MODAL_ANCHOR */.qD, + json: json, + queryDescription: queryDescription, + // can be undefined + createQuery: createQuery, + executeQuery: executeQuery, + onTransform: function onTransform(query) { + _this3.transform(query); + } + }); + } + /** + * get the type of a value + * @param {*} value + * @return {String} type Can be 'object', 'array', 'string', 'auto' + * @private + */ + + }, { + key: "_getType", + value: function _getType(value) { + if (value instanceof Array) { + return 'array'; + } + + if (value instanceof Object) { + return 'object'; + } + + if (typeof value === 'string' && typeof (0,util.parseString)(value) !== 'string') { + return 'string'; + } + + return 'auto'; + } + /** + * escape a text, such that it can be displayed safely in an HTML element + * @param {String} text + * @return {String} escapedText + * @private + */ + + }, { + key: "_escapeHTML", + value: function _escapeHTML(text) { + if (typeof text !== 'string') { + return String(text); + } else { + var htmlEscaped = String(text).replace(/&/g, '&') // must be replaced first! + .replace(//g, '>').replace(/ {2}/g, '  ') // replace double space with an nbsp and space + .replace(/^ /, ' ') // space at start + .replace(/ $/, ' '); // space at end + + var json = JSON.stringify(htmlEscaped); + var html = json.substring(1, json.length - 1); + + if (this.editor.options.escapeUnicode === true) { + html = (0,util.escapeUnicodeChars)(html); + } + + return html; + } + } + /** + * unescape a string. + * @param {String} escapedText + * @return {String} text + * @private + */ + + }, { + key: "_unescapeHTML", + value: function _unescapeHTML(escapedText) { + var json = '"' + this._escapeJSON(escapedText) + '"'; + var htmlEscaped = (0,util.parse)(json); + return htmlEscaped.replace(/</g, '<').replace(/>/g, '>').replace(/ |\u00A0/g, ' ').replace(/&/g, '&'); // must be replaced last + } + /** + * escape a text to make it a valid JSON string. The method will: + * - replace unescaped double quotes with '\"' + * - replace unescaped backslash with '\\' + * - replace returns with '\n' + * @param {String} text + * @return {String} escapedText + * @private + */ + + }, { + key: "_escapeJSON", + value: function _escapeJSON(text) { + // TODO: replace with some smart regex (only when a new solution is faster!) + var escaped = ''; + var i = 0; + + while (i < text.length) { + var c = text.charAt(i); + + if (c === '\n') { + escaped += '\\n'; + } else if (c === '\\') { + escaped += c; + i++; + c = text.charAt(i); + + if (c === '' || '"\\/bfnrtu'.indexOf(c) === -1) { + escaped += '\\'; // no valid escape character + } + + escaped += c; + } else if (c === '"') { + escaped += '\\"'; + } else { + escaped += c; + } + + i++; + } + + return escaped; + } + /** + * update the object name according to the callback onNodeName + * @private + */ + + }, { + key: "updateNodeName", + value: function updateNodeName() { + var count = this.childs ? this.childs.length : 0; + var nodeName; + + if (this.type === 'object' || this.type === 'array') { + if (this.editor.options.onNodeName) { + try { + nodeName = this.editor.options.onNodeName({ + path: this.getPath(), + size: count, + type: this.type + }); + } catch (err) { + console.error('Error in onNodeName callback: ', err); + } + } + + this.dom.value.textContent = this.type === 'object' ? '{' + (nodeName || count) + '}' : '[' + (nodeName || count) + ']'; + } + } + /** + * update recursively the object's and its children's name. + * @private + */ + + }, { + key: "recursivelyUpdateNodeName", + value: function recursivelyUpdateNodeName() { + if (this.expanded) { + this.updateNodeName(); + + if (this.childs !== 'undefined') { + var i; + + for (i in this.childs) { + this.childs[i].recursivelyUpdateNodeName(); + } + } + } + } + }]); + + return Node; +}(); // debounce interval for keyboard input in milliseconds + +Node.prototype.DEBOUNCE_INTERVAL = 150; // search will stop iterating as soon as the max is reached + +Node.prototype.MAX_SEARCH_RESULTS = 999; // default number of child nodes to display + +var DEFAULT_MAX_VISIBLE_CHILDS = 100; // stores the element name currently having the focus + +Node.focusElement = undefined; +/** + * Select all text in an editable div after a delay of 0 ms + * @param {Element} editableDiv + */ + +Node.select = function (editableDiv) { + setTimeout(function () { + (0,util.selectContentEditable)(editableDiv); + }, 0); +}; +/** + * DragStart event, fired on mousedown on the dragarea at the left side of a Node + * @param {Node[] | Node} nodes + * @param {Event} event + */ + + +Node.onDragStart = function (nodes, event) { + if (!Array.isArray(nodes)) { + return Node.onDragStart([nodes], event); + } + + if (nodes.length === 0) { + return; + } + + var firstNode = nodes[0]; + var lastNode = nodes[nodes.length - 1]; + var parent = firstNode.parent; + var draggedNode = Node.getNodeFromTarget(event.target); + var editor = firstNode.editor; // in case of multiple selected nodes, offsetY prevents the selection from + // jumping when you start dragging one of the lower down nodes in the selection + + var offsetY = (0,util.getAbsoluteTop)(draggedNode.dom.tr) - (0,util.getAbsoluteTop)(firstNode.dom.tr); + + if (!editor.mousemove) { + editor.mousemove = (0,util.addEventListener)(event.view, 'mousemove', function (event) { + Node.onDrag(nodes, event); + }); + } + + if (!editor.mouseup) { + editor.mouseup = (0,util.addEventListener)(event.view, 'mouseup', function (event) { + Node.onDragEnd(nodes, event); + }); + } + + editor.highlighter.lock(); + editor.drag = { + oldCursor: document.body.style.cursor, + oldSelection: editor.getDomSelection(), + oldPaths: nodes.map(getInternalPath), + oldParent: parent, + oldNextNode: parent.childs[lastNode.getIndex() + 1] || parent.append, + oldParentPathRedo: parent.getInternalPath(), + oldIndexRedo: firstNode.getIndex(), + mouseX: event.pageX, + offsetY: offsetY, + level: firstNode.getLevel() + }; + document.body.style.cursor = 'move'; + event.preventDefault(); +}; +/** + * Drag event, fired when moving the mouse while dragging a Node + * @param {Node[] | Node} nodes + * @param {Event} event + */ + + +Node.onDrag = function (nodes, event) { + if (!Array.isArray(nodes)) { + return Node.onDrag([nodes], event); + } + + if (nodes.length === 0) { + return; + } // TODO: this method has grown too large. Split it in a number of methods + + + var editor = nodes[0].editor; + var mouseY = event.pageY - editor.drag.offsetY; + var mouseX = event.pageX; + var trPrev, trNext, trFirst, trLast, trRoot; + var nodePrev, nodeNext; + var topPrev, topFirst, bottomNext, heightNext; + var moved = false; // TODO: add an ESC option, which resets to the original position + // move up/down + + var firstNode = nodes[0]; + var trThis = firstNode.dom.tr; + var topThis = (0,util.getAbsoluteTop)(trThis); + var heightThis = trThis.offsetHeight; + + if (mouseY < topThis) { + // move up + trPrev = trThis; + + do { + trPrev = trPrev.previousSibling; + nodePrev = Node.getNodeFromTarget(trPrev); + topPrev = trPrev ? (0,util.getAbsoluteTop)(trPrev) : 0; + } while (trPrev && mouseY < topPrev); + + if (nodePrev && !nodePrev.parent) { + nodePrev = undefined; + } + + if (!nodePrev) { + // move to the first node + trRoot = trThis.parentNode.firstChild; + trPrev = trRoot ? trRoot.nextSibling : undefined; + nodePrev = Node.getNodeFromTarget(trPrev); + + if (nodePrev === firstNode) { + nodePrev = undefined; + } + } + + if (nodePrev && nodePrev.isVisible()) { + // check if mouseY is really inside the found node + trPrev = nodePrev.dom.tr; + topPrev = trPrev ? (0,util.getAbsoluteTop)(trPrev) : 0; + + if (mouseY > topPrev + heightThis) { + nodePrev = undefined; + } + } + + if (nodePrev && (editor.options.limitDragging === false || nodePrev.parent === nodes[0].parent)) { + nodes.forEach(function (node) { + nodePrev.parent.moveBefore(node, nodePrev); + }); + moved = true; + } + } else { + // move down + var lastNode = nodes[nodes.length - 1]; + trLast = lastNode.expanded && lastNode.append ? lastNode.append.getDom() : lastNode.dom.tr; + trFirst = trLast ? trLast.nextSibling : undefined; + + if (trFirst) { + topFirst = (0,util.getAbsoluteTop)(trFirst); + trNext = trFirst; + + do { + nodeNext = Node.getNodeFromTarget(trNext); + + if (trNext) { + bottomNext = trNext.nextSibling ? (0,util.getAbsoluteTop)(trNext.nextSibling) : 0; + heightNext = trNext ? bottomNext - topFirst : 0; + + if (nodeNext && nodeNext.parent.childs.length === nodes.length && nodeNext.parent.childs[nodes.length - 1] === lastNode) { + // We are about to remove the last child of this parent, + // which will make the parents appendNode visible. + topThis += 27; // TODO: dangerous to suppose the height of the appendNode a constant of 27 px. + } + + trNext = trNext.nextSibling; + } + } while (trNext && mouseY > topThis + heightNext); + + if (nodeNext && nodeNext.parent) { + // calculate the desired level + var diffX = mouseX - editor.drag.mouseX; + var diffLevel = Math.round(diffX / 24 / 2); + var level = editor.drag.level + diffLevel; // desired level + + var levelNext = nodeNext.getLevel(); // level to be + // find the best fitting level (move upwards over the append nodes) + + trPrev = nodeNext.dom.tr && nodeNext.dom.tr.previousSibling; + + while (levelNext < level && trPrev) { + nodePrev = Node.getNodeFromTarget(trPrev); + var isDraggedNode = nodes.some(function (node) { + return node === nodePrev || nodePrev.isDescendantOf(node); + }); + + if (isDraggedNode) {// neglect the dragged nodes themselves and their childs + } else if (nodePrev instanceof AppendNode) { + var childs = nodePrev.parent.childs; + + if (childs.length !== nodes.length || childs[nodes.length - 1] !== lastNode) { + // non-visible append node of a list of childs + // consisting of not only this node (else the + // append node will change into a visible "empty" + // text when removing this node). + nodeNext = Node.getNodeFromTarget(trPrev); + levelNext = nodeNext.getLevel(); + } else { + break; + } + } else { + break; + } + + trPrev = trPrev.previousSibling; + } + + if (nodeNext instanceof AppendNode && !nodeNext.isVisible() && nodeNext.parent.showMore.isVisible()) { + nodeNext = nodeNext._nextNode(); + } // move the node when its position is changed + + + if (nodeNext && (editor.options.limitDragging === false || nodeNext.parent === nodes[0].parent) && nodeNext.dom.tr && nodeNext.dom.tr !== trLast.nextSibling) { + nodes.forEach(function (node) { + nodeNext.parent.moveBefore(node, nodeNext); + }); + moved = true; + } + } + } + } + + if (moved) { + // update the dragging parameters when moved + editor.drag.mouseX = mouseX; + editor.drag.level = firstNode.getLevel(); + } // auto scroll when hovering around the top of the editor + + + editor.startAutoScroll(mouseY); + event.preventDefault(); +}; +/** + * Drag event, fired on mouseup after having dragged a node + * @param {Node[] | Node} nodes + * @param {Event} event + */ + + +Node.onDragEnd = function (nodes, event) { + if (!Array.isArray(nodes)) { + return Node.onDrag([nodes], event); + } + + if (nodes.length === 0) { + return; + } + + var firstNode = nodes[0]; + var editor = firstNode.editor; // set focus to the context menu button of the first node + + if (nodes[0]) { + nodes[0].dom.menu.focus(); + } + + var oldParentPath = editor.drag.oldParent.getInternalPath(); + var newParentPath = firstNode.parent.getInternalPath(); + var sameParent = editor.drag.oldParent === firstNode.parent; + var oldIndex = editor.drag.oldNextNode.getIndex(); + var newIndex = firstNode.getIndex(); + var oldParentPathRedo = editor.drag.oldParentPathRedo; + var oldIndexRedo = editor.drag.oldIndexRedo; + var newIndexRedo = sameParent && oldIndexRedo < newIndex ? newIndex + nodes.length : newIndex; + + if (!sameParent || oldIndexRedo !== newIndex) { + // only register this action if the node is actually moved to another place + editor._onAction('moveNodes', { + count: nodes.length, + fieldNames: nodes.map(getField), + oldParentPath: oldParentPath, + newParentPath: newParentPath, + oldIndex: oldIndex, + newIndex: newIndex, + oldIndexRedo: oldIndexRedo, + newIndexRedo: newIndexRedo, + oldParentPathRedo: oldParentPathRedo, + newParentPathRedo: null, + // This is a hack, value will be filled in during undo + oldSelection: editor.drag.oldSelection, + newSelection: editor.getDomSelection() + }); + } + + document.body.style.cursor = editor.drag.oldCursor; + editor.highlighter.unlock(); + nodes.forEach(function (node) { + node.updateDom(); + + if (event.target !== node.dom.drag && event.target !== node.dom.menu) { + editor.highlighter.unhighlight(); + } + }); + delete editor.drag; + + if (editor.mousemove) { + (0,util.removeEventListener)(event.view, 'mousemove', editor.mousemove); + delete editor.mousemove; + } + + if (editor.mouseup) { + (0,util.removeEventListener)(event.view, 'mouseup', editor.mouseup); + delete editor.mouseup; + } // Stop any running auto scroll + + + editor.stopAutoScroll(); + event.preventDefault(); +}; +/** + * find an enum definition in a JSON schema, as property `enum` or inside + * one of the schemas composites (`oneOf`, `anyOf`, `allOf`) + * @param {Object} schema + * @return {Array | null} Returns the enum when found, null otherwise. + * @private + */ + + +Node._findEnum = function (schema) { + if (schema["enum"]) { + return schema["enum"]; + } + + var composite = schema.oneOf || schema.anyOf || schema.allOf; + + if (composite) { + var match = composite.filter(function (entry) { + return entry["enum"]; + }); + + if (match.length > 0) { + return match[0]["enum"]; + } + } + + return null; +}; +/** + * Return the part of a JSON schema matching given path. + * @param {Object} topLevelSchema + * @param {Object} schemaRefs + * @param {Array.} path + * @param {Object} currentSchema + * @return {Object | null} + * @private + */ + + +Node._findSchema = function (topLevelSchema, schemaRefs, path) { + var currentSchema = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : topLevelSchema; + var nextPath = path.slice(1, path.length); + var nextKey = path[0]; + var possibleSchemas = currentSchema.oneOf || currentSchema.anyOf || currentSchema.allOf || [currentSchema]; + + var _iterator = _createForOfIteratorHelper(possibleSchemas), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var schema = _step.value; + currentSchema = schema; + + if ('$ref' in currentSchema && typeof currentSchema.$ref === 'string') { + var ref = currentSchema.$ref; + + if (ref in schemaRefs) { + currentSchema = schemaRefs[ref]; + } else if (ref.startsWith('#/')) { + var refPath = ref.substring(2).split('/'); + currentSchema = topLevelSchema; + + var _iterator2 = _createForOfIteratorHelper(refPath), + _step2; + + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var segment = _step2.value; + + if (segment in currentSchema) { + currentSchema = currentSchema[segment]; + } else { + throw Error("Unable to resovle reference ".concat(ref)); + } + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + } else { + throw Error("Unable to resolve reference ".concat(ref)); + } + } // We have no more path segments to resolve, return the currently found schema + // We do this here, after resolving references, in case of the leaf schema beeing a reference + + + if (nextKey === undefined) { + return currentSchema; + } + + if (typeof nextKey === 'string') { + if (_typeof(currentSchema.properties) === 'object' && currentSchema.properties !== null && nextKey in currentSchema.properties) { + currentSchema = currentSchema.properties[nextKey]; + return Node._findSchema(topLevelSchema, schemaRefs, nextPath, currentSchema); + } + + if (_typeof(currentSchema.patternProperties) === 'object' && currentSchema.patternProperties !== null) { + for (var prop in currentSchema.patternProperties) { + if (nextKey.match(prop)) { + currentSchema = currentSchema.patternProperties[prop]; + return Node._findSchema(topLevelSchema, schemaRefs, nextPath, currentSchema); + } + } + } + + if (_typeof(currentSchema.additionalProperties) === 'object') { + currentSchema = currentSchema.additionalProperties; + return Node._findSchema(topLevelSchema, schemaRefs, nextPath, currentSchema); + } + + continue; + } + + if (typeof nextKey === 'number' && _typeof(currentSchema.items) === 'object' && currentSchema.items !== null) { + currentSchema = currentSchema.items; + return Node._findSchema(topLevelSchema, schemaRefs, nextPath, currentSchema); + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + + return null; +}; +/** + * Remove nodes + * @param {Node[] | Node} nodes + */ + + +Node.onRemove = function (nodes) { + if (!Array.isArray(nodes)) { + return Node.onRemove([nodes]); + } + + if (nodes && nodes.length > 0) { + var firstNode = nodes[0]; + var parent = firstNode.parent; + var editor = firstNode.editor; + var firstIndex = firstNode.getIndex(); + editor.highlighter.unhighlight(); // adjust the focus + + var oldSelection = editor.getDomSelection(); + Node.blurNodes(nodes); + var newSelection = editor.getDomSelection(); // store the paths before removing them (needed for history) + + var paths = nodes.map(getInternalPath); // remove the nodes + + nodes.forEach(function (node) { + node.parent._remove(node); + }); // store history action + + editor._onAction('removeNodes', { + nodes: nodes, + paths: paths, + parentPath: parent.getInternalPath(), + index: firstIndex, + oldSelection: oldSelection, + newSelection: newSelection + }); + } +}; +/** + * Duplicate nodes + * duplicated nodes will be added right after the original nodes + * @param {Node[] | Node} nodes + */ + + +Node.onDuplicate = function (nodes) { + if (!Array.isArray(nodes)) { + return Node.onDuplicate([nodes]); + } + + if (nodes && nodes.length > 0) { + var lastNode = nodes[nodes.length - 1]; + var parent = lastNode.parent; + var editor = lastNode.editor; + editor.deselect(editor.multiselection.nodes); // duplicate the nodes + + var oldSelection = editor.getDomSelection(); + var afterNode = lastNode; + var clones = nodes.map(function (node) { + var clone = node.clone(); + + if (node.parent.type === 'object') { + var existingFieldNames = node.parent.getFieldNames(); + clone.field = (0,util.findUniqueName)(node.field, existingFieldNames); + } + + parent.insertAfter(clone, afterNode); + afterNode = clone; + return clone; + }); // set selection to the duplicated nodes + + if (nodes.length === 1) { + if (clones[0].parent.type === 'object') { + // when duplicating a single object property, + // set focus to the field and keep the original field name + clones[0].dom.field.innerHTML = nodes[0]._escapeHTML(nodes[0].field); + clones[0].focus('field'); + } else { + clones[0].focus(); + } + } else { + editor.select(clones); + } + + var newSelection = editor.getDomSelection(); + + editor._onAction('duplicateNodes', { + paths: nodes.map(getInternalPath), + clonePaths: clones.map(getInternalPath), + afterPath: lastNode.getInternalPath(), + parentPath: parent.getInternalPath(), + oldSelection: oldSelection, + newSelection: newSelection + }); + } +}; +/** + * Find the node from an event target + * @param {HTMLElement} target + * @return {Node | undefined} node or undefined when not found + * @static + */ + + +Node.getNodeFromTarget = function (target) { + while (target) { + if (target.node) { + return target.node; + } + + target = target.parentNode; + } + + return undefined; +}; +/** + * Test whether target is a child of the color DOM of a node + * @param {HTMLElement} target + * @returns {boolean} + */ + + +Node.targetIsColorPicker = function (target) { + var node = Node.getNodeFromTarget(target); + + if (node) { + var parent = target && target.parentNode; + + while (parent) { + if (parent === node.dom.color) { + return true; + } + + parent = parent.parentNode; + } + } + + return false; +}; +/** + * Remove the focus of given nodes, and move the focus to the (a) node before, + * (b) the node after, or (c) the parent node. + * @param {Array. | Node} nodes + */ + + +Node.blurNodes = function (nodes) { + if (!Array.isArray(nodes)) { + Node.blurNodes([nodes]); + return; + } + + var firstNode = nodes[0]; + var parent = firstNode.parent; + var firstIndex = firstNode.getIndex(); + + if (parent.childs[firstIndex + nodes.length]) { + parent.childs[firstIndex + nodes.length].focus(); + } else if (parent.childs[firstIndex - 1]) { + parent.childs[firstIndex - 1].focus(); + } else { + parent.focus(); + } +}; // helper function to get the internal path of a node + + +function getInternalPath(node) { + return node.getInternalPath(); +} // helper function to get the field of a node + + +function getField(node) { + return node.getField(); +} + +function Node_hasOwnProperty(object, key) { + return Object.prototype.hasOwnProperty.call(object, key); +} // TODO: find a nicer solution to resolve this circular dependency between Node and AppendNode +// idea: introduce properties .isAppendNode and .isNode and use that instead of instanceof AppendNode checks + + +var AppendNode = appendNodeFactory(Node); +var ShowMoreNode = showMoreNodeFactory(Node); +;// CONCATENATED MODULE: ./src/js/NodeHistory.js + + +function NodeHistory_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function NodeHistory_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function NodeHistory_createClass(Constructor, protoProps, staticProps) { if (protoProps) NodeHistory_defineProperties(Constructor.prototype, protoProps); if (staticProps) NodeHistory_defineProperties(Constructor, staticProps); return Constructor; } + + +/** + * @constructor History + * Store action history, enables undo and redo + * @param {JSONEditor} editor + */ + +var NodeHistory = /*#__PURE__*/function () { + function NodeHistory(editor) { + NodeHistory_classCallCheck(this, NodeHistory); + + this.editor = editor; + this.history = []; + this.index = -1; + this.clear(); // helper function to find a Node from a path + + function findNode(path) { + return editor.node.findNodeByInternalPath(path); + } // map with all supported actions + + + this.actions = { + editField: { + undo: function undo(params) { + var parentNode = findNode(params.parentPath); + var node = parentNode.childs[params.index]; + node.updateField(params.oldValue); + }, + redo: function redo(params) { + var parentNode = findNode(params.parentPath); + var node = parentNode.childs[params.index]; + node.updateField(params.newValue); + } + }, + editValue: { + undo: function undo(params) { + findNode(params.path).updateValue(params.oldValue); + }, + redo: function redo(params) { + findNode(params.path).updateValue(params.newValue); + } + }, + changeType: { + undo: function undo(params) { + findNode(params.path).changeType(params.oldType); + }, + redo: function redo(params) { + findNode(params.path).changeType(params.newType); + } + }, + appendNodes: { + undo: function undo(params) { + var parentNode = findNode(params.parentPath); + params.paths.map(findNode).forEach(function (node) { + parentNode.removeChild(node); + }); + }, + redo: function redo(params) { + var parentNode = findNode(params.parentPath); + params.nodes.forEach(function (node) { + parentNode.appendChild(node); + }); + } + }, + insertBeforeNodes: { + undo: function undo(params) { + var parentNode = findNode(params.parentPath); + params.paths.map(findNode).forEach(function (node) { + parentNode.removeChild(node); + }); + }, + redo: function redo(params) { + var parentNode = findNode(params.parentPath); + var beforeNode = findNode(params.beforePath); + params.nodes.forEach(function (node) { + parentNode.insertBefore(node, beforeNode); + }); + } + }, + insertAfterNodes: { + undo: function undo(params) { + var parentNode = findNode(params.parentPath); + params.paths.map(findNode).forEach(function (node) { + parentNode.removeChild(node); + }); + }, + redo: function redo(params) { + var parentNode = findNode(params.parentPath); + var afterNode = findNode(params.afterPath); + params.nodes.forEach(function (node) { + parentNode.insertAfter(node, afterNode); + afterNode = node; + }); + } + }, + removeNodes: { + undo: function undo(params) { + var parentNode = findNode(params.parentPath); + var beforeNode = parentNode.childs[params.index] || parentNode.append; + params.nodes.forEach(function (node) { + parentNode.insertBefore(node, beforeNode); + }); + }, + redo: function redo(params) { + var parentNode = findNode(params.parentPath); + params.paths.map(findNode).forEach(function (node) { + parentNode.removeChild(node); + }); + } + }, + duplicateNodes: { + undo: function undo(params) { + var parentNode = findNode(params.parentPath); + params.clonePaths.map(findNode).forEach(function (node) { + parentNode.removeChild(node); + }); + }, + redo: function redo(params) { + var parentNode = findNode(params.parentPath); + var afterNode = findNode(params.afterPath); + var nodes = params.paths.map(findNode); + nodes.forEach(function (node) { + var clone = node.clone(); + + if (parentNode.type === 'object') { + var existingFieldNames = parentNode.getFieldNames(); + clone.field = (0,util.findUniqueName)(node.field, existingFieldNames); + } + + parentNode.insertAfter(clone, afterNode); + afterNode = clone; + }); + } + }, + moveNodes: { + undo: function undo(params) { + var oldParentNode = findNode(params.oldParentPath); + var newParentNode = findNode(params.newParentPath); + var oldBeforeNode = oldParentNode.childs[params.oldIndex] || oldParentNode.append; // first copy the nodes, then move them + + var nodes = newParentNode.childs.slice(params.newIndex, params.newIndex + params.count); + nodes.forEach(function (node, index) { + node.field = params.fieldNames[index]; + oldParentNode.moveBefore(node, oldBeforeNode); + }); // This is a hack to work around an issue that we don't know tha original + // path of the new parent after dragging, as the node is already moved at that time. + + if (params.newParentPathRedo === null) { + params.newParentPathRedo = newParentNode.getInternalPath(); + } + }, + redo: function redo(params) { + var oldParentNode = findNode(params.oldParentPathRedo); + var newParentNode = findNode(params.newParentPathRedo); + var newBeforeNode = newParentNode.childs[params.newIndexRedo] || newParentNode.append; // first copy the nodes, then move them + + var nodes = oldParentNode.childs.slice(params.oldIndexRedo, params.oldIndexRedo + params.count); + nodes.forEach(function (node, index) { + node.field = params.fieldNames[index]; + newParentNode.moveBefore(node, newBeforeNode); + }); + } + }, + sort: { + undo: function undo(params) { + var node = findNode(params.path); + node.hideChilds(); + node.childs = params.oldChilds; + node.updateDom({ + updateIndexes: true + }); + node.showChilds(); + }, + redo: function redo(params) { + var node = findNode(params.path); + node.hideChilds(); + node.childs = params.newChilds; + node.updateDom({ + updateIndexes: true + }); + node.showChilds(); + } + }, + transform: { + undo: function undo(params) { + findNode(params.path).setInternalValue(params.oldValue); // TODO: would be nice to restore the state of the node and childs + }, + redo: function redo(params) { + findNode(params.path).setInternalValue(params.newValue); // TODO: would be nice to restore the state of the node and childs + } + } // TODO: restore the original caret position and selection with each undo + // TODO: implement history for actions "expand", "collapse", "scroll", "setDocument" + + }; + } + /** + * The method onChange is executed when the History is changed, and can + * be overloaded. + */ + + + NodeHistory_createClass(NodeHistory, [{ + key: "onChange", + value: function onChange() {} + /** + * Add a new action to the history + * @param {String} action The executed action. Available actions: "editField", + * "editValue", "changeType", "appendNode", + * "removeNode", "duplicateNode", "moveNode" + * @param {Object} params Object containing parameters describing the change. + * The parameters in params depend on the action (for + * example for "editValue" the Node, old value, and new + * value are provided). params contains all information + * needed to undo or redo the action. + */ + + }, { + key: "add", + value: function add(action, params) { + this.index++; + this.history[this.index] = { + action: action, + params: params, + timestamp: new Date() + }; // remove redo actions which are invalid now + + if (this.index < this.history.length - 1) { + this.history.splice(this.index + 1, this.history.length - this.index - 1); + } // fire onchange event + + + this.onChange(); + } + /** + * Clear history + */ + + }, { + key: "clear", + value: function clear() { + this.history = []; + this.index = -1; // fire onchange event + + this.onChange(); + } + /** + * Check if there is an action available for undo + * @return {Boolean} canUndo + */ + + }, { + key: "canUndo", + value: function canUndo() { + return this.index >= 0; + } + /** + * Check if there is an action available for redo + * @return {Boolean} canRedo + */ + + }, { + key: "canRedo", + value: function canRedo() { + return this.index < this.history.length - 1; + } + /** + * Undo the last action + */ + + }, { + key: "undo", + value: function undo() { + if (this.canUndo()) { + var obj = this.history[this.index]; + + if (obj) { + var action = this.actions[obj.action]; + + if (action && action.undo) { + action.undo(obj.params); + + if (obj.params.oldSelection) { + try { + this.editor.setDomSelection(obj.params.oldSelection); + } catch (err) { + console.error(err); + } + } + } else { + console.error(new Error('unknown action "' + obj.action + '"')); + } + } + + this.index--; // fire onchange event + + this.onChange(); + } + } + /** + * Redo the last action + */ + + }, { + key: "redo", + value: function redo() { + if (this.canRedo()) { + this.index++; + var obj = this.history[this.index]; + + if (obj) { + var action = this.actions[obj.action]; + + if (action && action.redo) { + action.redo(obj.params); + + if (obj.params.newSelection) { + try { + this.editor.setDomSelection(obj.params.newSelection); + } catch (err) { + console.error(err); + } + } + } else { + console.error(new Error('unknown action "' + obj.action + '"')); + } + } // fire onchange event + + + this.onChange(); + } + } + /** + * Destroy history + */ + + }, { + key: "destroy", + value: function destroy() { + this.editor = null; + this.history = []; + this.index = -1; + } + }]); + + return NodeHistory; +}(); +;// CONCATENATED MODULE: ./src/js/SearchBox.js + + +function SearchBox_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function SearchBox_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function SearchBox_createClass(Constructor, protoProps, staticProps) { if (protoProps) SearchBox_defineProperties(Constructor.prototype, protoProps); if (staticProps) SearchBox_defineProperties(Constructor, staticProps); return Constructor; } + + +/** + * @constructor SearchBox + * Create a search box in given HTML container + * @param {JSONEditor} editor The JSON Editor to attach to + * @param {Element} container HTML container element of where to + * create the search box + */ + +var SearchBox = /*#__PURE__*/function () { + function SearchBox(editor, container) { + SearchBox_classCallCheck(this, SearchBox); + + var searchBox = this; + this.editor = editor; + this.timeout = undefined; + this.delay = 200; // ms + + this.lastText = undefined; + this.results = null; + this.dom = {}; + this.dom.container = container; + var wrapper = document.createElement('div'); + this.dom.wrapper = wrapper; + wrapper.className = 'jsoneditor-search'; + container.appendChild(wrapper); + var results = document.createElement('div'); + this.dom.results = results; + results.className = 'jsoneditor-results'; + wrapper.appendChild(results); + var divInput = document.createElement('div'); + this.dom.input = divInput; + divInput.className = 'jsoneditor-frame'; + divInput.title = (0,i18n/* translate */.Iu)('searchTitle'); + wrapper.appendChild(divInput); + var refreshSearch = document.createElement('button'); + refreshSearch.type = 'button'; + refreshSearch.className = 'jsoneditor-refresh'; + divInput.appendChild(refreshSearch); + var search = document.createElement('input'); + search.type = 'text'; + this.dom.search = search; + + search.oninput = function (event) { + searchBox._onDelayedSearch(event); + }; + + search.onchange = function (event) { + // For IE 9 + searchBox._onSearch(); + }; + + search.onkeydown = function (event) { + searchBox._onKeyDown(event); + }; + + search.onkeyup = function (event) { + searchBox._onKeyUp(event); + }; + + refreshSearch.onclick = function (event) { + search.select(); + }; // TODO: ESC in FF restores the last input, is a FF bug, https://bugzilla.mozilla.org/show_bug.cgi?id=598819 + + + divInput.appendChild(search); + var searchNext = document.createElement('button'); + searchNext.type = 'button'; + searchNext.title = (0,i18n/* translate */.Iu)('searchNextResultTitle'); + searchNext.className = 'jsoneditor-next'; + + searchNext.onclick = function () { + searchBox.next(); + }; + + divInput.appendChild(searchNext); + var searchPrevious = document.createElement('button'); + searchPrevious.type = 'button'; + searchPrevious.title = (0,i18n/* translate */.Iu)('searchPreviousResultTitle'); + searchPrevious.className = 'jsoneditor-previous'; + + searchPrevious.onclick = function () { + searchBox.previous(); + }; + + divInput.appendChild(searchPrevious); + } + /** + * Go to the next search result + * @param {boolean} [focus] If true, focus will be set to the next result + * focus is false by default. + */ + + + SearchBox_createClass(SearchBox, [{ + key: "next", + value: function next(focus) { + if (this.results) { + var index = this.resultIndex !== null ? this.resultIndex + 1 : 0; + + if (index > this.results.length - 1) { + index = 0; + } + + this._setActiveResult(index, focus); + } + } + /** + * Go to the prevous search result + * @param {boolean} [focus] If true, focus will be set to the next result + * focus is false by default. + */ + + }, { + key: "previous", + value: function previous(focus) { + if (this.results) { + var max = this.results.length - 1; + var index = this.resultIndex !== null ? this.resultIndex - 1 : max; + + if (index < 0) { + index = max; + } + + this._setActiveResult(index, focus); + } + } + /** + * Set new value for the current active result + * @param {Number} index + * @param {boolean} [focus] If true, focus will be set to the next result. + * focus is false by default. + * @private + */ + + }, { + key: "_setActiveResult", + value: function _setActiveResult(index, focus) { + // de-activate current active result + if (this.activeResult) { + var prevNode = this.activeResult.node; + var prevElem = this.activeResult.elem; + + if (prevElem === 'field') { + delete prevNode.searchFieldActive; + } else { + delete prevNode.searchValueActive; + } + + prevNode.updateDom(); + } + + if (!this.results || !this.results[index]) { + // out of range, set to undefined + this.resultIndex = undefined; + this.activeResult = undefined; + return; + } + + this.resultIndex = index; // set new node active + + var node = this.results[this.resultIndex].node; + var elem = this.results[this.resultIndex].elem; + + if (elem === 'field') { + node.searchFieldActive = true; + } else { + node.searchValueActive = true; + } + + this.activeResult = this.results[this.resultIndex]; + node.updateDom(); // TODO: not so nice that the focus is only set after the animation is finished + + node.scrollTo(function () { + if (focus) { + node.focus(elem); + } + }); + } + /** + * Cancel any running onDelayedSearch. + * @private + */ + + }, { + key: "_clearDelay", + value: function _clearDelay() { + if (this.timeout !== undefined) { + clearTimeout(this.timeout); + delete this.timeout; + } + } + /** + * Start a timer to execute a search after a short delay. + * Used for reducing the number of searches while typing. + * @param {Event} event + * @private + */ + + }, { + key: "_onDelayedSearch", + value: function _onDelayedSearch(event) { + // execute the search after a short delay (reduces the number of + // search actions while typing in the search text box) + this._clearDelay(); + + var searchBox = this; + this.timeout = setTimeout(function (event) { + searchBox._onSearch(); + }, this.delay); + } + /** + * Handle onSearch event + * @param {boolean} [forceSearch] If true, search will be executed again even + * when the search text is not changed. + * Default is false. + * @private + */ + + }, { + key: "_onSearch", + value: function _onSearch(forceSearch) { + this._clearDelay(); + + var value = this.dom.search.value; + var text = value.length > 0 ? value : undefined; + + if (text !== this.lastText || forceSearch) { + // only search again when changed + this.lastText = text; + this.results = this.editor.search(text); + var MAX_SEARCH_RESULTS = this.results[0] ? this.results[0].node.MAX_SEARCH_RESULTS : Infinity; // try to maintain the current active result if this is still part of the new search results + + var activeResultIndex = 0; + + if (this.activeResult) { + for (var i = 0; i < this.results.length; i++) { + if (this.results[i].node === this.activeResult.node) { + activeResultIndex = i; + break; + } + } + } + + this._setActiveResult(activeResultIndex, false); // display search results + + + if (text !== undefined) { + var resultCount = this.results.length; + + if (resultCount === 0) { + this.dom.results.textContent = "no\xA0results"; + } else if (resultCount === 1) { + this.dom.results.textContent = "1\xA0result"; + } else if (resultCount > MAX_SEARCH_RESULTS) { + this.dom.results.textContent = MAX_SEARCH_RESULTS + "+\xA0results"; + } else { + this.dom.results.textContent = resultCount + "\xA0results"; + } + } else { + this.dom.results.textContent = ''; + } + } + } + /** + * Handle onKeyDown event in the input box + * @param {Event} event + * @private + */ + + }, { + key: "_onKeyDown", + value: function _onKeyDown(event) { + var keynum = event.which; + + if (keynum === 27) { + // ESC + this.dom.search.value = ''; // clear search + + this._onSearch(); + + event.preventDefault(); + event.stopPropagation(); + } else if (keynum === 13) { + // Enter + if (event.ctrlKey) { + // force to search again + this._onSearch(true); + } else if (event.shiftKey) { + // move to the previous search result + this.previous(); + } else { + // move to the next search result + this.next(); + } + + event.preventDefault(); + event.stopPropagation(); + } + } + /** + * Handle onKeyUp event in the input box + * @param {Event} event + * @private + */ + + }, { + key: "_onKeyUp", + value: function _onKeyUp(event) { + var keynum = event.keyCode; + + if (keynum !== 27 && keynum !== 13) { + // !show and !Enter + this._onDelayedSearch(event); // For IE 9 + + } + } + /** + * Clear the search results + */ + + }, { + key: "clear", + value: function clear() { + this.dom.search.value = ''; + + this._onSearch(); + } + /** + * Refresh searchResults if there is a search value + */ + + }, { + key: "forceSearch", + value: function forceSearch() { + this._onSearch(true); + } + /** + * Test whether the search box value is empty + * @returns {boolean} Returns true when empty. + */ + + }, { + key: "isEmpty", + value: function isEmpty() { + return this.dom.search.value === ''; + } + /** + * Destroy the search box + */ + + }, { + key: "destroy", + value: function destroy() { + this.editor = null; + this.dom.container.removeChild(this.dom.wrapper); + this.dom = null; + this.results = null; + this.activeResult = null; + + this._clearDelay(); + } + }]); + + return SearchBox; +}(); +;// CONCATENATED MODULE: ./src/js/TreePath.js + + +function TreePath_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function TreePath_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function TreePath_createClass(Constructor, protoProps, staticProps) { if (protoProps) TreePath_defineProperties(Constructor.prototype, protoProps); if (staticProps) TreePath_defineProperties(Constructor, staticProps); return Constructor; } + + + + +/** + * Creates a component that visualize path selection in tree based editors + * @param {HTMLElement} container + * @param {HTMLElement} root + * @constructor + */ + +var TreePath = /*#__PURE__*/function () { + function TreePath(container, root) { + TreePath_classCallCheck(this, TreePath); + + if (container) { + this.root = root; + this.path = document.createElement('div'); + this.path.className = 'jsoneditor-treepath'; + this.path.setAttribute('tabindex', 0); + this.contentMenuClicked = false; + container.appendChild(this.path); + this.reset(); + } + } + /** + * Reset component to initial status + */ + + + TreePath_createClass(TreePath, [{ + key: "reset", + value: function reset() { + this.path.textContent = (0,i18n/* translate */.Iu)('selectNode'); + } + /** + * Renders the component UI according to a given path objects + * @param {Array<{name: String, childs: Array}>} pathObjs a list of path objects + * + */ + + }, { + key: "setPath", + value: function setPath(pathObjs) { + var me = this; + this.path.textContent = ''; + + if (pathObjs && pathObjs.length) { + pathObjs.forEach(function (pathObj, idx) { + var pathEl = document.createElement('span'); + var sepEl; + pathEl.className = 'jsoneditor-treepath-element'; + pathEl.innerText = pathObj.name; + pathEl.onclick = _onSegmentClick.bind(me, pathObj); + me.path.appendChild(pathEl); + + if (pathObj.children.length) { + sepEl = document.createElement('span'); + sepEl.className = 'jsoneditor-treepath-seperator'; + sepEl.textContent = "\u25BA"; + + sepEl.onclick = function () { + me.contentMenuClicked = true; + var items = []; + pathObj.children.forEach(function (child) { + items.push({ + text: child.name, + className: 'jsoneditor-type-modes' + (pathObjs[idx + 1] + 1 && pathObjs[idx + 1].name === child.name ? ' jsoneditor-selected' : ''), + click: _onContextMenuItemClick.bind(me, pathObj, child.name) + }); + }); + var menu = new ContextMenu/* ContextMenu */.x(items, { + limitHeight: true + }); + menu.show(sepEl, me.root, true); + }; + + me.path.appendChild(sepEl); + } + + if (idx === pathObjs.length - 1) { + var leftRectPos = (sepEl || pathEl).getBoundingClientRect().right; + + if (me.path.offsetWidth < leftRectPos) { + me.path.scrollLeft = leftRectPos; + } + + if (me.path.scrollLeft) { + var showAllBtn = document.createElement('span'); + showAllBtn.className = 'jsoneditor-treepath-show-all-btn'; + showAllBtn.title = 'show all path'; + showAllBtn.textContent = '...'; + showAllBtn.onclick = _onShowAllClick.bind(me, pathObjs); + me.path.insertBefore(showAllBtn, me.path.firstChild); + } + } + }); + } + + function _onShowAllClick(pathObjs) { + me.contentMenuClicked = false; + (0,util.addClassName)(me.path, 'show-all'); + me.path.style.width = me.path.parentNode.getBoundingClientRect().width - 10 + 'px'; + + me.path.onblur = function () { + if (me.contentMenuClicked) { + me.contentMenuClicked = false; + me.path.focus(); + return; + } + + (0,util.removeClassName)(me.path, 'show-all'); + me.path.onblur = undefined; + me.path.style.width = ''; + me.setPath(pathObjs); + }; + } + + function _onSegmentClick(pathObj) { + if (this.selectionCallback) { + this.selectionCallback(pathObj); + } + } + + function _onContextMenuItemClick(pathObj, selection) { + if (this.contextMenuCallback) { + this.contextMenuCallback(pathObj, selection); + } + } + } + /** + * set a callback function for selection of path section + * @param {Function} callback function to invoke when section is selected + */ + + }, { + key: "onSectionSelected", + value: function onSectionSelected(callback) { + if (typeof callback === 'function') { + this.selectionCallback = callback; + } + } + /** + * set a callback function for selection of path section + * @param {Function} callback function to invoke when section is selected + */ + + }, { + key: "onContextMenuItemSelected", + value: function onContextMenuItemSelected(callback) { + if (typeof callback === 'function') { + this.contextMenuCallback = callback; + } + } + }]); + + return TreePath; +}(); +// EXTERNAL MODULE: ./src/js/vanilla-picker/index.js +var vanilla_picker = __webpack_require__(8037); +var vanilla_picker_default = /*#__PURE__*/__webpack_require__.n(vanilla_picker); +;// CONCATENATED MODULE: ./src/js/treemode.js + + + + + + + + + + + + + + + // create a mixin with the functions for tree mode + +var treemode = {}; +/** + * Create a tree editor + * @param {Element} container Container element + * @param {Object} [options] Object with options. See docs for details. + * @private + */ + +treemode.create = function (container, options) { + if (!container) { + throw new Error('No container element provided.'); + } + + this.container = container; + this.dom = {}; + this.highlighter = new Highlighter(); + this.selection = undefined; // will hold the last input selection + + this.multiselection = { + nodes: [] + }; + this.validateSchema = null; // will be set in .setSchema(schema) + + this.validationSequence = 0; + this.errorNodes = []; + this.lastSchemaErrors = undefined; + this.node = null; + this.focusTarget = null; + + this._setOptions(options); + + if (options.autocomplete) { + this.autocomplete = autocomplete(options.autocomplete); + } + + if (this.options.history && this.options.mode !== 'view') { + this.history = new NodeHistory(this); + } + + this._createFrame(); + + this._createTable(); +}; +/** + * Destroy the editor. Clean up DOM, event listeners, and web workers. + */ + + +treemode.destroy = function () { + if (this.frame && this.container && this.frame.parentNode === this.container) { + this.container.removeChild(this.frame); + this.frame = null; + } + + this.container = null; + this.dom = null; + this.clear(); + this.node = null; + this.focusTarget = null; + this.selection = null; + this.multiselection = null; + this.errorNodes = null; + this.validateSchema = null; + this._debouncedValidate = null; + + if (this.history) { + this.history.destroy(); + this.history = null; + } + + if (this.searchBox) { + this.searchBox.destroy(); + this.searchBox = null; + } + + if (this.modeSwitcher) { + this.modeSwitcher.destroy(); + this.modeSwitcher = null; + } // Removing the FocusTracker set to track the editor's focus event + + + this.frameFocusTracker.destroy(); +}; +/** + * Initialize and set default options + * @param {Object} [options] See description in constructor + * @private + */ + + +treemode._setOptions = function (options) { + var _this = this; + + this.options = { + search: true, + history: true, + mode: 'tree', + name: undefined, + // field name of root node + schema: null, + schemaRefs: null, + autocomplete: null, + navigationBar: true, + mainMenuBar: true, + limitDragging: false, + onSelectionChange: null, + colorPicker: true, + onColorPicker: function onColorPicker(parent, color, onChange) { + if ((vanilla_picker_default())) { + // we'll render the color picker on top + // when there is not enough space below, and there is enough space above + var pickerHeight = 300; // estimated height of the color picker + + var top = parent.getBoundingClientRect().top; + var windowHeight = (0,util.getWindow)(parent).innerHeight; + var showOnTop = windowHeight - top < pickerHeight && top > pickerHeight; + new (vanilla_picker_default())({ + parent: parent, + color: color, + popup: showOnTop ? 'top' : 'bottom', + onDone: function onDone(color) { + var alpha = color.rgba[3]; + var hex = alpha === 1 ? color.hex.substr(0, 7) // return #RRGGBB + : color.hex; // return #RRGGBBAA + + onChange(hex); + } + }).show(); + } else { + console.warn('Cannot open color picker: the `vanilla-picker` library is not included in the bundle. ' + 'Either use the full bundle or implement your own color picker using `onColorPicker`.'); + } + }, + timestampTag: true, + timestampFormat: null, + createQuery: jmespathQuery/* createQuery */.r, + executeQuery: jmespathQuery/* executeQuery */.J, + onEvent: null, + enableSort: true, + enableTransform: true + }; // copy all options + + if (options) { + Object.keys(options).forEach(function (prop) { + _this.options[prop] = options[prop]; + }); // default limitDragging to true when a JSON schema is defined + + if (options.limitDragging == null && options.schema != null) { + this.options.limitDragging = true; + } + } // compile a JSON schema validator if a JSON schema is provided + + + this.setSchema(this.options.schema, this.options.schemaRefs); // create a debounced validate function + + this._debouncedValidate = (0,util.debounce)(this.validate.bind(this), this.DEBOUNCE_INTERVAL); + + if (options.onSelectionChange) { + this.onSelectionChange(options.onSelectionChange); + } + + (0,i18n/* setLanguages */.cC)(this.options.languages); + (0,i18n/* setLanguage */.m0)(this.options.language); +}; +/** + * Set new JSON object in editor. + * Resets the state of the editor (expanded nodes, search, selection). + * + * @param {*} json + */ + + +treemode.set = function (json) { + // verify if json is valid JSON, ignore when a function + if (json instanceof Function || json === undefined) { + this.clear(); + } else { + this.content.removeChild(this.table); // Take the table offline + // replace the root node + + var params = { + field: this.options.name, + value: json + }; + var node = new Node(this, params); + + this._setRoot(node); // validate JSON schema (if configured) + + + this.validate(); // expand + + var recurse = false; + this.node.expand(recurse); + this.content.appendChild(this.table); // Put the table online again + } // TODO: maintain history, store last state and previous document + + + if (this.history) { + this.history.clear(); + } // clear search + + + if (this.searchBox) { + this.searchBox.clear(); + } +}; +/** + * Update JSON object in editor. + * Maintains the state of the editor (expanded nodes, search, selection). + * + * @param {*} json + */ + + +treemode.update = function (json) { + // don't update if there are no changes + if (this.node.deepEqual(json)) { + return; + } + + var selection = this.getSelection(); // apply the changed json + + this.onChangeDisabled = true; // don't fire an onChange event + + this.node.update(json); + this.onChangeDisabled = false; // validate JSON schema + + this.validate(); // update search result if any + + if (this.searchBox && !this.searchBox.isEmpty()) { + this.searchBox.forceSearch(); + } // update selection if any + + + if (selection && selection.start && selection.end) { + // only keep/update the selection if both start and end node still exists, + // else we clear the selection + var startNode = this.node.findNodeByPath(selection.start.path); + var endNode = this.node.findNodeByPath(selection.end.path); + + if (startNode && endNode) { + this.setSelection(selection.start, selection.end); + } else { + this.setSelection({}, {}); // clear selection + } + } else { + this.setSelection({}, {}); // clear selection + } +}; +/** + * Get JSON object from editor + * @return {Object | undefined} json + */ + + +treemode.get = function () { + // TODO: resolve pending debounced input changes if any, but do not resolve invalid inputs + if (this.node) { + return this.node.getValue(); + } else { + return undefined; + } +}; +/** + * Get the text contents of the editor + * @return {String} jsonText + */ + + +treemode.getText = function () { + return JSON.stringify(this.get()); +}; +/** + * Set the text contents of the editor. + * Resets the state of the editor (expanded nodes, search, selection). + * @param {String} jsonText + */ + + +treemode.setText = function (jsonText) { + try { + this.set((0,util.parse)(jsonText)); // this can throw an error + } catch (err) { + // try to repair json, replace JavaScript notation with JSON notation + var repairedJsonText = (0,util.tryJsonRepair)(jsonText); // try to parse again + + this.set((0,util.parse)(repairedJsonText)); // this can throw an error + } +}; +/** + * Update the text contents of the editor. + * Maintains the state of the editor (expanded nodes, search, selection). + * @param {String} jsonText + */ + + +treemode.updateText = function (jsonText) { + try { + this.update((0,util.parse)(jsonText)); // this can throw an error + } catch (err) { + // try to repair json, replace JavaScript notation with JSON notation + var repairJsonText = (0,util.tryJsonRepair)(jsonText); // try to parse again + + this.update((0,util.parse)(repairJsonText)); // this can throw an error + } +}; +/** + * Set a field name for the root node. + * @param {String | undefined} name + */ + + +treemode.setName = function (name) { + this.options.name = name; + + if (this.node) { + this.node.updateField(this.options.name); + } +}; +/** + * Get the field name for the root node. + * @return {String | undefined} name + */ + + +treemode.getName = function () { + return this.options.name; +}; +/** + * Set focus to the editor. Focus will be set to: + * - the first editable field or value, or else + * - to the expand button of the root node, or else + * - to the context menu button of the root node, or else + * - to the first button in the top menu + */ + + +treemode.focus = function () { + var input = this.scrollableContent.querySelector('[contenteditable=true]'); + + if (input) { + input.focus(); + } else if (this.node.dom.expand) { + this.node.dom.expand.focus(); + } else if (this.node.dom.menu) { + this.node.dom.menu.focus(); + } else { + // focus to the first button in the menu + input = this.frame.querySelector('button'); + + if (input) { + input.focus(); + } + } +}; +/** + * Remove the root node from the editor + */ + + +treemode.clear = function () { + if (this.node) { + this.node.hide(); + delete this.node; + } + + if (this.treePath) { + this.treePath.reset(); + } +}; +/** + * Set the root node for the json editor + * @param {Node} node + * @private + */ + + +treemode._setRoot = function (node) { + this.clear(); + this.node = node; + node.setParent(null); + node.setField(this.getName(), false); + delete node.index; // append to the dom + + this.tbody.appendChild(node.getDom()); +}; +/** + * Search text in all nodes + * The nodes will be expanded when the text is found one of its childs, + * else it will be collapsed. Searches are case insensitive. + * @param {String} text + * @return {Object[]} results Array with nodes containing the search results + * The result objects contains fields: + * - {Node} node, + * - {String} elem the dom element name where + * the result is found ('field' or + * 'value') + */ + + +treemode.search = function (text) { + var results; + + if (this.node) { + this.content.removeChild(this.table); // Take the table offline + + results = this.node.search(text); + this.content.appendChild(this.table); // Put the table online again + } else { + results = []; + } + + return results; +}; +/** + * Expand all nodes + */ + + +treemode.expandAll = function () { + if (this.node) { + this.content.removeChild(this.table); // Take the table offline + + this.node.expand(); + this.content.appendChild(this.table); // Put the table online again + } +}; +/** + * Collapse all nodes + */ + + +treemode.collapseAll = function () { + if (this.node) { + this.content.removeChild(this.table); // Take the table offline + + this.node.collapse(); + this.content.appendChild(this.table); // Put the table online again + } +}; +/** + * The method onChange is called whenever a field or value is changed, created, + * deleted, duplicated, etc. + * @param {String} action Change action. Available values: "editField", + * "editValue", "changeType", "appendNode", + * "removeNode", "duplicateNode", "moveNode", "expand", + * "collapse". + * @param {Object} params Object containing parameters describing the change. + * The parameters in params depend on the action (for + * example for "editValue" the Node, old value, and new + * value are provided). params contains all information + * needed to undo or redo the action. + * @private + */ + + +treemode._onAction = function (action, params) { + // add an action to the history + if (this.history) { + this.history.add(action, params); + } + + this._onChange(); +}; +/** + * Handle a change: + * - Validate JSON schema + * - Send a callback to the onChange listener if provided + * @private + */ + + +treemode._onChange = function () { + if (this.onChangeDisabled) { + return; + } // selection can be changed after undo/redo + + + this.selection = this.getDomSelection(); // validate JSON schema (if configured) + + this._debouncedValidate(); + + if (this.treePath) { + var selectedNode = this.node && this.selection ? this.node.findNodeByInternalPath(this.selection.path) : this.multiselection ? this.multiselection.nodes[0] : undefined; + + if (selectedNode) { + this._updateTreePath(selectedNode.getNodePath()); + } else { + this.treePath.reset(); + } + } // trigger the onChange callback + + + if (this.options.onChange) { + try { + this.options.onChange(); + } catch (err) { + console.error('Error in onChange callback: ', err); + } + } // trigger the onChangeJSON callback + + + if (this.options.onChangeJSON) { + try { + this.options.onChangeJSON(this.get()); + } catch (err) { + console.error('Error in onChangeJSON callback: ', err); + } + } // trigger the onChangeText callback + + + if (this.options.onChangeText) { + try { + this.options.onChangeText(this.getText()); + } catch (err) { + console.error('Error in onChangeText callback: ', err); + } + } // trigger the onClassName callback + + + if (this.options.onClassName) { + this.node.recursivelyUpdateCssClassesOnNodes(); + } // trigger the onNodeName callback + + + if (this.options.onNodeName && this.node.childs) { + try { + this.node.recursivelyUpdateNodeName(); + } catch (err) { + console.error('Error in onNodeName callback: ', err); + } + } +}; +/** + * Validate current JSON object against the configured JSON schema + * Throws an exception when no JSON schema is configured + */ + + +treemode.validate = function () { + var _this2 = this; + + var root = this.node; + + if (!root) { + // TODO: this should be redundant but is needed on mode switch + return; + } + + var json = root.getValue(); // execute JSON schema validation + + var schemaErrors = []; + + if (this.validateSchema) { + var valid = this.validateSchema(json); + + if (!valid) { + // apply all new errors + schemaErrors = this.validateSchema.errors.map(function (error) { + return (0,util.improveSchemaError)(error); + }).map(function findNode(error) { + return { + node: root.findNode(error.dataPath), + error: error, + type: 'validation' + }; + }).filter(function hasNode(entry) { + return entry.node != null; + }); + } + } // execute custom validation and after than merge and render all errors + + + try { + this.validationSequence++; + var me = this; + var seq = this.validationSequence; + + this._validateCustom(json).then(function (customValidationErrors) { + // only apply when there was no other validation started whilst resolving async results + if (seq === me.validationSequence) { + var errorNodes = [].concat(schemaErrors, customValidationErrors || []); + + me._renderValidationErrors(errorNodes); + + if (typeof _this2.options.onValidationError === 'function') { + if ((0,util.isValidationErrorChanged)(errorNodes, _this2.lastSchemaErrors)) { + _this2.options.onValidationError.call(_this2, errorNodes); + } + + _this2.lastSchemaErrors = errorNodes; + } + } + })["catch"](function (err) { + console.error(err); + }); + } catch (err) { + console.error(err); + } +}; + +treemode._renderValidationErrors = function (errorNodes) { + // clear all current errors + if (this.errorNodes) { + this.errorNodes.forEach(function (node) { + node.setError(null); + }); + } // render the new errors + + + var parentPairs = errorNodes.reduce(function (all, entry) { + return entry.node.findParents().filter(function (parent) { + return !all.some(function (pair) { + return pair[0] === parent; + }); + }).map(function (parent) { + return [parent, entry.node]; + }).concat(all); + }, []); + this.errorNodes = parentPairs.map(function (pair) { + return { + node: pair[0], + child: pair[1], + error: { + message: pair[0].type === 'object' ? (0,i18n/* translate */.Iu)('containsInvalidProperties') // object + : (0,i18n/* translate */.Iu)('containsInvalidItems') // array + + } + }; + }).concat(errorNodes).map(function setError(entry) { + entry.node.setError(entry.error, entry.child); + return entry.node; + }); +}; +/** + * Execute custom validation if configured. + * + * Returns a promise resolving with the custom errors (or nothing). + */ + + +treemode._validateCustom = function (json) { + try { + if (this.options.onValidate) { + var root = this.node; + var customValidateResults = this.options.onValidate(json); + var resultPromise = (0,util.isPromise)(customValidateResults) ? customValidateResults : Promise.resolve(customValidateResults); + return resultPromise.then(function (customValidationPathErrors) { + if (Array.isArray(customValidationPathErrors)) { + return customValidationPathErrors.filter(function (error) { + var valid = (0,util.isValidValidationError)(error); + + if (!valid) { + console.warn('Ignoring a custom validation error with invalid structure. ' + 'Expected structure: {path: [...], message: "..."}. ' + 'Actual error:', error); + } + + return valid; + }).map(function (error) { + var node; + + try { + node = error && error.path ? root.findNodeByPath(error.path) : null; + } catch (err) {// stay silent here, we throw a generic warning if no node is found + } + + if (!node) { + console.warn('Ignoring validation error: node not found. Path:', error.path, 'Error:', error); + } + + return { + node: node, + error: error, + type: 'customValidation' + }; + }).filter(function (entry) { + return entry && entry.node && entry.error && entry.error.message; + }); + } else { + return null; + } + }); + } + } catch (err) { + return Promise.reject(err); + } + + return Promise.resolve(null); +}; +/** + * Refresh the rendered contents + */ + + +treemode.refresh = function () { + if (this.node) { + this.node.updateDom({ + recurse: true + }); + } +}; +/** + * Start autoscrolling when given mouse position is above the top of the + * editor contents, or below the bottom. + * @param {Number} mouseY Absolute mouse position in pixels + */ + + +treemode.startAutoScroll = function (mouseY) { + var me = this; + var content = this.scrollableContent; + var top = (0,util.getAbsoluteTop)(content); + var height = content.clientHeight; + var bottom = top + height; + var margin = 24; + var interval = 50; // ms + + if (mouseY < top + margin && content.scrollTop > 0) { + this.autoScrollStep = (top + margin - mouseY) / 3; + } else if (mouseY > bottom - margin && height + content.scrollTop < content.scrollHeight) { + this.autoScrollStep = (bottom - margin - mouseY) / 3; + } else { + this.autoScrollStep = undefined; + } + + if (this.autoScrollStep) { + if (!this.autoScrollTimer) { + this.autoScrollTimer = setInterval(function () { + if (me.autoScrollStep) { + content.scrollTop -= me.autoScrollStep; + } else { + me.stopAutoScroll(); + } + }, interval); + } + } else { + this.stopAutoScroll(); + } +}; +/** + * Stop auto scrolling. Only applicable when scrolling + */ + + +treemode.stopAutoScroll = function () { + if (this.autoScrollTimer) { + clearTimeout(this.autoScrollTimer); + delete this.autoScrollTimer; + } + + if (this.autoScrollStep) { + delete this.autoScrollStep; + } +}; +/** + * Set the focus to an element in the editor, set text selection, and + * set scroll position. + * @param {Object} selection An object containing fields: + * {Element | undefined} dom The dom element + * which has focus + * {Range | TextRange} range A text selection + * {Node[]} nodes Nodes in case of multi selection + * {Number} scrollTop Scroll position + */ + + +treemode.setDomSelection = function (selection) { + if (!selection) { + return; + } + + if ('scrollTop' in selection && this.scrollableContent) { + // TODO: animated scroll + this.scrollableContent.scrollTop = selection.scrollTop; + } + + if (selection.paths) { + // multi-select + var me = this; + var nodes = selection.paths.map(function (path) { + return me.node.findNodeByInternalPath(path); + }); + this.select(nodes); + } else { + // find the actual DOM element where to apply the focus + var node = selection.path ? this.node.findNodeByInternalPath(selection.path) : null; + var container = node && selection.domName ? node.dom[selection.domName] : null; + + if (selection.range && container) { + var range = Object.assign({}, selection.range, { + container: container + }); + (0,util.setSelectionOffset)(range); + } else if (node) { + // just a fallback + node.focus(); + } + } +}; +/** + * Get the current focus + * @return {Object} selection An object containing fields: + * {Element | undefined} dom The dom element + * which has focus + * {Range | TextRange} range A text selection + * {Node[]} nodes Nodes in case of multi selection + * {Number} scrollTop Scroll position + */ + + +treemode.getDomSelection = function () { + // find the node and field name of the current target, + // so we can store the current selection in a serializable + // way (internal node path and domName) + var node = Node.getNodeFromTarget(this.focusTarget); + var focusTarget = this.focusTarget; + var domName = node ? Object.keys(node.dom).find(function (domName) { + return node.dom[domName] === focusTarget; + }) : null; + var range = (0,util.getSelectionOffset)(); + + if (range && range.container.nodeName !== 'DIV') { + // filter on (editable) divs) + range = null; + } + + if (range && range.container !== focusTarget) { + range = null; + } + + if (range) { + // we cannot rely on the current instance of the container, + // we need to store the internal node path and field and + // find the actual DOM field when applying the selection + delete range.container; + } + + return { + path: node ? node.getInternalPath() : null, + domName: domName, + range: range, + paths: this.multiselection.length > 0 ? this.multiselection.nodes.map(function (node) { + return node.getInternalPath(); + }) : null, + scrollTop: this.scrollableContent ? this.scrollableContent.scrollTop : 0 + }; +}; +/** + * Adjust the scroll position such that given top position is shown at 1/4 + * of the window height. + * @param {Number} top + * @param {function(boolean)} [animateCallback] Callback, executed when animation is + * finished. The callback returns true + * when animation is finished, or false + * when not. + */ + + +treemode.scrollTo = function (top, animateCallback) { + var content = this.scrollableContent; + + if (content) { + var editor = this; // cancel any running animation + + if (editor.animateTimeout) { + clearTimeout(editor.animateTimeout); + delete editor.animateTimeout; + } + + if (editor.animateCallback) { + editor.animateCallback(false); + delete editor.animateCallback; + } // calculate final scroll position + + + var height = content.clientHeight; + var bottom = content.scrollHeight - height; + var finalScrollTop = Math.min(Math.max(top - height / 4, 0), bottom); // animate towards the new scroll position + + var animate = function animate() { + var scrollTop = content.scrollTop; + var diff = finalScrollTop - scrollTop; + + if (Math.abs(diff) > 3) { + content.scrollTop += diff / 3; + editor.animateCallback = animateCallback; + editor.animateTimeout = setTimeout(animate, 50); + } else { + // finished + if (animateCallback) { + animateCallback(true); + } + + content.scrollTop = finalScrollTop; + delete editor.animateTimeout; + delete editor.animateCallback; + } + }; + + animate(); + } else { + if (animateCallback) { + animateCallback(false); + } + } +}; +/** + * Create main frame + * @private + */ + + +treemode._createFrame = function () { + // create the frame + this.frame = document.createElement('div'); + this.frame.className = 'jsoneditor jsoneditor-mode-' + this.options.mode; // this.frame.setAttribute("tabindex","0"); + + this.container.appendChild(this.frame); + this.contentOuter = document.createElement('div'); + this.contentOuter.className = 'jsoneditor-outer'; // create one global event listener to handle all events from all nodes + + var editor = this; + + function onEvent(event) { + // when switching to mode "code" or "text" via the menu, some events + // are still fired whilst the _onEvent methods is already removed. + if (editor._onEvent) { + editor._onEvent(event); + } + } // setting the FocusTracker on 'this.frame' to track the editor's focus event + + + var focusTrackerConfig = { + target: this.frame, + onFocus: this.options.onFocus || null, + onBlur: this.options.onBlur || null + }; + this.frameFocusTracker = new FocusTracker/* FocusTracker */.R(focusTrackerConfig); + + this.frame.onclick = function (event) { + var target = event.target; // || event.srcElement; + + onEvent(event); // prevent default submit action of buttons when editor is located + // inside a form + + if (target.nodeName === 'BUTTON') { + event.preventDefault(); + } + }; + + this.frame.oninput = onEvent; + this.frame.onchange = onEvent; + this.frame.onkeydown = onEvent; + this.frame.onkeyup = onEvent; + this.frame.oncut = onEvent; + this.frame.onpaste = onEvent; + this.frame.onmousedown = onEvent; + this.frame.onmouseup = onEvent; + this.frame.onmouseover = onEvent; + this.frame.onmouseout = onEvent; // Note: focus and blur events do not propagate, therefore they defined + // using an eventListener with useCapture=true + // see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html + + (0,util.addEventListener)(this.frame, 'focus', onEvent, true); + (0,util.addEventListener)(this.frame, 'blur', onEvent, true); + this.frame.onfocusin = onEvent; // for IE + + this.frame.onfocusout = onEvent; // for IE + + if (this.options.mainMenuBar) { + (0,util.addClassName)(this.contentOuter, 'has-main-menu-bar'); // create menu + + this.menu = document.createElement('div'); + this.menu.className = 'jsoneditor-menu'; + this.frame.appendChild(this.menu); // create expand all button + + var expandAll = document.createElement('button'); + expandAll.type = 'button'; + expandAll.className = 'jsoneditor-expand-all'; + expandAll.title = (0,i18n/* translate */.Iu)('expandAll'); + + expandAll.onclick = function () { + editor.expandAll(); + }; + + this.menu.appendChild(expandAll); // create collapse all button + + var collapseAll = document.createElement('button'); + collapseAll.type = 'button'; + collapseAll.title = (0,i18n/* translate */.Iu)('collapseAll'); + collapseAll.className = 'jsoneditor-collapse-all'; + + collapseAll.onclick = function () { + editor.collapseAll(); + }; + + this.menu.appendChild(collapseAll); // create sort button + + if (this.options.enableSort) { + var sort = document.createElement('button'); + sort.type = 'button'; + sort.className = 'jsoneditor-sort'; + sort.title = (0,i18n/* translate */.Iu)('sortTitleShort'); + + sort.onclick = function () { + editor.node.showSortModal(); + }; + + this.menu.appendChild(sort); + } // create transform button + + + if (this.options.enableTransform) { + var transform = document.createElement('button'); + transform.type = 'button'; + transform.title = (0,i18n/* translate */.Iu)('transformTitleShort'); + transform.className = 'jsoneditor-transform'; + + transform.onclick = function () { + editor.node.showTransformModal(); + }; + + this.menu.appendChild(transform); + } // create undo/redo buttons + + + if (this.history) { + // create undo button + var undo = document.createElement('button'); + undo.type = 'button'; + undo.className = 'jsoneditor-undo jsoneditor-separator'; + undo.title = (0,i18n/* translate */.Iu)('undo'); + + undo.onclick = function () { + editor._onUndo(); + }; + + this.menu.appendChild(undo); + this.dom.undo = undo; // create redo button + + var redo = document.createElement('button'); + redo.type = 'button'; + redo.className = 'jsoneditor-redo'; + redo.title = (0,i18n/* translate */.Iu)('redo'); + + redo.onclick = function () { + editor._onRedo(); + }; + + this.menu.appendChild(redo); + this.dom.redo = redo; // register handler for onchange of history + + this.history.onChange = function () { + undo.disabled = !editor.history.canUndo(); + redo.disabled = !editor.history.canRedo(); + }; + + this.history.onChange(); + } // create mode box + + + if (this.options && this.options.modes && this.options.modes.length) { + var me = this; + this.modeSwitcher = new ModeSwitcher/* ModeSwitcher */.x(this.menu, this.options.modes, this.options.mode, function onSwitch(mode) { + // switch mode and restore focus + me.setMode(mode); + me.modeSwitcher.focus(); + }); + } // create search box + + + if (this.options.search) { + this.searchBox = new SearchBox(this, this.menu); + } + } + + if (this.options.navigationBar) { + // create second menu row for treepath + this.navBar = document.createElement('div'); + this.navBar.className = 'jsoneditor-navigation-bar nav-bar-empty'; + this.frame.appendChild(this.navBar); + this.treePath = new TreePath(this.navBar, this.getPopupAnchor()); + this.treePath.onSectionSelected(this._onTreePathSectionSelected.bind(this)); + this.treePath.onContextMenuItemSelected(this._onTreePathMenuItemSelected.bind(this)); + } +}; +/** + * Perform an undo action + * @private + */ + + +treemode._onUndo = function () { + if (this.history) { + // undo last action + this.history.undo(); // fire change event + + this._onChange(); + } +}; +/** + * Perform a redo action + * @private + */ + + +treemode._onRedo = function () { + if (this.history) { + // redo last action + this.history.redo(); // fire change event + + this._onChange(); + } +}; +/** + * Event handler + * @param event + * @private + */ + + +treemode._onEvent = function (event) { + // don't process events when coming from the color picker + if (Node.targetIsColorPicker(event.target)) { + return; + } + + var node = Node.getNodeFromTarget(event.target); + + if (event.type === 'keydown') { + this._onKeyDown(event); + } + + if (node && event.type === 'focus') { + this.focusTarget = event.target; + + if (this.options.autocomplete && this.options.autocomplete.trigger === 'focus') { + this._showAutoComplete(event.target); + } + } + + if (event.type === 'mousedown') { + this._startDragDistance(event); + } + + if (event.type === 'mousemove' || event.type === 'mouseup' || event.type === 'click') { + this._updateDragDistance(event); + } + + if (node && this.options && this.options.navigationBar && node && (event.type === 'keydown' || event.type === 'mousedown')) { + // apply on next tick, right after the new key press is applied + var me = this; + setTimeout(function () { + me._updateTreePath(node.getNodePath()); + }); + } + + if (node && node.selected) { + if (event.type === 'click') { + if (event.target === node.dom.menu) { + this.showContextMenu(event.target); // stop propagation (else we will open the context menu of a single node) + + return; + } // deselect a multi selection + + + if (!event.hasMoved) { + this.deselect(); + } + } + + if (event.type === 'mousedown') { + // drag multiple nodes + Node.onDragStart(this.multiselection.nodes, event); + } + } else { + // filter mouse events in the contents part of the editor (not the main menu) + if (event.type === 'mousedown' && (0,util.hasParentNode)(event.target, this.content)) { + this.deselect(); + + if (node && event.target === node.dom.drag) { + // drag a singe node + Node.onDragStart(node, event); + } else if (!node || event.target !== node.dom.field && event.target !== node.dom.value && event.target !== node.dom.select) { + // select multiple nodes + this._onMultiSelectStart(event); + } + } + } + + if (node) { + node.onEvent(event); + } +}; +/** + * Update TreePath components + * @param {Array} pathNodes list of nodes in path from root to selection + * @private + */ + + +treemode._updateTreePath = function (pathNodes) { + if (pathNodes && pathNodes.length) { + (0,util.removeClassName)(this.navBar, 'nav-bar-empty'); + var pathObjs = []; + pathNodes.forEach(function (node) { + var pathObj = { + name: getName(node), + node: node, + children: [] + }; + + if (node.childs && node.childs.length) { + node.childs.forEach(function (childNode) { + pathObj.children.push({ + name: getName(childNode), + node: childNode + }); + }); + } + + pathObjs.push(pathObj); + }); + this.treePath.setPath(pathObjs); + } else { + (0,util.addClassName)(this.navBar, 'nav-bar-empty'); + } + + function getName(node) { + return node.parent ? node.parent.type === 'array' ? node.index : node.field : node.field || node.type; + } +}; +/** + * Callback for tree path section selection - focus the selected node in the tree + * @param {Object} pathObj path object that was represents the selected section node + * @private + */ + + +treemode._onTreePathSectionSelected = function (pathObj) { + if (pathObj && pathObj.node) { + pathObj.node.expandTo(); + pathObj.node.focus(); + } +}; +/** + * Callback for tree path menu item selection - rebuild the path accrding to the new selection and focus the selected node in the tree + * @param {Object} pathObj path object that was represents the parent section node + * @param {String} selection selected section child + * @private + */ + + +treemode._onTreePathMenuItemSelected = function (pathObj, selection) { + if (pathObj && pathObj.children.length) { + var selectionObj = pathObj.children.find(function (obj) { + return obj.name === selection; + }); + + if (selectionObj && selectionObj.node) { + this._updateTreePath(selectionObj.node.getNodePath()); + + selectionObj.node.expandTo(); + selectionObj.node.focus(); + } + } +}; + +treemode._startDragDistance = function (event) { + this.dragDistanceEvent = { + initialTarget: event.target, + initialPageX: event.pageX, + initialPageY: event.pageY, + dragDistance: 0, + hasMoved: false + }; +}; + +treemode._updateDragDistance = function (event) { + if (!this.dragDistanceEvent) { + this._startDragDistance(event); + } + + var diffX = event.pageX - this.dragDistanceEvent.initialPageX; + var diffY = event.pageY - this.dragDistanceEvent.initialPageY; + this.dragDistanceEvent.dragDistance = Math.sqrt(diffX * diffX + diffY * diffY); + this.dragDistanceEvent.hasMoved = this.dragDistanceEvent.hasMoved || this.dragDistanceEvent.dragDistance > 10; + event.dragDistance = this.dragDistanceEvent.dragDistance; + event.hasMoved = this.dragDistanceEvent.hasMoved; + return event.dragDistance; +}; +/** + * Start multi selection of nodes by dragging the mouse + * @param {MouseEvent} event + * @private + */ + + +treemode._onMultiSelectStart = function (event) { + var node = Node.getNodeFromTarget(event.target); + + if (this.options.mode !== 'tree' || this.options.onEditable !== undefined) { + // dragging not allowed in modes 'view' and 'form' + // TODO: allow multiselection of items when option onEditable is specified + return; + } + + this.multiselection = { + start: node || null, + end: null, + nodes: [] + }; + + this._startDragDistance(event); + + var editor = this; + + if (!this.mousemove) { + this.mousemove = (0,util.addEventListener)(event.view, 'mousemove', function (event) { + editor._onMultiSelect(event); + }); + } + + if (!this.mouseup) { + this.mouseup = (0,util.addEventListener)(event.view, 'mouseup', function (event) { + editor._onMultiSelectEnd(event); + }); + } + + event.preventDefault(); +}; +/** + * Multiselect nodes by dragging + * @param {MouseEvent} event + * @private + */ + + +treemode._onMultiSelect = function (event) { + event.preventDefault(); + + this._updateDragDistance(event); + + if (!event.hasMoved) { + return; + } + + var node = Node.getNodeFromTarget(event.target); + + if (node) { + if (this.multiselection.start == null) { + this.multiselection.start = node; + } + + this.multiselection.end = node; + } // deselect previous selection + + + this.deselect(); // find the selected nodes in the range from first to last + + var start = this.multiselection.start; + var end = this.multiselection.end || this.multiselection.start; + + if (start && end) { + // find the top level childs, all having the same parent + this.multiselection.nodes = this._findTopLevelNodes(start, end); + + if (this.multiselection.nodes && this.multiselection.nodes.length) { + var firstNode = this.multiselection.nodes[0]; + + if (this.multiselection.start === firstNode || this.multiselection.start.isDescendantOf(firstNode)) { + this.multiselection.direction = 'down'; + } else { + this.multiselection.direction = 'up'; + } + } + + this.select(this.multiselection.nodes); + } +}; +/** + * End of multiselect nodes by dragging + * @param {MouseEvent} event + * @private + */ + + +treemode._onMultiSelectEnd = function (event) { + // set focus to the context menu button of the first node + if (this.multiselection.nodes[0]) { + this.multiselection.nodes[0].dom.menu.focus(); + } + + this.multiselection.start = null; + this.multiselection.end = null; // cleanup global event listeners + + if (this.mousemove) { + (0,util.removeEventListener)(event.view, 'mousemove', this.mousemove); + delete this.mousemove; + } + + if (this.mouseup) { + (0,util.removeEventListener)(event.view, 'mouseup', this.mouseup); + delete this.mouseup; + } +}; +/** + * deselect currently selected nodes + * @param {boolean} [clearStartAndEnd=false] If true, the `start` and `end` + * state is cleared too. + */ + + +treemode.deselect = function (clearStartAndEnd) { + var selectionChanged = !!this.multiselection.nodes.length; + this.multiselection.nodes.forEach(function (node) { + node.setSelected(false); + }); + this.multiselection.nodes = []; + + if (clearStartAndEnd) { + this.multiselection.start = null; + this.multiselection.end = null; + } + + if (selectionChanged) { + if (this._selectionChangedHandler) { + this._selectionChangedHandler(); + } + } +}; +/** + * select nodes + * @param {Node[] | Node} nodes + */ + + +treemode.select = function (nodes) { + if (!Array.isArray(nodes)) { + return this.select([nodes]); + } + + if (nodes) { + this.deselect(); + this.multiselection.nodes = nodes.slice(0); + var first = nodes[0]; + nodes.forEach(function (node) { + node.expandPathToNode(); + node.setSelected(true, node === first); + }); + + if (this._selectionChangedHandler) { + var selection = this.getSelection(); + + this._selectionChangedHandler(selection.start, selection.end); + } + } +}; +/** + * From two arbitrary selected nodes, find their shared parent node. + * From that parent node, select the two child nodes in the brances going to + * nodes `start` and `end`, and select all childs in between. + * @param {Node} start + * @param {Node} end + * @return {Array.} Returns an ordered list with child nodes + * @private + */ + + +treemode._findTopLevelNodes = function (start, end) { + var startPath = start.getNodePath(); + var endPath = end.getNodePath(); + var i = 0; + + while (i < startPath.length && startPath[i] === endPath[i]) { + i++; + } + + var root = startPath[i - 1]; + var startChild = startPath[i]; + var endChild = endPath[i]; + + if (!startChild || !endChild) { + if (root.parent) { + // startChild is a parent of endChild or vice versa + startChild = root; + endChild = root; + root = root.parent; + } else { + // we have selected the root node (which doesn't have a parent) + startChild = root.childs[0]; + endChild = root.childs[root.childs.length - 1]; + } + } + + if (root && startChild && endChild) { + var startIndex = root.childs.indexOf(startChild); + var endIndex = root.childs.indexOf(endChild); + var firstIndex = Math.min(startIndex, endIndex); + var lastIndex = Math.max(startIndex, endIndex); + return root.childs.slice(firstIndex, lastIndex + 1); + } else { + return []; + } +}; +/** + * Show autocomplete menu + * @param {HTMLElement} element + * @private + */ + + +treemode._showAutoComplete = function (element) { + var node = Node.getNodeFromTarget(element); + var jsonElementType = ''; + if (element.className.indexOf('jsoneditor-value') >= 0) jsonElementType = 'value'; + if (element.className.indexOf('jsoneditor-field') >= 0) jsonElementType = 'field'; + + if (jsonElementType === '') { + // Unknown element field. Could be a button or something else + return; + } + + var self = this; + setTimeout(function () { + if (node && (self.options.autocomplete.trigger === 'focus' || element.innerText.length > 0)) { + var result = self.options.autocomplete.getOptions(element.innerText, node.getPath(), jsonElementType, node.editor); + + if (result === null) { + self.autocomplete.hideDropDown(); + } else if (typeof result.then === 'function') { + // probably a promise + result.then(function (obj) { + if (obj === null) { + self.autocomplete.hideDropDown(); + } else if (obj.options) { + self.autocomplete.show(element, obj.startFrom, obj.options); + } else { + self.autocomplete.show(element, 0, obj); + } + })["catch"](function (err) { + console.error(err); + }); + } else { + // definitely not a promise + if (result.options) { + self.autocomplete.show(element, result.startFrom, result.options); + } else { + self.autocomplete.show(element, 0, result); + } + } + } else { + self.autocomplete.hideDropDown(); + } + }, 50); +}; +/** + * Event handler for keydown. Handles shortcut keys + * @param {Event} event + * @private + */ + + +treemode._onKeyDown = function (event) { + var keynum = event.which || event.keyCode; + var altKey = event.altKey; + var ctrlKey = event.ctrlKey; + var metaKey = event.metaKey; + var shiftKey = event.shiftKey; + var handled = false; + var currentTarget = this.focusTarget; + + if (keynum === 9) { + // Tab or Shift+Tab + var me = this; + setTimeout(function () { + /* + - Checking for change in focusTarget + - Without the check, + pressing tab after reaching the final DOM element in the editor will + set the focus back to it than passing focus outside the editor + */ + if (me.focusTarget !== currentTarget) { + // select all text when moving focus to an editable div + (0,util.selectContentEditable)(me.focusTarget); + } + }, 0); + } + + if (this.searchBox) { + if (ctrlKey && keynum === 70) { + // Ctrl+F + this.searchBox.dom.search.focus(); + this.searchBox.dom.search.select(); + handled = true; + } else if (keynum === 114 || ctrlKey && keynum === 71) { + // F3 or Ctrl+G + var focus = true; + + if (!shiftKey) { + // select next search result (F3 or Ctrl+G) + this.searchBox.next(focus); + } else { + // select previous search result (Shift+F3 or Ctrl+Shift+G) + this.searchBox.previous(focus); + } + + handled = true; + } + } + + if (this.history) { + if (ctrlKey && !shiftKey && keynum === 90) { + // Ctrl+Z + // undo + this._onUndo(); + + handled = true; + } else if (ctrlKey && shiftKey && keynum === 90) { + // Ctrl+Shift+Z + // redo + this._onRedo(); + + handled = true; + } + } + + if (this.options.autocomplete && !handled) { + if (!ctrlKey && !altKey && !metaKey && (event.key.length === 1 || keynum === 8 || keynum === 46)) { + handled = false; // Activate autocomplete + + this._showAutoComplete(event.target); + } + } + + if (handled) { + event.preventDefault(); + event.stopPropagation(); + } +}; +/** + * Create main table + * @private + */ + + +treemode._createTable = function () { + if (this.options.navigationBar) { + (0,util.addClassName)(this.contentOuter, 'has-nav-bar'); + } + + this.scrollableContent = document.createElement('div'); + this.scrollableContent.className = 'jsoneditor-tree'; + this.contentOuter.appendChild(this.scrollableContent); // the jsoneditor-tree-inner div with bottom padding is here to + // keep space for the action menu dropdown. It's created as a + // separate div instead of using scrollableContent to work around + // and issue in the Chrome browser showing scrollable contents outside of the div + // see https://github.com/josdejong/jsoneditor/issues/557 + + this.content = document.createElement('div'); + this.content.className = 'jsoneditor-tree-inner'; + this.scrollableContent.appendChild(this.content); + this.table = document.createElement('table'); + this.table.className = 'jsoneditor-tree'; + this.content.appendChild(this.table); // create colgroup where the first two columns don't have a fixed + // width, and the edit columns do have a fixed width + + var col; + this.colgroupContent = document.createElement('colgroup'); + + if (this.options.mode === 'tree') { + col = document.createElement('col'); + col.width = '24px'; + this.colgroupContent.appendChild(col); + } + + col = document.createElement('col'); + col.width = '24px'; + this.colgroupContent.appendChild(col); + col = document.createElement('col'); + this.colgroupContent.appendChild(col); + this.table.appendChild(this.colgroupContent); + this.tbody = document.createElement('tbody'); + this.table.appendChild(this.tbody); + this.frame.appendChild(this.contentOuter); +}; +/** + * Show a contextmenu for this node. + * Used for multiselection + * @param {HTMLElement} anchor Anchor element to attach the context menu to. + * @param {function} [onClose] Callback method called when the context menu + * is being closed. + */ + + +treemode.showContextMenu = function (anchor, onClose) { + var items = []; + var selectedNodes = this.multiselection.nodes.slice(); // create duplicate button + + items.push({ + text: (0,i18n/* translate */.Iu)('duplicateText'), + title: (0,i18n/* translate */.Iu)('duplicateTitle'), + className: 'jsoneditor-duplicate', + click: function click() { + Node.onDuplicate(selectedNodes); + } + }); // create remove button + + items.push({ + text: (0,i18n/* translate */.Iu)('remove'), + title: (0,i18n/* translate */.Iu)('removeTitle'), + className: 'jsoneditor-remove', + click: function click() { + Node.onRemove(selectedNodes); + } + }); + + if (this.options.onCreateMenu) { + var paths = selectedNodes.map(function (node) { + return node.getPath(); + }); + items = this.options.onCreateMenu(items, { + type: 'multiple', + path: paths[0], + paths: paths + }); + } + + var menu = new ContextMenu/* ContextMenu */.x(items, { + close: onClose + }); + menu.show(anchor, this.getPopupAnchor()); +}; + +treemode.getPopupAnchor = function () { + return this.options.popupAnchor || this.frame; +}; +/** + * Get current selected nodes + * @return {{start:SerializableNode, end: SerializableNode}} + */ + + +treemode.getSelection = function () { + var selection = { + start: null, + end: null + }; + + if (this.multiselection.nodes && this.multiselection.nodes.length) { + if (this.multiselection.nodes.length) { + var selection1 = this.multiselection.nodes[0]; + var selection2 = this.multiselection.nodes[this.multiselection.nodes.length - 1]; + + if (this.multiselection.direction === 'down') { + selection.start = selection1.serialize(); + selection.end = selection2.serialize(); + } else { + selection.start = selection2.serialize(); + selection.end = selection1.serialize(); + } + } + } + + return selection; +}; +/** + * Callback registration for selection change + * @param {selectionCallback} callback + * + * @callback selectionCallback + */ + + +treemode.onSelectionChange = function (callback) { + if (typeof callback === 'function') { + this._selectionChangedHandler = (0,util.debounce)(callback, this.DEBOUNCE_INTERVAL); + } +}; +/** + * Select range of nodes. + * For selecting single node send only the start parameter + * For clear the selection do not send any parameter + * If the nodes are not from the same level the first common parent will be selected + * @param {{path: Array.}} start object contains the path for selection start + * @param {{path: Array.}} end object contains the path for selection end + */ + + +treemode.setSelection = function (start, end) { + // check for old usage + if (start && start.dom && start.range) { + console.warn('setSelection/getSelection usage for text selection is deprecated and should not be used, see documentation for supported selection options'); + this.setDomSelection(start); + } + + var nodes = this._getNodeInstancesByRange(start, end); + + nodes.forEach(function (node) { + node.expandTo(); + }); + this.select(nodes); +}; +/** + * Returns a set of Nodes according to a range of selection + * @param {{path: Array.}} start object contains the path for range start + * @param {{path: Array.}=} end object contains the path for range end + * @return {Array.} Node instances on the given range + * @private + */ + + +treemode._getNodeInstancesByRange = function (start, end) { + var startNode, endNode; + + if (start && start.path) { + startNode = this.node.findNodeByPath(start.path); + + if (end && end.path) { + endNode = this.node.findNodeByPath(end.path); + } + } + + var nodes = []; + + if (startNode instanceof Node) { + if (endNode instanceof Node && endNode !== startNode) { + if (startNode.parent === endNode.parent) { + if (startNode.getIndex() < endNode.getIndex()) { + start = startNode; + end = endNode; + } else { + start = endNode; + end = startNode; + } + + var current = start; + nodes.push(current); + + do { + current = current.nextSibling(); + nodes.push(current); + } while (current && current !== end); + } else { + nodes = this._findTopLevelNodes(startNode, endNode); + } + } else { + nodes.push(startNode); + } + } + + return nodes; +}; + +treemode.getNodesByRange = function (start, end) { + var nodes = this._getNodeInstancesByRange(start, end); + + var serializableNodes = []; + nodes.forEach(function (node) { + serializableNodes.push(node.serialize()); + }); + return serializableNodes; +}; // define modes + + +var treeModeMixins = [{ + mode: 'tree', + mixin: treemode, + data: 'json' +}, { + mode: 'view', + mixin: treemode, + data: 'json' +}, { + mode: 'form', + mixin: treemode, + data: 'json' +}]; + +/***/ }), + +/***/ 2744: +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + +exports.tryRequireAjv = function () { + try { + return __webpack_require__(8903); + } catch (err) {// no problem... when we need Ajv we will throw a neat exception + } +}; + +/***/ }), + +/***/ 9125: +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + +exports.O = function () { + try { + __webpack_require__(4864); + } catch (err) { + console.error(err); + } +}; + +/***/ }), + +/***/ 9791: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "parse": function() { return /* binding */ parse; }, +/* harmony export */ "tryJsonRepair": function() { return /* binding */ tryJsonRepair; }, +/* harmony export */ "escapeUnicodeChars": function() { return /* binding */ escapeUnicodeChars; }, +/* harmony export */ "validate": function() { return /* binding */ validate; }, +/* harmony export */ "extend": function() { return /* binding */ extend; }, +/* harmony export */ "clear": function() { return /* binding */ clear; }, +/* harmony export */ "getType": function() { return /* binding */ getType; }, +/* harmony export */ "isUrl": function() { return /* binding */ isUrl; }, +/* harmony export */ "isArray": function() { return /* binding */ isArray; }, +/* harmony export */ "getWindow": function() { return /* binding */ getWindow; }, +/* harmony export */ "getAbsoluteLeft": function() { return /* binding */ getAbsoluteLeft; }, +/* harmony export */ "getAbsoluteTop": function() { return /* binding */ getAbsoluteTop; }, +/* harmony export */ "addClassName": function() { return /* binding */ addClassName; }, +/* harmony export */ "removeAllClassNames": function() { return /* binding */ removeAllClassNames; }, +/* harmony export */ "removeClassName": function() { return /* binding */ removeClassName; }, +/* harmony export */ "stripFormatting": function() { return /* binding */ stripFormatting; }, +/* harmony export */ "setEndOfContentEditable": function() { return /* binding */ setEndOfContentEditable; }, +/* harmony export */ "selectContentEditable": function() { return /* binding */ selectContentEditable; }, +/* harmony export */ "getSelection": function() { return /* binding */ getSelection; }, +/* harmony export */ "setSelection": function() { return /* binding */ setSelection; }, +/* harmony export */ "getSelectionOffset": function() { return /* binding */ getSelectionOffset; }, +/* harmony export */ "setSelectionOffset": function() { return /* binding */ setSelectionOffset; }, +/* harmony export */ "getInnerText": function() { return /* binding */ getInnerText; }, +/* harmony export */ "hasParentNode": function() { return /* binding */ hasParentNode; }, +/* harmony export */ "getInternetExplorerVersion": function() { return /* binding */ getInternetExplorerVersion; }, +/* harmony export */ "isFirefox": function() { return /* binding */ isFirefox; }, +/* harmony export */ "addEventListener": function() { return /* binding */ addEventListener; }, +/* harmony export */ "removeEventListener": function() { return /* binding */ removeEventListener; }, +/* harmony export */ "isChildOf": function() { return /* binding */ isChildOf; }, +/* harmony export */ "parsePath": function() { return /* binding */ parsePath; }, +/* harmony export */ "stringifyPath": function() { return /* binding */ stringifyPath; }, +/* harmony export */ "improveSchemaError": function() { return /* binding */ improveSchemaError; }, +/* harmony export */ "isPromise": function() { return /* binding */ isPromise; }, +/* harmony export */ "isValidValidationError": function() { return /* binding */ isValidValidationError; }, +/* harmony export */ "insideRect": function() { return /* binding */ insideRect; }, +/* harmony export */ "debounce": function() { return /* binding */ debounce; }, +/* harmony export */ "textDiff": function() { return /* binding */ textDiff; }, +/* harmony export */ "getInputSelection": function() { return /* binding */ getInputSelection; }, +/* harmony export */ "getIndexForPosition": function() { return /* binding */ getIndexForPosition; }, +/* harmony export */ "getPositionForPath": function() { return /* binding */ getPositionForPath; }, +/* harmony export */ "compileJSONPointer": function() { return /* binding */ compileJSONPointer; }, +/* harmony export */ "getColorCSS": function() { return /* binding */ getColorCSS; }, +/* harmony export */ "isValidColor": function() { return /* binding */ isValidColor; }, +/* harmony export */ "makeFieldTooltip": function() { return /* binding */ makeFieldTooltip; }, +/* harmony export */ "get": function() { return /* binding */ get; }, +/* harmony export */ "findUniqueName": function() { return /* binding */ findUniqueName; }, +/* harmony export */ "getChildPaths": function() { return /* binding */ getChildPaths; }, +/* harmony export */ "sort": function() { return /* binding */ sort; }, +/* harmony export */ "sortObjectKeys": function() { return /* binding */ sortObjectKeys; }, +/* harmony export */ "parseString": function() { return /* binding */ parseString; }, +/* harmony export */ "isTimestamp": function() { return /* binding */ isTimestamp; }, +/* harmony export */ "formatSize": function() { return /* binding */ formatSize; }, +/* harmony export */ "limitCharacters": function() { return /* binding */ limitCharacters; }, +/* harmony export */ "isObject": function() { return /* binding */ isObject; }, +/* harmony export */ "contains": function() { return /* binding */ contains; }, +/* harmony export */ "isValidationErrorChanged": function() { return /* binding */ isValidationErrorChanged; } +/* harmony export */ }); +/* harmony import */ var _polyfills__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4987); +/* harmony import */ var _polyfills__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_polyfills__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var javascript_natural_sort__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(233); +/* harmony import */ var javascript_natural_sort__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(javascript_natural_sort__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var jsonrepair__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8909); +/* harmony import */ var jsonrepair__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(jsonrepair__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _assets_jsonlint_jsonlint__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6589); +/* harmony import */ var json_source_map__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7026); +/* harmony import */ var _i18n__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7907); + + +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + + + + + + + +var MAX_ITEMS_FIELDS_COLLECTION = 10000; +var YEAR_2000 = 946684800000; +/** + * Parse JSON using the parser built-in in the browser. + * On exception, the jsonString is validated and a detailed error is thrown. + * @param {String} jsonString + * @return {JSON} json + */ + +function parse(jsonString) { + try { + return JSON.parse(jsonString); + } catch (err) { + // try to throw a more detailed error message using validate + validate(jsonString); // rethrow the original error + + throw err; + } +} +/** + * Try to fix the JSON string. If not successful, return the original string + * @param {string} jsonString + */ + +function tryJsonRepair(jsonString) { + try { + return jsonrepair__WEBPACK_IMPORTED_MODULE_2___default()(jsonString); + } catch (err) { + // repair was not successful, return original text + return jsonString; + } +} +/** + * Escape unicode characters. + * For example input '\u2661' (length 1) will output '\\u2661' (length 5). + * @param {string} text + * @return {string} + */ + +function escapeUnicodeChars( // see https://www.wikiwand.com/en/UTF-16 +text) { + return (// note: we leave surrogate pairs as two individual chars, + // as JSON doesn't interpret them as a single unicode char. + text.replace(/[\u007F-\uFFFF]/g, function (c) { + return "\\u" + ('0000' + c.charCodeAt(0).toString(16)).slice(-4); + }) + ); +} +/** + * Validate a string containing a JSON object + * This method uses JSONLint to validate the String. If JSONLint is not + * available, the built-in JSON parser of the browser is used. + * @param {String} jsonString String with an (invalid) JSON object + * @throws Error + */ + +function validate(jsonString) { + if (typeof _assets_jsonlint_jsonlint__WEBPACK_IMPORTED_MODULE_3__ !== 'undefined') { + _assets_jsonlint_jsonlint__WEBPACK_IMPORTED_MODULE_3__.parse(jsonString); + } else { + JSON.parse(jsonString); + } +} +/** + * Extend object a with the properties of object b + * @param {Object} a + * @param {Object} b + * @return {Object} a + */ + +function extend(a, b) { + for (var prop in b) { + if (hasOwnProperty(b, prop)) { + a[prop] = b[prop]; + } + } + + return a; +} +/** + * Remove all properties from object a + * @param {Object} a + * @return {Object} a + */ + +function clear(a) { + for (var prop in a) { + if (hasOwnProperty(a, prop)) { + delete a[prop]; + } + } + + return a; +} +/** + * Get the type of an object + * @param {*} object + * @return {String} type + */ + +function getType(object) { + if (object === null) { + return 'null'; + } + + if (object === undefined) { + return 'undefined'; + } + + if (object instanceof Number || typeof object === 'number') { + return 'number'; + } + + if (object instanceof String || typeof object === 'string') { + return 'string'; + } + + if (object instanceof Boolean || typeof object === 'boolean') { + return 'boolean'; + } + + if (object instanceof RegExp) { + return 'regexp'; + } + + if (isArray(object)) { + return 'array'; + } + + return 'object'; +} +/** + * Test whether a text contains a url (matches when a string starts + * with 'http://*' or 'https://*' and has no whitespace characters) + * @param {String} text + */ + +var isUrlRegex = /^https?:\/\/\S+$/; +function isUrl(text) { + return (typeof text === 'string' || text instanceof String) && isUrlRegex.test(text); +} +/** + * Tes whether given object is an Array + * @param {*} obj + * @returns {boolean} returns true when obj is an array + */ + +function isArray(obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; +} +/** + * Gets a DOM element's Window. This is normally just the global `window` + * variable, but if we opened a child window, it may be different. + * @param {HTMLElement} element + * @return {Window} + */ + +function getWindow(element) { + return element.ownerDocument.defaultView; +} +/** + * Retrieve the absolute left value of a DOM element + * @param {Element} elem A dom element, for example a div + * @return {Number} left The absolute left position of this element + * in the browser page. + */ + +function getAbsoluteLeft(elem) { + var rect = elem.getBoundingClientRect(); + return rect.left + window.pageXOffset || document.scrollLeft || 0; +} +/** + * Retrieve the absolute top value of a DOM element + * @param {Element} elem A dom element, for example a div + * @return {Number} top The absolute top position of this element + * in the browser page. + */ + +function getAbsoluteTop(elem) { + var rect = elem.getBoundingClientRect(); + return rect.top + window.pageYOffset || document.scrollTop || 0; +} +/** + * add a className to the given elements style + * @param {Element} elem + * @param {String} className + */ + +function addClassName(elem, className) { + var classes = elem.className.split(' '); + + if (classes.indexOf(className) === -1) { + classes.push(className); // add the class to the array + + elem.className = classes.join(' '); + } +} +/** + * remove all classes from the given elements style + * @param {Element} elem + */ + +function removeAllClassNames(elem) { + elem.className = ''; +} +/** + * add a className to the given elements style + * @param {Element} elem + * @param {String} className + */ + +function removeClassName(elem, className) { + var classes = elem.className.split(' '); + var index = classes.indexOf(className); + + if (index !== -1) { + classes.splice(index, 1); // remove the class from the array + + elem.className = classes.join(' '); + } +} +/** + * Strip the formatting from the contents of a div + * the formatting from the div itself is not stripped, only from its childs. + * @param {Element} divElement + */ + +function stripFormatting(divElement) { + var childs = divElement.childNodes; + + for (var i = 0, iMax = childs.length; i < iMax; i++) { + var child = childs[i]; // remove the style + + if (child.style) { + // TODO: test if child.attributes does contain style + child.removeAttribute('style'); + } // remove all attributes + + + var attributes = child.attributes; + + if (attributes) { + for (var j = attributes.length - 1; j >= 0; j--) { + var attribute = attributes[j]; + + if (attribute.specified === true) { + child.removeAttribute(attribute.name); + } + } + } // recursively strip childs + + + stripFormatting(child); + } +} +/** + * Set focus to the end of an editable div + * code from Nico Burns + * http://stackoverflow.com/users/140293/nico-burns + * http://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity + * @param {Element} contentEditableElement A content editable div + */ + +function setEndOfContentEditable(contentEditableElement) { + var range, selection; + + if (document.createRange) { + range = document.createRange(); // Create a range (a range is a like the selection but invisible) + + range.selectNodeContents(contentEditableElement); // Select the entire contents of the element with the range + + range.collapse(false); // collapse the range to the end point. false means collapse to end rather than the start + + selection = window.getSelection(); // get the selection object (allows you to change selection) + + selection.removeAllRanges(); // remove any selections already made + + selection.addRange(range); // make the range you have just created the visible selection + } +} +/** + * Select all text of a content editable div. + * http://stackoverflow.com/a/3806004/1262753 + * @param {Element} contentEditableElement A content editable div + */ + +function selectContentEditable(contentEditableElement) { + if (!contentEditableElement || contentEditableElement.nodeName !== 'DIV') { + return; + } + + var sel, range; + + if (window.getSelection && document.createRange) { + range = document.createRange(); + range.selectNodeContents(contentEditableElement); + sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + } +} +/** + * Get text selection + * http://stackoverflow.com/questions/4687808/contenteditable-selected-text-save-and-restore + * @return {Range | TextRange | null} range + */ + +function getSelection() { + if (window.getSelection) { + var sel = window.getSelection(); + + if (sel.getRangeAt && sel.rangeCount) { + return sel.getRangeAt(0); + } + } + + return null; +} +/** + * Set text selection + * http://stackoverflow.com/questions/4687808/contenteditable-selected-text-save-and-restore + * @param {Range | TextRange | null} range + */ + +function setSelection(range) { + if (range) { + if (window.getSelection) { + var sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + } + } +} +/** + * Get selected text range + * @return {Object} params object containing parameters: + * {Number} startOffset + * {Number} endOffset + * {Element} container HTML element holding the + * selected text element + * Returns null if no text selection is found + */ + +function getSelectionOffset() { + var range = getSelection(); + + if (range && 'startOffset' in range && 'endOffset' in range && range.startContainer && range.startContainer === range.endContainer) { + return { + startOffset: range.startOffset, + endOffset: range.endOffset, + container: range.startContainer.parentNode + }; + } + + return null; +} +/** + * Set selected text range in given element + * @param {Object} params An object containing: + * {Element} container + * {Number} startOffset + * {Number} endOffset + */ + +function setSelectionOffset(params) { + if (document.createRange && window.getSelection) { + var selection = window.getSelection(); + + if (selection) { + var range = document.createRange(); + + if (!params.container.firstChild) { + params.container.appendChild(document.createTextNode('')); + } // TODO: do not suppose that the first child of the container is a textnode, + // but recursively find the textnodes + + + range.setStart(params.container.firstChild, params.startOffset); + range.setEnd(params.container.firstChild, params.endOffset); + setSelection(range); + } + } +} +/** + * Get the inner text of an HTML element (for example a div element) + * @param {Element} element + * @param {Object} [buffer] + * @return {String} innerText + */ + +function getInnerText(element, buffer) { + var first = buffer === undefined; + + if (first) { + buffer = { + _text: '', + flush: function flush() { + var text = this._text; + this._text = ''; + return text; + }, + set: function set(text) { + this._text = text; + } + }; + } // text node + + + if (element.nodeValue) { + // remove return characters and the whitespace surrounding return characters + var trimmedValue = element.nodeValue.replace(/\s*\n\s*/g, ''); + + if (trimmedValue !== '') { + return buffer.flush() + trimmedValue; + } else { + // ignore empty text + return ''; + } + } // divs or other HTML elements + + + if (element.hasChildNodes()) { + var childNodes = element.childNodes; + var innerText = ''; + + for (var i = 0, iMax = childNodes.length; i < iMax; i++) { + var child = childNodes[i]; + + if (child.nodeName === 'DIV' || child.nodeName === 'P') { + var prevChild = childNodes[i - 1]; + var prevName = prevChild ? prevChild.nodeName : undefined; + + if (prevName && prevName !== 'DIV' && prevName !== 'P' && prevName !== 'BR') { + if (innerText !== '') { + innerText += '\n'; + } + + buffer.flush(); + } + + innerText += getInnerText(child, buffer); + buffer.set('\n'); + } else if (child.nodeName === 'BR') { + innerText += buffer.flush(); + buffer.set('\n'); + } else { + innerText += getInnerText(child, buffer); + } + } + + return innerText; + } // br or unknown + + + return ''; +} +/** + * Test whether an element has the provided parent node somewhere up the node tree. + * @param {Element} elem + * @param {Element} parent + * @return {boolean} + */ + +function hasParentNode(elem, parent) { + var e = elem ? elem.parentNode : undefined; + + while (e) { + if (e === parent) { + return true; + } + + e = e.parentNode; + } + + return false; +} +/** + * Returns the version of Internet Explorer or a -1 + * (indicating the use of another browser). + * Source: http://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx + * @return {Number} Internet Explorer version, or -1 in case of an other browser + */ + +function getInternetExplorerVersion() { + if (_ieVersion === -1) { + var rv = -1; // Return value assumes failure. + + if (typeof navigator !== 'undefined' && navigator.appName === 'Microsoft Internet Explorer') { + var ua = navigator.userAgent; + var re = /MSIE ([0-9]+[.0-9]+)/; + + if (re.exec(ua) != null) { + rv = parseFloat(RegExp.$1); + } + } + + _ieVersion = rv; + } + + return _ieVersion; +} +/** + * cached internet explorer version + * @type {Number} + * @private + */ + +var _ieVersion = -1; +/** + * Test whether the current browser is Firefox + * @returns {boolean} isFirefox + */ + + +function isFirefox() { + return typeof navigator !== 'undefined' && navigator.userAgent.indexOf('Firefox') !== -1; +} +/** + * Add an event listener. Works for all browsers + * @param {Element} element An html element + * @param {string} action The action, for example "click", + * without the prefix "on" + * @param {function} listener The callback function to be executed + * @param {boolean} [useCapture] false by default + * @return {function} the created event listener + */ + +function addEventListener(element, action, listener, useCapture) { + if (element.addEventListener) { + if (useCapture === undefined) { + useCapture = false; + } + + if (action === 'mousewheel' && isFirefox()) { + action = 'DOMMouseScroll'; // For Firefox + } + + element.addEventListener(action, listener, useCapture); + return listener; + } else if (element.attachEvent) { + // Old IE browsers + var f = function f() { + return listener.call(element, window.event); + }; + + element.attachEvent('on' + action, f); + return f; + } +} +/** + * Remove an event listener from an element + * @param {Element} element An html dom element + * @param {string} action The name of the event, for example "mousedown" + * @param {function} listener The listener function + * @param {boolean} [useCapture] false by default + */ + +function removeEventListener(element, action, listener, useCapture) { + if (element.removeEventListener) { + if (useCapture === undefined) { + useCapture = false; + } + + if (action === 'mousewheel' && isFirefox()) { + action = 'DOMMouseScroll'; // For Firefox + } + + element.removeEventListener(action, listener, useCapture); + } else if (element.detachEvent) { + // Old IE browsers + element.detachEvent('on' + action, listener); + } +} +/** + * Test if an element is a child of a parent element. + * @param {Element} elem + * @param {Element} parent + * @return {boolean} returns true if elem is a child of the parent + */ + +function isChildOf(elem, parent) { + var e = elem.parentNode; + + while (e) { + if (e === parent) { + return true; + } + + e = e.parentNode; + } + + return false; +} +/** + * Parse a JSON path like '.items[3].name' into an array + * @param {string} jsonPath + * @return {Array} + */ + +function parsePath(jsonPath) { + var path = []; + var i = 0; + + function parseProperty() { + var prop = ''; + + while (jsonPath[i] !== undefined && /[\w$]/.test(jsonPath[i])) { + prop += jsonPath[i]; + i++; + } + + if (prop === '') { + throw new Error('Invalid JSON path: property name expected at index ' + i); + } + + return prop; + } + + function parseIndex(end) { + var name = ''; + + while (jsonPath[i] !== undefined && jsonPath[i] !== end) { + name += jsonPath[i]; + i++; + } + + if (jsonPath[i] !== end) { + throw new Error('Invalid JSON path: unexpected end, character ' + end + ' expected'); + } + + return name; + } + + while (jsonPath[i] !== undefined) { + if (jsonPath[i] === '.') { + i++; + path.push(parseProperty()); + } else if (jsonPath[i] === '[') { + i++; + + if (jsonPath[i] === '\'' || jsonPath[i] === '"') { + var end = jsonPath[i]; + i++; + path.push(parseIndex(end)); + + if (jsonPath[i] !== end) { + throw new Error('Invalid JSON path: closing quote \' expected at index ' + i); + } + + i++; + } else { + var index = parseIndex(']').trim(); + + if (index.length === 0) { + throw new Error('Invalid JSON path: array value expected at index ' + i); + } // Coerce numeric indices to numbers, but ignore star + + + index = index === '*' ? index : JSON.parse(index); + path.push(index); + } + + if (jsonPath[i] !== ']') { + throw new Error('Invalid JSON path: closing bracket ] expected at index ' + i); + } + + i++; + } else { + throw new Error('Invalid JSON path: unexpected character "' + jsonPath[i] + '" at index ' + i); + } + } + + return path; +} +/** + * Stringify an array with a path in a JSON path like '.items[3].name' + * @param {Array.} path + * @returns {string} + */ + +function stringifyPath(path) { + return path.map(function (p) { + if (typeof p === 'number') { + return '[' + p + ']'; + } else if (typeof p === 'string' && p.match(/^[A-Za-z0-9_$]+$/)) { + return '.' + p; + } else { + return '["' + p + '"]'; + } + }).join(''); +} +/** + * Improve the error message of a JSON schema error + * @param {Object} error + * @return {Object} The error + */ + +function improveSchemaError(error) { + if (error.keyword === 'enum' && Array.isArray(error.schema)) { + var enums = error.schema; + + if (enums) { + enums = enums.map(function (value) { + return JSON.stringify(value); + }); + + if (enums.length > 5) { + var more = ['(' + (enums.length - 5) + ' more...)']; + enums = enums.slice(0, 5); + enums.push(more); + } + + error.message = 'should be equal to one of: ' + enums.join(', '); + } + } + + if (error.keyword === 'additionalProperties') { + error.message = 'should NOT have additional property: ' + error.params.additionalProperty; + } + + return error; +} +/** + * Test whether something is a Promise + * @param {*} object + * @returns {boolean} Returns true when object is a promise, false otherwise + */ + +function isPromise(object) { + return object && typeof object.then === 'function' && typeof object["catch"] === 'function'; +} +/** + * Test whether a custom validation error has the correct structure + * @param {*} validationError The error to be checked. + * @returns {boolean} Returns true if the structure is ok, false otherwise + */ + +function isValidValidationError(validationError) { + return _typeof(validationError) === 'object' && Array.isArray(validationError.path) && typeof validationError.message === 'string'; +} +/** + * Test whether the child rect fits completely inside the parent rect. + * @param {ClientRect} parent + * @param {ClientRect} child + * @param {number} margin + */ + +function insideRect(parent, child, margin) { + var _margin = margin !== undefined ? margin : 0; + + return child.left - _margin >= parent.left && child.right + _margin <= parent.right && child.top - _margin >= parent.top && child.bottom + _margin <= parent.bottom; +} +/** + * Returns a function, that, as long as it continues to be invoked, will not + * be triggered. The function will be called after it stops being called for + * N milliseconds. + * + * Source: https://davidwalsh.name/javascript-debounce-function + * + * @param {function} func + * @param {number} wait Number in milliseconds + * @param {boolean} [immediate=false] If `immediate` is passed, trigger the + * function on the leading edge, instead + * of the trailing. + * @return {function} Return the debounced function + */ + +function debounce(func, wait, immediate) { + var timeout; + return function () { + var context = this; + var args = arguments; + + var later = function later() { + timeout = null; + if (!immediate) func.apply(context, args); + }; + + var callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) func.apply(context, args); + }; +} +/** + * Determines the difference between two texts. + * Can only detect one removed or inserted block of characters. + * @param {string} oldText + * @param {string} newText + * @return {{start: number, end: number}} Returns the start and end + * of the changed part in newText. + */ + +function textDiff(oldText, newText) { + var len = newText.length; + var start = 0; + var oldEnd = oldText.length; + var newEnd = newText.length; + + while (newText.charAt(start) === oldText.charAt(start) && start < len) { + start++; + } + + while (newText.charAt(newEnd - 1) === oldText.charAt(oldEnd - 1) && newEnd > start && oldEnd > 0) { + newEnd--; + oldEnd--; + } + + return { + start: start, + end: newEnd + }; +} +/** + * Return an object with the selection range or cursor position (if both have the same value) + * Support also old browsers (IE8-) + * Source: http://ourcodeworld.com/articles/read/282/how-to-get-the-current-cursor-position-and-selection-within-a-text-input-or-textarea-in-javascript + * @param {DOMElement} el A dom element of a textarea or input text. + * @return {Object} reference Object with 2 properties (start and end) with the identifier of the location of the cursor and selected text. + **/ + +function getInputSelection(el) { + var startIndex = 0; + var endIndex = 0; + var normalizedValue; + var range; + var textInputRange; + var len; + var endRange; + + if (typeof el.selectionStart === 'number' && typeof el.selectionEnd === 'number') { + startIndex = el.selectionStart; + endIndex = el.selectionEnd; + } else { + range = document.selection.createRange(); + + if (range && range.parentElement() === el) { + len = el.value.length; + normalizedValue = el.value.replace(/\r\n/g, '\n'); // Create a working TextRange that lives only in the input + + textInputRange = el.createTextRange(); + textInputRange.moveToBookmark(range.getBookmark()); // Check if the startIndex and endIndex of the selection are at the very end + // of the input, since moveStart/moveEnd doesn't return what we want + // in those cases + + endRange = el.createTextRange(); + endRange.collapse(false); + + if (textInputRange.compareEndPoints('StartToEnd', endRange) > -1) { + startIndex = endIndex = len; + } else { + startIndex = -textInputRange.moveStart('character', -len); + startIndex += normalizedValue.slice(0, startIndex).split('\n').length - 1; + + if (textInputRange.compareEndPoints('EndToEnd', endRange) > -1) { + endIndex = len; + } else { + endIndex = -textInputRange.moveEnd('character', -len); + endIndex += normalizedValue.slice(0, endIndex).split('\n').length - 1; + } + } + } + } + + return { + startIndex: startIndex, + endIndex: endIndex, + start: _positionForIndex(startIndex), + end: _positionForIndex(endIndex) + }; + /** + * Returns textarea row and column position for certain index + * @param {Number} index text index + * @returns {{row: Number, column: Number}} + */ + + function _positionForIndex(index) { + var textTillIndex = el.value.substring(0, index); + var row = (textTillIndex.match(/\n/g) || []).length + 1; + var col = textTillIndex.length - textTillIndex.lastIndexOf('\n'); + return { + row: row, + column: col + }; + } +} +/** + * Returns the index for certain position in text element + * @param {DOMElement} el A dom element of a textarea or input text. + * @param {Number} row row value, > 0, if exceeds rows number - last row will be returned + * @param {Number} column column value, > 0, if exceeds column length - end of column will be returned + * @returns {Number} index of position in text, -1 if not found + */ + +function getIndexForPosition(el, row, column) { + var text = el.value || ''; + + if (row > 0 && column > 0) { + var rows = text.split('\n', row); + row = Math.min(rows.length, row); + column = Math.min(rows[row - 1].length, column - 1); + var columnCount = row === 1 ? column : column + 1; // count new line on multiple rows + + return rows.slice(0, row - 1).join('\n').length + columnCount; + } + + return -1; +} +/** + * Returns location of json paths in certain json string + * @param {String} text json string + * @param {Array} paths array of json paths + * @returns {Array<{path: String, line: Number, row: Number}>} + */ + +function getPositionForPath(text, paths) { + var result = []; + var jsmap; + + if (!paths || !paths.length) { + return result; + } + + try { + jsmap = json_source_map__WEBPACK_IMPORTED_MODULE_4__/* .parse */ .Q(text); + } catch (err) { + return result; + } + + paths.forEach(function (path) { + var pathArr = parsePath(path); + var pointerName = compileJSONPointer(pathArr); + var pointer = jsmap.pointers[pointerName]; + + if (pointer) { + result.push({ + path: path, + line: pointer.key ? pointer.key.line : pointer.value ? pointer.value.line : 0, + column: pointer.key ? pointer.key.column : pointer.value ? pointer.value.column : 0 + }); + } + }); + return result; +} +/** + * Compile a JSON Pointer + * WARNING: this is an incomplete implementation + * @param {Array.} path + * @return {string} + */ + +function compileJSONPointer(path) { + return path.map(function (p) { + return '/' + String(p).replace(/~/g, '~0').replace(/\//g, '~1'); + }).join(''); +} +/** + * Get the applied color given a color name or code + * Source: https://stackoverflow.com/questions/6386090/validating-css-color-names/33184805 + * @param {string} color + * @returns {string | null} returns the color if the input is a valid + * color, and returns null otherwise. Example output: + * 'rgba(255,0,0,0.7)' or 'rgb(255,0,0)' + */ + +function getColorCSS(color) { + var ele = document.createElement('div'); + ele.style.color = color; + return ele.style.color.split(/\s+/).join('').toLowerCase() || null; +} +/** + * Test if a string contains a valid color name or code. + * @param {string} color + * @returns {boolean} returns true if a valid color, false otherwise + */ + +function isValidColor(color) { + return !!getColorCSS(color); +} +/** + * Make a tooltip for a field based on the field's schema. + * @param {object} schema JSON schema + * @param {string} [locale] Locale code (for example, zh-CN) + * @returns {string} Field tooltip, may be empty string if all relevant schema properties are missing + */ + +function makeFieldTooltip(schema, locale) { + if (!schema) { + return ''; + } + + var tooltip = ''; + + if (schema.title) { + tooltip += schema.title; + } + + if (schema.description) { + if (tooltip.length > 0) { + tooltip += '\n'; + } + + tooltip += schema.description; + } + + if (schema["default"]) { + if (tooltip.length > 0) { + tooltip += '\n\n'; + } + + tooltip += (0,_i18n__WEBPACK_IMPORTED_MODULE_5__/* .translate */ .Iu)('default', undefined, locale) + '\n'; + tooltip += JSON.stringify(schema["default"], null, 2); + } + + if (Array.isArray(schema.examples) && schema.examples.length > 0) { + if (tooltip.length > 0) { + tooltip += '\n\n'; + } + + tooltip += (0,_i18n__WEBPACK_IMPORTED_MODULE_5__/* .translate */ .Iu)('examples', undefined, locale) + '\n'; + schema.examples.forEach(function (example, index) { + tooltip += JSON.stringify(example, null, 2); + + if (index !== schema.examples.length - 1) { + tooltip += '\n'; + } + }); + } + + return tooltip; +} +/** + * Get a nested property from an object. + * Returns undefined when the property does not exist. + * @param {Object} object + * @param {string[]} path + * @return {*} + */ + +function get(object, path) { + var value = object; + + for (var i = 0; i < path.length && value !== undefined && value !== null; i++) { + value = value[path[i]]; + } + + return value; +} +/** + * Find a unique name. Suffix the name with ' (copy)', '(copy 2)', etc + * until a unique name is found + * @param {string} name + * @param {Array} existingPropNames Array with existing prop names + */ + +function findUniqueName(name, existingPropNames) { + var strippedName = name.replace(/ \(copy( \d+)?\)$/, ''); + var validName = strippedName; + var i = 1; + + while (existingPropNames.indexOf(validName) !== -1) { + var copy = 'copy' + (i > 1 ? ' ' + i : ''); + validName = strippedName + ' (' + copy + ')'; + i++; + } + + return validName; +} +/** + * Get the child paths of an array + * @param {JSON} json + * @param {boolean} [includeObjects=false] If true, object and array paths are returned as well + * @return {string[]} + */ + +function getChildPaths(json, includeObjects) { + var pathsMap = {}; + + function getObjectChildPaths(json, pathsMap, rootPath, includeObjects) { + var isValue = !Array.isArray(json) && !isObject(json); + + if (isValue || includeObjects) { + pathsMap[rootPath || ''] = true; + } + + if (isObject(json)) { + Object.keys(json).forEach(function (field) { + getObjectChildPaths(json[field], pathsMap, rootPath + '.' + field, includeObjects); + }); + } + } + + if (Array.isArray(json)) { + var max = Math.min(json.length, MAX_ITEMS_FIELDS_COLLECTION); + + for (var i = 0; i < max; i++) { + var item = json[i]; + getObjectChildPaths(item, pathsMap, '', includeObjects); + } + } else { + pathsMap[''] = true; + } + + return Object.keys(pathsMap).sort(); +} +/** + * Sort object keys using natural sort + * @param {Array} array + * @param {String} [path] JSON pointer + * @param {'asc' | 'desc'} [direction] + */ + +function sort(array, path, direction) { + var parsedPath = path && path !== '.' ? parsePath(path) : []; + var sign = direction === 'desc' ? -1 : 1; + var sortedArray = array.slice(); + sortedArray.sort(function (a, b) { + var aValue = get(a, parsedPath); + var bValue = get(b, parsedPath); + return sign * (aValue > bValue ? 1 : aValue < bValue ? -1 : 0); + }); + return sortedArray; +} +/** + * Sort object keys using natural sort + * @param {Object} object + * @param {'asc' | 'desc'} [direction] + */ + +function sortObjectKeys(object, direction) { + var sign = direction === 'desc' ? -1 : 1; + var sortedFields = Object.keys(object).sort(function (a, b) { + return sign * javascript_natural_sort__WEBPACK_IMPORTED_MODULE_1___default()(a, b); + }); + var sortedObject = {}; + sortedFields.forEach(function (field) { + sortedObject[field] = object[field]; + }); + return sortedObject; +} +/** + * Cast contents of a string to the correct type. + * This can be a string, a number, a boolean, etc + * @param {String} str + * @return {*} castedStr + * @private + */ + +function parseString(str) { + if (str === '') { + return ''; + } + + var lower = str.toLowerCase(); + + if (lower === 'null') { + return null; + } + + if (lower === 'true') { + return true; + } + + if (lower === 'false') { + return false; + } + + var num = Number(str); // will nicely fail with '123ab' + + var numFloat = parseFloat(str); // will nicely fail with ' ' + + if (!isNaN(num) && !isNaN(numFloat)) { + return num; + } + + return str; +} +/** + * Test whether some field contains a timestamp in milliseconds after the year 2000. + * @param {string} field + * @param {number} value + * @return {boolean} + */ + +function isTimestamp(field, value) { + return typeof value === 'number' && value > YEAR_2000 && isFinite(value) && Math.floor(value) === value && !isNaN(new Date(value).valueOf()); +} +/** + * Return a human readable document size + * For example formatSize(7570718) outputs '7.6 MB' + * @param {number} size + * @return {string} Returns a human readable size + */ + +function formatSize(size) { + if (size < 900) { + return size.toFixed() + ' B'; + } + + var KB = size / 1000; + + if (KB < 900) { + return KB.toFixed(1) + ' KB'; + } + + var MB = KB / 1000; + + if (MB < 900) { + return MB.toFixed(1) + ' MB'; + } + + var GB = MB / 1000; + + if (GB < 900) { + return GB.toFixed(1) + ' GB'; + } + + var TB = GB / 1000; + return TB.toFixed(1) + ' TB'; +} +/** + * Limit text to a maximum number of characters + * @param {string} text + * @param {number} maxCharacterCount + * @return {string} Returns the limited text, + * ending with '...' if the max was exceeded + */ + +function limitCharacters(text, maxCharacterCount) { + if (text.length <= maxCharacterCount) { + return text; + } + + return text.slice(0, maxCharacterCount) + '...'; +} +/** + * Test whether a value is an Object + * @param {*} value + * @return {boolean} + */ + +function isObject(value) { + return _typeof(value) === 'object' && value !== null && !Array.isArray(value); +} +/** + * Helper function to test whether an array contains an item + * @param {Array} array + * @param {*} item + * @return {boolean} Returns true if `item` is in `array`, returns false otherwise. + */ + +function contains(array, item) { + return array.indexOf(item) !== -1; +} +/** + * Checks if validation has changed from the previous execution + * @param {Array} currErr current validation errors + * @param {Array} prevErr previous validation errors + */ + +function isValidationErrorChanged(currErr, prevErr) { + if (!prevErr && !currErr) { + return false; + } + + if (prevErr && !currErr || !prevErr && currErr) { + return true; + } + + if (prevErr.length !== currErr.length) { + return true; + } + + var _loop = function _loop(i) { + var pErr = void 0; + + if (currErr[i].type === 'error') { + pErr = prevErr.find(function (p) { + return p.line === currErr[i].line; + }); + } else { + pErr = prevErr.find(function (p) { + return p.dataPath === currErr[i].dataPath && p.schemaPath === currErr[i].schemaPath; + }); + } + + if (!pErr) { + return { + v: true + }; + } + }; + + for (var i = 0; i < currErr.length; ++i) { + var _ret = _loop(i); + + if (_typeof(_ret) === "object") return _ret.v; + } + + return false; +} + +function hasOwnProperty(object, key) { + return Object.prototype.hasOwnProperty.call(object, key); +} + +/***/ }), + +/***/ 8037: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +var VanillaPicker; + +if (window.Picker) { + // use the already loaded instance of VanillaPicker + VanillaPicker = window.Picker; +} else { + try { + // load color picker + VanillaPicker = __webpack_require__(4049); + } catch (err) {// probably running the minimalist bundle + } +} + +module.exports = VanillaPicker; + +/***/ }), + +/***/ 6225: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +/* module decorator */ module = __webpack_require__.nmd(module); +/* ***** BEGIN LICENSE BLOCK ***** + * Distributed under the BSD license: + * + * Copyright (c) 2010, Ajax.org B.V. + * All rights reserved. + * + * Redistribution and use 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 Ajax.org B.V. 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 AJAX.ORG B.V. 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. + * + * ***** END LICENSE BLOCK ***** */ + +/** + * Define a module along with a payload + * @param module a name for the payload + * @param payload a function to call with (require, exports, module) params + */ + +(function() { + +var ACE_NAMESPACE = "ace"; + +var global = (function() { return this; })(); +if (!global && typeof window != "undefined") global = window; // strict mode + + +if (!ACE_NAMESPACE && typeof requirejs !== "undefined") + return; + + +var define = function(module, deps, payload) { + if (typeof module !== "string") { + if (define.original) + define.original.apply(this, arguments); + else { + console.error("dropping module because define wasn\'t a string."); + console.trace(); + } + return; + } + if (arguments.length == 2) + payload = deps; + if (!define.modules[module]) { + define.payloads[module] = payload; + define.modules[module] = null; + } +}; + +define.modules = {}; +define.payloads = {}; + +/** + * Get at functionality define()ed using the function above + */ +var _require = function(parentId, module, callback) { + if (typeof module === "string") { + var payload = lookup(parentId, module); + if (payload != undefined) { + callback && callback(); + return payload; + } + } else if (Object.prototype.toString.call(module) === "[object Array]") { + var params = []; + for (var i = 0, l = module.length; i < l; ++i) { + var dep = lookup(parentId, module[i]); + if (dep == undefined && require.original) + return; + params.push(dep); + } + return callback && callback.apply(null, params) || true; + } +}; + +var require = function(module, callback) { + var packagedModule = _require("", module, callback); + if (packagedModule == undefined && require.original) + return require.original.apply(this, arguments); + return packagedModule; +}; + +var normalizeModule = function(parentId, moduleName) { + // normalize plugin requires + if (moduleName.indexOf("!") !== -1) { + var chunks = moduleName.split("!"); + return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]); + } + // normalize relative requires + if (moduleName.charAt(0) == ".") { + var base = parentId.split("/").slice(0, -1).join("/"); + moduleName = base + "/" + moduleName; + + while(moduleName.indexOf(".") !== -1 && previous != moduleName) { + var previous = moduleName; + moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, ""); + } + } + return moduleName; +}; + +/** + * Internal function to lookup moduleNames and resolve them by calling the + * definition function if needed. + */ +var lookup = function(parentId, moduleName) { + moduleName = normalizeModule(parentId, moduleName); + + var module = define.modules[moduleName]; + if (!module) { + module = define.payloads[moduleName]; + if (typeof module === 'function') { + var exports = {}; + var mod = { + id: moduleName, + uri: '', + exports: exports, + packaged: true + }; + + var req = function(module, callback) { + return _require(moduleName, module, callback); + }; + + var returnValue = module(req, exports, mod); + exports = returnValue || mod.exports; + define.modules[moduleName] = exports; + delete define.payloads[moduleName]; + } + module = define.modules[moduleName] = exports || module; + } + return module; +}; + +function exportAce(ns) { + var root = global; + if (ns) { + if (!global[ns]) + global[ns] = {}; + root = global[ns]; + } + + if (!root.define || !root.define.packaged) { + define.original = root.define; + root.define = define; + root.define.packaged = true; + } + + if (!root.require || !root.require.packaged) { + require.original = root.require; + root.require = require; + root.require.packaged = true; + } +} + +exportAce(ACE_NAMESPACE); + +})(); + +ace.define("ace/lib/fixoldbrowsers",["require","exports","module"], function(require, exports, module) { +"use strict"; +if (typeof Element != "undefined" && !Element.prototype.remove) { + Object.defineProperty(Element.prototype, "remove", { + enumerable: false, + writable: true, + configurable: true, + value: function() { this.parentNode && this.parentNode.removeChild(this); } + }); +} + + +}); + +ace.define("ace/lib/useragent",["require","exports","module"], function(require, exports, module) { +"use strict"; +exports.OS = { + LINUX: "LINUX", + MAC: "MAC", + WINDOWS: "WINDOWS" +}; +exports.getOS = function() { + if (exports.isMac) { + return exports.OS.MAC; + } else if (exports.isLinux) { + return exports.OS.LINUX; + } else { + return exports.OS.WINDOWS; + } +}; +var _navigator = typeof navigator == "object" ? navigator : {}; + +var os = (/mac|win|linux/i.exec(_navigator.platform) || ["other"])[0].toLowerCase(); +var ua = _navigator.userAgent || ""; +var appName = _navigator.appName || ""; +exports.isWin = (os == "win"); +exports.isMac = (os == "mac"); +exports.isLinux = (os == "linux"); +exports.isIE = + (appName == "Microsoft Internet Explorer" || appName.indexOf("MSAppHost") >= 0) + ? parseFloat((ua.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]) + : parseFloat((ua.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]); // for ie + +exports.isOldIE = exports.isIE && exports.isIE < 9; +exports.isGecko = exports.isMozilla = ua.match(/ Gecko\/\d+/); +exports.isOpera = typeof opera == "object" && Object.prototype.toString.call(window.opera) == "[object Opera]"; +exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined; + +exports.isChrome = parseFloat(ua.split(" Chrome/")[1]) || undefined; + +exports.isEdge = parseFloat(ua.split(" Edge/")[1]) || undefined; + +exports.isAIR = ua.indexOf("AdobeAIR") >= 0; + +exports.isAndroid = ua.indexOf("Android") >= 0; + +exports.isChromeOS = ua.indexOf(" CrOS ") >= 0; + +exports.isIOS = /iPad|iPhone|iPod/.test(ua) && !window.MSStream; + +if (exports.isIOS) exports.isMac = true; + +exports.isMobile = exports.isIOS || exports.isAndroid; + +}); + +ace.define("ace/lib/dom",["require","exports","module","ace/lib/useragent"], function(require, exports, module) { +"use strict"; + +var useragent = require("./useragent"); +var XHTML_NS = "http://www.w3.org/1999/xhtml"; + +exports.buildDom = function buildDom(arr, parent, refs) { + if (typeof arr == "string" && arr) { + var txt = document.createTextNode(arr); + if (parent) + parent.appendChild(txt); + return txt; + } + + if (!Array.isArray(arr)) { + if (arr && arr.appendChild && parent) + parent.appendChild(arr); + return arr; + } + if (typeof arr[0] != "string" || !arr[0]) { + var els = []; + for (var i = 0; i < arr.length; i++) { + var ch = buildDom(arr[i], parent, refs); + ch && els.push(ch); + } + return els; + } + + var el = document.createElement(arr[0]); + var options = arr[1]; + var childIndex = 1; + if (options && typeof options == "object" && !Array.isArray(options)) + childIndex = 2; + for (var i = childIndex; i < arr.length; i++) + buildDom(arr[i], el, refs); + if (childIndex == 2) { + Object.keys(options).forEach(function(n) { + var val = options[n]; + if (n === "class") { + el.className = Array.isArray(val) ? val.join(" ") : val; + } else if (typeof val == "function" || n == "value" || n[0] == "$") { + el[n] = val; + } else if (n === "ref") { + if (refs) refs[val] = el; + } else if (val != null) { + el.setAttribute(n, val); + } + }); + } + if (parent) + parent.appendChild(el); + return el; +}; + +exports.getDocumentHead = function(doc) { + if (!doc) + doc = document; + return doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement; +}; + +exports.createElement = function(tag, ns) { + return document.createElementNS ? + document.createElementNS(ns || XHTML_NS, tag) : + document.createElement(tag); +}; + +exports.removeChildren = function(element) { + element.innerHTML = ""; +}; + +exports.createTextNode = function(textContent, element) { + var doc = element ? element.ownerDocument : document; + return doc.createTextNode(textContent); +}; + +exports.createFragment = function(element) { + var doc = element ? element.ownerDocument : document; + return doc.createDocumentFragment(); +}; + +exports.hasCssClass = function(el, name) { + var classes = (el.className + "").split(/\s+/g); + return classes.indexOf(name) !== -1; +}; +exports.addCssClass = function(el, name) { + if (!exports.hasCssClass(el, name)) { + el.className += " " + name; + } +}; +exports.removeCssClass = function(el, name) { + var classes = el.className.split(/\s+/g); + while (true) { + var index = classes.indexOf(name); + if (index == -1) { + break; + } + classes.splice(index, 1); + } + el.className = classes.join(" "); +}; + +exports.toggleCssClass = function(el, name) { + var classes = el.className.split(/\s+/g), add = true; + while (true) { + var index = classes.indexOf(name); + if (index == -1) { + break; + } + add = false; + classes.splice(index, 1); + } + if (add) + classes.push(name); + + el.className = classes.join(" "); + return add; +}; +exports.setCssClass = function(node, className, include) { + if (include) { + exports.addCssClass(node, className); + } else { + exports.removeCssClass(node, className); + } +}; + +exports.hasCssString = function(id, doc) { + var index = 0, sheets; + doc = doc || document; + if ((sheets = doc.querySelectorAll("style"))) { + while (index < sheets.length) + if (sheets[index++].id === id) + return true; + } +}; + +exports.importCssString = function importCssString(cssText, id, target) { + var container = target; + if (!target || !target.getRootNode) { + container = document; + } else { + container = target.getRootNode(); + if (!container || container == target) + container = document; + } + + var doc = container.ownerDocument || container; + if (id && exports.hasCssString(id, container)) + return null; + + if (id) + cssText += "\n/*# sourceURL=ace/css/" + id + " */"; + + var style = exports.createElement("style"); + style.appendChild(doc.createTextNode(cssText)); + if (id) + style.id = id; + + if (container == doc) + container = exports.getDocumentHead(doc); + container.insertBefore(style, container.firstChild); +}; + +exports.importCssStylsheet = function(uri, doc) { + exports.buildDom(["link", {rel: "stylesheet", href: uri}], exports.getDocumentHead(doc)); +}; +exports.scrollbarWidth = function(document) { + var inner = exports.createElement("ace_inner"); + inner.style.width = "100%"; + inner.style.minWidth = "0px"; + inner.style.height = "200px"; + inner.style.display = "block"; + + var outer = exports.createElement("ace_outer"); + var style = outer.style; + + style.position = "absolute"; + style.left = "-10000px"; + style.overflow = "hidden"; + style.width = "200px"; + style.minWidth = "0px"; + style.height = "150px"; + style.display = "block"; + + outer.appendChild(inner); + + var body = document.documentElement; + body.appendChild(outer); + + var noScrollbar = inner.offsetWidth; + + style.overflow = "scroll"; + var withScrollbar = inner.offsetWidth; + + if (noScrollbar == withScrollbar) { + withScrollbar = outer.clientWidth; + } + + body.removeChild(outer); + + return noScrollbar-withScrollbar; +}; + +if (typeof document == "undefined") { + exports.importCssString = function() {}; +} + +exports.computedStyle = function(element, style) { + return window.getComputedStyle(element, "") || {}; +}; + +exports.setStyle = function(styles, property, value) { + if (styles[property] !== value) { + styles[property] = value; + } +}; + +exports.HAS_CSS_ANIMATION = false; +exports.HAS_CSS_TRANSFORMS = false; +exports.HI_DPI = useragent.isWin + ? typeof window !== "undefined" && window.devicePixelRatio >= 1.5 + : true; + +if (typeof document !== "undefined") { + var div = document.createElement("div"); + if (exports.HI_DPI && div.style.transform !== undefined) + exports.HAS_CSS_TRANSFORMS = true; + if (!useragent.isEdge && typeof div.style.animationName !== "undefined") + exports.HAS_CSS_ANIMATION = true; + div = null; +} + +if (exports.HAS_CSS_TRANSFORMS) { + exports.translate = function(element, tx, ty) { + element.style.transform = "translate(" + Math.round(tx) + "px, " + Math.round(ty) +"px)"; + }; +} else { + exports.translate = function(element, tx, ty) { + element.style.top = Math.round(ty) + "px"; + element.style.left = Math.round(tx) + "px"; + }; +} + +}); + +ace.define("ace/lib/oop",["require","exports","module"], function(require, exports, module) { +"use strict"; + +exports.inherits = function(ctor, superCtor) { + ctor.super_ = superCtor; + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); +}; + +exports.mixin = function(obj, mixin) { + for (var key in mixin) { + obj[key] = mixin[key]; + } + return obj; +}; + +exports.implement = function(proto, mixin) { + exports.mixin(proto, mixin); +}; + +}); + +ace.define("ace/lib/keys",["require","exports","module","ace/lib/oop"], function(require, exports, module) { +"use strict"; + +var oop = require("./oop"); +var Keys = (function() { + var ret = { + MODIFIER_KEYS: { + 16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta', + 91: 'MetaLeft', 92: 'MetaRight', 93: 'ContextMenu' + }, + + KEY_MODS: { + "ctrl": 1, "alt": 2, "option" : 2, "shift": 4, + "super": 8, "meta": 8, "command": 8, "cmd": 8, + "control": 1 + }, + + FUNCTION_KEYS : { + 8 : "Backspace", + 9 : "Tab", + 13 : "Return", + 19 : "Pause", + 27 : "Esc", + 32 : "Space", + 33 : "PageUp", + 34 : "PageDown", + 35 : "End", + 36 : "Home", + 37 : "Left", + 38 : "Up", + 39 : "Right", + 40 : "Down", + 44 : "Print", + 45 : "Insert", + 46 : "Delete", + 96 : "Numpad0", + 97 : "Numpad1", + 98 : "Numpad2", + 99 : "Numpad3", + 100: "Numpad4", + 101: "Numpad5", + 102: "Numpad6", + 103: "Numpad7", + 104: "Numpad8", + 105: "Numpad9", + '-13': "NumpadEnter", + 112: "F1", + 113: "F2", + 114: "F3", + 115: "F4", + 116: "F5", + 117: "F6", + 118: "F7", + 119: "F8", + 120: "F9", + 121: "F10", + 122: "F11", + 123: "F12", + 144: "Numlock", + 145: "Scrolllock" + }, + + PRINTABLE_KEYS: { + 32: ' ', 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5', + 54: '6', 55: '7', 56: '8', 57: '9', 59: ';', 61: '=', 65: 'a', + 66: 'b', 67: 'c', 68: 'd', 69: 'e', 70: 'f', 71: 'g', 72: 'h', + 73: 'i', 74: 'j', 75: 'k', 76: 'l', 77: 'm', 78: 'n', 79: 'o', + 80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v', + 87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.', + 186: ';', 187: '=', 188: ',', 189: '-', 190: '.', 191: '/', 192: '`', + 219: '[', 220: '\\',221: ']', 222: "'", 111: '/', 106: '*' + } + }; + var name, i; + for (i in ret.FUNCTION_KEYS) { + name = ret.FUNCTION_KEYS[i].toLowerCase(); + ret[name] = parseInt(i, 10); + } + for (i in ret.PRINTABLE_KEYS) { + name = ret.PRINTABLE_KEYS[i].toLowerCase(); + ret[name] = parseInt(i, 10); + } + oop.mixin(ret, ret.MODIFIER_KEYS); + oop.mixin(ret, ret.PRINTABLE_KEYS); + oop.mixin(ret, ret.FUNCTION_KEYS); + ret.enter = ret["return"]; + ret.escape = ret.esc; + ret.del = ret["delete"]; + ret[173] = '-'; + + (function() { + var mods = ["cmd", "ctrl", "alt", "shift"]; + for (var i = Math.pow(2, mods.length); i--;) { + ret.KEY_MODS[i] = mods.filter(function(x) { + return i & ret.KEY_MODS[x]; + }).join("-") + "-"; + } + })(); + + ret.KEY_MODS[0] = ""; + ret.KEY_MODS[-1] = "input-"; + + return ret; +})(); +oop.mixin(exports, Keys); + +exports.keyCodeToString = function(keyCode) { + var keyString = Keys[keyCode]; + if (typeof keyString != "string") + keyString = String.fromCharCode(keyCode); + return keyString.toLowerCase(); +}; + +}); + +ace.define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"], function(require, exports, module) { +"use strict"; + +var keys = require("./keys"); +var useragent = require("./useragent"); + +var pressedKeys = null; +var ts = 0; + +var activeListenerOptions; +function detectListenerOptionsSupport() { + activeListenerOptions = false; + try { + document.createComment("").addEventListener("test", function() {}, { + get passive() { + activeListenerOptions = {passive: false}; + } + }); + } catch(e) {} +} + +function getListenerOptions() { + if (activeListenerOptions == undefined) + detectListenerOptionsSupport(); + return activeListenerOptions; +} + +function EventListener(elem, type, callback) { + this.elem = elem; + this.type = type; + this.callback = callback; +} +EventListener.prototype.destroy = function() { + removeListener(this.elem, this.type, this.callback); + this.elem = this.type = this.callback = undefined; +}; + +var addListener = exports.addListener = function(elem, type, callback, destroyer) { + elem.addEventListener(type, callback, getListenerOptions()); + if (destroyer) + destroyer.$toDestroy.push(new EventListener(elem, type, callback)); +}; + +var removeListener = exports.removeListener = function(elem, type, callback) { + elem.removeEventListener(type, callback, getListenerOptions()); +}; +exports.stopEvent = function(e) { + exports.stopPropagation(e); + exports.preventDefault(e); + return false; +}; + +exports.stopPropagation = function(e) { + if (e.stopPropagation) + e.stopPropagation(); +}; + +exports.preventDefault = function(e) { + if (e.preventDefault) + e.preventDefault(); +}; +exports.getButton = function(e) { + if (e.type == "dblclick") + return 0; + if (e.type == "contextmenu" || (useragent.isMac && (e.ctrlKey && !e.altKey && !e.shiftKey))) + return 2; + return e.button; +}; + +exports.capture = function(el, eventHandler, releaseCaptureHandler) { + var ownerDocument = el && el.ownerDocument || document; + function onMouseUp(e) { + eventHandler && eventHandler(e); + releaseCaptureHandler && releaseCaptureHandler(e); + + removeListener(ownerDocument, "mousemove", eventHandler); + removeListener(ownerDocument, "mouseup", onMouseUp); + removeListener(ownerDocument, "dragstart", onMouseUp); + } + + addListener(ownerDocument, "mousemove", eventHandler); + addListener(ownerDocument, "mouseup", onMouseUp); + addListener(ownerDocument, "dragstart", onMouseUp); + + return onMouseUp; +}; + +exports.addMouseWheelListener = function(el, callback, destroyer) { + if ("onmousewheel" in el) { + addListener(el, "mousewheel", function(e) { + var factor = 8; + if (e.wheelDeltaX !== undefined) { + e.wheelX = -e.wheelDeltaX / factor; + e.wheelY = -e.wheelDeltaY / factor; + } else { + e.wheelX = 0; + e.wheelY = -e.wheelDelta / factor; + } + callback(e); + }, destroyer); + } else if ("onwheel" in el) { + addListener(el, "wheel", function(e) { + var factor = 0.35; + switch (e.deltaMode) { + case e.DOM_DELTA_PIXEL: + e.wheelX = e.deltaX * factor || 0; + e.wheelY = e.deltaY * factor || 0; + break; + case e.DOM_DELTA_LINE: + case e.DOM_DELTA_PAGE: + e.wheelX = (e.deltaX || 0) * 5; + e.wheelY = (e.deltaY || 0) * 5; + break; + } + + callback(e); + }, destroyer); + } else { + addListener(el, "DOMMouseScroll", function(e) { + if (e.axis && e.axis == e.HORIZONTAL_AXIS) { + e.wheelX = (e.detail || 0) * 5; + e.wheelY = 0; + } else { + e.wheelX = 0; + e.wheelY = (e.detail || 0) * 5; + } + callback(e); + }, destroyer); + } +}; + +exports.addMultiMouseDownListener = function(elements, timeouts, eventHandler, callbackName, destroyer) { + var clicks = 0; + var startX, startY, timer; + var eventNames = { + 2: "dblclick", + 3: "tripleclick", + 4: "quadclick" + }; + + function onMousedown(e) { + if (exports.getButton(e) !== 0) { + clicks = 0; + } else if (e.detail > 1) { + clicks++; + if (clicks > 4) + clicks = 1; + } else { + clicks = 1; + } + if (useragent.isIE) { + var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5; + if (!timer || isNewClick) + clicks = 1; + if (timer) + clearTimeout(timer); + timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600); + + if (clicks == 1) { + startX = e.clientX; + startY = e.clientY; + } + } + + e._clicks = clicks; + + eventHandler[callbackName]("mousedown", e); + + if (clicks > 4) + clicks = 0; + else if (clicks > 1) + return eventHandler[callbackName](eventNames[clicks], e); + } + if (!Array.isArray(elements)) + elements = [elements]; + elements.forEach(function(el) { + addListener(el, "mousedown", onMousedown, destroyer); + }); +}; + +var getModifierHash = function(e) { + return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0); +}; + +exports.getModifierString = function(e) { + return keys.KEY_MODS[getModifierHash(e)]; +}; + +function normalizeCommandKeys(callback, e, keyCode) { + var hashId = getModifierHash(e); + + if (!useragent.isMac && pressedKeys) { + if (e.getModifierState && (e.getModifierState("OS") || e.getModifierState("Win"))) + hashId |= 8; + if (pressedKeys.altGr) { + if ((3 & hashId) != 3) + pressedKeys.altGr = 0; + else + return; + } + if (keyCode === 18 || keyCode === 17) { + var location = "location" in e ? e.location : e.keyLocation; + if (keyCode === 17 && location === 1) { + if (pressedKeys[keyCode] == 1) + ts = e.timeStamp; + } else if (keyCode === 18 && hashId === 3 && location === 2) { + var dt = e.timeStamp - ts; + if (dt < 50) + pressedKeys.altGr = true; + } + } + } + + if (keyCode in keys.MODIFIER_KEYS) { + keyCode = -1; + } + + if (!hashId && keyCode === 13) { + var location = "location" in e ? e.location : e.keyLocation; + if (location === 3) { + callback(e, hashId, -keyCode); + if (e.defaultPrevented) + return; + } + } + + if (useragent.isChromeOS && hashId & 8) { + callback(e, hashId, keyCode); + if (e.defaultPrevented) + return; + else + hashId &= ~8; + } + if (!hashId && !(keyCode in keys.FUNCTION_KEYS) && !(keyCode in keys.PRINTABLE_KEYS)) { + return false; + } + + return callback(e, hashId, keyCode); +} + + +exports.addCommandKeyListener = function(el, callback, destroyer) { + if (useragent.isOldGecko || (useragent.isOpera && !("KeyboardEvent" in window))) { + var lastKeyDownKeyCode = null; + addListener(el, "keydown", function(e) { + lastKeyDownKeyCode = e.keyCode; + }, destroyer); + addListener(el, "keypress", function(e) { + return normalizeCommandKeys(callback, e, lastKeyDownKeyCode); + }, destroyer); + } else { + var lastDefaultPrevented = null; + + addListener(el, "keydown", function(e) { + pressedKeys[e.keyCode] = (pressedKeys[e.keyCode] || 0) + 1; + var result = normalizeCommandKeys(callback, e, e.keyCode); + lastDefaultPrevented = e.defaultPrevented; + return result; + }, destroyer); + + addListener(el, "keypress", function(e) { + if (lastDefaultPrevented && (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey)) { + exports.stopEvent(e); + lastDefaultPrevented = null; + } + }, destroyer); + + addListener(el, "keyup", function(e) { + pressedKeys[e.keyCode] = null; + }, destroyer); + + if (!pressedKeys) { + resetPressedKeys(); + addListener(window, "focus", resetPressedKeys); + } + } +}; +function resetPressedKeys() { + pressedKeys = Object.create(null); +} + +if (typeof window == "object" && window.postMessage && !useragent.isOldIE) { + var postMessageId = 1; + exports.nextTick = function(callback, win) { + win = win || window; + var messageName = "zero-timeout-message-" + (postMessageId++); + + var listener = function(e) { + if (e.data == messageName) { + exports.stopPropagation(e); + removeListener(win, "message", listener); + callback(); + } + }; + + addListener(win, "message", listener); + win.postMessage(messageName, "*"); + }; +} + +exports.$idleBlocked = false; +exports.onIdle = function(cb, timeout) { + return setTimeout(function handler() { + if (!exports.$idleBlocked) { + cb(); + } else { + setTimeout(handler, 100); + } + }, timeout); +}; + +exports.$idleBlockId = null; +exports.blockIdle = function(delay) { + if (exports.$idleBlockId) + clearTimeout(exports.$idleBlockId); + + exports.$idleBlocked = true; + exports.$idleBlockId = setTimeout(function() { + exports.$idleBlocked = false; + }, delay || 100); +}; + +exports.nextFrame = typeof window == "object" && (window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || window.oRequestAnimationFrame); + +if (exports.nextFrame) + exports.nextFrame = exports.nextFrame.bind(window); +else + exports.nextFrame = function(callback) { + setTimeout(callback, 17); + }; +}); + +ace.define("ace/range",["require","exports","module"], function(require, exports, module) { +"use strict"; +var comparePoints = function(p1, p2) { + return p1.row - p2.row || p1.column - p2.column; +}; +var Range = function(startRow, startColumn, endRow, endColumn) { + this.start = { + row: startRow, + column: startColumn + }; + + this.end = { + row: endRow, + column: endColumn + }; +}; + +(function() { + this.isEqual = function(range) { + return this.start.row === range.start.row && + this.end.row === range.end.row && + this.start.column === range.start.column && + this.end.column === range.end.column; + }; + this.toString = function() { + return ("Range: [" + this.start.row + "/" + this.start.column + + "] -> [" + this.end.row + "/" + this.end.column + "]"); + }; + + this.contains = function(row, column) { + return this.compare(row, column) == 0; + }; + this.compareRange = function(range) { + var cmp, + end = range.end, + start = range.start; + + cmp = this.compare(end.row, end.column); + if (cmp == 1) { + cmp = this.compare(start.row, start.column); + if (cmp == 1) { + return 2; + } else if (cmp == 0) { + return 1; + } else { + return 0; + } + } else if (cmp == -1) { + return -2; + } else { + cmp = this.compare(start.row, start.column); + if (cmp == -1) { + return -1; + } else if (cmp == 1) { + return 42; + } else { + return 0; + } + } + }; + this.comparePoint = function(p) { + return this.compare(p.row, p.column); + }; + this.containsRange = function(range) { + return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0; + }; + this.intersects = function(range) { + var cmp = this.compareRange(range); + return (cmp == -1 || cmp == 0 || cmp == 1); + }; + this.isEnd = function(row, column) { + return this.end.row == row && this.end.column == column; + }; + this.isStart = function(row, column) { + return this.start.row == row && this.start.column == column; + }; + this.setStart = function(row, column) { + if (typeof row == "object") { + this.start.column = row.column; + this.start.row = row.row; + } else { + this.start.row = row; + this.start.column = column; + } + }; + this.setEnd = function(row, column) { + if (typeof row == "object") { + this.end.column = row.column; + this.end.row = row.row; + } else { + this.end.row = row; + this.end.column = column; + } + }; + this.inside = function(row, column) { + if (this.compare(row, column) == 0) { + if (this.isEnd(row, column) || this.isStart(row, column)) { + return false; + } else { + return true; + } + } + return false; + }; + this.insideStart = function(row, column) { + if (this.compare(row, column) == 0) { + if (this.isEnd(row, column)) { + return false; + } else { + return true; + } + } + return false; + }; + this.insideEnd = function(row, column) { + if (this.compare(row, column) == 0) { + if (this.isStart(row, column)) { + return false; + } else { + return true; + } + } + return false; + }; + this.compare = function(row, column) { + if (!this.isMultiLine()) { + if (row === this.start.row) { + return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0); + } + } + + if (row < this.start.row) + return -1; + + if (row > this.end.row) + return 1; + + if (this.start.row === row) + return column >= this.start.column ? 0 : -1; + + if (this.end.row === row) + return column <= this.end.column ? 0 : 1; + + return 0; + }; + this.compareStart = function(row, column) { + if (this.start.row == row && this.start.column == column) { + return -1; + } else { + return this.compare(row, column); + } + }; + this.compareEnd = function(row, column) { + if (this.end.row == row && this.end.column == column) { + return 1; + } else { + return this.compare(row, column); + } + }; + this.compareInside = function(row, column) { + if (this.end.row == row && this.end.column == column) { + return 1; + } else if (this.start.row == row && this.start.column == column) { + return -1; + } else { + return this.compare(row, column); + } + }; + this.clipRows = function(firstRow, lastRow) { + if (this.end.row > lastRow) + var end = {row: lastRow + 1, column: 0}; + else if (this.end.row < firstRow) + var end = {row: firstRow, column: 0}; + + if (this.start.row > lastRow) + var start = {row: lastRow + 1, column: 0}; + else if (this.start.row < firstRow) + var start = {row: firstRow, column: 0}; + + return Range.fromPoints(start || this.start, end || this.end); + }; + this.extend = function(row, column) { + var cmp = this.compare(row, column); + + if (cmp == 0) + return this; + else if (cmp == -1) + var start = {row: row, column: column}; + else + var end = {row: row, column: column}; + + return Range.fromPoints(start || this.start, end || this.end); + }; + + this.isEmpty = function() { + return (this.start.row === this.end.row && this.start.column === this.end.column); + }; + this.isMultiLine = function() { + return (this.start.row !== this.end.row); + }; + this.clone = function() { + return Range.fromPoints(this.start, this.end); + }; + this.collapseRows = function() { + if (this.end.column == 0) + return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0); + else + return new Range(this.start.row, 0, this.end.row, 0); + }; + this.toScreenRange = function(session) { + var screenPosStart = session.documentToScreenPosition(this.start); + var screenPosEnd = session.documentToScreenPosition(this.end); + + return new Range( + screenPosStart.row, screenPosStart.column, + screenPosEnd.row, screenPosEnd.column + ); + }; + this.moveBy = function(row, column) { + this.start.row += row; + this.start.column += column; + this.end.row += row; + this.end.column += column; + }; + +}).call(Range.prototype); +Range.fromPoints = function(start, end) { + return new Range(start.row, start.column, end.row, end.column); +}; +Range.comparePoints = comparePoints; + +Range.comparePoints = function(p1, p2) { + return p1.row - p2.row || p1.column - p2.column; +}; + + +exports.Range = Range; +}); + +ace.define("ace/lib/lang",["require","exports","module"], function(require, exports, module) { +"use strict"; + +exports.last = function(a) { + return a[a.length - 1]; +}; + +exports.stringReverse = function(string) { + return string.split("").reverse().join(""); +}; + +exports.stringRepeat = function (string, count) { + var result = ''; + while (count > 0) { + if (count & 1) + result += string; + + if (count >>= 1) + string += string; + } + return result; +}; + +var trimBeginRegexp = /^\s\s*/; +var trimEndRegexp = /\s\s*$/; + +exports.stringTrimLeft = function (string) { + return string.replace(trimBeginRegexp, ''); +}; + +exports.stringTrimRight = function (string) { + return string.replace(trimEndRegexp, ''); +}; + +exports.copyObject = function(obj) { + var copy = {}; + for (var key in obj) { + copy[key] = obj[key]; + } + return copy; +}; + +exports.copyArray = function(array){ + var copy = []; + for (var i=0, l=array.length; i Date.now() - 50) + return true; + return $cancelT = false; + }, + cancel: function() { + $cancelT = Date.now(); + } +}; + +}); + +ace.define("ace/keyboard/textinput",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/dom","ace/lib/lang","ace/clipboard","ace/lib/keys"], function(require, exports, module) { +"use strict"; + +var event = require("../lib/event"); +var useragent = require("../lib/useragent"); +var dom = require("../lib/dom"); +var lang = require("../lib/lang"); +var clipboard = require("../clipboard"); +var BROKEN_SETDATA = useragent.isChrome < 18; +var USE_IE_MIME_TYPE = useragent.isIE; +var HAS_FOCUS_ARGS = useragent.isChrome > 63; +var MAX_LINE_LENGTH = 400; + +var KEYS = require("../lib/keys"); +var MODS = KEYS.KEY_MODS; +var isIOS = useragent.isIOS; +var valueResetRegex = isIOS ? /\s/ : /\n/; +var isMobile = useragent.isMobile; + +var TextInput = function(parentNode, host) { + var text = dom.createElement("textarea"); + text.className = "ace_text-input"; + + text.setAttribute("wrap", "off"); + text.setAttribute("autocorrect", "off"); + text.setAttribute("autocapitalize", "off"); + text.setAttribute("spellcheck", false); + + text.style.opacity = "0"; + parentNode.insertBefore(text, parentNode.firstChild); + + var copied = false; + var pasted = false; + var inComposition = false; + var sendingText = false; + var tempStyle = ''; + + if (!isMobile) + text.style.fontSize = "1px"; + + var commandMode = false; + var ignoreFocusEvents = false; + + var lastValue = ""; + var lastSelectionStart = 0; + var lastSelectionEnd = 0; + var lastRestoreEnd = 0; + try { var isFocused = document.activeElement === text; } catch(e) {} + + event.addListener(text, "blur", function(e) { + if (ignoreFocusEvents) return; + host.onBlur(e); + isFocused = false; + }, host); + event.addListener(text, "focus", function(e) { + if (ignoreFocusEvents) return; + isFocused = true; + if (useragent.isEdge) { + try { + if (!document.hasFocus()) + return; + } catch(e) {} + } + host.onFocus(e); + if (useragent.isEdge) + setTimeout(resetSelection); + else + resetSelection(); + }, host); + this.$focusScroll = false; + this.focus = function() { + if (tempStyle || HAS_FOCUS_ARGS || this.$focusScroll == "browser") + return text.focus({ preventScroll: true }); + + var top = text.style.top; + text.style.position = "fixed"; + text.style.top = "0px"; + try { + var isTransformed = text.getBoundingClientRect().top != 0; + } catch(e) { + return; + } + var ancestors = []; + if (isTransformed) { + var t = text.parentElement; + while (t && t.nodeType == 1) { + ancestors.push(t); + t.setAttribute("ace_nocontext", true); + if (!t.parentElement && t.getRootNode) + t = t.getRootNode().host; + else + t = t.parentElement; + } + } + text.focus({ preventScroll: true }); + if (isTransformed) { + ancestors.forEach(function(p) { + p.removeAttribute("ace_nocontext"); + }); + } + setTimeout(function() { + text.style.position = ""; + if (text.style.top == "0px") + text.style.top = top; + }, 0); + }; + this.blur = function() { + text.blur(); + }; + this.isFocused = function() { + return isFocused; + }; + + host.on("beforeEndOperation", function() { + var curOp = host.curOp; + var commandName = curOp && curOp.command && curOp.command.name; + if (commandName == "insertstring") + return; + var isUserAction = commandName && (curOp.docChanged || curOp.selectionChanged); + if (inComposition && isUserAction) { + lastValue = text.value = ""; + onCompositionEnd(); + } + resetSelection(); + }); + + var resetSelection = isIOS + ? function(value) { + if (!isFocused || (copied && !value) || sendingText) return; + if (!value) + value = ""; + var newValue = "\n ab" + value + "cde fg\n"; + if (newValue != text.value) + text.value = lastValue = newValue; + + var selectionStart = 4; + var selectionEnd = 4 + (value.length || (host.selection.isEmpty() ? 0 : 1)); + + if (lastSelectionStart != selectionStart || lastSelectionEnd != selectionEnd) { + text.setSelectionRange(selectionStart, selectionEnd); + } + lastSelectionStart = selectionStart; + lastSelectionEnd = selectionEnd; + } + : function() { + if (inComposition || sendingText) + return; + if (!isFocused && !afterContextMenu) + return; + inComposition = true; + + var selectionStart = 0; + var selectionEnd = 0; + var line = ""; + + if (host.session) { + var selection = host.selection; + var range = selection.getRange(); + var row = selection.cursor.row; + selectionStart = range.start.column; + selectionEnd = range.end.column; + line = host.session.getLine(row); + + if (range.start.row != row) { + var prevLine = host.session.getLine(row - 1); + selectionStart = range.start.row < row - 1 ? 0 : selectionStart; + selectionEnd += prevLine.length + 1; + line = prevLine + "\n" + line; + } + else if (range.end.row != row) { + var nextLine = host.session.getLine(row + 1); + selectionEnd = range.end.row > row + 1 ? nextLine.length : selectionEnd; + selectionEnd += line.length + 1; + line = line + "\n" + nextLine; + } + else if (isMobile && row > 0) { + line = "\n" + line; + selectionEnd += 1; + selectionStart += 1; + } + + if (line.length > MAX_LINE_LENGTH) { + if (selectionStart < MAX_LINE_LENGTH && selectionEnd < MAX_LINE_LENGTH) { + line = line.slice(0, MAX_LINE_LENGTH); + } else { + line = "\n"; + if (selectionStart == selectionEnd) { + selectionStart = selectionEnd = 0; + } + else { + selectionStart = 0; + selectionEnd = 1; + } + } + } + } + + var newValue = line + "\n\n"; + if (newValue != lastValue) { + text.value = lastValue = newValue; + lastSelectionStart = lastSelectionEnd = newValue.length; + } + if (afterContextMenu) { + lastSelectionStart = text.selectionStart; + lastSelectionEnd = text.selectionEnd; + } + if ( + lastSelectionEnd != selectionEnd + || lastSelectionStart != selectionStart + || text.selectionEnd != lastSelectionEnd // on ie edge selectionEnd changes silently after the initialization + ) { + try { + text.setSelectionRange(selectionStart, selectionEnd); + lastSelectionStart = selectionStart; + lastSelectionEnd = selectionEnd; + } catch(e){} + } + inComposition = false; + }; + this.resetSelection = resetSelection; + + if (isFocused) + host.onFocus(); + + + var isAllSelected = function(text) { + return text.selectionStart === 0 && text.selectionEnd >= lastValue.length + && text.value === lastValue && lastValue + && text.selectionEnd !== lastSelectionEnd; + }; + + var onSelect = function(e) { + if (inComposition) + return; + if (copied) { + copied = false; + } else if (isAllSelected(text)) { + host.selectAll(); + resetSelection(); + } else if (isMobile && text.selectionStart != lastSelectionStart) { + resetSelection(); + } + }; + + var inputHandler = null; + this.setInputHandler = function(cb) {inputHandler = cb;}; + this.getInputHandler = function() {return inputHandler;}; + var afterContextMenu = false; + + var sendText = function(value, fromInput) { + if (afterContextMenu) + afterContextMenu = false; + if (pasted) { + resetSelection(); + if (value) + host.onPaste(value); + pasted = false; + return ""; + } else { + var selectionStart = text.selectionStart; + var selectionEnd = text.selectionEnd; + + var extendLeft = lastSelectionStart; + var extendRight = lastValue.length - lastSelectionEnd; + + var inserted = value; + var restoreStart = value.length - selectionStart; + var restoreEnd = value.length - selectionEnd; + + var i = 0; + while (extendLeft > 0 && lastValue[i] == value[i]) { + i++; + extendLeft--; + } + inserted = inserted.slice(i); + i = 1; + while (extendRight > 0 && lastValue.length - i > lastSelectionStart - 1 && lastValue[lastValue.length - i] == value[value.length - i]) { + i++; + extendRight--; + } + restoreStart -= i-1; + restoreEnd -= i-1; + var endIndex = inserted.length - i + 1; + if (endIndex < 0) { + extendLeft = -endIndex; + endIndex = 0; + } + inserted = inserted.slice(0, endIndex); + if (!fromInput && !inserted && !restoreStart && !extendLeft && !extendRight && !restoreEnd) + return ""; + sendingText = true; + var shouldReset = false; + if (useragent.isAndroid && inserted == ". ") { + inserted = " "; + shouldReset = true; + } + + if (inserted && !extendLeft && !extendRight && !restoreStart && !restoreEnd || commandMode) { + host.onTextInput(inserted); + } else { + host.onTextInput(inserted, { + extendLeft: extendLeft, + extendRight: extendRight, + restoreStart: restoreStart, + restoreEnd: restoreEnd + }); + } + sendingText = false; + + lastValue = value; + lastSelectionStart = selectionStart; + lastSelectionEnd = selectionEnd; + lastRestoreEnd = restoreEnd; + return shouldReset ? "\n" : inserted; + } + }; + var onInput = function(e) { + if (inComposition) + return onCompositionUpdate(); + if (e && e.inputType) { + if (e.inputType == "historyUndo") return host.execCommand("undo"); + if (e.inputType == "historyRedo") return host.execCommand("redo"); + } + var data = text.value; + var inserted = sendText(data, true); + if ( + data.length > MAX_LINE_LENGTH + 100 + || valueResetRegex.test(inserted) + || isMobile && lastSelectionStart < 1 && lastSelectionStart == lastSelectionEnd + ) { + resetSelection(); + } + }; + + var handleClipboardData = function(e, data, forceIEMime) { + var clipboardData = e.clipboardData || window.clipboardData; + if (!clipboardData || BROKEN_SETDATA) + return; + var mime = USE_IE_MIME_TYPE || forceIEMime ? "Text" : "text/plain"; + try { + if (data) { + return clipboardData.setData(mime, data) !== false; + } else { + return clipboardData.getData(mime); + } + } catch(e) { + if (!forceIEMime) + return handleClipboardData(e, data, true); + } + }; + + var doCopy = function(e, isCut) { + var data = host.getCopyText(); + if (!data) + return event.preventDefault(e); + + if (handleClipboardData(e, data)) { + if (isIOS) { + resetSelection(data); + copied = data; + setTimeout(function () { + copied = false; + }, 10); + } + isCut ? host.onCut() : host.onCopy(); + event.preventDefault(e); + } else { + copied = true; + text.value = data; + text.select(); + setTimeout(function(){ + copied = false; + resetSelection(); + isCut ? host.onCut() : host.onCopy(); + }); + } + }; + + var onCut = function(e) { + doCopy(e, true); + }; + + var onCopy = function(e) { + doCopy(e, false); + }; + + var onPaste = function(e) { + var data = handleClipboardData(e); + if (clipboard.pasteCancelled()) + return; + if (typeof data == "string") { + if (data) + host.onPaste(data, e); + if (useragent.isIE) + setTimeout(resetSelection); + event.preventDefault(e); + } + else { + text.value = ""; + pasted = true; + } + }; + + event.addCommandKeyListener(text, host.onCommandKey.bind(host), host); + + event.addListener(text, "select", onSelect, host); + event.addListener(text, "input", onInput, host); + + event.addListener(text, "cut", onCut, host); + event.addListener(text, "copy", onCopy, host); + event.addListener(text, "paste", onPaste, host); + if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)) { + event.addListener(parentNode, "keydown", function(e) { + if ((useragent.isMac && !e.metaKey) || !e.ctrlKey) + return; + + switch (e.keyCode) { + case 67: + onCopy(e); + break; + case 86: + onPaste(e); + break; + case 88: + onCut(e); + break; + } + }, host); + } + var onCompositionStart = function(e) { + if (inComposition || !host.onCompositionStart || host.$readOnly) + return; + + inComposition = {}; + + if (commandMode) + return; + + if (e.data) + inComposition.useTextareaForIME = false; + + setTimeout(onCompositionUpdate, 0); + host._signal("compositionStart"); + host.on("mousedown", cancelComposition); + + var range = host.getSelectionRange(); + range.end.row = range.start.row; + range.end.column = range.start.column; + inComposition.markerRange = range; + inComposition.selectionStart = lastSelectionStart; + host.onCompositionStart(inComposition); + + if (inComposition.useTextareaForIME) { + lastValue = text.value = ""; + lastSelectionStart = 0; + lastSelectionEnd = 0; + } + else { + if (text.msGetInputContext) + inComposition.context = text.msGetInputContext(); + if (text.getInputContext) + inComposition.context = text.getInputContext(); + } + }; + + var onCompositionUpdate = function() { + if (!inComposition || !host.onCompositionUpdate || host.$readOnly) + return; + if (commandMode) + return cancelComposition(); + + if (inComposition.useTextareaForIME) { + host.onCompositionUpdate(text.value); + } + else { + var data = text.value; + sendText(data); + if (inComposition.markerRange) { + if (inComposition.context) { + inComposition.markerRange.start.column = inComposition.selectionStart + = inComposition.context.compositionStartOffset; + } + inComposition.markerRange.end.column = inComposition.markerRange.start.column + + lastSelectionEnd - inComposition.selectionStart + lastRestoreEnd; + } + } + }; + + var onCompositionEnd = function(e) { + if (!host.onCompositionEnd || host.$readOnly) return; + inComposition = false; + host.onCompositionEnd(); + host.off("mousedown", cancelComposition); + if (e) onInput(); + }; + + + function cancelComposition() { + ignoreFocusEvents = true; + text.blur(); + text.focus(); + ignoreFocusEvents = false; + } + + var syncComposition = lang.delayedCall(onCompositionUpdate, 50).schedule.bind(null, null); + + function onKeyup(e) { + if (e.keyCode == 27 && text.value.length < text.selectionStart) { + if (!inComposition) + lastValue = text.value; + lastSelectionStart = lastSelectionEnd = -1; + resetSelection(); + } + syncComposition(); + } + + event.addListener(text, "compositionstart", onCompositionStart, host); + event.addListener(text, "compositionupdate", onCompositionUpdate, host); + event.addListener(text, "keyup", onKeyup, host); + event.addListener(text, "keydown", syncComposition, host); + event.addListener(text, "compositionend", onCompositionEnd, host); + + this.getElement = function() { + return text; + }; + this.setCommandMode = function(value) { + commandMode = value; + text.readOnly = false; + }; + + this.setReadOnly = function(readOnly) { + if (!commandMode) + text.readOnly = readOnly; + }; + + this.setCopyWithEmptySelection = function(value) { + }; + + this.onContextMenu = function(e) { + afterContextMenu = true; + resetSelection(); + host._emit("nativecontextmenu", {target: host, domEvent: e}); + this.moveToMouse(e, true); + }; + + this.moveToMouse = function(e, bringToFront) { + if (!tempStyle) + tempStyle = text.style.cssText; + text.style.cssText = (bringToFront ? "z-index:100000;" : "") + + (useragent.isIE ? "opacity:0.1;" : "") + + "text-indent: -" + (lastSelectionStart + lastSelectionEnd) * host.renderer.characterWidth * 0.5 + "px;"; + + var rect = host.container.getBoundingClientRect(); + var style = dom.computedStyle(host.container); + var top = rect.top + (parseInt(style.borderTopWidth) || 0); + var left = rect.left + (parseInt(rect.borderLeftWidth) || 0); + var maxTop = rect.bottom - top - text.clientHeight -2; + var move = function(e) { + dom.translate(text, e.clientX - left - 2, Math.min(e.clientY - top - 2, maxTop)); + }; + move(e); + + if (e.type != "mousedown") + return; + + host.renderer.$isMousePressed = true; + + clearTimeout(closeTimeout); + if (useragent.isWin) + event.capture(host.container, move, onContextMenuClose); + }; + + this.onContextMenuClose = onContextMenuClose; + var closeTimeout; + function onContextMenuClose() { + clearTimeout(closeTimeout); + closeTimeout = setTimeout(function () { + if (tempStyle) { + text.style.cssText = tempStyle; + tempStyle = ''; + } + host.renderer.$isMousePressed = false; + if (host.renderer.$keepTextAreaAtCursor) + host.renderer.$moveTextAreaToCursor(); + }, 0); + } + + var onContextMenu = function(e) { + host.textInput.onContextMenu(e); + onContextMenuClose(); + }; + event.addListener(text, "mouseup", onContextMenu, host); + event.addListener(text, "mousedown", function(e) { + e.preventDefault(); + onContextMenuClose(); + }, host); + event.addListener(host.renderer.scroller, "contextmenu", onContextMenu, host); + event.addListener(text, "contextmenu", onContextMenu, host); + + if (isIOS) + addIosSelectionHandler(parentNode, host, text); + + function addIosSelectionHandler(parentNode, host, text) { + var typingResetTimeout = null; + var typing = false; + + text.addEventListener("keydown", function (e) { + if (typingResetTimeout) clearTimeout(typingResetTimeout); + typing = true; + }, true); + + text.addEventListener("keyup", function (e) { + typingResetTimeout = setTimeout(function () { + typing = false; + }, 100); + }, true); + var detectArrowKeys = function(e) { + if (document.activeElement !== text) return; + if (typing || inComposition || host.$mouseHandler.isMousePressed) return; + + if (copied) { + return; + } + var selectionStart = text.selectionStart; + var selectionEnd = text.selectionEnd; + + var key = null; + var modifier = 0; + if (selectionStart == 0) { + key = KEYS.up; + } else if (selectionStart == 1) { + key = KEYS.home; + } else if (selectionEnd > lastSelectionEnd && lastValue[selectionEnd] == "\n") { + key = KEYS.end; + } else if (selectionStart < lastSelectionStart && lastValue[selectionStart - 1] == " ") { + key = KEYS.left; + modifier = MODS.option; + } else if ( + selectionStart < lastSelectionStart + || ( + selectionStart == lastSelectionStart + && lastSelectionEnd != lastSelectionStart + && selectionStart == selectionEnd + ) + ) { + key = KEYS.left; + } else if (selectionEnd > lastSelectionEnd && lastValue.slice(0, selectionEnd).split("\n").length > 2) { + key = KEYS.down; + } else if (selectionEnd > lastSelectionEnd && lastValue[selectionEnd - 1] == " ") { + key = KEYS.right; + modifier = MODS.option; + } else if ( + selectionEnd > lastSelectionEnd + || ( + selectionEnd == lastSelectionEnd + && lastSelectionEnd != lastSelectionStart + && selectionStart == selectionEnd + ) + ) { + key = KEYS.right; + } + + if (selectionStart !== selectionEnd) + modifier |= MODS.shift; + + if (key) { + var result = host.onCommandKey({}, modifier, key); + if (!result && host.commands) { + key = KEYS.keyCodeToString(key); + var command = host.commands.findKeyCommand(modifier, key); + if (command) + host.execCommand(command); + } + lastSelectionStart = selectionStart; + lastSelectionEnd = selectionEnd; + resetSelection(""); + } + }; + document.addEventListener("selectionchange", detectArrowKeys); + host.on("destroy", function() { + document.removeEventListener("selectionchange", detectArrowKeys); + }); + } +}; + +exports.TextInput = TextInput; +exports.$setUserAgentForTests = function(_isMobile, _isIOS) { + isMobile = _isMobile; + isIOS = _isIOS; +}; +}); + +ace.define("ace/mouse/default_handlers",["require","exports","module","ace/lib/useragent"], function(require, exports, module) { +"use strict"; + +var useragent = require("../lib/useragent"); + +var DRAG_OFFSET = 0; // pixels +var SCROLL_COOLDOWN_T = 550; // milliseconds + +function DefaultHandlers(mouseHandler) { + mouseHandler.$clickSelection = null; + + var editor = mouseHandler.editor; + editor.setDefaultHandler("mousedown", this.onMouseDown.bind(mouseHandler)); + editor.setDefaultHandler("dblclick", this.onDoubleClick.bind(mouseHandler)); + editor.setDefaultHandler("tripleclick", this.onTripleClick.bind(mouseHandler)); + editor.setDefaultHandler("quadclick", this.onQuadClick.bind(mouseHandler)); + editor.setDefaultHandler("mousewheel", this.onMouseWheel.bind(mouseHandler)); + + var exports = ["select", "startSelect", "selectEnd", "selectAllEnd", "selectByWordsEnd", + "selectByLinesEnd", "dragWait", "dragWaitEnd", "focusWait"]; + + exports.forEach(function(x) { + mouseHandler[x] = this[x]; + }, this); + + mouseHandler.selectByLines = this.extendSelectionBy.bind(mouseHandler, "getLineRange"); + mouseHandler.selectByWords = this.extendSelectionBy.bind(mouseHandler, "getWordRange"); +} + +(function() { + + this.onMouseDown = function(ev) { + var inSelection = ev.inSelection(); + var pos = ev.getDocumentPosition(); + this.mousedownEvent = ev; + var editor = this.editor; + + var button = ev.getButton(); + if (button !== 0) { + var selectionRange = editor.getSelectionRange(); + var selectionEmpty = selectionRange.isEmpty(); + if (selectionEmpty || button == 1) + editor.selection.moveToPosition(pos); + if (button == 2) { + editor.textInput.onContextMenu(ev.domEvent); + if (!useragent.isMozilla) + ev.preventDefault(); + } + return; + } + + this.mousedownEvent.time = Date.now(); + if (inSelection && !editor.isFocused()) { + editor.focus(); + if (this.$focusTimeout && !this.$clickSelection && !editor.inMultiSelectMode) { + this.setState("focusWait"); + this.captureMouse(ev); + return; + } + } + + this.captureMouse(ev); + this.startSelect(pos, ev.domEvent._clicks > 1); + return ev.preventDefault(); + }; + + this.startSelect = function(pos, waitForClickSelection) { + pos = pos || this.editor.renderer.screenToTextCoordinates(this.x, this.y); + var editor = this.editor; + if (!this.mousedownEvent) return; + if (this.mousedownEvent.getShiftKey()) + editor.selection.selectToPosition(pos); + else if (!waitForClickSelection) + editor.selection.moveToPosition(pos); + if (!waitForClickSelection) + this.select(); + if (editor.renderer.scroller.setCapture) { + editor.renderer.scroller.setCapture(); + } + editor.setStyle("ace_selecting"); + this.setState("select"); + }; + + this.select = function() { + var anchor, editor = this.editor; + var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y); + if (this.$clickSelection) { + var cmp = this.$clickSelection.comparePoint(cursor); + + if (cmp == -1) { + anchor = this.$clickSelection.end; + } else if (cmp == 1) { + anchor = this.$clickSelection.start; + } else { + var orientedRange = calcRangeOrientation(this.$clickSelection, cursor); + cursor = orientedRange.cursor; + anchor = orientedRange.anchor; + } + editor.selection.setSelectionAnchor(anchor.row, anchor.column); + } + editor.selection.selectToPosition(cursor); + editor.renderer.scrollCursorIntoView(); + }; + + this.extendSelectionBy = function(unitName) { + var anchor, editor = this.editor; + var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y); + var range = editor.selection[unitName](cursor.row, cursor.column); + if (this.$clickSelection) { + var cmpStart = this.$clickSelection.comparePoint(range.start); + var cmpEnd = this.$clickSelection.comparePoint(range.end); + + if (cmpStart == -1 && cmpEnd <= 0) { + anchor = this.$clickSelection.end; + if (range.end.row != cursor.row || range.end.column != cursor.column) + cursor = range.start; + } else if (cmpEnd == 1 && cmpStart >= 0) { + anchor = this.$clickSelection.start; + if (range.start.row != cursor.row || range.start.column != cursor.column) + cursor = range.end; + } else if (cmpStart == -1 && cmpEnd == 1) { + cursor = range.end; + anchor = range.start; + } else { + var orientedRange = calcRangeOrientation(this.$clickSelection, cursor); + cursor = orientedRange.cursor; + anchor = orientedRange.anchor; + } + editor.selection.setSelectionAnchor(anchor.row, anchor.column); + } + editor.selection.selectToPosition(cursor); + editor.renderer.scrollCursorIntoView(); + }; + + this.selectEnd = + this.selectAllEnd = + this.selectByWordsEnd = + this.selectByLinesEnd = function() { + this.$clickSelection = null; + this.editor.unsetStyle("ace_selecting"); + if (this.editor.renderer.scroller.releaseCapture) { + this.editor.renderer.scroller.releaseCapture(); + } + }; + + this.focusWait = function() { + var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y); + var time = Date.now(); + + if (distance > DRAG_OFFSET || time - this.mousedownEvent.time > this.$focusTimeout) + this.startSelect(this.mousedownEvent.getDocumentPosition()); + }; + + this.onDoubleClick = function(ev) { + var pos = ev.getDocumentPosition(); + var editor = this.editor; + var session = editor.session; + + var range = session.getBracketRange(pos); + if (range) { + if (range.isEmpty()) { + range.start.column--; + range.end.column++; + } + this.setState("select"); + } else { + range = editor.selection.getWordRange(pos.row, pos.column); + this.setState("selectByWords"); + } + this.$clickSelection = range; + this.select(); + }; + + this.onTripleClick = function(ev) { + var pos = ev.getDocumentPosition(); + var editor = this.editor; + + this.setState("selectByLines"); + var range = editor.getSelectionRange(); + if (range.isMultiLine() && range.contains(pos.row, pos.column)) { + this.$clickSelection = editor.selection.getLineRange(range.start.row); + this.$clickSelection.end = editor.selection.getLineRange(range.end.row).end; + } else { + this.$clickSelection = editor.selection.getLineRange(pos.row); + } + this.select(); + }; + + this.onQuadClick = function(ev) { + var editor = this.editor; + + editor.selectAll(); + this.$clickSelection = editor.getSelectionRange(); + this.setState("selectAll"); + }; + + this.onMouseWheel = function(ev) { + if (ev.getAccelKey()) + return; + if (ev.getShiftKey() && ev.wheelY && !ev.wheelX) { + ev.wheelX = ev.wheelY; + ev.wheelY = 0; + } + + var editor = this.editor; + + if (!this.$lastScroll) + this.$lastScroll = { t: 0, vx: 0, vy: 0, allowed: 0 }; + + var prevScroll = this.$lastScroll; + var t = ev.domEvent.timeStamp; + var dt = t - prevScroll.t; + var vx = dt ? ev.wheelX / dt : prevScroll.vx; + var vy = dt ? ev.wheelY / dt : prevScroll.vy; + if (dt < SCROLL_COOLDOWN_T) { + vx = (vx + prevScroll.vx) / 2; + vy = (vy + prevScroll.vy) / 2; + } + + var direction = Math.abs(vx / vy); + + var canScroll = false; + if (direction >= 1 && editor.renderer.isScrollableBy(ev.wheelX * ev.speed, 0)) + canScroll = true; + if (direction <= 1 && editor.renderer.isScrollableBy(0, ev.wheelY * ev.speed)) + canScroll = true; + + if (canScroll) { + prevScroll.allowed = t; + } else if (t - prevScroll.allowed < SCROLL_COOLDOWN_T) { + var isSlower = Math.abs(vx) <= 1.5 * Math.abs(prevScroll.vx) + && Math.abs(vy) <= 1.5 * Math.abs(prevScroll.vy); + if (isSlower) { + canScroll = true; + prevScroll.allowed = t; + } + else { + prevScroll.allowed = 0; + } + } + + prevScroll.t = t; + prevScroll.vx = vx; + prevScroll.vy = vy; + + if (canScroll) { + editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed); + return ev.stop(); + } + }; + +}).call(DefaultHandlers.prototype); + +exports.DefaultHandlers = DefaultHandlers; + +function calcDistance(ax, ay, bx, by) { + return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2)); +} + +function calcRangeOrientation(range, cursor) { + if (range.start.row == range.end.row) + var cmp = 2 * cursor.column - range.start.column - range.end.column; + else if (range.start.row == range.end.row - 1 && !range.start.column && !range.end.column) + var cmp = cursor.column - 4; + else + var cmp = 2 * cursor.row - range.start.row - range.end.row; + + if (cmp < 0) + return {cursor: range.start, anchor: range.end}; + else + return {cursor: range.end, anchor: range.start}; +} + +}); + +ace.define("ace/tooltip",["require","exports","module","ace/lib/oop","ace/lib/dom"], function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var dom = require("./lib/dom"); +function Tooltip (parentNode) { + this.isOpen = false; + this.$element = null; + this.$parentNode = parentNode; +} + +(function() { + this.$init = function() { + this.$element = dom.createElement("div"); + this.$element.className = "ace_tooltip"; + this.$element.style.display = "none"; + this.$parentNode.appendChild(this.$element); + return this.$element; + }; + this.getElement = function() { + return this.$element || this.$init(); + }; + this.setText = function(text) { + this.getElement().textContent = text; + }; + this.setHtml = function(html) { + this.getElement().innerHTML = html; + }; + this.setPosition = function(x, y) { + this.getElement().style.left = x + "px"; + this.getElement().style.top = y + "px"; + }; + this.setClassName = function(className) { + dom.addCssClass(this.getElement(), className); + }; + this.show = function(text, x, y) { + if (text != null) + this.setText(text); + if (x != null && y != null) + this.setPosition(x, y); + if (!this.isOpen) { + this.getElement().style.display = "block"; + this.isOpen = true; + } + }; + + this.hide = function() { + if (this.isOpen) { + this.getElement().style.display = "none"; + this.isOpen = false; + } + }; + this.getHeight = function() { + return this.getElement().offsetHeight; + }; + this.getWidth = function() { + return this.getElement().offsetWidth; + }; + + this.destroy = function() { + this.isOpen = false; + if (this.$element && this.$element.parentNode) { + this.$element.parentNode.removeChild(this.$element); + } + }; + +}).call(Tooltip.prototype); + +exports.Tooltip = Tooltip; +}); + +ace.define("ace/mouse/default_gutter_handler",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event","ace/tooltip"], function(require, exports, module) { +"use strict"; +var dom = require("../lib/dom"); +var oop = require("../lib/oop"); +var event = require("../lib/event"); +var Tooltip = require("../tooltip").Tooltip; + +function GutterHandler(mouseHandler) { + var editor = mouseHandler.editor; + var gutter = editor.renderer.$gutterLayer; + var tooltip = new GutterTooltip(editor.container); + + mouseHandler.editor.setDefaultHandler("guttermousedown", function(e) { + if (!editor.isFocused() || e.getButton() != 0) + return; + var gutterRegion = gutter.getRegion(e); + + if (gutterRegion == "foldWidgets") + return; + + var row = e.getDocumentPosition().row; + var selection = editor.session.selection; + + if (e.getShiftKey()) + selection.selectTo(row, 0); + else { + if (e.domEvent.detail == 2) { + editor.selectAll(); + return e.preventDefault(); + } + mouseHandler.$clickSelection = editor.selection.getLineRange(row); + } + mouseHandler.setState("selectByLines"); + mouseHandler.captureMouse(e); + return e.preventDefault(); + }); + + + var tooltipTimeout, mouseEvent, tooltipAnnotation; + + function showTooltip() { + var row = mouseEvent.getDocumentPosition().row; + var annotation = gutter.$annotations[row]; + if (!annotation) + return hideTooltip(); + + var maxRow = editor.session.getLength(); + if (row == maxRow) { + var screenRow = editor.renderer.pixelToScreenCoordinates(0, mouseEvent.y).row; + var pos = mouseEvent.$pos; + if (screenRow > editor.session.documentToScreenRow(pos.row, pos.column)) + return hideTooltip(); + } + + if (tooltipAnnotation == annotation) + return; + tooltipAnnotation = annotation.text.join("
    "); + + tooltip.setHtml(tooltipAnnotation); + tooltip.show(); + editor._signal("showGutterTooltip", tooltip); + editor.on("mousewheel", hideTooltip); + + if (mouseHandler.$tooltipFollowsMouse) { + moveTooltip(mouseEvent); + } else { + var gutterElement = mouseEvent.domEvent.target; + var rect = gutterElement.getBoundingClientRect(); + var style = tooltip.getElement().style; + style.left = rect.right + "px"; + style.top = rect.bottom + "px"; + } + } + + function hideTooltip() { + if (tooltipTimeout) + tooltipTimeout = clearTimeout(tooltipTimeout); + if (tooltipAnnotation) { + tooltip.hide(); + tooltipAnnotation = null; + editor._signal("hideGutterTooltip", tooltip); + editor.off("mousewheel", hideTooltip); + } + } + + function moveTooltip(e) { + tooltip.setPosition(e.x, e.y); + } + + mouseHandler.editor.setDefaultHandler("guttermousemove", function(e) { + var target = e.domEvent.target || e.domEvent.srcElement; + if (dom.hasCssClass(target, "ace_fold-widget")) + return hideTooltip(); + + if (tooltipAnnotation && mouseHandler.$tooltipFollowsMouse) + moveTooltip(e); + + mouseEvent = e; + if (tooltipTimeout) + return; + tooltipTimeout = setTimeout(function() { + tooltipTimeout = null; + if (mouseEvent && !mouseHandler.isMousePressed) + showTooltip(); + else + hideTooltip(); + }, 50); + }); + + event.addListener(editor.renderer.$gutter, "mouseout", function(e) { + mouseEvent = null; + if (!tooltipAnnotation || tooltipTimeout) + return; + + tooltipTimeout = setTimeout(function() { + tooltipTimeout = null; + hideTooltip(); + }, 50); + }, editor); + + editor.on("changeSession", hideTooltip); +} + +function GutterTooltip(parentNode) { + Tooltip.call(this, parentNode); +} + +oop.inherits(GutterTooltip, Tooltip); + +(function(){ + this.setPosition = function(x, y) { + var windowWidth = window.innerWidth || document.documentElement.clientWidth; + var windowHeight = window.innerHeight || document.documentElement.clientHeight; + var width = this.getWidth(); + var height = this.getHeight(); + x += 15; + y += 15; + if (x + width > windowWidth) { + x -= (x + width) - windowWidth; + } + if (y + height > windowHeight) { + y -= 20 + height; + } + Tooltip.prototype.setPosition.call(this, x, y); + }; + +}).call(GutterTooltip.prototype); + + + +exports.GutterHandler = GutterHandler; + +}); + +ace.define("ace/mouse/mouse_event",["require","exports","module","ace/lib/event","ace/lib/useragent"], function(require, exports, module) { +"use strict"; + +var event = require("../lib/event"); +var useragent = require("../lib/useragent"); +var MouseEvent = exports.MouseEvent = function(domEvent, editor) { + this.domEvent = domEvent; + this.editor = editor; + + this.x = this.clientX = domEvent.clientX; + this.y = this.clientY = domEvent.clientY; + + this.$pos = null; + this.$inSelection = null; + + this.propagationStopped = false; + this.defaultPrevented = false; +}; + +(function() { + + this.stopPropagation = function() { + event.stopPropagation(this.domEvent); + this.propagationStopped = true; + }; + + this.preventDefault = function() { + event.preventDefault(this.domEvent); + this.defaultPrevented = true; + }; + + this.stop = function() { + this.stopPropagation(); + this.preventDefault(); + }; + this.getDocumentPosition = function() { + if (this.$pos) + return this.$pos; + + this.$pos = this.editor.renderer.screenToTextCoordinates(this.clientX, this.clientY); + return this.$pos; + }; + this.inSelection = function() { + if (this.$inSelection !== null) + return this.$inSelection; + + var editor = this.editor; + + + var selectionRange = editor.getSelectionRange(); + if (selectionRange.isEmpty()) + this.$inSelection = false; + else { + var pos = this.getDocumentPosition(); + this.$inSelection = selectionRange.contains(pos.row, pos.column); + } + + return this.$inSelection; + }; + this.getButton = function() { + return event.getButton(this.domEvent); + }; + this.getShiftKey = function() { + return this.domEvent.shiftKey; + }; + + this.getAccelKey = useragent.isMac + ? function() { return this.domEvent.metaKey; } + : function() { return this.domEvent.ctrlKey; }; + +}).call(MouseEvent.prototype); + +}); + +ace.define("ace/mouse/dragdrop_handler",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"], function(require, exports, module) { +"use strict"; + +var dom = require("../lib/dom"); +var event = require("../lib/event"); +var useragent = require("../lib/useragent"); + +var AUTOSCROLL_DELAY = 200; +var SCROLL_CURSOR_DELAY = 200; +var SCROLL_CURSOR_HYSTERESIS = 5; + +function DragdropHandler(mouseHandler) { + + var editor = mouseHandler.editor; + + var blankImage = dom.createElement("img"); + blankImage.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; + if (useragent.isOpera) + blankImage.style.cssText = "width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;"; + + var exports = ["dragWait", "dragWaitEnd", "startDrag", "dragReadyEnd", "onMouseDrag"]; + + exports.forEach(function(x) { + mouseHandler[x] = this[x]; + }, this); + editor.on("mousedown", this.onMouseDown.bind(mouseHandler)); + + + var mouseTarget = editor.container; + var dragSelectionMarker, x, y; + var timerId, range; + var dragCursor, counter = 0; + var dragOperation; + var isInternal; + var autoScrollStartTime; + var cursorMovedTime; + var cursorPointOnCaretMoved; + + this.onDragStart = function(e) { + if (this.cancelDrag || !mouseTarget.draggable) { + var self = this; + setTimeout(function(){ + self.startSelect(); + self.captureMouse(e); + }, 0); + return e.preventDefault(); + } + range = editor.getSelectionRange(); + + var dataTransfer = e.dataTransfer; + dataTransfer.effectAllowed = editor.getReadOnly() ? "copy" : "copyMove"; + if (useragent.isOpera) { + editor.container.appendChild(blankImage); + blankImage.scrollTop = 0; + } + dataTransfer.setDragImage && dataTransfer.setDragImage(blankImage, 0, 0); + if (useragent.isOpera) { + editor.container.removeChild(blankImage); + } + dataTransfer.clearData(); + dataTransfer.setData("Text", editor.session.getTextRange()); + + isInternal = true; + this.setState("drag"); + }; + + this.onDragEnd = function(e) { + mouseTarget.draggable = false; + isInternal = false; + this.setState(null); + if (!editor.getReadOnly()) { + var dropEffect = e.dataTransfer.dropEffect; + if (!dragOperation && dropEffect == "move") + editor.session.remove(editor.getSelectionRange()); + editor.$resetCursorStyle(); + } + this.editor.unsetStyle("ace_dragging"); + this.editor.renderer.setCursorStyle(""); + }; + + this.onDragEnter = function(e) { + if (editor.getReadOnly() || !canAccept(e.dataTransfer)) + return; + x = e.clientX; + y = e.clientY; + if (!dragSelectionMarker) + addDragMarker(); + counter++; + e.dataTransfer.dropEffect = dragOperation = getDropEffect(e); + return event.preventDefault(e); + }; + + this.onDragOver = function(e) { + if (editor.getReadOnly() || !canAccept(e.dataTransfer)) + return; + x = e.clientX; + y = e.clientY; + if (!dragSelectionMarker) { + addDragMarker(); + counter++; + } + if (onMouseMoveTimer !== null) + onMouseMoveTimer = null; + + e.dataTransfer.dropEffect = dragOperation = getDropEffect(e); + return event.preventDefault(e); + }; + + this.onDragLeave = function(e) { + counter--; + if (counter <= 0 && dragSelectionMarker) { + clearDragMarker(); + dragOperation = null; + return event.preventDefault(e); + } + }; + + this.onDrop = function(e) { + if (!dragCursor) + return; + var dataTransfer = e.dataTransfer; + if (isInternal) { + switch (dragOperation) { + case "move": + if (range.contains(dragCursor.row, dragCursor.column)) { + range = { + start: dragCursor, + end: dragCursor + }; + } else { + range = editor.moveText(range, dragCursor); + } + break; + case "copy": + range = editor.moveText(range, dragCursor, true); + break; + } + } else { + var dropData = dataTransfer.getData('Text'); + range = { + start: dragCursor, + end: editor.session.insert(dragCursor, dropData) + }; + editor.focus(); + dragOperation = null; + } + clearDragMarker(); + return event.preventDefault(e); + }; + + event.addListener(mouseTarget, "dragstart", this.onDragStart.bind(mouseHandler), editor); + event.addListener(mouseTarget, "dragend", this.onDragEnd.bind(mouseHandler), editor); + event.addListener(mouseTarget, "dragenter", this.onDragEnter.bind(mouseHandler), editor); + event.addListener(mouseTarget, "dragover", this.onDragOver.bind(mouseHandler), editor); + event.addListener(mouseTarget, "dragleave", this.onDragLeave.bind(mouseHandler), editor); + event.addListener(mouseTarget, "drop", this.onDrop.bind(mouseHandler), editor); + + function scrollCursorIntoView(cursor, prevCursor) { + var now = Date.now(); + var vMovement = !prevCursor || cursor.row != prevCursor.row; + var hMovement = !prevCursor || cursor.column != prevCursor.column; + if (!cursorMovedTime || vMovement || hMovement) { + editor.moveCursorToPosition(cursor); + cursorMovedTime = now; + cursorPointOnCaretMoved = {x: x, y: y}; + } else { + var distance = calcDistance(cursorPointOnCaretMoved.x, cursorPointOnCaretMoved.y, x, y); + if (distance > SCROLL_CURSOR_HYSTERESIS) { + cursorMovedTime = null; + } else if (now - cursorMovedTime >= SCROLL_CURSOR_DELAY) { + editor.renderer.scrollCursorIntoView(); + cursorMovedTime = null; + } + } + } + + function autoScroll(cursor, prevCursor) { + var now = Date.now(); + var lineHeight = editor.renderer.layerConfig.lineHeight; + var characterWidth = editor.renderer.layerConfig.characterWidth; + var editorRect = editor.renderer.scroller.getBoundingClientRect(); + var offsets = { + x: { + left: x - editorRect.left, + right: editorRect.right - x + }, + y: { + top: y - editorRect.top, + bottom: editorRect.bottom - y + } + }; + var nearestXOffset = Math.min(offsets.x.left, offsets.x.right); + var nearestYOffset = Math.min(offsets.y.top, offsets.y.bottom); + var scrollCursor = {row: cursor.row, column: cursor.column}; + if (nearestXOffset / characterWidth <= 2) { + scrollCursor.column += (offsets.x.left < offsets.x.right ? -3 : +2); + } + if (nearestYOffset / lineHeight <= 1) { + scrollCursor.row += (offsets.y.top < offsets.y.bottom ? -1 : +1); + } + var vScroll = cursor.row != scrollCursor.row; + var hScroll = cursor.column != scrollCursor.column; + var vMovement = !prevCursor || cursor.row != prevCursor.row; + if (vScroll || (hScroll && !vMovement)) { + if (!autoScrollStartTime) + autoScrollStartTime = now; + else if (now - autoScrollStartTime >= AUTOSCROLL_DELAY) + editor.renderer.scrollCursorIntoView(scrollCursor); + } else { + autoScrollStartTime = null; + } + } + + function onDragInterval() { + var prevCursor = dragCursor; + dragCursor = editor.renderer.screenToTextCoordinates(x, y); + scrollCursorIntoView(dragCursor, prevCursor); + autoScroll(dragCursor, prevCursor); + } + + function addDragMarker() { + range = editor.selection.toOrientedRange(); + dragSelectionMarker = editor.session.addMarker(range, "ace_selection", editor.getSelectionStyle()); + editor.clearSelection(); + if (editor.isFocused()) + editor.renderer.$cursorLayer.setBlinking(false); + clearInterval(timerId); + onDragInterval(); + timerId = setInterval(onDragInterval, 20); + counter = 0; + event.addListener(document, "mousemove", onMouseMove); + } + + function clearDragMarker() { + clearInterval(timerId); + editor.session.removeMarker(dragSelectionMarker); + dragSelectionMarker = null; + editor.selection.fromOrientedRange(range); + if (editor.isFocused() && !isInternal) + editor.$resetCursorStyle(); + range = null; + dragCursor = null; + counter = 0; + autoScrollStartTime = null; + cursorMovedTime = null; + event.removeListener(document, "mousemove", onMouseMove); + } + var onMouseMoveTimer = null; + function onMouseMove() { + if (onMouseMoveTimer == null) { + onMouseMoveTimer = setTimeout(function() { + if (onMouseMoveTimer != null && dragSelectionMarker) + clearDragMarker(); + }, 20); + } + } + + function canAccept(dataTransfer) { + var types = dataTransfer.types; + return !types || Array.prototype.some.call(types, function(type) { + return type == 'text/plain' || type == 'Text'; + }); + } + + function getDropEffect(e) { + var copyAllowed = ['copy', 'copymove', 'all', 'uninitialized']; + var moveAllowed = ['move', 'copymove', 'linkmove', 'all', 'uninitialized']; + + var copyModifierState = useragent.isMac ? e.altKey : e.ctrlKey; + var effectAllowed = "uninitialized"; + try { + effectAllowed = e.dataTransfer.effectAllowed.toLowerCase(); + } catch (e) {} + var dropEffect = "none"; + + if (copyModifierState && copyAllowed.indexOf(effectAllowed) >= 0) + dropEffect = "copy"; + else if (moveAllowed.indexOf(effectAllowed) >= 0) + dropEffect = "move"; + else if (copyAllowed.indexOf(effectAllowed) >= 0) + dropEffect = "copy"; + + return dropEffect; + } +} + +(function() { + + this.dragWait = function() { + var interval = Date.now() - this.mousedownEvent.time; + if (interval > this.editor.getDragDelay()) + this.startDrag(); + }; + + this.dragWaitEnd = function() { + var target = this.editor.container; + target.draggable = false; + this.startSelect(this.mousedownEvent.getDocumentPosition()); + this.selectEnd(); + }; + + this.dragReadyEnd = function(e) { + this.editor.$resetCursorStyle(); + this.editor.unsetStyle("ace_dragging"); + this.editor.renderer.setCursorStyle(""); + this.dragWaitEnd(); + }; + + this.startDrag = function(){ + this.cancelDrag = false; + var editor = this.editor; + var target = editor.container; + target.draggable = true; + editor.renderer.$cursorLayer.setBlinking(false); + editor.setStyle("ace_dragging"); + var cursorStyle = useragent.isWin ? "default" : "move"; + editor.renderer.setCursorStyle(cursorStyle); + this.setState("dragReady"); + }; + + this.onMouseDrag = function(e) { + var target = this.editor.container; + if (useragent.isIE && this.state == "dragReady") { + var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y); + if (distance > 3) + target.dragDrop(); + } + if (this.state === "dragWait") { + var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y); + if (distance > 0) { + target.draggable = false; + this.startSelect(this.mousedownEvent.getDocumentPosition()); + } + } + }; + + this.onMouseDown = function(e) { + if (!this.$dragEnabled) + return; + this.mousedownEvent = e; + var editor = this.editor; + + var inSelection = e.inSelection(); + var button = e.getButton(); + var clickCount = e.domEvent.detail || 1; + if (clickCount === 1 && button === 0 && inSelection) { + if (e.editor.inMultiSelectMode && (e.getAccelKey() || e.getShiftKey())) + return; + this.mousedownEvent.time = Date.now(); + var eventTarget = e.domEvent.target || e.domEvent.srcElement; + if ("unselectable" in eventTarget) + eventTarget.unselectable = "on"; + if (editor.getDragDelay()) { + if (useragent.isWebKit) { + this.cancelDrag = true; + var mouseTarget = editor.container; + mouseTarget.draggable = true; + } + this.setState("dragWait"); + } else { + this.startDrag(); + } + this.captureMouse(e, this.onMouseDrag.bind(this)); + e.defaultPrevented = true; + } + }; + +}).call(DragdropHandler.prototype); + + +function calcDistance(ax, ay, bx, by) { + return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2)); +} + +exports.DragdropHandler = DragdropHandler; + +}); + +ace.define("ace/mouse/touch_handler",["require","exports","module","ace/mouse/mouse_event","ace/lib/event","ace/lib/dom"], function(require, exports, module) { +"use strict"; + +var MouseEvent = require("./mouse_event").MouseEvent; +var event = require("../lib/event"); +var dom = require("../lib/dom"); + +exports.addTouchListeners = function(el, editor) { + var mode = "scroll"; + var startX; + var startY; + var touchStartT; + var lastT; + var longTouchTimer; + var animationTimer; + var animationSteps = 0; + var pos; + var clickCount = 0; + var vX = 0; + var vY = 0; + var pressed; + var contextMenu; + + function createContextMenu() { + var clipboard = window.navigator && window.navigator.clipboard; + var isOpen = false; + var updateMenu = function() { + var selected = editor.getCopyText(); + var hasUndo = editor.session.getUndoManager().hasUndo(); + contextMenu.replaceChild( + dom.buildDom(isOpen ? ["span", + !selected && ["span", { class: "ace_mobile-button", action: "selectall" }, "Select All"], + selected && ["span", { class: "ace_mobile-button", action: "copy" }, "Copy"], + selected && ["span", { class: "ace_mobile-button", action: "cut" }, "Cut"], + clipboard && ["span", { class: "ace_mobile-button", action: "paste" }, "Paste"], + hasUndo && ["span", { class: "ace_mobile-button", action: "undo" }, "Undo"], + ["span", { class: "ace_mobile-button", action: "find" }, "Find"], + ["span", { class: "ace_mobile-button", action: "openCommandPallete" }, "Pallete"] + ] : ["span"]), + contextMenu.firstChild + ); + }; + var handleClick = function(e) { + var action = e.target.getAttribute("action"); + + if (action == "more" || !isOpen) { + isOpen = !isOpen; + return updateMenu(); + } + if (action == "paste") { + clipboard.readText().then(function (text) { + editor.execCommand(action, text); + }); + } + else if (action) { + if (action == "cut" || action == "copy") { + if (clipboard) + clipboard.writeText(editor.getCopyText()); + else + document.execCommand("copy"); + } + editor.execCommand(action); + } + contextMenu.firstChild.style.display = "none"; + isOpen = false; + if (action != "openCommandPallete") + editor.focus(); + }; + contextMenu = dom.buildDom(["div", + { + class: "ace_mobile-menu", + ontouchstart: function(e) { + mode = "menu"; + e.stopPropagation(); + e.preventDefault(); + editor.textInput.focus(); + }, + ontouchend: function(e) { + e.stopPropagation(); + e.preventDefault(); + handleClick(e); + }, + onclick: handleClick + }, + ["span"], + ["span", { class: "ace_mobile-button", action: "more" }, "..."] + ], editor.container); + } + function showContextMenu() { + if (!contextMenu) createContextMenu(); + var cursor = editor.selection.cursor; + var pagePos = editor.renderer.textToScreenCoordinates(cursor.row, cursor.column); + var leftOffset = editor.renderer.textToScreenCoordinates(0, 0).pageX; + var scrollLeft = editor.renderer.scrollLeft; + var rect = editor.container.getBoundingClientRect(); + contextMenu.style.top = pagePos.pageY - rect.top - 3 + "px"; + if (pagePos.pageX - rect.left < rect.width - 70) { + contextMenu.style.left = ""; + contextMenu.style.right = "10px"; + } else { + contextMenu.style.right = ""; + contextMenu.style.left = leftOffset + scrollLeft - rect.left + "px"; + } + contextMenu.style.display = ""; + contextMenu.firstChild.style.display = "none"; + editor.on("input", hideContextMenu); + } + function hideContextMenu(e) { + if (contextMenu) + contextMenu.style.display = "none"; + editor.off("input", hideContextMenu); + } + + function handleLongTap() { + longTouchTimer = null; + clearTimeout(longTouchTimer); + var range = editor.selection.getRange(); + var inSelection = range.contains(pos.row, pos.column); + if (range.isEmpty() || !inSelection) { + editor.selection.moveToPosition(pos); + editor.selection.selectWord(); + } + mode = "wait"; + showContextMenu(); + } + function switchToSelectionMode() { + longTouchTimer = null; + clearTimeout(longTouchTimer); + editor.selection.moveToPosition(pos); + var range = clickCount >= 2 + ? editor.selection.getLineRange(pos.row) + : editor.session.getBracketRange(pos); + if (range && !range.isEmpty()) { + editor.selection.setRange(range); + } else { + editor.selection.selectWord(); + } + mode = "wait"; + } + event.addListener(el, "contextmenu", function(e) { + if (!pressed) return; + var textarea = editor.textInput.getElement(); + textarea.focus(); + }, editor); + event.addListener(el, "touchstart", function (e) { + var touches = e.touches; + if (longTouchTimer || touches.length > 1) { + clearTimeout(longTouchTimer); + longTouchTimer = null; + touchStartT = -1; + mode = "zoom"; + return; + } + + pressed = editor.$mouseHandler.isMousePressed = true; + var h = editor.renderer.layerConfig.lineHeight; + var w = editor.renderer.layerConfig.lineHeight; + var t = e.timeStamp; + lastT = t; + var touchObj = touches[0]; + var x = touchObj.clientX; + var y = touchObj.clientY; + if (Math.abs(startX - x) + Math.abs(startY - y) > h) + touchStartT = -1; + + startX = e.clientX = x; + startY = e.clientY = y; + vX = vY = 0; + + var ev = new MouseEvent(e, editor); + pos = ev.getDocumentPosition(); + + if (t - touchStartT < 500 && touches.length == 1 && !animationSteps) { + clickCount++; + e.preventDefault(); + e.button = 0; + switchToSelectionMode(); + } else { + clickCount = 0; + var cursor = editor.selection.cursor; + var anchor = editor.selection.isEmpty() ? cursor : editor.selection.anchor; + + var cursorPos = editor.renderer.$cursorLayer.getPixelPosition(cursor, true); + var anchorPos = editor.renderer.$cursorLayer.getPixelPosition(anchor, true); + var rect = editor.renderer.scroller.getBoundingClientRect(); + var offsetTop = editor.renderer.layerConfig.offset; + var offsetLeft = editor.renderer.scrollLeft; + var weightedDistance = function(x, y) { + x = x / w; + y = y / h - 0.75; + return x * x + y * y; + }; + + if (e.clientX < rect.left) { + mode = "zoom"; + return; + } + + var diff1 = weightedDistance( + e.clientX - rect.left - cursorPos.left + offsetLeft, + e.clientY - rect.top - cursorPos.top + offsetTop + ); + var diff2 = weightedDistance( + e.clientX - rect.left - anchorPos.left + offsetLeft, + e.clientY - rect.top - anchorPos.top + offsetTop + ); + if (diff1 < 3.5 && diff2 < 3.5) + mode = diff1 > diff2 ? "cursor" : "anchor"; + + if (diff2 < 3.5) + mode = "anchor"; + else if (diff1 < 3.5) + mode = "cursor"; + else + mode = "scroll"; + longTouchTimer = setTimeout(handleLongTap, 450); + } + touchStartT = t; + }, editor); + + event.addListener(el, "touchend", function (e) { + pressed = editor.$mouseHandler.isMousePressed = false; + if (animationTimer) clearInterval(animationTimer); + if (mode == "zoom") { + mode = ""; + animationSteps = 0; + } else if (longTouchTimer) { + editor.selection.moveToPosition(pos); + animationSteps = 0; + showContextMenu(); + } else if (mode == "scroll") { + animate(); + hideContextMenu(); + } else { + showContextMenu(); + } + clearTimeout(longTouchTimer); + longTouchTimer = null; + }, editor); + event.addListener(el, "touchmove", function (e) { + if (longTouchTimer) { + clearTimeout(longTouchTimer); + longTouchTimer = null; + } + var touches = e.touches; + if (touches.length > 1 || mode == "zoom") return; + + var touchObj = touches[0]; + + var wheelX = startX - touchObj.clientX; + var wheelY = startY - touchObj.clientY; + + if (mode == "wait") { + if (wheelX * wheelX + wheelY * wheelY > 4) + mode = "cursor"; + else + return e.preventDefault(); + } + + startX = touchObj.clientX; + startY = touchObj.clientY; + + e.clientX = touchObj.clientX; + e.clientY = touchObj.clientY; + + var t = e.timeStamp; + var dt = t - lastT; + lastT = t; + if (mode == "scroll") { + var mouseEvent = new MouseEvent(e, editor); + mouseEvent.speed = 1; + mouseEvent.wheelX = wheelX; + mouseEvent.wheelY = wheelY; + if (10 * Math.abs(wheelX) < Math.abs(wheelY)) wheelX = 0; + if (10 * Math.abs(wheelY) < Math.abs(wheelX)) wheelY = 0; + if (dt != 0) { + vX = wheelX / dt; + vY = wheelY / dt; + } + editor._emit("mousewheel", mouseEvent); + if (!mouseEvent.propagationStopped) { + vX = vY = 0; + } + } + else { + var ev = new MouseEvent(e, editor); + var pos = ev.getDocumentPosition(); + if (mode == "cursor") + editor.selection.moveCursorToPosition(pos); + else if (mode == "anchor") + editor.selection.setSelectionAnchor(pos.row, pos.column); + editor.renderer.scrollCursorIntoView(pos); + e.preventDefault(); + } + }, editor); + + function animate() { + animationSteps += 60; + animationTimer = setInterval(function() { + if (animationSteps-- <= 0) { + clearInterval(animationTimer); + animationTimer = null; + } + if (Math.abs(vX) < 0.01) vX = 0; + if (Math.abs(vY) < 0.01) vY = 0; + if (animationSteps < 20) vX = 0.9 * vX; + if (animationSteps < 20) vY = 0.9 * vY; + var oldScrollTop = editor.session.getScrollTop(); + editor.renderer.scrollBy(10 * vX, 10 * vY); + if (oldScrollTop == editor.session.getScrollTop()) + animationSteps = 0; + }, 10); + } +}; + +}); + +ace.define("ace/lib/net",["require","exports","module","ace/lib/dom"], function(require, exports, module) { +"use strict"; +var dom = require("./dom"); + +exports.get = function (url, callback) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + callback(xhr.responseText); + } + }; + xhr.send(null); +}; + +exports.loadScript = function(path, callback) { + var head = dom.getDocumentHead(); + var s = document.createElement('script'); + + s.src = path; + head.appendChild(s); + + s.onload = s.onreadystatechange = function(_, isAbort) { + if (isAbort || !s.readyState || s.readyState == "loaded" || s.readyState == "complete") { + s = s.onload = s.onreadystatechange = null; + if (!isAbort) + callback(); + } + }; +}; +exports.qualifyURL = function(url) { + var a = document.createElement('a'); + a.href = url; + return a.href; +}; + +}); + +ace.define("ace/lib/event_emitter",["require","exports","module"], function(require, exports, module) { +"use strict"; + +var EventEmitter = {}; +var stopPropagation = function() { this.propagationStopped = true; }; +var preventDefault = function() { this.defaultPrevented = true; }; + +EventEmitter._emit = +EventEmitter._dispatchEvent = function(eventName, e) { + this._eventRegistry || (this._eventRegistry = {}); + this._defaultHandlers || (this._defaultHandlers = {}); + + var listeners = this._eventRegistry[eventName] || []; + var defaultHandler = this._defaultHandlers[eventName]; + if (!listeners.length && !defaultHandler) + return; + + if (typeof e != "object" || !e) + e = {}; + + if (!e.type) + e.type = eventName; + if (!e.stopPropagation) + e.stopPropagation = stopPropagation; + if (!e.preventDefault) + e.preventDefault = preventDefault; + + listeners = listeners.slice(); + for (var i=0; i 1) + base = parts[parts.length - 2]; + var path = options[component + "Path"]; + if (path == null) { + path = options.basePath; + } else if (sep == "/") { + component = sep = ""; + } + if (path && path.slice(-1) != "/") + path += "/"; + return path + component + sep + base + this.get("suffix"); +}; + +exports.setModuleUrl = function(name, subst) { + return options.$moduleUrls[name] = subst; +}; + +exports.$loading = {}; +exports.loadModule = function(moduleName, onLoad) { + var module, moduleType; + if (Array.isArray(moduleName)) { + moduleType = moduleName[0]; + moduleName = moduleName[1]; + } + + try { + module = require(moduleName); + } catch (e) {} + if (module && !exports.$loading[moduleName]) + return onLoad && onLoad(module); + + if (!exports.$loading[moduleName]) + exports.$loading[moduleName] = []; + + exports.$loading[moduleName].push(onLoad); + + if (exports.$loading[moduleName].length > 1) + return; + + var afterLoad = function() { + require([moduleName], function(module) { + exports._emit("load.module", {name: moduleName, module: module}); + var listeners = exports.$loading[moduleName]; + exports.$loading[moduleName] = null; + listeners.forEach(function(onLoad) { + onLoad && onLoad(module); + }); + }); + }; + + if (!exports.get("packaged")) + return afterLoad(); + + net.loadScript(exports.moduleUrl(moduleName, moduleType), afterLoad); + reportErrorIfPathIsNotConfigured(); +}; + +var reportErrorIfPathIsNotConfigured = function() { + if ( + !options.basePath && !options.workerPath + && !options.modePath && !options.themePath + && !Object.keys(options.$moduleUrls).length + ) { + console.error( + "Unable to infer path to ace from script src,", + "use ace.config.set('basePath', 'path') to enable dynamic loading of modes and themes", + "or with webpack use ace/webpack-resolver" + ); + reportErrorIfPathIsNotConfigured = function() {}; + } +}; +init(true);function init(packaged) { + + if (!global || !global.document) + return; + + options.packaged = packaged || require.packaged || module.packaged || (global.define && __webpack_require__.amdD.packaged); + + var scriptOptions = {}; + var scriptUrl = ""; + var currentScript = (document.currentScript || document._currentScript ); // native or polyfill + var currentDocument = currentScript && currentScript.ownerDocument || document; + + var scripts = currentDocument.getElementsByTagName("script"); + for (var i=0; i 0){ + if (action == 0x10){ + for(i = condPos; i < ix; i++){ + levels[i] = 1; + } + condPos = -1; + } else { + condPos = -1; + } + } + cond = impTab[newState][6]; + if (cond){ + if(condPos == -1){ + condPos = ix; + } + }else{ + if (condPos > -1){ + for(i = condPos; i < ix; i++){ + levels[i] = newLevel; + } + condPos = -1; + } + } + if (charTypes[ix] == B){ + levels[ix] = 0; + } + hiLevel |= newLevel; + } + if (hasUBAT_S){ + for(i = 0; i < len; i++){ + if(charTypes[i] == S){ + levels[i] = dir; + for(var j = i - 1; j >= 0; j--){ + if(charTypes[j] == WS){ + levels[j] = dir; + }else{ + break; + } + } + } + } + } +} + +function _invertLevel(lev, levels, _array) { + if (hiLevel < lev){ + return; + } + if (lev == 1 && dir == RTL && !hasUBAT_B){ + _array.reverse(); + return; + } + var len = _array.length, start = 0, end, lo, hi, tmp; + while(start < len){ + if (levels[start] >= lev){ + end = start + 1; + while(end < len && levels[end] >= lev){ + end++; + } + for(lo = start, hi = end - 1 ; lo < hi; lo++, hi--){ + tmp = _array[lo]; + _array[lo] = _array[hi]; + _array[hi] = tmp; + } + start = end; + } + start++; + } +} + +function _getCharClass(chars, types, classes, ix) { + var cType = types[ix], wType, nType, len, i; + switch(cType){ + case L: + case R: + lastArabic = false; + case ON: + case AN: + return cType; + case EN: + return lastArabic ? AN : EN; + case AL: + lastArabic = true; + hasUBAT_AL = true; + return R; + case WS: + return ON; + case CS: + if (ix < 1 || (ix + 1) >= types.length || + ((wType = classes[ix - 1]) != EN && wType != AN) || + ((nType = types[ix + 1]) != EN && nType != AN)){ + return ON; + } + if (lastArabic){nType = AN;} + return nType == wType ? nType : ON; + case ES: + wType = ix > 0 ? classes[ix - 1] : B; + if (wType == EN && (ix + 1) < types.length && types[ix + 1] == EN){ + return EN; + } + return ON; + case ET: + if (ix > 0 && classes[ix - 1] == EN){ + return EN; + } + if (lastArabic){ + return ON; + } + i = ix + 1; + len = types.length; + while (i < len && types[i] == ET){ + i++; + } + if (i < len && types[i] == EN){ + return EN; + } + return ON; + case NSM: + len = types.length; + i = ix + 1; + while (i < len && types[i] == NSM){ + i++; + } + if (i < len){ + var c = chars[ix], rtlCandidate = (c >= 0x0591 && c <= 0x08FF) || c == 0xFB1E; + + wType = types[i]; + if (rtlCandidate && (wType == R || wType == AL)){ + return R; + } + } + + if (ix < 1 || (wType = types[ix - 1]) == B){ + return ON; + } + return classes[ix - 1]; + case B: + lastArabic = false; + hasUBAT_B = true; + return dir; + case S: + hasUBAT_S = true; + return ON; + case LRE: + case RLE: + case LRO: + case RLO: + case PDF: + lastArabic = false; + case BN: + return ON; + } +} + +function _getCharacterType( ch ) { + var uc = ch.charCodeAt(0), hi = uc >> 8; + + if (hi == 0) { + return ((uc > 0x00BF) ? L : UnicodeTBL00[uc]); + } else if (hi == 5) { + return (/[\u0591-\u05f4]/.test(ch) ? R : L); + } else if (hi == 6) { + if (/[\u0610-\u061a\u064b-\u065f\u06d6-\u06e4\u06e7-\u06ed]/.test(ch)) + return NSM; + else if (/[\u0660-\u0669\u066b-\u066c]/.test(ch)) + return AN; + else if (uc == 0x066A) + return ET; + else if (/[\u06f0-\u06f9]/.test(ch)) + return EN; + else + return AL; + } else if (hi == 0x20 && uc <= 0x205F) { + return UnicodeTBL20[uc & 0xFF]; + } else if (hi == 0xFE) { + return (uc >= 0xFE70 ? AL : ON); + } + return ON; +} + +function _isArabicDiacritics( ch ) { + return (ch >= '\u064b' && ch <= '\u0655'); +} +exports.L = L; +exports.R = R; +exports.EN = EN; +exports.ON_R = 3; +exports.AN = 4; +exports.R_H = 5; +exports.B = 6; +exports.RLE = 7; + +exports.DOT = "\xB7"; +exports.doBidiReorder = function(text, textCharTypes, isRtl) { + if (text.length < 2) + return {}; + + var chars = text.split(""), logicalFromVisual = new Array(chars.length), + bidiLevels = new Array(chars.length), levels = []; + + dir = isRtl ? RTL : LTR; + + _computeLevels(chars, levels, chars.length, textCharTypes); + + for (var i = 0; i < logicalFromVisual.length; logicalFromVisual[i] = i, i++); + + _invertLevel(2, levels, logicalFromVisual); + _invertLevel(1, levels, logicalFromVisual); + + for (var i = 0; i < logicalFromVisual.length - 1; i++) { //fix levels to reflect character width + if (textCharTypes[i] === AN) { + levels[i] = exports.AN; + } else if (levels[i] === R && ((textCharTypes[i] > AL && textCharTypes[i] < LRE) + || textCharTypes[i] === ON || textCharTypes[i] === BN)) { + levels[i] = exports.ON_R; + } else if ((i > 0 && chars[i - 1] === '\u0644') && /\u0622|\u0623|\u0625|\u0627/.test(chars[i])) { + levels[i - 1] = levels[i] = exports.R_H; + i++; + } + } + if (chars[chars.length - 1] === exports.DOT) + levels[chars.length - 1] = exports.B; + + if (chars[0] === '\u202B') + levels[0] = exports.RLE; + + for (var i = 0; i < logicalFromVisual.length; i++) { + bidiLevels[i] = levels[logicalFromVisual[i]]; + } + + return {'logicalFromVisual': logicalFromVisual, 'bidiLevels': bidiLevels}; +}; +exports.hasBidiCharacters = function(text, textCharTypes){ + var ret = false; + for (var i = 0; i < text.length; i++){ + textCharTypes[i] = _getCharacterType(text.charAt(i)); + if (!ret && (textCharTypes[i] == R || textCharTypes[i] == AL || textCharTypes[i] == AN)) + ret = true; + } + return ret; +}; +exports.getVisualFromLogicalIdx = function(logIdx, rowMap) { + for (var i = 0; i < rowMap.logicalFromVisual.length; i++) { + if (rowMap.logicalFromVisual[i] == logIdx) + return i; + } + return 0; +}; + +}); + +ace.define("ace/bidihandler",["require","exports","module","ace/lib/bidiutil","ace/lib/lang"], function(require, exports, module) { +"use strict"; + +var bidiUtil = require("./lib/bidiutil"); +var lang = require("./lib/lang"); +var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac\u202B]/; +var BidiHandler = function(session) { + this.session = session; + this.bidiMap = {}; + this.currentRow = null; + this.bidiUtil = bidiUtil; + this.charWidths = []; + this.EOL = "\xAC"; + this.showInvisibles = true; + this.isRtlDir = false; + this.$isRtl = false; + this.line = ""; + this.wrapIndent = 0; + this.EOF = "\xB6"; + this.RLE = "\u202B"; + this.contentWidth = 0; + this.fontMetrics = null; + this.rtlLineOffset = 0; + this.wrapOffset = 0; + this.isMoveLeftOperation = false; + this.seenBidi = bidiRE.test(session.getValue()); +}; + +(function() { + this.isBidiRow = function(screenRow, docRow, splitIndex) { + if (!this.seenBidi) + return false; + if (screenRow !== this.currentRow) { + this.currentRow = screenRow; + this.updateRowLine(docRow, splitIndex); + this.updateBidiMap(); + } + return this.bidiMap.bidiLevels; + }; + + this.onChange = function(delta) { + if (!this.seenBidi) { + if (delta.action == "insert" && bidiRE.test(delta.lines.join("\n"))) { + this.seenBidi = true; + this.currentRow = null; + } + } + else { + this.currentRow = null; + } + }; + + this.getDocumentRow = function() { + var docRow = 0; + var rowCache = this.session.$screenRowCache; + if (rowCache.length) { + var index = this.session.$getRowCacheIndex(rowCache, this.currentRow); + if (index >= 0) + docRow = this.session.$docRowCache[index]; + } + + return docRow; + }; + + this.getSplitIndex = function() { + var splitIndex = 0; + var rowCache = this.session.$screenRowCache; + if (rowCache.length) { + var currentIndex, prevIndex = this.session.$getRowCacheIndex(rowCache, this.currentRow); + while (this.currentRow - splitIndex > 0) { + currentIndex = this.session.$getRowCacheIndex(rowCache, this.currentRow - splitIndex - 1); + if (currentIndex !== prevIndex) + break; + + prevIndex = currentIndex; + splitIndex++; + } + } else { + splitIndex = this.currentRow; + } + + return splitIndex; + }; + + this.updateRowLine = function(docRow, splitIndex) { + if (docRow === undefined) + docRow = this.getDocumentRow(); + + var isLastRow = (docRow === this.session.getLength() - 1), + endOfLine = isLastRow ? this.EOF : this.EOL; + + this.wrapIndent = 0; + this.line = this.session.getLine(docRow); + this.isRtlDir = this.$isRtl || this.line.charAt(0) === this.RLE; + if (this.session.$useWrapMode) { + var splits = this.session.$wrapData[docRow]; + if (splits) { + if (splitIndex === undefined) + splitIndex = this.getSplitIndex(); + + if(splitIndex > 0 && splits.length) { + this.wrapIndent = splits.indent; + this.wrapOffset = this.wrapIndent * this.charWidths[bidiUtil.L]; + this.line = (splitIndex < splits.length) ? + this.line.substring(splits[splitIndex - 1], splits[splitIndex]) : + this.line.substring(splits[splits.length - 1]); + } else { + this.line = this.line.substring(0, splits[splitIndex]); + } + } + if (splitIndex == splits.length) + this.line += (this.showInvisibles) ? endOfLine : bidiUtil.DOT; + } else { + this.line += this.showInvisibles ? endOfLine : bidiUtil.DOT; + } + var session = this.session, shift = 0, size; + this.line = this.line.replace(/\t|[\u1100-\u2029, \u202F-\uFFE6]/g, function(ch, i){ + if (ch === '\t' || session.isFullWidth(ch.charCodeAt(0))) { + size = (ch === '\t') ? session.getScreenTabSize(i + shift) : 2; + shift += size - 1; + return lang.stringRepeat(bidiUtil.DOT, size); + } + return ch; + }); + + if (this.isRtlDir) { + this.fontMetrics.$main.textContent = (this.line.charAt(this.line.length - 1) == bidiUtil.DOT) ? this.line.substr(0, this.line.length - 1) : this.line; + this.rtlLineOffset = this.contentWidth - this.fontMetrics.$main.getBoundingClientRect().width; + } + }; + + this.updateBidiMap = function() { + var textCharTypes = []; + if (bidiUtil.hasBidiCharacters(this.line, textCharTypes) || this.isRtlDir) { + this.bidiMap = bidiUtil.doBidiReorder(this.line, textCharTypes, this.isRtlDir); + } else { + this.bidiMap = {}; + } + }; + this.markAsDirty = function() { + this.currentRow = null; + }; + this.updateCharacterWidths = function(fontMetrics) { + if (this.characterWidth === fontMetrics.$characterSize.width) + return; + + this.fontMetrics = fontMetrics; + var characterWidth = this.characterWidth = fontMetrics.$characterSize.width; + var bidiCharWidth = fontMetrics.$measureCharWidth("\u05d4"); + + this.charWidths[bidiUtil.L] = this.charWidths[bidiUtil.EN] = this.charWidths[bidiUtil.ON_R] = characterWidth; + this.charWidths[bidiUtil.R] = this.charWidths[bidiUtil.AN] = bidiCharWidth; + this.charWidths[bidiUtil.R_H] = bidiCharWidth * 0.45; + this.charWidths[bidiUtil.B] = this.charWidths[bidiUtil.RLE] = 0; + + this.currentRow = null; + }; + + this.setShowInvisibles = function(showInvisibles) { + this.showInvisibles = showInvisibles; + this.currentRow = null; + }; + + this.setEolChar = function(eolChar) { + this.EOL = eolChar; + }; + + this.setContentWidth = function(width) { + this.contentWidth = width; + }; + + this.isRtlLine = function(row) { + if (this.$isRtl) return true; + if (row != undefined) + return (this.session.getLine(row).charAt(0) == this.RLE); + else + return this.isRtlDir; + }; + + this.setRtlDirection = function(editor, isRtlDir) { + var cursor = editor.getCursorPosition(); + for (var row = editor.selection.getSelectionAnchor().row; row <= cursor.row; row++) { + if (!isRtlDir && editor.session.getLine(row).charAt(0) === editor.session.$bidiHandler.RLE) + editor.session.doc.removeInLine(row, 0, 1); + else if (isRtlDir && editor.session.getLine(row).charAt(0) !== editor.session.$bidiHandler.RLE) + editor.session.doc.insert({column: 0, row: row}, editor.session.$bidiHandler.RLE); + } + }; + this.getPosLeft = function(col) { + col -= this.wrapIndent; + var leftBoundary = (this.line.charAt(0) === this.RLE) ? 1 : 0; + var logicalIdx = (col > leftBoundary) ? (this.session.getOverwrite() ? col : col - 1) : leftBoundary; + var visualIdx = bidiUtil.getVisualFromLogicalIdx(logicalIdx, this.bidiMap), + levels = this.bidiMap.bidiLevels, left = 0; + + if (!this.session.getOverwrite() && col <= leftBoundary && levels[visualIdx] % 2 !== 0) + visualIdx++; + + for (var i = 0; i < visualIdx; i++) { + left += this.charWidths[levels[i]]; + } + + if (!this.session.getOverwrite() && (col > leftBoundary) && (levels[visualIdx] % 2 === 0)) + left += this.charWidths[levels[visualIdx]]; + + if (this.wrapIndent) + left += this.isRtlDir ? (-1 * this.wrapOffset) : this.wrapOffset; + + if (this.isRtlDir) + left += this.rtlLineOffset; + + return left; + }; + this.getSelections = function(startCol, endCol) { + var map = this.bidiMap, levels = map.bidiLevels, level, selections = [], offset = 0, + selColMin = Math.min(startCol, endCol) - this.wrapIndent, selColMax = Math.max(startCol, endCol) - this.wrapIndent, + isSelected = false, isSelectedPrev = false, selectionStart = 0; + + if (this.wrapIndent) + offset += this.isRtlDir ? (-1 * this.wrapOffset) : this.wrapOffset; + + for (var logIdx, visIdx = 0; visIdx < levels.length; visIdx++) { + logIdx = map.logicalFromVisual[visIdx]; + level = levels[visIdx]; + isSelected = (logIdx >= selColMin) && (logIdx < selColMax); + if (isSelected && !isSelectedPrev) { + selectionStart = offset; + } else if (!isSelected && isSelectedPrev) { + selections.push({left: selectionStart, width: offset - selectionStart}); + } + offset += this.charWidths[level]; + isSelectedPrev = isSelected; + } + + if (isSelected && (visIdx === levels.length)) { + selections.push({left: selectionStart, width: offset - selectionStart}); + } + + if(this.isRtlDir) { + for (var i = 0; i < selections.length; i++) { + selections[i].left += this.rtlLineOffset; + } + } + return selections; + }; + this.offsetToCol = function(posX) { + if(this.isRtlDir) + posX -= this.rtlLineOffset; + + var logicalIdx = 0, posX = Math.max(posX, 0), + offset = 0, visualIdx = 0, levels = this.bidiMap.bidiLevels, + charWidth = this.charWidths[levels[visualIdx]]; + + if (this.wrapIndent) + posX -= this.isRtlDir ? (-1 * this.wrapOffset) : this.wrapOffset; + + while(posX > offset + charWidth/2) { + offset += charWidth; + if(visualIdx === levels.length - 1) { + charWidth = 0; + break; + } + charWidth = this.charWidths[levels[++visualIdx]]; + } + + if (visualIdx > 0 && (levels[visualIdx - 1] % 2 !== 0) && (levels[visualIdx] % 2 === 0)){ + if(posX < offset) + visualIdx--; + logicalIdx = this.bidiMap.logicalFromVisual[visualIdx]; + + } else if (visualIdx > 0 && (levels[visualIdx - 1] % 2 === 0) && (levels[visualIdx] % 2 !== 0)){ + logicalIdx = 1 + ((posX > offset) ? this.bidiMap.logicalFromVisual[visualIdx] + : this.bidiMap.logicalFromVisual[visualIdx - 1]); + + } else if ((this.isRtlDir && visualIdx === levels.length - 1 && charWidth === 0 && (levels[visualIdx - 1] % 2 === 0)) + || (!this.isRtlDir && visualIdx === 0 && (levels[visualIdx] % 2 !== 0))){ + logicalIdx = 1 + this.bidiMap.logicalFromVisual[visualIdx]; + } else { + if (visualIdx > 0 && (levels[visualIdx - 1] % 2 !== 0) && charWidth !== 0) + visualIdx--; + logicalIdx = this.bidiMap.logicalFromVisual[visualIdx]; + } + + if (logicalIdx === 0 && this.isRtlDir) + logicalIdx++; + + return (logicalIdx + this.wrapIndent); + }; + +}).call(BidiHandler.prototype); + +exports.BidiHandler = BidiHandler; +}); + +ace.define("ace/selection",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter","ace/range"], function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var lang = require("./lib/lang"); +var EventEmitter = require("./lib/event_emitter").EventEmitter; +var Range = require("./range").Range; +var Selection = function(session) { + this.session = session; + this.doc = session.getDocument(); + + this.clearSelection(); + this.cursor = this.lead = this.doc.createAnchor(0, 0); + this.anchor = this.doc.createAnchor(0, 0); + this.$silent = false; + + var self = this; + this.cursor.on("change", function(e) { + self.$cursorChanged = true; + if (!self.$silent) + self._emit("changeCursor"); + if (!self.$isEmpty && !self.$silent) + self._emit("changeSelection"); + if (!self.$keepDesiredColumnOnChange && e.old.column != e.value.column) + self.$desiredColumn = null; + }); + + this.anchor.on("change", function() { + self.$anchorChanged = true; + if (!self.$isEmpty && !self.$silent) + self._emit("changeSelection"); + }); +}; + +(function() { + + oop.implement(this, EventEmitter); + this.isEmpty = function() { + return this.$isEmpty || ( + this.anchor.row == this.lead.row && + this.anchor.column == this.lead.column + ); + }; + this.isMultiLine = function() { + return !this.$isEmpty && this.anchor.row != this.cursor.row; + }; + this.getCursor = function() { + return this.lead.getPosition(); + }; + this.setSelectionAnchor = function(row, column) { + this.$isEmpty = false; + this.anchor.setPosition(row, column); + }; + this.getAnchor = + this.getSelectionAnchor = function() { + if (this.$isEmpty) + return this.getSelectionLead(); + + return this.anchor.getPosition(); + }; + this.getSelectionLead = function() { + return this.lead.getPosition(); + }; + this.isBackwards = function() { + var anchor = this.anchor; + var lead = this.lead; + return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column)); + }; + this.getRange = function() { + var anchor = this.anchor; + var lead = this.lead; + + if (this.$isEmpty) + return Range.fromPoints(lead, lead); + + return this.isBackwards() + ? Range.fromPoints(lead, anchor) + : Range.fromPoints(anchor, lead); + }; + this.clearSelection = function() { + if (!this.$isEmpty) { + this.$isEmpty = true; + this._emit("changeSelection"); + } + }; + this.selectAll = function() { + this.$setSelection(0, 0, Number.MAX_VALUE, Number.MAX_VALUE); + }; + this.setRange = + this.setSelectionRange = function(range, reverse) { + var start = reverse ? range.end : range.start; + var end = reverse ? range.start : range.end; + this.$setSelection(start.row, start.column, end.row, end.column); + }; + + this.$setSelection = function(anchorRow, anchorColumn, cursorRow, cursorColumn) { + if (this.$silent) + return; + var wasEmpty = this.$isEmpty; + var wasMultiselect = this.inMultiSelectMode; + this.$silent = true; + this.$cursorChanged = this.$anchorChanged = false; + this.anchor.setPosition(anchorRow, anchorColumn); + this.cursor.setPosition(cursorRow, cursorColumn); + this.$isEmpty = !Range.comparePoints(this.anchor, this.cursor); + this.$silent = false; + if (this.$cursorChanged) + this._emit("changeCursor"); + if (this.$cursorChanged || this.$anchorChanged || wasEmpty != this.$isEmpty || wasMultiselect) + this._emit("changeSelection"); + }; + + this.$moveSelection = function(mover) { + var lead = this.lead; + if (this.$isEmpty) + this.setSelectionAnchor(lead.row, lead.column); + + mover.call(this); + }; + this.selectTo = function(row, column) { + this.$moveSelection(function() { + this.moveCursorTo(row, column); + }); + }; + this.selectToPosition = function(pos) { + this.$moveSelection(function() { + this.moveCursorToPosition(pos); + }); + }; + this.moveTo = function(row, column) { + this.clearSelection(); + this.moveCursorTo(row, column); + }; + this.moveToPosition = function(pos) { + this.clearSelection(); + this.moveCursorToPosition(pos); + }; + this.selectUp = function() { + this.$moveSelection(this.moveCursorUp); + }; + this.selectDown = function() { + this.$moveSelection(this.moveCursorDown); + }; + this.selectRight = function() { + this.$moveSelection(this.moveCursorRight); + }; + this.selectLeft = function() { + this.$moveSelection(this.moveCursorLeft); + }; + this.selectLineStart = function() { + this.$moveSelection(this.moveCursorLineStart); + }; + this.selectLineEnd = function() { + this.$moveSelection(this.moveCursorLineEnd); + }; + this.selectFileEnd = function() { + this.$moveSelection(this.moveCursorFileEnd); + }; + this.selectFileStart = function() { + this.$moveSelection(this.moveCursorFileStart); + }; + this.selectWordRight = function() { + this.$moveSelection(this.moveCursorWordRight); + }; + this.selectWordLeft = function() { + this.$moveSelection(this.moveCursorWordLeft); + }; + this.getWordRange = function(row, column) { + if (typeof column == "undefined") { + var cursor = row || this.lead; + row = cursor.row; + column = cursor.column; + } + return this.session.getWordRange(row, column); + }; + this.selectWord = function() { + this.setSelectionRange(this.getWordRange()); + }; + this.selectAWord = function() { + var cursor = this.getCursor(); + var range = this.session.getAWordRange(cursor.row, cursor.column); + this.setSelectionRange(range); + }; + + this.getLineRange = function(row, excludeLastChar) { + var rowStart = typeof row == "number" ? row : this.lead.row; + var rowEnd; + + var foldLine = this.session.getFoldLine(rowStart); + if (foldLine) { + rowStart = foldLine.start.row; + rowEnd = foldLine.end.row; + } else { + rowEnd = rowStart; + } + if (excludeLastChar === true) + return new Range(rowStart, 0, rowEnd, this.session.getLine(rowEnd).length); + else + return new Range(rowStart, 0, rowEnd + 1, 0); + }; + this.selectLine = function() { + this.setSelectionRange(this.getLineRange()); + }; + this.moveCursorUp = function() { + this.moveCursorBy(-1, 0); + }; + this.moveCursorDown = function() { + this.moveCursorBy(1, 0); + }; + this.wouldMoveIntoSoftTab = function(cursor, tabSize, direction) { + var start = cursor.column; + var end = cursor.column + tabSize; + + if (direction < 0) { + start = cursor.column - tabSize; + end = cursor.column; + } + return this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(start, end).split(" ").length-1 == tabSize; + }; + this.moveCursorLeft = function() { + var cursor = this.lead.getPosition(), + fold; + + if (fold = this.session.getFoldAt(cursor.row, cursor.column, -1)) { + this.moveCursorTo(fold.start.row, fold.start.column); + } else if (cursor.column === 0) { + if (cursor.row > 0) { + this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length); + } + } + else { + var tabSize = this.session.getTabSize(); + if (this.wouldMoveIntoSoftTab(cursor, tabSize, -1) && !this.session.getNavigateWithinSoftTabs()) { + this.moveCursorBy(0, -tabSize); + } else { + this.moveCursorBy(0, -1); + } + } + }; + this.moveCursorRight = function() { + var cursor = this.lead.getPosition(), + fold; + if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) { + this.moveCursorTo(fold.end.row, fold.end.column); + } + else if (this.lead.column == this.doc.getLine(this.lead.row).length) { + if (this.lead.row < this.doc.getLength() - 1) { + this.moveCursorTo(this.lead.row + 1, 0); + } + } + else { + var tabSize = this.session.getTabSize(); + var cursor = this.lead; + if (this.wouldMoveIntoSoftTab(cursor, tabSize, 1) && !this.session.getNavigateWithinSoftTabs()) { + this.moveCursorBy(0, tabSize); + } else { + this.moveCursorBy(0, 1); + } + } + }; + this.moveCursorLineStart = function() { + var row = this.lead.row; + var column = this.lead.column; + var screenRow = this.session.documentToScreenRow(row, column); + var firstColumnPosition = this.session.screenToDocumentPosition(screenRow, 0); + var beforeCursor = this.session.getDisplayLine( + row, null, firstColumnPosition.row, + firstColumnPosition.column + ); + + var leadingSpace = beforeCursor.match(/^\s*/); + if (leadingSpace[0].length != column && !this.session.$useEmacsStyleLineStart) + firstColumnPosition.column += leadingSpace[0].length; + this.moveCursorToPosition(firstColumnPosition); + }; + this.moveCursorLineEnd = function() { + var lead = this.lead; + var lineEnd = this.session.getDocumentLastRowColumnPosition(lead.row, lead.column); + if (this.lead.column == lineEnd.column) { + var line = this.session.getLine(lineEnd.row); + if (lineEnd.column == line.length) { + var textEnd = line.search(/\s+$/); + if (textEnd > 0) + lineEnd.column = textEnd; + } + } + + this.moveCursorTo(lineEnd.row, lineEnd.column); + }; + this.moveCursorFileEnd = function() { + var row = this.doc.getLength() - 1; + var column = this.doc.getLine(row).length; + this.moveCursorTo(row, column); + }; + this.moveCursorFileStart = function() { + this.moveCursorTo(0, 0); + }; + this.moveCursorLongWordRight = function() { + var row = this.lead.row; + var column = this.lead.column; + var line = this.doc.getLine(row); + var rightOfCursor = line.substring(column); + + this.session.nonTokenRe.lastIndex = 0; + this.session.tokenRe.lastIndex = 0; + var fold = this.session.getFoldAt(row, column, 1); + if (fold) { + this.moveCursorTo(fold.end.row, fold.end.column); + return; + } + if (this.session.nonTokenRe.exec(rightOfCursor)) { + column += this.session.nonTokenRe.lastIndex; + this.session.nonTokenRe.lastIndex = 0; + rightOfCursor = line.substring(column); + } + if (column >= line.length) { + this.moveCursorTo(row, line.length); + this.moveCursorRight(); + if (row < this.doc.getLength() - 1) + this.moveCursorWordRight(); + return; + } + if (this.session.tokenRe.exec(rightOfCursor)) { + column += this.session.tokenRe.lastIndex; + this.session.tokenRe.lastIndex = 0; + } + + this.moveCursorTo(row, column); + }; + this.moveCursorLongWordLeft = function() { + var row = this.lead.row; + var column = this.lead.column; + var fold; + if (fold = this.session.getFoldAt(row, column, -1)) { + this.moveCursorTo(fold.start.row, fold.start.column); + return; + } + + var str = this.session.getFoldStringAt(row, column, -1); + if (str == null) { + str = this.doc.getLine(row).substring(0, column); + } + + var leftOfCursor = lang.stringReverse(str); + this.session.nonTokenRe.lastIndex = 0; + this.session.tokenRe.lastIndex = 0; + if (this.session.nonTokenRe.exec(leftOfCursor)) { + column -= this.session.nonTokenRe.lastIndex; + leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex); + this.session.nonTokenRe.lastIndex = 0; + } + if (column <= 0) { + this.moveCursorTo(row, 0); + this.moveCursorLeft(); + if (row > 0) + this.moveCursorWordLeft(); + return; + } + if (this.session.tokenRe.exec(leftOfCursor)) { + column -= this.session.tokenRe.lastIndex; + this.session.tokenRe.lastIndex = 0; + } + + this.moveCursorTo(row, column); + }; + + this.$shortWordEndIndex = function(rightOfCursor) { + var index = 0, ch; + var whitespaceRe = /\s/; + var tokenRe = this.session.tokenRe; + + tokenRe.lastIndex = 0; + if (this.session.tokenRe.exec(rightOfCursor)) { + index = this.session.tokenRe.lastIndex; + } else { + while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch)) + index ++; + + if (index < 1) { + tokenRe.lastIndex = 0; + while ((ch = rightOfCursor[index]) && !tokenRe.test(ch)) { + tokenRe.lastIndex = 0; + index ++; + if (whitespaceRe.test(ch)) { + if (index > 2) { + index--; + break; + } else { + while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch)) + index ++; + if (index > 2) + break; + } + } + } + } + } + tokenRe.lastIndex = 0; + + return index; + }; + + this.moveCursorShortWordRight = function() { + var row = this.lead.row; + var column = this.lead.column; + var line = this.doc.getLine(row); + var rightOfCursor = line.substring(column); + + var fold = this.session.getFoldAt(row, column, 1); + if (fold) + return this.moveCursorTo(fold.end.row, fold.end.column); + + if (column == line.length) { + var l = this.doc.getLength(); + do { + row++; + rightOfCursor = this.doc.getLine(row); + } while (row < l && /^\s*$/.test(rightOfCursor)); + + if (!/^\s+/.test(rightOfCursor)) + rightOfCursor = ""; + column = 0; + } + + var index = this.$shortWordEndIndex(rightOfCursor); + + this.moveCursorTo(row, column + index); + }; + + this.moveCursorShortWordLeft = function() { + var row = this.lead.row; + var column = this.lead.column; + + var fold; + if (fold = this.session.getFoldAt(row, column, -1)) + return this.moveCursorTo(fold.start.row, fold.start.column); + + var line = this.session.getLine(row).substring(0, column); + if (column === 0) { + do { + row--; + line = this.doc.getLine(row); + } while (row > 0 && /^\s*$/.test(line)); + + column = line.length; + if (!/\s+$/.test(line)) + line = ""; + } + + var leftOfCursor = lang.stringReverse(line); + var index = this.$shortWordEndIndex(leftOfCursor); + + return this.moveCursorTo(row, column - index); + }; + + this.moveCursorWordRight = function() { + if (this.session.$selectLongWords) + this.moveCursorLongWordRight(); + else + this.moveCursorShortWordRight(); + }; + + this.moveCursorWordLeft = function() { + if (this.session.$selectLongWords) + this.moveCursorLongWordLeft(); + else + this.moveCursorShortWordLeft(); + }; + this.moveCursorBy = function(rows, chars) { + var screenPos = this.session.documentToScreenPosition( + this.lead.row, + this.lead.column + ); + + var offsetX; + + if (chars === 0) { + if (rows !== 0) { + if (this.session.$bidiHandler.isBidiRow(screenPos.row, this.lead.row)) { + offsetX = this.session.$bidiHandler.getPosLeft(screenPos.column); + screenPos.column = Math.round(offsetX / this.session.$bidiHandler.charWidths[0]); + } else { + offsetX = screenPos.column * this.session.$bidiHandler.charWidths[0]; + } + } + + if (this.$desiredColumn) + screenPos.column = this.$desiredColumn; + else + this.$desiredColumn = screenPos.column; + } + + if (rows != 0 && this.session.lineWidgets && this.session.lineWidgets[this.lead.row]) { + var widget = this.session.lineWidgets[this.lead.row]; + if (rows < 0) + rows -= widget.rowsAbove || 0; + else if (rows > 0) + rows += widget.rowCount - (widget.rowsAbove || 0); + } + + var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column, offsetX); + + if (rows !== 0 && chars === 0 && docPos.row === this.lead.row && docPos.column === this.lead.column) { + + } + this.moveCursorTo(docPos.row, docPos.column + chars, chars === 0); + }; + this.moveCursorToPosition = function(position) { + this.moveCursorTo(position.row, position.column); + }; + this.moveCursorTo = function(row, column, keepDesiredColumn) { + var fold = this.session.getFoldAt(row, column, 1); + if (fold) { + row = fold.start.row; + column = fold.start.column; + } + + this.$keepDesiredColumnOnChange = true; + var line = this.session.getLine(row); + if (/[\uDC00-\uDFFF]/.test(line.charAt(column)) && line.charAt(column - 1)) { + if (this.lead.row == row && this.lead.column == column + 1) + column = column - 1; + else + column = column + 1; + } + this.lead.setPosition(row, column); + this.$keepDesiredColumnOnChange = false; + + if (!keepDesiredColumn) + this.$desiredColumn = null; + }; + this.moveCursorToScreen = function(row, column, keepDesiredColumn) { + var pos = this.session.screenToDocumentPosition(row, column); + this.moveCursorTo(pos.row, pos.column, keepDesiredColumn); + }; + this.detach = function() { + this.lead.detach(); + this.anchor.detach(); + this.session = this.doc = null; + }; + + this.fromOrientedRange = function(range) { + this.setSelectionRange(range, range.cursor == range.start); + this.$desiredColumn = range.desiredColumn || this.$desiredColumn; + }; + + this.toOrientedRange = function(range) { + var r = this.getRange(); + if (range) { + range.start.column = r.start.column; + range.start.row = r.start.row; + range.end.column = r.end.column; + range.end.row = r.end.row; + } else { + range = r; + } + + range.cursor = this.isBackwards() ? range.start : range.end; + range.desiredColumn = this.$desiredColumn; + return range; + }; + this.getRangeOfMovements = function(func) { + var start = this.getCursor(); + try { + func(this); + var end = this.getCursor(); + return Range.fromPoints(start, end); + } catch(e) { + return Range.fromPoints(start, start); + } finally { + this.moveCursorToPosition(start); + } + }; + + this.toJSON = function() { + if (this.rangeCount) { + var data = this.ranges.map(function(r) { + var r1 = r.clone(); + r1.isBackwards = r.cursor == r.start; + return r1; + }); + } else { + var data = this.getRange(); + data.isBackwards = this.isBackwards(); + } + return data; + }; + + this.fromJSON = function(data) { + if (data.start == undefined) { + if (this.rangeList && data.length > 1) { + this.toSingleRange(data[0]); + for (var i = data.length; i--; ) { + var r = Range.fromPoints(data[i].start, data[i].end); + if (data[i].isBackwards) + r.cursor = r.start; + this.addRange(r, true); + } + return; + } else { + data = data[0]; + } + } + if (this.rangeList) + this.toSingleRange(data); + this.setSelectionRange(data, data.isBackwards); + }; + + this.isEqual = function(data) { + if ((data.length || this.rangeCount) && data.length != this.rangeCount) + return false; + if (!data.length || !this.ranges) + return this.getRange().isEqual(data); + + for (var i = this.ranges.length; i--; ) { + if (!this.ranges[i].isEqual(data[i])) + return false; + } + return true; + }; + +}).call(Selection.prototype); + +exports.Selection = Selection; +}); + +ace.define("ace/tokenizer",["require","exports","module","ace/config"], function(require, exports, module) { +"use strict"; + +var config = require("./config"); +var MAX_TOKEN_COUNT = 2000; +var Tokenizer = function(rules) { + this.states = rules; + + this.regExps = {}; + this.matchMappings = {}; + for (var key in this.states) { + var state = this.states[key]; + var ruleRegExps = []; + var matchTotal = 0; + var mapping = this.matchMappings[key] = {defaultToken: "text"}; + var flag = "g"; + + var splitterRurles = []; + for (var i = 0; i < state.length; i++) { + var rule = state[i]; + if (rule.defaultToken) + mapping.defaultToken = rule.defaultToken; + if (rule.caseInsensitive) + flag = "gi"; + if (rule.regex == null) + continue; + + if (rule.regex instanceof RegExp) + rule.regex = rule.regex.toString().slice(1, -1); + var adjustedregex = rule.regex; + var matchcount = new RegExp("(?:(" + adjustedregex + ")|(.))").exec("a").length - 2; + if (Array.isArray(rule.token)) { + if (rule.token.length == 1 || matchcount == 1) { + rule.token = rule.token[0]; + } else if (matchcount - 1 != rule.token.length) { + this.reportError("number of classes and regexp groups doesn't match", { + rule: rule, + groupCount: matchcount - 1 + }); + rule.token = rule.token[0]; + } else { + rule.tokenArray = rule.token; + rule.token = null; + rule.onMatch = this.$arrayTokens; + } + } else if (typeof rule.token == "function" && !rule.onMatch) { + if (matchcount > 1) + rule.onMatch = this.$applyToken; + else + rule.onMatch = rule.token; + } + + if (matchcount > 1) { + if (/\\\d/.test(rule.regex)) { + adjustedregex = rule.regex.replace(/\\([0-9]+)/g, function(match, digit) { + return "\\" + (parseInt(digit, 10) + matchTotal + 1); + }); + } else { + matchcount = 1; + adjustedregex = this.removeCapturingGroups(rule.regex); + } + if (!rule.splitRegex && typeof rule.token != "string") + splitterRurles.push(rule); // flag will be known only at the very end + } + + mapping[matchTotal] = i; + matchTotal += matchcount; + + ruleRegExps.push(adjustedregex); + if (!rule.onMatch) + rule.onMatch = null; + } + + if (!ruleRegExps.length) { + mapping[0] = 0; + ruleRegExps.push("$"); + } + + splitterRurles.forEach(function(rule) { + rule.splitRegex = this.createSplitterRegexp(rule.regex, flag); + }, this); + + this.regExps[key] = new RegExp("(" + ruleRegExps.join(")|(") + ")|($)", flag); + } +}; + +(function() { + this.$setMaxTokenCount = function(m) { + MAX_TOKEN_COUNT = m | 0; + }; + + this.$applyToken = function(str) { + var values = this.splitRegex.exec(str).slice(1); + var types = this.token.apply(this, values); + if (typeof types === "string") + return [{type: types, value: str}]; + + var tokens = []; + for (var i = 0, l = types.length; i < l; i++) { + if (values[i]) + tokens[tokens.length] = { + type: types[i], + value: values[i] + }; + } + return tokens; + }; + + this.$arrayTokens = function(str) { + if (!str) + return []; + var values = this.splitRegex.exec(str); + if (!values) + return "text"; + var tokens = []; + var types = this.tokenArray; + for (var i = 0, l = types.length; i < l; i++) { + if (values[i + 1]) + tokens[tokens.length] = { + type: types[i], + value: values[i + 1] + }; + } + return tokens; + }; + + this.removeCapturingGroups = function(src) { + var r = src.replace( + /\\.|\[(?:\\.|[^\\\]])*|\(\?[:=!]|(\()/g, + function(x, y) {return y ? "(?:" : x;} + ); + return r; + }; + + this.createSplitterRegexp = function(src, flag) { + if (src.indexOf("(?=") != -1) { + var stack = 0; + var inChClass = false; + var lastCapture = {}; + src.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([\[\]])/g, function( + m, esc, parenOpen, parenClose, square, index + ) { + if (inChClass) { + inChClass = square != "]"; + } else if (square) { + inChClass = true; + } else if (parenClose) { + if (stack == lastCapture.stack) { + lastCapture.end = index+1; + lastCapture.stack = -1; + } + stack--; + } else if (parenOpen) { + stack++; + if (parenOpen.length != 1) { + lastCapture.stack = stack; + lastCapture.start = index; + } + } + return m; + }); + + if (lastCapture.end != null && /^\)*$/.test(src.substr(lastCapture.end))) + src = src.substring(0, lastCapture.start) + src.substr(lastCapture.end); + } + if (src.charAt(0) != "^") src = "^" + src; + if (src.charAt(src.length - 1) != "$") src += "$"; + + return new RegExp(src, (flag||"").replace("g", "")); + }; + this.getLineTokens = function(line, startState) { + if (startState && typeof startState != "string") { + var stack = startState.slice(0); + startState = stack[0]; + if (startState === "#tmp") { + stack.shift(); + startState = stack.shift(); + } + } else + var stack = []; + + var currentState = startState || "start"; + var state = this.states[currentState]; + if (!state) { + currentState = "start"; + state = this.states[currentState]; + } + var mapping = this.matchMappings[currentState]; + var re = this.regExps[currentState]; + re.lastIndex = 0; + + var match, tokens = []; + var lastIndex = 0; + var matchAttempts = 0; + + var token = {type: null, value: ""}; + + while (match = re.exec(line)) { + var type = mapping.defaultToken; + var rule = null; + var value = match[0]; + var index = re.lastIndex; + + if (index - value.length > lastIndex) { + var skipped = line.substring(lastIndex, index - value.length); + if (token.type == type) { + token.value += skipped; + } else { + if (token.type) + tokens.push(token); + token = {type: type, value: skipped}; + } + } + + for (var i = 0; i < match.length-2; i++) { + if (match[i + 1] === undefined) + continue; + + rule = state[mapping[i]]; + + if (rule.onMatch) + type = rule.onMatch(value, currentState, stack, line); + else + type = rule.token; + + if (rule.next) { + if (typeof rule.next == "string") { + currentState = rule.next; + } else { + currentState = rule.next(currentState, stack); + } + + state = this.states[currentState]; + if (!state) { + this.reportError("state doesn't exist", currentState); + currentState = "start"; + state = this.states[currentState]; + } + mapping = this.matchMappings[currentState]; + lastIndex = index; + re = this.regExps[currentState]; + re.lastIndex = index; + } + if (rule.consumeLineEnd) + lastIndex = index; + break; + } + + if (value) { + if (typeof type === "string") { + if ((!rule || rule.merge !== false) && token.type === type) { + token.value += value; + } else { + if (token.type) + tokens.push(token); + token = {type: type, value: value}; + } + } else if (type) { + if (token.type) + tokens.push(token); + token = {type: null, value: ""}; + for (var i = 0; i < type.length; i++) + tokens.push(type[i]); + } + } + + if (lastIndex == line.length) + break; + + lastIndex = index; + + if (matchAttempts++ > MAX_TOKEN_COUNT) { + if (matchAttempts > 2 * line.length) { + this.reportError("infinite loop with in ace tokenizer", { + startState: startState, + line: line + }); + } + while (lastIndex < line.length) { + if (token.type) + tokens.push(token); + token = { + value: line.substring(lastIndex, lastIndex += 500), + type: "overflow" + }; + } + currentState = "start"; + stack = []; + break; + } + } + + if (token.type) + tokens.push(token); + + if (stack.length > 1) { + if (stack[0] !== currentState) + stack.unshift("#tmp", currentState); + } + return { + tokens : tokens, + state : stack.length ? stack : currentState + }; + }; + + this.reportError = config.reportError; + +}).call(Tokenizer.prototype); + +exports.Tokenizer = Tokenizer; +}); + +ace.define("ace/mode/text_highlight_rules",["require","exports","module","ace/lib/lang"], function(require, exports, module) { +"use strict"; + +var lang = require("../lib/lang"); + +var TextHighlightRules = function() { + + this.$rules = { + "start" : [{ + token : "empty_line", + regex : '^$' + }, { + defaultToken : "text" + }] + }; +}; + +(function() { + + this.addRules = function(rules, prefix) { + if (!prefix) { + for (var key in rules) + this.$rules[key] = rules[key]; + return; + } + for (var key in rules) { + var state = rules[key]; + for (var i = 0; i < state.length; i++) { + var rule = state[i]; + if (rule.next || rule.onMatch) { + if (typeof rule.next == "string") { + if (rule.next.indexOf(prefix) !== 0) + rule.next = prefix + rule.next; + } + if (rule.nextState && rule.nextState.indexOf(prefix) !== 0) + rule.nextState = prefix + rule.nextState; + } + } + this.$rules[prefix + key] = state; + } + }; + + this.getRules = function() { + return this.$rules; + }; + + this.embedRules = function (HighlightRules, prefix, escapeRules, states, append) { + var embedRules = typeof HighlightRules == "function" + ? new HighlightRules().getRules() + : HighlightRules; + if (states) { + for (var i = 0; i < states.length; i++) + states[i] = prefix + states[i]; + } else { + states = []; + for (var key in embedRules) + states.push(prefix + key); + } + + this.addRules(embedRules, prefix); + + if (escapeRules) { + var addRules = Array.prototype[append ? "push" : "unshift"]; + for (var i = 0; i < states.length; i++) + addRules.apply(this.$rules[states[i]], lang.deepCopy(escapeRules)); + } + + if (!this.$embeds) + this.$embeds = []; + this.$embeds.push(prefix); + }; + + this.getEmbeds = function() { + return this.$embeds; + }; + + var pushState = function(currentState, stack) { + if (currentState != "start" || stack.length) + stack.unshift(this.nextState, currentState); + return this.nextState; + }; + var popState = function(currentState, stack) { + stack.shift(); + return stack.shift() || "start"; + }; + + this.normalizeRules = function() { + var id = 0; + var rules = this.$rules; + function processState(key) { + var state = rules[key]; + state.processed = true; + for (var i = 0; i < state.length; i++) { + var rule = state[i]; + var toInsert = null; + if (Array.isArray(rule)) { + toInsert = rule; + rule = {}; + } + if (!rule.regex && rule.start) { + rule.regex = rule.start; + if (!rule.next) + rule.next = []; + rule.next.push({ + defaultToken: rule.token + }, { + token: rule.token + ".end", + regex: rule.end || rule.start, + next: "pop" + }); + rule.token = rule.token + ".start"; + rule.push = true; + } + var next = rule.next || rule.push; + if (next && Array.isArray(next)) { + var stateName = rule.stateName; + if (!stateName) { + stateName = rule.token; + if (typeof stateName != "string") + stateName = stateName[0] || ""; + if (rules[stateName]) + stateName += id++; + } + rules[stateName] = next; + rule.next = stateName; + processState(stateName); + } else if (next == "pop") { + rule.next = popState; + } + + if (rule.push) { + rule.nextState = rule.next || rule.push; + rule.next = pushState; + delete rule.push; + } + + if (rule.rules) { + for (var r in rule.rules) { + if (rules[r]) { + if (rules[r].push) + rules[r].push.apply(rules[r], rule.rules[r]); + } else { + rules[r] = rule.rules[r]; + } + } + } + var includeName = typeof rule == "string" ? rule : rule.include; + if (includeName) { + if (Array.isArray(includeName)) + toInsert = includeName.map(function(x) { return rules[x]; }); + else + toInsert = rules[includeName]; + } + + if (toInsert) { + var args = [i, 1].concat(toInsert); + if (rule.noEscape) + args = args.filter(function(x) {return !x.next;}); + state.splice.apply(state, args); + i--; + } + + if (rule.keywordMap) { + rule.token = this.createKeywordMapper( + rule.keywordMap, rule.defaultToken || "text", rule.caseInsensitive + ); + delete rule.defaultToken; + } + } + } + Object.keys(rules).forEach(processState, this); + }; + + this.createKeywordMapper = function(map, defaultToken, ignoreCase, splitChar) { + var keywords = Object.create(null); + this.$keywordList = []; + Object.keys(map).forEach(function(className) { + var a = map[className]; + var list = a.split(splitChar || "|"); + for (var i = list.length; i--; ) { + var word = list[i]; + this.$keywordList.push(word); + if (ignoreCase) + word = word.toLowerCase(); + keywords[word] = className; + } + }, this); + map = null; + return ignoreCase + ? function(value) {return keywords[value.toLowerCase()] || defaultToken; } + : function(value) {return keywords[value] || defaultToken; }; + }; + + this.getKeywords = function() { + return this.$keywords; + }; + +}).call(TextHighlightRules.prototype); + +exports.TextHighlightRules = TextHighlightRules; +}); + +ace.define("ace/mode/behaviour",["require","exports","module"], function(require, exports, module) { +"use strict"; + +var Behaviour = function() { + this.$behaviours = {}; +}; + +(function () { + + this.add = function (name, action, callback) { + switch (undefined) { + case this.$behaviours: + this.$behaviours = {}; + case this.$behaviours[name]: + this.$behaviours[name] = {}; + } + this.$behaviours[name][action] = callback; + }; + + this.addBehaviours = function (behaviours) { + for (var key in behaviours) { + for (var action in behaviours[key]) { + this.add(key, action, behaviours[key][action]); + } + } + }; + + this.remove = function (name) { + if (this.$behaviours && this.$behaviours[name]) { + delete this.$behaviours[name]; + } + }; + + this.inherit = function (mode, filter) { + if (typeof mode === "function") { + var behaviours = new mode().getBehaviours(filter); + } else { + var behaviours = mode.getBehaviours(filter); + } + this.addBehaviours(behaviours); + }; + + this.getBehaviours = function (filter) { + if (!filter) { + return this.$behaviours; + } else { + var ret = {}; + for (var i = 0; i < filter.length; i++) { + if (this.$behaviours[filter[i]]) { + ret[filter[i]] = this.$behaviours[filter[i]]; + } + } + return ret; + } + }; + +}).call(Behaviour.prototype); + +exports.Behaviour = Behaviour; +}); + +ace.define("ace/token_iterator",["require","exports","module","ace/range"], function(require, exports, module) { +"use strict"; + +var Range = require("./range").Range; +var TokenIterator = function(session, initialRow, initialColumn) { + this.$session = session; + this.$row = initialRow; + this.$rowTokens = session.getTokens(initialRow); + + var token = session.getTokenAt(initialRow, initialColumn); + this.$tokenIndex = token ? token.index : -1; +}; + +(function() { + this.stepBackward = function() { + this.$tokenIndex -= 1; + + while (this.$tokenIndex < 0) { + this.$row -= 1; + if (this.$row < 0) { + this.$row = 0; + return null; + } + + this.$rowTokens = this.$session.getTokens(this.$row); + this.$tokenIndex = this.$rowTokens.length - 1; + } + + return this.$rowTokens[this.$tokenIndex]; + }; + this.stepForward = function() { + this.$tokenIndex += 1; + var rowCount; + while (this.$tokenIndex >= this.$rowTokens.length) { + this.$row += 1; + if (!rowCount) + rowCount = this.$session.getLength(); + if (this.$row >= rowCount) { + this.$row = rowCount - 1; + return null; + } + + this.$rowTokens = this.$session.getTokens(this.$row); + this.$tokenIndex = 0; + } + + return this.$rowTokens[this.$tokenIndex]; + }; + this.getCurrentToken = function () { + return this.$rowTokens[this.$tokenIndex]; + }; + this.getCurrentTokenRow = function () { + return this.$row; + }; + this.getCurrentTokenColumn = function() { + var rowTokens = this.$rowTokens; + var tokenIndex = this.$tokenIndex; + var column = rowTokens[tokenIndex].start; + if (column !== undefined) + return column; + + column = 0; + while (tokenIndex > 0) { + tokenIndex -= 1; + column += rowTokens[tokenIndex].value.length; + } + + return column; + }; + this.getCurrentTokenPosition = function() { + return {row: this.$row, column: this.getCurrentTokenColumn()}; + }; + this.getCurrentTokenRange = function() { + var token = this.$rowTokens[this.$tokenIndex]; + var column = this.getCurrentTokenColumn(); + return new Range(this.$row, column, this.$row, column + token.value.length); + }; + +}).call(TokenIterator.prototype); + +exports.TokenIterator = TokenIterator; +}); + +ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Behaviour = require("../behaviour").Behaviour; +var TokenIterator = require("../../token_iterator").TokenIterator; +var lang = require("../../lib/lang"); + +var SAFE_INSERT_IN_TOKENS = + ["text", "paren.rparen", "rparen", "paren", "punctuation.operator"]; +var SAFE_INSERT_BEFORE_TOKENS = + ["text", "paren.rparen", "rparen", "paren", "punctuation.operator", "comment"]; + +var context; +var contextCache = {}; +var defaultQuotes = {'"' : '"', "'" : "'"}; + +var initContext = function(editor) { + var id = -1; + if (editor.multiSelect) { + id = editor.selection.index; + if (contextCache.rangeCount != editor.multiSelect.rangeCount) + contextCache = {rangeCount: editor.multiSelect.rangeCount}; + } + if (contextCache[id]) + return context = contextCache[id]; + context = contextCache[id] = { + autoInsertedBrackets: 0, + autoInsertedRow: -1, + autoInsertedLineEnd: "", + maybeInsertedBrackets: 0, + maybeInsertedRow: -1, + maybeInsertedLineStart: "", + maybeInsertedLineEnd: "" + }; +}; + +var getWrapped = function(selection, selected, opening, closing) { + var rowDiff = selection.end.row - selection.start.row; + return { + text: opening + selected + closing, + selection: [ + 0, + selection.start.column + 1, + rowDiff, + selection.end.column + (rowDiff ? 0 : 1) + ] + }; +}; + +var CstyleBehaviour = function(options) { + this.add("braces", "insertion", function(state, action, editor, session, text) { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + if (text == '{') { + initContext(editor); + var selection = editor.getSelectionRange(); + var selected = session.doc.getTextRange(selection); + if (selected !== "" && selected !== "{" && editor.getWrapBehavioursEnabled()) { + return getWrapped(selection, selected, '{', '}'); + } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { + if (/[\]\}\)]/.test(line[cursor.column]) || editor.inMultiSelectMode || options && options.braces) { + CstyleBehaviour.recordAutoInsert(editor, session, "}"); + return { + text: '{}', + selection: [1, 1] + }; + } else { + CstyleBehaviour.recordMaybeInsert(editor, session, "{"); + return { + text: '{', + selection: [1, 1] + }; + } + } + } else if (text == '}') { + initContext(editor); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar == '}') { + var matching = session.$findOpeningBracket('}', {column: cursor.column + 1, row: cursor.row}); + if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { + CstyleBehaviour.popAutoInsertedClosing(); + return { + text: '', + selection: [1, 1] + }; + } + } + } else if (text == "\n" || text == "\r\n") { + initContext(editor); + var closing = ""; + if (CstyleBehaviour.isMaybeInsertedClosing(cursor, line)) { + closing = lang.stringRepeat("}", context.maybeInsertedBrackets); + CstyleBehaviour.clearMaybeInsertedClosing(); + } + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar === '}') { + var openBracePos = session.findMatchingBracket({row: cursor.row, column: cursor.column+1}, '}'); + if (!openBracePos) + return null; + var next_indent = this.$getIndent(session.getLine(openBracePos.row)); + } else if (closing) { + var next_indent = this.$getIndent(line); + } else { + CstyleBehaviour.clearMaybeInsertedClosing(); + return; + } + var indent = next_indent + session.getTabString(); + + return { + text: '\n' + indent + '\n' + next_indent + closing, + selection: [1, indent.length, 1, indent.length] + }; + } else { + CstyleBehaviour.clearMaybeInsertedClosing(); + } + }); + + this.add("braces", "deletion", function(state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && selected == '{') { + initContext(editor); + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.end.column, range.end.column + 1); + if (rightChar == '}') { + range.end.column++; + return range; + } else { + context.maybeInsertedBrackets--; + } + } + }); + + this.add("parens", "insertion", function(state, action, editor, session, text) { + if (text == '(') { + initContext(editor); + var selection = editor.getSelectionRange(); + var selected = session.doc.getTextRange(selection); + if (selected !== "" && editor.getWrapBehavioursEnabled()) { + return getWrapped(selection, selected, '(', ')'); + } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { + CstyleBehaviour.recordAutoInsert(editor, session, ")"); + return { + text: '()', + selection: [1, 1] + }; + } + } else if (text == ')') { + initContext(editor); + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar == ')') { + var matching = session.$findOpeningBracket(')', {column: cursor.column + 1, row: cursor.row}); + if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { + CstyleBehaviour.popAutoInsertedClosing(); + return { + text: '', + selection: [1, 1] + }; + } + } + } + }); + + this.add("parens", "deletion", function(state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && selected == '(') { + initContext(editor); + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.start.column + 1, range.start.column + 2); + if (rightChar == ')') { + range.end.column++; + return range; + } + } + }); + + this.add("brackets", "insertion", function(state, action, editor, session, text) { + if (text == '[') { + initContext(editor); + var selection = editor.getSelectionRange(); + var selected = session.doc.getTextRange(selection); + if (selected !== "" && editor.getWrapBehavioursEnabled()) { + return getWrapped(selection, selected, '[', ']'); + } else if (CstyleBehaviour.isSaneInsertion(editor, session)) { + CstyleBehaviour.recordAutoInsert(editor, session, "]"); + return { + text: '[]', + selection: [1, 1] + }; + } + } else if (text == ']') { + initContext(editor); + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar == ']') { + var matching = session.$findOpeningBracket(']', {column: cursor.column + 1, row: cursor.row}); + if (matching !== null && CstyleBehaviour.isAutoInsertedClosing(cursor, line, text)) { + CstyleBehaviour.popAutoInsertedClosing(); + return { + text: '', + selection: [1, 1] + }; + } + } + } + }); + + this.add("brackets", "deletion", function(state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && selected == '[') { + initContext(editor); + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.start.column + 1, range.start.column + 2); + if (rightChar == ']') { + range.end.column++; + return range; + } + } + }); + + this.add("string_dquotes", "insertion", function(state, action, editor, session, text) { + var quotes = session.$mode.$quotes || defaultQuotes; + if (text.length == 1 && quotes[text]) { + if (this.lineCommentStart && this.lineCommentStart.indexOf(text) != -1) + return; + initContext(editor); + var quote = text; + var selection = editor.getSelectionRange(); + var selected = session.doc.getTextRange(selection); + if (selected !== "" && (selected.length != 1 || !quotes[selected]) && editor.getWrapBehavioursEnabled()) { + return getWrapped(selection, selected, quote, quote); + } else if (!selected) { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var leftChar = line.substring(cursor.column-1, cursor.column); + var rightChar = line.substring(cursor.column, cursor.column + 1); + + var token = session.getTokenAt(cursor.row, cursor.column); + var rightToken = session.getTokenAt(cursor.row, cursor.column + 1); + if (leftChar == "\\" && token && /escape/.test(token.type)) + return null; + + var stringBefore = token && /string|escape/.test(token.type); + var stringAfter = !rightToken || /string|escape/.test(rightToken.type); + + var pair; + if (rightChar == quote) { + pair = stringBefore !== stringAfter; + if (pair && /string\.end/.test(rightToken.type)) + pair = false; + } else { + if (stringBefore && !stringAfter) + return null; // wrap string with different quote + if (stringBefore && stringAfter) + return null; // do not pair quotes inside strings + var wordRe = session.$mode.tokenRe; + wordRe.lastIndex = 0; + var isWordBefore = wordRe.test(leftChar); + wordRe.lastIndex = 0; + var isWordAfter = wordRe.test(leftChar); + if (isWordBefore || isWordAfter) + return null; // before or after alphanumeric + if (rightChar && !/[\s;,.})\]\\]/.test(rightChar)) + return null; // there is rightChar and it isn't closing + var charBefore = line[cursor.column - 2]; + if (leftChar == quote && (charBefore == quote || wordRe.test(charBefore))) + return null; + pair = true; + } + return { + text: pair ? quote + quote : "", + selection: [1,1] + }; + } + } + }); + + this.add("string_dquotes", "deletion", function(state, action, editor, session, range) { + var quotes = session.$mode.$quotes || defaultQuotes; + + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && quotes.hasOwnProperty(selected)) { + initContext(editor); + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.start.column + 1, range.start.column + 2); + if (rightChar == selected) { + range.end.column++; + return range; + } + } + }); + +}; + + +CstyleBehaviour.isSaneInsertion = function(editor, session) { + var cursor = editor.getCursorPosition(); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + if (!this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) { + if (/[)}\]]/.test(editor.session.getLine(cursor.row)[cursor.column])) + return true; + var iterator2 = new TokenIterator(session, cursor.row, cursor.column + 1); + if (!this.$matchTokenType(iterator2.getCurrentToken() || "text", SAFE_INSERT_IN_TOKENS)) + return false; + } + iterator.stepForward(); + return iterator.getCurrentTokenRow() !== cursor.row || + this.$matchTokenType(iterator.getCurrentToken() || "text", SAFE_INSERT_BEFORE_TOKENS); +}; + +CstyleBehaviour.$matchTokenType = function(token, types) { + return types.indexOf(token.type || token) > -1; +}; + +CstyleBehaviour.recordAutoInsert = function(editor, session, bracket) { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + if (!this.isAutoInsertedClosing(cursor, line, context.autoInsertedLineEnd[0])) + context.autoInsertedBrackets = 0; + context.autoInsertedRow = cursor.row; + context.autoInsertedLineEnd = bracket + line.substr(cursor.column); + context.autoInsertedBrackets++; +}; + +CstyleBehaviour.recordMaybeInsert = function(editor, session, bracket) { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + if (!this.isMaybeInsertedClosing(cursor, line)) + context.maybeInsertedBrackets = 0; + context.maybeInsertedRow = cursor.row; + context.maybeInsertedLineStart = line.substr(0, cursor.column) + bracket; + context.maybeInsertedLineEnd = line.substr(cursor.column); + context.maybeInsertedBrackets++; +}; + +CstyleBehaviour.isAutoInsertedClosing = function(cursor, line, bracket) { + return context.autoInsertedBrackets > 0 && + cursor.row === context.autoInsertedRow && + bracket === context.autoInsertedLineEnd[0] && + line.substr(cursor.column) === context.autoInsertedLineEnd; +}; + +CstyleBehaviour.isMaybeInsertedClosing = function(cursor, line) { + return context.maybeInsertedBrackets > 0 && + cursor.row === context.maybeInsertedRow && + line.substr(cursor.column) === context.maybeInsertedLineEnd && + line.substr(0, cursor.column) == context.maybeInsertedLineStart; +}; + +CstyleBehaviour.popAutoInsertedClosing = function() { + context.autoInsertedLineEnd = context.autoInsertedLineEnd.substr(1); + context.autoInsertedBrackets--; +}; + +CstyleBehaviour.clearMaybeInsertedClosing = function() { + if (context) { + context.maybeInsertedBrackets = 0; + context.maybeInsertedRow = -1; + } +}; + + + +oop.inherits(CstyleBehaviour, Behaviour); + +exports.CstyleBehaviour = CstyleBehaviour; +}); + +ace.define("ace/unicode",["require","exports","module"], function(require, exports, module) { +"use strict"; +var wordChars = [48,9,8,25,5,0,2,25,48,0,11,0,5,0,6,22,2,30,2,457,5,11,15,4,8,0,2,0,18,116,2,1,3,3,9,0,2,2,2,0,2,19,2,82,2,138,2,4,3,155,12,37,3,0,8,38,10,44,2,0,2,1,2,1,2,0,9,26,6,2,30,10,7,61,2,9,5,101,2,7,3,9,2,18,3,0,17,58,3,100,15,53,5,0,6,45,211,57,3,18,2,5,3,11,3,9,2,1,7,6,2,2,2,7,3,1,3,21,2,6,2,0,4,3,3,8,3,1,3,3,9,0,5,1,2,4,3,11,16,2,2,5,5,1,3,21,2,6,2,1,2,1,2,1,3,0,2,4,5,1,3,2,4,0,8,3,2,0,8,15,12,2,2,8,2,2,2,21,2,6,2,1,2,4,3,9,2,2,2,2,3,0,16,3,3,9,18,2,2,7,3,1,3,21,2,6,2,1,2,4,3,8,3,1,3,2,9,1,5,1,2,4,3,9,2,0,17,1,2,5,4,2,2,3,4,1,2,0,2,1,4,1,4,2,4,11,5,4,4,2,2,3,3,0,7,0,15,9,18,2,2,7,2,2,2,22,2,9,2,4,4,7,2,2,2,3,8,1,2,1,7,3,3,9,19,1,2,7,2,2,2,22,2,9,2,4,3,8,2,2,2,3,8,1,8,0,2,3,3,9,19,1,2,7,2,2,2,22,2,15,4,7,2,2,2,3,10,0,9,3,3,9,11,5,3,1,2,17,4,23,2,8,2,0,3,6,4,0,5,5,2,0,2,7,19,1,14,57,6,14,2,9,40,1,2,0,3,1,2,0,3,0,7,3,2,6,2,2,2,0,2,0,3,1,2,12,2,2,3,4,2,0,2,5,3,9,3,1,35,0,24,1,7,9,12,0,2,0,2,0,5,9,2,35,5,19,2,5,5,7,2,35,10,0,58,73,7,77,3,37,11,42,2,0,4,328,2,3,3,6,2,0,2,3,3,40,2,3,3,32,2,3,3,6,2,0,2,3,3,14,2,56,2,3,3,66,5,0,33,15,17,84,13,619,3,16,2,25,6,74,22,12,2,6,12,20,12,19,13,12,2,2,2,1,13,51,3,29,4,0,5,1,3,9,34,2,3,9,7,87,9,42,6,69,11,28,4,11,5,11,11,39,3,4,12,43,5,25,7,10,38,27,5,62,2,28,3,10,7,9,14,0,89,75,5,9,18,8,13,42,4,11,71,55,9,9,4,48,83,2,2,30,14,230,23,280,3,5,3,37,3,5,3,7,2,0,2,0,2,0,2,30,3,52,2,6,2,0,4,2,2,6,4,3,3,5,5,12,6,2,2,6,67,1,20,0,29,0,14,0,17,4,60,12,5,0,4,11,18,0,5,0,3,9,2,0,4,4,7,0,2,0,2,0,2,3,2,10,3,3,6,4,5,0,53,1,2684,46,2,46,2,132,7,6,15,37,11,53,10,0,17,22,10,6,2,6,2,6,2,6,2,6,2,6,2,6,2,6,2,31,48,0,470,1,36,5,2,4,6,1,5,85,3,1,3,2,2,89,2,3,6,40,4,93,18,23,57,15,513,6581,75,20939,53,1164,68,45,3,268,4,27,21,31,3,13,13,1,2,24,9,69,11,1,38,8,3,102,3,1,111,44,25,51,13,68,12,9,7,23,4,0,5,45,3,35,13,28,4,64,15,10,39,54,10,13,3,9,7,22,4,1,5,66,25,2,227,42,2,1,3,9,7,11171,13,22,5,48,8453,301,3,61,3,105,39,6,13,4,6,11,2,12,2,4,2,0,2,1,2,1,2,107,34,362,19,63,3,53,41,11,5,15,17,6,13,1,25,2,33,4,2,134,20,9,8,25,5,0,2,25,12,88,4,5,3,5,3,5,3,2]; + +var code = 0; +var str = []; +for (var i = 0; i < wordChars.length; i += 2) { + str.push(code += wordChars[i]); + if (wordChars[i + 1]) + str.push(45, code += wordChars[i + 1]); +} + +exports.wordChars = String.fromCharCode.apply(null, str); + +}); + +ace.define("ace/mode/text",["require","exports","module","ace/config","ace/tokenizer","ace/mode/text_highlight_rules","ace/mode/behaviour/cstyle","ace/unicode","ace/lib/lang","ace/token_iterator","ace/range"], function(require, exports, module) { +"use strict"; +var config = require("../config"); + +var Tokenizer = require("../tokenizer").Tokenizer; +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; +var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; +var unicode = require("../unicode"); +var lang = require("../lib/lang"); +var TokenIterator = require("../token_iterator").TokenIterator; +var Range = require("../range").Range; + +var Mode = function() { + this.HighlightRules = TextHighlightRules; +}; + +(function() { + this.$defaultBehaviour = new CstyleBehaviour(); + + this.tokenRe = new RegExp("^[" + unicode.wordChars + "\\$_]+", "g"); + + this.nonTokenRe = new RegExp("^(?:[^" + unicode.wordChars + "\\$_]|\\s])+", "g"); + + this.getTokenizer = function() { + if (!this.$tokenizer) { + this.$highlightRules = this.$highlightRules || new this.HighlightRules(this.$highlightRuleConfig); + this.$tokenizer = new Tokenizer(this.$highlightRules.getRules()); + } + return this.$tokenizer; + }; + + this.lineCommentStart = ""; + this.blockComment = ""; + + this.toggleCommentLines = function(state, session, startRow, endRow) { + var doc = session.doc; + + var ignoreBlankLines = true; + var shouldRemove = true; + var minIndent = Infinity; + var tabSize = session.getTabSize(); + var insertAtTabStop = false; + + if (!this.lineCommentStart) { + if (!this.blockComment) + return false; + var lineCommentStart = this.blockComment.start; + var lineCommentEnd = this.blockComment.end; + var regexpStart = new RegExp("^(\\s*)(?:" + lang.escapeRegExp(lineCommentStart) + ")"); + var regexpEnd = new RegExp("(?:" + lang.escapeRegExp(lineCommentEnd) + ")\\s*$"); + + var comment = function(line, i) { + if (testRemove(line, i)) + return; + if (!ignoreBlankLines || /\S/.test(line)) { + doc.insertInLine({row: i, column: line.length}, lineCommentEnd); + doc.insertInLine({row: i, column: minIndent}, lineCommentStart); + } + }; + + var uncomment = function(line, i) { + var m; + if (m = line.match(regexpEnd)) + doc.removeInLine(i, line.length - m[0].length, line.length); + if (m = line.match(regexpStart)) + doc.removeInLine(i, m[1].length, m[0].length); + }; + + var testRemove = function(line, row) { + if (regexpStart.test(line)) + return true; + var tokens = session.getTokens(row); + for (var i = 0; i < tokens.length; i++) { + if (tokens[i].type === "comment") + return true; + } + }; + } else { + if (Array.isArray(this.lineCommentStart)) { + var regexpStart = this.lineCommentStart.map(lang.escapeRegExp).join("|"); + var lineCommentStart = this.lineCommentStart[0]; + } else { + var regexpStart = lang.escapeRegExp(this.lineCommentStart); + var lineCommentStart = this.lineCommentStart; + } + regexpStart = new RegExp("^(\\s*)(?:" + regexpStart + ") ?"); + + insertAtTabStop = session.getUseSoftTabs(); + + var uncomment = function(line, i) { + var m = line.match(regexpStart); + if (!m) return; + var start = m[1].length, end = m[0].length; + if (!shouldInsertSpace(line, start, end) && m[0][end - 1] == " ") + end--; + doc.removeInLine(i, start, end); + }; + var commentWithSpace = lineCommentStart + " "; + var comment = function(line, i) { + if (!ignoreBlankLines || /\S/.test(line)) { + if (shouldInsertSpace(line, minIndent, minIndent)) + doc.insertInLine({row: i, column: minIndent}, commentWithSpace); + else + doc.insertInLine({row: i, column: minIndent}, lineCommentStart); + } + }; + var testRemove = function(line, i) { + return regexpStart.test(line); + }; + + var shouldInsertSpace = function(line, before, after) { + var spaces = 0; + while (before-- && line.charAt(before) == " ") + spaces++; + if (spaces % tabSize != 0) + return false; + var spaces = 0; + while (line.charAt(after++) == " ") + spaces++; + if (tabSize > 2) + return spaces % tabSize != tabSize - 1; + else + return spaces % tabSize == 0; + }; + } + + function iter(fun) { + for (var i = startRow; i <= endRow; i++) + fun(doc.getLine(i), i); + } + + + var minEmptyLength = Infinity; + iter(function(line, i) { + var indent = line.search(/\S/); + if (indent !== -1) { + if (indent < minIndent) + minIndent = indent; + if (shouldRemove && !testRemove(line, i)) + shouldRemove = false; + } else if (minEmptyLength > line.length) { + minEmptyLength = line.length; + } + }); + + if (minIndent == Infinity) { + minIndent = minEmptyLength; + ignoreBlankLines = false; + shouldRemove = false; + } + + if (insertAtTabStop && minIndent % tabSize != 0) + minIndent = Math.floor(minIndent / tabSize) * tabSize; + + iter(shouldRemove ? uncomment : comment); + }; + + this.toggleBlockComment = function(state, session, range, cursor) { + var comment = this.blockComment; + if (!comment) + return; + if (!comment.start && comment[0]) + comment = comment[0]; + + var iterator = new TokenIterator(session, cursor.row, cursor.column); + var token = iterator.getCurrentToken(); + + var sel = session.selection; + var initialRange = session.selection.toOrientedRange(); + var startRow, colDiff; + + if (token && /comment/.test(token.type)) { + var startRange, endRange; + while (token && /comment/.test(token.type)) { + var i = token.value.indexOf(comment.start); + if (i != -1) { + var row = iterator.getCurrentTokenRow(); + var column = iterator.getCurrentTokenColumn() + i; + startRange = new Range(row, column, row, column + comment.start.length); + break; + } + token = iterator.stepBackward(); + } + + var iterator = new TokenIterator(session, cursor.row, cursor.column); + var token = iterator.getCurrentToken(); + while (token && /comment/.test(token.type)) { + var i = token.value.indexOf(comment.end); + if (i != -1) { + var row = iterator.getCurrentTokenRow(); + var column = iterator.getCurrentTokenColumn() + i; + endRange = new Range(row, column, row, column + comment.end.length); + break; + } + token = iterator.stepForward(); + } + if (endRange) + session.remove(endRange); + if (startRange) { + session.remove(startRange); + startRow = startRange.start.row; + colDiff = -comment.start.length; + } + } else { + colDiff = comment.start.length; + startRow = range.start.row; + session.insert(range.end, comment.end); + session.insert(range.start, comment.start); + } + if (initialRange.start.row == startRow) + initialRange.start.column += colDiff; + if (initialRange.end.row == startRow) + initialRange.end.column += colDiff; + session.selection.fromOrientedRange(initialRange); + }; + + this.getNextLineIndent = function(state, line, tab) { + return this.$getIndent(line); + }; + + this.checkOutdent = function(state, line, input) { + return false; + }; + + this.autoOutdent = function(state, doc, row) { + }; + + this.$getIndent = function(line) { + return line.match(/^\s*/)[0]; + }; + + this.createWorker = function(session) { + return null; + }; + + this.createModeDelegates = function (mapping) { + this.$embeds = []; + this.$modes = {}; + for (var i in mapping) { + if (mapping[i]) { + var Mode = mapping[i]; + var id = Mode.prototype.$id; + var mode = config.$modes[id]; + if (!mode) + config.$modes[id] = mode = new Mode(); + if (!config.$modes[i]) + config.$modes[i] = mode; + this.$embeds.push(i); + this.$modes[i] = mode; + } + } + + var delegations = ["toggleBlockComment", "toggleCommentLines", "getNextLineIndent", + "checkOutdent", "autoOutdent", "transformAction", "getCompletions"]; + + for (var i = 0; i < delegations.length; i++) { + (function(scope) { + var functionName = delegations[i]; + var defaultHandler = scope[functionName]; + scope[delegations[i]] = function() { + return this.$delegator(functionName, arguments, defaultHandler); + }; + }(this)); + } + }; + + this.$delegator = function(method, args, defaultHandler) { + var state = args[0] || "start"; + if (typeof state != "string") { + if (Array.isArray(state[2])) { + var language = state[2][state[2].length - 1]; + var mode = this.$modes[language]; + if (mode) + return mode[method].apply(mode, [state[1]].concat([].slice.call(args, 1))); + } + state = state[0] || "start"; + } + + for (var i = 0; i < this.$embeds.length; i++) { + if (!this.$modes[this.$embeds[i]]) continue; + + var split = state.split(this.$embeds[i]); + if (!split[0] && split[1]) { + args[0] = split[1]; + var mode = this.$modes[this.$embeds[i]]; + return mode[method].apply(mode, args); + } + } + var ret = defaultHandler.apply(this, args); + return defaultHandler ? ret : undefined; + }; + + this.transformAction = function(state, action, editor, session, param) { + if (this.$behaviour) { + var behaviours = this.$behaviour.getBehaviours(); + for (var key in behaviours) { + if (behaviours[key][action]) { + var ret = behaviours[key][action].apply(this, arguments); + if (ret) { + return ret; + } + } + } + } + }; + + this.getKeywords = function(append) { + if (!this.completionKeywords) { + var rules = this.$tokenizer.rules; + var completionKeywords = []; + for (var rule in rules) { + var ruleItr = rules[rule]; + for (var r = 0, l = ruleItr.length; r < l; r++) { + if (typeof ruleItr[r].token === "string") { + if (/keyword|support|storage/.test(ruleItr[r].token)) + completionKeywords.push(ruleItr[r].regex); + } + else if (typeof ruleItr[r].token === "object") { + for (var a = 0, aLength = ruleItr[r].token.length; a < aLength; a++) { + if (/keyword|support|storage/.test(ruleItr[r].token[a])) { + var rule = ruleItr[r].regex.match(/\(.+?\)/g)[a]; + completionKeywords.push(rule.substr(1, rule.length - 2)); + } + } + } + } + } + this.completionKeywords = completionKeywords; + } + if (!append) + return this.$keywordList; + return completionKeywords.concat(this.$keywordList || []); + }; + + this.$createKeywordList = function() { + if (!this.$highlightRules) + this.getTokenizer(); + return this.$keywordList = this.$highlightRules.$keywordList || []; + }; + + this.getCompletions = function(state, session, pos, prefix) { + var keywords = this.$keywordList || this.$createKeywordList(); + return keywords.map(function(word) { + return { + name: word, + value: word, + score: 0, + meta: "keyword" + }; + }); + }; + + this.$id = "ace/mode/text"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); + +ace.define("ace/apply_delta",["require","exports","module"], function(require, exports, module) { +"use strict"; + +function throwDeltaError(delta, errorText){ + console.log("Invalid Delta:", delta); + throw "Invalid Delta: " + errorText; +} + +function positionInDocument(docLines, position) { + return position.row >= 0 && position.row < docLines.length && + position.column >= 0 && position.column <= docLines[position.row].length; +} + +function validateDelta(docLines, delta) { + if (delta.action != "insert" && delta.action != "remove") + throwDeltaError(delta, "delta.action must be 'insert' or 'remove'"); + if (!(delta.lines instanceof Array)) + throwDeltaError(delta, "delta.lines must be an Array"); + if (!delta.start || !delta.end) + throwDeltaError(delta, "delta.start/end must be an present"); + var start = delta.start; + if (!positionInDocument(docLines, delta.start)) + throwDeltaError(delta, "delta.start must be contained in document"); + var end = delta.end; + if (delta.action == "remove" && !positionInDocument(docLines, end)) + throwDeltaError(delta, "delta.end must contained in document for 'remove' actions"); + var numRangeRows = end.row - start.row; + var numRangeLastLineChars = (end.column - (numRangeRows == 0 ? start.column : 0)); + if (numRangeRows != delta.lines.length - 1 || delta.lines[numRangeRows].length != numRangeLastLineChars) + throwDeltaError(delta, "delta.range must match delta lines"); +} + +exports.applyDelta = function(docLines, delta, doNotValidate) { + + var row = delta.start.row; + var startColumn = delta.start.column; + var line = docLines[row] || ""; + switch (delta.action) { + case "insert": + var lines = delta.lines; + if (lines.length === 1) { + docLines[row] = line.substring(0, startColumn) + delta.lines[0] + line.substring(startColumn); + } else { + var args = [row, 1].concat(delta.lines); + docLines.splice.apply(docLines, args); + docLines[row] = line.substring(0, startColumn) + docLines[row]; + docLines[row + delta.lines.length - 1] += line.substring(startColumn); + } + break; + case "remove": + var endColumn = delta.end.column; + var endRow = delta.end.row; + if (row === endRow) { + docLines[row] = line.substring(0, startColumn) + line.substring(endColumn); + } else { + docLines.splice( + row, endRow - row + 1, + line.substring(0, startColumn) + docLines[endRow].substring(endColumn) + ); + } + break; + } +}; +}); + +ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var EventEmitter = require("./lib/event_emitter").EventEmitter; + +var Anchor = exports.Anchor = function(doc, row, column) { + this.$onChange = this.onChange.bind(this); + this.attach(doc); + + if (typeof column == "undefined") + this.setPosition(row.row, row.column); + else + this.setPosition(row, column); +}; + +(function() { + + oop.implement(this, EventEmitter); + this.getPosition = function() { + return this.$clipPositionToDocument(this.row, this.column); + }; + this.getDocument = function() { + return this.document; + }; + this.$insertRight = false; + this.onChange = function(delta) { + if (delta.start.row == delta.end.row && delta.start.row != this.row) + return; + + if (delta.start.row > this.row) + return; + + var point = $getTransformedPoint(delta, {row: this.row, column: this.column}, this.$insertRight); + this.setPosition(point.row, point.column, true); + }; + + function $pointsInOrder(point1, point2, equalPointsInOrder) { + var bColIsAfter = equalPointsInOrder ? point1.column <= point2.column : point1.column < point2.column; + return (point1.row < point2.row) || (point1.row == point2.row && bColIsAfter); + } + + function $getTransformedPoint(delta, point, moveIfEqual) { + var deltaIsInsert = delta.action == "insert"; + var deltaRowShift = (deltaIsInsert ? 1 : -1) * (delta.end.row - delta.start.row); + var deltaColShift = (deltaIsInsert ? 1 : -1) * (delta.end.column - delta.start.column); + var deltaStart = delta.start; + var deltaEnd = deltaIsInsert ? deltaStart : delta.end; // Collapse insert range. + if ($pointsInOrder(point, deltaStart, moveIfEqual)) { + return { + row: point.row, + column: point.column + }; + } + if ($pointsInOrder(deltaEnd, point, !moveIfEqual)) { + return { + row: point.row + deltaRowShift, + column: point.column + (point.row == deltaEnd.row ? deltaColShift : 0) + }; + } + + return { + row: deltaStart.row, + column: deltaStart.column + }; + } + this.setPosition = function(row, column, noClip) { + var pos; + if (noClip) { + pos = { + row: row, + column: column + }; + } else { + pos = this.$clipPositionToDocument(row, column); + } + + if (this.row == pos.row && this.column == pos.column) + return; + + var old = { + row: this.row, + column: this.column + }; + + this.row = pos.row; + this.column = pos.column; + this._signal("change", { + old: old, + value: pos + }); + }; + this.detach = function() { + this.document.off("change", this.$onChange); + }; + this.attach = function(doc) { + this.document = doc || this.document; + this.document.on("change", this.$onChange); + }; + this.$clipPositionToDocument = function(row, column) { + var pos = {}; + + if (row >= this.document.getLength()) { + pos.row = Math.max(0, this.document.getLength() - 1); + pos.column = this.document.getLine(pos.row).length; + } + else if (row < 0) { + pos.row = 0; + pos.column = 0; + } + else { + pos.row = row; + pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column)); + } + + if (column < 0) + pos.column = 0; + + return pos; + }; + +}).call(Anchor.prototype); + +}); + +ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"], function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var applyDelta = require("./apply_delta").applyDelta; +var EventEmitter = require("./lib/event_emitter").EventEmitter; +var Range = require("./range").Range; +var Anchor = require("./anchor").Anchor; + +var Document = function(textOrLines) { + this.$lines = [""]; + if (textOrLines.length === 0) { + this.$lines = [""]; + } else if (Array.isArray(textOrLines)) { + this.insertMergedLines({row: 0, column: 0}, textOrLines); + } else { + this.insert({row: 0, column:0}, textOrLines); + } +}; + +(function() { + + oop.implement(this, EventEmitter); + this.setValue = function(text) { + var len = this.getLength() - 1; + this.remove(new Range(0, 0, len, this.getLine(len).length)); + this.insert({row: 0, column: 0}, text); + }; + this.getValue = function() { + return this.getAllLines().join(this.getNewLineCharacter()); + }; + this.createAnchor = function(row, column) { + return new Anchor(this, row, column); + }; + if ("aaa".split(/a/).length === 0) { + this.$split = function(text) { + return text.replace(/\r\n|\r/g, "\n").split("\n"); + }; + } else { + this.$split = function(text) { + return text.split(/\r\n|\r|\n/); + }; + } + + + this.$detectNewLine = function(text) { + var match = text.match(/^.*?(\r\n|\r|\n)/m); + this.$autoNewLine = match ? match[1] : "\n"; + this._signal("changeNewLineMode"); + }; + this.getNewLineCharacter = function() { + switch (this.$newLineMode) { + case "windows": + return "\r\n"; + case "unix": + return "\n"; + default: + return this.$autoNewLine || "\n"; + } + }; + + this.$autoNewLine = ""; + this.$newLineMode = "auto"; + this.setNewLineMode = function(newLineMode) { + if (this.$newLineMode === newLineMode) + return; + + this.$newLineMode = newLineMode; + this._signal("changeNewLineMode"); + }; + this.getNewLineMode = function() { + return this.$newLineMode; + }; + this.isNewLine = function(text) { + return (text == "\r\n" || text == "\r" || text == "\n"); + }; + this.getLine = function(row) { + return this.$lines[row] || ""; + }; + this.getLines = function(firstRow, lastRow) { + return this.$lines.slice(firstRow, lastRow + 1); + }; + this.getAllLines = function() { + return this.getLines(0, this.getLength()); + }; + this.getLength = function() { + return this.$lines.length; + }; + this.getTextRange = function(range) { + return this.getLinesForRange(range).join(this.getNewLineCharacter()); + }; + this.getLinesForRange = function(range) { + var lines; + if (range.start.row === range.end.row) { + lines = [this.getLine(range.start.row).substring(range.start.column, range.end.column)]; + } else { + lines = this.getLines(range.start.row, range.end.row); + lines[0] = (lines[0] || "").substring(range.start.column); + var l = lines.length - 1; + if (range.end.row - range.start.row == l) + lines[l] = lines[l].substring(0, range.end.column); + } + return lines; + }; + this.insertLines = function(row, lines) { + console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."); + return this.insertFullLines(row, lines); + }; + this.removeLines = function(firstRow, lastRow) { + console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."); + return this.removeFullLines(firstRow, lastRow); + }; + this.insertNewLine = function(position) { + console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."); + return this.insertMergedLines(position, ["", ""]); + }; + this.insert = function(position, text) { + if (this.getLength() <= 1) + this.$detectNewLine(text); + + return this.insertMergedLines(position, this.$split(text)); + }; + this.insertInLine = function(position, text) { + var start = this.clippedPos(position.row, position.column); + var end = this.pos(position.row, position.column + text.length); + + this.applyDelta({ + start: start, + end: end, + action: "insert", + lines: [text] + }, true); + + return this.clonePos(end); + }; + + this.clippedPos = function(row, column) { + var length = this.getLength(); + if (row === undefined) { + row = length; + } else if (row < 0) { + row = 0; + } else if (row >= length) { + row = length - 1; + column = undefined; + } + var line = this.getLine(row); + if (column == undefined) + column = line.length; + column = Math.min(Math.max(column, 0), line.length); + return {row: row, column: column}; + }; + + this.clonePos = function(pos) { + return {row: pos.row, column: pos.column}; + }; + + this.pos = function(row, column) { + return {row: row, column: column}; + }; + + this.$clipPosition = function(position) { + var length = this.getLength(); + if (position.row >= length) { + position.row = Math.max(0, length - 1); + position.column = this.getLine(length - 1).length; + } else { + position.row = Math.max(0, position.row); + position.column = Math.min(Math.max(position.column, 0), this.getLine(position.row).length); + } + return position; + }; + this.insertFullLines = function(row, lines) { + row = Math.min(Math.max(row, 0), this.getLength()); + var column = 0; + if (row < this.getLength()) { + lines = lines.concat([""]); + column = 0; + } else { + lines = [""].concat(lines); + row--; + column = this.$lines[row].length; + } + this.insertMergedLines({row: row, column: column}, lines); + }; + this.insertMergedLines = function(position, lines) { + var start = this.clippedPos(position.row, position.column); + var end = { + row: start.row + lines.length - 1, + column: (lines.length == 1 ? start.column : 0) + lines[lines.length - 1].length + }; + + this.applyDelta({ + start: start, + end: end, + action: "insert", + lines: lines + }); + + return this.clonePos(end); + }; + this.remove = function(range) { + var start = this.clippedPos(range.start.row, range.start.column); + var end = this.clippedPos(range.end.row, range.end.column); + this.applyDelta({ + start: start, + end: end, + action: "remove", + lines: this.getLinesForRange({start: start, end: end}) + }); + return this.clonePos(start); + }; + this.removeInLine = function(row, startColumn, endColumn) { + var start = this.clippedPos(row, startColumn); + var end = this.clippedPos(row, endColumn); + + this.applyDelta({ + start: start, + end: end, + action: "remove", + lines: this.getLinesForRange({start: start, end: end}) + }, true); + + return this.clonePos(start); + }; + this.removeFullLines = function(firstRow, lastRow) { + firstRow = Math.min(Math.max(0, firstRow), this.getLength() - 1); + lastRow = Math.min(Math.max(0, lastRow ), this.getLength() - 1); + var deleteFirstNewLine = lastRow == this.getLength() - 1 && firstRow > 0; + var deleteLastNewLine = lastRow < this.getLength() - 1; + var startRow = ( deleteFirstNewLine ? firstRow - 1 : firstRow ); + var startCol = ( deleteFirstNewLine ? this.getLine(startRow).length : 0 ); + var endRow = ( deleteLastNewLine ? lastRow + 1 : lastRow ); + var endCol = ( deleteLastNewLine ? 0 : this.getLine(endRow).length ); + var range = new Range(startRow, startCol, endRow, endCol); + var deletedLines = this.$lines.slice(firstRow, lastRow + 1); + + this.applyDelta({ + start: range.start, + end: range.end, + action: "remove", + lines: this.getLinesForRange(range) + }); + return deletedLines; + }; + this.removeNewLine = function(row) { + if (row < this.getLength() - 1 && row >= 0) { + this.applyDelta({ + start: this.pos(row, this.getLine(row).length), + end: this.pos(row + 1, 0), + action: "remove", + lines: ["", ""] + }); + } + }; + this.replace = function(range, text) { + if (!(range instanceof Range)) + range = Range.fromPoints(range.start, range.end); + if (text.length === 0 && range.isEmpty()) + return range.start; + if (text == this.getTextRange(range)) + return range.end; + + this.remove(range); + var end; + if (text) { + end = this.insert(range.start, text); + } + else { + end = range.start; + } + + return end; + }; + this.applyDeltas = function(deltas) { + for (var i=0; i=0; i--) { + this.revertDelta(deltas[i]); + } + }; + this.applyDelta = function(delta, doNotValidate) { + var isInsert = delta.action == "insert"; + if (isInsert ? delta.lines.length <= 1 && !delta.lines[0] + : !Range.comparePoints(delta.start, delta.end)) { + return; + } + + if (isInsert && delta.lines.length > 20000) { + this.$splitAndapplyLargeDelta(delta, 20000); + } + else { + applyDelta(this.$lines, delta, doNotValidate); + this._signal("change", delta); + } + }; + + this.$safeApplyDelta = function(delta) { + var docLength = this.$lines.length; + if ( + delta.action == "remove" && delta.start.row < docLength && delta.end.row < docLength + || delta.action == "insert" && delta.start.row <= docLength + ) { + this.applyDelta(delta); + } + }; + + this.$splitAndapplyLargeDelta = function(delta, MAX) { + var lines = delta.lines; + var l = lines.length - MAX + 1; + var row = delta.start.row; + var column = delta.start.column; + for (var from = 0, to = 0; from < l; from = to) { + to += MAX - 1; + var chunk = lines.slice(from, to); + chunk.push(""); + this.applyDelta({ + start: this.pos(row + from, column), + end: this.pos(row + to, column = 0), + action: delta.action, + lines: chunk + }, true); + } + delta.lines = lines.slice(from); + delta.start.row = row + from; + delta.start.column = column; + this.applyDelta(delta, true); + }; + this.revertDelta = function(delta) { + this.$safeApplyDelta({ + start: this.clonePos(delta.start), + end: this.clonePos(delta.end), + action: (delta.action == "insert" ? "remove" : "insert"), + lines: delta.lines.slice() + }); + }; + this.indexToPosition = function(index, startRow) { + var lines = this.$lines || this.getAllLines(); + var newlineLength = this.getNewLineCharacter().length; + for (var i = startRow || 0, l = lines.length; i < l; i++) { + index -= lines[i].length + newlineLength; + if (index < 0) + return {row: i, column: index + lines[i].length + newlineLength}; + } + return {row: l-1, column: index + lines[l-1].length + newlineLength}; + }; + this.positionToIndex = function(pos, startRow) { + var lines = this.$lines || this.getAllLines(); + var newlineLength = this.getNewLineCharacter().length; + var index = 0; + var row = Math.min(pos.row, lines.length); + for (var i = startRow || 0; i < row; ++i) + index += lines[i].length + newlineLength; + + return index + pos.column; + }; + +}).call(Document.prototype); + +exports.Document = Document; +}); + +ace.define("ace/background_tokenizer",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var EventEmitter = require("./lib/event_emitter").EventEmitter; + +var BackgroundTokenizer = function(tokenizer, editor) { + this.running = false; + this.lines = []; + this.states = []; + this.currentLine = 0; + this.tokenizer = tokenizer; + + var self = this; + + this.$worker = function() { + if (!self.running) { return; } + + var workerStart = new Date(); + var currentLine = self.currentLine; + var endLine = -1; + var doc = self.doc; + + var startLine = currentLine; + while (self.lines[currentLine]) + currentLine++; + + var len = doc.getLength(); + var processedLines = 0; + self.running = false; + while (currentLine < len) { + self.$tokenizeRow(currentLine); + endLine = currentLine; + do { + currentLine++; + } while (self.lines[currentLine]); + processedLines ++; + if ((processedLines % 5 === 0) && (new Date() - workerStart) > 20) { + self.running = setTimeout(self.$worker, 20); + break; + } + } + self.currentLine = currentLine; + + if (endLine == -1) + endLine = currentLine; + + if (startLine <= endLine) + self.fireUpdateEvent(startLine, endLine); + }; +}; + +(function(){ + + oop.implement(this, EventEmitter); + this.setTokenizer = function(tokenizer) { + this.tokenizer = tokenizer; + this.lines = []; + this.states = []; + + this.start(0); + }; + this.setDocument = function(doc) { + this.doc = doc; + this.lines = []; + this.states = []; + + this.stop(); + }; + this.fireUpdateEvent = function(firstRow, lastRow) { + var data = { + first: firstRow, + last: lastRow + }; + this._signal("update", {data: data}); + }; + this.start = function(startRow) { + this.currentLine = Math.min(startRow || 0, this.currentLine, this.doc.getLength()); + this.lines.splice(this.currentLine, this.lines.length); + this.states.splice(this.currentLine, this.states.length); + + this.stop(); + this.running = setTimeout(this.$worker, 700); + }; + + this.scheduleStart = function() { + if (!this.running) + this.running = setTimeout(this.$worker, 700); + }; + + this.$updateOnChange = function(delta) { + var startRow = delta.start.row; + var len = delta.end.row - startRow; + + if (len === 0) { + this.lines[startRow] = null; + } else if (delta.action == "remove") { + this.lines.splice(startRow, len + 1, null); + this.states.splice(startRow, len + 1, null); + } else { + var args = Array(len + 1); + args.unshift(startRow, 1); + this.lines.splice.apply(this.lines, args); + this.states.splice.apply(this.states, args); + } + + this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength()); + + this.stop(); + }; + this.stop = function() { + if (this.running) + clearTimeout(this.running); + this.running = false; + }; + this.getTokens = function(row) { + return this.lines[row] || this.$tokenizeRow(row); + }; + this.getState = function(row) { + if (this.currentLine == row) + this.$tokenizeRow(row); + return this.states[row] || "start"; + }; + + this.$tokenizeRow = function(row) { + var line = this.doc.getLine(row); + var state = this.states[row - 1]; + + var data = this.tokenizer.getLineTokens(line, state, row); + + if (this.states[row] + "" !== data.state + "") { + this.states[row] = data.state; + this.lines[row + 1] = null; + if (this.currentLine > row + 1) + this.currentLine = row + 1; + } else if (this.currentLine == row) { + this.currentLine = row + 1; + } + + return this.lines[row] = data.tokens; + }; + +}).call(BackgroundTokenizer.prototype); + +exports.BackgroundTokenizer = BackgroundTokenizer; +}); + +ace.define("ace/search_highlight",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"], function(require, exports, module) { +"use strict"; + +var lang = require("./lib/lang"); +var oop = require("./lib/oop"); +var Range = require("./range").Range; + +var SearchHighlight = function(regExp, clazz, type) { + this.setRegexp(regExp); + this.clazz = clazz; + this.type = type || "text"; +}; + +(function() { + this.MAX_RANGES = 500; + + this.setRegexp = function(regExp) { + if (this.regExp+"" == regExp+"") + return; + this.regExp = regExp; + this.cache = []; + }; + + this.update = function(html, markerLayer, session, config) { + if (!this.regExp) + return; + var start = config.firstRow, end = config.lastRow; + + for (var i = start; i <= end; i++) { + var ranges = this.cache[i]; + if (ranges == null) { + ranges = lang.getMatchOffsets(session.getLine(i), this.regExp); + if (ranges.length > this.MAX_RANGES) + ranges = ranges.slice(0, this.MAX_RANGES); + ranges = ranges.map(function(match) { + return new Range(i, match.offset, i, match.offset + match.length); + }); + this.cache[i] = ranges.length ? ranges : ""; + } + + for (var j = ranges.length; j --; ) { + markerLayer.drawSingleLineMarker( + html, ranges[j].toScreenRange(session), this.clazz, config); + } + } + }; + +}).call(SearchHighlight.prototype); + +exports.SearchHighlight = SearchHighlight; +}); + +ace.define("ace/edit_session/fold_line",["require","exports","module","ace/range"], function(require, exports, module) { +"use strict"; + +var Range = require("../range").Range; +function FoldLine(foldData, folds) { + this.foldData = foldData; + if (Array.isArray(folds)) { + this.folds = folds; + } else { + folds = this.folds = [ folds ]; + } + + var last = folds[folds.length - 1]; + this.range = new Range(folds[0].start.row, folds[0].start.column, + last.end.row, last.end.column); + this.start = this.range.start; + this.end = this.range.end; + + this.folds.forEach(function(fold) { + fold.setFoldLine(this); + }, this); +} + +(function() { + this.shiftRow = function(shift) { + this.start.row += shift; + this.end.row += shift; + this.folds.forEach(function(fold) { + fold.start.row += shift; + fold.end.row += shift; + }); + }; + + this.addFold = function(fold) { + if (fold.sameRow) { + if (fold.start.row < this.startRow || fold.endRow > this.endRow) { + throw new Error("Can't add a fold to this FoldLine as it has no connection"); + } + this.folds.push(fold); + this.folds.sort(function(a, b) { + return -a.range.compareEnd(b.start.row, b.start.column); + }); + if (this.range.compareEnd(fold.start.row, fold.start.column) > 0) { + this.end.row = fold.end.row; + this.end.column = fold.end.column; + } else if (this.range.compareStart(fold.end.row, fold.end.column) < 0) { + this.start.row = fold.start.row; + this.start.column = fold.start.column; + } + } else if (fold.start.row == this.end.row) { + this.folds.push(fold); + this.end.row = fold.end.row; + this.end.column = fold.end.column; + } else if (fold.end.row == this.start.row) { + this.folds.unshift(fold); + this.start.row = fold.start.row; + this.start.column = fold.start.column; + } else { + throw new Error("Trying to add fold to FoldRow that doesn't have a matching row"); + } + fold.foldLine = this; + }; + + this.containsRow = function(row) { + return row >= this.start.row && row <= this.end.row; + }; + + this.walk = function(callback, endRow, endColumn) { + var lastEnd = 0, + folds = this.folds, + fold, + cmp, stop, isNewRow = true; + + if (endRow == null) { + endRow = this.end.row; + endColumn = this.end.column; + } + + for (var i = 0; i < folds.length; i++) { + fold = folds[i]; + + cmp = fold.range.compareStart(endRow, endColumn); + if (cmp == -1) { + callback(null, endRow, endColumn, lastEnd, isNewRow); + return; + } + + stop = callback(null, fold.start.row, fold.start.column, lastEnd, isNewRow); + stop = !stop && callback(fold.placeholder, fold.start.row, fold.start.column, lastEnd); + if (stop || cmp === 0) { + return; + } + isNewRow = !fold.sameRow; + lastEnd = fold.end.column; + } + callback(null, endRow, endColumn, lastEnd, isNewRow); + }; + + this.getNextFoldTo = function(row, column) { + var fold, cmp; + for (var i = 0; i < this.folds.length; i++) { + fold = this.folds[i]; + cmp = fold.range.compareEnd(row, column); + if (cmp == -1) { + return { + fold: fold, + kind: "after" + }; + } else if (cmp === 0) { + return { + fold: fold, + kind: "inside" + }; + } + } + return null; + }; + + this.addRemoveChars = function(row, column, len) { + var ret = this.getNextFoldTo(row, column), + fold, folds; + if (ret) { + fold = ret.fold; + if (ret.kind == "inside" + && fold.start.column != column + && fold.start.row != row) + { + window.console && window.console.log(row, column, fold); + } else if (fold.start.row == row) { + folds = this.folds; + var i = folds.indexOf(fold); + if (i === 0) { + this.start.column += len; + } + for (i; i < folds.length; i++) { + fold = folds[i]; + fold.start.column += len; + if (!fold.sameRow) { + return; + } + fold.end.column += len; + } + this.end.column += len; + } + } + }; + + this.split = function(row, column) { + var pos = this.getNextFoldTo(row, column); + + if (!pos || pos.kind == "inside") + return null; + + var fold = pos.fold; + var folds = this.folds; + var foldData = this.foldData; + + var i = folds.indexOf(fold); + var foldBefore = folds[i - 1]; + this.end.row = foldBefore.end.row; + this.end.column = foldBefore.end.column; + folds = folds.splice(i, folds.length - i); + + var newFoldLine = new FoldLine(foldData, folds); + foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine); + return newFoldLine; + }; + + this.merge = function(foldLineNext) { + var folds = foldLineNext.folds; + for (var i = 0; i < folds.length; i++) { + this.addFold(folds[i]); + } + var foldData = this.foldData; + foldData.splice(foldData.indexOf(foldLineNext), 1); + }; + + this.toString = function() { + var ret = [this.range.toString() + ": [" ]; + + this.folds.forEach(function(fold) { + ret.push(" " + fold.toString()); + }); + ret.push("]"); + return ret.join("\n"); + }; + + this.idxToPosition = function(idx) { + var lastFoldEndColumn = 0; + + for (var i = 0; i < this.folds.length; i++) { + var fold = this.folds[i]; + + idx -= fold.start.column - lastFoldEndColumn; + if (idx < 0) { + return { + row: fold.start.row, + column: fold.start.column + idx + }; + } + + idx -= fold.placeholder.length; + if (idx < 0) { + return fold.start; + } + + lastFoldEndColumn = fold.end.column; + } + + return { + row: this.end.row, + column: this.end.column + idx + }; + }; +}).call(FoldLine.prototype); + +exports.FoldLine = FoldLine; +}); + +ace.define("ace/range_list",["require","exports","module","ace/range"], function(require, exports, module) { +"use strict"; +var Range = require("./range").Range; +var comparePoints = Range.comparePoints; + +var RangeList = function() { + this.ranges = []; + this.$bias = 1; +}; + +(function() { + this.comparePoints = comparePoints; + + this.pointIndex = function(pos, excludeEdges, startIndex) { + var list = this.ranges; + + for (var i = startIndex || 0; i < list.length; i++) { + var range = list[i]; + var cmpEnd = comparePoints(pos, range.end); + if (cmpEnd > 0) + continue; + var cmpStart = comparePoints(pos, range.start); + if (cmpEnd === 0) + return excludeEdges && cmpStart !== 0 ? -i-2 : i; + if (cmpStart > 0 || (cmpStart === 0 && !excludeEdges)) + return i; + + return -i-1; + } + return -i - 1; + }; + + this.add = function(range) { + var excludeEdges = !range.isEmpty(); + var startIndex = this.pointIndex(range.start, excludeEdges); + if (startIndex < 0) + startIndex = -startIndex - 1; + + var endIndex = this.pointIndex(range.end, excludeEdges, startIndex); + + if (endIndex < 0) + endIndex = -endIndex - 1; + else + endIndex++; + return this.ranges.splice(startIndex, endIndex - startIndex, range); + }; + + this.addList = function(list) { + var removed = []; + for (var i = list.length; i--; ) { + removed.push.apply(removed, this.add(list[i])); + } + return removed; + }; + + this.substractPoint = function(pos) { + var i = this.pointIndex(pos); + + if (i >= 0) + return this.ranges.splice(i, 1); + }; + this.merge = function() { + var removed = []; + var list = this.ranges; + + list = list.sort(function(a, b) { + return comparePoints(a.start, b.start); + }); + + var next = list[0], range; + for (var i = 1; i < list.length; i++) { + range = next; + next = list[i]; + var cmp = comparePoints(range.end, next.start); + if (cmp < 0) + continue; + + if (cmp == 0 && !range.isEmpty() && !next.isEmpty()) + continue; + + if (comparePoints(range.end, next.end) < 0) { + range.end.row = next.end.row; + range.end.column = next.end.column; + } + + list.splice(i, 1); + removed.push(next); + next = range; + i--; + } + + this.ranges = list; + + return removed; + }; + + this.contains = function(row, column) { + return this.pointIndex({row: row, column: column}) >= 0; + }; + + this.containsPoint = function(pos) { + return this.pointIndex(pos) >= 0; + }; + + this.rangeAtPoint = function(pos) { + var i = this.pointIndex(pos); + if (i >= 0) + return this.ranges[i]; + }; + + + this.clipRows = function(startRow, endRow) { + var list = this.ranges; + if (list[0].start.row > endRow || list[list.length - 1].start.row < startRow) + return []; + + var startIndex = this.pointIndex({row: startRow, column: 0}); + if (startIndex < 0) + startIndex = -startIndex - 1; + var endIndex = this.pointIndex({row: endRow, column: 0}, startIndex); + if (endIndex < 0) + endIndex = -endIndex - 1; + + var clipped = []; + for (var i = startIndex; i < endIndex; i++) { + clipped.push(list[i]); + } + return clipped; + }; + + this.removeAll = function() { + return this.ranges.splice(0, this.ranges.length); + }; + + this.attach = function(session) { + if (this.session) + this.detach(); + + this.session = session; + this.onChange = this.$onChange.bind(this); + + this.session.on('change', this.onChange); + }; + + this.detach = function() { + if (!this.session) + return; + this.session.removeListener('change', this.onChange); + this.session = null; + }; + + this.$onChange = function(delta) { + var start = delta.start; + var end = delta.end; + var startRow = start.row; + var endRow = end.row; + var ranges = this.ranges; + for (var i = 0, n = ranges.length; i < n; i++) { + var r = ranges[i]; + if (r.end.row >= startRow) + break; + } + + if (delta.action == "insert") { + var lineDif = endRow - startRow; + var colDiff = -start.column + end.column; + for (; i < n; i++) { + var r = ranges[i]; + if (r.start.row > startRow) + break; + + if (r.start.row == startRow && r.start.column >= start.column) { + if (r.start.column == start.column && this.$bias <= 0) { + } else { + r.start.column += colDiff; + r.start.row += lineDif; + } + } + if (r.end.row == startRow && r.end.column >= start.column) { + if (r.end.column == start.column && this.$bias < 0) { + continue; + } + if (r.end.column == start.column && colDiff > 0 && i < n - 1) { + if (r.end.column > r.start.column && r.end.column == ranges[i+1].start.column) + r.end.column -= colDiff; + } + r.end.column += colDiff; + r.end.row += lineDif; + } + } + } else { + var lineDif = startRow - endRow; + var colDiff = start.column - end.column; + for (; i < n; i++) { + var r = ranges[i]; + + if (r.start.row > endRow) + break; + + if (r.end.row < endRow + && ( + startRow < r.end.row + || startRow == r.end.row && start.column < r.end.column + ) + ) { + r.end.row = startRow; + r.end.column = start.column; + } + else if (r.end.row == endRow) { + if (r.end.column <= end.column) { + if (lineDif || r.end.column > start.column) { + r.end.column = start.column; + r.end.row = start.row; + } + } + else { + r.end.column += colDiff; + r.end.row += lineDif; + } + } + else if (r.end.row > endRow) { + r.end.row += lineDif; + } + + if (r.start.row < endRow + && ( + startRow < r.start.row + || startRow == r.start.row && start.column < r.start.column + ) + ) { + r.start.row = startRow; + r.start.column = start.column; + } + else if (r.start.row == endRow) { + if (r.start.column <= end.column) { + if (lineDif || r.start.column > start.column) { + r.start.column = start.column; + r.start.row = start.row; + } + } + else { + r.start.column += colDiff; + r.start.row += lineDif; + } + } + else if (r.start.row > endRow) { + r.start.row += lineDif; + } + } + } + + if (lineDif != 0 && i < n) { + for (; i < n; i++) { + var r = ranges[i]; + r.start.row += lineDif; + r.end.row += lineDif; + } + } + }; + +}).call(RangeList.prototype); + +exports.RangeList = RangeList; +}); + +ace.define("ace/edit_session/fold",["require","exports","module","ace/range_list","ace/lib/oop"], function(require, exports, module) { +"use strict"; + +var RangeList = require("../range_list").RangeList; +var oop = require("../lib/oop"); +var Fold = exports.Fold = function(range, placeholder) { + this.foldLine = null; + this.placeholder = placeholder; + this.range = range; + this.start = range.start; + this.end = range.end; + + this.sameRow = range.start.row == range.end.row; + this.subFolds = this.ranges = []; +}; + +oop.inherits(Fold, RangeList); + +(function() { + + this.toString = function() { + return '"' + this.placeholder + '" ' + this.range.toString(); + }; + + this.setFoldLine = function(foldLine) { + this.foldLine = foldLine; + this.subFolds.forEach(function(fold) { + fold.setFoldLine(foldLine); + }); + }; + + this.clone = function() { + var range = this.range.clone(); + var fold = new Fold(range, this.placeholder); + this.subFolds.forEach(function(subFold) { + fold.subFolds.push(subFold.clone()); + }); + fold.collapseChildren = this.collapseChildren; + return fold; + }; + + this.addSubFold = function(fold) { + if (this.range.isEqual(fold)) + return; + consumeRange(fold, this.start); + + var row = fold.start.row, column = fold.start.column; + for (var i = 0, cmp = -1; i < this.subFolds.length; i++) { + cmp = this.subFolds[i].range.compare(row, column); + if (cmp != 1) + break; + } + var afterStart = this.subFolds[i]; + var firstConsumed = 0; + + if (cmp == 0) { + if (afterStart.range.containsRange(fold)) + return afterStart.addSubFold(fold); + else + firstConsumed = 1; + } + var row = fold.range.end.row, column = fold.range.end.column; + for (var j = i, cmp = -1; j < this.subFolds.length; j++) { + cmp = this.subFolds[j].range.compare(row, column); + if (cmp != 1) + break; + } + if (cmp == 0) j++; + var consumedFolds = this.subFolds.splice(i, j - i, fold); + var last = cmp == 0 ? consumedFolds.length - 1 : consumedFolds.length; + for (var k = firstConsumed; k < last; k++) { + fold.addSubFold(consumedFolds[k]); + } + fold.setFoldLine(this.foldLine); + + return fold; + }; + + this.restoreRange = function(range) { + return restoreRange(range, this.start); + }; + +}).call(Fold.prototype); + +function consumePoint(point, anchor) { + point.row -= anchor.row; + if (point.row == 0) + point.column -= anchor.column; +} +function consumeRange(range, anchor) { + consumePoint(range.start, anchor); + consumePoint(range.end, anchor); +} +function restorePoint(point, anchor) { + if (point.row == 0) + point.column += anchor.column; + point.row += anchor.row; +} +function restoreRange(range, anchor) { + restorePoint(range.start, anchor); + restorePoint(range.end, anchor); +} + +}); + +ace.define("ace/edit_session/folding",["require","exports","module","ace/range","ace/edit_session/fold_line","ace/edit_session/fold","ace/token_iterator"], function(require, exports, module) { +"use strict"; + +var Range = require("../range").Range; +var FoldLine = require("./fold_line").FoldLine; +var Fold = require("./fold").Fold; +var TokenIterator = require("../token_iterator").TokenIterator; + +function Folding() { + this.getFoldAt = function(row, column, side) { + var foldLine = this.getFoldLine(row); + if (!foldLine) + return null; + + var folds = foldLine.folds; + for (var i = 0; i < folds.length; i++) { + var range = folds[i].range; + if (range.contains(row, column)) { + if (side == 1 && range.isEnd(row, column) && !range.isEmpty()) { + continue; + } else if (side == -1 && range.isStart(row, column) && !range.isEmpty()) { + continue; + } + return folds[i]; + } + } + }; + this.getFoldsInRange = function(range) { + var start = range.start; + var end = range.end; + var foldLines = this.$foldData; + var foundFolds = []; + + start.column += 1; + end.column -= 1; + + for (var i = 0; i < foldLines.length; i++) { + var cmp = foldLines[i].range.compareRange(range); + if (cmp == 2) { + continue; + } + else if (cmp == -2) { + break; + } + + var folds = foldLines[i].folds; + for (var j = 0; j < folds.length; j++) { + var fold = folds[j]; + cmp = fold.range.compareRange(range); + if (cmp == -2) { + break; + } else if (cmp == 2) { + continue; + } else + if (cmp == 42) { + break; + } + foundFolds.push(fold); + } + } + start.column -= 1; + end.column += 1; + + return foundFolds; + }; + + this.getFoldsInRangeList = function(ranges) { + if (Array.isArray(ranges)) { + var folds = []; + ranges.forEach(function(range) { + folds = folds.concat(this.getFoldsInRange(range)); + }, this); + } else { + var folds = this.getFoldsInRange(ranges); + } + return folds; + }; + this.getAllFolds = function() { + var folds = []; + var foldLines = this.$foldData; + + for (var i = 0; i < foldLines.length; i++) + for (var j = 0; j < foldLines[i].folds.length; j++) + folds.push(foldLines[i].folds[j]); + + return folds; + }; + this.getFoldStringAt = function(row, column, trim, foldLine) { + foldLine = foldLine || this.getFoldLine(row); + if (!foldLine) + return null; + + var lastFold = { + end: { column: 0 } + }; + var str, fold; + for (var i = 0; i < foldLine.folds.length; i++) { + fold = foldLine.folds[i]; + var cmp = fold.range.compareEnd(row, column); + if (cmp == -1) { + str = this + .getLine(fold.start.row) + .substring(lastFold.end.column, fold.start.column); + break; + } + else if (cmp === 0) { + return null; + } + lastFold = fold; + } + if (!str) + str = this.getLine(fold.start.row).substring(lastFold.end.column); + + if (trim == -1) + return str.substring(0, column - lastFold.end.column); + else if (trim == 1) + return str.substring(column - lastFold.end.column); + else + return str; + }; + + this.getFoldLine = function(docRow, startFoldLine) { + var foldData = this.$foldData; + var i = 0; + if (startFoldLine) + i = foldData.indexOf(startFoldLine); + if (i == -1) + i = 0; + for (i; i < foldData.length; i++) { + var foldLine = foldData[i]; + if (foldLine.start.row <= docRow && foldLine.end.row >= docRow) { + return foldLine; + } else if (foldLine.end.row > docRow) { + return null; + } + } + return null; + }; + this.getNextFoldLine = function(docRow, startFoldLine) { + var foldData = this.$foldData; + var i = 0; + if (startFoldLine) + i = foldData.indexOf(startFoldLine); + if (i == -1) + i = 0; + for (i; i < foldData.length; i++) { + var foldLine = foldData[i]; + if (foldLine.end.row >= docRow) { + return foldLine; + } + } + return null; + }; + + this.getFoldedRowCount = function(first, last) { + var foldData = this.$foldData, rowCount = last-first+1; + for (var i = 0; i < foldData.length; i++) { + var foldLine = foldData[i], + end = foldLine.end.row, + start = foldLine.start.row; + if (end >= last) { + if (start < last) { + if (start >= first) + rowCount -= last-start; + else + rowCount = 0; // in one fold + } + break; + } else if (end >= first){ + if (start >= first) // fold inside range + rowCount -= end-start; + else + rowCount -= end-first+1; + } + } + return rowCount; + }; + + this.$addFoldLine = function(foldLine) { + this.$foldData.push(foldLine); + this.$foldData.sort(function(a, b) { + return a.start.row - b.start.row; + }); + return foldLine; + }; + this.addFold = function(placeholder, range) { + var foldData = this.$foldData; + var added = false; + var fold; + + if (placeholder instanceof Fold) + fold = placeholder; + else { + fold = new Fold(range, placeholder); + fold.collapseChildren = range.collapseChildren; + } + this.$clipRangeToDocument(fold.range); + + var startRow = fold.start.row; + var startColumn = fold.start.column; + var endRow = fold.end.row; + var endColumn = fold.end.column; + + var startFold = this.getFoldAt(startRow, startColumn, 1); + var endFold = this.getFoldAt(endRow, endColumn, -1); + if (startFold && endFold == startFold) + return startFold.addSubFold(fold); + + if (startFold && !startFold.range.isStart(startRow, startColumn)) + this.removeFold(startFold); + + if (endFold && !endFold.range.isEnd(endRow, endColumn)) + this.removeFold(endFold); + var folds = this.getFoldsInRange(fold.range); + if (folds.length > 0) { + this.removeFolds(folds); + if (!fold.collapseChildren) { + folds.forEach(function(subFold) { + fold.addSubFold(subFold); + }); + } + } + + for (var i = 0; i < foldData.length; i++) { + var foldLine = foldData[i]; + if (endRow == foldLine.start.row) { + foldLine.addFold(fold); + added = true; + break; + } else if (startRow == foldLine.end.row) { + foldLine.addFold(fold); + added = true; + if (!fold.sameRow) { + var foldLineNext = foldData[i + 1]; + if (foldLineNext && foldLineNext.start.row == endRow) { + foldLine.merge(foldLineNext); + break; + } + } + break; + } else if (endRow <= foldLine.start.row) { + break; + } + } + + if (!added) + foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold)); + + if (this.$useWrapMode) + this.$updateWrapData(foldLine.start.row, foldLine.start.row); + else + this.$updateRowLengthCache(foldLine.start.row, foldLine.start.row); + this.$modified = true; + this._signal("changeFold", { data: fold, action: "add" }); + + return fold; + }; + + this.addFolds = function(folds) { + folds.forEach(function(fold) { + this.addFold(fold); + }, this); + }; + + this.removeFold = function(fold) { + var foldLine = fold.foldLine; + var startRow = foldLine.start.row; + var endRow = foldLine.end.row; + + var foldLines = this.$foldData; + var folds = foldLine.folds; + if (folds.length == 1) { + foldLines.splice(foldLines.indexOf(foldLine), 1); + } else + if (foldLine.range.isEnd(fold.end.row, fold.end.column)) { + folds.pop(); + foldLine.end.row = folds[folds.length - 1].end.row; + foldLine.end.column = folds[folds.length - 1].end.column; + } else + if (foldLine.range.isStart(fold.start.row, fold.start.column)) { + folds.shift(); + foldLine.start.row = folds[0].start.row; + foldLine.start.column = folds[0].start.column; + } else + if (fold.sameRow) { + folds.splice(folds.indexOf(fold), 1); + } else + { + var newFoldLine = foldLine.split(fold.start.row, fold.start.column); + folds = newFoldLine.folds; + folds.shift(); + newFoldLine.start.row = folds[0].start.row; + newFoldLine.start.column = folds[0].start.column; + } + + if (!this.$updating) { + if (this.$useWrapMode) + this.$updateWrapData(startRow, endRow); + else + this.$updateRowLengthCache(startRow, endRow); + } + this.$modified = true; + this._signal("changeFold", { data: fold, action: "remove" }); + }; + + this.removeFolds = function(folds) { + var cloneFolds = []; + for (var i = 0; i < folds.length; i++) { + cloneFolds.push(folds[i]); + } + + cloneFolds.forEach(function(fold) { + this.removeFold(fold); + }, this); + this.$modified = true; + }; + + this.expandFold = function(fold) { + this.removeFold(fold); + fold.subFolds.forEach(function(subFold) { + fold.restoreRange(subFold); + this.addFold(subFold); + }, this); + if (fold.collapseChildren > 0) { + this.foldAll(fold.start.row+1, fold.end.row, fold.collapseChildren-1); + } + fold.subFolds = []; + }; + + this.expandFolds = function(folds) { + folds.forEach(function(fold) { + this.expandFold(fold); + }, this); + }; + + this.unfold = function(location, expandInner) { + var range, folds; + if (location == null) { + range = new Range(0, 0, this.getLength(), 0); + if (expandInner == null) expandInner = true; + } else if (typeof location == "number") + range = new Range(location, 0, location, this.getLine(location).length); + else if ("row" in location) + range = Range.fromPoints(location, location); + else + range = location; + + folds = this.getFoldsInRangeList(range); + if (expandInner != false) { + this.removeFolds(folds); + } else { + this.expandFolds(folds); + } + if (folds.length) + return folds; + }; + this.isRowFolded = function(docRow, startFoldRow) { + return !!this.getFoldLine(docRow, startFoldRow); + }; + + this.getRowFoldEnd = function(docRow, startFoldRow) { + var foldLine = this.getFoldLine(docRow, startFoldRow); + return foldLine ? foldLine.end.row : docRow; + }; + + this.getRowFoldStart = function(docRow, startFoldRow) { + var foldLine = this.getFoldLine(docRow, startFoldRow); + return foldLine ? foldLine.start.row : docRow; + }; + + this.getFoldDisplayLine = function(foldLine, endRow, endColumn, startRow, startColumn) { + if (startRow == null) + startRow = foldLine.start.row; + if (startColumn == null) + startColumn = 0; + if (endRow == null) + endRow = foldLine.end.row; + if (endColumn == null) + endColumn = this.getLine(endRow).length; + var doc = this.doc; + var textLine = ""; + + foldLine.walk(function(placeholder, row, column, lastColumn) { + if (row < startRow) + return; + if (row == startRow) { + if (column < startColumn) + return; + lastColumn = Math.max(startColumn, lastColumn); + } + + if (placeholder != null) { + textLine += placeholder; + } else { + textLine += doc.getLine(row).substring(lastColumn, column); + } + }, endRow, endColumn); + return textLine; + }; + + this.getDisplayLine = function(row, endColumn, startRow, startColumn) { + var foldLine = this.getFoldLine(row); + + if (!foldLine) { + var line; + line = this.doc.getLine(row); + return line.substring(startColumn || 0, endColumn || line.length); + } else { + return this.getFoldDisplayLine( + foldLine, row, endColumn, startRow, startColumn); + } + }; + + this.$cloneFoldData = function() { + var fd = []; + fd = this.$foldData.map(function(foldLine) { + var folds = foldLine.folds.map(function(fold) { + return fold.clone(); + }); + return new FoldLine(fd, folds); + }); + + return fd; + }; + + this.toggleFold = function(tryToUnfold) { + var selection = this.selection; + var range = selection.getRange(); + var fold; + var bracketPos; + + if (range.isEmpty()) { + var cursor = range.start; + fold = this.getFoldAt(cursor.row, cursor.column); + + if (fold) { + this.expandFold(fold); + return; + } else if (bracketPos = this.findMatchingBracket(cursor)) { + if (range.comparePoint(bracketPos) == 1) { + range.end = bracketPos; + } else { + range.start = bracketPos; + range.start.column++; + range.end.column--; + } + } else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) { + if (range.comparePoint(bracketPos) == 1) + range.end = bracketPos; + else + range.start = bracketPos; + + range.start.column++; + } else { + range = this.getCommentFoldRange(cursor.row, cursor.column) || range; + } + } else { + var folds = this.getFoldsInRange(range); + if (tryToUnfold && folds.length) { + this.expandFolds(folds); + return; + } else if (folds.length == 1 ) { + fold = folds[0]; + } + } + + if (!fold) + fold = this.getFoldAt(range.start.row, range.start.column); + + if (fold && fold.range.toString() == range.toString()) { + this.expandFold(fold); + return; + } + + var placeholder = "..."; + if (!range.isMultiLine()) { + placeholder = this.getTextRange(range); + if (placeholder.length < 4) + return; + placeholder = placeholder.trim().substring(0, 2) + ".."; + } + + this.addFold(placeholder, range); + }; + + this.getCommentFoldRange = function(row, column, dir) { + var iterator = new TokenIterator(this, row, column); + var token = iterator.getCurrentToken(); + var type = token && token.type; + if (token && /^comment|string/.test(type)) { + type = type.match(/comment|string/)[0]; + if (type == "comment") + type += "|doc-start"; + var re = new RegExp(type); + var range = new Range(); + if (dir != 1) { + do { + token = iterator.stepBackward(); + } while (token && re.test(token.type)); + iterator.stepForward(); + } + + range.start.row = iterator.getCurrentTokenRow(); + range.start.column = iterator.getCurrentTokenColumn() + 2; + + iterator = new TokenIterator(this, row, column); + + if (dir != -1) { + var lastRow = -1; + do { + token = iterator.stepForward(); + if (lastRow == -1) { + var state = this.getState(iterator.$row); + if (!re.test(state)) + lastRow = iterator.$row; + } else if (iterator.$row > lastRow) { + break; + } + } while (token && re.test(token.type)); + token = iterator.stepBackward(); + } else + token = iterator.getCurrentToken(); + + range.end.row = iterator.getCurrentTokenRow(); + range.end.column = iterator.getCurrentTokenColumn() + token.value.length - 2; + return range; + } + }; + + this.foldAll = function(startRow, endRow, depth, test) { + if (depth == undefined) + depth = 100000; // JSON.stringify doesn't hanle Infinity + var foldWidgets = this.foldWidgets; + if (!foldWidgets) + return; // mode doesn't support folding + endRow = endRow || this.getLength(); + startRow = startRow || 0; + for (var row = startRow; row < endRow; row++) { + if (foldWidgets[row] == null) + foldWidgets[row] = this.getFoldWidget(row); + if (foldWidgets[row] != "start") + continue; + + if (test && !test(row)) continue; + + var range = this.getFoldWidgetRange(row); + if (range && range.isMultiLine() + && range.end.row <= endRow + && range.start.row >= startRow + ) { + row = range.end.row; + range.collapseChildren = depth; + this.addFold("...", range); + } + } + }; + + this.foldToLevel = function(level) { + this.foldAll(); + while (level-- > 0) + this.unfold(null, false); + }; + + this.foldAllComments = function() { + var session = this; + this.foldAll(null, null, null, function(row) { + var tokens = session.getTokens(row); + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + if (token.type == "text" && /^\s+$/.test(token.value)) + continue; + if (/comment/.test(token.type)) + return true; + return false; + } + }); + }; + this.$foldStyles = { + "manual": 1, + "markbegin": 1, + "markbeginend": 1 + }; + this.$foldStyle = "markbegin"; + this.setFoldStyle = function(style) { + if (!this.$foldStyles[style]) + throw new Error("invalid fold style: " + style + "[" + Object.keys(this.$foldStyles).join(", ") + "]"); + + if (this.$foldStyle == style) + return; + + this.$foldStyle = style; + + if (style == "manual") + this.unfold(); + var mode = this.$foldMode; + this.$setFolding(null); + this.$setFolding(mode); + }; + + this.$setFolding = function(foldMode) { + if (this.$foldMode == foldMode) + return; + + this.$foldMode = foldMode; + + this.off('change', this.$updateFoldWidgets); + this.off('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets); + this._signal("changeAnnotation"); + + if (!foldMode || this.$foldStyle == "manual") { + this.foldWidgets = null; + return; + } + + this.foldWidgets = []; + this.getFoldWidget = foldMode.getFoldWidget.bind(foldMode, this, this.$foldStyle); + this.getFoldWidgetRange = foldMode.getFoldWidgetRange.bind(foldMode, this, this.$foldStyle); + + this.$updateFoldWidgets = this.updateFoldWidgets.bind(this); + this.$tokenizerUpdateFoldWidgets = this.tokenizerUpdateFoldWidgets.bind(this); + this.on('change', this.$updateFoldWidgets); + this.on('tokenizerUpdate', this.$tokenizerUpdateFoldWidgets); + }; + + this.getParentFoldRangeData = function (row, ignoreCurrent) { + var fw = this.foldWidgets; + if (!fw || (ignoreCurrent && fw[row])) + return {}; + + var i = row - 1, firstRange; + while (i >= 0) { + var c = fw[i]; + if (c == null) + c = fw[i] = this.getFoldWidget(i); + + if (c == "start") { + var range = this.getFoldWidgetRange(i); + if (!firstRange) + firstRange = range; + if (range && range.end.row >= row) + break; + } + i--; + } + + return { + range: i !== -1 && range, + firstRange: firstRange + }; + }; + + this.onFoldWidgetClick = function(row, e) { + e = e.domEvent; + var options = { + children: e.shiftKey, + all: e.ctrlKey || e.metaKey, + siblings: e.altKey + }; + + var range = this.$toggleFoldWidget(row, options); + if (!range) { + var el = (e.target || e.srcElement); + if (el && /ace_fold-widget/.test(el.className)) + el.className += " ace_invalid"; + } + }; + + this.$toggleFoldWidget = function(row, options) { + if (!this.getFoldWidget) + return; + var type = this.getFoldWidget(row); + var line = this.getLine(row); + + var dir = type === "end" ? -1 : 1; + var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir); + + if (fold) { + if (options.children || options.all) + this.removeFold(fold); + else + this.expandFold(fold); + return fold; + } + + var range = this.getFoldWidgetRange(row, true); + if (range && !range.isMultiLine()) { + fold = this.getFoldAt(range.start.row, range.start.column, 1); + if (fold && range.isEqual(fold.range)) { + this.removeFold(fold); + return fold; + } + } + + if (options.siblings) { + var data = this.getParentFoldRangeData(row); + if (data.range) { + var startRow = data.range.start.row + 1; + var endRow = data.range.end.row; + } + this.foldAll(startRow, endRow, options.all ? 10000 : 0); + } else if (options.children) { + endRow = range ? range.end.row : this.getLength(); + this.foldAll(row + 1, endRow, options.all ? 10000 : 0); + } else if (range) { + if (options.all) + range.collapseChildren = 10000; + this.addFold("...", range); + } + + return range; + }; + + + + this.toggleFoldWidget = function(toggleParent) { + var row = this.selection.getCursor().row; + row = this.getRowFoldStart(row); + var range = this.$toggleFoldWidget(row, {}); + + if (range) + return; + var data = this.getParentFoldRangeData(row, true); + range = data.range || data.firstRange; + + if (range) { + row = range.start.row; + var fold = this.getFoldAt(row, this.getLine(row).length, 1); + + if (fold) { + this.removeFold(fold); + } else { + this.addFold("...", range); + } + } + }; + + this.updateFoldWidgets = function(delta) { + var firstRow = delta.start.row; + var len = delta.end.row - firstRow; + + if (len === 0) { + this.foldWidgets[firstRow] = null; + } else if (delta.action == 'remove') { + this.foldWidgets.splice(firstRow, len + 1, null); + } else { + var args = Array(len + 1); + args.unshift(firstRow, 1); + this.foldWidgets.splice.apply(this.foldWidgets, args); + } + }; + this.tokenizerUpdateFoldWidgets = function(e) { + var rows = e.data; + if (rows.first != rows.last) { + if (this.foldWidgets.length > rows.first) + this.foldWidgets.splice(rows.first, this.foldWidgets.length); + } + }; +} + +exports.Folding = Folding; + +}); + +ace.define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator","ace/range"], function(require, exports, module) { +"use strict"; + +var TokenIterator = require("../token_iterator").TokenIterator; +var Range = require("../range").Range; + + +function BracketMatch() { + + this.findMatchingBracket = function(position, chr) { + if (position.column == 0) return null; + + var charBeforeCursor = chr || this.getLine(position.row).charAt(position.column-1); + if (charBeforeCursor == "") return null; + + var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/); + if (!match) + return null; + + if (match[1]) + return this.$findClosingBracket(match[1], position); + else + return this.$findOpeningBracket(match[2], position); + }; + + this.getBracketRange = function(pos) { + var line = this.getLine(pos.row); + var before = true, range; + + var chr = line.charAt(pos.column - 1); + var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/); + if (!match) { + chr = line.charAt(pos.column); + pos = {row: pos.row, column: pos.column + 1}; + match = chr && chr.match(/([\(\[\{])|([\)\]\}])/); + before = false; + } + if (!match) + return null; + + if (match[1]) { + var bracketPos = this.$findClosingBracket(match[1], pos); + if (!bracketPos) + return null; + range = Range.fromPoints(pos, bracketPos); + if (!before) { + range.end.column++; + range.start.column--; + } + range.cursor = range.end; + } else { + var bracketPos = this.$findOpeningBracket(match[2], pos); + if (!bracketPos) + return null; + range = Range.fromPoints(bracketPos, pos); + if (!before) { + range.start.column++; + range.end.column--; + } + range.cursor = range.start; + } + + return range; + }; + this.getMatchingBracketRanges = function(pos) { + var line = this.getLine(pos.row); + + var chr = line.charAt(pos.column - 1); + var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/); + if (!match) { + chr = line.charAt(pos.column); + pos = {row: pos.row, column: pos.column + 1}; + match = chr && chr.match(/([\(\[\{])|([\)\]\}])/); + } + + if (!match) + return null; + + var startRange = new Range(pos.row, pos.column - 1, pos.row, pos.column); + var bracketPos = match[1] ? this.$findClosingBracket(match[1], pos) + : this.$findOpeningBracket(match[2], pos); + if (!bracketPos) + return [startRange]; + var endRange = new Range(bracketPos.row, bracketPos.column, bracketPos.row, bracketPos.column + 1); + + return [startRange, endRange]; + }; + + this.$brackets = { + ")": "(", + "(": ")", + "]": "[", + "[": "]", + "{": "}", + "}": "{", + "<": ">", + ">": "<" + }; + + this.$findOpeningBracket = function(bracket, position, typeRe) { + var openBracket = this.$brackets[bracket]; + var depth = 1; + + var iterator = new TokenIterator(this, position.row, position.column); + var token = iterator.getCurrentToken(); + if (!token) + token = iterator.stepForward(); + if (!token) + return; + + if (!typeRe){ + typeRe = new RegExp( + "(\\.?" + + token.type.replace(".", "\\.").replace("rparen", ".paren") + .replace(/\b(?:end)\b/, "(?:start|begin|end)") + + ")+" + ); + } + var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2; + var value = token.value; + + while (true) { + + while (valueIndex >= 0) { + var chr = value.charAt(valueIndex); + if (chr == openBracket) { + depth -= 1; + if (depth == 0) { + return {row: iterator.getCurrentTokenRow(), + column: valueIndex + iterator.getCurrentTokenColumn()}; + } + } + else if (chr == bracket) { + depth += 1; + } + valueIndex -= 1; + } + do { + token = iterator.stepBackward(); + } while (token && !typeRe.test(token.type)); + + if (token == null) + break; + + value = token.value; + valueIndex = value.length - 1; + } + + return null; + }; + + this.$findClosingBracket = function(bracket, position, typeRe) { + var closingBracket = this.$brackets[bracket]; + var depth = 1; + + var iterator = new TokenIterator(this, position.row, position.column); + var token = iterator.getCurrentToken(); + if (!token) + token = iterator.stepForward(); + if (!token) + return; + + if (!typeRe){ + typeRe = new RegExp( + "(\\.?" + + token.type.replace(".", "\\.").replace("lparen", ".paren") + .replace(/\b(?:start|begin)\b/, "(?:start|begin|end)") + + ")+" + ); + } + var valueIndex = position.column - iterator.getCurrentTokenColumn(); + + while (true) { + + var value = token.value; + var valueLength = value.length; + while (valueIndex < valueLength) { + var chr = value.charAt(valueIndex); + if (chr == closingBracket) { + depth -= 1; + if (depth == 0) { + return {row: iterator.getCurrentTokenRow(), + column: valueIndex + iterator.getCurrentTokenColumn()}; + } + } + else if (chr == bracket) { + depth += 1; + } + valueIndex += 1; + } + do { + token = iterator.stepForward(); + } while (token && !typeRe.test(token.type)); + + if (token == null) + break; + + valueIndex = 0; + } + + return null; + }; +} +exports.BracketMatch = BracketMatch; + +}); + +ace.define("ace/edit_session",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/bidihandler","ace/config","ace/lib/event_emitter","ace/selection","ace/mode/text","ace/range","ace/document","ace/background_tokenizer","ace/search_highlight","ace/edit_session/folding","ace/edit_session/bracket_match"], function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var lang = require("./lib/lang"); +var BidiHandler = require("./bidihandler").BidiHandler; +var config = require("./config"); +var EventEmitter = require("./lib/event_emitter").EventEmitter; +var Selection = require("./selection").Selection; +var TextMode = require("./mode/text").Mode; +var Range = require("./range").Range; +var Document = require("./document").Document; +var BackgroundTokenizer = require("./background_tokenizer").BackgroundTokenizer; +var SearchHighlight = require("./search_highlight").SearchHighlight; + +var EditSession = function(text, mode) { + this.$breakpoints = []; + this.$decorations = []; + this.$frontMarkers = {}; + this.$backMarkers = {}; + this.$markerId = 1; + this.$undoSelect = true; + + this.$foldData = []; + this.id = "session" + (++EditSession.$uid); + this.$foldData.toString = function() { + return this.join("\n"); + }; + this.on("changeFold", this.onChangeFold.bind(this)); + this.$onChange = this.onChange.bind(this); + + if (typeof text != "object" || !text.getLine) + text = new Document(text); + + this.setDocument(text); + this.selection = new Selection(this); + this.$bidiHandler = new BidiHandler(this); + + config.resetOptions(this); + this.setMode(mode); + config._signal("session", this); +}; + + +EditSession.$uid = 0; + +(function() { + + oop.implement(this, EventEmitter); + this.setDocument = function(doc) { + if (this.doc) + this.doc.removeListener("change", this.$onChange); + + this.doc = doc; + doc.on("change", this.$onChange); + + if (this.bgTokenizer) + this.bgTokenizer.setDocument(this.getDocument()); + + this.resetCaches(); + }; + this.getDocument = function() { + return this.doc; + }; + this.$resetRowCache = function(docRow) { + if (!docRow) { + this.$docRowCache = []; + this.$screenRowCache = []; + return; + } + var l = this.$docRowCache.length; + var i = this.$getRowCacheIndex(this.$docRowCache, docRow) + 1; + if (l > i) { + this.$docRowCache.splice(i, l); + this.$screenRowCache.splice(i, l); + } + }; + + this.$getRowCacheIndex = function(cacheArray, val) { + var low = 0; + var hi = cacheArray.length - 1; + + while (low <= hi) { + var mid = (low + hi) >> 1; + var c = cacheArray[mid]; + + if (val > c) + low = mid + 1; + else if (val < c) + hi = mid - 1; + else + return mid; + } + + return low -1; + }; + + this.resetCaches = function() { + this.$modified = true; + this.$wrapData = []; + this.$rowLengthCache = []; + this.$resetRowCache(0); + if (this.bgTokenizer) + this.bgTokenizer.start(0); + }; + + this.onChangeFold = function(e) { + var fold = e.data; + this.$resetRowCache(fold.start.row); + }; + + this.onChange = function(delta) { + this.$modified = true; + this.$bidiHandler.onChange(delta); + this.$resetRowCache(delta.start.row); + + var removedFolds = this.$updateInternalDataOnChange(delta); + if (!this.$fromUndo && this.$undoManager) { + if (removedFolds && removedFolds.length) { + this.$undoManager.add({ + action: "removeFolds", + folds: removedFolds + }, this.mergeUndoDeltas); + this.mergeUndoDeltas = true; + } + this.$undoManager.add(delta, this.mergeUndoDeltas); + this.mergeUndoDeltas = true; + + this.$informUndoManager.schedule(); + } + + this.bgTokenizer && this.bgTokenizer.$updateOnChange(delta); + this._signal("change", delta); + }; + this.setValue = function(text) { + this.doc.setValue(text); + this.selection.moveTo(0, 0); + + this.$resetRowCache(0); + this.setUndoManager(this.$undoManager); + this.getUndoManager().reset(); + }; + this.getValue = + this.toString = function() { + return this.doc.getValue(); + }; + this.getSelection = function() { + return this.selection; + }; + this.getState = function(row) { + return this.bgTokenizer.getState(row); + }; + this.getTokens = function(row) { + return this.bgTokenizer.getTokens(row); + }; + this.getTokenAt = function(row, column) { + var tokens = this.bgTokenizer.getTokens(row); + var token, c = 0; + if (column == null) { + var i = tokens.length - 1; + c = this.getLine(row).length; + } else { + for (var i = 0; i < tokens.length; i++) { + c += tokens[i].value.length; + if (c >= column) + break; + } + } + token = tokens[i]; + if (!token) + return null; + token.index = i; + token.start = c - token.value.length; + return token; + }; + this.setUndoManager = function(undoManager) { + this.$undoManager = undoManager; + + if (this.$informUndoManager) + this.$informUndoManager.cancel(); + + if (undoManager) { + var self = this; + undoManager.addSession(this); + this.$syncInformUndoManager = function() { + self.$informUndoManager.cancel(); + self.mergeUndoDeltas = false; + }; + this.$informUndoManager = lang.delayedCall(this.$syncInformUndoManager); + } else { + this.$syncInformUndoManager = function() {}; + } + }; + this.markUndoGroup = function() { + if (this.$syncInformUndoManager) + this.$syncInformUndoManager(); + }; + + this.$defaultUndoManager = { + undo: function() {}, + redo: function() {}, + hasUndo: function() {}, + hasRedo: function() {}, + reset: function() {}, + add: function() {}, + addSelection: function() {}, + startNewGroup: function() {}, + addSession: function() {} + }; + this.getUndoManager = function() { + return this.$undoManager || this.$defaultUndoManager; + }; + this.getTabString = function() { + if (this.getUseSoftTabs()) { + return lang.stringRepeat(" ", this.getTabSize()); + } else { + return "\t"; + } + }; + this.setUseSoftTabs = function(val) { + this.setOption("useSoftTabs", val); + }; + this.getUseSoftTabs = function() { + return this.$useSoftTabs && !this.$mode.$indentWithTabs; + }; + this.setTabSize = function(tabSize) { + this.setOption("tabSize", tabSize); + }; + this.getTabSize = function() { + return this.$tabSize; + }; + this.isTabStop = function(position) { + return this.$useSoftTabs && (position.column % this.$tabSize === 0); + }; + this.setNavigateWithinSoftTabs = function (navigateWithinSoftTabs) { + this.setOption("navigateWithinSoftTabs", navigateWithinSoftTabs); + }; + this.getNavigateWithinSoftTabs = function() { + return this.$navigateWithinSoftTabs; + }; + + this.$overwrite = false; + this.setOverwrite = function(overwrite) { + this.setOption("overwrite", overwrite); + }; + this.getOverwrite = function() { + return this.$overwrite; + }; + this.toggleOverwrite = function() { + this.setOverwrite(!this.$overwrite); + }; + this.addGutterDecoration = function(row, className) { + if (!this.$decorations[row]) + this.$decorations[row] = ""; + this.$decorations[row] += " " + className; + this._signal("changeBreakpoint", {}); + }; + this.removeGutterDecoration = function(row, className) { + this.$decorations[row] = (this.$decorations[row] || "").replace(" " + className, ""); + this._signal("changeBreakpoint", {}); + }; + this.getBreakpoints = function() { + return this.$breakpoints; + }; + this.setBreakpoints = function(rows) { + this.$breakpoints = []; + for (var i=0; i 0) + inToken = !!line.charAt(column - 1).match(this.tokenRe); + + if (!inToken) + inToken = !!line.charAt(column).match(this.tokenRe); + + if (inToken) + var re = this.tokenRe; + else if (/^\s+$/.test(line.slice(column-1, column+1))) + var re = /\s/; + else + var re = this.nonTokenRe; + + var start = column; + if (start > 0) { + do { + start--; + } + while (start >= 0 && line.charAt(start).match(re)); + start++; + } + + var end = column; + while (end < line.length && line.charAt(end).match(re)) { + end++; + } + + return new Range(row, start, row, end); + }; + this.getAWordRange = function(row, column) { + var wordRange = this.getWordRange(row, column); + var line = this.getLine(wordRange.end.row); + + while (line.charAt(wordRange.end.column).match(/[ \t]/)) { + wordRange.end.column += 1; + } + return wordRange; + }; + this.setNewLineMode = function(newLineMode) { + this.doc.setNewLineMode(newLineMode); + }; + this.getNewLineMode = function() { + return this.doc.getNewLineMode(); + }; + this.setUseWorker = function(useWorker) { this.setOption("useWorker", useWorker); }; + this.getUseWorker = function() { return this.$useWorker; }; + this.onReloadTokenizer = function(e) { + var rows = e.data; + this.bgTokenizer.start(rows.first); + this._signal("tokenizerUpdate", e); + }; + + this.$modes = config.$modes; + this.$mode = null; + this.$modeId = null; + this.setMode = function(mode, cb) { + if (mode && typeof mode === "object") { + if (mode.getTokenizer) + return this.$onChangeMode(mode); + var options = mode; + var path = options.path; + } else { + path = mode || "ace/mode/text"; + } + if (!this.$modes["ace/mode/text"]) + this.$modes["ace/mode/text"] = new TextMode(); + + if (this.$modes[path] && !options) { + this.$onChangeMode(this.$modes[path]); + cb && cb(); + return; + } + this.$modeId = path; + config.loadModule(["mode", path], function(m) { + if (this.$modeId !== path) + return cb && cb(); + if (this.$modes[path] && !options) { + this.$onChangeMode(this.$modes[path]); + } else if (m && m.Mode) { + m = new m.Mode(options); + if (!options) { + this.$modes[path] = m; + m.$id = path; + } + this.$onChangeMode(m); + } + cb && cb(); + }.bind(this)); + if (!this.$mode) + this.$onChangeMode(this.$modes["ace/mode/text"], true); + }; + + this.$onChangeMode = function(mode, $isPlaceholder) { + if (!$isPlaceholder) + this.$modeId = mode.$id; + if (this.$mode === mode) + return; + + var oldMode = this.$mode; + this.$mode = mode; + + this.$stopWorker(); + + if (this.$useWorker) + this.$startWorker(); + + var tokenizer = mode.getTokenizer(); + + if(tokenizer.on !== undefined) { + var onReloadTokenizer = this.onReloadTokenizer.bind(this); + tokenizer.on("update", onReloadTokenizer); + } + + if (!this.bgTokenizer) { + this.bgTokenizer = new BackgroundTokenizer(tokenizer); + var _self = this; + this.bgTokenizer.on("update", function(e) { + _self._signal("tokenizerUpdate", e); + }); + } else { + this.bgTokenizer.setTokenizer(tokenizer); + } + + this.bgTokenizer.setDocument(this.getDocument()); + + this.tokenRe = mode.tokenRe; + this.nonTokenRe = mode.nonTokenRe; + + + if (!$isPlaceholder) { + if (mode.attachToSession) + mode.attachToSession(this); + this.$options.wrapMethod.set.call(this, this.$wrapMethod); + this.$setFolding(mode.foldingRules); + this.bgTokenizer.start(0); + this._emit("changeMode", {oldMode: oldMode, mode: mode}); + } + }; + + this.$stopWorker = function() { + if (this.$worker) { + this.$worker.terminate(); + this.$worker = null; + } + }; + + this.$startWorker = function() { + try { + this.$worker = this.$mode.createWorker(this); + } catch (e) { + config.warn("Could not load worker", e); + this.$worker = null; + } + }; + this.getMode = function() { + return this.$mode; + }; + + this.$scrollTop = 0; + this.setScrollTop = function(scrollTop) { + if (this.$scrollTop === scrollTop || isNaN(scrollTop)) + return; + + this.$scrollTop = scrollTop; + this._signal("changeScrollTop", scrollTop); + }; + this.getScrollTop = function() { + return this.$scrollTop; + }; + + this.$scrollLeft = 0; + this.setScrollLeft = function(scrollLeft) { + if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft)) + return; + + this.$scrollLeft = scrollLeft; + this._signal("changeScrollLeft", scrollLeft); + }; + this.getScrollLeft = function() { + return this.$scrollLeft; + }; + this.getScreenWidth = function() { + this.$computeWidth(); + if (this.lineWidgets) + return Math.max(this.getLineWidgetMaxWidth(), this.screenWidth); + return this.screenWidth; + }; + + this.getLineWidgetMaxWidth = function() { + if (this.lineWidgetsWidth != null) return this.lineWidgetsWidth; + var width = 0; + this.lineWidgets.forEach(function(w) { + if (w && w.screenWidth > width) + width = w.screenWidth; + }); + return this.lineWidgetWidth = width; + }; + + this.$computeWidth = function(force) { + if (this.$modified || force) { + this.$modified = false; + + if (this.$useWrapMode) + return this.screenWidth = this.$wrapLimit; + + var lines = this.doc.getAllLines(); + var cache = this.$rowLengthCache; + var longestScreenLine = 0; + var foldIndex = 0; + var foldLine = this.$foldData[foldIndex]; + var foldStart = foldLine ? foldLine.start.row : Infinity; + var len = lines.length; + + for (var i = 0; i < len; i++) { + if (i > foldStart) { + i = foldLine.end.row + 1; + if (i >= len) + break; + foldLine = this.$foldData[foldIndex++]; + foldStart = foldLine ? foldLine.start.row : Infinity; + } + + if (cache[i] == null) + cache[i] = this.$getStringScreenWidth(lines[i])[0]; + + if (cache[i] > longestScreenLine) + longestScreenLine = cache[i]; + } + this.screenWidth = longestScreenLine; + } + }; + this.getLine = function(row) { + return this.doc.getLine(row); + }; + this.getLines = function(firstRow, lastRow) { + return this.doc.getLines(firstRow, lastRow); + }; + this.getLength = function() { + return this.doc.getLength(); + }; + this.getTextRange = function(range) { + return this.doc.getTextRange(range || this.selection.getRange()); + }; + this.insert = function(position, text) { + return this.doc.insert(position, text); + }; + this.remove = function(range) { + return this.doc.remove(range); + }; + this.removeFullLines = function(firstRow, lastRow){ + return this.doc.removeFullLines(firstRow, lastRow); + }; + this.undoChanges = function(deltas, dontSelect) { + if (!deltas.length) + return; + + this.$fromUndo = true; + for (var i = deltas.length - 1; i != -1; i--) { + var delta = deltas[i]; + if (delta.action == "insert" || delta.action == "remove") { + this.doc.revertDelta(delta); + } else if (delta.folds) { + this.addFolds(delta.folds); + } + } + if (!dontSelect && this.$undoSelect) { + if (deltas.selectionBefore) + this.selection.fromJSON(deltas.selectionBefore); + else + this.selection.setRange(this.$getUndoSelection(deltas, true)); + } + this.$fromUndo = false; + }; + this.redoChanges = function(deltas, dontSelect) { + if (!deltas.length) + return; + + this.$fromUndo = true; + for (var i = 0; i < deltas.length; i++) { + var delta = deltas[i]; + if (delta.action == "insert" || delta.action == "remove") { + this.doc.$safeApplyDelta(delta); + } + } + + if (!dontSelect && this.$undoSelect) { + if (deltas.selectionAfter) + this.selection.fromJSON(deltas.selectionAfter); + else + this.selection.setRange(this.$getUndoSelection(deltas, false)); + } + this.$fromUndo = false; + }; + this.setUndoSelect = function(enable) { + this.$undoSelect = enable; + }; + + this.$getUndoSelection = function(deltas, isUndo) { + function isInsert(delta) { + return isUndo ? delta.action !== "insert" : delta.action === "insert"; + } + + var range, point; + + for (var i = 0; i < deltas.length; i++) { + var delta = deltas[i]; + if (!delta.start) continue; // skip folds + if (!range) { + if (isInsert(delta)) { + range = Range.fromPoints(delta.start, delta.end); + } else { + range = Range.fromPoints(delta.start, delta.start); + } + continue; + } + + if (isInsert(delta)) { + point = delta.start; + if (range.compare(point.row, point.column) == -1) { + range.setStart(point); + } + point = delta.end; + if (range.compare(point.row, point.column) == 1) { + range.setEnd(point); + } + } else { + point = delta.start; + if (range.compare(point.row, point.column) == -1) { + range = Range.fromPoints(delta.start, delta.start); + } + } + } + return range; + }; + this.replace = function(range, text) { + return this.doc.replace(range, text); + }; + this.moveText = function(fromRange, toPosition, copy) { + var text = this.getTextRange(fromRange); + var folds = this.getFoldsInRange(fromRange); + + var toRange = Range.fromPoints(toPosition, toPosition); + if (!copy) { + this.remove(fromRange); + var rowDiff = fromRange.start.row - fromRange.end.row; + var collDiff = rowDiff ? -fromRange.end.column : fromRange.start.column - fromRange.end.column; + if (collDiff) { + if (toRange.start.row == fromRange.end.row && toRange.start.column > fromRange.end.column) + toRange.start.column += collDiff; + if (toRange.end.row == fromRange.end.row && toRange.end.column > fromRange.end.column) + toRange.end.column += collDiff; + } + if (rowDiff && toRange.start.row >= fromRange.end.row) { + toRange.start.row += rowDiff; + toRange.end.row += rowDiff; + } + } + + toRange.end = this.insert(toRange.start, text); + if (folds.length) { + var oldStart = fromRange.start; + var newStart = toRange.start; + var rowDiff = newStart.row - oldStart.row; + var collDiff = newStart.column - oldStart.column; + this.addFolds(folds.map(function(x) { + x = x.clone(); + if (x.start.row == oldStart.row) + x.start.column += collDiff; + if (x.end.row == oldStart.row) + x.end.column += collDiff; + x.start.row += rowDiff; + x.end.row += rowDiff; + return x; + })); + } + + return toRange; + }; + this.indentRows = function(startRow, endRow, indentString) { + indentString = indentString.replace(/\t/g, this.getTabString()); + for (var row=startRow; row<=endRow; row++) + this.doc.insertInLine({row: row, column: 0}, indentString); + }; + this.outdentRows = function (range) { + var rowRange = range.collapseRows(); + var deleteRange = new Range(0, 0, 0, 0); + var size = this.getTabSize(); + + for (var i = rowRange.start.row; i <= rowRange.end.row; ++i) { + var line = this.getLine(i); + + deleteRange.start.row = i; + deleteRange.end.row = i; + for (var j = 0; j < size; ++j) + if (line.charAt(j) != ' ') + break; + if (j < size && line.charAt(j) == '\t') { + deleteRange.start.column = j; + deleteRange.end.column = j + 1; + } else { + deleteRange.start.column = 0; + deleteRange.end.column = j; + } + this.remove(deleteRange); + } + }; + + this.$moveLines = function(firstRow, lastRow, dir) { + firstRow = this.getRowFoldStart(firstRow); + lastRow = this.getRowFoldEnd(lastRow); + if (dir < 0) { + var row = this.getRowFoldStart(firstRow + dir); + if (row < 0) return 0; + var diff = row-firstRow; + } else if (dir > 0) { + var row = this.getRowFoldEnd(lastRow + dir); + if (row > this.doc.getLength()-1) return 0; + var diff = row-lastRow; + } else { + firstRow = this.$clipRowToDocument(firstRow); + lastRow = this.$clipRowToDocument(lastRow); + var diff = lastRow - firstRow + 1; + } + + var range = new Range(firstRow, 0, lastRow, Number.MAX_VALUE); + var folds = this.getFoldsInRange(range).map(function(x){ + x = x.clone(); + x.start.row += diff; + x.end.row += diff; + return x; + }); + + var lines = dir == 0 + ? this.doc.getLines(firstRow, lastRow) + : this.doc.removeFullLines(firstRow, lastRow); + this.doc.insertFullLines(firstRow+diff, lines); + folds.length && this.addFolds(folds); + return diff; + }; + this.moveLinesUp = function(firstRow, lastRow) { + return this.$moveLines(firstRow, lastRow, -1); + }; + this.moveLinesDown = function(firstRow, lastRow) { + return this.$moveLines(firstRow, lastRow, 1); + }; + this.duplicateLines = function(firstRow, lastRow) { + return this.$moveLines(firstRow, lastRow, 0); + }; + + + this.$clipRowToDocument = function(row) { + return Math.max(0, Math.min(row, this.doc.getLength()-1)); + }; + + this.$clipColumnToRow = function(row, column) { + if (column < 0) + return 0; + return Math.min(this.doc.getLine(row).length, column); + }; + + + this.$clipPositionToDocument = function(row, column) { + column = Math.max(0, column); + + if (row < 0) { + row = 0; + column = 0; + } else { + var len = this.doc.getLength(); + if (row >= len) { + row = len - 1; + column = this.doc.getLine(len-1).length; + } else { + column = Math.min(this.doc.getLine(row).length, column); + } + } + + return { + row: row, + column: column + }; + }; + + this.$clipRangeToDocument = function(range) { + if (range.start.row < 0) { + range.start.row = 0; + range.start.column = 0; + } else { + range.start.column = this.$clipColumnToRow( + range.start.row, + range.start.column + ); + } + + var len = this.doc.getLength() - 1; + if (range.end.row > len) { + range.end.row = len; + range.end.column = this.doc.getLine(len).length; + } else { + range.end.column = this.$clipColumnToRow( + range.end.row, + range.end.column + ); + } + return range; + }; + this.$wrapLimit = 80; + this.$useWrapMode = false; + this.$wrapLimitRange = { + min : null, + max : null + }; + this.setUseWrapMode = function(useWrapMode) { + if (useWrapMode != this.$useWrapMode) { + this.$useWrapMode = useWrapMode; + this.$modified = true; + this.$resetRowCache(0); + if (useWrapMode) { + var len = this.getLength(); + this.$wrapData = Array(len); + this.$updateWrapData(0, len - 1); + } + + this._signal("changeWrapMode"); + } + }; + this.getUseWrapMode = function() { + return this.$useWrapMode; + }; + this.setWrapLimitRange = function(min, max) { + if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) { + this.$wrapLimitRange = { min: min, max: max }; + this.$modified = true; + this.$bidiHandler.markAsDirty(); + if (this.$useWrapMode) + this._signal("changeWrapMode"); + } + }; + this.adjustWrapLimit = function(desiredLimit, $printMargin) { + var limits = this.$wrapLimitRange; + if (limits.max < 0) + limits = {min: $printMargin, max: $printMargin}; + var wrapLimit = this.$constrainWrapLimit(desiredLimit, limits.min, limits.max); + if (wrapLimit != this.$wrapLimit && wrapLimit > 1) { + this.$wrapLimit = wrapLimit; + this.$modified = true; + if (this.$useWrapMode) { + this.$updateWrapData(0, this.getLength() - 1); + this.$resetRowCache(0); + this._signal("changeWrapLimit"); + } + return true; + } + return false; + }; + + this.$constrainWrapLimit = function(wrapLimit, min, max) { + if (min) + wrapLimit = Math.max(min, wrapLimit); + + if (max) + wrapLimit = Math.min(max, wrapLimit); + + return wrapLimit; + }; + this.getWrapLimit = function() { + return this.$wrapLimit; + }; + this.setWrapLimit = function (limit) { + this.setWrapLimitRange(limit, limit); + }; + this.getWrapLimitRange = function() { + return { + min : this.$wrapLimitRange.min, + max : this.$wrapLimitRange.max + }; + }; + + this.$updateInternalDataOnChange = function(delta) { + var useWrapMode = this.$useWrapMode; + var action = delta.action; + var start = delta.start; + var end = delta.end; + var firstRow = start.row; + var lastRow = end.row; + var len = lastRow - firstRow; + var removedFolds = null; + + this.$updating = true; + if (len != 0) { + if (action === "remove") { + this[useWrapMode ? "$wrapData" : "$rowLengthCache"].splice(firstRow, len); + + var foldLines = this.$foldData; + removedFolds = this.getFoldsInRange(delta); + this.removeFolds(removedFolds); + + var foldLine = this.getFoldLine(end.row); + var idx = 0; + if (foldLine) { + foldLine.addRemoveChars(end.row, end.column, start.column - end.column); + foldLine.shiftRow(-len); + + var foldLineBefore = this.getFoldLine(firstRow); + if (foldLineBefore && foldLineBefore !== foldLine) { + foldLineBefore.merge(foldLine); + foldLine = foldLineBefore; + } + idx = foldLines.indexOf(foldLine) + 1; + } + + for (idx; idx < foldLines.length; idx++) { + var foldLine = foldLines[idx]; + if (foldLine.start.row >= end.row) { + foldLine.shiftRow(-len); + } + } + + lastRow = firstRow; + } else { + var args = Array(len); + args.unshift(firstRow, 0); + var arr = useWrapMode ? this.$wrapData : this.$rowLengthCache; + arr.splice.apply(arr, args); + var foldLines = this.$foldData; + var foldLine = this.getFoldLine(firstRow); + var idx = 0; + if (foldLine) { + var cmp = foldLine.range.compareInside(start.row, start.column); + if (cmp == 0) { + foldLine = foldLine.split(start.row, start.column); + if (foldLine) { + foldLine.shiftRow(len); + foldLine.addRemoveChars(lastRow, 0, end.column - start.column); + } + } else + if (cmp == -1) { + foldLine.addRemoveChars(firstRow, 0, end.column - start.column); + foldLine.shiftRow(len); + } + idx = foldLines.indexOf(foldLine) + 1; + } + + for (idx; idx < foldLines.length; idx++) { + var foldLine = foldLines[idx]; + if (foldLine.start.row >= firstRow) { + foldLine.shiftRow(len); + } + } + } + } else { + len = Math.abs(delta.start.column - delta.end.column); + if (action === "remove") { + removedFolds = this.getFoldsInRange(delta); + this.removeFolds(removedFolds); + + len = -len; + } + var foldLine = this.getFoldLine(firstRow); + if (foldLine) { + foldLine.addRemoveChars(firstRow, start.column, len); + } + } + + if (useWrapMode && this.$wrapData.length != this.doc.getLength()) { + console.error("doc.getLength() and $wrapData.length have to be the same!"); + } + this.$updating = false; + + if (useWrapMode) + this.$updateWrapData(firstRow, lastRow); + else + this.$updateRowLengthCache(firstRow, lastRow); + + return removedFolds; + }; + + this.$updateRowLengthCache = function(firstRow, lastRow, b) { + this.$rowLengthCache[firstRow] = null; + this.$rowLengthCache[lastRow] = null; + }; + + this.$updateWrapData = function(firstRow, lastRow) { + var lines = this.doc.getAllLines(); + var tabSize = this.getTabSize(); + var wrapData = this.$wrapData; + var wrapLimit = this.$wrapLimit; + var tokens; + var foldLine; + + var row = firstRow; + lastRow = Math.min(lastRow, lines.length - 1); + while (row <= lastRow) { + foldLine = this.getFoldLine(row, foldLine); + if (!foldLine) { + tokens = this.$getDisplayTokens(lines[row]); + wrapData[row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize); + row ++; + } else { + tokens = []; + foldLine.walk(function(placeholder, row, column, lastColumn) { + var walkTokens; + if (placeholder != null) { + walkTokens = this.$getDisplayTokens( + placeholder, tokens.length); + walkTokens[0] = PLACEHOLDER_START; + for (var i = 1; i < walkTokens.length; i++) { + walkTokens[i] = PLACEHOLDER_BODY; + } + } else { + walkTokens = this.$getDisplayTokens( + lines[row].substring(lastColumn, column), + tokens.length); + } + tokens = tokens.concat(walkTokens); + }.bind(this), + foldLine.end.row, + lines[foldLine.end.row].length + 1 + ); + + wrapData[foldLine.start.row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize); + row = foldLine.end.row + 1; + } + } + }; + var CHAR = 1, + CHAR_EXT = 2, + PLACEHOLDER_START = 3, + PLACEHOLDER_BODY = 4, + PUNCTUATION = 9, + SPACE = 10, + TAB = 11, + TAB_SPACE = 12; + + + this.$computeWrapSplits = function(tokens, wrapLimit, tabSize) { + if (tokens.length == 0) { + return []; + } + + var splits = []; + var displayLength = tokens.length; + var lastSplit = 0, lastDocSplit = 0; + + var isCode = this.$wrapAsCode; + + var indentedSoftWrap = this.$indentedSoftWrap; + var maxIndent = wrapLimit <= Math.max(2 * tabSize, 8) + || indentedSoftWrap === false ? 0 : Math.floor(wrapLimit / 2); + + function getWrapIndent() { + var indentation = 0; + if (maxIndent === 0) + return indentation; + if (indentedSoftWrap) { + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + if (token == SPACE) + indentation += 1; + else if (token == TAB) + indentation += tabSize; + else if (token == TAB_SPACE) + continue; + else + break; + } + } + if (isCode && indentedSoftWrap !== false) + indentation += tabSize; + return Math.min(indentation, maxIndent); + } + function addSplit(screenPos) { + var len = screenPos - lastSplit; + for (var i = lastSplit; i < screenPos; i++) { + var ch = tokens[i]; + if (ch === 12 || ch === 2) len -= 1; + } + + if (!splits.length) { + indent = getWrapIndent(); + splits.indent = indent; + } + lastDocSplit += len; + splits.push(lastDocSplit); + lastSplit = screenPos; + } + var indent = 0; + while (displayLength - lastSplit > wrapLimit - indent) { + var split = lastSplit + wrapLimit - indent; + if (tokens[split - 1] >= SPACE && tokens[split] >= SPACE) { + addSplit(split); + continue; + } + if (tokens[split] == PLACEHOLDER_START || tokens[split] == PLACEHOLDER_BODY) { + for (split; split != lastSplit - 1; split--) { + if (tokens[split] == PLACEHOLDER_START) { + break; + } + } + if (split > lastSplit) { + addSplit(split); + continue; + } + split = lastSplit + wrapLimit; + for (split; split < tokens.length; split++) { + if (tokens[split] != PLACEHOLDER_BODY) { + break; + } + } + if (split == tokens.length) { + break; // Breaks the while-loop. + } + addSplit(split); + continue; + } + var minSplit = Math.max(split - (wrapLimit -(wrapLimit>>2)), lastSplit - 1); + while (split > minSplit && tokens[split] < PLACEHOLDER_START) { + split --; + } + if (isCode) { + while (split > minSplit && tokens[split] < PLACEHOLDER_START) { + split --; + } + while (split > minSplit && tokens[split] == PUNCTUATION) { + split --; + } + } else { + while (split > minSplit && tokens[split] < SPACE) { + split --; + } + } + if (split > minSplit) { + addSplit(++split); + continue; + } + split = lastSplit + wrapLimit; + if (tokens[split] == CHAR_EXT) + split--; + addSplit(split - indent); + } + return splits; + }; + this.$getDisplayTokens = function(str, offset) { + var arr = []; + var tabSize; + offset = offset || 0; + + for (var i = 0; i < str.length; i++) { + var c = str.charCodeAt(i); + if (c == 9) { + tabSize = this.getScreenTabSize(arr.length + offset); + arr.push(TAB); + for (var n = 1; n < tabSize; n++) { + arr.push(TAB_SPACE); + } + } + else if (c == 32) { + arr.push(SPACE); + } else if((c > 39 && c < 48) || (c > 57 && c < 64)) { + arr.push(PUNCTUATION); + } + else if (c >= 0x1100 && isFullWidth(c)) { + arr.push(CHAR, CHAR_EXT); + } else { + arr.push(CHAR); + } + } + return arr; + }; + this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) { + if (maxScreenColumn == 0) + return [0, 0]; + if (maxScreenColumn == null) + maxScreenColumn = Infinity; + screenColumn = screenColumn || 0; + + var c, column; + for (column = 0; column < str.length; column++) { + c = str.charCodeAt(column); + if (c == 9) { + screenColumn += this.getScreenTabSize(screenColumn); + } + else if (c >= 0x1100 && isFullWidth(c)) { + screenColumn += 2; + } else { + screenColumn += 1; + } + if (screenColumn > maxScreenColumn) { + break; + } + } + + return [screenColumn, column]; + }; + + this.lineWidgets = null; + this.getRowLength = function(row) { + var h = 1; + if (this.lineWidgets) + h += this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0; + + if (!this.$useWrapMode || !this.$wrapData[row]) + return h; + else + return this.$wrapData[row].length + h; + }; + this.getRowLineCount = function(row) { + if (!this.$useWrapMode || !this.$wrapData[row]) { + return 1; + } else { + return this.$wrapData[row].length + 1; + } + }; + + this.getRowWrapIndent = function(screenRow) { + if (this.$useWrapMode) { + var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE); + var splits = this.$wrapData[pos.row]; + return splits.length && splits[0] < pos.column ? splits.indent : 0; + } else { + return 0; + } + }; + this.getScreenLastRowColumn = function(screenRow) { + var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE); + return this.documentToScreenColumn(pos.row, pos.column); + }; + this.getDocumentLastRowColumn = function(docRow, docColumn) { + var screenRow = this.documentToScreenRow(docRow, docColumn); + return this.getScreenLastRowColumn(screenRow); + }; + this.getDocumentLastRowColumnPosition = function(docRow, docColumn) { + var screenRow = this.documentToScreenRow(docRow, docColumn); + return this.screenToDocumentPosition(screenRow, Number.MAX_VALUE / 10); + }; + this.getRowSplitData = function(row) { + if (!this.$useWrapMode) { + return undefined; + } else { + return this.$wrapData[row]; + } + }; + this.getScreenTabSize = function(screenColumn) { + return this.$tabSize - (screenColumn % this.$tabSize | 0); + }; + + + this.screenToDocumentRow = function(screenRow, screenColumn) { + return this.screenToDocumentPosition(screenRow, screenColumn).row; + }; + + + this.screenToDocumentColumn = function(screenRow, screenColumn) { + return this.screenToDocumentPosition(screenRow, screenColumn).column; + }; + this.screenToDocumentPosition = function(screenRow, screenColumn, offsetX) { + if (screenRow < 0) + return {row: 0, column: 0}; + + var line; + var docRow = 0; + var docColumn = 0; + var column; + var row = 0; + var rowLength = 0; + + var rowCache = this.$screenRowCache; + var i = this.$getRowCacheIndex(rowCache, screenRow); + var l = rowCache.length; + if (l && i >= 0) { + var row = rowCache[i]; + var docRow = this.$docRowCache[i]; + var doCache = screenRow > rowCache[l - 1]; + } else { + var doCache = !l; + } + + var maxRow = this.getLength() - 1; + var foldLine = this.getNextFoldLine(docRow); + var foldStart = foldLine ? foldLine.start.row : Infinity; + + while (row <= screenRow) { + rowLength = this.getRowLength(docRow); + if (row + rowLength > screenRow || docRow >= maxRow) { + break; + } else { + row += rowLength; + docRow++; + if (docRow > foldStart) { + docRow = foldLine.end.row+1; + foldLine = this.getNextFoldLine(docRow, foldLine); + foldStart = foldLine ? foldLine.start.row : Infinity; + } + } + + if (doCache) { + this.$docRowCache.push(docRow); + this.$screenRowCache.push(row); + } + } + + if (foldLine && foldLine.start.row <= docRow) { + line = this.getFoldDisplayLine(foldLine); + docRow = foldLine.start.row; + } else if (row + rowLength <= screenRow || docRow > maxRow) { + return { + row: maxRow, + column: this.getLine(maxRow).length + }; + } else { + line = this.getLine(docRow); + foldLine = null; + } + var wrapIndent = 0, splitIndex = Math.floor(screenRow - row); + if (this.$useWrapMode) { + var splits = this.$wrapData[docRow]; + if (splits) { + column = splits[splitIndex]; + if(splitIndex > 0 && splits.length) { + wrapIndent = splits.indent; + docColumn = splits[splitIndex - 1] || splits[splits.length - 1]; + line = line.substring(docColumn); + } + } + } + + if (offsetX !== undefined && this.$bidiHandler.isBidiRow(row + splitIndex, docRow, splitIndex)) + screenColumn = this.$bidiHandler.offsetToCol(offsetX); + + docColumn += this.$getStringScreenWidth(line, screenColumn - wrapIndent)[1]; + if (this.$useWrapMode && docColumn >= column) + docColumn = column - 1; + + if (foldLine) + return foldLine.idxToPosition(docColumn); + + return {row: docRow, column: docColumn}; + }; + this.documentToScreenPosition = function(docRow, docColumn) { + if (typeof docColumn === "undefined") + var pos = this.$clipPositionToDocument(docRow.row, docRow.column); + else + pos = this.$clipPositionToDocument(docRow, docColumn); + + docRow = pos.row; + docColumn = pos.column; + + var screenRow = 0; + var foldStartRow = null; + var fold = null; + fold = this.getFoldAt(docRow, docColumn, 1); + if (fold) { + docRow = fold.start.row; + docColumn = fold.start.column; + } + + var rowEnd, row = 0; + + + var rowCache = this.$docRowCache; + var i = this.$getRowCacheIndex(rowCache, docRow); + var l = rowCache.length; + if (l && i >= 0) { + var row = rowCache[i]; + var screenRow = this.$screenRowCache[i]; + var doCache = docRow > rowCache[l - 1]; + } else { + var doCache = !l; + } + + var foldLine = this.getNextFoldLine(row); + var foldStart = foldLine ?foldLine.start.row :Infinity; + + while (row < docRow) { + if (row >= foldStart) { + rowEnd = foldLine.end.row + 1; + if (rowEnd > docRow) + break; + foldLine = this.getNextFoldLine(rowEnd, foldLine); + foldStart = foldLine ?foldLine.start.row :Infinity; + } + else { + rowEnd = row + 1; + } + + screenRow += this.getRowLength(row); + row = rowEnd; + + if (doCache) { + this.$docRowCache.push(row); + this.$screenRowCache.push(screenRow); + } + } + var textLine = ""; + if (foldLine && row >= foldStart) { + textLine = this.getFoldDisplayLine(foldLine, docRow, docColumn); + foldStartRow = foldLine.start.row; + } else { + textLine = this.getLine(docRow).substring(0, docColumn); + foldStartRow = docRow; + } + var wrapIndent = 0; + if (this.$useWrapMode) { + var wrapRow = this.$wrapData[foldStartRow]; + if (wrapRow) { + var screenRowOffset = 0; + while (textLine.length >= wrapRow[screenRowOffset]) { + screenRow ++; + screenRowOffset++; + } + textLine = textLine.substring( + wrapRow[screenRowOffset - 1] || 0, textLine.length + ); + wrapIndent = screenRowOffset > 0 ? wrapRow.indent : 0; + } + } + + if (this.lineWidgets && this.lineWidgets[row] && this.lineWidgets[row].rowsAbove) + screenRow += this.lineWidgets[row].rowsAbove; + + return { + row: screenRow, + column: wrapIndent + this.$getStringScreenWidth(textLine)[0] + }; + }; + this.documentToScreenColumn = function(row, docColumn) { + return this.documentToScreenPosition(row, docColumn).column; + }; + this.documentToScreenRow = function(docRow, docColumn) { + return this.documentToScreenPosition(docRow, docColumn).row; + }; + this.getScreenLength = function() { + var screenRows = 0; + var fold = null; + if (!this.$useWrapMode) { + screenRows = this.getLength(); + var foldData = this.$foldData; + for (var i = 0; i < foldData.length; i++) { + fold = foldData[i]; + screenRows -= fold.end.row - fold.start.row; + } + } else { + var lastRow = this.$wrapData.length; + var row = 0, i = 0; + var fold = this.$foldData[i++]; + var foldStart = fold ? fold.start.row :Infinity; + + while (row < lastRow) { + var splits = this.$wrapData[row]; + screenRows += splits ? splits.length + 1 : 1; + row ++; + if (row > foldStart) { + row = fold.end.row+1; + fold = this.$foldData[i++]; + foldStart = fold ?fold.start.row :Infinity; + } + } + } + if (this.lineWidgets) + screenRows += this.$getWidgetScreenLength(); + + return screenRows; + }; + this.$setFontMetrics = function(fm) { + if (!this.$enableVarChar) return; + this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) { + if (maxScreenColumn === 0) + return [0, 0]; + if (!maxScreenColumn) + maxScreenColumn = Infinity; + screenColumn = screenColumn || 0; + + var c, column; + for (column = 0; column < str.length; column++) { + c = str.charAt(column); + if (c === "\t") { + screenColumn += this.getScreenTabSize(screenColumn); + } else { + screenColumn += fm.getCharacterWidth(c); + } + if (screenColumn > maxScreenColumn) { + break; + } + } + + return [screenColumn, column]; + }; + }; + + this.destroy = function() { + if (this.bgTokenizer) { + this.bgTokenizer.setDocument(null); + this.bgTokenizer = null; + } + this.$stopWorker(); + this.removeAllListeners(); + this.selection.detach(); + }; + + this.isFullWidth = isFullWidth; + function isFullWidth(c) { + if (c < 0x1100) + return false; + return c >= 0x1100 && c <= 0x115F || + c >= 0x11A3 && c <= 0x11A7 || + c >= 0x11FA && c <= 0x11FF || + c >= 0x2329 && c <= 0x232A || + c >= 0x2E80 && c <= 0x2E99 || + c >= 0x2E9B && c <= 0x2EF3 || + c >= 0x2F00 && c <= 0x2FD5 || + c >= 0x2FF0 && c <= 0x2FFB || + c >= 0x3000 && c <= 0x303E || + c >= 0x3041 && c <= 0x3096 || + c >= 0x3099 && c <= 0x30FF || + c >= 0x3105 && c <= 0x312D || + c >= 0x3131 && c <= 0x318E || + c >= 0x3190 && c <= 0x31BA || + c >= 0x31C0 && c <= 0x31E3 || + c >= 0x31F0 && c <= 0x321E || + c >= 0x3220 && c <= 0x3247 || + c >= 0x3250 && c <= 0x32FE || + c >= 0x3300 && c <= 0x4DBF || + c >= 0x4E00 && c <= 0xA48C || + c >= 0xA490 && c <= 0xA4C6 || + c >= 0xA960 && c <= 0xA97C || + c >= 0xAC00 && c <= 0xD7A3 || + c >= 0xD7B0 && c <= 0xD7C6 || + c >= 0xD7CB && c <= 0xD7FB || + c >= 0xF900 && c <= 0xFAFF || + c >= 0xFE10 && c <= 0xFE19 || + c >= 0xFE30 && c <= 0xFE52 || + c >= 0xFE54 && c <= 0xFE66 || + c >= 0xFE68 && c <= 0xFE6B || + c >= 0xFF01 && c <= 0xFF60 || + c >= 0xFFE0 && c <= 0xFFE6; + } + +}).call(EditSession.prototype); + +require("./edit_session/folding").Folding.call(EditSession.prototype); +require("./edit_session/bracket_match").BracketMatch.call(EditSession.prototype); + + +config.defineOptions(EditSession.prototype, "session", { + wrap: { + set: function(value) { + if (!value || value == "off") + value = false; + else if (value == "free") + value = true; + else if (value == "printMargin") + value = -1; + else if (typeof value == "string") + value = parseInt(value, 10) || false; + + if (this.$wrap == value) + return; + this.$wrap = value; + if (!value) { + this.setUseWrapMode(false); + } else { + var col = typeof value == "number" ? value : null; + this.setWrapLimitRange(col, col); + this.setUseWrapMode(true); + } + }, + get: function() { + if (this.getUseWrapMode()) { + if (this.$wrap == -1) + return "printMargin"; + if (!this.getWrapLimitRange().min) + return "free"; + return this.$wrap; + } + return "off"; + }, + handlesSet: true + }, + wrapMethod: { + set: function(val) { + val = val == "auto" + ? this.$mode.type != "text" + : val != "text"; + if (val != this.$wrapAsCode) { + this.$wrapAsCode = val; + if (this.$useWrapMode) { + this.$useWrapMode = false; + this.setUseWrapMode(true); + } + } + }, + initialValue: "auto" + }, + indentedSoftWrap: { + set: function() { + if (this.$useWrapMode) { + this.$useWrapMode = false; + this.setUseWrapMode(true); + } + }, + initialValue: true + }, + firstLineNumber: { + set: function() {this._signal("changeBreakpoint");}, + initialValue: 1 + }, + useWorker: { + set: function(useWorker) { + this.$useWorker = useWorker; + + this.$stopWorker(); + if (useWorker) + this.$startWorker(); + }, + initialValue: true + }, + useSoftTabs: {initialValue: true}, + tabSize: { + set: function(tabSize) { + tabSize = parseInt(tabSize); + if (tabSize > 0 && this.$tabSize !== tabSize) { + this.$modified = true; + this.$rowLengthCache = []; + this.$tabSize = tabSize; + this._signal("changeTabSize"); + } + }, + initialValue: 4, + handlesSet: true + }, + navigateWithinSoftTabs: {initialValue: false}, + foldStyle: { + set: function(val) {this.setFoldStyle(val);}, + handlesSet: true + }, + overwrite: { + set: function(val) {this._signal("changeOverwrite");}, + initialValue: false + }, + newLineMode: { + set: function(val) {this.doc.setNewLineMode(val);}, + get: function() {return this.doc.getNewLineMode();}, + handlesSet: true + }, + mode: { + set: function(val) { this.setMode(val); }, + get: function() { return this.$modeId; }, + handlesSet: true + } +}); + +exports.EditSession = EditSession; +}); + +ace.define("ace/search",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"], function(require, exports, module) { +"use strict"; + +var lang = require("./lib/lang"); +var oop = require("./lib/oop"); +var Range = require("./range").Range; + +var Search = function() { + this.$options = {}; +}; + +(function() { + this.set = function(options) { + oop.mixin(this.$options, options); + return this; + }; + this.getOptions = function() { + return lang.copyObject(this.$options); + }; + this.setOptions = function(options) { + this.$options = options; + }; + this.find = function(session) { + var options = this.$options; + var iterator = this.$matchIterator(session, options); + if (!iterator) + return false; + + var firstRange = null; + iterator.forEach(function(sr, sc, er, ec) { + firstRange = new Range(sr, sc, er, ec); + if (sc == ec && options.start && options.start.start + && options.skipCurrent != false && firstRange.isEqual(options.start) + ) { + firstRange = null; + return false; + } + + return true; + }); + + return firstRange; + }; + this.findAll = function(session) { + var options = this.$options; + if (!options.needle) + return []; + this.$assembleRegExp(options); + + var range = options.range; + var lines = range + ? session.getLines(range.start.row, range.end.row) + : session.doc.getAllLines(); + + var ranges = []; + var re = options.re; + if (options.$isMultiLine) { + var len = re.length; + var maxRow = lines.length - len; + var prevRange; + outer: for (var row = re.offset || 0; row <= maxRow; row++) { + for (var j = 0; j < len; j++) + if (lines[row + j].search(re[j]) == -1) + continue outer; + + var startLine = lines[row]; + var line = lines[row + len - 1]; + var startIndex = startLine.length - startLine.match(re[0])[0].length; + var endIndex = line.match(re[len - 1])[0].length; + + if (prevRange && prevRange.end.row === row && + prevRange.end.column > startIndex + ) { + continue; + } + ranges.push(prevRange = new Range( + row, startIndex, row + len - 1, endIndex + )); + if (len > 2) + row = row + len - 2; + } + } else { + for (var i = 0; i < lines.length; i++) { + var matches = lang.getMatchOffsets(lines[i], re); + for (var j = 0; j < matches.length; j++) { + var match = matches[j]; + ranges.push(new Range(i, match.offset, i, match.offset + match.length)); + } + } + } + + if (range) { + var startColumn = range.start.column; + var endColumn = range.start.column; + var i = 0, j = ranges.length - 1; + while (i < j && ranges[i].start.column < startColumn && ranges[i].start.row == range.start.row) + i++; + + while (i < j && ranges[j].end.column > endColumn && ranges[j].end.row == range.end.row) + j--; + + ranges = ranges.slice(i, j + 1); + for (i = 0, j = ranges.length; i < j; i++) { + ranges[i].start.row += range.start.row; + ranges[i].end.row += range.start.row; + } + } + + return ranges; + }; + this.replace = function(input, replacement) { + var options = this.$options; + + var re = this.$assembleRegExp(options); + if (options.$isMultiLine) + return replacement; + + if (!re) + return; + + var match = re.exec(input); + if (!match || match[0].length != input.length) + return null; + + replacement = input.replace(re, replacement); + if (options.preserveCase) { + replacement = replacement.split(""); + for (var i = Math.min(input.length, input.length); i--; ) { + var ch = input[i]; + if (ch && ch.toLowerCase() != ch) + replacement[i] = replacement[i].toUpperCase(); + else + replacement[i] = replacement[i].toLowerCase(); + } + replacement = replacement.join(""); + } + + return replacement; + }; + + this.$assembleRegExp = function(options, $disableFakeMultiline) { + if (options.needle instanceof RegExp) + return options.re = options.needle; + + var needle = options.needle; + + if (!options.needle) + return options.re = false; + + if (!options.regExp) + needle = lang.escapeRegExp(needle); + + if (options.wholeWord) + needle = addWordBoundary(needle, options); + + var modifier = options.caseSensitive ? "gm" : "gmi"; + + options.$isMultiLine = !$disableFakeMultiline && /[\n\r]/.test(needle); + if (options.$isMultiLine) + return options.re = this.$assembleMultilineRegExp(needle, modifier); + + try { + var re = new RegExp(needle, modifier); + } catch(e) { + re = false; + } + return options.re = re; + }; + + this.$assembleMultilineRegExp = function(needle, modifier) { + var parts = needle.replace(/\r\n|\r|\n/g, "$\n^").split("\n"); + var re = []; + for (var i = 0; i < parts.length; i++) try { + re.push(new RegExp(parts[i], modifier)); + } catch(e) { + return false; + } + return re; + }; + + this.$matchIterator = function(session, options) { + var re = this.$assembleRegExp(options); + if (!re) + return false; + var backwards = options.backwards == true; + var skipCurrent = options.skipCurrent != false; + + var range = options.range; + var start = options.start; + if (!start) + start = range ? range[backwards ? "end" : "start"] : session.selection.getRange(); + + if (start.start) + start = start[skipCurrent != backwards ? "end" : "start"]; + + var firstRow = range ? range.start.row : 0; + var lastRow = range ? range.end.row : session.getLength() - 1; + + if (backwards) { + var forEach = function(callback) { + var row = start.row; + if (forEachInLine(row, start.column, callback)) + return; + for (row--; row >= firstRow; row--) + if (forEachInLine(row, Number.MAX_VALUE, callback)) + return; + if (options.wrap == false) + return; + for (row = lastRow, firstRow = start.row; row >= firstRow; row--) + if (forEachInLine(row, Number.MAX_VALUE, callback)) + return; + }; + } + else { + var forEach = function(callback) { + var row = start.row; + if (forEachInLine(row, start.column, callback)) + return; + for (row = row + 1; row <= lastRow; row++) + if (forEachInLine(row, 0, callback)) + return; + if (options.wrap == false) + return; + for (row = firstRow, lastRow = start.row; row <= lastRow; row++) + if (forEachInLine(row, 0, callback)) + return; + }; + } + + if (options.$isMultiLine) { + var len = re.length; + var forEachInLine = function(row, offset, callback) { + var startRow = backwards ? row - len + 1 : row; + if (startRow < 0) return; + var line = session.getLine(startRow); + var startIndex = line.search(re[0]); + if (!backwards && startIndex < offset || startIndex === -1) return; + for (var i = 1; i < len; i++) { + line = session.getLine(startRow + i); + if (line.search(re[i]) == -1) + return; + } + var endIndex = line.match(re[len - 1])[0].length; + if (backwards && endIndex > offset) return; + if (callback(startRow, startIndex, startRow + len - 1, endIndex)) + return true; + }; + } + else if (backwards) { + var forEachInLine = function(row, endIndex, callback) { + var line = session.getLine(row); + var matches = []; + var m, last = 0; + re.lastIndex = 0; + while((m = re.exec(line))) { + var length = m[0].length; + last = m.index; + if (!length) { + if (last >= line.length) break; + re.lastIndex = last += 1; + } + if (m.index + length > endIndex) + break; + matches.push(m.index, length); + } + for (var i = matches.length - 1; i >= 0; i -= 2) { + var column = matches[i - 1]; + var length = matches[i]; + if (callback(row, column, row, column + length)) + return true; + } + }; + } + else { + var forEachInLine = function(row, startIndex, callback) { + var line = session.getLine(row); + var last; + var m; + re.lastIndex = startIndex; + while((m = re.exec(line))) { + var length = m[0].length; + last = m.index; + if (callback(row, last, row,last + length)) + return true; + if (!length) { + re.lastIndex = last += 1; + if (last >= line.length) return false; + } + } + }; + } + return {forEach: forEach}; + }; + +}).call(Search.prototype); + +function addWordBoundary(needle, options) { + function wordBoundary(c) { + if (/\w/.test(c) || options.regExp) return "\\b"; + return ""; + } + return wordBoundary(needle[0]) + needle + + wordBoundary(needle[needle.length - 1]); +} + +exports.Search = Search; +}); + +ace.define("ace/keyboard/hash_handler",["require","exports","module","ace/lib/keys","ace/lib/useragent"], function(require, exports, module) { +"use strict"; + +var keyUtil = require("../lib/keys"); +var useragent = require("../lib/useragent"); +var KEY_MODS = keyUtil.KEY_MODS; + +function HashHandler(config, platform) { + this.platform = platform || (useragent.isMac ? "mac" : "win"); + this.commands = {}; + this.commandKeyBinding = {}; + this.addCommands(config); + this.$singleCommand = true; +} + +function MultiHashHandler(config, platform) { + HashHandler.call(this, config, platform); + this.$singleCommand = false; +} + +MultiHashHandler.prototype = HashHandler.prototype; + +(function() { + + + this.addCommand = function(command) { + if (this.commands[command.name]) + this.removeCommand(command); + + this.commands[command.name] = command; + + if (command.bindKey) + this._buildKeyHash(command); + }; + + this.removeCommand = function(command, keepCommand) { + var name = command && (typeof command === 'string' ? command : command.name); + command = this.commands[name]; + if (!keepCommand) + delete this.commands[name]; + var ckb = this.commandKeyBinding; + for (var keyId in ckb) { + var cmdGroup = ckb[keyId]; + if (cmdGroup == command) { + delete ckb[keyId]; + } else if (Array.isArray(cmdGroup)) { + var i = cmdGroup.indexOf(command); + if (i != -1) { + cmdGroup.splice(i, 1); + if (cmdGroup.length == 1) + ckb[keyId] = cmdGroup[0]; + } + } + } + }; + + this.bindKey = function(key, command, position) { + if (typeof key == "object" && key) { + if (position == undefined) + position = key.position; + key = key[this.platform]; + } + if (!key) + return; + if (typeof command == "function") + return this.addCommand({exec: command, bindKey: key, name: command.name || key}); + + key.split("|").forEach(function(keyPart) { + var chain = ""; + if (keyPart.indexOf(" ") != -1) { + var parts = keyPart.split(/\s+/); + keyPart = parts.pop(); + parts.forEach(function(keyPart) { + var binding = this.parseKeys(keyPart); + var id = KEY_MODS[binding.hashId] + binding.key; + chain += (chain ? " " : "") + id; + this._addCommandToBinding(chain, "chainKeys"); + }, this); + chain += " "; + } + var binding = this.parseKeys(keyPart); + var id = KEY_MODS[binding.hashId] + binding.key; + this._addCommandToBinding(chain + id, command, position); + }, this); + }; + + function getPosition(command) { + return typeof command == "object" && command.bindKey + && command.bindKey.position + || (command.isDefault ? -100 : 0); + } + this._addCommandToBinding = function(keyId, command, position) { + var ckb = this.commandKeyBinding, i; + if (!command) { + delete ckb[keyId]; + } else if (!ckb[keyId] || this.$singleCommand) { + ckb[keyId] = command; + } else { + if (!Array.isArray(ckb[keyId])) { + ckb[keyId] = [ckb[keyId]]; + } else if ((i = ckb[keyId].indexOf(command)) != -1) { + ckb[keyId].splice(i, 1); + } + + if (typeof position != "number") { + position = getPosition(command); + } + + var commands = ckb[keyId]; + for (i = 0; i < commands.length; i++) { + var other = commands[i]; + var otherPos = getPosition(other); + if (otherPos > position) + break; + } + commands.splice(i, 0, command); + } + }; + + this.addCommands = function(commands) { + commands && Object.keys(commands).forEach(function(name) { + var command = commands[name]; + if (!command) + return; + + if (typeof command === "string") + return this.bindKey(command, name); + + if (typeof command === "function") + command = { exec: command }; + + if (typeof command !== "object") + return; + + if (!command.name) + command.name = name; + + this.addCommand(command); + }, this); + }; + + this.removeCommands = function(commands) { + Object.keys(commands).forEach(function(name) { + this.removeCommand(commands[name]); + }, this); + }; + + this.bindKeys = function(keyList) { + Object.keys(keyList).forEach(function(key) { + this.bindKey(key, keyList[key]); + }, this); + }; + + this._buildKeyHash = function(command) { + this.bindKey(command.bindKey, command); + }; + this.parseKeys = function(keys) { + var parts = keys.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(x){return x;}); + var key = parts.pop(); + + var keyCode = keyUtil[key]; + if (keyUtil.FUNCTION_KEYS[keyCode]) + key = keyUtil.FUNCTION_KEYS[keyCode].toLowerCase(); + else if (!parts.length) + return {key: key, hashId: -1}; + else if (parts.length == 1 && parts[0] == "shift") + return {key: key.toUpperCase(), hashId: -1}; + + var hashId = 0; + for (var i = parts.length; i--;) { + var modifier = keyUtil.KEY_MODS[parts[i]]; + if (modifier == null) { + if (typeof console != "undefined") + console.error("invalid modifier " + parts[i] + " in " + keys); + return false; + } + hashId |= modifier; + } + return {key: key, hashId: hashId}; + }; + + this.findKeyCommand = function findKeyCommand(hashId, keyString) { + var key = KEY_MODS[hashId] + keyString; + return this.commandKeyBinding[key]; + }; + + this.handleKeyboard = function(data, hashId, keyString, keyCode) { + if (keyCode < 0) return; + var key = KEY_MODS[hashId] + keyString; + var command = this.commandKeyBinding[key]; + if (data.$keyChain) { + data.$keyChain += " " + key; + command = this.commandKeyBinding[data.$keyChain] || command; + } + + if (command) { + if (command == "chainKeys" || command[command.length - 1] == "chainKeys") { + data.$keyChain = data.$keyChain || key; + return {command: "null"}; + } + } + + if (data.$keyChain) { + if ((!hashId || hashId == 4) && keyString.length == 1) + data.$keyChain = data.$keyChain.slice(0, -key.length - 1); // wait for input + else if (hashId == -1 || keyCode > 0) + data.$keyChain = ""; // reset keyChain + } + return {command: command}; + }; + + this.getStatusText = function(editor, data) { + return data.$keyChain || ""; + }; + +}).call(HashHandler.prototype); + +exports.HashHandler = HashHandler; +exports.MultiHashHandler = MultiHashHandler; +}); + +ace.define("ace/commands/command_manager",["require","exports","module","ace/lib/oop","ace/keyboard/hash_handler","ace/lib/event_emitter"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var MultiHashHandler = require("../keyboard/hash_handler").MultiHashHandler; +var EventEmitter = require("../lib/event_emitter").EventEmitter; + +var CommandManager = function(platform, commands) { + MultiHashHandler.call(this, commands, platform); + this.byName = this.commands; + this.setDefaultHandler("exec", function(e) { + return e.command.exec(e.editor, e.args || {}); + }); +}; + +oop.inherits(CommandManager, MultiHashHandler); + +(function() { + + oop.implement(this, EventEmitter); + + this.exec = function(command, editor, args) { + if (Array.isArray(command)) { + for (var i = command.length; i--; ) { + if (this.exec(command[i], editor, args)) return true; + } + return false; + } + + if (typeof command === "string") + command = this.commands[command]; + + if (!command) + return false; + + if (editor && editor.$readOnly && !command.readOnly) + return false; + + if (this.$checkCommandState != false && command.isAvailable && !command.isAvailable(editor)) + return false; + + var e = {editor: editor, command: command, args: args}; + e.returnValue = this._emit("exec", e); + this._signal("afterExec", e); + + return e.returnValue === false ? false : true; + }; + + this.toggleRecording = function(editor) { + if (this.$inReplay) + return; + + editor && editor._emit("changeStatus"); + if (this.recording) { + this.macro.pop(); + this.off("exec", this.$addCommandToMacro); + + if (!this.macro.length) + this.macro = this.oldMacro; + + return this.recording = false; + } + if (!this.$addCommandToMacro) { + this.$addCommandToMacro = function(e) { + this.macro.push([e.command, e.args]); + }.bind(this); + } + + this.oldMacro = this.macro; + this.macro = []; + this.on("exec", this.$addCommandToMacro); + return this.recording = true; + }; + + this.replay = function(editor) { + if (this.$inReplay || !this.macro) + return; + + if (this.recording) + return this.toggleRecording(editor); + + try { + this.$inReplay = true; + this.macro.forEach(function(x) { + if (typeof x == "string") + this.exec(x, editor); + else + this.exec(x[0], editor, x[1]); + }, this); + } finally { + this.$inReplay = false; + } + }; + + this.trimMacro = function(m) { + return m.map(function(x){ + if (typeof x[0] != "string") + x[0] = x[0].name; + if (!x[1]) + x = x[0]; + return x; + }); + }; + +}).call(CommandManager.prototype); + +exports.CommandManager = CommandManager; + +}); + +ace.define("ace/commands/default_commands",["require","exports","module","ace/lib/lang","ace/config","ace/range"], function(require, exports, module) { +"use strict"; + +var lang = require("../lib/lang"); +var config = require("../config"); +var Range = require("../range").Range; + +function bindKey(win, mac) { + return {win: win, mac: mac}; +} +exports.commands = [{ + name: "showSettingsMenu", + bindKey: bindKey("Ctrl-,", "Command-,"), + exec: function(editor) { + config.loadModule("ace/ext/settings_menu", function(module) { + module.init(editor); + editor.showSettingsMenu(); + }); + }, + readOnly: true +}, { + name: "goToNextError", + bindKey: bindKey("Alt-E", "F4"), + exec: function(editor) { + config.loadModule("./ext/error_marker", function(module) { + module.showErrorMarker(editor, 1); + }); + }, + scrollIntoView: "animate", + readOnly: true +}, { + name: "goToPreviousError", + bindKey: bindKey("Alt-Shift-E", "Shift-F4"), + exec: function(editor) { + config.loadModule("./ext/error_marker", function(module) { + module.showErrorMarker(editor, -1); + }); + }, + scrollIntoView: "animate", + readOnly: true +}, { + name: "selectall", + description: "Select all", + bindKey: bindKey("Ctrl-A", "Command-A"), + exec: function(editor) { editor.selectAll(); }, + readOnly: true +}, { + name: "centerselection", + description: "Center selection", + bindKey: bindKey(null, "Ctrl-L"), + exec: function(editor) { editor.centerSelection(); }, + readOnly: true +}, { + name: "gotoline", + description: "Go to line...", + bindKey: bindKey("Ctrl-L", "Command-L"), + exec: function(editor, line) { + if (typeof line === "number" && !isNaN(line)) + editor.gotoLine(line); + editor.prompt({ $type: "gotoLine" }); + }, + readOnly: true +}, { + name: "fold", + bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"), + exec: function(editor) { editor.session.toggleFold(false); }, + multiSelectAction: "forEach", + scrollIntoView: "center", + readOnly: true +}, { + name: "unfold", + bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"), + exec: function(editor) { editor.session.toggleFold(true); }, + multiSelectAction: "forEach", + scrollIntoView: "center", + readOnly: true +}, { + name: "toggleFoldWidget", + bindKey: bindKey("F2", "F2"), + exec: function(editor) { editor.session.toggleFoldWidget(); }, + multiSelectAction: "forEach", + scrollIntoView: "center", + readOnly: true +}, { + name: "toggleParentFoldWidget", + bindKey: bindKey("Alt-F2", "Alt-F2"), + exec: function(editor) { editor.session.toggleFoldWidget(true); }, + multiSelectAction: "forEach", + scrollIntoView: "center", + readOnly: true +}, { + name: "foldall", + description: "Fold all", + bindKey: bindKey(null, "Ctrl-Command-Option-0"), + exec: function(editor) { editor.session.foldAll(); }, + scrollIntoView: "center", + readOnly: true +}, { + name: "foldAllComments", + description: "Fold all comments", + bindKey: bindKey(null, "Ctrl-Command-Option-0"), + exec: function(editor) { editor.session.foldAllComments(); }, + scrollIntoView: "center", + readOnly: true +}, { + name: "foldOther", + description: "Fold other", + bindKey: bindKey("Alt-0", "Command-Option-0"), + exec: function(editor) { + editor.session.foldAll(); + editor.session.unfold(editor.selection.getAllRanges()); + }, + scrollIntoView: "center", + readOnly: true +}, { + name: "unfoldall", + description: "Unfold all", + bindKey: bindKey("Alt-Shift-0", "Command-Option-Shift-0"), + exec: function(editor) { editor.session.unfold(); }, + scrollIntoView: "center", + readOnly: true +}, { + name: "findnext", + description: "Find next", + bindKey: bindKey("Ctrl-K", "Command-G"), + exec: function(editor) { editor.findNext(); }, + multiSelectAction: "forEach", + scrollIntoView: "center", + readOnly: true +}, { + name: "findprevious", + description: "Find previous", + bindKey: bindKey("Ctrl-Shift-K", "Command-Shift-G"), + exec: function(editor) { editor.findPrevious(); }, + multiSelectAction: "forEach", + scrollIntoView: "center", + readOnly: true +}, { + name: "selectOrFindNext", + description: "Select or find next", + bindKey: bindKey("Alt-K", "Ctrl-G"), + exec: function(editor) { + if (editor.selection.isEmpty()) + editor.selection.selectWord(); + else + editor.findNext(); + }, + readOnly: true +}, { + name: "selectOrFindPrevious", + description: "Select or find previous", + bindKey: bindKey("Alt-Shift-K", "Ctrl-Shift-G"), + exec: function(editor) { + if (editor.selection.isEmpty()) + editor.selection.selectWord(); + else + editor.findPrevious(); + }, + readOnly: true +}, { + name: "find", + description: "Find", + bindKey: bindKey("Ctrl-F", "Command-F"), + exec: function(editor) { + config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor);}); + }, + readOnly: true +}, { + name: "overwrite", + description: "Overwrite", + bindKey: "Insert", + exec: function(editor) { editor.toggleOverwrite(); }, + readOnly: true +}, { + name: "selecttostart", + description: "Select to start", + bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Home|Command-Shift-Up"), + exec: function(editor) { editor.getSelection().selectFileStart(); }, + multiSelectAction: "forEach", + readOnly: true, + scrollIntoView: "animate", + aceCommandGroup: "fileJump" +}, { + name: "gotostart", + description: "Go to start", + bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"), + exec: function(editor) { editor.navigateFileStart(); }, + multiSelectAction: "forEach", + readOnly: true, + scrollIntoView: "animate", + aceCommandGroup: "fileJump" +}, { + name: "selectup", + description: "Select up", + bindKey: bindKey("Shift-Up", "Shift-Up|Ctrl-Shift-P"), + exec: function(editor) { editor.getSelection().selectUp(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "golineup", + description: "Go line up", + bindKey: bindKey("Up", "Up|Ctrl-P"), + exec: function(editor, args) { editor.navigateUp(args.times); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selecttoend", + description: "Select to end", + bindKey: bindKey("Ctrl-Shift-End", "Command-Shift-End|Command-Shift-Down"), + exec: function(editor) { editor.getSelection().selectFileEnd(); }, + multiSelectAction: "forEach", + readOnly: true, + scrollIntoView: "animate", + aceCommandGroup: "fileJump" +}, { + name: "gotoend", + description: "Go to end", + bindKey: bindKey("Ctrl-End", "Command-End|Command-Down"), + exec: function(editor) { editor.navigateFileEnd(); }, + multiSelectAction: "forEach", + readOnly: true, + scrollIntoView: "animate", + aceCommandGroup: "fileJump" +}, { + name: "selectdown", + description: "Select down", + bindKey: bindKey("Shift-Down", "Shift-Down|Ctrl-Shift-N"), + exec: function(editor) { editor.getSelection().selectDown(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "golinedown", + description: "Go line down", + bindKey: bindKey("Down", "Down|Ctrl-N"), + exec: function(editor, args) { editor.navigateDown(args.times); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectwordleft", + description: "Select word left", + bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"), + exec: function(editor) { editor.getSelection().selectWordLeft(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "gotowordleft", + description: "Go to word left", + bindKey: bindKey("Ctrl-Left", "Option-Left"), + exec: function(editor) { editor.navigateWordLeft(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selecttolinestart", + description: "Select to line start", + bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left|Ctrl-Shift-A"), + exec: function(editor) { editor.getSelection().selectLineStart(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "gotolinestart", + description: "Go to line start", + bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"), + exec: function(editor) { editor.navigateLineStart(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectleft", + description: "Select left", + bindKey: bindKey("Shift-Left", "Shift-Left|Ctrl-Shift-B"), + exec: function(editor) { editor.getSelection().selectLeft(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "gotoleft", + description: "Go to left", + bindKey: bindKey("Left", "Left|Ctrl-B"), + exec: function(editor, args) { editor.navigateLeft(args.times); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectwordright", + description: "Select word right", + bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"), + exec: function(editor) { editor.getSelection().selectWordRight(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "gotowordright", + description: "Go to word right", + bindKey: bindKey("Ctrl-Right", "Option-Right"), + exec: function(editor) { editor.navigateWordRight(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selecttolineend", + description: "Select to line end", + bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right|Shift-End|Ctrl-Shift-E"), + exec: function(editor) { editor.getSelection().selectLineEnd(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "gotolineend", + description: "Go to line end", + bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"), + exec: function(editor) { editor.navigateLineEnd(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectright", + description: "Select right", + bindKey: bindKey("Shift-Right", "Shift-Right"), + exec: function(editor) { editor.getSelection().selectRight(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "gotoright", + description: "Go to right", + bindKey: bindKey("Right", "Right|Ctrl-F"), + exec: function(editor, args) { editor.navigateRight(args.times); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectpagedown", + description: "Select page down", + bindKey: "Shift-PageDown", + exec: function(editor) { editor.selectPageDown(); }, + readOnly: true +}, { + name: "pagedown", + description: "Page down", + bindKey: bindKey(null, "Option-PageDown"), + exec: function(editor) { editor.scrollPageDown(); }, + readOnly: true +}, { + name: "gotopagedown", + description: "Go to page down", + bindKey: bindKey("PageDown", "PageDown|Ctrl-V"), + exec: function(editor) { editor.gotoPageDown(); }, + readOnly: true +}, { + name: "selectpageup", + description: "Select page up", + bindKey: "Shift-PageUp", + exec: function(editor) { editor.selectPageUp(); }, + readOnly: true +}, { + name: "pageup", + description: "Page up", + bindKey: bindKey(null, "Option-PageUp"), + exec: function(editor) { editor.scrollPageUp(); }, + readOnly: true +}, { + name: "gotopageup", + description: "Go to page up", + bindKey: "PageUp", + exec: function(editor) { editor.gotoPageUp(); }, + readOnly: true +}, { + name: "scrollup", + description: "Scroll up", + bindKey: bindKey("Ctrl-Up", null), + exec: function(e) { e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight); }, + readOnly: true +}, { + name: "scrolldown", + description: "Scroll down", + bindKey: bindKey("Ctrl-Down", null), + exec: function(e) { e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight); }, + readOnly: true +}, { + name: "selectlinestart", + description: "Select line start", + bindKey: "Shift-Home", + exec: function(editor) { editor.getSelection().selectLineStart(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectlineend", + description: "Select line end", + bindKey: "Shift-End", + exec: function(editor) { editor.getSelection().selectLineEnd(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "togglerecording", + description: "Toggle recording", + bindKey: bindKey("Ctrl-Alt-E", "Command-Option-E"), + exec: function(editor) { editor.commands.toggleRecording(editor); }, + readOnly: true +}, { + name: "replaymacro", + description: "Replay macro", + bindKey: bindKey("Ctrl-Shift-E", "Command-Shift-E"), + exec: function(editor) { editor.commands.replay(editor); }, + readOnly: true +}, { + name: "jumptomatching", + description: "Jump to matching", + bindKey: bindKey("Ctrl-\\|Ctrl-P", "Command-\\"), + exec: function(editor) { editor.jumpToMatching(); }, + multiSelectAction: "forEach", + scrollIntoView: "animate", + readOnly: true +}, { + name: "selecttomatching", + description: "Select to matching", + bindKey: bindKey("Ctrl-Shift-\\|Ctrl-Shift-P", "Command-Shift-\\"), + exec: function(editor) { editor.jumpToMatching(true); }, + multiSelectAction: "forEach", + scrollIntoView: "animate", + readOnly: true +}, { + name: "expandToMatching", + description: "Expand to matching", + bindKey: bindKey("Ctrl-Shift-M", "Ctrl-Shift-M"), + exec: function(editor) { editor.jumpToMatching(true, true); }, + multiSelectAction: "forEach", + scrollIntoView: "animate", + readOnly: true +}, { + name: "passKeysToBrowser", + description: "Pass keys to browser", + bindKey: bindKey(null, null), + exec: function() {}, + passEvent: true, + readOnly: true +}, { + name: "copy", + description: "Copy", + exec: function(editor) { + }, + readOnly: true +}, +{ + name: "cut", + description: "Cut", + exec: function(editor) { + var cutLine = editor.$copyWithEmptySelection && editor.selection.isEmpty(); + var range = cutLine ? editor.selection.getLineRange() : editor.selection.getRange(); + editor._emit("cut", range); + + if (!range.isEmpty()) + editor.session.remove(range); + editor.clearSelection(); + }, + scrollIntoView: "cursor", + multiSelectAction: "forEach" +}, { + name: "paste", + description: "Paste", + exec: function(editor, args) { + editor.$handlePaste(args); + }, + scrollIntoView: "cursor" +}, { + name: "removeline", + description: "Remove line", + bindKey: bindKey("Ctrl-D", "Command-D"), + exec: function(editor) { editor.removeLines(); }, + scrollIntoView: "cursor", + multiSelectAction: "forEachLine" +}, { + name: "duplicateSelection", + description: "Duplicate selection", + bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"), + exec: function(editor) { editor.duplicateSelection(); }, + scrollIntoView: "cursor", + multiSelectAction: "forEach" +}, { + name: "sortlines", + description: "Sort lines", + bindKey: bindKey("Ctrl-Alt-S", "Command-Alt-S"), + exec: function(editor) { editor.sortLines(); }, + scrollIntoView: "selection", + multiSelectAction: "forEachLine" +}, { + name: "togglecomment", + description: "Toggle comment", + bindKey: bindKey("Ctrl-/", "Command-/"), + exec: function(editor) { editor.toggleCommentLines(); }, + multiSelectAction: "forEachLine", + scrollIntoView: "selectionPart" +}, { + name: "toggleBlockComment", + description: "Toggle block comment", + bindKey: bindKey("Ctrl-Shift-/", "Command-Shift-/"), + exec: function(editor) { editor.toggleBlockComment(); }, + multiSelectAction: "forEach", + scrollIntoView: "selectionPart" +}, { + name: "modifyNumberUp", + description: "Modify number up", + bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"), + exec: function(editor) { editor.modifyNumber(1); }, + scrollIntoView: "cursor", + multiSelectAction: "forEach" +}, { + name: "modifyNumberDown", + description: "Modify number down", + bindKey: bindKey("Ctrl-Shift-Down", "Alt-Shift-Down"), + exec: function(editor) { editor.modifyNumber(-1); }, + scrollIntoView: "cursor", + multiSelectAction: "forEach" +}, { + name: "replace", + description: "Replace", + bindKey: bindKey("Ctrl-H", "Command-Option-F"), + exec: function(editor) { + config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor, true);}); + } +}, { + name: "undo", + description: "Undo", + bindKey: bindKey("Ctrl-Z", "Command-Z"), + exec: function(editor) { editor.undo(); } +}, { + name: "redo", + description: "Redo", + bindKey: bindKey("Ctrl-Shift-Z|Ctrl-Y", "Command-Shift-Z|Command-Y"), + exec: function(editor) { editor.redo(); } +}, { + name: "copylinesup", + description: "Copy lines up", + bindKey: bindKey("Alt-Shift-Up", "Command-Option-Up"), + exec: function(editor) { editor.copyLinesUp(); }, + scrollIntoView: "cursor" +}, { + name: "movelinesup", + description: "Move lines up", + bindKey: bindKey("Alt-Up", "Option-Up"), + exec: function(editor) { editor.moveLinesUp(); }, + scrollIntoView: "cursor" +}, { + name: "copylinesdown", + description: "Copy lines down", + bindKey: bindKey("Alt-Shift-Down", "Command-Option-Down"), + exec: function(editor) { editor.copyLinesDown(); }, + scrollIntoView: "cursor" +}, { + name: "movelinesdown", + description: "Move lines down", + bindKey: bindKey("Alt-Down", "Option-Down"), + exec: function(editor) { editor.moveLinesDown(); }, + scrollIntoView: "cursor" +}, { + name: "del", + description: "Delete", + bindKey: bindKey("Delete", "Delete|Ctrl-D|Shift-Delete"), + exec: function(editor) { editor.remove("right"); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "backspace", + description: "Backspace", + bindKey: bindKey( + "Shift-Backspace|Backspace", + "Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H" + ), + exec: function(editor) { editor.remove("left"); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "cut_or_delete", + description: "Cut or delete", + bindKey: bindKey("Shift-Delete", null), + exec: function(editor) { + if (editor.selection.isEmpty()) { + editor.remove("left"); + } else { + return false; + } + }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "removetolinestart", + description: "Remove to line start", + bindKey: bindKey("Alt-Backspace", "Command-Backspace"), + exec: function(editor) { editor.removeToLineStart(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "removetolineend", + description: "Remove to line end", + bindKey: bindKey("Alt-Delete", "Ctrl-K|Command-Delete"), + exec: function(editor) { editor.removeToLineEnd(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "removetolinestarthard", + description: "Remove to line start hard", + bindKey: bindKey("Ctrl-Shift-Backspace", null), + exec: function(editor) { + var range = editor.selection.getRange(); + range.start.column = 0; + editor.session.remove(range); + }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "removetolineendhard", + description: "Remove to line end hard", + bindKey: bindKey("Ctrl-Shift-Delete", null), + exec: function(editor) { + var range = editor.selection.getRange(); + range.end.column = Number.MAX_VALUE; + editor.session.remove(range); + }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "removewordleft", + description: "Remove word left", + bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"), + exec: function(editor) { editor.removeWordLeft(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "removewordright", + description: "Remove word right", + bindKey: bindKey("Ctrl-Delete", "Alt-Delete"), + exec: function(editor) { editor.removeWordRight(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "outdent", + description: "Outdent", + bindKey: bindKey("Shift-Tab", "Shift-Tab"), + exec: function(editor) { editor.blockOutdent(); }, + multiSelectAction: "forEach", + scrollIntoView: "selectionPart" +}, { + name: "indent", + description: "Indent", + bindKey: bindKey("Tab", "Tab"), + exec: function(editor) { editor.indent(); }, + multiSelectAction: "forEach", + scrollIntoView: "selectionPart" +}, { + name: "blockoutdent", + description: "Block outdent", + bindKey: bindKey("Ctrl-[", "Ctrl-["), + exec: function(editor) { editor.blockOutdent(); }, + multiSelectAction: "forEachLine", + scrollIntoView: "selectionPart" +}, { + name: "blockindent", + description: "Block indent", + bindKey: bindKey("Ctrl-]", "Ctrl-]"), + exec: function(editor) { editor.blockIndent(); }, + multiSelectAction: "forEachLine", + scrollIntoView: "selectionPart" +}, { + name: "insertstring", + description: "Insert string", + exec: function(editor, str) { editor.insert(str); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "inserttext", + description: "Insert text", + exec: function(editor, args) { + editor.insert(lang.stringRepeat(args.text || "", args.times || 1)); + }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "splitline", + description: "Split line", + bindKey: bindKey(null, "Ctrl-O"), + exec: function(editor) { editor.splitLine(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "transposeletters", + description: "Transpose letters", + bindKey: bindKey("Alt-Shift-X", "Ctrl-T"), + exec: function(editor) { editor.transposeLetters(); }, + multiSelectAction: function(editor) {editor.transposeSelections(1); }, + scrollIntoView: "cursor" +}, { + name: "touppercase", + description: "To uppercase", + bindKey: bindKey("Ctrl-U", "Ctrl-U"), + exec: function(editor) { editor.toUpperCase(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "tolowercase", + description: "To lowercase", + bindKey: bindKey("Ctrl-Shift-U", "Ctrl-Shift-U"), + exec: function(editor) { editor.toLowerCase(); }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "autoindent", + description: "Auto Indent", + bindKey: bindKey(null, null), + exec: function(editor) { editor.autoIndent(); }, + multiSelectAction: "forEachLine", + scrollIntoView: "animate" +}, { + name: "expandtoline", + description: "Expand to line", + bindKey: bindKey("Ctrl-Shift-L", "Command-Shift-L"), + exec: function(editor) { + var range = editor.selection.getRange(); + + range.start.column = range.end.column = 0; + range.end.row++; + editor.selection.setRange(range, false); + }, + multiSelectAction: "forEach", + scrollIntoView: "cursor", + readOnly: true +}, { + name: "joinlines", + description: "Join lines", + bindKey: bindKey(null, null), + exec: function(editor) { + var isBackwards = editor.selection.isBackwards(); + var selectionStart = isBackwards ? editor.selection.getSelectionLead() : editor.selection.getSelectionAnchor(); + var selectionEnd = isBackwards ? editor.selection.getSelectionAnchor() : editor.selection.getSelectionLead(); + var firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length; + var selectedText = editor.session.doc.getTextRange(editor.selection.getRange()); + var selectedCount = selectedText.replace(/\n\s*/, " ").length; + var insertLine = editor.session.doc.getLine(selectionStart.row); + + for (var i = selectionStart.row + 1; i <= selectionEnd.row + 1; i++) { + var curLine = lang.stringTrimLeft(lang.stringTrimRight(editor.session.doc.getLine(i))); + if (curLine.length !== 0) { + curLine = " " + curLine; + } + insertLine += curLine; + } + + if (selectionEnd.row + 1 < (editor.session.doc.getLength() - 1)) { + insertLine += editor.session.doc.getNewLineCharacter(); + } + + editor.clearSelection(); + editor.session.doc.replace(new Range(selectionStart.row, 0, selectionEnd.row + 2, 0), insertLine); + + if (selectedCount > 0) { + editor.selection.moveCursorTo(selectionStart.row, selectionStart.column); + editor.selection.selectTo(selectionStart.row, selectionStart.column + selectedCount); + } else { + firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length > firstLineEndCol ? (firstLineEndCol + 1) : firstLineEndCol; + editor.selection.moveCursorTo(selectionStart.row, firstLineEndCol); + } + }, + multiSelectAction: "forEach", + readOnly: true +}, { + name: "invertSelection", + description: "Invert selection", + bindKey: bindKey(null, null), + exec: function(editor) { + var endRow = editor.session.doc.getLength() - 1; + var endCol = editor.session.doc.getLine(endRow).length; + var ranges = editor.selection.rangeList.ranges; + var newRanges = []; + if (ranges.length < 1) { + ranges = [editor.selection.getRange()]; + } + + for (var i = 0; i < ranges.length; i++) { + if (i == (ranges.length - 1)) { + if (!(ranges[i].end.row === endRow && ranges[i].end.column === endCol)) { + newRanges.push(new Range(ranges[i].end.row, ranges[i].end.column, endRow, endCol)); + } + } + + if (i === 0) { + if (!(ranges[i].start.row === 0 && ranges[i].start.column === 0)) { + newRanges.push(new Range(0, 0, ranges[i].start.row, ranges[i].start.column)); + } + } else { + newRanges.push(new Range(ranges[i-1].end.row, ranges[i-1].end.column, ranges[i].start.row, ranges[i].start.column)); + } + } + + editor.exitMultiSelectMode(); + editor.clearSelection(); + + for(var i = 0; i < newRanges.length; i++) { + editor.selection.addRange(newRanges[i], false); + } + }, + readOnly: true, + scrollIntoView: "none" +}, { + name: "addLineAfter", + exec: function(editor) { + editor.selection.clearSelection(); + editor.navigateLineEnd(); + editor.insert("\n"); + }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "addLineBefore", + exec: function(editor) { + editor.selection.clearSelection(); + var cursor = editor.getCursorPosition(); + editor.selection.moveTo(cursor.row - 1, Number.MAX_VALUE); + editor.insert("\n"); + if (cursor.row === 0) editor.navigateUp(); + }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "openCommandPallete", + description: "Open command pallete", + bindKey: bindKey("F1", "F1"), + exec: function(editor) { + editor.prompt({ $type: "commands" }); + }, + readOnly: true +}, { + name: "modeSelect", + description: "Change language mode...", + bindKey: bindKey(null, null), + exec: function(editor) { + editor.prompt({ $type: "modes" }); + }, + readOnly: true +}]; + +for (var i = 1; i < 9; i++) { + exports.commands.push({ + name: "foldToLevel" + i, + description: "Fold To Level " + i, + level: i, + exec: function(editor) { editor.session.foldToLevel(this.level); }, + scrollIntoView: "center", + readOnly: true + }); +} + +}); + +ace.define("ace/editor",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/keyboard/textinput","ace/mouse/mouse_handler","ace/mouse/fold_handler","ace/keyboard/keybinding","ace/edit_session","ace/search","ace/range","ace/lib/event_emitter","ace/commands/command_manager","ace/commands/default_commands","ace/config","ace/token_iterator","ace/clipboard"], function(require, exports, module) { +"use strict"; + +require("./lib/fixoldbrowsers"); + +var oop = require("./lib/oop"); +var dom = require("./lib/dom"); +var lang = require("./lib/lang"); +var useragent = require("./lib/useragent"); +var TextInput = require("./keyboard/textinput").TextInput; +var MouseHandler = require("./mouse/mouse_handler").MouseHandler; +var FoldHandler = require("./mouse/fold_handler").FoldHandler; +var KeyBinding = require("./keyboard/keybinding").KeyBinding; +var EditSession = require("./edit_session").EditSession; +var Search = require("./search").Search; +var Range = require("./range").Range; +var EventEmitter = require("./lib/event_emitter").EventEmitter; +var CommandManager = require("./commands/command_manager").CommandManager; +var defaultCommands = require("./commands/default_commands").commands; +var config = require("./config"); +var TokenIterator = require("./token_iterator").TokenIterator; + +var clipboard = require("./clipboard"); +var Editor = function(renderer, session, options) { + this.$toDestroy = []; + var container = renderer.getContainerElement(); + this.container = container; + this.renderer = renderer; + this.id = "editor" + (++Editor.$uid); + + this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands); + if (typeof document == "object") { + this.textInput = new TextInput(renderer.getTextAreaContainer(), this); + this.renderer.textarea = this.textInput.getElement(); + this.$mouseHandler = new MouseHandler(this); + new FoldHandler(this); + } + + this.keyBinding = new KeyBinding(this); + + this.$search = new Search().set({ + wrap: true + }); + + this.$historyTracker = this.$historyTracker.bind(this); + this.commands.on("exec", this.$historyTracker); + + this.$initOperationListeners(); + + this._$emitInputEvent = lang.delayedCall(function() { + this._signal("input", {}); + if (this.session && this.session.bgTokenizer) + this.session.bgTokenizer.scheduleStart(); + }.bind(this)); + + this.on("change", function(_, _self) { + _self._$emitInputEvent.schedule(31); + }); + + this.setSession(session || options && options.session || new EditSession("")); + config.resetOptions(this); + if (options) + this.setOptions(options); + config._signal("editor", this); +}; + +Editor.$uid = 0; + +(function(){ + + oop.implement(this, EventEmitter); + + this.$initOperationListeners = function() { + this.commands.on("exec", this.startOperation.bind(this), true); + this.commands.on("afterExec", this.endOperation.bind(this), true); + + this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this, true)); + this.on("change", function() { + if (!this.curOp) { + this.startOperation(); + this.curOp.selectionBefore = this.$lastSel; + } + this.curOp.docChanged = true; + }.bind(this), true); + + this.on("changeSelection", function() { + if (!this.curOp) { + this.startOperation(); + this.curOp.selectionBefore = this.$lastSel; + } + this.curOp.selectionChanged = true; + }.bind(this), true); + }; + + this.curOp = null; + this.prevOp = {}; + this.startOperation = function(commandEvent) { + if (this.curOp) { + if (!commandEvent || this.curOp.command) + return; + this.prevOp = this.curOp; + } + if (!commandEvent) { + this.previousCommand = null; + commandEvent = {}; + } + + this.$opResetTimer.schedule(); + this.curOp = this.session.curOp = { + command: commandEvent.command || {}, + args: commandEvent.args, + scrollTop: this.renderer.scrollTop + }; + this.curOp.selectionBefore = this.selection.toJSON(); + }; + + this.endOperation = function(e) { + if (this.curOp && this.session) { + if (e && e.returnValue === false || !this.session) + return (this.curOp = null); + if (e == true && this.curOp.command && this.curOp.command.name == "mouse") + return; + this._signal("beforeEndOperation"); + if (!this.curOp) return; + var command = this.curOp.command; + var scrollIntoView = command && command.scrollIntoView; + if (scrollIntoView) { + switch (scrollIntoView) { + case "center-animate": + scrollIntoView = "animate"; + case "center": + this.renderer.scrollCursorIntoView(null, 0.5); + break; + case "animate": + case "cursor": + this.renderer.scrollCursorIntoView(); + break; + case "selectionPart": + var range = this.selection.getRange(); + var config = this.renderer.layerConfig; + if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) { + this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead); + } + break; + default: + break; + } + if (scrollIntoView == "animate") + this.renderer.animateScrolling(this.curOp.scrollTop); + } + var sel = this.selection.toJSON(); + this.curOp.selectionAfter = sel; + this.$lastSel = this.selection.toJSON(); + this.session.getUndoManager().addSelection(sel); + this.prevOp = this.curOp; + this.curOp = null; + } + }; + this.$mergeableCommands = ["backspace", "del", "insertstring"]; + this.$historyTracker = function(e) { + if (!this.$mergeUndoDeltas) + return; + + var prev = this.prevOp; + var mergeableCommands = this.$mergeableCommands; + var shouldMerge = prev.command && (e.command.name == prev.command.name); + if (e.command.name == "insertstring") { + var text = e.args; + if (this.mergeNextCommand === undefined) + this.mergeNextCommand = true; + + shouldMerge = shouldMerge + && this.mergeNextCommand // previous command allows to coalesce with + && (!/\s/.test(text) || /\s/.test(prev.args)); // previous insertion was of same type + + this.mergeNextCommand = true; + } else { + shouldMerge = shouldMerge + && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable + } + + if ( + this.$mergeUndoDeltas != "always" + && Date.now() - this.sequenceStartTime > 2000 + ) { + shouldMerge = false; // the sequence is too long + } + + if (shouldMerge) + this.session.mergeUndoDeltas = true; + else if (mergeableCommands.indexOf(e.command.name) !== -1) + this.sequenceStartTime = Date.now(); + }; + this.setKeyboardHandler = function(keyboardHandler, cb) { + if (keyboardHandler && typeof keyboardHandler === "string" && keyboardHandler != "ace") { + this.$keybindingId = keyboardHandler; + var _self = this; + config.loadModule(["keybinding", keyboardHandler], function(module) { + if (_self.$keybindingId == keyboardHandler) + _self.keyBinding.setKeyboardHandler(module && module.handler); + cb && cb(); + }); + } else { + this.$keybindingId = null; + this.keyBinding.setKeyboardHandler(keyboardHandler); + cb && cb(); + } + }; + this.getKeyboardHandler = function() { + return this.keyBinding.getKeyboardHandler(); + }; + this.setSession = function(session) { + if (this.session == session) + return; + if (this.curOp) this.endOperation(); + this.curOp = {}; + + var oldSession = this.session; + if (oldSession) { + this.session.off("change", this.$onDocumentChange); + this.session.off("changeMode", this.$onChangeMode); + this.session.off("tokenizerUpdate", this.$onTokenizerUpdate); + this.session.off("changeTabSize", this.$onChangeTabSize); + this.session.off("changeWrapLimit", this.$onChangeWrapLimit); + this.session.off("changeWrapMode", this.$onChangeWrapMode); + this.session.off("changeFold", this.$onChangeFold); + this.session.off("changeFrontMarker", this.$onChangeFrontMarker); + this.session.off("changeBackMarker", this.$onChangeBackMarker); + this.session.off("changeBreakpoint", this.$onChangeBreakpoint); + this.session.off("changeAnnotation", this.$onChangeAnnotation); + this.session.off("changeOverwrite", this.$onCursorChange); + this.session.off("changeScrollTop", this.$onScrollTopChange); + this.session.off("changeScrollLeft", this.$onScrollLeftChange); + + var selection = this.session.getSelection(); + selection.off("changeCursor", this.$onCursorChange); + selection.off("changeSelection", this.$onSelectionChange); + } + + this.session = session; + if (session) { + this.$onDocumentChange = this.onDocumentChange.bind(this); + session.on("change", this.$onDocumentChange); + this.renderer.setSession(session); + + this.$onChangeMode = this.onChangeMode.bind(this); + session.on("changeMode", this.$onChangeMode); + + this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this); + session.on("tokenizerUpdate", this.$onTokenizerUpdate); + + this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer); + session.on("changeTabSize", this.$onChangeTabSize); + + this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this); + session.on("changeWrapLimit", this.$onChangeWrapLimit); + + this.$onChangeWrapMode = this.onChangeWrapMode.bind(this); + session.on("changeWrapMode", this.$onChangeWrapMode); + + this.$onChangeFold = this.onChangeFold.bind(this); + session.on("changeFold", this.$onChangeFold); + + this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this); + this.session.on("changeFrontMarker", this.$onChangeFrontMarker); + + this.$onChangeBackMarker = this.onChangeBackMarker.bind(this); + this.session.on("changeBackMarker", this.$onChangeBackMarker); + + this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this); + this.session.on("changeBreakpoint", this.$onChangeBreakpoint); + + this.$onChangeAnnotation = this.onChangeAnnotation.bind(this); + this.session.on("changeAnnotation", this.$onChangeAnnotation); + + this.$onCursorChange = this.onCursorChange.bind(this); + this.session.on("changeOverwrite", this.$onCursorChange); + + this.$onScrollTopChange = this.onScrollTopChange.bind(this); + this.session.on("changeScrollTop", this.$onScrollTopChange); + + this.$onScrollLeftChange = this.onScrollLeftChange.bind(this); + this.session.on("changeScrollLeft", this.$onScrollLeftChange); + + this.selection = session.getSelection(); + this.selection.on("changeCursor", this.$onCursorChange); + + this.$onSelectionChange = this.onSelectionChange.bind(this); + this.selection.on("changeSelection", this.$onSelectionChange); + + this.onChangeMode(); + + this.onCursorChange(); + + this.onScrollTopChange(); + this.onScrollLeftChange(); + this.onSelectionChange(); + this.onChangeFrontMarker(); + this.onChangeBackMarker(); + this.onChangeBreakpoint(); + this.onChangeAnnotation(); + this.session.getUseWrapMode() && this.renderer.adjustWrapLimit(); + this.renderer.updateFull(); + } else { + this.selection = null; + this.renderer.setSession(session); + } + + this._signal("changeSession", { + session: session, + oldSession: oldSession + }); + + this.curOp = null; + + oldSession && oldSession._signal("changeEditor", {oldEditor: this}); + session && session._signal("changeEditor", {editor: this}); + + if (session && session.bgTokenizer) + session.bgTokenizer.scheduleStart(); + }; + this.getSession = function() { + return this.session; + }; + this.setValue = function(val, cursorPos) { + this.session.doc.setValue(val); + + if (!cursorPos) + this.selectAll(); + else if (cursorPos == 1) + this.navigateFileEnd(); + else if (cursorPos == -1) + this.navigateFileStart(); + + return val; + }; + this.getValue = function() { + return this.session.getValue(); + }; + this.getSelection = function() { + return this.selection; + }; + this.resize = function(force) { + this.renderer.onResize(force); + }; + this.setTheme = function(theme, cb) { + this.renderer.setTheme(theme, cb); + }; + this.getTheme = function() { + return this.renderer.getTheme(); + }; + this.setStyle = function(style) { + this.renderer.setStyle(style); + }; + this.unsetStyle = function(style) { + this.renderer.unsetStyle(style); + }; + this.getFontSize = function () { + return this.getOption("fontSize") || + dom.computedStyle(this.container).fontSize; + }; + this.setFontSize = function(size) { + this.setOption("fontSize", size); + }; + + this.$highlightBrackets = function() { + if (this.$highlightPending) { + return; + } + var self = this; + this.$highlightPending = true; + setTimeout(function () { + self.$highlightPending = false; + var session = self.session; + if (!session || !session.bgTokenizer) return; + if (session.$bracketHighlight) { + session.$bracketHighlight.markerIds.forEach(function(id) { + session.removeMarker(id); + }); + session.$bracketHighlight = null; + } + var ranges = session.getMatchingBracketRanges(self.getCursorPosition()); + if (!ranges && session.$mode.getMatching) + ranges = session.$mode.getMatching(self.session); + if (!ranges) + return; + + var markerType = "ace_bracket"; + if (!Array.isArray(ranges)) { + ranges = [ranges]; + } else if (ranges.length == 1) { + markerType = "ace_error_bracket"; + } + if (ranges.length == 2) { + if (Range.comparePoints(ranges[0].end, ranges[1].start) == 0) + ranges = [Range.fromPoints(ranges[0].start, ranges[1].end)]; + else if (Range.comparePoints(ranges[0].start, ranges[1].end) == 0) + ranges = [Range.fromPoints(ranges[1].start, ranges[0].end)]; + } + + session.$bracketHighlight = { + ranges: ranges, + markerIds: ranges.map(function(range) { + return session.addMarker(range, markerType, "text"); + }) + }; + }, 50); + }; + this.$highlightTags = function() { + if (this.$highlightTagPending) + return; + var self = this; + this.$highlightTagPending = true; + setTimeout(function() { + self.$highlightTagPending = false; + + var session = self.session; + if (!session || !session.bgTokenizer) return; + + var pos = self.getCursorPosition(); + var iterator = new TokenIterator(self.session, pos.row, pos.column); + var token = iterator.getCurrentToken(); + + if (!token || !/\b(?:tag-open|tag-name)/.test(token.type)) { + session.removeMarker(session.$tagHighlight); + session.$tagHighlight = null; + return; + } + + if (token.type.indexOf("tag-open") !== -1) { + token = iterator.stepForward(); + if (!token) + return; + } + + var tag = token.value; + var currentTag = token.value; + var depth = 0; + var prevToken = iterator.stepBackward(); + + if (prevToken.value === '<'){ + do { + prevToken = token; + token = iterator.stepForward(); + + if (token) { + if (token.type.indexOf('tag-name') !== -1) { + currentTag = token.value; + if (tag === currentTag) { + if (prevToken.value === '<') { + depth++; + } else if (prevToken.value === '') { // self closing tag + depth--; + } + } + + } while (token && depth >= 0); + } else { + do { + token = prevToken; + prevToken = iterator.stepBackward(); + + if (token) { + if (token.type.indexOf('tag-name') !== -1) { + if (tag === token.value) { + if (prevToken.value === '<') { + depth++; + } else if (prevToken.value === '') { // self closing tag + var stepCount = 0; + var tmpToken = prevToken; + while (tmpToken) { + if (tmpToken.type.indexOf('tag-name') !== -1 && tmpToken.value === tag) { + depth--; + break; + } else if (tmpToken.value === '<') { + break; + } + tmpToken = iterator.stepBackward(); + stepCount++; + } + for (var i = 0; i < stepCount; i++) { + iterator.stepForward(); + } + } + } + } while (prevToken && depth <= 0); + iterator.stepForward(); + } + + if (!token) { + session.removeMarker(session.$tagHighlight); + session.$tagHighlight = null; + return; + } + + var row = iterator.getCurrentTokenRow(); + var column = iterator.getCurrentTokenColumn(); + var range = new Range(row, column, row, column+token.value.length); + var sbm = session.$backMarkers[session.$tagHighlight]; + if (session.$tagHighlight && sbm != undefined && range.compareRange(sbm.range) !== 0) { + session.removeMarker(session.$tagHighlight); + session.$tagHighlight = null; + } + + if (!session.$tagHighlight) + session.$tagHighlight = session.addMarker(range, "ace_bracket", "text"); + }, 50); + }; + this.focus = function() { + var _self = this; + setTimeout(function() { + if (!_self.isFocused()) + _self.textInput.focus(); + }); + this.textInput.focus(); + }; + this.isFocused = function() { + return this.textInput.isFocused(); + }; + this.blur = function() { + this.textInput.blur(); + }; + this.onFocus = function(e) { + if (this.$isFocused) + return; + this.$isFocused = true; + this.renderer.showCursor(); + this.renderer.visualizeFocus(); + this._emit("focus", e); + }; + this.onBlur = function(e) { + if (!this.$isFocused) + return; + this.$isFocused = false; + this.renderer.hideCursor(); + this.renderer.visualizeBlur(); + this._emit("blur", e); + }; + + this.$cursorChange = function() { + this.renderer.updateCursor(); + this.$highlightBrackets(); + this.$highlightTags(); + this.$updateHighlightActiveLine(); + }; + this.onDocumentChange = function(delta) { + var wrap = this.session.$useWrapMode; + var lastRow = (delta.start.row == delta.end.row ? delta.end.row : Infinity); + this.renderer.updateLines(delta.start.row, lastRow, wrap); + + this._signal("change", delta); + this.$cursorChange(); + }; + + this.onTokenizerUpdate = function(e) { + var rows = e.data; + this.renderer.updateLines(rows.first, rows.last); + }; + + + this.onScrollTopChange = function() { + this.renderer.scrollToY(this.session.getScrollTop()); + }; + + this.onScrollLeftChange = function() { + this.renderer.scrollToX(this.session.getScrollLeft()); + }; + this.onCursorChange = function() { + this.$cursorChange(); + this._signal("changeSelection"); + }; + + this.$updateHighlightActiveLine = function() { + var session = this.getSession(); + + var highlight; + if (this.$highlightActiveLine) { + if (this.$selectionStyle != "line" || !this.selection.isMultiLine()) + highlight = this.getCursorPosition(); + if (this.renderer.theme && this.renderer.theme.$selectionColorConflict && !this.selection.isEmpty()) + highlight = false; + if (this.renderer.$maxLines && this.session.getLength() === 1 && !(this.renderer.$minLines > 1)) + highlight = false; + } + + if (session.$highlightLineMarker && !highlight) { + session.removeMarker(session.$highlightLineMarker.id); + session.$highlightLineMarker = null; + } else if (!session.$highlightLineMarker && highlight) { + var range = new Range(highlight.row, highlight.column, highlight.row, Infinity); + range.id = session.addMarker(range, "ace_active-line", "screenLine"); + session.$highlightLineMarker = range; + } else if (highlight) { + session.$highlightLineMarker.start.row = highlight.row; + session.$highlightLineMarker.end.row = highlight.row; + session.$highlightLineMarker.start.column = highlight.column; + session._signal("changeBackMarker"); + } + }; + + this.onSelectionChange = function(e) { + var session = this.session; + + if (session.$selectionMarker) { + session.removeMarker(session.$selectionMarker); + } + session.$selectionMarker = null; + + if (!this.selection.isEmpty()) { + var range = this.selection.getRange(); + var style = this.getSelectionStyle(); + session.$selectionMarker = session.addMarker(range, "ace_selection", style); + } else { + this.$updateHighlightActiveLine(); + } + + var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp(); + this.session.highlight(re); + + this._signal("changeSelection"); + }; + + this.$getSelectionHighLightRegexp = function() { + var session = this.session; + + var selection = this.getSelectionRange(); + if (selection.isEmpty() || selection.isMultiLine()) + return; + + var startColumn = selection.start.column; + var endColumn = selection.end.column; + var line = session.getLine(selection.start.row); + + var needle = line.substring(startColumn, endColumn); + if (needle.length > 5000 || !/[\w\d]/.test(needle)) + return; + + var re = this.$search.$assembleRegExp({ + wholeWord: true, + caseSensitive: true, + needle: needle + }); + + var wordWithBoundary = line.substring(startColumn - 1, endColumn + 1); + if (!re.test(wordWithBoundary)) + return; + + return re; + }; + + + this.onChangeFrontMarker = function() { + this.renderer.updateFrontMarkers(); + }; + + this.onChangeBackMarker = function() { + this.renderer.updateBackMarkers(); + }; + + + this.onChangeBreakpoint = function() { + this.renderer.updateBreakpoints(); + }; + + this.onChangeAnnotation = function() { + this.renderer.setAnnotations(this.session.getAnnotations()); + }; + + + this.onChangeMode = function(e) { + this.renderer.updateText(); + this._emit("changeMode", e); + }; + + + this.onChangeWrapLimit = function() { + this.renderer.updateFull(); + }; + + this.onChangeWrapMode = function() { + this.renderer.onResize(true); + }; + + + this.onChangeFold = function() { + this.$updateHighlightActiveLine(); + this.renderer.updateFull(); + }; + this.getSelectedText = function() { + return this.session.getTextRange(this.getSelectionRange()); + }; + this.getCopyText = function() { + var text = this.getSelectedText(); + var nl = this.session.doc.getNewLineCharacter(); + var copyLine= false; + if (!text && this.$copyWithEmptySelection) { + copyLine = true; + var ranges = this.selection.getAllRanges(); + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (i && ranges[i - 1].start.row == range.start.row) + continue; + text += this.session.getLine(range.start.row) + nl; + } + } + var e = {text: text}; + this._signal("copy", e); + clipboard.lineMode = copyLine ? e.text : ""; + return e.text; + }; + this.onCopy = function() { + this.commands.exec("copy", this); + }; + this.onCut = function() { + this.commands.exec("cut", this); + }; + this.onPaste = function(text, event) { + var e = {text: text, event: event}; + this.commands.exec("paste", this, e); + }; + + this.$handlePaste = function(e) { + if (typeof e == "string") + e = {text: e}; + this._signal("paste", e); + var text = e.text; + + var lineMode = text == clipboard.lineMode; + var session = this.session; + if (!this.inMultiSelectMode || this.inVirtualSelectionMode) { + if (lineMode) + session.insert({ row: this.selection.lead.row, column: 0 }, text); + else + this.insert(text); + } else if (lineMode) { + this.selection.rangeList.ranges.forEach(function(range) { + session.insert({ row: range.start.row, column: 0 }, text); + }); + } else { + var lines = text.split(/\r\n|\r|\n/); + var ranges = this.selection.rangeList.ranges; + + var isFullLine = lines.length == 2 && (!lines[0] || !lines[1]); + if (lines.length != ranges.length || isFullLine) + return this.commands.exec("insertstring", this, text); + + for (var i = ranges.length; i--;) { + var range = ranges[i]; + if (!range.isEmpty()) + session.remove(range); + + session.insert(range.start, lines[i]); + } + } + }; + + this.execCommand = function(command, args) { + return this.commands.exec(command, this, args); + }; + this.insert = function(text, pasted) { + var session = this.session; + var mode = session.getMode(); + var cursor = this.getCursorPosition(); + + if (this.getBehavioursEnabled() && !pasted) { + var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text); + if (transform) { + if (text !== transform.text) { + if (!this.inVirtualSelectionMode) { + this.session.mergeUndoDeltas = false; + this.mergeNextCommand = false; + } + } + text = transform.text; + + } + } + + if (text == "\t") + text = this.session.getTabString(); + if (!this.selection.isEmpty()) { + var range = this.getSelectionRange(); + cursor = this.session.remove(range); + this.clearSelection(); + } + else if (this.session.getOverwrite() && text.indexOf("\n") == -1) { + var range = new Range.fromPoints(cursor, cursor); + range.end.column += text.length; + this.session.remove(range); + } + + if (text == "\n" || text == "\r\n") { + var line = session.getLine(cursor.row); + if (cursor.column > line.search(/\S|$/)) { + var d = line.substr(cursor.column).search(/\S|$/); + session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d); + } + } + this.clearSelection(); + + var start = cursor.column; + var lineState = session.getState(cursor.row); + var line = session.getLine(cursor.row); + var shouldOutdent = mode.checkOutdent(lineState, line, text); + session.insert(cursor, text); + + if (transform && transform.selection) { + if (transform.selection.length == 2) { // Transform relative to the current column + this.selection.setSelectionRange( + new Range(cursor.row, start + transform.selection[0], + cursor.row, start + transform.selection[1])); + } else { // Transform relative to the current row. + this.selection.setSelectionRange( + new Range(cursor.row + transform.selection[0], + transform.selection[1], + cursor.row + transform.selection[2], + transform.selection[3])); + } + } + if (this.$enableAutoIndent) { + if (session.getDocument().isNewLine(text)) { + var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString()); + + session.insert({row: cursor.row+1, column: 0}, lineIndent); + } + if (shouldOutdent) + mode.autoOutdent(lineState, session, cursor.row); + } + }; + + this.autoIndent = function () { + var session = this.session; + var mode = session.getMode(); + + var startRow, endRow; + if (this.selection.isEmpty()) { + startRow = 0; + endRow = session.doc.getLength() - 1; + } else { + var selectedRange = this.getSelectionRange(); + + startRow = selectedRange.start.row; + endRow = selectedRange.end.row; + } + + var prevLineState = ""; + var prevLine = ""; + var lineIndent = ""; + var line, currIndent, range; + var tab = session.getTabString(); + + for (var row = startRow; row <= endRow; row++) { + if (row > 0) { + prevLineState = session.getState(row - 1); + prevLine = session.getLine(row - 1); + lineIndent = mode.getNextLineIndent(prevLineState, prevLine, tab); + } + + line = session.getLine(row); + currIndent = mode.$getIndent(line); + if (lineIndent !== currIndent) { + if (currIndent.length > 0) { + range = new Range(row, 0, row, currIndent.length); + session.remove(range); + } + if (lineIndent.length > 0) { + session.insert({row: row, column: 0}, lineIndent); + } + } + + mode.autoOutdent(prevLineState, session, row); + } + }; + + + this.onTextInput = function(text, composition) { + if (!composition) + return this.keyBinding.onTextInput(text); + + this.startOperation({command: { name: "insertstring" }}); + var applyComposition = this.applyComposition.bind(this, text, composition); + if (this.selection.rangeCount) + this.forEachSelection(applyComposition); + else + applyComposition(); + this.endOperation(); + }; + + this.applyComposition = function(text, composition) { + if (composition.extendLeft || composition.extendRight) { + var r = this.selection.getRange(); + r.start.column -= composition.extendLeft; + r.end.column += composition.extendRight; + if (r.start.column < 0) { + r.start.row--; + r.start.column += this.session.getLine(r.start.row).length + 1; + } + this.selection.setRange(r); + if (!text && !r.isEmpty()) + this.remove(); + } + if (text || !this.selection.isEmpty()) + this.insert(text, true); + if (composition.restoreStart || composition.restoreEnd) { + var r = this.selection.getRange(); + r.start.column -= composition.restoreStart; + r.end.column -= composition.restoreEnd; + this.selection.setRange(r); + } + }; + + this.onCommandKey = function(e, hashId, keyCode) { + return this.keyBinding.onCommandKey(e, hashId, keyCode); + }; + this.setOverwrite = function(overwrite) { + this.session.setOverwrite(overwrite); + }; + this.getOverwrite = function() { + return this.session.getOverwrite(); + }; + this.toggleOverwrite = function() { + this.session.toggleOverwrite(); + }; + this.setScrollSpeed = function(speed) { + this.setOption("scrollSpeed", speed); + }; + this.getScrollSpeed = function() { + return this.getOption("scrollSpeed"); + }; + this.setDragDelay = function(dragDelay) { + this.setOption("dragDelay", dragDelay); + }; + this.getDragDelay = function() { + return this.getOption("dragDelay"); + }; + this.setSelectionStyle = function(val) { + this.setOption("selectionStyle", val); + }; + this.getSelectionStyle = function() { + return this.getOption("selectionStyle"); + }; + this.setHighlightActiveLine = function(shouldHighlight) { + this.setOption("highlightActiveLine", shouldHighlight); + }; + this.getHighlightActiveLine = function() { + return this.getOption("highlightActiveLine"); + }; + this.setHighlightGutterLine = function(shouldHighlight) { + this.setOption("highlightGutterLine", shouldHighlight); + }; + + this.getHighlightGutterLine = function() { + return this.getOption("highlightGutterLine"); + }; + this.setHighlightSelectedWord = function(shouldHighlight) { + this.setOption("highlightSelectedWord", shouldHighlight); + }; + this.getHighlightSelectedWord = function() { + return this.$highlightSelectedWord; + }; + + this.setAnimatedScroll = function(shouldAnimate){ + this.renderer.setAnimatedScroll(shouldAnimate); + }; + + this.getAnimatedScroll = function(){ + return this.renderer.getAnimatedScroll(); + }; + this.setShowInvisibles = function(showInvisibles) { + this.renderer.setShowInvisibles(showInvisibles); + }; + this.getShowInvisibles = function() { + return this.renderer.getShowInvisibles(); + }; + + this.setDisplayIndentGuides = function(display) { + this.renderer.setDisplayIndentGuides(display); + }; + + this.getDisplayIndentGuides = function() { + return this.renderer.getDisplayIndentGuides(); + }; + this.setShowPrintMargin = function(showPrintMargin) { + this.renderer.setShowPrintMargin(showPrintMargin); + }; + this.getShowPrintMargin = function() { + return this.renderer.getShowPrintMargin(); + }; + this.setPrintMarginColumn = function(showPrintMargin) { + this.renderer.setPrintMarginColumn(showPrintMargin); + }; + this.getPrintMarginColumn = function() { + return this.renderer.getPrintMarginColumn(); + }; + this.setReadOnly = function(readOnly) { + this.setOption("readOnly", readOnly); + }; + this.getReadOnly = function() { + return this.getOption("readOnly"); + }; + this.setBehavioursEnabled = function (enabled) { + this.setOption("behavioursEnabled", enabled); + }; + this.getBehavioursEnabled = function () { + return this.getOption("behavioursEnabled"); + }; + this.setWrapBehavioursEnabled = function (enabled) { + this.setOption("wrapBehavioursEnabled", enabled); + }; + this.getWrapBehavioursEnabled = function () { + return this.getOption("wrapBehavioursEnabled"); + }; + this.setShowFoldWidgets = function(show) { + this.setOption("showFoldWidgets", show); + + }; + this.getShowFoldWidgets = function() { + return this.getOption("showFoldWidgets"); + }; + + this.setFadeFoldWidgets = function(fade) { + this.setOption("fadeFoldWidgets", fade); + }; + + this.getFadeFoldWidgets = function() { + return this.getOption("fadeFoldWidgets"); + }; + this.remove = function(dir) { + if (this.selection.isEmpty()){ + if (dir == "left") + this.selection.selectLeft(); + else + this.selection.selectRight(); + } + + var range = this.getSelectionRange(); + if (this.getBehavioursEnabled()) { + var session = this.session; + var state = session.getState(range.start.row); + var new_range = session.getMode().transformAction(state, 'deletion', this, session, range); + + if (range.end.column === 0) { + var text = session.getTextRange(range); + if (text[text.length - 1] == "\n") { + var line = session.getLine(range.end.row); + if (/^\s+$/.test(line)) { + range.end.column = line.length; + } + } + } + if (new_range) + range = new_range; + } + + this.session.remove(range); + this.clearSelection(); + }; + this.removeWordRight = function() { + if (this.selection.isEmpty()) + this.selection.selectWordRight(); + + this.session.remove(this.getSelectionRange()); + this.clearSelection(); + }; + this.removeWordLeft = function() { + if (this.selection.isEmpty()) + this.selection.selectWordLeft(); + + this.session.remove(this.getSelectionRange()); + this.clearSelection(); + }; + this.removeToLineStart = function() { + if (this.selection.isEmpty()) + this.selection.selectLineStart(); + if (this.selection.isEmpty()) + this.selection.selectLeft(); + this.session.remove(this.getSelectionRange()); + this.clearSelection(); + }; + this.removeToLineEnd = function() { + if (this.selection.isEmpty()) + this.selection.selectLineEnd(); + + var range = this.getSelectionRange(); + if (range.start.column == range.end.column && range.start.row == range.end.row) { + range.end.column = 0; + range.end.row++; + } + + this.session.remove(range); + this.clearSelection(); + }; + this.splitLine = function() { + if (!this.selection.isEmpty()) { + this.session.remove(this.getSelectionRange()); + this.clearSelection(); + } + + var cursor = this.getCursorPosition(); + this.insert("\n"); + this.moveCursorToPosition(cursor); + }; + this.transposeLetters = function() { + if (!this.selection.isEmpty()) { + return; + } + + var cursor = this.getCursorPosition(); + var column = cursor.column; + if (column === 0) + return; + + var line = this.session.getLine(cursor.row); + var swap, range; + if (column < line.length) { + swap = line.charAt(column) + line.charAt(column-1); + range = new Range(cursor.row, column-1, cursor.row, column+1); + } + else { + swap = line.charAt(column-1) + line.charAt(column-2); + range = new Range(cursor.row, column-2, cursor.row, column); + } + this.session.replace(range, swap); + this.session.selection.moveToPosition(range.end); + }; + this.toLowerCase = function() { + var originalRange = this.getSelectionRange(); + if (this.selection.isEmpty()) { + this.selection.selectWord(); + } + + var range = this.getSelectionRange(); + var text = this.session.getTextRange(range); + this.session.replace(range, text.toLowerCase()); + this.selection.setSelectionRange(originalRange); + }; + this.toUpperCase = function() { + var originalRange = this.getSelectionRange(); + if (this.selection.isEmpty()) { + this.selection.selectWord(); + } + + var range = this.getSelectionRange(); + var text = this.session.getTextRange(range); + this.session.replace(range, text.toUpperCase()); + this.selection.setSelectionRange(originalRange); + }; + this.indent = function() { + var session = this.session; + var range = this.getSelectionRange(); + + if (range.start.row < range.end.row) { + var rows = this.$getSelectedRows(); + session.indentRows(rows.first, rows.last, "\t"); + return; + } else if (range.start.column < range.end.column) { + var text = session.getTextRange(range); + if (!/^\s+$/.test(text)) { + var rows = this.$getSelectedRows(); + session.indentRows(rows.first, rows.last, "\t"); + return; + } + } + + var line = session.getLine(range.start.row); + var position = range.start; + var size = session.getTabSize(); + var column = session.documentToScreenColumn(position.row, position.column); + + if (this.session.getUseSoftTabs()) { + var count = (size - column % size); + var indentString = lang.stringRepeat(" ", count); + } else { + var count = column % size; + while (line[range.start.column - 1] == " " && count) { + range.start.column--; + count--; + } + this.selection.setSelectionRange(range); + indentString = "\t"; + } + return this.insert(indentString); + }; + this.blockIndent = function() { + var rows = this.$getSelectedRows(); + this.session.indentRows(rows.first, rows.last, "\t"); + }; + this.blockOutdent = function() { + var selection = this.session.getSelection(); + this.session.outdentRows(selection.getRange()); + }; + this.sortLines = function() { + var rows = this.$getSelectedRows(); + var session = this.session; + + var lines = []; + for (var i = rows.first; i <= rows.last; i++) + lines.push(session.getLine(i)); + + lines.sort(function(a, b) { + if (a.toLowerCase() < b.toLowerCase()) return -1; + if (a.toLowerCase() > b.toLowerCase()) return 1; + return 0; + }); + + var deleteRange = new Range(0, 0, 0, 0); + for (var i = rows.first; i <= rows.last; i++) { + var line = session.getLine(i); + deleteRange.start.row = i; + deleteRange.end.row = i; + deleteRange.end.column = line.length; + session.replace(deleteRange, lines[i-rows.first]); + } + }; + this.toggleCommentLines = function() { + var state = this.session.getState(this.getCursorPosition().row); + var rows = this.$getSelectedRows(); + this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last); + }; + + this.toggleBlockComment = function() { + var cursor = this.getCursorPosition(); + var state = this.session.getState(cursor.row); + var range = this.getSelectionRange(); + this.session.getMode().toggleBlockComment(state, this.session, range, cursor); + }; + this.getNumberAt = function(row, column) { + var _numberRx = /[\-]?[0-9]+(?:\.[0-9]+)?/g; + _numberRx.lastIndex = 0; + + var s = this.session.getLine(row); + while (_numberRx.lastIndex < column) { + var m = _numberRx.exec(s); + if(m.index <= column && m.index+m[0].length >= column){ + var number = { + value: m[0], + start: m.index, + end: m.index+m[0].length + }; + return number; + } + } + return null; + }; + this.modifyNumber = function(amount) { + var row = this.selection.getCursor().row; + var column = this.selection.getCursor().column; + var charRange = new Range(row, column-1, row, column); + + var c = this.session.getTextRange(charRange); + if (!isNaN(parseFloat(c)) && isFinite(c)) { + var nr = this.getNumberAt(row, column); + if (nr) { + var fp = nr.value.indexOf(".") >= 0 ? nr.start + nr.value.indexOf(".") + 1 : nr.end; + var decimals = nr.start + nr.value.length - fp; + + var t = parseFloat(nr.value); + t *= Math.pow(10, decimals); + + + if(fp !== nr.end && column < fp){ + amount *= Math.pow(10, nr.end - column - 1); + } else { + amount *= Math.pow(10, nr.end - column); + } + + t += amount; + t /= Math.pow(10, decimals); + var nnr = t.toFixed(decimals); + var replaceRange = new Range(row, nr.start, row, nr.end); + this.session.replace(replaceRange, nnr); + this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length)); + + } + } else { + this.toggleWord(); + } + }; + + this.$toggleWordPairs = [ + ["first", "last"], + ["true", "false"], + ["yes", "no"], + ["width", "height"], + ["top", "bottom"], + ["right", "left"], + ["on", "off"], + ["x", "y"], + ["get", "set"], + ["max", "min"], + ["horizontal", "vertical"], + ["show", "hide"], + ["add", "remove"], + ["up", "down"], + ["before", "after"], + ["even", "odd"], + ["in", "out"], + ["inside", "outside"], + ["next", "previous"], + ["increase", "decrease"], + ["attach", "detach"], + ["&&", "||"], + ["==", "!="] + ]; + + this.toggleWord = function () { + var row = this.selection.getCursor().row; + var column = this.selection.getCursor().column; + this.selection.selectWord(); + var currentState = this.getSelectedText(); + var currWordStart = this.selection.getWordRange().start.column; + var wordParts = currentState.replace(/([a-z]+|[A-Z]+)(?=[A-Z_]|$)/g, '$1 ').split(/\s/); + var delta = column - currWordStart - 1; + if (delta < 0) delta = 0; + var curLength = 0, itLength = 0; + var that = this; + if (currentState.match(/[A-Za-z0-9_]+/)) { + wordParts.forEach(function (item, i) { + itLength = curLength + item.length; + if (delta >= curLength && delta <= itLength) { + currentState = item; + that.selection.clearSelection(); + that.moveCursorTo(row, curLength + currWordStart); + that.selection.selectTo(row, itLength + currWordStart); + } + curLength = itLength; + }); + } + + var wordPairs = this.$toggleWordPairs; + var reg; + for (var i = 0; i < wordPairs.length; i++) { + var item = wordPairs[i]; + for (var j = 0; j <= 1; j++) { + var negate = +!j; + var firstCondition = currentState.match(new RegExp('^\\s?_?(' + lang.escapeRegExp(item[j]) + ')\\s?$', 'i')); + if (firstCondition) { + var secondCondition = currentState.match(new RegExp('([_]|^|\\s)(' + lang.escapeRegExp(firstCondition[1]) + ')($|\\s)', 'g')); + if (secondCondition) { + reg = currentState.replace(new RegExp(lang.escapeRegExp(item[j]), 'i'), function (result) { + var res = item[negate]; + if (result.toUpperCase() == result) { + res = res.toUpperCase(); + } else if (result.charAt(0).toUpperCase() == result.charAt(0)) { + res = res.substr(0, 0) + item[negate].charAt(0).toUpperCase() + res.substr(1); + } + return res; + }); + this.insert(reg); + reg = ""; + } + } + } + } + }; + this.removeLines = function() { + var rows = this.$getSelectedRows(); + this.session.removeFullLines(rows.first, rows.last); + this.clearSelection(); + }; + + this.duplicateSelection = function() { + var sel = this.selection; + var doc = this.session; + var range = sel.getRange(); + var reverse = sel.isBackwards(); + if (range.isEmpty()) { + var row = range.start.row; + doc.duplicateLines(row, row); + } else { + var point = reverse ? range.start : range.end; + var endPoint = doc.insert(point, doc.getTextRange(range), false); + range.start = point; + range.end = endPoint; + + sel.setSelectionRange(range, reverse); + } + }; + this.moveLinesDown = function() { + this.$moveLines(1, false); + }; + this.moveLinesUp = function() { + this.$moveLines(-1, false); + }; + this.moveText = function(range, toPosition, copy) { + return this.session.moveText(range, toPosition, copy); + }; + this.copyLinesUp = function() { + this.$moveLines(-1, true); + }; + this.copyLinesDown = function() { + this.$moveLines(1, true); + }; + this.$moveLines = function(dir, copy) { + var rows, moved; + var selection = this.selection; + if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) { + var range = selection.toOrientedRange(); + rows = this.$getSelectedRows(range); + moved = this.session.$moveLines(rows.first, rows.last, copy ? 0 : dir); + if (copy && dir == -1) moved = 0; + range.moveBy(moved, 0); + selection.fromOrientedRange(range); + } else { + var ranges = selection.rangeList.ranges; + selection.rangeList.detach(this.session); + this.inVirtualSelectionMode = true; + + var diff = 0; + var totalDiff = 0; + var l = ranges.length; + for (var i = 0; i < l; i++) { + var rangeIndex = i; + ranges[i].moveBy(diff, 0); + rows = this.$getSelectedRows(ranges[i]); + var first = rows.first; + var last = rows.last; + while (++i < l) { + if (totalDiff) ranges[i].moveBy(totalDiff, 0); + var subRows = this.$getSelectedRows(ranges[i]); + if (copy && subRows.first != last) + break; + else if (!copy && subRows.first > last + 1) + break; + last = subRows.last; + } + i--; + diff = this.session.$moveLines(first, last, copy ? 0 : dir); + if (copy && dir == -1) rangeIndex = i + 1; + while (rangeIndex <= i) { + ranges[rangeIndex].moveBy(diff, 0); + rangeIndex++; + } + if (!copy) diff = 0; + totalDiff += diff; + } + + selection.fromOrientedRange(selection.ranges[0]); + selection.rangeList.attach(this.session); + this.inVirtualSelectionMode = false; + } + }; + this.$getSelectedRows = function(range) { + range = (range || this.getSelectionRange()).collapseRows(); + + return { + first: this.session.getRowFoldStart(range.start.row), + last: this.session.getRowFoldEnd(range.end.row) + }; + }; + + this.onCompositionStart = function(compositionState) { + this.renderer.showComposition(compositionState); + }; + + this.onCompositionUpdate = function(text) { + this.renderer.setCompositionText(text); + }; + + this.onCompositionEnd = function() { + this.renderer.hideComposition(); + }; + this.getFirstVisibleRow = function() { + return this.renderer.getFirstVisibleRow(); + }; + this.getLastVisibleRow = function() { + return this.renderer.getLastVisibleRow(); + }; + this.isRowVisible = function(row) { + return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow()); + }; + this.isRowFullyVisible = function(row) { + return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow()); + }; + this.$getVisibleRowCount = function() { + return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1; + }; + + this.$moveByPage = function(dir, select) { + var renderer = this.renderer; + var config = this.renderer.layerConfig; + var rows = dir * Math.floor(config.height / config.lineHeight); + + if (select === true) { + this.selection.$moveSelection(function(){ + this.moveCursorBy(rows, 0); + }); + } else if (select === false) { + this.selection.moveCursorBy(rows, 0); + this.selection.clearSelection(); + } + + var scrollTop = renderer.scrollTop; + + renderer.scrollBy(0, rows * config.lineHeight); + if (select != null) + renderer.scrollCursorIntoView(null, 0.5); + + renderer.animateScrolling(scrollTop); + }; + this.selectPageDown = function() { + this.$moveByPage(1, true); + }; + this.selectPageUp = function() { + this.$moveByPage(-1, true); + }; + this.gotoPageDown = function() { + this.$moveByPage(1, false); + }; + this.gotoPageUp = function() { + this.$moveByPage(-1, false); + }; + this.scrollPageDown = function() { + this.$moveByPage(1); + }; + this.scrollPageUp = function() { + this.$moveByPage(-1); + }; + this.scrollToRow = function(row) { + this.renderer.scrollToRow(row); + }; + this.scrollToLine = function(line, center, animate, callback) { + this.renderer.scrollToLine(line, center, animate, callback); + }; + this.centerSelection = function() { + var range = this.getSelectionRange(); + var pos = { + row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2), + column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2) + }; + this.renderer.alignCursor(pos, 0.5); + }; + this.getCursorPosition = function() { + return this.selection.getCursor(); + }; + this.getCursorPositionScreen = function() { + return this.session.documentToScreenPosition(this.getCursorPosition()); + }; + this.getSelectionRange = function() { + return this.selection.getRange(); + }; + this.selectAll = function() { + this.selection.selectAll(); + }; + this.clearSelection = function() { + this.selection.clearSelection(); + }; + this.moveCursorTo = function(row, column) { + this.selection.moveCursorTo(row, column); + }; + this.moveCursorToPosition = function(pos) { + this.selection.moveCursorToPosition(pos); + }; + this.jumpToMatching = function(select, expand) { + var cursor = this.getCursorPosition(); + var iterator = new TokenIterator(this.session, cursor.row, cursor.column); + var prevToken = iterator.getCurrentToken(); + var token = prevToken || iterator.stepForward(); + + if (!token) return; + var matchType; + var found = false; + var depth = {}; + var i = cursor.column - token.start; + var bracketType; + var brackets = { + ")": "(", + "(": "(", + "]": "[", + "[": "[", + "{": "{", + "}": "{" + }; + + do { + if (token.value.match(/[{}()\[\]]/g)) { + for (; i < token.value.length && !found; i++) { + if (!brackets[token.value[i]]) { + continue; + } + + bracketType = brackets[token.value[i]] + '.' + token.type.replace("rparen", "lparen"); + + if (isNaN(depth[bracketType])) { + depth[bracketType] = 0; + } + + switch (token.value[i]) { + case '(': + case '[': + case '{': + depth[bracketType]++; + break; + case ')': + case ']': + case '}': + depth[bracketType]--; + + if (depth[bracketType] === -1) { + matchType = 'bracket'; + found = true; + } + break; + } + } + } + else if (token.type.indexOf('tag-name') !== -1) { + if (isNaN(depth[token.value])) { + depth[token.value] = 0; + } + + if (prevToken.value === '<') { + depth[token.value]++; + } + else if (prevToken.value === '= 0; --i) { + if(this.$tryReplace(ranges[i], replacement)) { + replaced++; + } + } + + this.selection.setSelectionRange(selection); + + return replaced; + }; + + this.$tryReplace = function(range, replacement) { + var input = this.session.getTextRange(range); + replacement = this.$search.replace(input, replacement); + if (replacement !== null) { + range.end = this.session.replace(range, replacement); + return range; + } else { + return null; + } + }; + this.getLastSearchOptions = function() { + return this.$search.getOptions(); + }; + this.find = function(needle, options, animate) { + if (!options) + options = {}; + + if (typeof needle == "string" || needle instanceof RegExp) + options.needle = needle; + else if (typeof needle == "object") + oop.mixin(options, needle); + + var range = this.selection.getRange(); + if (options.needle == null) { + needle = this.session.getTextRange(range) + || this.$search.$options.needle; + if (!needle) { + range = this.session.getWordRange(range.start.row, range.start.column); + needle = this.session.getTextRange(range); + } + this.$search.set({needle: needle}); + } + + this.$search.set(options); + if (!options.start) + this.$search.set({start: range}); + + var newRange = this.$search.find(this.session); + if (options.preventScroll) + return newRange; + if (newRange) { + this.revealRange(newRange, animate); + return newRange; + } + if (options.backwards) + range.start = range.end; + else + range.end = range.start; + this.selection.setRange(range); + }; + this.findNext = function(options, animate) { + this.find({skipCurrent: true, backwards: false}, options, animate); + }; + this.findPrevious = function(options, animate) { + this.find(options, {skipCurrent: true, backwards: true}, animate); + }; + + this.revealRange = function(range, animate) { + this.session.unfold(range); + this.selection.setSelectionRange(range); + + var scrollTop = this.renderer.scrollTop; + this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5); + if (animate !== false) + this.renderer.animateScrolling(scrollTop); + }; + this.undo = function() { + this.session.getUndoManager().undo(this.session); + this.renderer.scrollCursorIntoView(null, 0.5); + }; + this.redo = function() { + this.session.getUndoManager().redo(this.session); + this.renderer.scrollCursorIntoView(null, 0.5); + }; + this.destroy = function() { + if (this.$toDestroy) { + this.$toDestroy.forEach(function(el) { + el.destroy(); + }); + this.$toDestroy = null; + } + if (this.$mouseHandler) + this.$mouseHandler.destroy(); + this.renderer.destroy(); + this._signal("destroy", this); + if (this.session) + this.session.destroy(); + if (this._$emitInputEvent) + this._$emitInputEvent.cancel(); + this.removeAllListeners(); + }; + this.setAutoScrollEditorIntoView = function(enable) { + if (!enable) + return; + var rect; + var self = this; + var shouldScroll = false; + if (!this.$scrollAnchor) + this.$scrollAnchor = document.createElement("div"); + var scrollAnchor = this.$scrollAnchor; + scrollAnchor.style.cssText = "position:absolute"; + this.container.insertBefore(scrollAnchor, this.container.firstChild); + var onChangeSelection = this.on("changeSelection", function() { + shouldScroll = true; + }); + var onBeforeRender = this.renderer.on("beforeRender", function() { + if (shouldScroll) + rect = self.renderer.container.getBoundingClientRect(); + }); + var onAfterRender = this.renderer.on("afterRender", function() { + if (shouldScroll && rect && (self.isFocused() + || self.searchBox && self.searchBox.isFocused()) + ) { + var renderer = self.renderer; + var pos = renderer.$cursorLayer.$pixelPos; + var config = renderer.layerConfig; + var top = pos.top - config.offset; + if (pos.top >= 0 && top + rect.top < 0) { + shouldScroll = true; + } else if (pos.top < config.height && + pos.top + rect.top + config.lineHeight > window.innerHeight) { + shouldScroll = false; + } else { + shouldScroll = null; + } + if (shouldScroll != null) { + scrollAnchor.style.top = top + "px"; + scrollAnchor.style.left = pos.left + "px"; + scrollAnchor.style.height = config.lineHeight + "px"; + scrollAnchor.scrollIntoView(shouldScroll); + } + shouldScroll = rect = null; + } + }); + this.setAutoScrollEditorIntoView = function(enable) { + if (enable) + return; + delete this.setAutoScrollEditorIntoView; + this.off("changeSelection", onChangeSelection); + this.renderer.off("afterRender", onAfterRender); + this.renderer.off("beforeRender", onBeforeRender); + }; + }; + + + this.$resetCursorStyle = function() { + var style = this.$cursorStyle || "ace"; + var cursorLayer = this.renderer.$cursorLayer; + if (!cursorLayer) + return; + cursorLayer.setSmoothBlinking(/smooth/.test(style)); + cursorLayer.isBlinking = !this.$readOnly && style != "wide"; + dom.setCssClass(cursorLayer.element, "ace_slim-cursors", /slim/.test(style)); + }; + this.prompt = function(message, options, callback) { + var editor = this; + config.loadModule("./ext/prompt", function (module) { + module.prompt(editor, message, options, callback); + }); + }; + +}).call(Editor.prototype); + + + +config.defineOptions(Editor.prototype, "editor", { + selectionStyle: { + set: function(style) { + this.onSelectionChange(); + this._signal("changeSelectionStyle", {data: style}); + }, + initialValue: "line" + }, + highlightActiveLine: { + set: function() {this.$updateHighlightActiveLine();}, + initialValue: true + }, + highlightSelectedWord: { + set: function(shouldHighlight) {this.$onSelectionChange();}, + initialValue: true + }, + readOnly: { + set: function(readOnly) { + this.textInput.setReadOnly(readOnly); + this.$resetCursorStyle(); + }, + initialValue: false + }, + copyWithEmptySelection: { + set: function(value) { + this.textInput.setCopyWithEmptySelection(value); + }, + initialValue: false + }, + cursorStyle: { + set: function(val) { this.$resetCursorStyle(); }, + values: ["ace", "slim", "smooth", "wide"], + initialValue: "ace" + }, + mergeUndoDeltas: { + values: [false, true, "always"], + initialValue: true + }, + behavioursEnabled: {initialValue: true}, + wrapBehavioursEnabled: {initialValue: true}, + enableAutoIndent: {initialValue: true}, + autoScrollEditorIntoView: { + set: function(val) {this.setAutoScrollEditorIntoView(val);} + }, + keyboardHandler: { + set: function(val) { this.setKeyboardHandler(val); }, + get: function() { return this.$keybindingId; }, + handlesSet: true + }, + value: { + set: function(val) { this.session.setValue(val); }, + get: function() { return this.getValue(); }, + handlesSet: true, + hidden: true + }, + session: { + set: function(val) { this.setSession(val); }, + get: function() { return this.session; }, + handlesSet: true, + hidden: true + }, + + showLineNumbers: { + set: function(show) { + this.renderer.$gutterLayer.setShowLineNumbers(show); + this.renderer.$loop.schedule(this.renderer.CHANGE_GUTTER); + if (show && this.$relativeLineNumbers) + relativeNumberRenderer.attach(this); + else + relativeNumberRenderer.detach(this); + }, + initialValue: true + }, + relativeLineNumbers: { + set: function(value) { + if (this.$showLineNumbers && value) + relativeNumberRenderer.attach(this); + else + relativeNumberRenderer.detach(this); + } + }, + placeholder: { + set: function(message) { + if (!this.$updatePlaceholder) { + this.$updatePlaceholder = function() { + var value = this.session && (this.renderer.$composition || this.getValue()); + if (value && this.renderer.placeholderNode) { + this.renderer.off("afterRender", this.$updatePlaceholder); + dom.removeCssClass(this.container, "ace_hasPlaceholder"); + this.renderer.placeholderNode.remove(); + this.renderer.placeholderNode = null; + } else if (!value && !this.renderer.placeholderNode) { + this.renderer.on("afterRender", this.$updatePlaceholder); + dom.addCssClass(this.container, "ace_hasPlaceholder"); + var el = dom.createElement("div"); + el.className = "ace_placeholder"; + el.textContent = this.$placeholder || ""; + this.renderer.placeholderNode = el; + this.renderer.content.appendChild(this.renderer.placeholderNode); + } else if (!value && this.renderer.placeholderNode) { + this.renderer.placeholderNode.textContent = this.$placeholder || ""; + } + }.bind(this); + this.on("input", this.$updatePlaceholder); + } + this.$updatePlaceholder(); + } + }, + + hScrollBarAlwaysVisible: "renderer", + vScrollBarAlwaysVisible: "renderer", + highlightGutterLine: "renderer", + animatedScroll: "renderer", + showInvisibles: "renderer", + showPrintMargin: "renderer", + printMarginColumn: "renderer", + printMargin: "renderer", + fadeFoldWidgets: "renderer", + showFoldWidgets: "renderer", + displayIndentGuides: "renderer", + showGutter: "renderer", + fontSize: "renderer", + fontFamily: "renderer", + maxLines: "renderer", + minLines: "renderer", + scrollPastEnd: "renderer", + fixedWidthGutter: "renderer", + theme: "renderer", + hasCssTransforms: "renderer", + maxPixelHeight: "renderer", + useTextareaForIME: "renderer", + + scrollSpeed: "$mouseHandler", + dragDelay: "$mouseHandler", + dragEnabled: "$mouseHandler", + focusTimeout: "$mouseHandler", + tooltipFollowsMouse: "$mouseHandler", + + firstLineNumber: "session", + overwrite: "session", + newLineMode: "session", + useWorker: "session", + useSoftTabs: "session", + navigateWithinSoftTabs: "session", + tabSize: "session", + wrap: "session", + indentedSoftWrap: "session", + foldStyle: "session", + mode: "session" +}); + + +var relativeNumberRenderer = { + getText: function(session, row) { + return (Math.abs(session.selection.lead.row - row) || (row + 1 + (row < 9 ? "\xb7" : ""))) + ""; + }, + getWidth: function(session, lastLineNumber, config) { + return Math.max( + lastLineNumber.toString().length, + (config.lastRow + 1).toString().length, + 2 + ) * config.characterWidth; + }, + update: function(e, editor) { + editor.renderer.$loop.schedule(editor.renderer.CHANGE_GUTTER); + }, + attach: function(editor) { + editor.renderer.$gutterLayer.$renderer = this; + editor.on("changeSelection", this.update); + this.update(null, editor); + }, + detach: function(editor) { + if (editor.renderer.$gutterLayer.$renderer == this) + editor.renderer.$gutterLayer.$renderer = null; + editor.off("changeSelection", this.update); + this.update(null, editor); + } +}; + +exports.Editor = Editor; +}); + +ace.define("ace/undomanager",["require","exports","module","ace/range"], function(require, exports, module) { +"use strict"; +var UndoManager = function() { + this.$maxRev = 0; + this.$fromUndo = false; + this.reset(); +}; + +(function() { + + this.addSession = function(session) { + this.$session = session; + }; + this.add = function(delta, allowMerge, session) { + if (this.$fromUndo) return; + if (delta == this.$lastDelta) return; + if (!this.$keepRedoStack) this.$redoStack.length = 0; + if (allowMerge === false || !this.lastDeltas) { + this.lastDeltas = []; + this.$undoStack.push(this.lastDeltas); + delta.id = this.$rev = ++this.$maxRev; + } + if (delta.action == "remove" || delta.action == "insert") + this.$lastDelta = delta; + this.lastDeltas.push(delta); + }; + + this.addSelection = function(selection, rev) { + this.selections.push({ + value: selection, + rev: rev || this.$rev + }); + }; + + this.startNewGroup = function() { + this.lastDeltas = null; + return this.$rev; + }; + + this.markIgnored = function(from, to) { + if (to == null) to = this.$rev + 1; + var stack = this.$undoStack; + for (var i = stack.length; i--;) { + var delta = stack[i][0]; + if (delta.id <= from) + break; + if (delta.id < to) + delta.ignore = true; + } + this.lastDeltas = null; + }; + + this.getSelection = function(rev, after) { + var stack = this.selections; + for (var i = stack.length; i--;) { + var selection = stack[i]; + if (selection.rev < rev) { + if (after) + selection = stack[i + 1]; + return selection; + } + } + }; + + this.getRevision = function() { + return this.$rev; + }; + + this.getDeltas = function(from, to) { + if (to == null) to = this.$rev + 1; + var stack = this.$undoStack; + var end = null, start = 0; + for (var i = stack.length; i--;) { + var delta = stack[i][0]; + if (delta.id < to && !end) + end = i+1; + if (delta.id <= from) { + start = i + 1; + break; + } + } + return stack.slice(start, end); + }; + + this.getChangedRanges = function(from, to) { + if (to == null) to = this.$rev + 1; + + }; + + this.getChangedLines = function(from, to) { + if (to == null) to = this.$rev + 1; + + }; + this.undo = function(session, dontSelect) { + this.lastDeltas = null; + var stack = this.$undoStack; + + if (!rearrangeUndoStack(stack, stack.length)) + return; + + if (!session) + session = this.$session; + + if (this.$redoStackBaseRev !== this.$rev && this.$redoStack.length) + this.$redoStack = []; + + this.$fromUndo = true; + + var deltaSet = stack.pop(); + var undoSelectionRange = null; + if (deltaSet) { + undoSelectionRange = session.undoChanges(deltaSet, dontSelect); + this.$redoStack.push(deltaSet); + this.$syncRev(); + } + + this.$fromUndo = false; + + return undoSelectionRange; + }; + this.redo = function(session, dontSelect) { + this.lastDeltas = null; + + if (!session) + session = this.$session; + + this.$fromUndo = true; + if (this.$redoStackBaseRev != this.$rev) { + var diff = this.getDeltas(this.$redoStackBaseRev, this.$rev + 1); + rebaseRedoStack(this.$redoStack, diff); + this.$redoStackBaseRev = this.$rev; + this.$redoStack.forEach(function(x) { + x[0].id = ++this.$maxRev; + }, this); + } + var deltaSet = this.$redoStack.pop(); + var redoSelectionRange = null; + + if (deltaSet) { + redoSelectionRange = session.redoChanges(deltaSet, dontSelect); + this.$undoStack.push(deltaSet); + this.$syncRev(); + } + this.$fromUndo = false; + + return redoSelectionRange; + }; + + this.$syncRev = function() { + var stack = this.$undoStack; + var nextDelta = stack[stack.length - 1]; + var id = nextDelta && nextDelta[0].id || 0; + this.$redoStackBaseRev = id; + this.$rev = id; + }; + this.reset = function() { + this.lastDeltas = null; + this.$lastDelta = null; + this.$undoStack = []; + this.$redoStack = []; + this.$rev = 0; + this.mark = 0; + this.$redoStackBaseRev = this.$rev; + this.selections = []; + }; + this.canUndo = function() { + return this.$undoStack.length > 0; + }; + this.canRedo = function() { + return this.$redoStack.length > 0; + }; + this.bookmark = function(rev) { + if (rev == undefined) + rev = this.$rev; + this.mark = rev; + }; + this.isAtBookmark = function() { + return this.$rev === this.mark; + }; + + this.toJSON = function() { + + }; + + this.fromJSON = function() { + + }; + + this.hasUndo = this.canUndo; + this.hasRedo = this.canRedo; + this.isClean = this.isAtBookmark; + this.markClean = this.bookmark; + + this.$prettyPrint = function(delta) { + if (delta) return stringifyDelta(delta); + return stringifyDelta(this.$undoStack) + "\n---\n" + stringifyDelta(this.$redoStack); + }; +}).call(UndoManager.prototype); + +function rearrangeUndoStack(stack, pos) { + for (var i = pos; i--; ) { + var deltaSet = stack[i]; + if (deltaSet && !deltaSet[0].ignore) { + while(i < pos - 1) { + var swapped = swapGroups(stack[i], stack[i + 1]); + stack[i] = swapped[0]; + stack[i + 1] = swapped[1]; + i++; + } + return true; + } + } +} + +var Range = require("./range").Range; +var cmp = Range.comparePoints; +var comparePoints = Range.comparePoints; + +function $updateMarkers(delta) { + var isInsert = delta.action == "insert"; + var start = delta.start; + var end = delta.end; + var rowShift = (end.row - start.row) * (isInsert ? 1 : -1); + var colShift = (end.column - start.column) * (isInsert ? 1 : -1); + if (isInsert) end = start; + + for (var i in this.marks) { + var point = this.marks[i]; + var cmp = comparePoints(point, start); + if (cmp < 0) { + continue; // delta starts after the range + } + if (cmp === 0) { + if (isInsert) { + if (point.bias == 1) { + cmp = 1; + } + else { + point.bias == -1; + continue; + } + } + } + var cmp2 = isInsert ? cmp : comparePoints(point, end); + if (cmp2 > 0) { + point.row += rowShift; + point.column += point.row == end.row ? colShift : 0; + continue; + } + if (!isInsert && cmp2 <= 0) { + point.row = start.row; + point.column = start.column; + if (cmp2 === 0) + point.bias = 1; + } + } +} + + + +function clonePos(pos) { + return {row: pos.row,column: pos.column}; +} +function cloneDelta(d) { + return { + start: clonePos(d.start), + end: clonePos(d.end), + action: d.action, + lines: d.lines.slice() + }; +} +function stringifyDelta(d) { + d = d || this; + if (Array.isArray(d)) { + return d.map(stringifyDelta).join("\n"); + } + var type = ""; + if (d.action) { + type = d.action == "insert" ? "+" : "-"; + type += "[" + d.lines + "]"; + } else if (d.value) { + if (Array.isArray(d.value)) { + type = d.value.map(stringifyRange).join("\n"); + } else { + type = stringifyRange(d.value); + } + } + if (d.start) { + type += stringifyRange(d); + } + if (d.id || d.rev) { + type += "\t(" + (d.id || d.rev) + ")"; + } + return type; +} +function stringifyRange(r) { + return r.start.row + ":" + r.start.column + + "=>" + r.end.row + ":" + r.end.column; +} + +function swap(d1, d2) { + var i1 = d1.action == "insert"; + var i2 = d2.action == "insert"; + + if (i1 && i2) { + if (cmp(d2.start, d1.end) >= 0) { + shift(d2, d1, -1); + } else if (cmp(d2.start, d1.start) <= 0) { + shift(d1, d2, +1); + } else { + return null; + } + } else if (i1 && !i2) { + if (cmp(d2.start, d1.end) >= 0) { + shift(d2, d1, -1); + } else if (cmp(d2.end, d1.start) <= 0) { + shift(d1, d2, -1); + } else { + return null; + } + } else if (!i1 && i2) { + if (cmp(d2.start, d1.start) >= 0) { + shift(d2, d1, +1); + } else if (cmp(d2.start, d1.start) <= 0) { + shift(d1, d2, +1); + } else { + return null; + } + } else if (!i1 && !i2) { + if (cmp(d2.start, d1.start) >= 0) { + shift(d2, d1, +1); + } else if (cmp(d2.end, d1.start) <= 0) { + shift(d1, d2, -1); + } else { + return null; + } + } + return [d2, d1]; +} +function swapGroups(ds1, ds2) { + for (var i = ds1.length; i--; ) { + for (var j = 0; j < ds2.length; j++) { + if (!swap(ds1[i], ds2[j])) { + while (i < ds1.length) { + while (j--) { + swap(ds2[j], ds1[i]); + } + j = ds2.length; + i++; + } + return [ds1, ds2]; + } + } + } + ds1.selectionBefore = ds2.selectionBefore = + ds1.selectionAfter = ds2.selectionAfter = null; + return [ds2, ds1]; +} +function xform(d1, c1) { + var i1 = d1.action == "insert"; + var i2 = c1.action == "insert"; + + if (i1 && i2) { + if (cmp(d1.start, c1.start) < 0) { + shift(c1, d1, 1); + } else { + shift(d1, c1, 1); + } + } else if (i1 && !i2) { + if (cmp(d1.start, c1.end) >= 0) { + shift(d1, c1, -1); + } else if (cmp(d1.start, c1.start) <= 0) { + shift(c1, d1, +1); + } else { + shift(d1, Range.fromPoints(c1.start, d1.start), -1); + shift(c1, d1, +1); + } + } else if (!i1 && i2) { + if (cmp(c1.start, d1.end) >= 0) { + shift(c1, d1, -1); + } else if (cmp(c1.start, d1.start) <= 0) { + shift(d1, c1, +1); + } else { + shift(c1, Range.fromPoints(d1.start, c1.start), -1); + shift(d1, c1, +1); + } + } else if (!i1 && !i2) { + if (cmp(c1.start, d1.end) >= 0) { + shift(c1, d1, -1); + } else if (cmp(c1.end, d1.start) <= 0) { + shift(d1, c1, -1); + } else { + var before, after; + if (cmp(d1.start, c1.start) < 0) { + before = d1; + d1 = splitDelta(d1, c1.start); + } + if (cmp(d1.end, c1.end) > 0) { + after = splitDelta(d1, c1.end); + } + + shiftPos(c1.end, d1.start, d1.end, -1); + if (after && !before) { + d1.lines = after.lines; + d1.start = after.start; + d1.end = after.end; + after = d1; + } + + return [c1, before, after].filter(Boolean); + } + } + return [c1, d1]; +} + +function shift(d1, d2, dir) { + shiftPos(d1.start, d2.start, d2.end, dir); + shiftPos(d1.end, d2.start, d2.end, dir); +} +function shiftPos(pos, start, end, dir) { + if (pos.row == (dir == 1 ? start : end).row) { + pos.column += dir * (end.column - start.column); + } + pos.row += dir * (end.row - start.row); +} +function splitDelta(c, pos) { + var lines = c.lines; + var end = c.end; + c.end = clonePos(pos); + var rowsBefore = c.end.row - c.start.row; + var otherLines = lines.splice(rowsBefore, lines.length); + + var col = rowsBefore ? pos.column : pos.column - c.start.column; + lines.push(otherLines[0].substring(0, col)); + otherLines[0] = otherLines[0].substr(col) ; + var rest = { + start: clonePos(pos), + end: end, + lines: otherLines, + action: c.action + }; + return rest; +} + +function moveDeltasByOne(redoStack, d) { + d = cloneDelta(d); + for (var j = redoStack.length; j--;) { + var deltaSet = redoStack[j]; + for (var i = 0; i < deltaSet.length; i++) { + var x = deltaSet[i]; + var xformed = xform(x, d); + d = xformed[0]; + if (xformed.length != 2) { + if (xformed[2]) { + deltaSet.splice(i + 1, 1, xformed[1], xformed[2]); + i++; + } else if (!xformed[1]) { + deltaSet.splice(i, 1); + i--; + } + } + } + if (!deltaSet.length) { + redoStack.splice(j, 1); + } + } + return redoStack; +} +function rebaseRedoStack(redoStack, deltaSets) { + for (var i = 0; i < deltaSets.length; i++) { + var deltas = deltaSets[i]; + for (var j = 0; j < deltas.length; j++) { + moveDeltasByOne(redoStack, deltas[j]); + } + } +} + +exports.UndoManager = UndoManager; + +}); + +ace.define("ace/layer/lines",["require","exports","module","ace/lib/dom"], function(require, exports, module) { +"use strict"; + +var dom = require("../lib/dom"); + +var Lines = function(element, canvasHeight) { + this.element = element; + this.canvasHeight = canvasHeight || 500000; + this.element.style.height = (this.canvasHeight * 2) + "px"; + + this.cells = []; + this.cellCache = []; + this.$offsetCoefficient = 0; +}; + +(function() { + + this.moveContainer = function(config) { + dom.translate(this.element, 0, -((config.firstRowScreen * config.lineHeight) % this.canvasHeight) - config.offset * this.$offsetCoefficient); + }; + + this.pageChanged = function(oldConfig, newConfig) { + return ( + Math.floor((oldConfig.firstRowScreen * oldConfig.lineHeight) / this.canvasHeight) !== + Math.floor((newConfig.firstRowScreen * newConfig.lineHeight) / this.canvasHeight) + ); + }; + + this.computeLineTop = function(row, config, session) { + var screenTop = config.firstRowScreen * config.lineHeight; + var screenPage = Math.floor(screenTop / this.canvasHeight); + var lineTop = session.documentToScreenRow(row, 0) * config.lineHeight; + return lineTop - (screenPage * this.canvasHeight); + }; + + this.computeLineHeight = function(row, config, session) { + return config.lineHeight * session.getRowLineCount(row); + }; + + this.getLength = function() { + return this.cells.length; + }; + + this.get = function(index) { + return this.cells[index]; + }; + + this.shift = function() { + this.$cacheCell(this.cells.shift()); + }; + + this.pop = function() { + this.$cacheCell(this.cells.pop()); + }; + + this.push = function(cell) { + if (Array.isArray(cell)) { + this.cells.push.apply(this.cells, cell); + var fragment = dom.createFragment(this.element); + for (var i=0; i foldStart) { + row = fold.end.row + 1; + fold = session.getNextFoldLine(row, fold); + foldStart = fold ? fold.start.row : Infinity; + } + if (row > lastRow) { + while (this.$lines.getLength() > index + 1) + this.$lines.pop(); + + break; + } + + cell = this.$lines.get(++index); + if (cell) { + cell.row = row; + } else { + cell = this.$lines.createCell(row, config, this.session, onCreateCell); + this.$lines.push(cell); + } + + this.$renderCell(cell, config, fold, row); + row++; + } + + this._signal("afterRender"); + this.$updateGutterWidth(config); + }; + + this.$updateGutterWidth = function(config) { + var session = this.session; + + var gutterRenderer = session.gutterRenderer || this.$renderer; + + var firstLineNumber = session.$firstLineNumber; + var lastLineText = this.$lines.last() ? this.$lines.last().text : ""; + + if (this.$fixedWidth || session.$useWrapMode) + lastLineText = session.getLength() + firstLineNumber - 1; + + var gutterWidth = gutterRenderer + ? gutterRenderer.getWidth(session, lastLineText, config) + : lastLineText.toString().length * config.characterWidth; + + var padding = this.$padding || this.$computePadding(); + gutterWidth += padding.left + padding.right; + if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) { + this.gutterWidth = gutterWidth; + this.element.parentNode.style.width = + this.element.style.width = Math.ceil(this.gutterWidth) + "px"; + this._signal("changeGutterWidth", gutterWidth); + } + }; + + this.$updateCursorRow = function() { + if (!this.$highlightGutterLine) + return; + + var position = this.session.selection.getCursor(); + if (this.$cursorRow === position.row) + return; + + this.$cursorRow = position.row; + }; + + this.updateLineHighlight = function() { + if (!this.$highlightGutterLine) + return; + var row = this.session.selection.cursor.row; + this.$cursorRow = row; + + if (this.$cursorCell && this.$cursorCell.row == row) + return; + if (this.$cursorCell) + this.$cursorCell.element.className = this.$cursorCell.element.className.replace("ace_gutter-active-line ", ""); + var cells = this.$lines.cells; + this.$cursorCell = null; + for (var i = 0; i < cells.length; i++) { + var cell = cells[i]; + if (cell.row >= this.$cursorRow) { + if (cell.row > this.$cursorRow) { + var fold = this.session.getFoldLine(this.$cursorRow); + if (i > 0 && fold && fold.start.row == cells[i - 1].row) + cell = cells[i - 1]; + else + break; + } + cell.element.className = "ace_gutter-active-line " + cell.element.className; + this.$cursorCell = cell; + break; + } + } + }; + + this.scrollLines = function(config) { + var oldConfig = this.config; + this.config = config; + + this.$updateCursorRow(); + if (this.$lines.pageChanged(oldConfig, config)) + return this.update(config); + + this.$lines.moveContainer(config); + + var lastRow = Math.min(config.lastRow + config.gutterOffset, // needed to compensate for hor scollbar + this.session.getLength() - 1); + var oldLastRow = this.oldLastRow; + this.oldLastRow = lastRow; + + if (!oldConfig || oldLastRow < config.firstRow) + return this.update(config); + + if (lastRow < oldConfig.firstRow) + return this.update(config); + + if (oldConfig.firstRow < config.firstRow) + for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--) + this.$lines.shift(); + + if (oldLastRow > lastRow) + for (var row=this.session.getFoldedRowCount(lastRow + 1, oldLastRow); row>0; row--) + this.$lines.pop(); + + if (config.firstRow < oldConfig.firstRow) { + this.$lines.unshift(this.$renderLines(config, config.firstRow, oldConfig.firstRow - 1)); + } + + if (lastRow > oldLastRow) { + this.$lines.push(this.$renderLines(config, oldLastRow + 1, lastRow)); + } + + this.updateLineHighlight(); + + this._signal("afterRender"); + this.$updateGutterWidth(config); + }; + + this.$renderLines = function(config, firstRow, lastRow) { + var fragment = []; + var row = firstRow; + var foldLine = this.session.getNextFoldLine(row); + var foldStart = foldLine ? foldLine.start.row : Infinity; + + while (true) { + if (row > foldStart) { + row = foldLine.end.row+1; + foldLine = this.session.getNextFoldLine(row, foldLine); + foldStart = foldLine ? foldLine.start.row : Infinity; + } + if (row > lastRow) + break; + + var cell = this.$lines.createCell(row, config, this.session, onCreateCell); + this.$renderCell(cell, config, foldLine, row); + fragment.push(cell); + + row++; + } + return fragment; + }; + + this.$renderCell = function(cell, config, fold, row) { + var element = cell.element; + + var session = this.session; + + var textNode = element.childNodes[0]; + var foldWidget = element.childNodes[1]; + + var firstLineNumber = session.$firstLineNumber; + + var breakpoints = session.$breakpoints; + var decorations = session.$decorations; + var gutterRenderer = session.gutterRenderer || this.$renderer; + var foldWidgets = this.$showFoldWidgets && session.foldWidgets; + var foldStart = fold ? fold.start.row : Number.MAX_VALUE; + + var className = "ace_gutter-cell "; + if (this.$highlightGutterLine) { + if (row == this.$cursorRow || (fold && row < this.$cursorRow && row >= foldStart && this.$cursorRow <= fold.end.row)) { + className += "ace_gutter-active-line "; + if (this.$cursorCell != cell) { + if (this.$cursorCell) + this.$cursorCell.element.className = this.$cursorCell.element.className.replace("ace_gutter-active-line ", ""); + this.$cursorCell = cell; + } + } + } + + if (breakpoints[row]) + className += breakpoints[row]; + if (decorations[row]) + className += decorations[row]; + if (this.$annotations[row]) + className += this.$annotations[row].className; + if (element.className != className) + element.className = className; + + if (foldWidgets) { + var c = foldWidgets[row]; + if (c == null) + c = foldWidgets[row] = session.getFoldWidget(row); + } + + if (c) { + var className = "ace_fold-widget ace_" + c; + if (c == "start" && row == foldStart && row < fold.end.row) + className += " ace_closed"; + else + className += " ace_open"; + if (foldWidget.className != className) + foldWidget.className = className; + + var foldHeight = config.lineHeight + "px"; + dom.setStyle(foldWidget.style, "height", foldHeight); + dom.setStyle(foldWidget.style, "display", "inline-block"); + } else { + if (foldWidget) { + dom.setStyle(foldWidget.style, "display", "none"); + } + } + + var text = (gutterRenderer + ? gutterRenderer.getText(session, row) + : row + firstLineNumber).toString(); + + if (text !== textNode.data) { + textNode.data = text; + } + + dom.setStyle(cell.element.style, "height", this.$lines.computeLineHeight(row, config, session) + "px"); + dom.setStyle(cell.element.style, "top", this.$lines.computeLineTop(row, config, session) + "px"); + + cell.text = text; + return cell; + }; + + this.$fixedWidth = false; + + this.$highlightGutterLine = true; + this.$renderer = ""; + this.setHighlightGutterLine = function(highlightGutterLine) { + this.$highlightGutterLine = highlightGutterLine; + }; + + this.$showLineNumbers = true; + this.$renderer = ""; + this.setShowLineNumbers = function(show) { + this.$renderer = !show && { + getWidth: function() {return 0;}, + getText: function() {return "";} + }; + }; + + this.getShowLineNumbers = function() { + return this.$showLineNumbers; + }; + + this.$showFoldWidgets = true; + this.setShowFoldWidgets = function(show) { + if (show) + dom.addCssClass(this.element, "ace_folding-enabled"); + else + dom.removeCssClass(this.element, "ace_folding-enabled"); + + this.$showFoldWidgets = show; + this.$padding = null; + }; + + this.getShowFoldWidgets = function() { + return this.$showFoldWidgets; + }; + + this.$computePadding = function() { + if (!this.element.firstChild) + return {left: 0, right: 0}; + var style = dom.computedStyle(this.element.firstChild); + this.$padding = {}; + this.$padding.left = (parseInt(style.borderLeftWidth) || 0) + + (parseInt(style.paddingLeft) || 0) + 1; + this.$padding.right = (parseInt(style.borderRightWidth) || 0) + + (parseInt(style.paddingRight) || 0); + return this.$padding; + }; + + this.getRegion = function(point) { + var padding = this.$padding || this.$computePadding(); + var rect = this.element.getBoundingClientRect(); + if (point.x < padding.left + rect.left) + return "markers"; + if (this.$showFoldWidgets && point.x > rect.right - padding.right) + return "foldWidgets"; + }; + +}).call(Gutter.prototype); + +function onCreateCell(element) { + var textNode = document.createTextNode(''); + element.appendChild(textNode); + + var foldWidget = dom.createElement("span"); + element.appendChild(foldWidget); + + return element; +} + +exports.Gutter = Gutter; + +}); + +ace.define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"], function(require, exports, module) { +"use strict"; + +var Range = require("../range").Range; +var dom = require("../lib/dom"); + +var Marker = function(parentEl) { + this.element = dom.createElement("div"); + this.element.className = "ace_layer ace_marker-layer"; + parentEl.appendChild(this.element); +}; + +(function() { + + this.$padding = 0; + + this.setPadding = function(padding) { + this.$padding = padding; + }; + this.setSession = function(session) { + this.session = session; + }; + + this.setMarkers = function(markers) { + this.markers = markers; + }; + + this.elt = function(className, css) { + var x = this.i != -1 && this.element.childNodes[this.i]; + if (!x) { + x = document.createElement("div"); + this.element.appendChild(x); + this.i = -1; + } else { + this.i++; + } + x.style.cssText = css; + x.className = className; + }; + + this.update = function(config) { + if (!config) return; + + this.config = config; + + this.i = 0; + var html; + for (var key in this.markers) { + var marker = this.markers[key]; + + if (!marker.range) { + marker.update(html, this, this.session, config); + continue; + } + + var range = marker.range.clipRows(config.firstRow, config.lastRow); + if (range.isEmpty()) continue; + + range = range.toScreenRange(this.session); + if (marker.renderer) { + var top = this.$getTop(range.start.row, config); + var left = this.$padding + range.start.column * config.characterWidth; + marker.renderer(html, range, left, top, config); + } else if (marker.type == "fullLine") { + this.drawFullLineMarker(html, range, marker.clazz, config); + } else if (marker.type == "screenLine") { + this.drawScreenLineMarker(html, range, marker.clazz, config); + } else if (range.isMultiLine()) { + if (marker.type == "text") + this.drawTextMarker(html, range, marker.clazz, config); + else + this.drawMultiLineMarker(html, range, marker.clazz, config); + } else { + this.drawSingleLineMarker(html, range, marker.clazz + " ace_start" + " ace_br15", config); + } + } + if (this.i !=-1) { + while (this.i < this.element.childElementCount) + this.element.removeChild(this.element.lastChild); + } + }; + + this.$getTop = function(row, layerConfig) { + return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight; + }; + + function getBorderClass(tl, tr, br, bl) { + return (tl ? 1 : 0) | (tr ? 2 : 0) | (br ? 4 : 0) | (bl ? 8 : 0); + } + this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig, extraStyle) { + var session = this.session; + var start = range.start.row; + var end = range.end.row; + var row = start; + var prev = 0; + var curr = 0; + var next = session.getScreenLastRowColumn(row); + var lineRange = new Range(row, range.start.column, row, curr); + for (; row <= end; row++) { + lineRange.start.row = lineRange.end.row = row; + lineRange.start.column = row == start ? range.start.column : session.getRowWrapIndent(row); + lineRange.end.column = next; + prev = curr; + curr = next; + next = row + 1 < end ? session.getScreenLastRowColumn(row + 1) : row == end ? 0 : range.end.column; + this.drawSingleLineMarker(stringBuilder, lineRange, + clazz + (row == start ? " ace_start" : "") + " ace_br" + + getBorderClass(row == start || row == start + 1 && range.start.column, prev < curr, curr > next, row == end), + layerConfig, row == end ? 0 : 1, extraStyle); + } + }; + this.drawMultiLineMarker = function(stringBuilder, range, clazz, config, extraStyle) { + var padding = this.$padding; + var height = config.lineHeight; + var top = this.$getTop(range.start.row, config); + var left = padding + range.start.column * config.characterWidth; + extraStyle = extraStyle || ""; + + if (this.session.$bidiHandler.isBidiRow(range.start.row)) { + var range1 = range.clone(); + range1.end.row = range1.start.row; + range1.end.column = this.session.getLine(range1.start.row).length; + this.drawBidiSingleLineMarker(stringBuilder, range1, clazz + " ace_br1 ace_start", config, null, extraStyle); + } else { + this.elt( + clazz + " ace_br1 ace_start", + "height:"+ height+ "px;"+ "right:0;"+ "top:"+top+ "px;left:"+ left+ "px;" + (extraStyle || "") + ); + } + if (this.session.$bidiHandler.isBidiRow(range.end.row)) { + var range1 = range.clone(); + range1.start.row = range1.end.row; + range1.start.column = 0; + this.drawBidiSingleLineMarker(stringBuilder, range1, clazz + " ace_br12", config, null, extraStyle); + } else { + top = this.$getTop(range.end.row, config); + var width = range.end.column * config.characterWidth; + + this.elt( + clazz + " ace_br12", + "height:"+ height+ "px;"+ + "width:"+ width+ "px;"+ + "top:"+ top+ "px;"+ + "left:"+ padding+ "px;"+ (extraStyle || "") + ); + } + height = (range.end.row - range.start.row - 1) * config.lineHeight; + if (height <= 0) + return; + top = this.$getTop(range.start.row + 1, config); + + var radiusClass = (range.start.column ? 1 : 0) | (range.end.column ? 0 : 8); + + this.elt( + clazz + (radiusClass ? " ace_br" + radiusClass : ""), + "height:"+ height+ "px;"+ + "right:0;"+ + "top:"+ top+ "px;"+ + "left:"+ padding+ "px;"+ (extraStyle || "") + ); + }; + this.drawSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) { + if (this.session.$bidiHandler.isBidiRow(range.start.row)) + return this.drawBidiSingleLineMarker(stringBuilder, range, clazz, config, extraLength, extraStyle); + var height = config.lineHeight; + var width = (range.end.column + (extraLength || 0) - range.start.column) * config.characterWidth; + + var top = this.$getTop(range.start.row, config); + var left = this.$padding + range.start.column * config.characterWidth; + + this.elt( + clazz, + "height:"+ height+ "px;"+ + "width:"+ width+ "px;"+ + "top:"+ top+ "px;"+ + "left:"+ left+ "px;"+ (extraStyle || "") + ); + }; + this.drawBidiSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) { + var height = config.lineHeight, top = this.$getTop(range.start.row, config), padding = this.$padding; + var selections = this.session.$bidiHandler.getSelections(range.start.column, range.end.column); + + selections.forEach(function(selection) { + this.elt( + clazz, + "height:" + height + "px;" + + "width:" + selection.width + (extraLength || 0) + "px;" + + "top:" + top + "px;" + + "left:" + (padding + selection.left) + "px;" + (extraStyle || "") + ); + }, this); + }; + + this.drawFullLineMarker = function(stringBuilder, range, clazz, config, extraStyle) { + var top = this.$getTop(range.start.row, config); + var height = config.lineHeight; + if (range.start.row != range.end.row) + height += this.$getTop(range.end.row, config) - top; + + this.elt( + clazz, + "height:"+ height+ "px;"+ + "top:"+ top+ "px;"+ + "left:0;right:0;"+ (extraStyle || "") + ); + }; + + this.drawScreenLineMarker = function(stringBuilder, range, clazz, config, extraStyle) { + var top = this.$getTop(range.start.row, config); + var height = config.lineHeight; + + this.elt( + clazz, + "height:"+ height+ "px;"+ + "top:"+ top+ "px;"+ + "left:0;right:0;"+ (extraStyle || "") + ); + }; + +}).call(Marker.prototype); + +exports.Marker = Marker; + +}); + +ace.define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/layer/lines","ace/lib/event_emitter"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var dom = require("../lib/dom"); +var lang = require("../lib/lang"); +var Lines = require("./lines").Lines; +var EventEmitter = require("../lib/event_emitter").EventEmitter; + +var Text = function(parentEl) { + this.dom = dom; + this.element = this.dom.createElement("div"); + this.element.className = "ace_layer ace_text-layer"; + parentEl.appendChild(this.element); + this.$updateEolChar = this.$updateEolChar.bind(this); + this.$lines = new Lines(this.element); +}; + +(function() { + + oop.implement(this, EventEmitter); + + this.EOF_CHAR = "\xB6"; + this.EOL_CHAR_LF = "\xAC"; + this.EOL_CHAR_CRLF = "\xa4"; + this.EOL_CHAR = this.EOL_CHAR_LF; + this.TAB_CHAR = "\u2014"; //"\u21E5"; + this.SPACE_CHAR = "\xB7"; + this.$padding = 0; + this.MAX_LINE_LENGTH = 10000; + + this.$updateEolChar = function() { + var doc = this.session.doc; + var unixMode = doc.getNewLineCharacter() == "\n" && doc.getNewLineMode() != "windows"; + var EOL_CHAR = unixMode ? this.EOL_CHAR_LF : this.EOL_CHAR_CRLF; + if (this.EOL_CHAR != EOL_CHAR) { + this.EOL_CHAR = EOL_CHAR; + return true; + } + }; + + this.setPadding = function(padding) { + this.$padding = padding; + this.element.style.margin = "0 " + padding + "px"; + }; + + this.getLineHeight = function() { + return this.$fontMetrics.$characterSize.height || 0; + }; + + this.getCharacterWidth = function() { + return this.$fontMetrics.$characterSize.width || 0; + }; + + this.$setFontMetrics = function(measure) { + this.$fontMetrics = measure; + this.$fontMetrics.on("changeCharacterSize", function(e) { + this._signal("changeCharacterSize", e); + }.bind(this)); + this.$pollSizeChanges(); + }; + + this.checkForSizeChanges = function() { + this.$fontMetrics.checkForSizeChanges(); + }; + this.$pollSizeChanges = function() { + return this.$pollSizeChangesTimer = this.$fontMetrics.$pollSizeChanges(); + }; + this.setSession = function(session) { + this.session = session; + if (session) + this.$computeTabString(); + }; + + this.showInvisibles = false; + this.showSpaces = false; + this.showTabs = false; + this.showEOL = false; + this.setShowInvisibles = function(showInvisibles) { + if (this.showInvisibles == showInvisibles) + return false; + + this.showInvisibles = showInvisibles; + if (typeof showInvisibles == "string") { + this.showSpaces = /tab/i.test(showInvisibles); + this.showTabs = /space/i.test(showInvisibles); + this.showEOL = /eol/i.test(showInvisibles); + } else { + this.showSpaces = this.showTabs = this.showEOL = showInvisibles; + } + this.$computeTabString(); + return true; + }; + + this.displayIndentGuides = true; + this.setDisplayIndentGuides = function(display) { + if (this.displayIndentGuides == display) + return false; + + this.displayIndentGuides = display; + this.$computeTabString(); + return true; + }; + + this.$tabStrings = []; + this.onChangeTabSize = + this.$computeTabString = function() { + var tabSize = this.session.getTabSize(); + this.tabSize = tabSize; + var tabStr = this.$tabStrings = [0]; + for (var i = 1; i < tabSize + 1; i++) { + if (this.showTabs) { + var span = this.dom.createElement("span"); + span.className = "ace_invisible ace_invisible_tab"; + span.textContent = lang.stringRepeat(this.TAB_CHAR, i); + tabStr.push(span); + } else { + tabStr.push(this.dom.createTextNode(lang.stringRepeat(" ", i), this.element)); + } + } + if (this.displayIndentGuides) { + this.$indentGuideRe = /\s\S| \t|\t |\s$/; + var className = "ace_indent-guide"; + var spaceClass = this.showSpaces ? " ace_invisible ace_invisible_space" : ""; + var spaceContent = this.showSpaces + ? lang.stringRepeat(this.SPACE_CHAR, this.tabSize) + : lang.stringRepeat(" ", this.tabSize); + + var tabClass = this.showTabs ? " ace_invisible ace_invisible_tab" : ""; + var tabContent = this.showTabs + ? lang.stringRepeat(this.TAB_CHAR, this.tabSize) + : spaceContent; + + var span = this.dom.createElement("span"); + span.className = className + spaceClass; + span.textContent = spaceContent; + this.$tabStrings[" "] = span; + + var span = this.dom.createElement("span"); + span.className = className + tabClass; + span.textContent = tabContent; + this.$tabStrings["\t"] = span; + } + }; + + this.updateLines = function(config, firstRow, lastRow) { + if (this.config.lastRow != config.lastRow || + this.config.firstRow != config.firstRow) { + return this.update(config); + } + + this.config = config; + + var first = Math.max(firstRow, config.firstRow); + var last = Math.min(lastRow, config.lastRow); + + var lineElements = this.element.childNodes; + var lineElementsIdx = 0; + + for (var row = config.firstRow; row < first; row++) { + var foldLine = this.session.getFoldLine(row); + if (foldLine) { + if (foldLine.containsRow(first)) { + first = foldLine.start.row; + break; + } else { + row = foldLine.end.row; + } + } + lineElementsIdx ++; + } + + var heightChanged = false; + var row = first; + var foldLine = this.session.getNextFoldLine(row); + var foldStart = foldLine ? foldLine.start.row : Infinity; + + while (true) { + if (row > foldStart) { + row = foldLine.end.row+1; + foldLine = this.session.getNextFoldLine(row, foldLine); + foldStart = foldLine ? foldLine.start.row :Infinity; + } + if (row > last) + break; + + var lineElement = lineElements[lineElementsIdx++]; + if (lineElement) { + this.dom.removeChildren(lineElement); + this.$renderLine( + lineElement, row, row == foldStart ? foldLine : false + ); + + if (heightChanged) + lineElement.style.top = this.$lines.computeLineTop(row, config, this.session) + "px"; + + var height = (config.lineHeight * this.session.getRowLength(row)) + "px"; + if (lineElement.style.height != height) { + heightChanged = true; + lineElement.style.height = height; + } + } + row++; + } + if (heightChanged) { + while (lineElementsIdx < this.$lines.cells.length) { + var cell = this.$lines.cells[lineElementsIdx++]; + cell.element.style.top = this.$lines.computeLineTop(cell.row, config, this.session) + "px"; + } + } + }; + + this.scrollLines = function(config) { + var oldConfig = this.config; + this.config = config; + + if (this.$lines.pageChanged(oldConfig, config)) + return this.update(config); + + this.$lines.moveContainer(config); + + var lastRow = config.lastRow; + var oldLastRow = oldConfig ? oldConfig.lastRow : -1; + + if (!oldConfig || oldLastRow < config.firstRow) + return this.update(config); + + if (lastRow < oldConfig.firstRow) + return this.update(config); + + if (!oldConfig || oldConfig.lastRow < config.firstRow) + return this.update(config); + + if (config.lastRow < oldConfig.firstRow) + return this.update(config); + + if (oldConfig.firstRow < config.firstRow) + for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--) + this.$lines.shift(); + + if (oldConfig.lastRow > config.lastRow) + for (var row=this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row>0; row--) + this.$lines.pop(); + + if (config.firstRow < oldConfig.firstRow) { + this.$lines.unshift(this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1)); + } + + if (config.lastRow > oldConfig.lastRow) { + this.$lines.push(this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow)); + } + }; + + this.$renderLinesFragment = function(config, firstRow, lastRow) { + var fragment = []; + var row = firstRow; + var foldLine = this.session.getNextFoldLine(row); + var foldStart = foldLine ? foldLine.start.row : Infinity; + + while (true) { + if (row > foldStart) { + row = foldLine.end.row+1; + foldLine = this.session.getNextFoldLine(row, foldLine); + foldStart = foldLine ? foldLine.start.row : Infinity; + } + if (row > lastRow) + break; + + var line = this.$lines.createCell(row, config, this.session); + + var lineEl = line.element; + this.dom.removeChildren(lineEl); + dom.setStyle(lineEl.style, "height", this.$lines.computeLineHeight(row, config, this.session) + "px"); + dom.setStyle(lineEl.style, "top", this.$lines.computeLineTop(row, config, this.session) + "px"); + this.$renderLine(lineEl, row, row == foldStart ? foldLine : false); + + if (this.$useLineGroups()) { + lineEl.className = "ace_line_group"; + } else { + lineEl.className = "ace_line"; + } + fragment.push(line); + + row++; + } + return fragment; + }; + + this.update = function(config) { + this.$lines.moveContainer(config); + + this.config = config; + + var firstRow = config.firstRow; + var lastRow = config.lastRow; + + var lines = this.$lines; + while (lines.getLength()) + lines.pop(); + + lines.push(this.$renderLinesFragment(config, firstRow, lastRow)); + }; + + this.$textToken = { + "text": true, + "rparen": true, + "lparen": true + }; + + this.$renderToken = function(parent, screenColumn, token, value) { + var self = this; + var re = /(\t)|( +)|([\x00-\x1f\x80-\xa0\xad\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\uFEFF\uFFF9-\uFFFC]+)|(\u3000)|([\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3001-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]|[\uD800-\uDBFF][\uDC00-\uDFFF])/g; + + var valueFragment = this.dom.createFragment(this.element); + + var m; + var i = 0; + while (m = re.exec(value)) { + var tab = m[1]; + var simpleSpace = m[2]; + var controlCharacter = m[3]; + var cjkSpace = m[4]; + var cjk = m[5]; + + if (!self.showSpaces && simpleSpace) + continue; + + var before = i != m.index ? value.slice(i, m.index) : ""; + + i = m.index + m[0].length; + + if (before) { + valueFragment.appendChild(this.dom.createTextNode(before, this.element)); + } + + if (tab) { + var tabSize = self.session.getScreenTabSize(screenColumn + m.index); + valueFragment.appendChild(self.$tabStrings[tabSize].cloneNode(true)); + screenColumn += tabSize - 1; + } else if (simpleSpace) { + if (self.showSpaces) { + var span = this.dom.createElement("span"); + span.className = "ace_invisible ace_invisible_space"; + span.textContent = lang.stringRepeat(self.SPACE_CHAR, simpleSpace.length); + valueFragment.appendChild(span); + } else { + valueFragment.appendChild(this.com.createTextNode(simpleSpace, this.element)); + } + } else if (controlCharacter) { + var span = this.dom.createElement("span"); + span.className = "ace_invisible ace_invisible_space ace_invalid"; + span.textContent = lang.stringRepeat(self.SPACE_CHAR, controlCharacter.length); + valueFragment.appendChild(span); + } else if (cjkSpace) { + screenColumn += 1; + + var span = this.dom.createElement("span"); + span.style.width = (self.config.characterWidth * 2) + "px"; + span.className = self.showSpaces ? "ace_cjk ace_invisible ace_invisible_space" : "ace_cjk"; + span.textContent = self.showSpaces ? self.SPACE_CHAR : cjkSpace; + valueFragment.appendChild(span); + } else if (cjk) { + screenColumn += 1; + var span = this.dom.createElement("span"); + span.style.width = (self.config.characterWidth * 2) + "px"; + span.className = "ace_cjk"; + span.textContent = cjk; + valueFragment.appendChild(span); + } + } + + valueFragment.appendChild(this.dom.createTextNode(i ? value.slice(i) : value, this.element)); + + if (!this.$textToken[token.type]) { + var classes = "ace_" + token.type.replace(/\./g, " ace_"); + var span = this.dom.createElement("span"); + if (token.type == "fold") + span.style.width = (token.value.length * this.config.characterWidth) + "px"; + + span.className = classes; + span.appendChild(valueFragment); + + parent.appendChild(span); + } + else { + parent.appendChild(valueFragment); + } + + return screenColumn + value.length; + }; + + this.renderIndentGuide = function(parent, value, max) { + var cols = value.search(this.$indentGuideRe); + if (cols <= 0 || cols >= max) + return value; + if (value[0] == " ") { + cols -= cols % this.tabSize; + var count = cols/this.tabSize; + for (var i=0; i= splitChars) { + screenColumn = this.$renderToken( + lineEl, screenColumn, + token, value.substring(0, splitChars - chars) + ); + value = value.substring(splitChars - chars); + chars = splitChars; + + lineEl = this.$createLineElement(); + parent.appendChild(lineEl); + + lineEl.appendChild(this.dom.createTextNode(lang.stringRepeat("\xa0", splits.indent), this.element)); + + split ++; + screenColumn = 0; + splitChars = splits[split] || Number.MAX_VALUE; + } + if (value.length != 0) { + chars += value.length; + screenColumn = this.$renderToken( + lineEl, screenColumn, token, value + ); + } + } + } + + if (splits[splits.length - 1] > this.MAX_LINE_LENGTH) + this.$renderOverflowMessage(lineEl, screenColumn, null, "", true); + }; + + this.$renderSimpleLine = function(parent, tokens) { + var screenColumn = 0; + var token = tokens[0]; + var value = token.value; + if (this.displayIndentGuides) + value = this.renderIndentGuide(parent, value); + if (value) + screenColumn = this.$renderToken(parent, screenColumn, token, value); + for (var i = 1; i < tokens.length; i++) { + token = tokens[i]; + value = token.value; + if (screenColumn + value.length > this.MAX_LINE_LENGTH) + return this.$renderOverflowMessage(parent, screenColumn, token, value); + screenColumn = this.$renderToken(parent, screenColumn, token, value); + } + }; + + this.$renderOverflowMessage = function(parent, screenColumn, token, value, hide) { + token && this.$renderToken(parent, screenColumn, token, + value.slice(0, this.MAX_LINE_LENGTH - screenColumn)); + + var overflowEl = this.dom.createElement("span"); + overflowEl.className = "ace_inline_button ace_keyword ace_toggle_wrap"; + overflowEl.textContent = hide ? "" : ""; + + parent.appendChild(overflowEl); + }; + this.$renderLine = function(parent, row, foldLine) { + if (!foldLine && foldLine != false) + foldLine = this.session.getFoldLine(row); + + if (foldLine) + var tokens = this.$getFoldLineTokens(row, foldLine); + else + var tokens = this.session.getTokens(row); + + var lastLineEl = parent; + if (tokens.length) { + var splits = this.session.getRowSplitData(row); + if (splits && splits.length) { + this.$renderWrappedLine(parent, tokens, splits); + var lastLineEl = parent.lastChild; + } else { + var lastLineEl = parent; + if (this.$useLineGroups()) { + lastLineEl = this.$createLineElement(); + parent.appendChild(lastLineEl); + } + this.$renderSimpleLine(lastLineEl, tokens); + } + } else if (this.$useLineGroups()) { + lastLineEl = this.$createLineElement(); + parent.appendChild(lastLineEl); + } + + if (this.showEOL && lastLineEl) { + if (foldLine) + row = foldLine.end.row; + + var invisibleEl = this.dom.createElement("span"); + invisibleEl.className = "ace_invisible ace_invisible_eol"; + invisibleEl.textContent = row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR; + + lastLineEl.appendChild(invisibleEl); + } + }; + + this.$getFoldLineTokens = function(row, foldLine) { + var session = this.session; + var renderTokens = []; + + function addTokens(tokens, from, to) { + var idx = 0, col = 0; + while ((col + tokens[idx].value.length) < from) { + col += tokens[idx].value.length; + idx++; + + if (idx == tokens.length) + return; + } + if (col != from) { + var value = tokens[idx].value.substring(from - col); + if (value.length > (to - from)) + value = value.substring(0, to - from); + + renderTokens.push({ + type: tokens[idx].type, + value: value + }); + + col = from + value.length; + idx += 1; + } + + while (col < to && idx < tokens.length) { + var value = tokens[idx].value; + if (value.length + col > to) { + renderTokens.push({ + type: tokens[idx].type, + value: value.substring(0, to - col) + }); + } else + renderTokens.push(tokens[idx]); + col += value.length; + idx += 1; + } + } + + var tokens = session.getTokens(row); + foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) { + if (placeholder != null) { + renderTokens.push({ + type: "fold", + value: placeholder + }); + } else { + if (isNewRow) + tokens = session.getTokens(row); + + if (tokens.length) + addTokens(tokens, lastColumn, column); + } + }, foldLine.end.row, this.session.getLine(foldLine.end.row).length); + + return renderTokens; + }; + + this.$useLineGroups = function() { + return this.session.getUseWrapMode(); + }; + + this.destroy = function() {}; +}).call(Text.prototype); + +exports.Text = Text; + +}); + +ace.define("ace/layer/cursor",["require","exports","module","ace/lib/dom"], function(require, exports, module) { +"use strict"; + +var dom = require("../lib/dom"); + +var Cursor = function(parentEl) { + this.element = dom.createElement("div"); + this.element.className = "ace_layer ace_cursor-layer"; + parentEl.appendChild(this.element); + + this.isVisible = false; + this.isBlinking = true; + this.blinkInterval = 1000; + this.smoothBlinking = false; + + this.cursors = []; + this.cursor = this.addCursor(); + dom.addCssClass(this.element, "ace_hidden-cursors"); + this.$updateCursors = this.$updateOpacity.bind(this); +}; + +(function() { + + this.$updateOpacity = function(val) { + var cursors = this.cursors; + for (var i = cursors.length; i--; ) + dom.setStyle(cursors[i].style, "opacity", val ? "" : "0"); + }; + + this.$startCssAnimation = function() { + var cursors = this.cursors; + for (var i = cursors.length; i--; ) + cursors[i].style.animationDuration = this.blinkInterval + "ms"; + + setTimeout(function() { + dom.addCssClass(this.element, "ace_animate-blinking"); + }.bind(this)); + }; + + this.$stopCssAnimation = function() { + dom.removeCssClass(this.element, "ace_animate-blinking"); + }; + + this.$padding = 0; + this.setPadding = function(padding) { + this.$padding = padding; + }; + + this.setSession = function(session) { + this.session = session; + }; + + this.setBlinking = function(blinking) { + if (blinking != this.isBlinking) { + this.isBlinking = blinking; + this.restartTimer(); + } + }; + + this.setBlinkInterval = function(blinkInterval) { + if (blinkInterval != this.blinkInterval) { + this.blinkInterval = blinkInterval; + this.restartTimer(); + } + }; + + this.setSmoothBlinking = function(smoothBlinking) { + if (smoothBlinking != this.smoothBlinking) { + this.smoothBlinking = smoothBlinking; + dom.setCssClass(this.element, "ace_smooth-blinking", smoothBlinking); + this.$updateCursors(true); + this.restartTimer(); + } + }; + + this.addCursor = function() { + var el = dom.createElement("div"); + el.className = "ace_cursor"; + this.element.appendChild(el); + this.cursors.push(el); + return el; + }; + + this.removeCursor = function() { + if (this.cursors.length > 1) { + var el = this.cursors.pop(); + el.parentNode.removeChild(el); + return el; + } + }; + + this.hideCursor = function() { + this.isVisible = false; + dom.addCssClass(this.element, "ace_hidden-cursors"); + this.restartTimer(); + }; + + this.showCursor = function() { + this.isVisible = true; + dom.removeCssClass(this.element, "ace_hidden-cursors"); + this.restartTimer(); + }; + + this.restartTimer = function() { + var update = this.$updateCursors; + clearInterval(this.intervalId); + clearTimeout(this.timeoutId); + this.$stopCssAnimation(); + + if (this.smoothBlinking) { + dom.removeCssClass(this.element, "ace_smooth-blinking"); + } + + update(true); + + if (!this.isBlinking || !this.blinkInterval || !this.isVisible) { + this.$stopCssAnimation(); + return; + } + + if (this.smoothBlinking) { + setTimeout(function(){ + dom.addCssClass(this.element, "ace_smooth-blinking"); + }.bind(this)); + } + + if (dom.HAS_CSS_ANIMATION) { + this.$startCssAnimation(); + } else { + var blink = function(){ + this.timeoutId = setTimeout(function() { + update(false); + }, 0.6 * this.blinkInterval); + }.bind(this); + + this.intervalId = setInterval(function() { + update(true); + blink(); + }, this.blinkInterval); + blink(); + } + }; + + this.getPixelPosition = function(position, onScreen) { + if (!this.config || !this.session) + return {left : 0, top : 0}; + + if (!position) + position = this.session.selection.getCursor(); + var pos = this.session.documentToScreenPosition(position); + var cursorLeft = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, position.row) + ? this.session.$bidiHandler.getPosLeft(pos.column) + : pos.column * this.config.characterWidth); + + var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) * + this.config.lineHeight; + + return {left : cursorLeft, top : cursorTop}; + }; + + this.isCursorInView = function(pixelPos, config) { + return pixelPos.top >= 0 && pixelPos.top < config.maxHeight; + }; + + this.update = function(config) { + this.config = config; + + var selections = this.session.$selectionMarkers; + var i = 0, cursorIndex = 0; + + if (selections === undefined || selections.length === 0){ + selections = [{cursor: null}]; + } + + for (var i = 0, n = selections.length; i < n; i++) { + var pixelPos = this.getPixelPosition(selections[i].cursor, true); + if ((pixelPos.top > config.height + config.offset || + pixelPos.top < 0) && i > 1) { + continue; + } + + var element = this.cursors[cursorIndex++] || this.addCursor(); + var style = element.style; + + if (!this.drawCursor) { + if (!this.isCursorInView(pixelPos, config)) { + dom.setStyle(style, "display", "none"); + } else { + dom.setStyle(style, "display", "block"); + dom.translate(element, pixelPos.left, pixelPos.top); + dom.setStyle(style, "width", Math.round(config.characterWidth) + "px"); + dom.setStyle(style, "height", config.lineHeight + "px"); + } + } else { + this.drawCursor(element, pixelPos, config, selections[i], this.session); + } + } + while (this.cursors.length > cursorIndex) + this.removeCursor(); + + var overwrite = this.session.getOverwrite(); + this.$setOverwrite(overwrite); + this.$pixelPos = pixelPos; + this.restartTimer(); + }; + + this.drawCursor = null; + + this.$setOverwrite = function(overwrite) { + if (overwrite != this.overwrite) { + this.overwrite = overwrite; + if (overwrite) + dom.addCssClass(this.element, "ace_overwrite-cursors"); + else + dom.removeCssClass(this.element, "ace_overwrite-cursors"); + } + }; + + this.destroy = function() { + clearInterval(this.intervalId); + clearTimeout(this.timeoutId); + }; + +}).call(Cursor.prototype); + +exports.Cursor = Cursor; + +}); + +ace.define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"], function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var dom = require("./lib/dom"); +var event = require("./lib/event"); +var EventEmitter = require("./lib/event_emitter").EventEmitter; +var MAX_SCROLL_H = 0x8000; +var ScrollBar = function(parent) { + this.element = dom.createElement("div"); + this.element.className = "ace_scrollbar ace_scrollbar" + this.classSuffix; + + this.inner = dom.createElement("div"); + this.inner.className = "ace_scrollbar-inner"; + this.inner.textContent = "\xa0"; + this.element.appendChild(this.inner); + + parent.appendChild(this.element); + + this.setVisible(false); + this.skipEvent = false; + + event.addListener(this.element, "scroll", this.onScroll.bind(this)); + event.addListener(this.element, "mousedown", event.preventDefault); +}; + +(function() { + oop.implement(this, EventEmitter); + + this.setVisible = function(isVisible) { + this.element.style.display = isVisible ? "" : "none"; + this.isVisible = isVisible; + this.coeff = 1; + }; +}).call(ScrollBar.prototype); +var VScrollBar = function(parent, renderer) { + ScrollBar.call(this, parent); + this.scrollTop = 0; + this.scrollHeight = 0; + renderer.$scrollbarWidth = + this.width = dom.scrollbarWidth(parent.ownerDocument); + this.inner.style.width = + this.element.style.width = (this.width || 15) + 5 + "px"; + this.$minWidth = 0; +}; + +oop.inherits(VScrollBar, ScrollBar); + +(function() { + + this.classSuffix = '-v'; + this.onScroll = function() { + if (!this.skipEvent) { + this.scrollTop = this.element.scrollTop; + if (this.coeff != 1) { + var h = this.element.clientHeight / this.scrollHeight; + this.scrollTop = this.scrollTop * (1 - h) / (this.coeff - h); + } + this._emit("scroll", {data: this.scrollTop}); + } + this.skipEvent = false; + }; + this.getWidth = function() { + return Math.max(this.isVisible ? this.width : 0, this.$minWidth || 0); + }; + this.setHeight = function(height) { + this.element.style.height = height + "px"; + }; + this.setInnerHeight = + this.setScrollHeight = function(height) { + this.scrollHeight = height; + if (height > MAX_SCROLL_H) { + this.coeff = MAX_SCROLL_H / height; + height = MAX_SCROLL_H; + } else if (this.coeff != 1) { + this.coeff = 1; + } + this.inner.style.height = height + "px"; + }; + this.setScrollTop = function(scrollTop) { + if (this.scrollTop != scrollTop) { + this.skipEvent = true; + this.scrollTop = scrollTop; + this.element.scrollTop = scrollTop * this.coeff; + } + }; + +}).call(VScrollBar.prototype); +var HScrollBar = function(parent, renderer) { + ScrollBar.call(this, parent); + this.scrollLeft = 0; + this.height = renderer.$scrollbarWidth; + this.inner.style.height = + this.element.style.height = (this.height || 15) + 5 + "px"; +}; + +oop.inherits(HScrollBar, ScrollBar); + +(function() { + + this.classSuffix = '-h'; + this.onScroll = function() { + if (!this.skipEvent) { + this.scrollLeft = this.element.scrollLeft; + this._emit("scroll", {data: this.scrollLeft}); + } + this.skipEvent = false; + }; + this.getHeight = function() { + return this.isVisible ? this.height : 0; + }; + this.setWidth = function(width) { + this.element.style.width = width + "px"; + }; + this.setInnerWidth = function(width) { + this.inner.style.width = width + "px"; + }; + this.setScrollWidth = function(width) { + this.inner.style.width = width + "px"; + }; + this.setScrollLeft = function(scrollLeft) { + if (this.scrollLeft != scrollLeft) { + this.skipEvent = true; + this.scrollLeft = this.element.scrollLeft = scrollLeft; + } + }; + +}).call(HScrollBar.prototype); + + +exports.ScrollBar = VScrollBar; // backward compatibility +exports.ScrollBarV = VScrollBar; // backward compatibility +exports.ScrollBarH = HScrollBar; // backward compatibility + +exports.VScrollBar = VScrollBar; +exports.HScrollBar = HScrollBar; +}); + +ace.define("ace/renderloop",["require","exports","module","ace/lib/event"], function(require, exports, module) { +"use strict"; + +var event = require("./lib/event"); + + +var RenderLoop = function(onRender, win) { + this.onRender = onRender; + this.pending = false; + this.changes = 0; + this.$recursionLimit = 2; + this.window = win || window; + var _self = this; + this._flush = function(ts) { + _self.pending = false; + var changes = _self.changes; + + if (changes) { + event.blockIdle(100); + _self.changes = 0; + _self.onRender(changes); + } + + if (_self.changes) { + if (_self.$recursionLimit-- < 0) return; + _self.schedule(); + } else { + _self.$recursionLimit = 2; + } + }; +}; + +(function() { + + this.schedule = function(change) { + this.changes = this.changes | change; + if (this.changes && !this.pending) { + event.nextFrame(this._flush); + this.pending = true; + } + }; + + this.clear = function(change) { + var changes = this.changes; + this.changes = 0; + return changes; + }; + +}).call(RenderLoop.prototype); + +exports.RenderLoop = RenderLoop; +}); + +ace.define("ace/layer/font_metrics",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/event","ace/lib/useragent","ace/lib/event_emitter"], function(require, exports, module) { + +var oop = require("../lib/oop"); +var dom = require("../lib/dom"); +var lang = require("../lib/lang"); +var event = require("../lib/event"); +var useragent = require("../lib/useragent"); +var EventEmitter = require("../lib/event_emitter").EventEmitter; + +var CHAR_COUNT = 256; +var USE_OBSERVER = typeof ResizeObserver == "function"; +var L = 200; + +var FontMetrics = exports.FontMetrics = function(parentEl) { + this.el = dom.createElement("div"); + this.$setMeasureNodeStyles(this.el.style, true); + + this.$main = dom.createElement("div"); + this.$setMeasureNodeStyles(this.$main.style); + + this.$measureNode = dom.createElement("div"); + this.$setMeasureNodeStyles(this.$measureNode.style); + + + this.el.appendChild(this.$main); + this.el.appendChild(this.$measureNode); + parentEl.appendChild(this.el); + + this.$measureNode.textContent = lang.stringRepeat("X", CHAR_COUNT); + + this.$characterSize = {width: 0, height: 0}; + + + if (USE_OBSERVER) + this.$addObserver(); + else + this.checkForSizeChanges(); +}; + +(function() { + + oop.implement(this, EventEmitter); + + this.$characterSize = {width: 0, height: 0}; + + this.$setMeasureNodeStyles = function(style, isRoot) { + style.width = style.height = "auto"; + style.left = style.top = "0px"; + style.visibility = "hidden"; + style.position = "absolute"; + style.whiteSpace = "pre"; + + if (useragent.isIE < 8) { + style["font-family"] = "inherit"; + } else { + style.font = "inherit"; + } + style.overflow = isRoot ? "hidden" : "visible"; + }; + + this.checkForSizeChanges = function(size) { + if (size === undefined) + size = this.$measureSizes(); + if (size && (this.$characterSize.width !== size.width || this.$characterSize.height !== size.height)) { + this.$measureNode.style.fontWeight = "bold"; + var boldSize = this.$measureSizes(); + this.$measureNode.style.fontWeight = ""; + this.$characterSize = size; + this.charSizes = Object.create(null); + this.allowBoldFonts = boldSize && boldSize.width === size.width && boldSize.height === size.height; + this._emit("changeCharacterSize", {data: size}); + } + }; + + this.$addObserver = function() { + var self = this; + this.$observer = new window.ResizeObserver(function(e) { + self.checkForSizeChanges(); + }); + this.$observer.observe(this.$measureNode); + }; + + this.$pollSizeChanges = function() { + if (this.$pollSizeChangesTimer || this.$observer) + return this.$pollSizeChangesTimer; + var self = this; + + return this.$pollSizeChangesTimer = event.onIdle(function cb() { + self.checkForSizeChanges(); + event.onIdle(cb, 500); + }, 500); + }; + + this.setPolling = function(val) { + if (val) { + this.$pollSizeChanges(); + } else if (this.$pollSizeChangesTimer) { + clearInterval(this.$pollSizeChangesTimer); + this.$pollSizeChangesTimer = 0; + } + }; + + this.$measureSizes = function(node) { + var size = { + height: (node || this.$measureNode).clientHeight, + width: (node || this.$measureNode).clientWidth / CHAR_COUNT + }; + if (size.width === 0 || size.height === 0) + return null; + return size; + }; + + this.$measureCharWidth = function(ch) { + this.$main.textContent = lang.stringRepeat(ch, CHAR_COUNT); + var rect = this.$main.getBoundingClientRect(); + return rect.width / CHAR_COUNT; + }; + + this.getCharacterWidth = function(ch) { + var w = this.charSizes[ch]; + if (w === undefined) { + w = this.charSizes[ch] = this.$measureCharWidth(ch) / this.$characterSize.width; + } + return w; + }; + + this.destroy = function() { + clearInterval(this.$pollSizeChangesTimer); + if (this.$observer) + this.$observer.disconnect(); + if (this.el && this.el.parentNode) + this.el.parentNode.removeChild(this.el); + }; + + + this.$getZoom = function getZoom(element) { + if (!element || !element.parentElement) return 1; + return (window.getComputedStyle(element).zoom || 1) * getZoom(element.parentElement); + }; + this.$initTransformMeasureNodes = function() { + var t = function(t, l) { + return ["div", { + style: "position: absolute;top:" + t + "px;left:" + l + "px;" + }]; + }; + this.els = dom.buildDom([t(0, 0), t(L, 0), t(0, L), t(L, L)], this.el); + }; + this.transformCoordinates = function(clientPos, elPos) { + if (clientPos) { + var zoom = this.$getZoom(this.el); + clientPos = mul(1 / zoom, clientPos); + } + function solve(l1, l2, r) { + var det = l1[1] * l2[0] - l1[0] * l2[1]; + return [ + (-l2[1] * r[0] + l2[0] * r[1]) / det, + (+l1[1] * r[0] - l1[0] * r[1]) / det + ]; + } + function sub(a, b) { return [a[0] - b[0], a[1] - b[1]]; } + function add(a, b) { return [a[0] + b[0], a[1] + b[1]]; } + function mul(a, b) { return [a * b[0], a * b[1]]; } + + if (!this.els) + this.$initTransformMeasureNodes(); + + function p(el) { + var r = el.getBoundingClientRect(); + return [r.left, r.top]; + } + + var a = p(this.els[0]); + var b = p(this.els[1]); + var c = p(this.els[2]); + var d = p(this.els[3]); + + var h = solve(sub(d, b), sub(d, c), sub(add(b, c), add(d, a))); + + var m1 = mul(1 + h[0], sub(b, a)); + var m2 = mul(1 + h[1], sub(c, a)); + + if (elPos) { + var x = elPos; + var k = h[0] * x[0] / L + h[1] * x[1] / L + 1; + var ut = add(mul(x[0], m1), mul(x[1], m2)); + return add(mul(1 / k / L, ut), a); + } + var u = sub(clientPos, a); + var f = solve(sub(m1, mul(h[0], u)), sub(m2, mul(h[1], u)), u); + return mul(L, f); + }; + +}).call(FontMetrics.prototype); + +}); + +ace.define("ace/virtual_renderer",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/config","ace/layer/gutter","ace/layer/marker","ace/layer/text","ace/layer/cursor","ace/scrollbar","ace/scrollbar","ace/renderloop","ace/layer/font_metrics","ace/lib/event_emitter","ace/lib/useragent"], function(require, exports, module) { +"use strict"; + +var oop = require("./lib/oop"); +var dom = require("./lib/dom"); +var config = require("./config"); +var GutterLayer = require("./layer/gutter").Gutter; +var MarkerLayer = require("./layer/marker").Marker; +var TextLayer = require("./layer/text").Text; +var CursorLayer = require("./layer/cursor").Cursor; +var HScrollBar = require("./scrollbar").HScrollBar; +var VScrollBar = require("./scrollbar").VScrollBar; +var RenderLoop = require("./renderloop").RenderLoop; +var FontMetrics = require("./layer/font_metrics").FontMetrics; +var EventEmitter = require("./lib/event_emitter").EventEmitter; +var editorCss = "\ +.ace_br1 {border-top-left-radius : 3px;}\ +.ace_br2 {border-top-right-radius : 3px;}\ +.ace_br3 {border-top-left-radius : 3px; border-top-right-radius: 3px;}\ +.ace_br4 {border-bottom-right-radius: 3px;}\ +.ace_br5 {border-top-left-radius : 3px; border-bottom-right-radius: 3px;}\ +.ace_br6 {border-top-right-radius : 3px; border-bottom-right-radius: 3px;}\ +.ace_br7 {border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px;}\ +.ace_br8 {border-bottom-left-radius : 3px;}\ +.ace_br9 {border-top-left-radius : 3px; border-bottom-left-radius: 3px;}\ +.ace_br10{border-top-right-radius : 3px; border-bottom-left-radius: 3px;}\ +.ace_br11{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-left-radius: 3px;}\ +.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\ +.ace_br13{border-top-left-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\ +.ace_br14{border-top-right-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\ +.ace_br15{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}\ +.ace_editor {\ +position: relative;\ +overflow: hidden;\ +padding: 0;\ +font: 12px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;\ +direction: ltr;\ +text-align: left;\ +-webkit-tap-highlight-color: rgba(0, 0, 0, 0);\ +}\ +.ace_scroller {\ +position: absolute;\ +overflow: hidden;\ +top: 0;\ +bottom: 0;\ +background-color: inherit;\ +-ms-user-select: none;\ +-moz-user-select: none;\ +-webkit-user-select: none;\ +user-select: none;\ +cursor: text;\ +}\ +.ace_content {\ +position: absolute;\ +box-sizing: border-box;\ +min-width: 100%;\ +contain: style size layout;\ +font-variant-ligatures: no-common-ligatures;\ +}\ +.ace_dragging .ace_scroller:before{\ +position: absolute;\ +top: 0;\ +left: 0;\ +right: 0;\ +bottom: 0;\ +content: '';\ +background: rgba(250, 250, 250, 0.01);\ +z-index: 1000;\ +}\ +.ace_dragging.ace_dark .ace_scroller:before{\ +background: rgba(0, 0, 0, 0.01);\ +}\ +.ace_selecting, .ace_selecting * {\ +cursor: text !important;\ +}\ +.ace_gutter {\ +position: absolute;\ +overflow : hidden;\ +width: auto;\ +top: 0;\ +bottom: 0;\ +left: 0;\ +cursor: default;\ +z-index: 4;\ +-ms-user-select: none;\ +-moz-user-select: none;\ +-webkit-user-select: none;\ +user-select: none;\ +contain: style size layout;\ +}\ +.ace_gutter-active-line {\ +position: absolute;\ +left: 0;\ +right: 0;\ +}\ +.ace_scroller.ace_scroll-left {\ +box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;\ +}\ +.ace_gutter-cell {\ +position: absolute;\ +top: 0;\ +left: 0;\ +right: 0;\ +padding-left: 19px;\ +padding-right: 6px;\ +background-repeat: no-repeat;\ +}\ +.ace_gutter-cell.ace_error {\ +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==\");\ +background-repeat: no-repeat;\ +background-position: 2px center;\ +}\ +.ace_gutter-cell.ace_warning {\ +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==\");\ +background-position: 2px center;\ +}\ +.ace_gutter-cell.ace_info {\ +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=\");\ +background-position: 2px center;\ +}\ +.ace_dark .ace_gutter-cell.ace_info {\ +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC\");\ +}\ +.ace_scrollbar {\ +contain: strict;\ +position: absolute;\ +right: 0;\ +bottom: 0;\ +z-index: 6;\ +}\ +.ace_scrollbar-inner {\ +position: absolute;\ +cursor: text;\ +left: 0;\ +top: 0;\ +}\ +.ace_scrollbar-v{\ +overflow-x: hidden;\ +overflow-y: scroll;\ +top: 0;\ +}\ +.ace_scrollbar-h {\ +overflow-x: scroll;\ +overflow-y: hidden;\ +left: 0;\ +}\ +.ace_print-margin {\ +position: absolute;\ +height: 100%;\ +}\ +.ace_text-input {\ +position: absolute;\ +z-index: 0;\ +width: 0.5em;\ +height: 1em;\ +opacity: 0;\ +background: transparent;\ +-moz-appearance: none;\ +appearance: none;\ +border: none;\ +resize: none;\ +outline: none;\ +overflow: hidden;\ +font: inherit;\ +padding: 0 1px;\ +margin: 0 -1px;\ +contain: strict;\ +-ms-user-select: text;\ +-moz-user-select: text;\ +-webkit-user-select: text;\ +user-select: text;\ +white-space: pre!important;\ +}\ +.ace_text-input.ace_composition {\ +background: transparent;\ +color: inherit;\ +z-index: 1000;\ +opacity: 1;\ +}\ +.ace_composition_placeholder { color: transparent }\ +.ace_composition_marker { \ +border-bottom: 1px solid;\ +position: absolute;\ +border-radius: 0;\ +margin-top: 1px;\ +}\ +[ace_nocontext=true] {\ +transform: none!important;\ +filter: none!important;\ +clip-path: none!important;\ +mask : none!important;\ +contain: none!important;\ +perspective: none!important;\ +mix-blend-mode: initial!important;\ +z-index: auto;\ +}\ +.ace_layer {\ +z-index: 1;\ +position: absolute;\ +overflow: hidden;\ +word-wrap: normal;\ +white-space: pre;\ +height: 100%;\ +width: 100%;\ +box-sizing: border-box;\ +pointer-events: none;\ +}\ +.ace_gutter-layer {\ +position: relative;\ +width: auto;\ +text-align: right;\ +pointer-events: auto;\ +height: 1000000px;\ +contain: style size layout;\ +}\ +.ace_text-layer {\ +font: inherit !important;\ +position: absolute;\ +height: 1000000px;\ +width: 1000000px;\ +contain: style size layout;\ +}\ +.ace_text-layer > .ace_line, .ace_text-layer > .ace_line_group {\ +contain: style size layout;\ +position: absolute;\ +top: 0;\ +left: 0;\ +right: 0;\ +}\ +.ace_hidpi .ace_text-layer,\ +.ace_hidpi .ace_gutter-layer,\ +.ace_hidpi .ace_content,\ +.ace_hidpi .ace_gutter {\ +contain: strict;\ +will-change: transform;\ +}\ +.ace_hidpi .ace_text-layer > .ace_line, \ +.ace_hidpi .ace_text-layer > .ace_line_group {\ +contain: strict;\ +}\ +.ace_cjk {\ +display: inline-block;\ +text-align: center;\ +}\ +.ace_cursor-layer {\ +z-index: 4;\ +}\ +.ace_cursor {\ +z-index: 4;\ +position: absolute;\ +box-sizing: border-box;\ +border-left: 2px solid;\ +transform: translatez(0);\ +}\ +.ace_multiselect .ace_cursor {\ +border-left-width: 1px;\ +}\ +.ace_slim-cursors .ace_cursor {\ +border-left-width: 1px;\ +}\ +.ace_overwrite-cursors .ace_cursor {\ +border-left-width: 0;\ +border-bottom: 1px solid;\ +}\ +.ace_hidden-cursors .ace_cursor {\ +opacity: 0.2;\ +}\ +.ace_hasPlaceholder .ace_hidden-cursors .ace_cursor {\ +opacity: 0;\ +}\ +.ace_smooth-blinking .ace_cursor {\ +transition: opacity 0.18s;\ +}\ +.ace_animate-blinking .ace_cursor {\ +animation-duration: 1000ms;\ +animation-timing-function: step-end;\ +animation-name: blink-ace-animate;\ +animation-iteration-count: infinite;\ +}\ +.ace_animate-blinking.ace_smooth-blinking .ace_cursor {\ +animation-duration: 1000ms;\ +animation-timing-function: ease-in-out;\ +animation-name: blink-ace-animate-smooth;\ +}\ +@keyframes blink-ace-animate {\ +from, to { opacity: 1; }\ +60% { opacity: 0; }\ +}\ +@keyframes blink-ace-animate-smooth {\ +from, to { opacity: 1; }\ +45% { opacity: 1; }\ +60% { opacity: 0; }\ +85% { opacity: 0; }\ +}\ +.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {\ +position: absolute;\ +z-index: 3;\ +}\ +.ace_marker-layer .ace_selection {\ +position: absolute;\ +z-index: 5;\ +}\ +.ace_marker-layer .ace_bracket {\ +position: absolute;\ +z-index: 6;\ +}\ +.ace_marker-layer .ace_error_bracket {\ +position: absolute;\ +border-bottom: 1px solid #DE5555;\ +border-radius: 0;\ +}\ +.ace_marker-layer .ace_active-line {\ +position: absolute;\ +z-index: 2;\ +}\ +.ace_marker-layer .ace_selected-word {\ +position: absolute;\ +z-index: 4;\ +box-sizing: border-box;\ +}\ +.ace_line .ace_fold {\ +box-sizing: border-box;\ +display: inline-block;\ +height: 11px;\ +margin-top: -2px;\ +vertical-align: middle;\ +background-image:\ +url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),\ +url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=\");\ +background-repeat: no-repeat, repeat-x;\ +background-position: center center, top left;\ +color: transparent;\ +border: 1px solid black;\ +border-radius: 2px;\ +cursor: pointer;\ +pointer-events: auto;\ +}\ +.ace_dark .ace_fold {\ +}\ +.ace_fold:hover{\ +background-image:\ +url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),\ +url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC\");\ +}\ +.ace_tooltip {\ +background-color: #FFF;\ +background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));\ +border: 1px solid gray;\ +border-radius: 1px;\ +box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);\ +color: black;\ +max-width: 100%;\ +padding: 3px 4px;\ +position: fixed;\ +z-index: 999999;\ +box-sizing: border-box;\ +cursor: default;\ +white-space: pre;\ +word-wrap: break-word;\ +line-height: normal;\ +font-style: normal;\ +font-weight: normal;\ +letter-spacing: normal;\ +pointer-events: none;\ +}\ +.ace_folding-enabled > .ace_gutter-cell {\ +padding-right: 13px;\ +}\ +.ace_fold-widget {\ +box-sizing: border-box;\ +margin: 0 -12px 0 1px;\ +display: none;\ +width: 11px;\ +vertical-align: top;\ +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==\");\ +background-repeat: no-repeat;\ +background-position: center;\ +border-radius: 3px;\ +border: 1px solid transparent;\ +cursor: pointer;\ +}\ +.ace_folding-enabled .ace_fold-widget {\ +display: inline-block; \ +}\ +.ace_fold-widget.ace_end {\ +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==\");\ +}\ +.ace_fold-widget.ace_closed {\ +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==\");\ +}\ +.ace_fold-widget:hover {\ +border: 1px solid rgba(0, 0, 0, 0.3);\ +background-color: rgba(255, 255, 255, 0.2);\ +box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\ +}\ +.ace_fold-widget:active {\ +border: 1px solid rgba(0, 0, 0, 0.4);\ +background-color: rgba(0, 0, 0, 0.05);\ +box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\ +}\ +.ace_dark .ace_fold-widget {\ +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC\");\ +}\ +.ace_dark .ace_fold-widget.ace_end {\ +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==\");\ +}\ +.ace_dark .ace_fold-widget.ace_closed {\ +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==\");\ +}\ +.ace_dark .ace_fold-widget:hover {\ +box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\ +background-color: rgba(255, 255, 255, 0.1);\ +}\ +.ace_dark .ace_fold-widget:active {\ +box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\ +}\ +.ace_inline_button {\ +border: 1px solid lightgray;\ +display: inline-block;\ +margin: -1px 8px;\ +padding: 0 5px;\ +pointer-events: auto;\ +cursor: pointer;\ +}\ +.ace_inline_button:hover {\ +border-color: gray;\ +background: rgba(200,200,200,0.2);\ +display: inline-block;\ +pointer-events: auto;\ +}\ +.ace_fold-widget.ace_invalid {\ +background-color: #FFB4B4;\ +border-color: #DE5555;\ +}\ +.ace_fade-fold-widgets .ace_fold-widget {\ +transition: opacity 0.4s ease 0.05s;\ +opacity: 0;\ +}\ +.ace_fade-fold-widgets:hover .ace_fold-widget {\ +transition: opacity 0.05s ease 0.05s;\ +opacity:1;\ +}\ +.ace_underline {\ +text-decoration: underline;\ +}\ +.ace_bold {\ +font-weight: bold;\ +}\ +.ace_nobold .ace_bold {\ +font-weight: normal;\ +}\ +.ace_italic {\ +font-style: italic;\ +}\ +.ace_error-marker {\ +background-color: rgba(255, 0, 0,0.2);\ +position: absolute;\ +z-index: 9;\ +}\ +.ace_highlight-marker {\ +background-color: rgba(255, 255, 0,0.2);\ +position: absolute;\ +z-index: 8;\ +}\ +.ace_mobile-menu {\ +position: absolute;\ +line-height: 1.5;\ +border-radius: 4px;\ +-ms-user-select: none;\ +-moz-user-select: none;\ +-webkit-user-select: none;\ +user-select: none;\ +background: white;\ +box-shadow: 1px 3px 2px grey;\ +border: 1px solid #dcdcdc;\ +color: black;\ +}\ +.ace_dark > .ace_mobile-menu {\ +background: #333;\ +color: #ccc;\ +box-shadow: 1px 3px 2px grey;\ +border: 1px solid #444;\ +}\ +.ace_mobile-button {\ +padding: 2px;\ +cursor: pointer;\ +overflow: hidden;\ +}\ +.ace_mobile-button:hover {\ +background-color: #eee;\ +opacity:1;\ +}\ +.ace_mobile-button:active {\ +background-color: #ddd;\ +}\ +.ace_placeholder {\ +font-family: arial;\ +transform: scale(0.9);\ +transform-origin: left;\ +white-space: pre;\ +opacity: 0.7;\ +margin: 0 10px;\ +}"; + +var useragent = require("./lib/useragent"); +var HIDE_TEXTAREA = useragent.isIE; + +dom.importCssString(editorCss, "ace_editor.css"); + +var VirtualRenderer = function(container, theme) { + var _self = this; + + this.container = container || dom.createElement("div"); + + dom.addCssClass(this.container, "ace_editor"); + if (dom.HI_DPI) dom.addCssClass(this.container, "ace_hidpi"); + + this.setTheme(theme); + + this.$gutter = dom.createElement("div"); + this.$gutter.className = "ace_gutter"; + this.container.appendChild(this.$gutter); + this.$gutter.setAttribute("aria-hidden", true); + + this.scroller = dom.createElement("div"); + this.scroller.className = "ace_scroller"; + + this.container.appendChild(this.scroller); + + this.content = dom.createElement("div"); + this.content.className = "ace_content"; + this.scroller.appendChild(this.content); + + this.$gutterLayer = new GutterLayer(this.$gutter); + this.$gutterLayer.on("changeGutterWidth", this.onGutterResize.bind(this)); + + this.$markerBack = new MarkerLayer(this.content); + + var textLayer = this.$textLayer = new TextLayer(this.content); + this.canvas = textLayer.element; + + this.$markerFront = new MarkerLayer(this.content); + + this.$cursorLayer = new CursorLayer(this.content); + this.$horizScroll = false; + this.$vScroll = false; + + this.scrollBar = + this.scrollBarV = new VScrollBar(this.container, this); + this.scrollBarH = new HScrollBar(this.container, this); + this.scrollBarV.on("scroll", function(e) { + if (!_self.$scrollAnimation) + _self.session.setScrollTop(e.data - _self.scrollMargin.top); + }); + this.scrollBarH.on("scroll", function(e) { + if (!_self.$scrollAnimation) + _self.session.setScrollLeft(e.data - _self.scrollMargin.left); + }); + + this.scrollTop = 0; + this.scrollLeft = 0; + + this.cursorPos = { + row : 0, + column : 0 + }; + + this.$fontMetrics = new FontMetrics(this.container); + this.$textLayer.$setFontMetrics(this.$fontMetrics); + this.$textLayer.on("changeCharacterSize", function(e) { + _self.updateCharacterSize(); + _self.onResize(true, _self.gutterWidth, _self.$size.width, _self.$size.height); + _self._signal("changeCharacterSize", e); + }); + + this.$size = { + width: 0, + height: 0, + scrollerHeight: 0, + scrollerWidth: 0, + $dirty: true + }; + + this.layerConfig = { + width : 1, + padding : 0, + firstRow : 0, + firstRowScreen: 0, + lastRow : 0, + lineHeight : 0, + characterWidth : 0, + minHeight : 1, + maxHeight : 1, + offset : 0, + height : 1, + gutterOffset: 1 + }; + + this.scrollMargin = { + left: 0, + right: 0, + top: 0, + bottom: 0, + v: 0, + h: 0 + }; + + this.margin = { + left: 0, + right: 0, + top: 0, + bottom: 0, + v: 0, + h: 0 + }; + + this.$keepTextAreaAtCursor = !useragent.isIOS; + + this.$loop = new RenderLoop( + this.$renderChanges.bind(this), + this.container.ownerDocument.defaultView + ); + this.$loop.schedule(this.CHANGE_FULL); + + this.updateCharacterSize(); + this.setPadding(4); + config.resetOptions(this); + config._signal("renderer", this); +}; + +(function() { + + this.CHANGE_CURSOR = 1; + this.CHANGE_MARKER = 2; + this.CHANGE_GUTTER = 4; + this.CHANGE_SCROLL = 8; + this.CHANGE_LINES = 16; + this.CHANGE_TEXT = 32; + this.CHANGE_SIZE = 64; + this.CHANGE_MARKER_BACK = 128; + this.CHANGE_MARKER_FRONT = 256; + this.CHANGE_FULL = 512; + this.CHANGE_H_SCROLL = 1024; + + oop.implement(this, EventEmitter); + + this.updateCharacterSize = function() { + if (this.$textLayer.allowBoldFonts != this.$allowBoldFonts) { + this.$allowBoldFonts = this.$textLayer.allowBoldFonts; + this.setStyle("ace_nobold", !this.$allowBoldFonts); + } + + this.layerConfig.characterWidth = + this.characterWidth = this.$textLayer.getCharacterWidth(); + this.layerConfig.lineHeight = + this.lineHeight = this.$textLayer.getLineHeight(); + this.$updatePrintMargin(); + dom.setStyle(this.scroller.style, "line-height", this.lineHeight + "px"); + }; + this.setSession = function(session) { + if (this.session) + this.session.doc.off("changeNewLineMode", this.onChangeNewLineMode); + + this.session = session; + if (session && this.scrollMargin.top && session.getScrollTop() <= 0) + session.setScrollTop(-this.scrollMargin.top); + + this.$cursorLayer.setSession(session); + this.$markerBack.setSession(session); + this.$markerFront.setSession(session); + this.$gutterLayer.setSession(session); + this.$textLayer.setSession(session); + if (!session) + return; + + this.$loop.schedule(this.CHANGE_FULL); + this.session.$setFontMetrics(this.$fontMetrics); + this.scrollBarH.scrollLeft = this.scrollBarV.scrollTop = null; + + this.onChangeNewLineMode = this.onChangeNewLineMode.bind(this); + this.onChangeNewLineMode(); + this.session.doc.on("changeNewLineMode", this.onChangeNewLineMode); + }; + this.updateLines = function(firstRow, lastRow, force) { + if (lastRow === undefined) + lastRow = Infinity; + + if (!this.$changedLines) { + this.$changedLines = { + firstRow: firstRow, + lastRow: lastRow + }; + } + else { + if (this.$changedLines.firstRow > firstRow) + this.$changedLines.firstRow = firstRow; + + if (this.$changedLines.lastRow < lastRow) + this.$changedLines.lastRow = lastRow; + } + if (this.$changedLines.lastRow < this.layerConfig.firstRow) { + if (force) + this.$changedLines.lastRow = this.layerConfig.lastRow; + else + return; + } + if (this.$changedLines.firstRow > this.layerConfig.lastRow) + return; + this.$loop.schedule(this.CHANGE_LINES); + }; + + this.onChangeNewLineMode = function() { + this.$loop.schedule(this.CHANGE_TEXT); + this.$textLayer.$updateEolChar(); + this.session.$bidiHandler.setEolChar(this.$textLayer.EOL_CHAR); + }; + + this.onChangeTabSize = function() { + this.$loop.schedule(this.CHANGE_TEXT | this.CHANGE_MARKER); + this.$textLayer.onChangeTabSize(); + }; + this.updateText = function() { + this.$loop.schedule(this.CHANGE_TEXT); + }; + this.updateFull = function(force) { + if (force) + this.$renderChanges(this.CHANGE_FULL, true); + else + this.$loop.schedule(this.CHANGE_FULL); + }; + this.updateFontSize = function() { + this.$textLayer.checkForSizeChanges(); + }; + + this.$changes = 0; + this.$updateSizeAsync = function() { + if (this.$loop.pending) + this.$size.$dirty = true; + else + this.onResize(); + }; + this.onResize = function(force, gutterWidth, width, height) { + if (this.resizing > 2) + return; + else if (this.resizing > 0) + this.resizing++; + else + this.resizing = force ? 1 : 0; + var el = this.container; + if (!height) + height = el.clientHeight || el.scrollHeight; + if (!width) + width = el.clientWidth || el.scrollWidth; + var changes = this.$updateCachedSize(force, gutterWidth, width, height); + + + if (!this.$size.scrollerHeight || (!width && !height)) + return this.resizing = 0; + + if (force) + this.$gutterLayer.$padding = null; + + if (force) + this.$renderChanges(changes | this.$changes, true); + else + this.$loop.schedule(changes | this.$changes); + + if (this.resizing) + this.resizing = 0; + this.scrollBarV.scrollLeft = this.scrollBarV.scrollTop = null; + }; + + this.$updateCachedSize = function(force, gutterWidth, width, height) { + height -= (this.$extraHeight || 0); + var changes = 0; + var size = this.$size; + var oldSize = { + width: size.width, + height: size.height, + scrollerHeight: size.scrollerHeight, + scrollerWidth: size.scrollerWidth + }; + if (height && (force || size.height != height)) { + size.height = height; + changes |= this.CHANGE_SIZE; + + size.scrollerHeight = size.height; + if (this.$horizScroll) + size.scrollerHeight -= this.scrollBarH.getHeight(); + this.scrollBarV.element.style.bottom = this.scrollBarH.getHeight() + "px"; + + changes = changes | this.CHANGE_SCROLL; + } + + if (width && (force || size.width != width)) { + changes |= this.CHANGE_SIZE; + size.width = width; + + if (gutterWidth == null) + gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0; + + this.gutterWidth = gutterWidth; + + dom.setStyle(this.scrollBarH.element.style, "left", gutterWidth + "px"); + dom.setStyle(this.scroller.style, "left", gutterWidth + this.margin.left + "px"); + size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBarV.getWidth() - this.margin.h); + dom.setStyle(this.$gutter.style, "left", this.margin.left + "px"); + + var right = this.scrollBarV.getWidth() + "px"; + dom.setStyle(this.scrollBarH.element.style, "right", right); + dom.setStyle(this.scroller.style, "right", right); + dom.setStyle(this.scroller.style, "bottom", this.scrollBarH.getHeight()); + + if (this.session && this.session.getUseWrapMode() && this.adjustWrapLimit() || force) { + changes |= this.CHANGE_FULL; + } + } + + size.$dirty = !width || !height; + + if (changes) + this._signal("resize", oldSize); + + return changes; + }; + + this.onGutterResize = function(width) { + var gutterWidth = this.$showGutter ? width : 0; + if (gutterWidth != this.gutterWidth) + this.$changes |= this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height); + + if (this.session.getUseWrapMode() && this.adjustWrapLimit()) { + this.$loop.schedule(this.CHANGE_FULL); + } else if (this.$size.$dirty) { + this.$loop.schedule(this.CHANGE_FULL); + } else { + this.$computeLayerConfig(); + } + }; + this.adjustWrapLimit = function() { + var availableWidth = this.$size.scrollerWidth - this.$padding * 2; + var limit = Math.floor(availableWidth / this.characterWidth); + return this.session.adjustWrapLimit(limit, this.$showPrintMargin && this.$printMarginColumn); + }; + this.setAnimatedScroll = function(shouldAnimate){ + this.setOption("animatedScroll", shouldAnimate); + }; + this.getAnimatedScroll = function() { + return this.$animatedScroll; + }; + this.setShowInvisibles = function(showInvisibles) { + this.setOption("showInvisibles", showInvisibles); + this.session.$bidiHandler.setShowInvisibles(showInvisibles); + }; + this.getShowInvisibles = function() { + return this.getOption("showInvisibles"); + }; + this.getDisplayIndentGuides = function() { + return this.getOption("displayIndentGuides"); + }; + + this.setDisplayIndentGuides = function(display) { + this.setOption("displayIndentGuides", display); + }; + this.setShowPrintMargin = function(showPrintMargin) { + this.setOption("showPrintMargin", showPrintMargin); + }; + this.getShowPrintMargin = function() { + return this.getOption("showPrintMargin"); + }; + this.setPrintMarginColumn = function(showPrintMargin) { + this.setOption("printMarginColumn", showPrintMargin); + }; + this.getPrintMarginColumn = function() { + return this.getOption("printMarginColumn"); + }; + this.getShowGutter = function(){ + return this.getOption("showGutter"); + }; + this.setShowGutter = function(show){ + return this.setOption("showGutter", show); + }; + + this.getFadeFoldWidgets = function(){ + return this.getOption("fadeFoldWidgets"); + }; + + this.setFadeFoldWidgets = function(show) { + this.setOption("fadeFoldWidgets", show); + }; + + this.setHighlightGutterLine = function(shouldHighlight) { + this.setOption("highlightGutterLine", shouldHighlight); + }; + + this.getHighlightGutterLine = function() { + return this.getOption("highlightGutterLine"); + }; + + this.$updatePrintMargin = function() { + if (!this.$showPrintMargin && !this.$printMarginEl) + return; + + if (!this.$printMarginEl) { + var containerEl = dom.createElement("div"); + containerEl.className = "ace_layer ace_print-margin-layer"; + this.$printMarginEl = dom.createElement("div"); + this.$printMarginEl.className = "ace_print-margin"; + containerEl.appendChild(this.$printMarginEl); + this.content.insertBefore(containerEl, this.content.firstChild); + } + + var style = this.$printMarginEl.style; + style.left = Math.round(this.characterWidth * this.$printMarginColumn + this.$padding) + "px"; + style.visibility = this.$showPrintMargin ? "visible" : "hidden"; + + if (this.session && this.session.$wrap == -1) + this.adjustWrapLimit(); + }; + this.getContainerElement = function() { + return this.container; + }; + this.getMouseEventTarget = function() { + return this.scroller; + }; + this.getTextAreaContainer = function() { + return this.container; + }; + this.$moveTextAreaToCursor = function() { + if (this.$isMousePressed) return; + var style = this.textarea.style; + var composition = this.$composition; + if (!this.$keepTextAreaAtCursor && !composition) { + dom.translate(this.textarea, -100, 0); + return; + } + var pixelPos = this.$cursorLayer.$pixelPos; + if (!pixelPos) + return; + if (composition && composition.markerRange) + pixelPos = this.$cursorLayer.getPixelPosition(composition.markerRange.start, true); + + var config = this.layerConfig; + var posTop = pixelPos.top; + var posLeft = pixelPos.left; + posTop -= config.offset; + + var h = composition && composition.useTextareaForIME ? this.lineHeight : HIDE_TEXTAREA ? 0 : 1; + if (posTop < 0 || posTop > config.height - h) { + dom.translate(this.textarea, 0, 0); + return; + } + + var w = 1; + var maxTop = this.$size.height - h; + if (!composition) { + posTop += this.lineHeight; + } + else { + if (composition.useTextareaForIME) { + var val = this.textarea.value; + w = this.characterWidth * (this.session.$getStringScreenWidth(val)[0]); + } + else { + posTop += this.lineHeight + 2; + } + } + + posLeft -= this.scrollLeft; + if (posLeft > this.$size.scrollerWidth - w) + posLeft = this.$size.scrollerWidth - w; + + posLeft += this.gutterWidth + this.margin.left; + + dom.setStyle(style, "height", h + "px"); + dom.setStyle(style, "width", w + "px"); + dom.translate(this.textarea, Math.min(posLeft, this.$size.scrollerWidth - w), Math.min(posTop, maxTop)); + }; + this.getFirstVisibleRow = function() { + return this.layerConfig.firstRow; + }; + this.getFirstFullyVisibleRow = function() { + return this.layerConfig.firstRow + (this.layerConfig.offset === 0 ? 0 : 1); + }; + this.getLastFullyVisibleRow = function() { + var config = this.layerConfig; + var lastRow = config.lastRow; + var top = this.session.documentToScreenRow(lastRow, 0) * config.lineHeight; + if (top - this.session.getScrollTop() > config.height - config.lineHeight) + return lastRow - 1; + return lastRow; + }; + this.getLastVisibleRow = function() { + return this.layerConfig.lastRow; + }; + + this.$padding = null; + this.setPadding = function(padding) { + this.$padding = padding; + this.$textLayer.setPadding(padding); + this.$cursorLayer.setPadding(padding); + this.$markerFront.setPadding(padding); + this.$markerBack.setPadding(padding); + this.$loop.schedule(this.CHANGE_FULL); + this.$updatePrintMargin(); + }; + + this.setScrollMargin = function(top, bottom, left, right) { + var sm = this.scrollMargin; + sm.top = top|0; + sm.bottom = bottom|0; + sm.right = right|0; + sm.left = left|0; + sm.v = sm.top + sm.bottom; + sm.h = sm.left + sm.right; + if (sm.top && this.scrollTop <= 0 && this.session) + this.session.setScrollTop(-sm.top); + this.updateFull(); + }; + + this.setMargin = function(top, bottom, left, right) { + var sm = this.margin; + sm.top = top|0; + sm.bottom = bottom|0; + sm.right = right|0; + sm.left = left|0; + sm.v = sm.top + sm.bottom; + sm.h = sm.left + sm.right; + this.$updateCachedSize(true, this.gutterWidth, this.$size.width, this.$size.height); + this.updateFull(); + }; + this.getHScrollBarAlwaysVisible = function() { + return this.$hScrollBarAlwaysVisible; + }; + this.setHScrollBarAlwaysVisible = function(alwaysVisible) { + this.setOption("hScrollBarAlwaysVisible", alwaysVisible); + }; + this.getVScrollBarAlwaysVisible = function() { + return this.$vScrollBarAlwaysVisible; + }; + this.setVScrollBarAlwaysVisible = function(alwaysVisible) { + this.setOption("vScrollBarAlwaysVisible", alwaysVisible); + }; + + this.$updateScrollBarV = function() { + var scrollHeight = this.layerConfig.maxHeight; + var scrollerHeight = this.$size.scrollerHeight; + if (!this.$maxLines && this.$scrollPastEnd) { + scrollHeight -= (scrollerHeight - this.lineHeight) * this.$scrollPastEnd; + if (this.scrollTop > scrollHeight - scrollerHeight) { + scrollHeight = this.scrollTop + scrollerHeight; + this.scrollBarV.scrollTop = null; + } + } + this.scrollBarV.setScrollHeight(scrollHeight + this.scrollMargin.v); + this.scrollBarV.setScrollTop(this.scrollTop + this.scrollMargin.top); + }; + this.$updateScrollBarH = function() { + this.scrollBarH.setScrollWidth(this.layerConfig.width + 2 * this.$padding + this.scrollMargin.h); + this.scrollBarH.setScrollLeft(this.scrollLeft + this.scrollMargin.left); + }; + + this.$frozen = false; + this.freeze = function() { + this.$frozen = true; + }; + + this.unfreeze = function() { + this.$frozen = false; + }; + + this.$renderChanges = function(changes, force) { + if (this.$changes) { + changes |= this.$changes; + this.$changes = 0; + } + if ((!this.session || !this.container.offsetWidth || this.$frozen) || (!changes && !force)) { + this.$changes |= changes; + return; + } + if (this.$size.$dirty) { + this.$changes |= changes; + return this.onResize(true); + } + if (!this.lineHeight) { + this.$textLayer.checkForSizeChanges(); + } + + this._signal("beforeRender", changes); + + if (this.session && this.session.$bidiHandler) + this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics); + + var config = this.layerConfig; + if (changes & this.CHANGE_FULL || + changes & this.CHANGE_SIZE || + changes & this.CHANGE_TEXT || + changes & this.CHANGE_LINES || + changes & this.CHANGE_SCROLL || + changes & this.CHANGE_H_SCROLL + ) { + changes |= this.$computeLayerConfig() | this.$loop.clear(); + if (config.firstRow != this.layerConfig.firstRow && config.firstRowScreen == this.layerConfig.firstRowScreen) { + var st = this.scrollTop + (config.firstRow - this.layerConfig.firstRow) * this.lineHeight; + if (st > 0) { + this.scrollTop = st; + changes = changes | this.CHANGE_SCROLL; + changes |= this.$computeLayerConfig() | this.$loop.clear(); + } + } + config = this.layerConfig; + this.$updateScrollBarV(); + if (changes & this.CHANGE_H_SCROLL) + this.$updateScrollBarH(); + + dom.translate(this.content, -this.scrollLeft, -config.offset); + + var width = config.width + 2 * this.$padding + "px"; + var height = config.minHeight + "px"; + + dom.setStyle(this.content.style, "width", width); + dom.setStyle(this.content.style, "height", height); + } + if (changes & this.CHANGE_H_SCROLL) { + dom.translate(this.content, -this.scrollLeft, -config.offset); + this.scroller.className = this.scrollLeft <= 0 ? "ace_scroller" : "ace_scroller ace_scroll-left"; + } + if (changes & this.CHANGE_FULL) { + this.$changedLines = null; + this.$textLayer.update(config); + if (this.$showGutter) + this.$gutterLayer.update(config); + this.$markerBack.update(config); + this.$markerFront.update(config); + this.$cursorLayer.update(config); + this.$moveTextAreaToCursor(); + this._signal("afterRender", changes); + return; + } + if (changes & this.CHANGE_SCROLL) { + this.$changedLines = null; + if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES) + this.$textLayer.update(config); + else + this.$textLayer.scrollLines(config); + + if (this.$showGutter) { + if (changes & this.CHANGE_GUTTER || changes & this.CHANGE_LINES) + this.$gutterLayer.update(config); + else + this.$gutterLayer.scrollLines(config); + } + this.$markerBack.update(config); + this.$markerFront.update(config); + this.$cursorLayer.update(config); + this.$moveTextAreaToCursor(); + this._signal("afterRender", changes); + return; + } + + if (changes & this.CHANGE_TEXT) { + this.$changedLines = null; + this.$textLayer.update(config); + if (this.$showGutter) + this.$gutterLayer.update(config); + } + else if (changes & this.CHANGE_LINES) { + if (this.$updateLines() || (changes & this.CHANGE_GUTTER) && this.$showGutter) + this.$gutterLayer.update(config); + } + else if (changes & this.CHANGE_TEXT || changes & this.CHANGE_GUTTER) { + if (this.$showGutter) + this.$gutterLayer.update(config); + } + else if (changes & this.CHANGE_CURSOR) { + if (this.$highlightGutterLine) + this.$gutterLayer.updateLineHighlight(config); + } + + if (changes & this.CHANGE_CURSOR) { + this.$cursorLayer.update(config); + this.$moveTextAreaToCursor(); + } + + if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) { + this.$markerFront.update(config); + } + + if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) { + this.$markerBack.update(config); + } + + this._signal("afterRender", changes); + }; + + + this.$autosize = function() { + var height = this.session.getScreenLength() * this.lineHeight; + var maxHeight = this.$maxLines * this.lineHeight; + var desiredHeight = Math.min(maxHeight, + Math.max((this.$minLines || 1) * this.lineHeight, height) + ) + this.scrollMargin.v + (this.$extraHeight || 0); + if (this.$horizScroll) + desiredHeight += this.scrollBarH.getHeight(); + if (this.$maxPixelHeight && desiredHeight > this.$maxPixelHeight) + desiredHeight = this.$maxPixelHeight; + + var hideScrollbars = desiredHeight <= 2 * this.lineHeight; + var vScroll = !hideScrollbars && height > maxHeight; + + if (desiredHeight != this.desiredHeight || + this.$size.height != this.desiredHeight || vScroll != this.$vScroll) { + if (vScroll != this.$vScroll) { + this.$vScroll = vScroll; + this.scrollBarV.setVisible(vScroll); + } + + var w = this.container.clientWidth; + this.container.style.height = desiredHeight + "px"; + this.$updateCachedSize(true, this.$gutterWidth, w, desiredHeight); + this.desiredHeight = desiredHeight; + + this._signal("autosize"); + } + }; + + this.$computeLayerConfig = function() { + var session = this.session; + var size = this.$size; + + var hideScrollbars = size.height <= 2 * this.lineHeight; + var screenLines = this.session.getScreenLength(); + var maxHeight = screenLines * this.lineHeight; + + var longestLine = this.$getLongestLine(); + + var horizScroll = !hideScrollbars && (this.$hScrollBarAlwaysVisible || + size.scrollerWidth - longestLine - 2 * this.$padding < 0); + + var hScrollChanged = this.$horizScroll !== horizScroll; + if (hScrollChanged) { + this.$horizScroll = horizScroll; + this.scrollBarH.setVisible(horizScroll); + } + var vScrollBefore = this.$vScroll; // autosize can change vscroll value in which case we need to update longestLine + if (this.$maxLines && this.lineHeight > 1) + this.$autosize(); + + var minHeight = size.scrollerHeight + this.lineHeight; + + var scrollPastEnd = !this.$maxLines && this.$scrollPastEnd + ? (size.scrollerHeight - this.lineHeight) * this.$scrollPastEnd + : 0; + maxHeight += scrollPastEnd; + + var sm = this.scrollMargin; + this.session.setScrollTop(Math.max(-sm.top, + Math.min(this.scrollTop, maxHeight - size.scrollerHeight + sm.bottom))); + + this.session.setScrollLeft(Math.max(-sm.left, Math.min(this.scrollLeft, + longestLine + 2 * this.$padding - size.scrollerWidth + sm.right))); + + var vScroll = !hideScrollbars && (this.$vScrollBarAlwaysVisible || + size.scrollerHeight - maxHeight + scrollPastEnd < 0 || this.scrollTop > sm.top); + var vScrollChanged = vScrollBefore !== vScroll; + if (vScrollChanged) { + this.$vScroll = vScroll; + this.scrollBarV.setVisible(vScroll); + } + + var offset = this.scrollTop % this.lineHeight; + var lineCount = Math.ceil(minHeight / this.lineHeight) - 1; + var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight)); + var lastRow = firstRow + lineCount; + var firstRowScreen, firstRowHeight; + var lineHeight = this.lineHeight; + firstRow = session.screenToDocumentRow(firstRow, 0); + var foldLine = session.getFoldLine(firstRow); + if (foldLine) { + firstRow = foldLine.start.row; + } + + firstRowScreen = session.documentToScreenRow(firstRow, 0); + firstRowHeight = session.getRowLength(firstRow) * lineHeight; + + lastRow = Math.min(session.screenToDocumentRow(lastRow, 0), session.getLength() - 1); + minHeight = size.scrollerHeight + session.getRowLength(lastRow) * lineHeight + + firstRowHeight; + + offset = this.scrollTop - firstRowScreen * lineHeight; + + var changes = 0; + if (this.layerConfig.width != longestLine || hScrollChanged) + changes = this.CHANGE_H_SCROLL; + if (hScrollChanged || vScrollChanged) { + changes |= this.$updateCachedSize(true, this.gutterWidth, size.width, size.height); + this._signal("scrollbarVisibilityChanged"); + if (vScrollChanged) + longestLine = this.$getLongestLine(); + } + + this.layerConfig = { + width : longestLine, + padding : this.$padding, + firstRow : firstRow, + firstRowScreen: firstRowScreen, + lastRow : lastRow, + lineHeight : lineHeight, + characterWidth : this.characterWidth, + minHeight : minHeight, + maxHeight : maxHeight, + offset : offset, + gutterOffset : lineHeight ? Math.max(0, Math.ceil((offset + size.height - size.scrollerHeight) / lineHeight)) : 0, + height : this.$size.scrollerHeight + }; + + if (this.session.$bidiHandler) + this.session.$bidiHandler.setContentWidth(longestLine - this.$padding); + + return changes; + }; + + this.$updateLines = function() { + if (!this.$changedLines) return; + var firstRow = this.$changedLines.firstRow; + var lastRow = this.$changedLines.lastRow; + this.$changedLines = null; + + var layerConfig = this.layerConfig; + + if (firstRow > layerConfig.lastRow + 1) { return; } + if (lastRow < layerConfig.firstRow) { return; } + if (lastRow === Infinity) { + if (this.$showGutter) + this.$gutterLayer.update(layerConfig); + this.$textLayer.update(layerConfig); + return; + } + this.$textLayer.updateLines(layerConfig, firstRow, lastRow); + return true; + }; + + this.$getLongestLine = function() { + var charCount = this.session.getScreenWidth(); + if (this.showInvisibles && !this.session.$useWrapMode) + charCount += 1; + + if (this.$textLayer && charCount > this.$textLayer.MAX_LINE_LENGTH) + charCount = this.$textLayer.MAX_LINE_LENGTH + 30; + + return Math.max(this.$size.scrollerWidth - 2 * this.$padding, Math.round(charCount * this.characterWidth)); + }; + this.updateFrontMarkers = function() { + this.$markerFront.setMarkers(this.session.getMarkers(true)); + this.$loop.schedule(this.CHANGE_MARKER_FRONT); + }; + this.updateBackMarkers = function() { + this.$markerBack.setMarkers(this.session.getMarkers()); + this.$loop.schedule(this.CHANGE_MARKER_BACK); + }; + this.addGutterDecoration = function(row, className){ + this.$gutterLayer.addGutterDecoration(row, className); + }; + this.removeGutterDecoration = function(row, className){ + this.$gutterLayer.removeGutterDecoration(row, className); + }; + this.updateBreakpoints = function(rows) { + this.$loop.schedule(this.CHANGE_GUTTER); + }; + this.setAnnotations = function(annotations) { + this.$gutterLayer.setAnnotations(annotations); + this.$loop.schedule(this.CHANGE_GUTTER); + }; + this.updateCursor = function() { + this.$loop.schedule(this.CHANGE_CURSOR); + }; + this.hideCursor = function() { + this.$cursorLayer.hideCursor(); + }; + this.showCursor = function() { + this.$cursorLayer.showCursor(); + }; + + this.scrollSelectionIntoView = function(anchor, lead, offset) { + this.scrollCursorIntoView(anchor, offset); + this.scrollCursorIntoView(lead, offset); + }; + this.scrollCursorIntoView = function(cursor, offset, $viewMargin) { + if (this.$size.scrollerHeight === 0) + return; + + var pos = this.$cursorLayer.getPixelPosition(cursor); + + var left = pos.left; + var top = pos.top; + + var topMargin = $viewMargin && $viewMargin.top || 0; + var bottomMargin = $viewMargin && $viewMargin.bottom || 0; + + var scrollTop = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop; + + if (scrollTop + topMargin > top) { + if (offset && scrollTop + topMargin > top + this.lineHeight) + top -= offset * this.$size.scrollerHeight; + if (top === 0) + top = -this.scrollMargin.top; + this.session.setScrollTop(top); + } else if (scrollTop + this.$size.scrollerHeight - bottomMargin < top + this.lineHeight) { + if (offset && scrollTop + this.$size.scrollerHeight - bottomMargin < top - this.lineHeight) + top += offset * this.$size.scrollerHeight; + this.session.setScrollTop(top + this.lineHeight + bottomMargin - this.$size.scrollerHeight); + } + + var scrollLeft = this.scrollLeft; + + if (scrollLeft > left) { + if (left < this.$padding + 2 * this.layerConfig.characterWidth) + left = -this.scrollMargin.left; + this.session.setScrollLeft(left); + } else if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) { + this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth)); + } else if (scrollLeft <= this.$padding && left - scrollLeft < this.characterWidth) { + this.session.setScrollLeft(0); + } + }; + this.getScrollTop = function() { + return this.session.getScrollTop(); + }; + this.getScrollLeft = function() { + return this.session.getScrollLeft(); + }; + this.getScrollTopRow = function() { + return this.scrollTop / this.lineHeight; + }; + this.getScrollBottomRow = function() { + return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1); + }; + this.scrollToRow = function(row) { + this.session.setScrollTop(row * this.lineHeight); + }; + + this.alignCursor = function(cursor, alignment) { + if (typeof cursor == "number") + cursor = {row: cursor, column: 0}; + + var pos = this.$cursorLayer.getPixelPosition(cursor); + var h = this.$size.scrollerHeight - this.lineHeight; + var offset = pos.top - h * (alignment || 0); + + this.session.setScrollTop(offset); + return offset; + }; + + this.STEPS = 8; + this.$calcSteps = function(fromValue, toValue){ + var i = 0; + var l = this.STEPS; + var steps = []; + + var func = function(t, x_min, dx) { + return dx * (Math.pow(t - 1, 3) + 1) + x_min; + }; + + for (i = 0; i < l; ++i) + steps.push(func(i / this.STEPS, fromValue, toValue - fromValue)); + + return steps; + }; + this.scrollToLine = function(line, center, animate, callback) { + var pos = this.$cursorLayer.getPixelPosition({row: line, column: 0}); + var offset = pos.top; + if (center) + offset -= this.$size.scrollerHeight / 2; + + var initialScroll = this.scrollTop; + this.session.setScrollTop(offset); + if (animate !== false) + this.animateScrolling(initialScroll, callback); + }; + + this.animateScrolling = function(fromValue, callback) { + var toValue = this.scrollTop; + if (!this.$animatedScroll) + return; + var _self = this; + + if (fromValue == toValue) + return; + + if (this.$scrollAnimation) { + var oldSteps = this.$scrollAnimation.steps; + if (oldSteps.length) { + fromValue = oldSteps[0]; + if (fromValue == toValue) + return; + } + } + + var steps = _self.$calcSteps(fromValue, toValue); + this.$scrollAnimation = {from: fromValue, to: toValue, steps: steps}; + + clearInterval(this.$timer); + + _self.session.setScrollTop(steps.shift()); + _self.session.$scrollTop = toValue; + this.$timer = setInterval(function() { + if (!_self.session) + return clearInterval(_self.$timer); + if (steps.length) { + _self.session.setScrollTop(steps.shift()); + _self.session.$scrollTop = toValue; + } else if (toValue != null) { + _self.session.$scrollTop = -1; + _self.session.setScrollTop(toValue); + toValue = null; + } else { + _self.$timer = clearInterval(_self.$timer); + _self.$scrollAnimation = null; + callback && callback(); + } + }, 10); + }; + this.scrollToY = function(scrollTop) { + if (this.scrollTop !== scrollTop) { + this.$loop.schedule(this.CHANGE_SCROLL); + this.scrollTop = scrollTop; + } + }; + this.scrollToX = function(scrollLeft) { + if (this.scrollLeft !== scrollLeft) + this.scrollLeft = scrollLeft; + this.$loop.schedule(this.CHANGE_H_SCROLL); + }; + this.scrollTo = function(x, y) { + this.session.setScrollTop(y); + this.session.setScrollLeft(y); + }; + this.scrollBy = function(deltaX, deltaY) { + deltaY && this.session.setScrollTop(this.session.getScrollTop() + deltaY); + deltaX && this.session.setScrollLeft(this.session.getScrollLeft() + deltaX); + }; + this.isScrollableBy = function(deltaX, deltaY) { + if (deltaY < 0 && this.session.getScrollTop() >= 1 - this.scrollMargin.top) + return true; + if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight + - this.layerConfig.maxHeight < -1 + this.scrollMargin.bottom) + return true; + if (deltaX < 0 && this.session.getScrollLeft() >= 1 - this.scrollMargin.left) + return true; + if (deltaX > 0 && this.session.getScrollLeft() + this.$size.scrollerWidth + - this.layerConfig.width < -1 + this.scrollMargin.right) + return true; + }; + + this.pixelToScreenCoordinates = function(x, y) { + var canvasPos; + if (this.$hasCssTransforms) { + canvasPos = {top:0, left: 0}; + var p = this.$fontMetrics.transformCoordinates([x, y]); + x = p[1] - this.gutterWidth - this.margin.left; + y = p[0]; + } else { + canvasPos = this.scroller.getBoundingClientRect(); + } + + var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding; + var offset = offsetX / this.characterWidth; + var row = Math.floor((y + this.scrollTop - canvasPos.top) / this.lineHeight); + var col = this.$blockCursor ? Math.floor(offset) : Math.round(offset); + + return {row: row, column: col, side: offset - col > 0 ? 1 : -1, offsetX: offsetX}; + }; + + this.screenToTextCoordinates = function(x, y) { + var canvasPos; + if (this.$hasCssTransforms) { + canvasPos = {top:0, left: 0}; + var p = this.$fontMetrics.transformCoordinates([x, y]); + x = p[1] - this.gutterWidth - this.margin.left; + y = p[0]; + } else { + canvasPos = this.scroller.getBoundingClientRect(); + } + + var offsetX = x + this.scrollLeft - canvasPos.left - this.$padding; + var offset = offsetX / this.characterWidth; + var col = this.$blockCursor ? Math.floor(offset) : Math.round(offset); + + var row = Math.floor((y + this.scrollTop - canvasPos.top) / this.lineHeight); + + return this.session.screenToDocumentPosition(row, Math.max(col, 0), offsetX); + }; + this.textToScreenCoordinates = function(row, column) { + var canvasPos = this.scroller.getBoundingClientRect(); + var pos = this.session.documentToScreenPosition(row, column); + + var x = this.$padding + (this.session.$bidiHandler.isBidiRow(pos.row, row) + ? this.session.$bidiHandler.getPosLeft(pos.column) + : Math.round(pos.column * this.characterWidth)); + + var y = pos.row * this.lineHeight; + + return { + pageX: canvasPos.left + x - this.scrollLeft, + pageY: canvasPos.top + y - this.scrollTop + }; + }; + this.visualizeFocus = function() { + dom.addCssClass(this.container, "ace_focus"); + }; + this.visualizeBlur = function() { + dom.removeCssClass(this.container, "ace_focus"); + }; + this.showComposition = function(composition) { + this.$composition = composition; + if (!composition.cssText) { + composition.cssText = this.textarea.style.cssText; + } + if (composition.useTextareaForIME == undefined) + composition.useTextareaForIME = this.$useTextareaForIME; + + if (this.$useTextareaForIME) { + dom.addCssClass(this.textarea, "ace_composition"); + this.textarea.style.cssText = ""; + this.$moveTextAreaToCursor(); + this.$cursorLayer.element.style.display = "none"; + } + else { + composition.markerId = this.session.addMarker(composition.markerRange, "ace_composition_marker", "text"); + } + }; + this.setCompositionText = function(text) { + var cursor = this.session.selection.cursor; + this.addToken(text, "composition_placeholder", cursor.row, cursor.column); + this.$moveTextAreaToCursor(); + }; + this.hideComposition = function() { + if (!this.$composition) + return; + + if (this.$composition.markerId) + this.session.removeMarker(this.$composition.markerId); + + dom.removeCssClass(this.textarea, "ace_composition"); + this.textarea.style.cssText = this.$composition.cssText; + var cursor = this.session.selection.cursor; + this.removeExtraToken(cursor.row, cursor.column); + this.$composition = null; + this.$cursorLayer.element.style.display = ""; + }; + + this.addToken = function(text, type, row, column) { + var session = this.session; + session.bgTokenizer.lines[row] = null; + var newToken = {type: type, value: text}; + var tokens = session.getTokens(row); + if (column == null) { + tokens.push(newToken); + } else { + var l = 0; + for (var i =0; i < tokens.length; i++) { + var token = tokens[i]; + l += token.value.length; + if (column <= l) { + var diff = token.value.length - (l - column); + var before = token.value.slice(0, diff); + var after = token.value.slice(diff); + + tokens.splice(i, 1, {type: token.type, value: before}, newToken, {type: token.type, value: after}); + break; + } + } + } + this.updateLines(row, row); + }; + + this.removeExtraToken = function(row, column) { + this.updateLines(row, row); + }; + this.setTheme = function(theme, cb) { + var _self = this; + this.$themeId = theme; + _self._dispatchEvent('themeChange',{theme:theme}); + + if (!theme || typeof theme == "string") { + var moduleName = theme || this.$options.theme.initialValue; + config.loadModule(["theme", moduleName], afterLoad); + } else { + afterLoad(theme); + } + + function afterLoad(module) { + if (_self.$themeId != theme) + return cb && cb(); + if (!module || !module.cssClass) + throw new Error("couldn't load module " + theme + " or it didn't call define"); + if (module.$id) + _self.$themeId = module.$id; + dom.importCssString( + module.cssText, + module.cssClass, + _self.container + ); + + if (_self.theme) + dom.removeCssClass(_self.container, _self.theme.cssClass); + + var padding = "padding" in module ? module.padding + : "padding" in (_self.theme || {}) ? 4 : _self.$padding; + if (_self.$padding && padding != _self.$padding) + _self.setPadding(padding); + _self.$theme = module.cssClass; + + _self.theme = module; + dom.addCssClass(_self.container, module.cssClass); + dom.setCssClass(_self.container, "ace_dark", module.isDark); + if (_self.$size) { + _self.$size.width = 0; + _self.$updateSizeAsync(); + } + + _self._dispatchEvent('themeLoaded', {theme:module}); + cb && cb(); + } + }; + this.getTheme = function() { + return this.$themeId; + }; + this.setStyle = function(style, include) { + dom.setCssClass(this.container, style, include !== false); + }; + this.unsetStyle = function(style) { + dom.removeCssClass(this.container, style); + }; + + this.setCursorStyle = function(style) { + dom.setStyle(this.scroller.style, "cursor", style); + }; + this.setMouseCursor = function(cursorStyle) { + dom.setStyle(this.scroller.style, "cursor", cursorStyle); + }; + + this.attachToShadowRoot = function() { + dom.importCssString(editorCss, "ace_editor.css", this.container); + }; + this.destroy = function() { + this.freeze(); + this.$fontMetrics.destroy(); + this.$cursorLayer.destroy(); + this.removeAllListeners(); + this.container.textContent = ""; + }; + +}).call(VirtualRenderer.prototype); + + +config.defineOptions(VirtualRenderer.prototype, "renderer", { + animatedScroll: {initialValue: false}, + showInvisibles: { + set: function(value) { + if (this.$textLayer.setShowInvisibles(value)) + this.$loop.schedule(this.CHANGE_TEXT); + }, + initialValue: false + }, + showPrintMargin: { + set: function() { this.$updatePrintMargin(); }, + initialValue: true + }, + printMarginColumn: { + set: function() { this.$updatePrintMargin(); }, + initialValue: 80 + }, + printMargin: { + set: function(val) { + if (typeof val == "number") + this.$printMarginColumn = val; + this.$showPrintMargin = !!val; + this.$updatePrintMargin(); + }, + get: function() { + return this.$showPrintMargin && this.$printMarginColumn; + } + }, + showGutter: { + set: function(show){ + this.$gutter.style.display = show ? "block" : "none"; + this.$loop.schedule(this.CHANGE_FULL); + this.onGutterResize(); + }, + initialValue: true + }, + fadeFoldWidgets: { + set: function(show) { + dom.setCssClass(this.$gutter, "ace_fade-fold-widgets", show); + }, + initialValue: false + }, + showFoldWidgets: { + set: function(show) { + this.$gutterLayer.setShowFoldWidgets(show); + this.$loop.schedule(this.CHANGE_GUTTER); + }, + initialValue: true + }, + displayIndentGuides: { + set: function(show) { + if (this.$textLayer.setDisplayIndentGuides(show)) + this.$loop.schedule(this.CHANGE_TEXT); + }, + initialValue: true + }, + highlightGutterLine: { + set: function(shouldHighlight) { + this.$gutterLayer.setHighlightGutterLine(shouldHighlight); + this.$loop.schedule(this.CHANGE_GUTTER); + }, + initialValue: true + }, + hScrollBarAlwaysVisible: { + set: function(val) { + if (!this.$hScrollBarAlwaysVisible || !this.$horizScroll) + this.$loop.schedule(this.CHANGE_SCROLL); + }, + initialValue: false + }, + vScrollBarAlwaysVisible: { + set: function(val) { + if (!this.$vScrollBarAlwaysVisible || !this.$vScroll) + this.$loop.schedule(this.CHANGE_SCROLL); + }, + initialValue: false + }, + fontSize: { + set: function(size) { + if (typeof size == "number") + size = size + "px"; + this.container.style.fontSize = size; + this.updateFontSize(); + }, + initialValue: 12 + }, + fontFamily: { + set: function(name) { + this.container.style.fontFamily = name; + this.updateFontSize(); + } + }, + maxLines: { + set: function(val) { + this.updateFull(); + } + }, + minLines: { + set: function(val) { + if (!(this.$minLines < 0x1ffffffffffff)) + this.$minLines = 0; + this.updateFull(); + } + }, + maxPixelHeight: { + set: function(val) { + this.updateFull(); + }, + initialValue: 0 + }, + scrollPastEnd: { + set: function(val) { + val = +val || 0; + if (this.$scrollPastEnd == val) + return; + this.$scrollPastEnd = val; + this.$loop.schedule(this.CHANGE_SCROLL); + }, + initialValue: 0, + handlesSet: true + }, + fixedWidthGutter: { + set: function(val) { + this.$gutterLayer.$fixedWidth = !!val; + this.$loop.schedule(this.CHANGE_GUTTER); + } + }, + theme: { + set: function(val) { this.setTheme(val); }, + get: function() { return this.$themeId || this.theme; }, + initialValue: "./theme/textmate", + handlesSet: true + }, + hasCssTransforms: { + }, + useTextareaForIME: { + initialValue: !useragent.isMobile && !useragent.isIE + } +}); + +exports.VirtualRenderer = VirtualRenderer; +}); + +ace.define("ace/worker/worker_client",["require","exports","module","ace/lib/oop","ace/lib/net","ace/lib/event_emitter","ace/config"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var net = require("../lib/net"); +var EventEmitter = require("../lib/event_emitter").EventEmitter; +var config = require("../config"); + +function $workerBlob(workerUrl) { + var script = "importScripts('" + net.qualifyURL(workerUrl) + "');"; + try { + return new Blob([script], {"type": "application/javascript"}); + } catch (e) { // Backwards-compatibility + var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder; + var blobBuilder = new BlobBuilder(); + blobBuilder.append(script); + return blobBuilder.getBlob("application/javascript"); + } +} + +function createWorker(workerUrl) { + if (typeof Worker == "undefined") + return { postMessage: function() {}, terminate: function() {} }; + if (config.get("loadWorkerFromBlob")) { + var blob = $workerBlob(workerUrl); + var URL = window.URL || window.webkitURL; + var blobURL = URL.createObjectURL(blob); + return new Worker(blobURL); + } + return new Worker(workerUrl); +} + +var WorkerClient = function(worker) { + if (!worker.postMessage) + worker = this.$createWorkerFromOldConfig.apply(this, arguments); + + this.$worker = worker; + this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this); + this.changeListener = this.changeListener.bind(this); + this.onMessage = this.onMessage.bind(this); + + this.callbackId = 1; + this.callbacks = {}; + + this.$worker.onmessage = this.onMessage; +}; + +(function(){ + + oop.implement(this, EventEmitter); + + this.$createWorkerFromOldConfig = function(topLevelNamespaces, mod, classname, workerUrl, importScripts) { + if (require.nameToUrl && !require.toUrl) + require.toUrl = require.nameToUrl; + + if (config.get("packaged") || !require.toUrl) { + workerUrl = workerUrl || config.moduleUrl(mod, "worker"); + } else { + var normalizePath = this.$normalizePath; + workerUrl = workerUrl || normalizePath(require.toUrl("ace/worker/worker.js", null, "_")); + + var tlns = {}; + topLevelNamespaces.forEach(function(ns) { + tlns[ns] = normalizePath(require.toUrl(ns, null, "_").replace(/(\.js)?(\?.*)?$/, "")); + }); + } + + this.$worker = createWorker(workerUrl); + if (importScripts) { + this.send("importScripts", importScripts); + } + this.$worker.postMessage({ + init : true, + tlns : tlns, + module : mod, + classname : classname + }); + return this.$worker; + }; + + this.onMessage = function(e) { + var msg = e.data; + switch (msg.type) { + case "event": + this._signal(msg.name, {data: msg.data}); + break; + case "call": + var callback = this.callbacks[msg.id]; + if (callback) { + callback(msg.data); + delete this.callbacks[msg.id]; + } + break; + case "error": + this.reportError(msg.data); + break; + case "log": + window.console && console.log && console.log.apply(console, msg.data); + break; + } + }; + + this.reportError = function(err) { + window.console && console.error && console.error(err); + }; + + this.$normalizePath = function(path) { + return net.qualifyURL(path); + }; + + this.terminate = function() { + this._signal("terminate", {}); + this.deltaQueue = null; + this.$worker.terminate(); + this.$worker = null; + if (this.$doc) + this.$doc.off("change", this.changeListener); + this.$doc = null; + }; + + this.send = function(cmd, args) { + this.$worker.postMessage({command: cmd, args: args}); + }; + + this.call = function(cmd, args, callback) { + if (callback) { + var id = this.callbackId++; + this.callbacks[id] = callback; + args.push(id); + } + this.send(cmd, args); + }; + + this.emit = function(event, data) { + try { + if (data.data && data.data.err) + data.data.err = {message: data.data.err.message, stack: data.data.err.stack, code: data.data.err.code}; + this.$worker.postMessage({event: event, data: {data: data.data}}); + } + catch(ex) { + console.error(ex.stack); + } + }; + + this.attachToDocument = function(doc) { + if (this.$doc) + this.terminate(); + + this.$doc = doc; + this.call("setValue", [doc.getValue()]); + doc.on("change", this.changeListener); + }; + + this.changeListener = function(delta) { + if (!this.deltaQueue) { + this.deltaQueue = []; + setTimeout(this.$sendDeltaQueue, 0); + } + if (delta.action == "insert") + this.deltaQueue.push(delta.start, delta.lines); + else + this.deltaQueue.push(delta.start, delta.end); + }; + + this.$sendDeltaQueue = function() { + var q = this.deltaQueue; + if (!q) return; + this.deltaQueue = null; + if (q.length > 50 && q.length > this.$doc.getLength() >> 1) { + this.call("setValue", [this.$doc.getValue()]); + } else + this.emit("change", {data: q}); + }; + +}).call(WorkerClient.prototype); + + +var UIWorkerClient = function(topLevelNamespaces, mod, classname) { + var main = null; + var emitSync = false; + var sender = Object.create(EventEmitter); + + var messageBuffer = []; + var workerClient = new WorkerClient({ + messageBuffer: messageBuffer, + terminate: function() {}, + postMessage: function(e) { + messageBuffer.push(e); + if (!main) return; + if (emitSync) + setTimeout(processNext); + else + processNext(); + } + }); + + workerClient.setEmitSync = function(val) { emitSync = val; }; + + var processNext = function() { + var msg = messageBuffer.shift(); + if (msg.command) + main[msg.command].apply(main, msg.args); + else if (msg.event) + sender._signal(msg.event, msg.data); + }; + + sender.postMessage = function(msg) { + workerClient.onMessage({data: msg}); + }; + sender.callback = function(data, callbackId) { + this.postMessage({type: "call", id: callbackId, data: data}); + }; + sender.emit = function(name, data) { + this.postMessage({type: "event", name: name, data: data}); + }; + + config.loadModule(["worker", mod], function(Main) { + main = new Main[classname](sender); + while (messageBuffer.length) + processNext(); + }); + + return workerClient; +}; + +exports.UIWorkerClient = UIWorkerClient; +exports.WorkerClient = WorkerClient; +exports.createWorker = createWorker; + + +}); + +ace.define("ace/placeholder",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/oop"], function(require, exports, module) { +"use strict"; + +var Range = require("./range").Range; +var EventEmitter = require("./lib/event_emitter").EventEmitter; +var oop = require("./lib/oop"); + +var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) { + var _self = this; + this.length = length; + this.session = session; + this.doc = session.getDocument(); + this.mainClass = mainClass; + this.othersClass = othersClass; + this.$onUpdate = this.onUpdate.bind(this); + this.doc.on("change", this.$onUpdate); + this.$others = others; + + this.$onCursorChange = function() { + setTimeout(function() { + _self.onCursorChange(); + }); + }; + + this.$pos = pos; + var undoStack = session.getUndoManager().$undoStack || session.getUndoManager().$undostack || {length: -1}; + this.$undoStackDepth = undoStack.length; + this.setup(); + + session.selection.on("changeCursor", this.$onCursorChange); +}; + +(function() { + + oop.implement(this, EventEmitter); + this.setup = function() { + var _self = this; + var doc = this.doc; + var session = this.session; + + this.selectionBefore = session.selection.toJSON(); + if (session.selection.inMultiSelectMode) + session.selection.toSingleRange(); + + this.pos = doc.createAnchor(this.$pos.row, this.$pos.column); + var pos = this.pos; + pos.$insertRight = true; + pos.detach(); + pos.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column + this.length), this.mainClass, null, false); + this.others = []; + this.$others.forEach(function(other) { + var anchor = doc.createAnchor(other.row, other.column); + anchor.$insertRight = true; + anchor.detach(); + _self.others.push(anchor); + }); + session.setUndoSelect(false); + }; + this.showOtherMarkers = function() { + if (this.othersActive) return; + var session = this.session; + var _self = this; + this.othersActive = true; + this.others.forEach(function(anchor) { + anchor.markerId = session.addMarker(new Range(anchor.row, anchor.column, anchor.row, anchor.column+_self.length), _self.othersClass, null, false); + }); + }; + this.hideOtherMarkers = function() { + if (!this.othersActive) return; + this.othersActive = false; + for (var i = 0; i < this.others.length; i++) { + this.session.removeMarker(this.others[i].markerId); + } + }; + this.onUpdate = function(delta) { + if (this.$updating) + return this.updateAnchors(delta); + + var range = delta; + if (range.start.row !== range.end.row) return; + if (range.start.row !== this.pos.row) return; + this.$updating = true; + var lengthDiff = delta.action === "insert" ? range.end.column - range.start.column : range.start.column - range.end.column; + var inMainRange = range.start.column >= this.pos.column && range.start.column <= this.pos.column + this.length + 1; + var distanceFromStart = range.start.column - this.pos.column; + + this.updateAnchors(delta); + + if (inMainRange) + this.length += lengthDiff; + + if (inMainRange && !this.session.$fromUndo) { + if (delta.action === 'insert') { + for (var i = this.others.length - 1; i >= 0; i--) { + var otherPos = this.others[i]; + var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart}; + this.doc.insertMergedLines(newPos, delta.lines); + } + } else if (delta.action === 'remove') { + for (var i = this.others.length - 1; i >= 0; i--) { + var otherPos = this.others[i]; + var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart}; + this.doc.remove(new Range(newPos.row, newPos.column, newPos.row, newPos.column - lengthDiff)); + } + } + } + + this.$updating = false; + this.updateMarkers(); + }; + + this.updateAnchors = function(delta) { + this.pos.onChange(delta); + for (var i = this.others.length; i--;) + this.others[i].onChange(delta); + this.updateMarkers(); + }; + + this.updateMarkers = function() { + if (this.$updating) + return; + var _self = this; + var session = this.session; + var updateMarker = function(pos, className) { + session.removeMarker(pos.markerId); + pos.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column+_self.length), className, null, false); + }; + updateMarker(this.pos, this.mainClass); + for (var i = this.others.length; i--;) + updateMarker(this.others[i], this.othersClass); + }; + + this.onCursorChange = function(event) { + if (this.$updating || !this.session) return; + var pos = this.session.selection.getCursor(); + if (pos.row === this.pos.row && pos.column >= this.pos.column && pos.column <= this.pos.column + this.length) { + this.showOtherMarkers(); + this._emit("cursorEnter", event); + } else { + this.hideOtherMarkers(); + this._emit("cursorLeave", event); + } + }; + this.detach = function() { + this.session.removeMarker(this.pos && this.pos.markerId); + this.hideOtherMarkers(); + this.doc.off("change", this.$onUpdate); + this.session.selection.off("changeCursor", this.$onCursorChange); + this.session.setUndoSelect(true); + this.session = null; + }; + this.cancel = function() { + if (this.$undoStackDepth === -1) + return; + var undoManager = this.session.getUndoManager(); + var undosRequired = (undoManager.$undoStack || undoManager.$undostack).length - this.$undoStackDepth; + for (var i = 0; i < undosRequired; i++) { + undoManager.undo(this.session, true); + } + if (this.selectionBefore) + this.session.selection.fromJSON(this.selectionBefore); + }; +}).call(PlaceHolder.prototype); + + +exports.PlaceHolder = PlaceHolder; +}); + +ace.define("ace/mouse/multi_select_handler",["require","exports","module","ace/lib/event","ace/lib/useragent"], function(require, exports, module) { + +var event = require("../lib/event"); +var useragent = require("../lib/useragent"); +function isSamePoint(p1, p2) { + return p1.row == p2.row && p1.column == p2.column; +} + +function onMouseDown(e) { + var ev = e.domEvent; + var alt = ev.altKey; + var shift = ev.shiftKey; + var ctrl = ev.ctrlKey; + var accel = e.getAccelKey(); + var button = e.getButton(); + + if (ctrl && useragent.isMac) + button = ev.button; + + if (e.editor.inMultiSelectMode && button == 2) { + e.editor.textInput.onContextMenu(e.domEvent); + return; + } + + if (!ctrl && !alt && !accel) { + if (button === 0 && e.editor.inMultiSelectMode) + e.editor.exitMultiSelectMode(); + return; + } + + if (button !== 0) + return; + + var editor = e.editor; + var selection = editor.selection; + var isMultiSelect = editor.inMultiSelectMode; + var pos = e.getDocumentPosition(); + var cursor = selection.getCursor(); + var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor)); + + var mouseX = e.x, mouseY = e.y; + var onMouseSelection = function(e) { + mouseX = e.clientX; + mouseY = e.clientY; + }; + + var session = editor.session; + var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY); + var screenCursor = screenAnchor; + + var selectionMode; + if (editor.$mouseHandler.$enableJumpToDef) { + if (ctrl && alt || accel && alt) + selectionMode = shift ? "block" : "add"; + else if (alt && editor.$blockSelectEnabled) + selectionMode = "block"; + } else { + if (accel && !alt) { + selectionMode = "add"; + if (!isMultiSelect && shift) + return; + } else if (alt && editor.$blockSelectEnabled) { + selectionMode = "block"; + } + } + + if (selectionMode && useragent.isMac && ev.ctrlKey) { + editor.$mouseHandler.cancelContextMenu(); + } + + if (selectionMode == "add") { + if (!isMultiSelect && inSelection) + return; // dragging + + if (!isMultiSelect) { + var range = selection.toOrientedRange(); + editor.addSelectionMarker(range); + } + + var oldRange = selection.rangeList.rangeAtPoint(pos); + + editor.inVirtualSelectionMode = true; + + if (shift) { + oldRange = null; + range = selection.ranges[0] || range; + editor.removeSelectionMarker(range); + } + editor.once("mouseup", function() { + var tmpSel = selection.toOrientedRange(); + + if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor)) + selection.substractPoint(tmpSel.cursor); + else { + if (shift) { + selection.substractPoint(range.cursor); + } else if (range) { + editor.removeSelectionMarker(range); + selection.addRange(range); + } + selection.addRange(tmpSel); + } + editor.inVirtualSelectionMode = false; + }); + + } else if (selectionMode == "block") { + e.stop(); + editor.inVirtualSelectionMode = true; + var initialRange; + var rectSel = []; + var blockSelect = function() { + var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY); + var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column, newCursor.offsetX); + + if (isSamePoint(screenCursor, newCursor) && isSamePoint(cursor, selection.lead)) + return; + screenCursor = newCursor; + + editor.selection.moveToPosition(cursor); + editor.renderer.scrollCursorIntoView(); + + editor.removeSelectionMarkers(rectSel); + rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor); + if (editor.$mouseHandler.$clickSelection && rectSel.length == 1 && rectSel[0].isEmpty()) + rectSel[0] = editor.$mouseHandler.$clickSelection.clone(); + rectSel.forEach(editor.addSelectionMarker, editor); + editor.updateSelectionMarkers(); + }; + if (isMultiSelect && !accel) { + selection.toSingleRange(); + } else if (!isMultiSelect && accel) { + initialRange = selection.toOrientedRange(); + editor.addSelectionMarker(initialRange); + } + + if (shift) + screenAnchor = session.documentToScreenPosition(selection.lead); + else + selection.moveToPosition(pos); + + screenCursor = {row: -1, column: -1}; + + var onMouseSelectionEnd = function(e) { + blockSelect(); + clearInterval(timerId); + editor.removeSelectionMarkers(rectSel); + if (!rectSel.length) + rectSel = [selection.toOrientedRange()]; + if (initialRange) { + editor.removeSelectionMarker(initialRange); + selection.toSingleRange(initialRange); + } + for (var i = 0; i < rectSel.length; i++) + selection.addRange(rectSel[i]); + editor.inVirtualSelectionMode = false; + editor.$mouseHandler.$clickSelection = null; + }; + + var onSelectionInterval = blockSelect; + + event.capture(editor.container, onMouseSelection, onMouseSelectionEnd); + var timerId = setInterval(function() {onSelectionInterval();}, 20); + + return e.preventDefault(); + } +} + + +exports.onMouseDown = onMouseDown; + +}); + +ace.define("ace/commands/multi_select_commands",["require","exports","module","ace/keyboard/hash_handler"], function(require, exports, module) { +exports.defaultCommands = [{ + name: "addCursorAbove", + description: "Add cursor above", + exec: function(editor) { editor.selectMoreLines(-1); }, + bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"}, + scrollIntoView: "cursor", + readOnly: true +}, { + name: "addCursorBelow", + description: "Add cursor below", + exec: function(editor) { editor.selectMoreLines(1); }, + bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"}, + scrollIntoView: "cursor", + readOnly: true +}, { + name: "addCursorAboveSkipCurrent", + description: "Add cursor above (skip current)", + exec: function(editor) { editor.selectMoreLines(-1, true); }, + bindKey: {win: "Ctrl-Alt-Shift-Up", mac: "Ctrl-Alt-Shift-Up"}, + scrollIntoView: "cursor", + readOnly: true +}, { + name: "addCursorBelowSkipCurrent", + description: "Add cursor below (skip current)", + exec: function(editor) { editor.selectMoreLines(1, true); }, + bindKey: {win: "Ctrl-Alt-Shift-Down", mac: "Ctrl-Alt-Shift-Down"}, + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectMoreBefore", + description: "Select more before", + exec: function(editor) { editor.selectMore(-1); }, + bindKey: {win: "Ctrl-Alt-Left", mac: "Ctrl-Alt-Left"}, + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectMoreAfter", + description: "Select more after", + exec: function(editor) { editor.selectMore(1); }, + bindKey: {win: "Ctrl-Alt-Right", mac: "Ctrl-Alt-Right"}, + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectNextBefore", + description: "Select next before", + exec: function(editor) { editor.selectMore(-1, true); }, + bindKey: {win: "Ctrl-Alt-Shift-Left", mac: "Ctrl-Alt-Shift-Left"}, + scrollIntoView: "cursor", + readOnly: true +}, { + name: "selectNextAfter", + description: "Select next after", + exec: function(editor) { editor.selectMore(1, true); }, + bindKey: {win: "Ctrl-Alt-Shift-Right", mac: "Ctrl-Alt-Shift-Right"}, + scrollIntoView: "cursor", + readOnly: true +}, { + name: "toggleSplitSelectionIntoLines", + description: "Split into lines", + exec: function(editor) { + if (editor.multiSelect.rangeCount > 1) + editor.multiSelect.joinSelections(); + else + editor.multiSelect.splitIntoLines(); + }, + bindKey: {win: "Ctrl-Alt-L", mac: "Ctrl-Alt-L"}, + readOnly: true +}, { + name: "splitSelectionIntoLines", + description: "Split into lines", + exec: function(editor) { editor.multiSelect.splitIntoLines(); }, + readOnly: true +}, { + name: "alignCursors", + description: "Align cursors", + exec: function(editor) { editor.alignCursors(); }, + bindKey: {win: "Ctrl-Alt-A", mac: "Ctrl-Alt-A"}, + scrollIntoView: "cursor" +}, { + name: "findAll", + description: "Find all", + exec: function(editor) { editor.findAll(); }, + bindKey: {win: "Ctrl-Alt-K", mac: "Ctrl-Alt-G"}, + scrollIntoView: "cursor", + readOnly: true +}]; +exports.multiSelectCommands = [{ + name: "singleSelection", + description: "Single selection", + bindKey: "esc", + exec: function(editor) { editor.exitMultiSelectMode(); }, + scrollIntoView: "cursor", + readOnly: true, + isAvailable: function(editor) {return editor && editor.inMultiSelectMode;} +}]; + +var HashHandler = require("../keyboard/hash_handler").HashHandler; +exports.keyboardHandler = new HashHandler(exports.multiSelectCommands); + +}); + +ace.define("ace/multi_select",["require","exports","module","ace/range_list","ace/range","ace/selection","ace/mouse/multi_select_handler","ace/lib/event","ace/lib/lang","ace/commands/multi_select_commands","ace/search","ace/edit_session","ace/editor","ace/config"], function(require, exports, module) { + +var RangeList = require("./range_list").RangeList; +var Range = require("./range").Range; +var Selection = require("./selection").Selection; +var onMouseDown = require("./mouse/multi_select_handler").onMouseDown; +var event = require("./lib/event"); +var lang = require("./lib/lang"); +var commands = require("./commands/multi_select_commands"); +exports.commands = commands.defaultCommands.concat(commands.multiSelectCommands); +var Search = require("./search").Search; +var search = new Search(); + +function find(session, needle, dir) { + search.$options.wrap = true; + search.$options.needle = needle; + search.$options.backwards = dir == -1; + return search.find(session); +} +var EditSession = require("./edit_session").EditSession; +(function() { + this.getSelectionMarkers = function() { + return this.$selectionMarkers; + }; +}).call(EditSession.prototype); +(function() { + this.ranges = null; + this.rangeList = null; + this.addRange = function(range, $blockChangeEvents) { + if (!range) + return; + + if (!this.inMultiSelectMode && this.rangeCount === 0) { + var oldRange = this.toOrientedRange(); + this.rangeList.add(oldRange); + this.rangeList.add(range); + if (this.rangeList.ranges.length != 2) { + this.rangeList.removeAll(); + return $blockChangeEvents || this.fromOrientedRange(range); + } + this.rangeList.removeAll(); + this.rangeList.add(oldRange); + this.$onAddRange(oldRange); + } + + if (!range.cursor) + range.cursor = range.end; + + var removed = this.rangeList.add(range); + + this.$onAddRange(range); + + if (removed.length) + this.$onRemoveRange(removed); + + if (this.rangeCount > 1 && !this.inMultiSelectMode) { + this._signal("multiSelect"); + this.inMultiSelectMode = true; + this.session.$undoSelect = false; + this.rangeList.attach(this.session); + } + + return $blockChangeEvents || this.fromOrientedRange(range); + }; + this.toSingleRange = function(range) { + range = range || this.ranges[0]; + var removed = this.rangeList.removeAll(); + if (removed.length) + this.$onRemoveRange(removed); + + range && this.fromOrientedRange(range); + }; + this.substractPoint = function(pos) { + var removed = this.rangeList.substractPoint(pos); + if (removed) { + this.$onRemoveRange(removed); + return removed[0]; + } + }; + this.mergeOverlappingRanges = function() { + var removed = this.rangeList.merge(); + if (removed.length) + this.$onRemoveRange(removed); + }; + + this.$onAddRange = function(range) { + this.rangeCount = this.rangeList.ranges.length; + this.ranges.unshift(range); + this._signal("addRange", {range: range}); + }; + + this.$onRemoveRange = function(removed) { + this.rangeCount = this.rangeList.ranges.length; + if (this.rangeCount == 1 && this.inMultiSelectMode) { + var lastRange = this.rangeList.ranges.pop(); + removed.push(lastRange); + this.rangeCount = 0; + } + + for (var i = removed.length; i--; ) { + var index = this.ranges.indexOf(removed[i]); + this.ranges.splice(index, 1); + } + + this._signal("removeRange", {ranges: removed}); + + if (this.rangeCount === 0 && this.inMultiSelectMode) { + this.inMultiSelectMode = false; + this._signal("singleSelect"); + this.session.$undoSelect = true; + this.rangeList.detach(this.session); + } + + lastRange = lastRange || this.ranges[0]; + if (lastRange && !lastRange.isEqual(this.getRange())) + this.fromOrientedRange(lastRange); + }; + this.$initRangeList = function() { + if (this.rangeList) + return; + + this.rangeList = new RangeList(); + this.ranges = []; + this.rangeCount = 0; + }; + this.getAllRanges = function() { + return this.rangeCount ? this.rangeList.ranges.concat() : [this.getRange()]; + }; + this.splitIntoLines = function () { + var ranges = this.ranges.length ? this.ranges : [this.getRange()]; + var newRanges = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + var row = range.start.row; + var endRow = range.end.row; + if (row === endRow) { + newRanges.push(range.clone()); + } else { + newRanges.push(new Range(row, range.start.column, row, this.session.getLine(row).length)); + while (++row < endRow) + newRanges.push(this.getLineRange(row, true)); + newRanges.push(new Range(endRow, 0, endRow, range.end.column)); + } + if (i == 0 && !this.isBackwards()) + newRanges = newRanges.reverse(); + } + this.toSingleRange(); + for (var i = newRanges.length; i--;) + this.addRange(newRanges[i]); + }; + + this.joinSelections = function () { + var ranges = this.rangeList.ranges; + var lastRange = ranges[ranges.length - 1]; + var range = Range.fromPoints(ranges[0].start, lastRange.end); + + this.toSingleRange(); + this.setSelectionRange(range, lastRange.cursor == lastRange.start); + }; + this.toggleBlockSelection = function () { + if (this.rangeCount > 1) { + var ranges = this.rangeList.ranges; + var lastRange = ranges[ranges.length - 1]; + var range = Range.fromPoints(ranges[0].start, lastRange.end); + + this.toSingleRange(); + this.setSelectionRange(range, lastRange.cursor == lastRange.start); + } else { + var cursor = this.session.documentToScreenPosition(this.cursor); + var anchor = this.session.documentToScreenPosition(this.anchor); + + var rectSel = this.rectangularRangeBlock(cursor, anchor); + rectSel.forEach(this.addRange, this); + } + }; + this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) { + var rectSel = []; + + var xBackwards = screenCursor.column < screenAnchor.column; + if (xBackwards) { + var startColumn = screenCursor.column; + var endColumn = screenAnchor.column; + var startOffsetX = screenCursor.offsetX; + var endOffsetX = screenAnchor.offsetX; + } else { + var startColumn = screenAnchor.column; + var endColumn = screenCursor.column; + var startOffsetX = screenAnchor.offsetX; + var endOffsetX = screenCursor.offsetX; + } + + var yBackwards = screenCursor.row < screenAnchor.row; + if (yBackwards) { + var startRow = screenCursor.row; + var endRow = screenAnchor.row; + } else { + var startRow = screenAnchor.row; + var endRow = screenCursor.row; + } + + if (startColumn < 0) + startColumn = 0; + if (startRow < 0) + startRow = 0; + + if (startRow == endRow) + includeEmptyLines = true; + + var docEnd; + for (var row = startRow; row <= endRow; row++) { + var range = Range.fromPoints( + this.session.screenToDocumentPosition(row, startColumn, startOffsetX), + this.session.screenToDocumentPosition(row, endColumn, endOffsetX) + ); + if (range.isEmpty()) { + if (docEnd && isSamePoint(range.end, docEnd)) + break; + docEnd = range.end; + } + range.cursor = xBackwards ? range.start : range.end; + rectSel.push(range); + } + + if (yBackwards) + rectSel.reverse(); + + if (!includeEmptyLines) { + var end = rectSel.length - 1; + while (rectSel[end].isEmpty() && end > 0) + end--; + if (end > 0) { + var start = 0; + while (rectSel[start].isEmpty()) + start++; + } + for (var i = end; i >= start; i--) { + if (rectSel[i].isEmpty()) + rectSel.splice(i, 1); + } + } + + return rectSel; + }; +}).call(Selection.prototype); +var Editor = require("./editor").Editor; +(function() { + this.updateSelectionMarkers = function() { + this.renderer.updateCursor(); + this.renderer.updateBackMarkers(); + }; + this.addSelectionMarker = function(orientedRange) { + if (!orientedRange.cursor) + orientedRange.cursor = orientedRange.end; + + var style = this.getSelectionStyle(); + orientedRange.marker = this.session.addMarker(orientedRange, "ace_selection", style); + + this.session.$selectionMarkers.push(orientedRange); + this.session.selectionMarkerCount = this.session.$selectionMarkers.length; + return orientedRange; + }; + this.removeSelectionMarker = function(range) { + if (!range.marker) + return; + this.session.removeMarker(range.marker); + var index = this.session.$selectionMarkers.indexOf(range); + if (index != -1) + this.session.$selectionMarkers.splice(index, 1); + this.session.selectionMarkerCount = this.session.$selectionMarkers.length; + }; + + this.removeSelectionMarkers = function(ranges) { + var markerList = this.session.$selectionMarkers; + for (var i = ranges.length; i--; ) { + var range = ranges[i]; + if (!range.marker) + continue; + this.session.removeMarker(range.marker); + var index = markerList.indexOf(range); + if (index != -1) + markerList.splice(index, 1); + } + this.session.selectionMarkerCount = markerList.length; + }; + + this.$onAddRange = function(e) { + this.addSelectionMarker(e.range); + this.renderer.updateCursor(); + this.renderer.updateBackMarkers(); + }; + + this.$onRemoveRange = function(e) { + this.removeSelectionMarkers(e.ranges); + this.renderer.updateCursor(); + this.renderer.updateBackMarkers(); + }; + + this.$onMultiSelect = function(e) { + if (this.inMultiSelectMode) + return; + this.inMultiSelectMode = true; + + this.setStyle("ace_multiselect"); + this.keyBinding.addKeyboardHandler(commands.keyboardHandler); + this.commands.setDefaultHandler("exec", this.$onMultiSelectExec); + + this.renderer.updateCursor(); + this.renderer.updateBackMarkers(); + }; + + this.$onSingleSelect = function(e) { + if (this.session.multiSelect.inVirtualMode) + return; + this.inMultiSelectMode = false; + + this.unsetStyle("ace_multiselect"); + this.keyBinding.removeKeyboardHandler(commands.keyboardHandler); + + this.commands.removeDefaultHandler("exec", this.$onMultiSelectExec); + this.renderer.updateCursor(); + this.renderer.updateBackMarkers(); + this._emit("changeSelection"); + }; + + this.$onMultiSelectExec = function(e) { + var command = e.command; + var editor = e.editor; + if (!editor.multiSelect) + return; + if (!command.multiSelectAction) { + var result = command.exec(editor, e.args || {}); + editor.multiSelect.addRange(editor.multiSelect.toOrientedRange()); + editor.multiSelect.mergeOverlappingRanges(); + } else if (command.multiSelectAction == "forEach") { + result = editor.forEachSelection(command, e.args); + } else if (command.multiSelectAction == "forEachLine") { + result = editor.forEachSelection(command, e.args, true); + } else if (command.multiSelectAction == "single") { + editor.exitMultiSelectMode(); + result = command.exec(editor, e.args || {}); + } else { + result = command.multiSelectAction(editor, e.args || {}); + } + return result; + }; + this.forEachSelection = function(cmd, args, options) { + if (this.inVirtualSelectionMode) + return; + var keepOrder = options && options.keepOrder; + var $byLines = options == true || options && options.$byLines; + var session = this.session; + var selection = this.selection; + var rangeList = selection.rangeList; + var ranges = (keepOrder ? selection : rangeList).ranges; + var result; + + if (!ranges.length) + return cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {}); + + var reg = selection._eventRegistry; + selection._eventRegistry = {}; + + var tmpSel = new Selection(session); + this.inVirtualSelectionMode = true; + for (var i = ranges.length; i--;) { + if ($byLines) { + while (i > 0 && ranges[i].start.row == ranges[i - 1].end.row) + i--; + } + tmpSel.fromOrientedRange(ranges[i]); + tmpSel.index = i; + this.selection = session.selection = tmpSel; + var cmdResult = cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {}); + if (!result && cmdResult !== undefined) + result = cmdResult; + tmpSel.toOrientedRange(ranges[i]); + } + tmpSel.detach(); + + this.selection = session.selection = selection; + this.inVirtualSelectionMode = false; + selection._eventRegistry = reg; + selection.mergeOverlappingRanges(); + if (selection.ranges[0]) + selection.fromOrientedRange(selection.ranges[0]); + + var anim = this.renderer.$scrollAnimation; + this.onCursorChange(); + this.onSelectionChange(); + if (anim && anim.from == anim.to) + this.renderer.animateScrolling(anim.from); + + return result; + }; + this.exitMultiSelectMode = function() { + if (!this.inMultiSelectMode || this.inVirtualSelectionMode) + return; + this.multiSelect.toSingleRange(); + }; + + this.getSelectedText = function() { + var text = ""; + if (this.inMultiSelectMode && !this.inVirtualSelectionMode) { + var ranges = this.multiSelect.rangeList.ranges; + var buf = []; + for (var i = 0; i < ranges.length; i++) { + buf.push(this.session.getTextRange(ranges[i])); + } + var nl = this.session.getDocument().getNewLineCharacter(); + text = buf.join(nl); + if (text.length == (buf.length - 1) * nl.length) + text = ""; + } else if (!this.selection.isEmpty()) { + text = this.session.getTextRange(this.getSelectionRange()); + } + return text; + }; + + this.$checkMultiselectChange = function(e, anchor) { + if (this.inMultiSelectMode && !this.inVirtualSelectionMode) { + var range = this.multiSelect.ranges[0]; + if (this.multiSelect.isEmpty() && anchor == this.multiSelect.anchor) + return; + var pos = anchor == this.multiSelect.anchor + ? range.cursor == range.start ? range.end : range.start + : range.cursor; + if (pos.row != anchor.row + || this.session.$clipPositionToDocument(pos.row, pos.column).column != anchor.column) + this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange()); + else + this.multiSelect.mergeOverlappingRanges(); + } + }; + this.findAll = function(needle, options, additive) { + options = options || {}; + options.needle = needle || options.needle; + if (options.needle == undefined) { + var range = this.selection.isEmpty() + ? this.selection.getWordRange() + : this.selection.getRange(); + options.needle = this.session.getTextRange(range); + } + this.$search.set(options); + + var ranges = this.$search.findAll(this.session); + if (!ranges.length) + return 0; + + var selection = this.multiSelect; + + if (!additive) + selection.toSingleRange(ranges[0]); + + for (var i = ranges.length; i--; ) + selection.addRange(ranges[i], true); + if (range && selection.rangeList.rangeAtPoint(range.start)) + selection.addRange(range, true); + + return ranges.length; + }; + this.selectMoreLines = function(dir, skip) { + var range = this.selection.toOrientedRange(); + var isBackwards = range.cursor == range.end; + + var screenLead = this.session.documentToScreenPosition(range.cursor); + if (this.selection.$desiredColumn) + screenLead.column = this.selection.$desiredColumn; + + var lead = this.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column); + + if (!range.isEmpty()) { + var screenAnchor = this.session.documentToScreenPosition(isBackwards ? range.end : range.start); + var anchor = this.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column); + } else { + var anchor = lead; + } + + if (isBackwards) { + var newRange = Range.fromPoints(lead, anchor); + newRange.cursor = newRange.start; + } else { + var newRange = Range.fromPoints(anchor, lead); + newRange.cursor = newRange.end; + } + + newRange.desiredColumn = screenLead.column; + if (!this.selection.inMultiSelectMode) { + this.selection.addRange(range); + } else { + if (skip) + var toRemove = range.cursor; + } + + this.selection.addRange(newRange); + if (toRemove) + this.selection.substractPoint(toRemove); + }; + this.transposeSelections = function(dir) { + var session = this.session; + var sel = session.multiSelect; + var all = sel.ranges; + + for (var i = all.length; i--; ) { + var range = all[i]; + if (range.isEmpty()) { + var tmp = session.getWordRange(range.start.row, range.start.column); + range.start.row = tmp.start.row; + range.start.column = tmp.start.column; + range.end.row = tmp.end.row; + range.end.column = tmp.end.column; + } + } + sel.mergeOverlappingRanges(); + + var words = []; + for (var i = all.length; i--; ) { + var range = all[i]; + words.unshift(session.getTextRange(range)); + } + + if (dir < 0) + words.unshift(words.pop()); + else + words.push(words.shift()); + + for (var i = all.length; i--; ) { + var range = all[i]; + var tmp = range.clone(); + session.replace(range, words[i]); + range.start.row = tmp.start.row; + range.start.column = tmp.start.column; + } + sel.fromOrientedRange(sel.ranges[0]); + }; + this.selectMore = function(dir, skip, stopAtFirst) { + var session = this.session; + var sel = session.multiSelect; + + var range = sel.toOrientedRange(); + if (range.isEmpty()) { + range = session.getWordRange(range.start.row, range.start.column); + range.cursor = dir == -1 ? range.start : range.end; + this.multiSelect.addRange(range); + if (stopAtFirst) + return; + } + var needle = session.getTextRange(range); + + var newRange = find(session, needle, dir); + if (newRange) { + newRange.cursor = dir == -1 ? newRange.start : newRange.end; + this.session.unfold(newRange); + this.multiSelect.addRange(newRange); + this.renderer.scrollCursorIntoView(null, 0.5); + } + if (skip) + this.multiSelect.substractPoint(range.cursor); + }; + this.alignCursors = function() { + var session = this.session; + var sel = session.multiSelect; + var ranges = sel.ranges; + var row = -1; + var sameRowRanges = ranges.filter(function(r) { + if (r.cursor.row == row) + return true; + row = r.cursor.row; + }); + + if (!ranges.length || sameRowRanges.length == ranges.length - 1) { + var range = this.selection.getRange(); + var fr = range.start.row, lr = range.end.row; + var guessRange = fr == lr; + if (guessRange) { + var max = this.session.getLength(); + var line; + do { + line = this.session.getLine(lr); + } while (/[=:]/.test(line) && ++lr < max); + do { + line = this.session.getLine(fr); + } while (/[=:]/.test(line) && --fr > 0); + + if (fr < 0) fr = 0; + if (lr >= max) lr = max - 1; + } + var lines = this.session.removeFullLines(fr, lr); + lines = this.$reAlignText(lines, guessRange); + this.session.insert({row: fr, column: 0}, lines.join("\n") + "\n"); + if (!guessRange) { + range.start.column = 0; + range.end.column = lines[lines.length - 1].length; + } + this.selection.setRange(range); + } else { + sameRowRanges.forEach(function(r) { + sel.substractPoint(r.cursor); + }); + + var maxCol = 0; + var minSpace = Infinity; + var spaceOffsets = ranges.map(function(r) { + var p = r.cursor; + var line = session.getLine(p.row); + var spaceOffset = line.substr(p.column).search(/\S/g); + if (spaceOffset == -1) + spaceOffset = 0; + + if (p.column > maxCol) + maxCol = p.column; + if (spaceOffset < minSpace) + minSpace = spaceOffset; + return spaceOffset; + }); + ranges.forEach(function(r, i) { + var p = r.cursor; + var l = maxCol - p.column; + var d = spaceOffsets[i] - minSpace; + if (l > d) + session.insert(p, lang.stringRepeat(" ", l - d)); + else + session.remove(new Range(p.row, p.column, p.row, p.column - l + d)); + + r.start.column = r.end.column = maxCol; + r.start.row = r.end.row = p.row; + r.cursor = r.end; + }); + sel.fromOrientedRange(ranges[0]); + this.renderer.updateCursor(); + this.renderer.updateBackMarkers(); + } + }; + + this.$reAlignText = function(lines, forceLeft) { + var isLeftAligned = true, isRightAligned = true; + var startW, textW, endW; + + return lines.map(function(line) { + var m = line.match(/(\s*)(.*?)(\s*)([=:].*)/); + if (!m) + return [line]; + + if (startW == null) { + startW = m[1].length; + textW = m[2].length; + endW = m[3].length; + return m; + } + + if (startW + textW + endW != m[1].length + m[2].length + m[3].length) + isRightAligned = false; + if (startW != m[1].length) + isLeftAligned = false; + + if (startW > m[1].length) + startW = m[1].length; + if (textW < m[2].length) + textW = m[2].length; + if (endW > m[3].length) + endW = m[3].length; + + return m; + }).map(forceLeft ? alignLeft : + isLeftAligned ? isRightAligned ? alignRight : alignLeft : unAlign); + + function spaces(n) { + return lang.stringRepeat(" ", n); + } + + function alignLeft(m) { + return !m[2] ? m[0] : spaces(startW) + m[2] + + spaces(textW - m[2].length + endW) + + m[4].replace(/^([=:])\s+/, "$1 "); + } + function alignRight(m) { + return !m[2] ? m[0] : spaces(startW + textW - m[2].length) + m[2] + + spaces(endW) + + m[4].replace(/^([=:])\s+/, "$1 "); + } + function unAlign(m) { + return !m[2] ? m[0] : spaces(startW) + m[2] + + spaces(endW) + + m[4].replace(/^([=:])\s+/, "$1 "); + } + }; +}).call(Editor.prototype); + + +function isSamePoint(p1, p2) { + return p1.row == p2.row && p1.column == p2.column; +} +exports.onSessionChange = function(e) { + var session = e.session; + if (session && !session.multiSelect) { + session.$selectionMarkers = []; + session.selection.$initRangeList(); + session.multiSelect = session.selection; + } + this.multiSelect = session && session.multiSelect; + + var oldSession = e.oldSession; + if (oldSession) { + oldSession.multiSelect.off("addRange", this.$onAddRange); + oldSession.multiSelect.off("removeRange", this.$onRemoveRange); + oldSession.multiSelect.off("multiSelect", this.$onMultiSelect); + oldSession.multiSelect.off("singleSelect", this.$onSingleSelect); + oldSession.multiSelect.lead.off("change", this.$checkMultiselectChange); + oldSession.multiSelect.anchor.off("change", this.$checkMultiselectChange); + } + + if (session) { + session.multiSelect.on("addRange", this.$onAddRange); + session.multiSelect.on("removeRange", this.$onRemoveRange); + session.multiSelect.on("multiSelect", this.$onMultiSelect); + session.multiSelect.on("singleSelect", this.$onSingleSelect); + session.multiSelect.lead.on("change", this.$checkMultiselectChange); + session.multiSelect.anchor.on("change", this.$checkMultiselectChange); + } + + if (session && this.inMultiSelectMode != session.selection.inMultiSelectMode) { + if (session.selection.inMultiSelectMode) + this.$onMultiSelect(); + else + this.$onSingleSelect(); + } +}; +function MultiSelect(editor) { + if (editor.$multiselectOnSessionChange) + return; + editor.$onAddRange = editor.$onAddRange.bind(editor); + editor.$onRemoveRange = editor.$onRemoveRange.bind(editor); + editor.$onMultiSelect = editor.$onMultiSelect.bind(editor); + editor.$onSingleSelect = editor.$onSingleSelect.bind(editor); + editor.$multiselectOnSessionChange = exports.onSessionChange.bind(editor); + editor.$checkMultiselectChange = editor.$checkMultiselectChange.bind(editor); + + editor.$multiselectOnSessionChange(editor); + editor.on("changeSession", editor.$multiselectOnSessionChange); + + editor.on("mousedown", onMouseDown); + editor.commands.addCommands(commands.defaultCommands); + + addAltCursorListeners(editor); +} + +function addAltCursorListeners(editor){ + if (!editor.textInput) return; + var el = editor.textInput.getElement(); + var altCursor = false; + event.addListener(el, "keydown", function(e) { + var altDown = e.keyCode == 18 && !(e.ctrlKey || e.shiftKey || e.metaKey); + if (editor.$blockSelectEnabled && altDown) { + if (!altCursor) { + editor.renderer.setMouseCursor("crosshair"); + altCursor = true; + } + } else if (altCursor) { + reset(); + } + }, editor); + + event.addListener(el, "keyup", reset, editor); + event.addListener(el, "blur", reset, editor); + function reset(e) { + if (altCursor) { + editor.renderer.setMouseCursor(""); + altCursor = false; + } + } +} + +exports.MultiSelect = MultiSelect; + + +require("./config").defineOptions(Editor.prototype, "editor", { + enableMultiselect: { + set: function(val) { + MultiSelect(this); + if (val) { + this.on("changeSession", this.$multiselectOnSessionChange); + this.on("mousedown", onMouseDown); + } else { + this.off("changeSession", this.$multiselectOnSessionChange); + this.off("mousedown", onMouseDown); + } + }, + value: true + }, + enableBlockSelect: { + set: function(val) { + this.$blockSelectEnabled = val; + }, + value: true + } +}); + + + +}); + +ace.define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"], function(require, exports, module) { +"use strict"; + +var Range = require("../../range").Range; + +var FoldMode = exports.FoldMode = function() {}; + +(function() { + + this.foldingStartMarker = null; + this.foldingStopMarker = null; + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + if (this.foldingStartMarker.test(line)) + return "start"; + if (foldStyle == "markbeginend" + && this.foldingStopMarker + && this.foldingStopMarker.test(line)) + return "end"; + return ""; + }; + + this.getFoldWidgetRange = function(session, foldStyle, row) { + return null; + }; + + this.indentationBlock = function(session, row, column) { + var re = /\S/; + var line = session.getLine(row); + var startLevel = line.search(re); + if (startLevel == -1) + return; + + var startColumn = column || line.length; + var maxRow = session.getLength(); + var startRow = row; + var endRow = row; + + while (++row < maxRow) { + var level = session.getLine(row).search(re); + + if (level == -1) + continue; + + if (level <= startLevel) { + var token = session.getTokenAt(row, 0); + if (!token || token.type !== "string") + break; + } + + endRow = row; + } + + if (endRow > startRow) { + var endColumn = session.getLine(endRow).length; + return new Range(startRow, startColumn, endRow, endColumn); + } + }; + + this.openingBracketBlock = function(session, bracket, row, column, typeRe) { + var start = {row: row, column: column + 1}; + var end = session.$findClosingBracket(bracket, start, typeRe); + if (!end) + return; + + var fw = session.foldWidgets[end.row]; + if (fw == null) + fw = session.getFoldWidget(end.row); + + if (fw == "start" && end.row > start.row) { + end.row --; + end.column = session.getLine(end.row).length; + } + return Range.fromPoints(start, end); + }; + + this.closingBracketBlock = function(session, bracket, row, column, typeRe) { + var end = {row: row, column: column}; + var start = session.$findOpeningBracket(bracket, end); + + if (!start) + return; + + start.column++; + end.column--; + + return Range.fromPoints(start, end); + }; +}).call(FoldMode.prototype); + +}); + +ace.define("ace/theme/textmate",["require","exports","module","ace/lib/dom"], function(require, exports, module) { +"use strict"; + +exports.isDark = false; +exports.cssClass = "ace-tm"; +exports.cssText = ".ace-tm .ace_gutter {\ +background: #f0f0f0;\ +color: #333;\ +}\ +.ace-tm .ace_print-margin {\ +width: 1px;\ +background: #e8e8e8;\ +}\ +.ace-tm .ace_fold {\ +background-color: #6B72E6;\ +}\ +.ace-tm {\ +background-color: #FFFFFF;\ +color: black;\ +}\ +.ace-tm .ace_cursor {\ +color: black;\ +}\ +.ace-tm .ace_invisible {\ +color: rgb(191, 191, 191);\ +}\ +.ace-tm .ace_storage,\ +.ace-tm .ace_keyword {\ +color: blue;\ +}\ +.ace-tm .ace_constant {\ +color: rgb(197, 6, 11);\ +}\ +.ace-tm .ace_constant.ace_buildin {\ +color: rgb(88, 72, 246);\ +}\ +.ace-tm .ace_constant.ace_language {\ +color: rgb(88, 92, 246);\ +}\ +.ace-tm .ace_constant.ace_library {\ +color: rgb(6, 150, 14);\ +}\ +.ace-tm .ace_invalid {\ +background-color: rgba(255, 0, 0, 0.1);\ +color: red;\ +}\ +.ace-tm .ace_support.ace_function {\ +color: rgb(60, 76, 114);\ +}\ +.ace-tm .ace_support.ace_constant {\ +color: rgb(6, 150, 14);\ +}\ +.ace-tm .ace_support.ace_type,\ +.ace-tm .ace_support.ace_class {\ +color: rgb(109, 121, 222);\ +}\ +.ace-tm .ace_keyword.ace_operator {\ +color: rgb(104, 118, 135);\ +}\ +.ace-tm .ace_string {\ +color: rgb(3, 106, 7);\ +}\ +.ace-tm .ace_comment {\ +color: rgb(76, 136, 107);\ +}\ +.ace-tm .ace_comment.ace_doc {\ +color: rgb(0, 102, 255);\ +}\ +.ace-tm .ace_comment.ace_doc.ace_tag {\ +color: rgb(128, 159, 191);\ +}\ +.ace-tm .ace_constant.ace_numeric {\ +color: rgb(0, 0, 205);\ +}\ +.ace-tm .ace_variable {\ +color: rgb(49, 132, 149);\ +}\ +.ace-tm .ace_xml-pe {\ +color: rgb(104, 104, 91);\ +}\ +.ace-tm .ace_entity.ace_name.ace_function {\ +color: #0000A2;\ +}\ +.ace-tm .ace_heading {\ +color: rgb(12, 7, 255);\ +}\ +.ace-tm .ace_list {\ +color:rgb(185, 6, 144);\ +}\ +.ace-tm .ace_meta.ace_tag {\ +color:rgb(0, 22, 142);\ +}\ +.ace-tm .ace_string.ace_regex {\ +color: rgb(255, 0, 0)\ +}\ +.ace-tm .ace_marker-layer .ace_selection {\ +background: rgb(181, 213, 255);\ +}\ +.ace-tm.ace_multiselect .ace_selection.ace_start {\ +box-shadow: 0 0 3px 0px white;\ +}\ +.ace-tm .ace_marker-layer .ace_step {\ +background: rgb(252, 255, 0);\ +}\ +.ace-tm .ace_marker-layer .ace_stack {\ +background: rgb(164, 229, 101);\ +}\ +.ace-tm .ace_marker-layer .ace_bracket {\ +margin: -1px 0 0 -1px;\ +border: 1px solid rgb(192, 192, 192);\ +}\ +.ace-tm .ace_marker-layer .ace_active-line {\ +background: rgba(0, 0, 0, 0.07);\ +}\ +.ace-tm .ace_gutter-active-line {\ +background-color : #dcdcdc;\ +}\ +.ace-tm .ace_marker-layer .ace_selected-word {\ +background: rgb(250, 250, 255);\ +border: 1px solid rgb(200, 200, 250);\ +}\ +.ace-tm .ace_indent-guide {\ +background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\ +}\ +"; +exports.$id = "ace/theme/textmate"; + +var dom = require("../lib/dom"); +dom.importCssString(exports.cssText, exports.cssClass); +}); + +ace.define("ace/line_widgets",["require","exports","module","ace/lib/dom"], function(require, exports, module) { +"use strict"; + +var dom = require("./lib/dom"); + +function LineWidgets(session) { + this.session = session; + this.session.widgetManager = this; + this.session.getRowLength = this.getRowLength; + this.session.$getWidgetScreenLength = this.$getWidgetScreenLength; + this.updateOnChange = this.updateOnChange.bind(this); + this.renderWidgets = this.renderWidgets.bind(this); + this.measureWidgets = this.measureWidgets.bind(this); + this.session._changedWidgets = []; + this.$onChangeEditor = this.$onChangeEditor.bind(this); + + this.session.on("change", this.updateOnChange); + this.session.on("changeFold", this.updateOnFold); + this.session.on("changeEditor", this.$onChangeEditor); +} + +(function() { + this.getRowLength = function(row) { + var h; + if (this.lineWidgets) + h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0; + else + h = 0; + if (!this.$useWrapMode || !this.$wrapData[row]) { + return 1 + h; + } else { + return this.$wrapData[row].length + 1 + h; + } + }; + + this.$getWidgetScreenLength = function() { + var screenRows = 0; + this.lineWidgets.forEach(function(w){ + if (w && w.rowCount && !w.hidden) + screenRows += w.rowCount; + }); + return screenRows; + }; + + this.$onChangeEditor = function(e) { + this.attach(e.editor); + }; + + this.attach = function(editor) { + if (editor && editor.widgetManager && editor.widgetManager != this) + editor.widgetManager.detach(); + + if (this.editor == editor) + return; + + this.detach(); + this.editor = editor; + + if (editor) { + editor.widgetManager = this; + editor.renderer.on("beforeRender", this.measureWidgets); + editor.renderer.on("afterRender", this.renderWidgets); + } + }; + this.detach = function(e) { + var editor = this.editor; + if (!editor) + return; + + this.editor = null; + editor.widgetManager = null; + + editor.renderer.off("beforeRender", this.measureWidgets); + editor.renderer.off("afterRender", this.renderWidgets); + var lineWidgets = this.session.lineWidgets; + lineWidgets && lineWidgets.forEach(function(w) { + if (w && w.el && w.el.parentNode) { + w._inDocument = false; + w.el.parentNode.removeChild(w.el); + } + }); + }; + + this.updateOnFold = function(e, session) { + var lineWidgets = session.lineWidgets; + if (!lineWidgets || !e.action) + return; + var fold = e.data; + var start = fold.start.row; + var end = fold.end.row; + var hide = e.action == "add"; + for (var i = start + 1; i < end; i++) { + if (lineWidgets[i]) + lineWidgets[i].hidden = hide; + } + if (lineWidgets[end]) { + if (hide) { + if (!lineWidgets[start]) + lineWidgets[start] = lineWidgets[end]; + else + lineWidgets[end].hidden = hide; + } else { + if (lineWidgets[start] == lineWidgets[end]) + lineWidgets[start] = undefined; + lineWidgets[end].hidden = hide; + } + } + }; + + this.updateOnChange = function(delta) { + var lineWidgets = this.session.lineWidgets; + if (!lineWidgets) return; + + var startRow = delta.start.row; + var len = delta.end.row - startRow; + + if (len === 0) { + } else if (delta.action == "remove") { + var removed = lineWidgets.splice(startRow + 1, len); + if (!lineWidgets[startRow] && removed[removed.length - 1]) { + lineWidgets[startRow] = removed.pop(); + } + removed.forEach(function(w) { + w && this.removeLineWidget(w); + }, this); + this.$updateRows(); + } else { + var args = new Array(len); + if (lineWidgets[startRow] && lineWidgets[startRow].column != null) { + if (delta.start.column > lineWidgets[startRow].column) + startRow++; + } + args.unshift(startRow, 0); + lineWidgets.splice.apply(lineWidgets, args); + this.$updateRows(); + } + }; + + this.$updateRows = function() { + var lineWidgets = this.session.lineWidgets; + if (!lineWidgets) return; + var noWidgets = true; + lineWidgets.forEach(function(w, i) { + if (w) { + noWidgets = false; + w.row = i; + while (w.$oldWidget) { + w.$oldWidget.row = i; + w = w.$oldWidget; + } + } + }); + if (noWidgets) + this.session.lineWidgets = null; + }; + + this.$registerLineWidget = function(w) { + if (!this.session.lineWidgets) + this.session.lineWidgets = new Array(this.session.getLength()); + + var old = this.session.lineWidgets[w.row]; + if (old) { + w.$oldWidget = old; + if (old.el && old.el.parentNode) { + old.el.parentNode.removeChild(old.el); + old._inDocument = false; + } + } + + this.session.lineWidgets[w.row] = w; + return w; + }; + + this.addLineWidget = function(w) { + this.$registerLineWidget(w); + w.session = this.session; + + if (!this.editor) return w; + + var renderer = this.editor.renderer; + if (w.html && !w.el) { + w.el = dom.createElement("div"); + w.el.innerHTML = w.html; + } + if (w.el) { + dom.addCssClass(w.el, "ace_lineWidgetContainer"); + w.el.style.position = "absolute"; + w.el.style.zIndex = 5; + renderer.container.appendChild(w.el); + w._inDocument = true; + + if (!w.coverGutter) { + w.el.style.zIndex = 3; + } + if (w.pixelHeight == null) { + w.pixelHeight = w.el.offsetHeight; + } + } + if (w.rowCount == null) { + w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight; + } + + var fold = this.session.getFoldAt(w.row, 0); + w.$fold = fold; + if (fold) { + var lineWidgets = this.session.lineWidgets; + if (w.row == fold.end.row && !lineWidgets[fold.start.row]) + lineWidgets[fold.start.row] = w; + else + w.hidden = true; + } + + this.session._emit("changeFold", {data:{start:{row: w.row}}}); + + this.$updateRows(); + this.renderWidgets(null, renderer); + this.onWidgetChanged(w); + return w; + }; + + this.removeLineWidget = function(w) { + w._inDocument = false; + w.session = null; + if (w.el && w.el.parentNode) + w.el.parentNode.removeChild(w.el); + if (w.editor && w.editor.destroy) try { + w.editor.destroy(); + } catch(e){} + if (this.session.lineWidgets) { + var w1 = this.session.lineWidgets[w.row]; + if (w1 == w) { + this.session.lineWidgets[w.row] = w.$oldWidget; + if (w.$oldWidget) + this.onWidgetChanged(w.$oldWidget); + } else { + while (w1) { + if (w1.$oldWidget == w) { + w1.$oldWidget = w.$oldWidget; + break; + } + w1 = w1.$oldWidget; + } + } + } + this.session._emit("changeFold", {data:{start:{row: w.row}}}); + this.$updateRows(); + }; + + this.getWidgetsAtRow = function(row) { + var lineWidgets = this.session.lineWidgets; + var w = lineWidgets && lineWidgets[row]; + var list = []; + while (w) { + list.push(w); + w = w.$oldWidget; + } + return list; + }; + + this.onWidgetChanged = function(w) { + this.session._changedWidgets.push(w); + this.editor && this.editor.renderer.updateFull(); + }; + + this.measureWidgets = function(e, renderer) { + var changedWidgets = this.session._changedWidgets; + var config = renderer.layerConfig; + + if (!changedWidgets || !changedWidgets.length) return; + var min = Infinity; + for (var i = 0; i < changedWidgets.length; i++) { + var w = changedWidgets[i]; + if (!w || !w.el) continue; + if (w.session != this.session) continue; + if (!w._inDocument) { + if (this.session.lineWidgets[w.row] != w) + continue; + w._inDocument = true; + renderer.container.appendChild(w.el); + } + + w.h = w.el.offsetHeight; + + if (!w.fixedWidth) { + w.w = w.el.offsetWidth; + w.screenWidth = Math.ceil(w.w / config.characterWidth); + } + + var rowCount = w.h / config.lineHeight; + if (w.coverLine) { + rowCount -= this.session.getRowLineCount(w.row); + if (rowCount < 0) + rowCount = 0; + } + if (w.rowCount != rowCount) { + w.rowCount = rowCount; + if (w.row < min) + min = w.row; + } + } + if (min != Infinity) { + this.session._emit("changeFold", {data:{start:{row: min}}}); + this.session.lineWidgetWidth = null; + } + this.session._changedWidgets = []; + }; + + this.renderWidgets = function(e, renderer) { + var config = renderer.layerConfig; + var lineWidgets = this.session.lineWidgets; + if (!lineWidgets) + return; + var first = Math.min(this.firstRow, config.firstRow); + var last = Math.max(this.lastRow, config.lastRow, lineWidgets.length); + + while (first > 0 && !lineWidgets[first]) + first--; + + this.firstRow = config.firstRow; + this.lastRow = config.lastRow; + + renderer.$cursorLayer.config = config; + for (var i = first; i <= last; i++) { + var w = lineWidgets[i]; + if (!w || !w.el) continue; + if (w.hidden) { + w.el.style.top = -100 - (w.pixelHeight || 0) + "px"; + continue; + } + if (!w._inDocument) { + w._inDocument = true; + renderer.container.appendChild(w.el); + } + var top = renderer.$cursorLayer.getPixelPosition({row: i, column:0}, true).top; + if (!w.coverLine) + top += config.lineHeight * this.session.getRowLineCount(w.row); + w.el.style.top = top - config.offset + "px"; + + var left = w.coverGutter ? 0 : renderer.gutterWidth; + if (!w.fixedWidth) + left -= renderer.scrollLeft; + w.el.style.left = left + "px"; + + if (w.fullWidth && w.screenWidth) { + w.el.style.minWidth = config.width + 2 * config.padding + "px"; + } + + if (w.fixedWidth) { + w.el.style.right = renderer.scrollBar.getWidth() + "px"; + } else { + w.el.style.right = ""; + } + } + }; + +}).call(LineWidgets.prototype); + + +exports.LineWidgets = LineWidgets; + +}); + +ace.define("ace/ext/error_marker",["require","exports","module","ace/line_widgets","ace/lib/dom","ace/range"], function(require, exports, module) { +"use strict"; +var LineWidgets = require("../line_widgets").LineWidgets; +var dom = require("../lib/dom"); +var Range = require("../range").Range; + +function binarySearch(array, needle, comparator) { + var first = 0; + var last = array.length - 1; + + while (first <= last) { + var mid = (first + last) >> 1; + var c = comparator(needle, array[mid]); + if (c > 0) + first = mid + 1; + else if (c < 0) + last = mid - 1; + else + return mid; + } + return -(first + 1); +} + +function findAnnotations(session, row, dir) { + var annotations = session.getAnnotations().sort(Range.comparePoints); + if (!annotations.length) + return; + + var i = binarySearch(annotations, {row: row, column: -1}, Range.comparePoints); + if (i < 0) + i = -i - 1; + + if (i >= annotations.length) + i = dir > 0 ? 0 : annotations.length - 1; + else if (i === 0 && dir < 0) + i = annotations.length - 1; + + var annotation = annotations[i]; + if (!annotation || !dir) + return; + + if (annotation.row === row) { + do { + annotation = annotations[i += dir]; + } while (annotation && annotation.row === row); + if (!annotation) + return annotations.slice(); + } + + + var matched = []; + row = annotation.row; + do { + matched[dir < 0 ? "unshift" : "push"](annotation); + annotation = annotations[i += dir]; + } while (annotation && annotation.row == row); + return matched.length && matched; +} + +exports.showErrorMarker = function(editor, dir) { + var session = editor.session; + if (!session.widgetManager) { + session.widgetManager = new LineWidgets(session); + session.widgetManager.attach(editor); + } + + var pos = editor.getCursorPosition(); + var row = pos.row; + var oldWidget = session.widgetManager.getWidgetsAtRow(row).filter(function(w) { + return w.type == "errorMarker"; + })[0]; + if (oldWidget) { + oldWidget.destroy(); + } else { + row -= dir; + } + var annotations = findAnnotations(session, row, dir); + var gutterAnno; + if (annotations) { + var annotation = annotations[0]; + pos.column = (annotation.pos && typeof annotation.column != "number" + ? annotation.pos.sc + : annotation.column) || 0; + pos.row = annotation.row; + gutterAnno = editor.renderer.$gutterLayer.$annotations[pos.row]; + } else if (oldWidget) { + return; + } else { + gutterAnno = { + text: ["Looks good!"], + className: "ace_ok" + }; + } + editor.session.unfold(pos.row); + editor.selection.moveToPosition(pos); + + var w = { + row: pos.row, + fixedWidth: true, + coverGutter: true, + el: dom.createElement("div"), + type: "errorMarker" + }; + var el = w.el.appendChild(dom.createElement("div")); + var arrow = w.el.appendChild(dom.createElement("div")); + arrow.className = "error_widget_arrow " + gutterAnno.className; + + var left = editor.renderer.$cursorLayer + .getPixelPosition(pos).left; + arrow.style.left = left + editor.renderer.gutterWidth - 5 + "px"; + + w.el.className = "error_widget_wrapper"; + el.className = "error_widget " + gutterAnno.className; + el.innerHTML = gutterAnno.text.join("
    "); + + el.appendChild(dom.createElement("div")); + + var kb = function(_, hashId, keyString) { + if (hashId === 0 && (keyString === "esc" || keyString === "return")) { + w.destroy(); + return {command: "null"}; + } + }; + + w.destroy = function() { + if (editor.$mouseHandler.isMousePressed) + return; + editor.keyBinding.removeKeyboardHandler(kb); + session.widgetManager.removeLineWidget(w); + editor.off("changeSelection", w.destroy); + editor.off("changeSession", w.destroy); + editor.off("mouseup", w.destroy); + editor.off("change", w.destroy); + }; + + editor.keyBinding.addKeyboardHandler(kb); + editor.on("changeSelection", w.destroy); + editor.on("changeSession", w.destroy); + editor.on("mouseup", w.destroy); + editor.on("change", w.destroy); + + editor.session.widgetManager.addLineWidget(w); + + w.el.onmousedown = editor.focus.bind(editor); + + editor.renderer.scrollCursorIntoView(null, 0.5, {bottom: w.el.offsetHeight}); +}; + + +dom.importCssString("\ + .error_widget_wrapper {\ + background: inherit;\ + color: inherit;\ + border:none\ + }\ + .error_widget {\ + border-top: solid 2px;\ + border-bottom: solid 2px;\ + margin: 5px 0;\ + padding: 10px 40px;\ + white-space: pre-wrap;\ + }\ + .error_widget.ace_error, .error_widget_arrow.ace_error{\ + border-color: #ff5a5a\ + }\ + .error_widget.ace_warning, .error_widget_arrow.ace_warning{\ + border-color: #F1D817\ + }\ + .error_widget.ace_info, .error_widget_arrow.ace_info{\ + border-color: #5a5a5a\ + }\ + .error_widget.ace_ok, .error_widget_arrow.ace_ok{\ + border-color: #5aaa5a\ + }\ + .error_widget_arrow {\ + position: absolute;\ + border: solid 5px;\ + border-top-color: transparent!important;\ + border-right-color: transparent!important;\ + border-left-color: transparent!important;\ + top: -5px;\ + }\ +", ""); + +}); + +ace.define("ace/ace",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/dom","ace/lib/event","ace/range","ace/editor","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/worker/worker_client","ace/keyboard/hash_handler","ace/placeholder","ace/multi_select","ace/mode/folding/fold_mode","ace/theme/textmate","ace/ext/error_marker","ace/config"], function(require, exports, module) { +"use strict"; + +require("./lib/fixoldbrowsers"); + +var dom = require("./lib/dom"); +var event = require("./lib/event"); + +var Range = require("./range").Range; +var Editor = require("./editor").Editor; +var EditSession = require("./edit_session").EditSession; +var UndoManager = require("./undomanager").UndoManager; +var Renderer = require("./virtual_renderer").VirtualRenderer; +require("./worker/worker_client"); +require("./keyboard/hash_handler"); +require("./placeholder"); +require("./multi_select"); +require("./mode/folding/fold_mode"); +require("./theme/textmate"); +require("./ext/error_marker"); + +exports.config = require("./config"); +exports.require = require; + +if (true) + exports.define = __webpack_require__.amdD; +exports.edit = function(el, options) { + if (typeof el == "string") { + var _id = el; + el = document.getElementById(_id); + if (!el) + throw new Error("ace.edit can't find div #" + _id); + } + + if (el && el.env && el.env.editor instanceof Editor) + return el.env.editor; + + var value = ""; + if (el && /input|textarea/i.test(el.tagName)) { + var oldNode = el; + value = oldNode.value; + el = dom.createElement("pre"); + oldNode.parentNode.replaceChild(el, oldNode); + } else if (el) { + value = el.textContent; + el.innerHTML = ""; + } + + var doc = exports.createEditSession(value); + + var editor = new Editor(new Renderer(el), doc, options); + + var env = { + document: doc, + editor: editor, + onResize: editor.resize.bind(editor, null) + }; + if (oldNode) env.textarea = oldNode; + event.addListener(window, "resize", env.onResize); + editor.on("destroy", function() { + event.removeListener(window, "resize", env.onResize); + env.editor.container.env = null; // prevent memory leak on old ie + }); + editor.container.env = editor.env = env; + return editor; +}; +exports.createEditSession = function(text, mode) { + var doc = new EditSession(text, mode); + doc.setUndoManager(new UndoManager()); + return doc; +}; +exports.Range = Range; +exports.Editor = Editor; +exports.EditSession = EditSession; +exports.UndoManager = UndoManager; +exports.VirtualRenderer = Renderer; +exports.version = exports.config.version; +}); (function() { + ace.require(["ace/ace"], function(a) { + if (a) { + a.config.init(true); + a.define = ace.define; + } + if (!window.ace) + window.ace = a; + for (var key in a) if (a.hasOwnProperty(key)) + window.ace[key] = a[key]; + window.ace["default"] = window.ace; + if ( true && module) { + module.exports = window.ace; + } + }); + })(); + + +/***/ }), + +/***/ 3330: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +/* module decorator */ module = __webpack_require__.nmd(module); +ace.define("ace/ext/searchbox",["require","exports","module","ace/lib/dom","ace/lib/lang","ace/lib/event","ace/keyboard/hash_handler","ace/lib/keys"], function(require, exports, module) { +"use strict"; + +var dom = require("../lib/dom"); +var lang = require("../lib/lang"); +var event = require("../lib/event"); +var searchboxCss = "\ +.ace_search {\ +background-color: #ddd;\ +color: #666;\ +border: 1px solid #cbcbcb;\ +border-top: 0 none;\ +overflow: hidden;\ +margin: 0;\ +padding: 4px 6px 0 4px;\ +position: absolute;\ +top: 0;\ +z-index: 99;\ +white-space: normal;\ +}\ +.ace_search.left {\ +border-left: 0 none;\ +border-radius: 0px 0px 5px 0px;\ +left: 0;\ +}\ +.ace_search.right {\ +border-radius: 0px 0px 0px 5px;\ +border-right: 0 none;\ +right: 0;\ +}\ +.ace_search_form, .ace_replace_form {\ +margin: 0 20px 4px 0;\ +overflow: hidden;\ +line-height: 1.9;\ +}\ +.ace_replace_form {\ +margin-right: 0;\ +}\ +.ace_search_form.ace_nomatch {\ +outline: 1px solid red;\ +}\ +.ace_search_field {\ +border-radius: 3px 0 0 3px;\ +background-color: white;\ +color: black;\ +border: 1px solid #cbcbcb;\ +border-right: 0 none;\ +outline: 0;\ +padding: 0;\ +font-size: inherit;\ +margin: 0;\ +line-height: inherit;\ +padding: 0 6px;\ +min-width: 17em;\ +vertical-align: top;\ +min-height: 1.8em;\ +box-sizing: content-box;\ +}\ +.ace_searchbtn {\ +border: 1px solid #cbcbcb;\ +line-height: inherit;\ +display: inline-block;\ +padding: 0 6px;\ +background: #fff;\ +border-right: 0 none;\ +border-left: 1px solid #dcdcdc;\ +cursor: pointer;\ +margin: 0;\ +position: relative;\ +color: #666;\ +}\ +.ace_searchbtn:last-child {\ +border-radius: 0 3px 3px 0;\ +border-right: 1px solid #cbcbcb;\ +}\ +.ace_searchbtn:disabled {\ +background: none;\ +cursor: default;\ +}\ +.ace_searchbtn:hover {\ +background-color: #eef1f6;\ +}\ +.ace_searchbtn.prev, .ace_searchbtn.next {\ +padding: 0px 0.7em\ +}\ +.ace_searchbtn.prev:after, .ace_searchbtn.next:after {\ +content: \"\";\ +border: solid 2px #888;\ +width: 0.5em;\ +height: 0.5em;\ +border-width: 2px 0 0 2px;\ +display:inline-block;\ +transform: rotate(-45deg);\ +}\ +.ace_searchbtn.next:after {\ +border-width: 0 2px 2px 0 ;\ +}\ +.ace_searchbtn_close {\ +background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0;\ +border-radius: 50%;\ +border: 0 none;\ +color: #656565;\ +cursor: pointer;\ +font: 16px/16px Arial;\ +padding: 0;\ +height: 14px;\ +width: 14px;\ +top: 9px;\ +right: 7px;\ +position: absolute;\ +}\ +.ace_searchbtn_close:hover {\ +background-color: #656565;\ +background-position: 50% 100%;\ +color: white;\ +}\ +.ace_button {\ +margin-left: 2px;\ +cursor: pointer;\ +-webkit-user-select: none;\ +-moz-user-select: none;\ +-o-user-select: none;\ +-ms-user-select: none;\ +user-select: none;\ +overflow: hidden;\ +opacity: 0.7;\ +border: 1px solid rgba(100,100,100,0.23);\ +padding: 1px;\ +box-sizing: border-box!important;\ +color: black;\ +}\ +.ace_button:hover {\ +background-color: #eee;\ +opacity:1;\ +}\ +.ace_button:active {\ +background-color: #ddd;\ +}\ +.ace_button.checked {\ +border-color: #3399ff;\ +opacity:1;\ +}\ +.ace_search_options{\ +margin-bottom: 3px;\ +text-align: right;\ +-webkit-user-select: none;\ +-moz-user-select: none;\ +-o-user-select: none;\ +-ms-user-select: none;\ +user-select: none;\ +clear: both;\ +}\ +.ace_search_counter {\ +float: left;\ +font-family: arial;\ +padding: 0 8px;\ +}"; +var HashHandler = require("../keyboard/hash_handler").HashHandler; +var keyUtil = require("../lib/keys"); + +var MAX_COUNT = 999; + +dom.importCssString(searchboxCss, "ace_searchbox"); + +var SearchBox = function(editor, range, showReplaceForm) { + var div = dom.createElement("div"); + dom.buildDom(["div", {class:"ace_search right"}, + ["span", {action: "hide", class: "ace_searchbtn_close"}], + ["div", {class: "ace_search_form"}, + ["input", {class: "ace_search_field", placeholder: "Search for", spellcheck: "false"}], + ["span", {action: "findPrev", class: "ace_searchbtn prev"}, "\u200b"], + ["span", {action: "findNext", class: "ace_searchbtn next"}, "\u200b"], + ["span", {action: "findAll", class: "ace_searchbtn", title: "Alt-Enter"}, "All"] + ], + ["div", {class: "ace_replace_form"}, + ["input", {class: "ace_search_field", placeholder: "Replace with", spellcheck: "false"}], + ["span", {action: "replaceAndFindNext", class: "ace_searchbtn"}, "Replace"], + ["span", {action: "replaceAll", class: "ace_searchbtn"}, "All"] + ], + ["div", {class: "ace_search_options"}, + ["span", {action: "toggleReplace", class: "ace_button", title: "Toggle Replace mode", + style: "float:left;margin-top:-2px;padding:0 5px;"}, "+"], + ["span", {class: "ace_search_counter"}], + ["span", {action: "toggleRegexpMode", class: "ace_button", title: "RegExp Search"}, ".*"], + ["span", {action: "toggleCaseSensitive", class: "ace_button", title: "CaseSensitive Search"}, "Aa"], + ["span", {action: "toggleWholeWords", class: "ace_button", title: "Whole Word Search"}, "\\b"], + ["span", {action: "searchInSelection", class: "ace_button", title: "Search In Selection"}, "S"] + ] + ], div); + this.element = div.firstChild; + + this.setSession = this.setSession.bind(this); + + this.$init(); + this.setEditor(editor); + dom.importCssString(searchboxCss, "ace_searchbox", editor.container); +}; + +(function() { + this.setEditor = function(editor) { + editor.searchBox = this; + editor.renderer.scroller.appendChild(this.element); + this.editor = editor; + }; + + this.setSession = function(e) { + this.searchRange = null; + this.$syncOptions(true); + }; + + this.$initElements = function(sb) { + this.searchBox = sb.querySelector(".ace_search_form"); + this.replaceBox = sb.querySelector(".ace_replace_form"); + this.searchOption = sb.querySelector("[action=searchInSelection]"); + this.replaceOption = sb.querySelector("[action=toggleReplace]"); + this.regExpOption = sb.querySelector("[action=toggleRegexpMode]"); + this.caseSensitiveOption = sb.querySelector("[action=toggleCaseSensitive]"); + this.wholeWordOption = sb.querySelector("[action=toggleWholeWords]"); + this.searchInput = this.searchBox.querySelector(".ace_search_field"); + this.replaceInput = this.replaceBox.querySelector(".ace_search_field"); + this.searchCounter = sb.querySelector(".ace_search_counter"); + }; + + this.$init = function() { + var sb = this.element; + + this.$initElements(sb); + + var _this = this; + event.addListener(sb, "mousedown", function(e) { + setTimeout(function(){ + _this.activeInput.focus(); + }, 0); + event.stopPropagation(e); + }); + event.addListener(sb, "click", function(e) { + var t = e.target || e.srcElement; + var action = t.getAttribute("action"); + if (action && _this[action]) + _this[action](); + else if (_this.$searchBarKb.commands[action]) + _this.$searchBarKb.commands[action].exec(_this); + event.stopPropagation(e); + }); + + event.addCommandKeyListener(sb, function(e, hashId, keyCode) { + var keyString = keyUtil.keyCodeToString(keyCode); + var command = _this.$searchBarKb.findKeyCommand(hashId, keyString); + if (command && command.exec) { + command.exec(_this); + event.stopEvent(e); + } + }); + + this.$onChange = lang.delayedCall(function() { + _this.find(false, false); + }); + + event.addListener(this.searchInput, "input", function() { + _this.$onChange.schedule(20); + }); + event.addListener(this.searchInput, "focus", function() { + _this.activeInput = _this.searchInput; + _this.searchInput.value && _this.highlight(); + }); + event.addListener(this.replaceInput, "focus", function() { + _this.activeInput = _this.replaceInput; + _this.searchInput.value && _this.highlight(); + }); + }; + this.$closeSearchBarKb = new HashHandler([{ + bindKey: "Esc", + name: "closeSearchBar", + exec: function(editor) { + editor.searchBox.hide(); + } + }]); + this.$searchBarKb = new HashHandler(); + this.$searchBarKb.bindKeys({ + "Ctrl-f|Command-f": function(sb) { + var isReplace = sb.isReplace = !sb.isReplace; + sb.replaceBox.style.display = isReplace ? "" : "none"; + sb.replaceOption.checked = false; + sb.$syncOptions(); + sb.searchInput.focus(); + }, + "Ctrl-H|Command-Option-F": function(sb) { + if (sb.editor.getReadOnly()) + return; + sb.replaceOption.checked = true; + sb.$syncOptions(); + sb.replaceInput.focus(); + }, + "Ctrl-G|Command-G": function(sb) { + sb.findNext(); + }, + "Ctrl-Shift-G|Command-Shift-G": function(sb) { + sb.findPrev(); + }, + "esc": function(sb) { + setTimeout(function() { sb.hide();}); + }, + "Return": function(sb) { + if (sb.activeInput == sb.replaceInput) + sb.replace(); + sb.findNext(); + }, + "Shift-Return": function(sb) { + if (sb.activeInput == sb.replaceInput) + sb.replace(); + sb.findPrev(); + }, + "Alt-Return": function(sb) { + if (sb.activeInput == sb.replaceInput) + sb.replaceAll(); + sb.findAll(); + }, + "Tab": function(sb) { + (sb.activeInput == sb.replaceInput ? sb.searchInput : sb.replaceInput).focus(); + } + }); + + this.$searchBarKb.addCommands([{ + name: "toggleRegexpMode", + bindKey: {win: "Alt-R|Alt-/", mac: "Ctrl-Alt-R|Ctrl-Alt-/"}, + exec: function(sb) { + sb.regExpOption.checked = !sb.regExpOption.checked; + sb.$syncOptions(); + } + }, { + name: "toggleCaseSensitive", + bindKey: {win: "Alt-C|Alt-I", mac: "Ctrl-Alt-R|Ctrl-Alt-I"}, + exec: function(sb) { + sb.caseSensitiveOption.checked = !sb.caseSensitiveOption.checked; + sb.$syncOptions(); + } + }, { + name: "toggleWholeWords", + bindKey: {win: "Alt-B|Alt-W", mac: "Ctrl-Alt-B|Ctrl-Alt-W"}, + exec: function(sb) { + sb.wholeWordOption.checked = !sb.wholeWordOption.checked; + sb.$syncOptions(); + } + }, { + name: "toggleReplace", + exec: function(sb) { + sb.replaceOption.checked = !sb.replaceOption.checked; + sb.$syncOptions(); + } + }, { + name: "searchInSelection", + exec: function(sb) { + sb.searchOption.checked = !sb.searchRange; + sb.setSearchRange(sb.searchOption.checked && sb.editor.getSelectionRange()); + sb.$syncOptions(); + } + }]); + + this.setSearchRange = function(range) { + this.searchRange = range; + if (range) { + this.searchRangeMarker = this.editor.session.addMarker(range, "ace_active-line"); + } else if (this.searchRangeMarker) { + this.editor.session.removeMarker(this.searchRangeMarker); + this.searchRangeMarker = null; + } + }; + + this.$syncOptions = function(preventScroll) { + dom.setCssClass(this.replaceOption, "checked", this.searchRange); + dom.setCssClass(this.searchOption, "checked", this.searchOption.checked); + this.replaceOption.textContent = this.replaceOption.checked ? "-" : "+"; + dom.setCssClass(this.regExpOption, "checked", this.regExpOption.checked); + dom.setCssClass(this.wholeWordOption, "checked", this.wholeWordOption.checked); + dom.setCssClass(this.caseSensitiveOption, "checked", this.caseSensitiveOption.checked); + var readOnly = this.editor.getReadOnly(); + this.replaceOption.style.display = readOnly ? "none" : ""; + this.replaceBox.style.display = this.replaceOption.checked && !readOnly ? "" : "none"; + this.find(false, false, preventScroll); + }; + + this.highlight = function(re) { + this.editor.session.highlight(re || this.editor.$search.$options.re); + this.editor.renderer.updateBackMarkers(); + }; + this.find = function(skipCurrent, backwards, preventScroll) { + var range = this.editor.find(this.searchInput.value, { + skipCurrent: skipCurrent, + backwards: backwards, + wrap: true, + regExp: this.regExpOption.checked, + caseSensitive: this.caseSensitiveOption.checked, + wholeWord: this.wholeWordOption.checked, + preventScroll: preventScroll, + range: this.searchRange + }); + var noMatch = !range && this.searchInput.value; + dom.setCssClass(this.searchBox, "ace_nomatch", noMatch); + this.editor._emit("findSearchBox", { match: !noMatch }); + this.highlight(); + this.updateCounter(); + }; + this.updateCounter = function() { + var editor = this.editor; + var regex = editor.$search.$options.re; + var all = 0; + var before = 0; + if (regex) { + var value = this.searchRange + ? editor.session.getTextRange(this.searchRange) + : editor.getValue(); + + var offset = editor.session.doc.positionToIndex(editor.selection.anchor); + if (this.searchRange) + offset -= editor.session.doc.positionToIndex(this.searchRange.start); + + var last = regex.lastIndex = 0; + var m; + while ((m = regex.exec(value))) { + all++; + last = m.index; + if (last <= offset) + before++; + if (all > MAX_COUNT) + break; + if (!m[0]) { + regex.lastIndex = last += 1; + if (last >= value.length) + break; + } + } + } + this.searchCounter.textContent = before + " of " + (all > MAX_COUNT ? MAX_COUNT + "+" : all); + }; + this.findNext = function() { + this.find(true, false); + }; + this.findPrev = function() { + this.find(true, true); + }; + this.findAll = function(){ + var range = this.editor.findAll(this.searchInput.value, { + regExp: this.regExpOption.checked, + caseSensitive: this.caseSensitiveOption.checked, + wholeWord: this.wholeWordOption.checked + }); + var noMatch = !range && this.searchInput.value; + dom.setCssClass(this.searchBox, "ace_nomatch", noMatch); + this.editor._emit("findSearchBox", { match: !noMatch }); + this.highlight(); + this.hide(); + }; + this.replace = function() { + if (!this.editor.getReadOnly()) + this.editor.replace(this.replaceInput.value); + }; + this.replaceAndFindNext = function() { + if (!this.editor.getReadOnly()) { + this.editor.replace(this.replaceInput.value); + this.findNext(); + } + }; + this.replaceAll = function() { + if (!this.editor.getReadOnly()) + this.editor.replaceAll(this.replaceInput.value); + }; + + this.hide = function() { + this.active = false; + this.setSearchRange(null); + this.editor.off("changeSession", this.setSession); + + this.element.style.display = "none"; + this.editor.keyBinding.removeKeyboardHandler(this.$closeSearchBarKb); + this.editor.focus(); + }; + this.show = function(value, isReplace) { + this.active = true; + this.editor.on("changeSession", this.setSession); + this.element.style.display = ""; + this.replaceOption.checked = isReplace; + + if (value) + this.searchInput.value = value; + + this.searchInput.focus(); + this.searchInput.select(); + + this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb); + + this.$syncOptions(true); + }; + + this.isFocused = function() { + var el = document.activeElement; + return el == this.searchInput || el == this.replaceInput; + }; +}).call(SearchBox.prototype); + +exports.SearchBox = SearchBox; + +exports.Search = function(editor, isReplace) { + var sb = editor.searchBox || new SearchBox(editor); + sb.show(editor.session.getTextRange(), isReplace); +}; + +}); (function() { + ace.require(["ace/ext/searchbox"], function(m) { + if ( true && module) { + module.exports = m; + } + }); + })(); + + +/***/ }), + +/***/ 4091: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +/* module decorator */ module = __webpack_require__.nmd(module); +ace.define("ace/mode/json_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var JsonHighlightRules = function() { + this.$rules = { + "start" : [ + { + token : "variable", // single line + regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]\\s*(?=:)' + }, { + token : "string", // single line + regex : '"', + next : "string" + }, { + token : "constant.numeric", // hex + regex : "0[xX][0-9a-fA-F]+\\b" + }, { + token : "constant.numeric", // float + regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" + }, { + token : "constant.language.boolean", + regex : "(?:true|false)\\b" + }, { + token : "text", // single quoted strings are not allowed + regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" + }, { + token : "comment", // comments are not allowed, but who cares? + regex : "\\/\\/.*$" + }, { + token : "comment.start", // comments are not allowed, but who cares? + regex : "\\/\\*", + next : "comment" + }, { + token : "paren.lparen", + regex : "[[({]" + }, { + token : "paren.rparen", + regex : "[\\])}]" + }, { + token : "text", + regex : "\\s+" + } + ], + "string" : [ + { + token : "constant.language.escape", + regex : /\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|["\\\/bfnrt])/ + }, { + token : "string", + regex : '"|$', + next : "start" + }, { + defaultToken : "string" + } + ], + "comment" : [ + { + token : "comment.end", // comments are not allowed, but who cares? + regex : "\\*\\/", + next : "start" + }, { + defaultToken: "comment" + } + ] + }; + +}; + +oop.inherits(JsonHighlightRules, TextHighlightRules); + +exports.JsonHighlightRules = JsonHighlightRules; +}); + +ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) { +"use strict"; + +var Range = require("../range").Range; + +var MatchingBraceOutdent = function() {}; + +(function() { + + this.checkOutdent = function(line, input) { + if (! /^\s+$/.test(line)) + return false; + + return /^\s*\}/.test(input); + }; + + this.autoOutdent = function(doc, row) { + var line = doc.getLine(row); + var match = line.match(/^(\s*\})/); + + if (!match) return 0; + + var column = match[1].length; + var openBracePos = doc.findMatchingBracket({row: row, column: column}); + + if (!openBracePos || openBracePos.row == row) return 0; + + var indent = this.$getIndent(doc.getLine(openBracePos.row)); + doc.replace(new Range(row, 0, row, column-1), indent); + }; + + this.$getIndent = function(line) { + return line.match(/^\s*/)[0]; + }; + +}).call(MatchingBraceOutdent.prototype); + +exports.MatchingBraceOutdent = MatchingBraceOutdent; +}); + +ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Range = require("../../range").Range; +var BaseFoldMode = require("./fold_mode").FoldMode; + +var FoldMode = exports.FoldMode = function(commentRegex) { + if (commentRegex) { + this.foldingStartMarker = new RegExp( + this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) + ); + this.foldingStopMarker = new RegExp( + this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) + ); + } +}; +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + + this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/; + this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/; + this.singleLineBlockCommentRe= /^\s*(\/\*).*\*\/\s*$/; + this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/; + this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/; + this._getFoldWidgetBase = this.getFoldWidget; + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + + if (this.singleLineBlockCommentRe.test(line)) { + if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line)) + return ""; + } + + var fw = this._getFoldWidgetBase(session, foldStyle, row); + + if (!fw && this.startRegionRe.test(line)) + return "start"; // lineCommentRegionStart + + return fw; + }; + + this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { + var line = session.getLine(row); + + if (this.startRegionRe.test(line)) + return this.getCommentRegionBlock(session, line, row); + + var match = line.match(this.foldingStartMarker); + if (match) { + var i = match.index; + + if (match[1]) + return this.openingBracketBlock(session, match[1], row, i); + + var range = session.getCommentFoldRange(row, i + match[0].length, 1); + + if (range && !range.isMultiLine()) { + if (forceMultiline) { + range = this.getSectionRange(session, row); + } else if (foldStyle != "all") + range = null; + } + + return range; + } + + if (foldStyle === "markbegin") + return; + + var match = line.match(this.foldingStopMarker); + if (match) { + var i = match.index + match[0].length; + + if (match[1]) + return this.closingBracketBlock(session, match[1], row, i); + + return session.getCommentFoldRange(row, i, -1); + } + }; + + this.getSectionRange = function(session, row) { + var line = session.getLine(row); + var startIndent = line.search(/\S/); + var startRow = row; + var startColumn = line.length; + row = row + 1; + var endRow = row; + var maxRow = session.getLength(); + while (++row < maxRow) { + line = session.getLine(row); + var indent = line.search(/\S/); + if (indent === -1) + continue; + if (startIndent > indent) + break; + var subRange = this.getFoldWidgetRange(session, "all", row); + + if (subRange) { + if (subRange.start.row <= startRow) { + break; + } else if (subRange.isMultiLine()) { + row = subRange.end.row; + } else if (startIndent == indent) { + break; + } + } + endRow = row; + } + + return new Range(startRow, startColumn, endRow, session.getLine(endRow).length); + }; + this.getCommentRegionBlock = function(session, line, row) { + var startColumn = line.search(/\s*$/); + var maxRow = session.getLength(); + var startRow = row; + + var re = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/; + var depth = 1; + while (++row < maxRow) { + line = session.getLine(row); + var m = re.exec(line); + if (!m) continue; + if (m[1]) depth--; + else depth++; + + if (!depth) break; + } + + var endRow = row; + if (endRow > startRow) { + return new Range(startRow, startColumn, endRow, line.length); + } + }; + +}).call(FoldMode.prototype); + +}); + +ace.define("ace/mode/json",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/json_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle","ace/worker/worker_client"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var HighlightRules = require("./json_highlight_rules").JsonHighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; +var CStyleFoldMode = require("./folding/cstyle").FoldMode; +var WorkerClient = require("../worker/worker_client").WorkerClient; + +var Mode = function() { + this.HighlightRules = HighlightRules; + this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CstyleBehaviour(); + this.foldingRules = new CStyleFoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + + this.lineCommentStart = "//"; + this.blockComment = {start: "/*", end: "*/"}; + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + + if (state == "start") { + var match = line.match(/^.*[\{\(\[]\s*$/); + if (match) { + indent += tab; + } + } + + return indent; + }; + + this.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); + }; + + this.autoOutdent = function(state, doc, row) { + this.$outdent.autoOutdent(doc, row); + }; + + this.createWorker = function(session) { + var worker = new WorkerClient(["ace"], "ace/mode/json_worker", "JsonWorker"); + worker.attachToDocument(session.getDocument()); + + worker.on("annotate", function(e) { + session.setAnnotations(e.data); + }); + + worker.on("terminate", function() { + session.clearAnnotations(); + }); + + return worker; + }; + + + this.$id = "ace/mode/json"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); (function() { + ace.require(["ace/mode/json"], function(m) { + if ( true && module) { + module.exports = m; + } + }); + })(); + + +/***/ }), + +/***/ 8903: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +"use strict"; + + +var compileSchema = __webpack_require__(5689) + , resolve = __webpack_require__(3969) + , Cache = __webpack_require__(5255) + , SchemaObject = __webpack_require__(4293) + , stableStringify = __webpack_require__(3508) + , formats = __webpack_require__(3368) + , rules = __webpack_require__(742) + , $dataMetaSchema = __webpack_require__(9394) + , util = __webpack_require__(3724); + +module.exports = Ajv; + +Ajv.prototype.validate = validate; +Ajv.prototype.compile = compile; +Ajv.prototype.addSchema = addSchema; +Ajv.prototype.addMetaSchema = addMetaSchema; +Ajv.prototype.validateSchema = validateSchema; +Ajv.prototype.getSchema = getSchema; +Ajv.prototype.removeSchema = removeSchema; +Ajv.prototype.addFormat = addFormat; +Ajv.prototype.errorsText = errorsText; + +Ajv.prototype._addSchema = _addSchema; +Ajv.prototype._compile = _compile; + +Ajv.prototype.compileAsync = __webpack_require__(9677); +var customKeyword = __webpack_require__(7931); +Ajv.prototype.addKeyword = customKeyword.add; +Ajv.prototype.getKeyword = customKeyword.get; +Ajv.prototype.removeKeyword = customKeyword.remove; +Ajv.prototype.validateKeyword = customKeyword.validate; + +var errorClasses = __webpack_require__(5359); +Ajv.ValidationError = errorClasses.Validation; +Ajv.MissingRefError = errorClasses.MissingRef; +Ajv.$dataMetaSchema = $dataMetaSchema; + +var META_SCHEMA_ID = 'http://json-schema.org/draft-07/schema'; + +var META_IGNORE_OPTIONS = [ 'removeAdditional', 'useDefaults', 'coerceTypes', 'strictDefaults' ]; +var META_SUPPORT_DATA = ['/properties']; + +/** + * Creates validator instance. + * Usage: `Ajv(opts)` + * @param {Object} opts optional options + * @return {Object} ajv instance + */ +function Ajv(opts) { + if (!(this instanceof Ajv)) return new Ajv(opts); + opts = this._opts = util.copy(opts) || {}; + setLogger(this); + this._schemas = {}; + this._refs = {}; + this._fragments = {}; + this._formats = formats(opts.format); + + this._cache = opts.cache || new Cache; + this._loadingSchemas = {}; + this._compilations = []; + this.RULES = rules(); + this._getId = chooseGetId(opts); + + opts.loopRequired = opts.loopRequired || Infinity; + if (opts.errorDataPath == 'property') opts._errorDataPathProperty = true; + if (opts.serialize === undefined) opts.serialize = stableStringify; + this._metaOpts = getMetaSchemaOptions(this); + + if (opts.formats) addInitialFormats(this); + if (opts.keywords) addInitialKeywords(this); + addDefaultMetaSchema(this); + if (typeof opts.meta == 'object') this.addMetaSchema(opts.meta); + if (opts.nullable) this.addKeyword('nullable', {metaSchema: {type: 'boolean'}}); + addInitialSchemas(this); +} + + + +/** + * Validate data using schema + * Schema will be compiled and cached (using serialized JSON as key. [fast-json-stable-stringify](https://github.com/epoberezkin/fast-json-stable-stringify) is used to serialize. + * @this Ajv + * @param {String|Object} schemaKeyRef key, ref or schema object + * @param {Any} data to be validated + * @return {Boolean} validation result. Errors from the last validation will be available in `ajv.errors` (and also in compiled schema: `schema.errors`). + */ +function validate(schemaKeyRef, data) { + var v; + if (typeof schemaKeyRef == 'string') { + v = this.getSchema(schemaKeyRef); + if (!v) throw new Error('no schema with key or ref "' + schemaKeyRef + '"'); + } else { + var schemaObj = this._addSchema(schemaKeyRef); + v = schemaObj.validate || this._compile(schemaObj); + } + + var valid = v(data); + if (v.$async !== true) this.errors = v.errors; + return valid; +} + + +/** + * Create validating function for passed schema. + * @this Ajv + * @param {Object} schema schema object + * @param {Boolean} _meta true if schema is a meta-schema. Used internally to compile meta schemas of custom keywords. + * @return {Function} validating function + */ +function compile(schema, _meta) { + var schemaObj = this._addSchema(schema, undefined, _meta); + return schemaObj.validate || this._compile(schemaObj); +} + + +/** + * Adds schema to the instance. + * @this Ajv + * @param {Object|Array} schema schema or array of schemas. If array is passed, `key` and other parameters will be ignored. + * @param {String} key Optional schema key. Can be passed to `validate` method instead of schema object or id/ref. One schema per instance can have empty `id` and `key`. + * @param {Boolean} _skipValidation true to skip schema validation. Used internally, option validateSchema should be used instead. + * @param {Boolean} _meta true if schema is a meta-schema. Used internally, addMetaSchema should be used instead. + * @return {Ajv} this for method chaining + */ +function addSchema(schema, key, _skipValidation, _meta) { + if (Array.isArray(schema)){ + for (var i=0; i} errors optional array of validation errors, if not passed errors from the instance are used. + * @param {Object} options optional options with properties `separator` and `dataVar`. + * @return {String} human readable string with all errors descriptions + */ +function errorsText(errors, options) { + errors = errors || this.errors; + if (!errors) return 'No errors'; + options = options || {}; + var separator = options.separator === undefined ? ', ' : options.separator; + var dataVar = options.dataVar === undefined ? 'data' : options.dataVar; + + var text = ''; + for (var i=0; i%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i; +// For the source: https://gist.github.com/dperini/729294 +// For test cases: https://mathiasbynens.be/demo/url-regex +// @todo Delete current URL in favour of the commented out URL rule when this issue is fixed https://github.com/eslint/eslint/issues/7983. +// var URL = /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!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\u{00a1}-\u{ffff}0-9]+-)*[a-z\u{00a1}-\u{ffff}0-9]+)(?:\.(?:[a-z\u{00a1}-\u{ffff}0-9]+-)*[a-z\u{00a1}-\u{ffff}0-9]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu; +var URL = /^(?:(?:http[s\u017F]?|ftp):\/\/)(?:(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+(?::(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?@)?(?:(?!10(?:\.[0-9]{1,3}){3})(?!127(?:\.[0-9]{1,3}){3})(?!169\.254(?:\.[0-9]{1,3}){2})(?!192\.168(?:\.[0-9]{1,3}){2})(?!172\.(?:1[6-9]|2[0-9]|3[01])(?:\.[0-9]{1,3}){2})(?:[1-9][0-9]?|1[0-9][0-9]|2[01][0-9]|22[0-3])(?:\.(?:1?[0-9]{1,2}|2[0-4][0-9]|25[0-5])){2}(?:\.(?:[1-9][0-9]?|1[0-9][0-9]|2[0-4][0-9]|25[0-4]))|(?:(?:(?:[0-9a-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-)*(?:[0-9a-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)(?:\.(?:(?:[0-9a-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+-)*(?:[0-9a-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])+)*(?:\.(?:(?:[a-z\xA1-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]){2,})))(?::[0-9]{2,5})?(?:\/(?:[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uD7FF\uE000-\uFEFE\uFF00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])*)?$/i; +var UUID = /^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i; +var JSON_POINTER = /^(?:\/(?:[^~/]|~0|~1)*)*$/; +var JSON_POINTER_URI_FRAGMENT = /^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i; +var RELATIVE_JSON_POINTER = /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/; + + +module.exports = formats; + +function formats(mode) { + mode = mode == 'full' ? 'full' : 'fast'; + return util.copy(formats[mode]); +} + + +formats.fast = { + // date: http://tools.ietf.org/html/rfc3339#section-5.6 + date: /^\d\d\d\d-[0-1]\d-[0-3]\d$/, + // date-time: http://tools.ietf.org/html/rfc3339#section-5.6 + time: /^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)?$/i, + 'date-time': /^\d\d\d\d-[0-1]\d-[0-3]\d[t\s](?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i, + // uri: https://github.com/mafintosh/is-my-json-valid/blob/master/formats.js + uri: /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/)?[^\s]*$/i, + 'uri-reference': /^(?:(?:[a-z][a-z0-9+\-.]*:)?\/?\/)?(?:[^\\\s#][^\s#]*)?(?:#[^\\\s]*)?$/i, + 'uri-template': URITEMPLATE, + url: URL, + // email (sources from jsen validator): + // http://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address#answer-8829363 + // http://www.w3.org/TR/html5/forms.html#valid-e-mail-address (search for 'willful violation') + email: /^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i, + hostname: HOSTNAME, + // optimized https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html + ipv4: /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/, + // optimized http://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses + ipv6: /^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i, + regex: regex, + // uuid: http://tools.ietf.org/html/rfc4122 + uuid: UUID, + // JSON-pointer: https://tools.ietf.org/html/rfc6901 + // uri fragment: https://tools.ietf.org/html/rfc3986#appendix-A + 'json-pointer': JSON_POINTER, + 'json-pointer-uri-fragment': JSON_POINTER_URI_FRAGMENT, + // relative JSON-pointer: http://tools.ietf.org/html/draft-luff-relative-json-pointer-00 + 'relative-json-pointer': RELATIVE_JSON_POINTER +}; + + +formats.full = { + date: date, + time: time, + 'date-time': date_time, + uri: uri, + 'uri-reference': URIREF, + 'uri-template': URITEMPLATE, + url: URL, + email: /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i, + hostname: HOSTNAME, + ipv4: /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/, + ipv6: /^\s*(?:(?:(?:[0-9a-f]{1,4}:){7}(?:[0-9a-f]{1,4}|:))|(?:(?:[0-9a-f]{1,4}:){6}(?::[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){5}(?:(?:(?::[0-9a-f]{1,4}){1,2})|:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(?:(?:[0-9a-f]{1,4}:){4}(?:(?:(?::[0-9a-f]{1,4}){1,3})|(?:(?::[0-9a-f]{1,4})?:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){3}(?:(?:(?::[0-9a-f]{1,4}){1,4})|(?:(?::[0-9a-f]{1,4}){0,2}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){2}(?:(?:(?::[0-9a-f]{1,4}){1,5})|(?:(?::[0-9a-f]{1,4}){0,3}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?:(?:[0-9a-f]{1,4}:){1}(?:(?:(?::[0-9a-f]{1,4}){1,6})|(?:(?::[0-9a-f]{1,4}){0,4}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(?::(?:(?:(?::[0-9a-f]{1,4}){1,7})|(?:(?::[0-9a-f]{1,4}){0,5}:(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(?:%.+)?\s*$/i, + regex: regex, + uuid: UUID, + 'json-pointer': JSON_POINTER, + 'json-pointer-uri-fragment': JSON_POINTER_URI_FRAGMENT, + 'relative-json-pointer': RELATIVE_JSON_POINTER +}; + + +function isLeapYear(year) { + // https://tools.ietf.org/html/rfc3339#appendix-C + return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0); +} + + +function date(str) { + // full-date from http://tools.ietf.org/html/rfc3339#section-5.6 + var matches = str.match(DATE); + if (!matches) return false; + + var year = +matches[1]; + var month = +matches[2]; + var day = +matches[3]; + + return month >= 1 && month <= 12 && day >= 1 && + day <= (month == 2 && isLeapYear(year) ? 29 : DAYS[month]); +} + + +function time(str, full) { + var matches = str.match(TIME); + if (!matches) return false; + + var hour = matches[1]; + var minute = matches[2]; + var second = matches[3]; + var timeZone = matches[5]; + return ((hour <= 23 && minute <= 59 && second <= 59) || + (hour == 23 && minute == 59 && second == 60)) && + (!full || timeZone); +} + + +var DATE_TIME_SEPARATOR = /t|\s/i; +function date_time(str) { + // http://tools.ietf.org/html/rfc3339#section-5.6 + var dateTime = str.split(DATE_TIME_SEPARATOR); + return dateTime.length == 2 && date(dateTime[0]) && time(dateTime[1], true); +} + + +var NOT_URI_FRAGMENT = /\/|:/; +function uri(str) { + // http://jmrware.com/articles/2009/uri_regexp/URI_regex.html + optional protocol + required "." + return NOT_URI_FRAGMENT.test(str) && URI.test(str); +} + + +var Z_ANCHOR = /[^\\]\\Z/; +function regex(str) { + if (Z_ANCHOR.test(str)) return false; + try { + new RegExp(str); + return true; + } catch(e) { + return false; + } +} + + +/***/ }), + +/***/ 5689: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +"use strict"; + + +var resolve = __webpack_require__(3969) + , util = __webpack_require__(3724) + , errorClasses = __webpack_require__(5359) + , stableStringify = __webpack_require__(3508); + +var validateGenerator = __webpack_require__(1869); + +/** + * Functions below are used inside compiled validations function + */ + +var ucs2length = util.ucs2length; +var equal = __webpack_require__(2303); + +// this error is thrown by async schemas to return validation errors via exception +var ValidationError = errorClasses.Validation; + +module.exports = compile; + + +/** + * Compiles schema to validation function + * @this Ajv + * @param {Object} schema schema object + * @param {Object} root object with information about the root schema for this schema + * @param {Object} localRefs the hash of local references inside the schema (created by resolve.id), used for inline resolution + * @param {String} baseId base ID for IDs in the schema + * @return {Function} validation function + */ +function compile(schema, root, localRefs, baseId) { + /* jshint validthis: true, evil: true */ + /* eslint no-shadow: 0 */ + var self = this + , opts = this._opts + , refVal = [ undefined ] + , refs = {} + , patterns = [] + , patternsHash = {} + , defaults = [] + , defaultsHash = {} + , customRules = []; + + root = root || { schema: schema, refVal: refVal, refs: refs }; + + var c = checkCompiling.call(this, schema, root, baseId); + var compilation = this._compilations[c.index]; + if (c.compiling) return (compilation.callValidate = callValidate); + + var formats = this._formats; + var RULES = this.RULES; + + try { + var v = localCompile(schema, root, localRefs, baseId); + compilation.validate = v; + var cv = compilation.callValidate; + if (cv) { + cv.schema = v.schema; + cv.errors = null; + cv.refs = v.refs; + cv.refVal = v.refVal; + cv.root = v.root; + cv.$async = v.$async; + if (opts.sourceCode) cv.source = v.source; + } + return v; + } finally { + endCompiling.call(this, schema, root, baseId); + } + + /* @this {*} - custom context, see passContext option */ + function callValidate() { + /* jshint validthis: true */ + var validate = compilation.validate; + var result = validate.apply(this, arguments); + callValidate.errors = validate.errors; + return result; + } + + function localCompile(_schema, _root, localRefs, baseId) { + var isRoot = !_root || (_root && _root.schema == _schema); + if (_root.schema != root.schema) + return compile.call(self, _schema, _root, localRefs, baseId); + + var $async = _schema.$async === true; + + var sourceCode = validateGenerator({ + isTop: true, + schema: _schema, + isRoot: isRoot, + baseId: baseId, + root: _root, + schemaPath: '', + errSchemaPath: '#', + errorPath: '""', + MissingRefError: errorClasses.MissingRef, + RULES: RULES, + validate: validateGenerator, + util: util, + resolve: resolve, + resolveRef: resolveRef, + usePattern: usePattern, + useDefault: useDefault, + useCustomRule: useCustomRule, + opts: opts, + formats: formats, + logger: self.logger, + self: self + }); + + sourceCode = vars(refVal, refValCode) + vars(patterns, patternCode) + + vars(defaults, defaultCode) + vars(customRules, customRuleCode) + + sourceCode; + + if (opts.processCode) sourceCode = opts.processCode(sourceCode, _schema); + // console.log('\n\n\n *** \n', JSON.stringify(sourceCode)); + var validate; + try { + var makeValidate = new Function( + 'self', + 'RULES', + 'formats', + 'root', + 'refVal', + 'defaults', + 'customRules', + 'equal', + 'ucs2length', + 'ValidationError', + sourceCode + ); + + validate = makeValidate( + self, + RULES, + formats, + root, + refVal, + defaults, + customRules, + equal, + ucs2length, + ValidationError + ); + + refVal[0] = validate; + } catch(e) { + self.logger.error('Error compiling schema, function code:', sourceCode); + throw e; + } + + validate.schema = _schema; + validate.errors = null; + validate.refs = refs; + validate.refVal = refVal; + validate.root = isRoot ? validate : _root; + if ($async) validate.$async = true; + if (opts.sourceCode === true) { + validate.source = { + code: sourceCode, + patterns: patterns, + defaults: defaults + }; + } + + return validate; + } + + function resolveRef(baseId, ref, isRoot) { + ref = resolve.url(baseId, ref); + var refIndex = refs[ref]; + var _refVal, refCode; + if (refIndex !== undefined) { + _refVal = refVal[refIndex]; + refCode = 'refVal[' + refIndex + ']'; + return resolvedRef(_refVal, refCode); + } + if (!isRoot && root.refs) { + var rootRefId = root.refs[ref]; + if (rootRefId !== undefined) { + _refVal = root.refVal[rootRefId]; + refCode = addLocalRef(ref, _refVal); + return resolvedRef(_refVal, refCode); + } + } + + refCode = addLocalRef(ref); + var v = resolve.call(self, localCompile, root, ref); + if (v === undefined) { + var localSchema = localRefs && localRefs[ref]; + if (localSchema) { + v = resolve.inlineRef(localSchema, opts.inlineRefs) + ? localSchema + : compile.call(self, localSchema, root, localRefs, baseId); + } + } + + if (v === undefined) { + removeLocalRef(ref); + } else { + replaceLocalRef(ref, v); + return resolvedRef(v, refCode); + } + } + + function addLocalRef(ref, v) { + var refId = refVal.length; + refVal[refId] = v; + refs[ref] = refId; + return 'refVal' + refId; + } + + function removeLocalRef(ref) { + delete refs[ref]; + } + + function replaceLocalRef(ref, v) { + var refId = refs[ref]; + refVal[refId] = v; + } + + function resolvedRef(refVal, code) { + return typeof refVal == 'object' || typeof refVal == 'boolean' + ? { code: code, schema: refVal, inline: true } + : { code: code, $async: refVal && !!refVal.$async }; + } + + function usePattern(regexStr) { + var index = patternsHash[regexStr]; + if (index === undefined) { + index = patternsHash[regexStr] = patterns.length; + patterns[index] = regexStr; + } + return 'pattern' + index; + } + + function useDefault(value) { + switch (typeof value) { + case 'boolean': + case 'number': + return '' + value; + case 'string': + return util.toQuotedString(value); + case 'object': + if (value === null) return 'null'; + var valueStr = stableStringify(value); + var index = defaultsHash[valueStr]; + if (index === undefined) { + index = defaultsHash[valueStr] = defaults.length; + defaults[index] = value; + } + return 'default' + index; + } + } + + function useCustomRule(rule, schema, parentSchema, it) { + if (self._opts.validateSchema !== false) { + var deps = rule.definition.dependencies; + if (deps && !deps.every(function(keyword) { + return Object.prototype.hasOwnProperty.call(parentSchema, keyword); + })) + throw new Error('parent schema must have all required keywords: ' + deps.join(',')); + + var validateSchema = rule.definition.validateSchema; + if (validateSchema) { + var valid = validateSchema(schema); + if (!valid) { + var message = 'keyword schema is invalid: ' + self.errorsText(validateSchema.errors); + if (self._opts.validateSchema == 'log') self.logger.error(message); + else throw new Error(message); + } + } + } + + var compile = rule.definition.compile + , inline = rule.definition.inline + , macro = rule.definition.macro; + + var validate; + if (compile) { + validate = compile.call(self, schema, parentSchema, it); + } else if (macro) { + validate = macro.call(self, schema, parentSchema, it); + if (opts.validateSchema !== false) self.validateSchema(validate, true); + } else if (inline) { + validate = inline.call(self, it, rule.keyword, schema, parentSchema); + } else { + validate = rule.definition.validate; + if (!validate) return; + } + + if (validate === undefined) + throw new Error('custom keyword "' + rule.keyword + '"failed to compile'); + + var index = customRules.length; + customRules[index] = validate; + + return { + code: 'customRule' + index, + validate: validate + }; + } +} + + +/** + * Checks if the schema is currently compiled + * @this Ajv + * @param {Object} schema schema to compile + * @param {Object} root root object + * @param {String} baseId base schema ID + * @return {Object} object with properties "index" (compilation index) and "compiling" (boolean) + */ +function checkCompiling(schema, root, baseId) { + /* jshint validthis: true */ + var index = compIndex.call(this, schema, root, baseId); + if (index >= 0) return { index: index, compiling: true }; + index = this._compilations.length; + this._compilations[index] = { + schema: schema, + root: root, + baseId: baseId + }; + return { index: index, compiling: false }; +} + + +/** + * Removes the schema from the currently compiled list + * @this Ajv + * @param {Object} schema schema to compile + * @param {Object} root root object + * @param {String} baseId base schema ID + */ +function endCompiling(schema, root, baseId) { + /* jshint validthis: true */ + var i = compIndex.call(this, schema, root, baseId); + if (i >= 0) this._compilations.splice(i, 1); +} + + +/** + * Index of schema compilation in the currently compiled list + * @this Ajv + * @param {Object} schema schema to compile + * @param {Object} root root object + * @param {String} baseId base schema ID + * @return {Integer} compilation index + */ +function compIndex(schema, root, baseId) { + /* jshint validthis: true */ + for (var i=0; i= 0xD800 && value <= 0xDBFF && pos < len) { + // high surrogate, and there is a next character + value = str.charCodeAt(pos); + if ((value & 0xFC00) == 0xDC00) pos++; // low surrogate + } + } + return length; +}; + + +/***/ }), + +/***/ 3724: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +"use strict"; + + + +module.exports = { + copy: copy, + checkDataType: checkDataType, + checkDataTypes: checkDataTypes, + coerceToTypes: coerceToTypes, + toHash: toHash, + getProperty: getProperty, + escapeQuotes: escapeQuotes, + equal: __webpack_require__(2303), + ucs2length: __webpack_require__(6887), + varOccurences: varOccurences, + varReplace: varReplace, + schemaHasRules: schemaHasRules, + schemaHasRulesExcept: schemaHasRulesExcept, + schemaUnknownRules: schemaUnknownRules, + toQuotedString: toQuotedString, + getPathExpr: getPathExpr, + getPath: getPath, + getData: getData, + unescapeFragment: unescapeFragment, + unescapeJsonPointer: unescapeJsonPointer, + escapeFragment: escapeFragment, + escapeJsonPointer: escapeJsonPointer +}; + + +function copy(o, to) { + to = to || {}; + for (var key in o) to[key] = o[key]; + return to; +} + + +function checkDataType(dataType, data, strictNumbers, negate) { + var EQUAL = negate ? ' !== ' : ' === ' + , AND = negate ? ' || ' : ' && ' + , OK = negate ? '!' : '' + , NOT = negate ? '' : '!'; + switch (dataType) { + case 'null': return data + EQUAL + 'null'; + case 'array': return OK + 'Array.isArray(' + data + ')'; + case 'object': return '(' + OK + data + AND + + 'typeof ' + data + EQUAL + '"object"' + AND + + NOT + 'Array.isArray(' + data + '))'; + case 'integer': return '(typeof ' + data + EQUAL + '"number"' + AND + + NOT + '(' + data + ' % 1)' + + AND + data + EQUAL + data + + (strictNumbers ? (AND + OK + 'isFinite(' + data + ')') : '') + ')'; + case 'number': return '(typeof ' + data + EQUAL + '"' + dataType + '"' + + (strictNumbers ? (AND + OK + 'isFinite(' + data + ')') : '') + ')'; + default: return 'typeof ' + data + EQUAL + '"' + dataType + '"'; + } +} + + +function checkDataTypes(dataTypes, data, strictNumbers) { + switch (dataTypes.length) { + case 1: return checkDataType(dataTypes[0], data, strictNumbers, true); + default: + var code = ''; + var types = toHash(dataTypes); + if (types.array && types.object) { + code = types.null ? '(': '(!' + data + ' || '; + code += 'typeof ' + data + ' !== "object")'; + delete types.null; + delete types.array; + delete types.object; + } + if (types.number) delete types.integer; + for (var t in types) + code += (code ? ' && ' : '' ) + checkDataType(t, data, strictNumbers, true); + + return code; + } +} + + +var COERCE_TO_TYPES = toHash([ 'string', 'number', 'integer', 'boolean', 'null' ]); +function coerceToTypes(optionCoerceTypes, dataTypes) { + if (Array.isArray(dataTypes)) { + var types = []; + for (var i=0; i= lvl) throw new Error('Cannot access property/index ' + up + ' levels up, current level is ' + lvl); + return paths[lvl - up]; + } + + if (up > lvl) throw new Error('Cannot access data ' + up + ' levels up, current level is ' + lvl); + data = 'data' + ((lvl - up) || ''); + if (!jsonPointer) return data; + } + + var expr = data; + var segments = jsonPointer.split('/'); + for (var i=0; i', + $notOp = $isMax ? '>' : '<', + $errorKeyword = undefined; + if (!($isData || typeof $schema == 'number' || $schema === undefined)) { + throw new Error($keyword + ' must be number'); + } + if (!($isDataExcl || $schemaExcl === undefined || typeof $schemaExcl == 'number' || typeof $schemaExcl == 'boolean')) { + throw new Error($exclusiveKeyword + ' must be number or boolean'); + } + if ($isDataExcl) { + var $schemaValueExcl = it.util.getData($schemaExcl.$data, $dataLvl, it.dataPathArr), + $exclusive = 'exclusive' + $lvl, + $exclType = 'exclType' + $lvl, + $exclIsNumber = 'exclIsNumber' + $lvl, + $opExpr = 'op' + $lvl, + $opStr = '\' + ' + $opExpr + ' + \''; + out += ' var schemaExcl' + ($lvl) + ' = ' + ($schemaValueExcl) + '; '; + $schemaValueExcl = 'schemaExcl' + $lvl; + out += ' var ' + ($exclusive) + '; var ' + ($exclType) + ' = typeof ' + ($schemaValueExcl) + '; if (' + ($exclType) + ' != \'boolean\' && ' + ($exclType) + ' != \'undefined\' && ' + ($exclType) + ' != \'number\') { '; + var $errorKeyword = $exclusiveKeyword; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ($errorKeyword || '_exclusiveLimit') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; + if (it.opts.messages !== false) { + out += ' , message: \'' + ($exclusiveKeyword) + ' should be boolean\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += ' } else if ( '; + if ($isData) { + out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; + } + out += ' ' + ($exclType) + ' == \'number\' ? ( (' + ($exclusive) + ' = ' + ($schemaValue) + ' === undefined || ' + ($schemaValueExcl) + ' ' + ($op) + '= ' + ($schemaValue) + ') ? ' + ($data) + ' ' + ($notOp) + '= ' + ($schemaValueExcl) + ' : ' + ($data) + ' ' + ($notOp) + ' ' + ($schemaValue) + ' ) : ( (' + ($exclusive) + ' = ' + ($schemaValueExcl) + ' === true) ? ' + ($data) + ' ' + ($notOp) + '= ' + ($schemaValue) + ' : ' + ($data) + ' ' + ($notOp) + ' ' + ($schemaValue) + ' ) || ' + ($data) + ' !== ' + ($data) + ') { var op' + ($lvl) + ' = ' + ($exclusive) + ' ? \'' + ($op) + '\' : \'' + ($op) + '=\'; '; + if ($schema === undefined) { + $errorKeyword = $exclusiveKeyword; + $errSchemaPath = it.errSchemaPath + '/' + $exclusiveKeyword; + $schemaValue = $schemaValueExcl; + $isData = $isDataExcl; + } + } else { + var $exclIsNumber = typeof $schemaExcl == 'number', + $opStr = $op; + if ($exclIsNumber && $isData) { + var $opExpr = '\'' + $opStr + '\''; + out += ' if ( '; + if ($isData) { + out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; + } + out += ' ( ' + ($schemaValue) + ' === undefined || ' + ($schemaExcl) + ' ' + ($op) + '= ' + ($schemaValue) + ' ? ' + ($data) + ' ' + ($notOp) + '= ' + ($schemaExcl) + ' : ' + ($data) + ' ' + ($notOp) + ' ' + ($schemaValue) + ' ) || ' + ($data) + ' !== ' + ($data) + ') { '; + } else { + if ($exclIsNumber && $schema === undefined) { + $exclusive = true; + $errorKeyword = $exclusiveKeyword; + $errSchemaPath = it.errSchemaPath + '/' + $exclusiveKeyword; + $schemaValue = $schemaExcl; + $notOp += '='; + } else { + if ($exclIsNumber) $schemaValue = Math[$isMax ? 'min' : 'max']($schemaExcl, $schema); + if ($schemaExcl === ($exclIsNumber ? $schemaValue : true)) { + $exclusive = true; + $errorKeyword = $exclusiveKeyword; + $errSchemaPath = it.errSchemaPath + '/' + $exclusiveKeyword; + $notOp += '='; + } else { + $exclusive = false; + $opStr += '='; + } + } + var $opExpr = '\'' + $opStr + '\''; + out += ' if ( '; + if ($isData) { + out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; + } + out += ' ' + ($data) + ' ' + ($notOp) + ' ' + ($schemaValue) + ' || ' + ($data) + ' !== ' + ($data) + ') { '; + } + } + $errorKeyword = $errorKeyword || $keyword; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ($errorKeyword || '_limit') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { comparison: ' + ($opExpr) + ', limit: ' + ($schemaValue) + ', exclusive: ' + ($exclusive) + ' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should be ' + ($opStr) + ' '; + if ($isData) { + out += '\' + ' + ($schemaValue); + } else { + out += '' + ($schemaValue) + '\''; + } + } + if (it.opts.verbose) { + out += ' , schema: '; + if ($isData) { + out += 'validate.schema' + ($schemaPath); + } else { + out += '' + ($schema); + } + out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += ' } '; + if ($breakOnError) { + out += ' else { '; + } + return out; +} + + +/***/ }), + +/***/ 2407: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate__limitItems(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $errorKeyword; + var $data = 'data' + ($dataLvl || ''); + var $isData = it.opts.$data && $schema && $schema.$data, + $schemaValue; + if ($isData) { + out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; + $schemaValue = 'schema' + $lvl; + } else { + $schemaValue = $schema; + } + if (!($isData || typeof $schema == 'number')) { + throw new Error($keyword + ' must be number'); + } + var $op = $keyword == 'maxItems' ? '>' : '<'; + out += 'if ( '; + if ($isData) { + out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; + } + out += ' ' + ($data) + '.length ' + ($op) + ' ' + ($schemaValue) + ') { '; + var $errorKeyword = $keyword; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ($errorKeyword || '_limitItems') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { limit: ' + ($schemaValue) + ' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should NOT have '; + if ($keyword == 'maxItems') { + out += 'more'; + } else { + out += 'fewer'; + } + out += ' than '; + if ($isData) { + out += '\' + ' + ($schemaValue) + ' + \''; + } else { + out += '' + ($schema); + } + out += ' items\' '; + } + if (it.opts.verbose) { + out += ' , schema: '; + if ($isData) { + out += 'validate.schema' + ($schemaPath); + } else { + out += '' + ($schema); + } + out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += '} '; + if ($breakOnError) { + out += ' else { '; + } + return out; +} + + +/***/ }), + +/***/ 1250: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate__limitLength(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $errorKeyword; + var $data = 'data' + ($dataLvl || ''); + var $isData = it.opts.$data && $schema && $schema.$data, + $schemaValue; + if ($isData) { + out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; + $schemaValue = 'schema' + $lvl; + } else { + $schemaValue = $schema; + } + if (!($isData || typeof $schema == 'number')) { + throw new Error($keyword + ' must be number'); + } + var $op = $keyword == 'maxLength' ? '>' : '<'; + out += 'if ( '; + if ($isData) { + out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; + } + if (it.opts.unicode === false) { + out += ' ' + ($data) + '.length '; + } else { + out += ' ucs2length(' + ($data) + ') '; + } + out += ' ' + ($op) + ' ' + ($schemaValue) + ') { '; + var $errorKeyword = $keyword; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ($errorKeyword || '_limitLength') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { limit: ' + ($schemaValue) + ' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should NOT be '; + if ($keyword == 'maxLength') { + out += 'longer'; + } else { + out += 'shorter'; + } + out += ' than '; + if ($isData) { + out += '\' + ' + ($schemaValue) + ' + \''; + } else { + out += '' + ($schema); + } + out += ' characters\' '; + } + if (it.opts.verbose) { + out += ' , schema: '; + if ($isData) { + out += 'validate.schema' + ($schemaPath); + } else { + out += '' + ($schema); + } + out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += '} '; + if ($breakOnError) { + out += ' else { '; + } + return out; +} + + +/***/ }), + +/***/ 2596: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate__limitProperties(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $errorKeyword; + var $data = 'data' + ($dataLvl || ''); + var $isData = it.opts.$data && $schema && $schema.$data, + $schemaValue; + if ($isData) { + out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; + $schemaValue = 'schema' + $lvl; + } else { + $schemaValue = $schema; + } + if (!($isData || typeof $schema == 'number')) { + throw new Error($keyword + ' must be number'); + } + var $op = $keyword == 'maxProperties' ? '>' : '<'; + out += 'if ( '; + if ($isData) { + out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || '; + } + out += ' Object.keys(' + ($data) + ').length ' + ($op) + ' ' + ($schemaValue) + ') { '; + var $errorKeyword = $keyword; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ($errorKeyword || '_limitProperties') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { limit: ' + ($schemaValue) + ' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should NOT have '; + if ($keyword == 'maxProperties') { + out += 'more'; + } else { + out += 'fewer'; + } + out += ' than '; + if ($isData) { + out += '\' + ' + ($schemaValue) + ' + \''; + } else { + out += '' + ($schema); + } + out += ' properties\' '; + } + if (it.opts.verbose) { + out += ' , schema: '; + if ($isData) { + out += 'validate.schema' + ($schemaPath); + } else { + out += '' + ($schema); + } + out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += '} '; + if ($breakOnError) { + out += ' else { '; + } + return out; +} + + +/***/ }), + +/***/ 9486: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_allOf(it, $keyword, $ruleType) { + var out = ' '; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $it = it.util.copy(it); + var $closingBraces = ''; + $it.level++; + var $nextValid = 'valid' + $it.level; + var $currentBaseId = $it.baseId, + $allSchemasEmpty = true; + var arr1 = $schema; + if (arr1) { + var $sch, $i = -1, + l1 = arr1.length - 1; + while ($i < l1) { + $sch = arr1[$i += 1]; + if ((it.opts.strictKeywords ? (typeof $sch == 'object' && Object.keys($sch).length > 0) || $sch === false : it.util.schemaHasRules($sch, it.RULES.all))) { + $allSchemasEmpty = false; + $it.schema = $sch; + $it.schemaPath = $schemaPath + '[' + $i + ']'; + $it.errSchemaPath = $errSchemaPath + '/' + $i; + out += ' ' + (it.validate($it)) + ' '; + $it.baseId = $currentBaseId; + if ($breakOnError) { + out += ' if (' + ($nextValid) + ') { '; + $closingBraces += '}'; + } + } + } + } + if ($breakOnError) { + if ($allSchemasEmpty) { + out += ' if (true) { '; + } else { + out += ' ' + ($closingBraces.slice(0, -1)) + ' '; + } + } + return out; +} + + +/***/ }), + +/***/ 5347: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_anyOf(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $data = 'data' + ($dataLvl || ''); + var $valid = 'valid' + $lvl; + var $errs = 'errs__' + $lvl; + var $it = it.util.copy(it); + var $closingBraces = ''; + $it.level++; + var $nextValid = 'valid' + $it.level; + var $noEmptySchema = $schema.every(function($sch) { + return (it.opts.strictKeywords ? (typeof $sch == 'object' && Object.keys($sch).length > 0) || $sch === false : it.util.schemaHasRules($sch, it.RULES.all)); + }); + if ($noEmptySchema) { + var $currentBaseId = $it.baseId; + out += ' var ' + ($errs) + ' = errors; var ' + ($valid) + ' = false; '; + var $wasComposite = it.compositeRule; + it.compositeRule = $it.compositeRule = true; + var arr1 = $schema; + if (arr1) { + var $sch, $i = -1, + l1 = arr1.length - 1; + while ($i < l1) { + $sch = arr1[$i += 1]; + $it.schema = $sch; + $it.schemaPath = $schemaPath + '[' + $i + ']'; + $it.errSchemaPath = $errSchemaPath + '/' + $i; + out += ' ' + (it.validate($it)) + ' '; + $it.baseId = $currentBaseId; + out += ' ' + ($valid) + ' = ' + ($valid) + ' || ' + ($nextValid) + '; if (!' + ($valid) + ') { '; + $closingBraces += '}'; + } + } + it.compositeRule = $it.compositeRule = $wasComposite; + out += ' ' + ($closingBraces) + ' if (!' + ($valid) + ') { var err = '; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('anyOf') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; + if (it.opts.messages !== false) { + out += ' , message: \'should match some schema in anyOf\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError(vErrors); '; + } else { + out += ' validate.errors = vErrors; return false; '; + } + } + out += ' } else { errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; } '; + if (it.opts.allErrors) { + out += ' } '; + } + } else { + if ($breakOnError) { + out += ' if (true) { '; + } + } + return out; +} + + +/***/ }), + +/***/ 923: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_comment(it, $keyword, $ruleType) { + var out = ' '; + var $schema = it.schema[$keyword]; + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $comment = it.util.toQuotedString($schema); + if (it.opts.$comment === true) { + out += ' console.log(' + ($comment) + ');'; + } else if (typeof it.opts.$comment == 'function') { + out += ' self._opts.$comment(' + ($comment) + ', ' + (it.util.toQuotedString($errSchemaPath)) + ', validate.root.schema);'; + } + return out; +} + + +/***/ }), + +/***/ 2617: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_const(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $data = 'data' + ($dataLvl || ''); + var $valid = 'valid' + $lvl; + var $isData = it.opts.$data && $schema && $schema.$data, + $schemaValue; + if ($isData) { + out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; + $schemaValue = 'schema' + $lvl; + } else { + $schemaValue = $schema; + } + if (!$isData) { + out += ' var schema' + ($lvl) + ' = validate.schema' + ($schemaPath) + ';'; + } + out += 'var ' + ($valid) + ' = equal(' + ($data) + ', schema' + ($lvl) + '); if (!' + ($valid) + ') { '; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('const') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { allowedValue: schema' + ($lvl) + ' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should be equal to constant\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += ' }'; + if ($breakOnError) { + out += ' else { '; + } + return out; +} + + +/***/ }), + +/***/ 2119: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_contains(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $data = 'data' + ($dataLvl || ''); + var $valid = 'valid' + $lvl; + var $errs = 'errs__' + $lvl; + var $it = it.util.copy(it); + var $closingBraces = ''; + $it.level++; + var $nextValid = 'valid' + $it.level; + var $idx = 'i' + $lvl, + $dataNxt = $it.dataLevel = it.dataLevel + 1, + $nextData = 'data' + $dataNxt, + $currentBaseId = it.baseId, + $nonEmptySchema = (it.opts.strictKeywords ? (typeof $schema == 'object' && Object.keys($schema).length > 0) || $schema === false : it.util.schemaHasRules($schema, it.RULES.all)); + out += 'var ' + ($errs) + ' = errors;var ' + ($valid) + ';'; + if ($nonEmptySchema) { + var $wasComposite = it.compositeRule; + it.compositeRule = $it.compositeRule = true; + $it.schema = $schema; + $it.schemaPath = $schemaPath; + $it.errSchemaPath = $errSchemaPath; + out += ' var ' + ($nextValid) + ' = false; for (var ' + ($idx) + ' = 0; ' + ($idx) + ' < ' + ($data) + '.length; ' + ($idx) + '++) { '; + $it.errorPath = it.util.getPathExpr(it.errorPath, $idx, it.opts.jsonPointers, true); + var $passData = $data + '[' + $idx + ']'; + $it.dataPathArr[$dataNxt] = $idx; + var $code = it.validate($it); + $it.baseId = $currentBaseId; + if (it.util.varOccurences($code, $nextData) < 2) { + out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; + } else { + out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; + } + out += ' if (' + ($nextValid) + ') break; } '; + it.compositeRule = $it.compositeRule = $wasComposite; + out += ' ' + ($closingBraces) + ' if (!' + ($nextValid) + ') {'; + } else { + out += ' if (' + ($data) + '.length == 0) {'; + } + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('contains') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; + if (it.opts.messages !== false) { + out += ' , message: \'should contain a valid item\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += ' } else { '; + if ($nonEmptySchema) { + out += ' errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; } '; + } + if (it.opts.allErrors) { + out += ' } '; + } + return out; +} + + +/***/ }), + +/***/ 1793: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_custom(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $errorKeyword; + var $data = 'data' + ($dataLvl || ''); + var $valid = 'valid' + $lvl; + var $errs = 'errs__' + $lvl; + var $isData = it.opts.$data && $schema && $schema.$data, + $schemaValue; + if ($isData) { + out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; + $schemaValue = 'schema' + $lvl; + } else { + $schemaValue = $schema; + } + var $rule = this, + $definition = 'definition' + $lvl, + $rDef = $rule.definition, + $closingBraces = ''; + var $compile, $inline, $macro, $ruleValidate, $validateCode; + if ($isData && $rDef.$data) { + $validateCode = 'keywordValidate' + $lvl; + var $validateSchema = $rDef.validateSchema; + out += ' var ' + ($definition) + ' = RULES.custom[\'' + ($keyword) + '\'].definition; var ' + ($validateCode) + ' = ' + ($definition) + '.validate;'; + } else { + $ruleValidate = it.useCustomRule($rule, $schema, it.schema, it); + if (!$ruleValidate) return; + $schemaValue = 'validate.schema' + $schemaPath; + $validateCode = $ruleValidate.code; + $compile = $rDef.compile; + $inline = $rDef.inline; + $macro = $rDef.macro; + } + var $ruleErrs = $validateCode + '.errors', + $i = 'i' + $lvl, + $ruleErr = 'ruleErr' + $lvl, + $asyncKeyword = $rDef.async; + if ($asyncKeyword && !it.async) throw new Error('async keyword in sync schema'); + if (!($inline || $macro)) { + out += '' + ($ruleErrs) + ' = null;'; + } + out += 'var ' + ($errs) + ' = errors;var ' + ($valid) + ';'; + if ($isData && $rDef.$data) { + $closingBraces += '}'; + out += ' if (' + ($schemaValue) + ' === undefined) { ' + ($valid) + ' = true; } else { '; + if ($validateSchema) { + $closingBraces += '}'; + out += ' ' + ($valid) + ' = ' + ($definition) + '.validateSchema(' + ($schemaValue) + '); if (' + ($valid) + ') { '; + } + } + if ($inline) { + if ($rDef.statements) { + out += ' ' + ($ruleValidate.validate) + ' '; + } else { + out += ' ' + ($valid) + ' = ' + ($ruleValidate.validate) + '; '; + } + } else if ($macro) { + var $it = it.util.copy(it); + var $closingBraces = ''; + $it.level++; + var $nextValid = 'valid' + $it.level; + $it.schema = $ruleValidate.validate; + $it.schemaPath = ''; + var $wasComposite = it.compositeRule; + it.compositeRule = $it.compositeRule = true; + var $code = it.validate($it).replace(/validate\.schema/g, $validateCode); + it.compositeRule = $it.compositeRule = $wasComposite; + out += ' ' + ($code); + } else { + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; + out += ' ' + ($validateCode) + '.call( '; + if (it.opts.passContext) { + out += 'this'; + } else { + out += 'self'; + } + if ($compile || $rDef.schema === false) { + out += ' , ' + ($data) + ' '; + } else { + out += ' , ' + ($schemaValue) + ' , ' + ($data) + ' , validate.schema' + (it.schemaPath) + ' '; + } + out += ' , (dataPath || \'\')'; + if (it.errorPath != '""') { + out += ' + ' + (it.errorPath); + } + var $parentData = $dataLvl ? 'data' + (($dataLvl - 1) || '') : 'parentData', + $parentDataProperty = $dataLvl ? it.dataPathArr[$dataLvl] : 'parentDataProperty'; + out += ' , ' + ($parentData) + ' , ' + ($parentDataProperty) + ' , rootData ) '; + var def_callRuleValidate = out; + out = $$outStack.pop(); + if ($rDef.errors === false) { + out += ' ' + ($valid) + ' = '; + if ($asyncKeyword) { + out += 'await '; + } + out += '' + (def_callRuleValidate) + '; '; + } else { + if ($asyncKeyword) { + $ruleErrs = 'customErrors' + $lvl; + out += ' var ' + ($ruleErrs) + ' = null; try { ' + ($valid) + ' = await ' + (def_callRuleValidate) + '; } catch (e) { ' + ($valid) + ' = false; if (e instanceof ValidationError) ' + ($ruleErrs) + ' = e.errors; else throw e; } '; + } else { + out += ' ' + ($ruleErrs) + ' = null; ' + ($valid) + ' = ' + (def_callRuleValidate) + '; '; + } + } + } + if ($rDef.modifying) { + out += ' if (' + ($parentData) + ') ' + ($data) + ' = ' + ($parentData) + '[' + ($parentDataProperty) + '];'; + } + out += '' + ($closingBraces); + if ($rDef.valid) { + if ($breakOnError) { + out += ' if (true) { '; + } + } else { + out += ' if ( '; + if ($rDef.valid === undefined) { + out += ' !'; + if ($macro) { + out += '' + ($nextValid); + } else { + out += '' + ($valid); + } + } else { + out += ' ' + (!$rDef.valid) + ' '; + } + out += ') { '; + $errorKeyword = $rule.keyword; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ($errorKeyword || 'custom') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { keyword: \'' + ($rule.keyword) + '\' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should pass "' + ($rule.keyword) + '" keyword validation\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + var def_customError = out; + out = $$outStack.pop(); + if ($inline) { + if ($rDef.errors) { + if ($rDef.errors != 'full') { + out += ' for (var ' + ($i) + '=' + ($errs) + '; ' + ($i) + ' 0) || $sch === false : it.util.schemaHasRules($sch, it.RULES.all))) { + out += ' ' + ($nextValid) + ' = true; if ( ' + ($data) + (it.util.getProperty($property)) + ' !== undefined '; + if ($ownProperties) { + out += ' && Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($property)) + '\') '; + } + out += ') { '; + $it.schema = $sch; + $it.schemaPath = $schemaPath + it.util.getProperty($property); + $it.errSchemaPath = $errSchemaPath + '/' + it.util.escapeFragment($property); + out += ' ' + (it.validate($it)) + ' '; + $it.baseId = $currentBaseId; + out += ' } '; + if ($breakOnError) { + out += ' if (' + ($nextValid) + ') { '; + $closingBraces += '}'; + } + } + } + if ($breakOnError) { + out += ' ' + ($closingBraces) + ' if (' + ($errs) + ' == errors) {'; + } + return out; +} + + +/***/ }), + +/***/ 9317: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_enum(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $data = 'data' + ($dataLvl || ''); + var $valid = 'valid' + $lvl; + var $isData = it.opts.$data && $schema && $schema.$data, + $schemaValue; + if ($isData) { + out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; + $schemaValue = 'schema' + $lvl; + } else { + $schemaValue = $schema; + } + var $i = 'i' + $lvl, + $vSchema = 'schema' + $lvl; + if (!$isData) { + out += ' var ' + ($vSchema) + ' = validate.schema' + ($schemaPath) + ';'; + } + out += 'var ' + ($valid) + ';'; + if ($isData) { + out += ' if (schema' + ($lvl) + ' === undefined) ' + ($valid) + ' = true; else if (!Array.isArray(schema' + ($lvl) + ')) ' + ($valid) + ' = false; else {'; + } + out += '' + ($valid) + ' = false;for (var ' + ($i) + '=0; ' + ($i) + '<' + ($vSchema) + '.length; ' + ($i) + '++) if (equal(' + ($data) + ', ' + ($vSchema) + '[' + ($i) + '])) { ' + ($valid) + ' = true; break; }'; + if ($isData) { + out += ' } '; + } + out += ' if (!' + ($valid) + ') { '; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('enum') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { allowedValues: schema' + ($lvl) + ' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should be equal to one of the allowed values\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += ' }'; + if ($breakOnError) { + out += ' else { '; + } + return out; +} + + +/***/ }), + +/***/ 8327: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_format(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $data = 'data' + ($dataLvl || ''); + if (it.opts.format === false) { + if ($breakOnError) { + out += ' if (true) { '; + } + return out; + } + var $isData = it.opts.$data && $schema && $schema.$data, + $schemaValue; + if ($isData) { + out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; + $schemaValue = 'schema' + $lvl; + } else { + $schemaValue = $schema; + } + var $unknownFormats = it.opts.unknownFormats, + $allowUnknown = Array.isArray($unknownFormats); + if ($isData) { + var $format = 'format' + $lvl, + $isObject = 'isObject' + $lvl, + $formatType = 'formatType' + $lvl; + out += ' var ' + ($format) + ' = formats[' + ($schemaValue) + ']; var ' + ($isObject) + ' = typeof ' + ($format) + ' == \'object\' && !(' + ($format) + ' instanceof RegExp) && ' + ($format) + '.validate; var ' + ($formatType) + ' = ' + ($isObject) + ' && ' + ($format) + '.type || \'string\'; if (' + ($isObject) + ') { '; + if (it.async) { + out += ' var async' + ($lvl) + ' = ' + ($format) + '.async; '; + } + out += ' ' + ($format) + ' = ' + ($format) + '.validate; } if ( '; + if ($isData) { + out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'string\') || '; + } + out += ' ('; + if ($unknownFormats != 'ignore') { + out += ' (' + ($schemaValue) + ' && !' + ($format) + ' '; + if ($allowUnknown) { + out += ' && self._opts.unknownFormats.indexOf(' + ($schemaValue) + ') == -1 '; + } + out += ') || '; + } + out += ' (' + ($format) + ' && ' + ($formatType) + ' == \'' + ($ruleType) + '\' && !(typeof ' + ($format) + ' == \'function\' ? '; + if (it.async) { + out += ' (async' + ($lvl) + ' ? await ' + ($format) + '(' + ($data) + ') : ' + ($format) + '(' + ($data) + ')) '; + } else { + out += ' ' + ($format) + '(' + ($data) + ') '; + } + out += ' : ' + ($format) + '.test(' + ($data) + '))))) {'; + } else { + var $format = it.formats[$schema]; + if (!$format) { + if ($unknownFormats == 'ignore') { + it.logger.warn('unknown format "' + $schema + '" ignored in schema at path "' + it.errSchemaPath + '"'); + if ($breakOnError) { + out += ' if (true) { '; + } + return out; + } else if ($allowUnknown && $unknownFormats.indexOf($schema) >= 0) { + if ($breakOnError) { + out += ' if (true) { '; + } + return out; + } else { + throw new Error('unknown format "' + $schema + '" is used in schema at path "' + it.errSchemaPath + '"'); + } + } + var $isObject = typeof $format == 'object' && !($format instanceof RegExp) && $format.validate; + var $formatType = $isObject && $format.type || 'string'; + if ($isObject) { + var $async = $format.async === true; + $format = $format.validate; + } + if ($formatType != $ruleType) { + if ($breakOnError) { + out += ' if (true) { '; + } + return out; + } + if ($async) { + if (!it.async) throw new Error('async format in sync schema'); + var $formatRef = 'formats' + it.util.getProperty($schema) + '.validate'; + out += ' if (!(await ' + ($formatRef) + '(' + ($data) + '))) { '; + } else { + out += ' if (! '; + var $formatRef = 'formats' + it.util.getProperty($schema); + if ($isObject) $formatRef += '.validate'; + if (typeof $format == 'function') { + out += ' ' + ($formatRef) + '(' + ($data) + ') '; + } else { + out += ' ' + ($formatRef) + '.test(' + ($data) + ') '; + } + out += ') { '; + } + } + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('format') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { format: '; + if ($isData) { + out += '' + ($schemaValue); + } else { + out += '' + (it.util.toQuotedString($schema)); + } + out += ' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should match format "'; + if ($isData) { + out += '\' + ' + ($schemaValue) + ' + \''; + } else { + out += '' + (it.util.escapeQuotes($schema)); + } + out += '"\' '; + } + if (it.opts.verbose) { + out += ' , schema: '; + if ($isData) { + out += 'validate.schema' + ($schemaPath); + } else { + out += '' + (it.util.toQuotedString($schema)); + } + out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += ' } '; + if ($breakOnError) { + out += ' else { '; + } + return out; +} + + +/***/ }), + +/***/ 5926: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_if(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $data = 'data' + ($dataLvl || ''); + var $valid = 'valid' + $lvl; + var $errs = 'errs__' + $lvl; + var $it = it.util.copy(it); + $it.level++; + var $nextValid = 'valid' + $it.level; + var $thenSch = it.schema['then'], + $elseSch = it.schema['else'], + $thenPresent = $thenSch !== undefined && (it.opts.strictKeywords ? (typeof $thenSch == 'object' && Object.keys($thenSch).length > 0) || $thenSch === false : it.util.schemaHasRules($thenSch, it.RULES.all)), + $elsePresent = $elseSch !== undefined && (it.opts.strictKeywords ? (typeof $elseSch == 'object' && Object.keys($elseSch).length > 0) || $elseSch === false : it.util.schemaHasRules($elseSch, it.RULES.all)), + $currentBaseId = $it.baseId; + if ($thenPresent || $elsePresent) { + var $ifClause; + $it.createErrors = false; + $it.schema = $schema; + $it.schemaPath = $schemaPath; + $it.errSchemaPath = $errSchemaPath; + out += ' var ' + ($errs) + ' = errors; var ' + ($valid) + ' = true; '; + var $wasComposite = it.compositeRule; + it.compositeRule = $it.compositeRule = true; + out += ' ' + (it.validate($it)) + ' '; + $it.baseId = $currentBaseId; + $it.createErrors = true; + out += ' errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; } '; + it.compositeRule = $it.compositeRule = $wasComposite; + if ($thenPresent) { + out += ' if (' + ($nextValid) + ') { '; + $it.schema = it.schema['then']; + $it.schemaPath = it.schemaPath + '.then'; + $it.errSchemaPath = it.errSchemaPath + '/then'; + out += ' ' + (it.validate($it)) + ' '; + $it.baseId = $currentBaseId; + out += ' ' + ($valid) + ' = ' + ($nextValid) + '; '; + if ($thenPresent && $elsePresent) { + $ifClause = 'ifClause' + $lvl; + out += ' var ' + ($ifClause) + ' = \'then\'; '; + } else { + $ifClause = '\'then\''; + } + out += ' } '; + if ($elsePresent) { + out += ' else { '; + } + } else { + out += ' if (!' + ($nextValid) + ') { '; + } + if ($elsePresent) { + $it.schema = it.schema['else']; + $it.schemaPath = it.schemaPath + '.else'; + $it.errSchemaPath = it.errSchemaPath + '/else'; + out += ' ' + (it.validate($it)) + ' '; + $it.baseId = $currentBaseId; + out += ' ' + ($valid) + ' = ' + ($nextValid) + '; '; + if ($thenPresent && $elsePresent) { + $ifClause = 'ifClause' + $lvl; + out += ' var ' + ($ifClause) + ' = \'else\'; '; + } else { + $ifClause = '\'else\''; + } + out += ' } '; + } + out += ' if (!' + ($valid) + ') { var err = '; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('if') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { failingKeyword: ' + ($ifClause) + ' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should match "\' + ' + ($ifClause) + ' + \'" schema\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError(vErrors); '; + } else { + out += ' validate.errors = vErrors; return false; '; + } + } + out += ' } '; + if ($breakOnError) { + out += ' else { '; + } + } else { + if ($breakOnError) { + out += ' if (true) { '; + } + } + return out; +} + + +/***/ }), + +/***/ 9646: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +"use strict"; + + +//all requires must be explicit because browserify won't work with dynamic requires +module.exports = { + '$ref': __webpack_require__(2331), + allOf: __webpack_require__(9486), + anyOf: __webpack_require__(5347), + '$comment': __webpack_require__(923), + const: __webpack_require__(2617), + contains: __webpack_require__(2119), + dependencies: __webpack_require__(9115), + 'enum': __webpack_require__(9317), + format: __webpack_require__(8327), + 'if': __webpack_require__(5926), + items: __webpack_require__(392), + maximum: __webpack_require__(1796), + minimum: __webpack_require__(1796), + maxItems: __webpack_require__(2407), + minItems: __webpack_require__(2407), + maxLength: __webpack_require__(1250), + minLength: __webpack_require__(1250), + maxProperties: __webpack_require__(2596), + minProperties: __webpack_require__(2596), + multipleOf: __webpack_require__(6039), + not: __webpack_require__(7946), + oneOf: __webpack_require__(9344), + pattern: __webpack_require__(9737), + properties: __webpack_require__(2537), + propertyNames: __webpack_require__(2127), + required: __webpack_require__(1204), + uniqueItems: __webpack_require__(1985), + validate: __webpack_require__(1869) +}; + + +/***/ }), + +/***/ 392: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_items(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $data = 'data' + ($dataLvl || ''); + var $valid = 'valid' + $lvl; + var $errs = 'errs__' + $lvl; + var $it = it.util.copy(it); + var $closingBraces = ''; + $it.level++; + var $nextValid = 'valid' + $it.level; + var $idx = 'i' + $lvl, + $dataNxt = $it.dataLevel = it.dataLevel + 1, + $nextData = 'data' + $dataNxt, + $currentBaseId = it.baseId; + out += 'var ' + ($errs) + ' = errors;var ' + ($valid) + ';'; + if (Array.isArray($schema)) { + var $additionalItems = it.schema.additionalItems; + if ($additionalItems === false) { + out += ' ' + ($valid) + ' = ' + ($data) + '.length <= ' + ($schema.length) + '; '; + var $currErrSchemaPath = $errSchemaPath; + $errSchemaPath = it.errSchemaPath + '/additionalItems'; + out += ' if (!' + ($valid) + ') { '; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('additionalItems') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { limit: ' + ($schema.length) + ' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should NOT have more than ' + ($schema.length) + ' items\' '; + } + if (it.opts.verbose) { + out += ' , schema: false , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += ' } '; + $errSchemaPath = $currErrSchemaPath; + if ($breakOnError) { + $closingBraces += '}'; + out += ' else { '; + } + } + var arr1 = $schema; + if (arr1) { + var $sch, $i = -1, + l1 = arr1.length - 1; + while ($i < l1) { + $sch = arr1[$i += 1]; + if ((it.opts.strictKeywords ? (typeof $sch == 'object' && Object.keys($sch).length > 0) || $sch === false : it.util.schemaHasRules($sch, it.RULES.all))) { + out += ' ' + ($nextValid) + ' = true; if (' + ($data) + '.length > ' + ($i) + ') { '; + var $passData = $data + '[' + $i + ']'; + $it.schema = $sch; + $it.schemaPath = $schemaPath + '[' + $i + ']'; + $it.errSchemaPath = $errSchemaPath + '/' + $i; + $it.errorPath = it.util.getPathExpr(it.errorPath, $i, it.opts.jsonPointers, true); + $it.dataPathArr[$dataNxt] = $i; + var $code = it.validate($it); + $it.baseId = $currentBaseId; + if (it.util.varOccurences($code, $nextData) < 2) { + out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; + } else { + out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; + } + out += ' } '; + if ($breakOnError) { + out += ' if (' + ($nextValid) + ') { '; + $closingBraces += '}'; + } + } + } + } + if (typeof $additionalItems == 'object' && (it.opts.strictKeywords ? (typeof $additionalItems == 'object' && Object.keys($additionalItems).length > 0) || $additionalItems === false : it.util.schemaHasRules($additionalItems, it.RULES.all))) { + $it.schema = $additionalItems; + $it.schemaPath = it.schemaPath + '.additionalItems'; + $it.errSchemaPath = it.errSchemaPath + '/additionalItems'; + out += ' ' + ($nextValid) + ' = true; if (' + ($data) + '.length > ' + ($schema.length) + ') { for (var ' + ($idx) + ' = ' + ($schema.length) + '; ' + ($idx) + ' < ' + ($data) + '.length; ' + ($idx) + '++) { '; + $it.errorPath = it.util.getPathExpr(it.errorPath, $idx, it.opts.jsonPointers, true); + var $passData = $data + '[' + $idx + ']'; + $it.dataPathArr[$dataNxt] = $idx; + var $code = it.validate($it); + $it.baseId = $currentBaseId; + if (it.util.varOccurences($code, $nextData) < 2) { + out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; + } else { + out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; + } + if ($breakOnError) { + out += ' if (!' + ($nextValid) + ') break; '; + } + out += ' } } '; + if ($breakOnError) { + out += ' if (' + ($nextValid) + ') { '; + $closingBraces += '}'; + } + } + } else if ((it.opts.strictKeywords ? (typeof $schema == 'object' && Object.keys($schema).length > 0) || $schema === false : it.util.schemaHasRules($schema, it.RULES.all))) { + $it.schema = $schema; + $it.schemaPath = $schemaPath; + $it.errSchemaPath = $errSchemaPath; + out += ' for (var ' + ($idx) + ' = ' + (0) + '; ' + ($idx) + ' < ' + ($data) + '.length; ' + ($idx) + '++) { '; + $it.errorPath = it.util.getPathExpr(it.errorPath, $idx, it.opts.jsonPointers, true); + var $passData = $data + '[' + $idx + ']'; + $it.dataPathArr[$dataNxt] = $idx; + var $code = it.validate($it); + $it.baseId = $currentBaseId; + if (it.util.varOccurences($code, $nextData) < 2) { + out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; + } else { + out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; + } + if ($breakOnError) { + out += ' if (!' + ($nextValid) + ') break; '; + } + out += ' }'; + } + if ($breakOnError) { + out += ' ' + ($closingBraces) + ' if (' + ($errs) + ' == errors) {'; + } + return out; +} + + +/***/ }), + +/***/ 6039: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_multipleOf(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $data = 'data' + ($dataLvl || ''); + var $isData = it.opts.$data && $schema && $schema.$data, + $schemaValue; + if ($isData) { + out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; + $schemaValue = 'schema' + $lvl; + } else { + $schemaValue = $schema; + } + if (!($isData || typeof $schema == 'number')) { + throw new Error($keyword + ' must be number'); + } + out += 'var division' + ($lvl) + ';if ('; + if ($isData) { + out += ' ' + ($schemaValue) + ' !== undefined && ( typeof ' + ($schemaValue) + ' != \'number\' || '; + } + out += ' (division' + ($lvl) + ' = ' + ($data) + ' / ' + ($schemaValue) + ', '; + if (it.opts.multipleOfPrecision) { + out += ' Math.abs(Math.round(division' + ($lvl) + ') - division' + ($lvl) + ') > 1e-' + (it.opts.multipleOfPrecision) + ' '; + } else { + out += ' division' + ($lvl) + ' !== parseInt(division' + ($lvl) + ') '; + } + out += ' ) '; + if ($isData) { + out += ' ) '; + } + out += ' ) { '; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('multipleOf') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { multipleOf: ' + ($schemaValue) + ' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should be multiple of '; + if ($isData) { + out += '\' + ' + ($schemaValue); + } else { + out += '' + ($schemaValue) + '\''; + } + } + if (it.opts.verbose) { + out += ' , schema: '; + if ($isData) { + out += 'validate.schema' + ($schemaPath); + } else { + out += '' + ($schema); + } + out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += '} '; + if ($breakOnError) { + out += ' else { '; + } + return out; +} + + +/***/ }), + +/***/ 7946: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_not(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $data = 'data' + ($dataLvl || ''); + var $errs = 'errs__' + $lvl; + var $it = it.util.copy(it); + $it.level++; + var $nextValid = 'valid' + $it.level; + if ((it.opts.strictKeywords ? (typeof $schema == 'object' && Object.keys($schema).length > 0) || $schema === false : it.util.schemaHasRules($schema, it.RULES.all))) { + $it.schema = $schema; + $it.schemaPath = $schemaPath; + $it.errSchemaPath = $errSchemaPath; + out += ' var ' + ($errs) + ' = errors; '; + var $wasComposite = it.compositeRule; + it.compositeRule = $it.compositeRule = true; + $it.createErrors = false; + var $allErrorsOption; + if ($it.opts.allErrors) { + $allErrorsOption = $it.opts.allErrors; + $it.opts.allErrors = false; + } + out += ' ' + (it.validate($it)) + ' '; + $it.createErrors = true; + if ($allErrorsOption) $it.opts.allErrors = $allErrorsOption; + it.compositeRule = $it.compositeRule = $wasComposite; + out += ' if (' + ($nextValid) + ') { '; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('not') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; + if (it.opts.messages !== false) { + out += ' , message: \'should NOT be valid\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += ' } else { errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; } '; + if (it.opts.allErrors) { + out += ' } '; + } + } else { + out += ' var err = '; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('not') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; + if (it.opts.messages !== false) { + out += ' , message: \'should NOT be valid\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + if ($breakOnError) { + out += ' if (false) { '; + } + } + return out; +} + + +/***/ }), + +/***/ 9344: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_oneOf(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $data = 'data' + ($dataLvl || ''); + var $valid = 'valid' + $lvl; + var $errs = 'errs__' + $lvl; + var $it = it.util.copy(it); + var $closingBraces = ''; + $it.level++; + var $nextValid = 'valid' + $it.level; + var $currentBaseId = $it.baseId, + $prevValid = 'prevValid' + $lvl, + $passingSchemas = 'passingSchemas' + $lvl; + out += 'var ' + ($errs) + ' = errors , ' + ($prevValid) + ' = false , ' + ($valid) + ' = false , ' + ($passingSchemas) + ' = null; '; + var $wasComposite = it.compositeRule; + it.compositeRule = $it.compositeRule = true; + var arr1 = $schema; + if (arr1) { + var $sch, $i = -1, + l1 = arr1.length - 1; + while ($i < l1) { + $sch = arr1[$i += 1]; + if ((it.opts.strictKeywords ? (typeof $sch == 'object' && Object.keys($sch).length > 0) || $sch === false : it.util.schemaHasRules($sch, it.RULES.all))) { + $it.schema = $sch; + $it.schemaPath = $schemaPath + '[' + $i + ']'; + $it.errSchemaPath = $errSchemaPath + '/' + $i; + out += ' ' + (it.validate($it)) + ' '; + $it.baseId = $currentBaseId; + } else { + out += ' var ' + ($nextValid) + ' = true; '; + } + if ($i) { + out += ' if (' + ($nextValid) + ' && ' + ($prevValid) + ') { ' + ($valid) + ' = false; ' + ($passingSchemas) + ' = [' + ($passingSchemas) + ', ' + ($i) + ']; } else { '; + $closingBraces += '}'; + } + out += ' if (' + ($nextValid) + ') { ' + ($valid) + ' = ' + ($prevValid) + ' = true; ' + ($passingSchemas) + ' = ' + ($i) + '; }'; + } + } + it.compositeRule = $it.compositeRule = $wasComposite; + out += '' + ($closingBraces) + 'if (!' + ($valid) + ') { var err = '; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('oneOf') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { passingSchemas: ' + ($passingSchemas) + ' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should match exactly one schema in oneOf\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError(vErrors); '; + } else { + out += ' validate.errors = vErrors; return false; '; + } + } + out += '} else { errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; }'; + if (it.opts.allErrors) { + out += ' } '; + } + return out; +} + + +/***/ }), + +/***/ 9737: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_pattern(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $data = 'data' + ($dataLvl || ''); + var $isData = it.opts.$data && $schema && $schema.$data, + $schemaValue; + if ($isData) { + out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; + $schemaValue = 'schema' + $lvl; + } else { + $schemaValue = $schema; + } + var $regexp = $isData ? '(new RegExp(' + $schemaValue + '))' : it.usePattern($schema); + out += 'if ( '; + if ($isData) { + out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'string\') || '; + } + out += ' !' + ($regexp) + '.test(' + ($data) + ') ) { '; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('pattern') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { pattern: '; + if ($isData) { + out += '' + ($schemaValue); + } else { + out += '' + (it.util.toQuotedString($schema)); + } + out += ' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should match pattern "'; + if ($isData) { + out += '\' + ' + ($schemaValue) + ' + \''; + } else { + out += '' + (it.util.escapeQuotes($schema)); + } + out += '"\' '; + } + if (it.opts.verbose) { + out += ' , schema: '; + if ($isData) { + out += 'validate.schema' + ($schemaPath); + } else { + out += '' + (it.util.toQuotedString($schema)); + } + out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += '} '; + if ($breakOnError) { + out += ' else { '; + } + return out; +} + + +/***/ }), + +/***/ 2537: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_properties(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $data = 'data' + ($dataLvl || ''); + var $errs = 'errs__' + $lvl; + var $it = it.util.copy(it); + var $closingBraces = ''; + $it.level++; + var $nextValid = 'valid' + $it.level; + var $key = 'key' + $lvl, + $idx = 'idx' + $lvl, + $dataNxt = $it.dataLevel = it.dataLevel + 1, + $nextData = 'data' + $dataNxt, + $dataProperties = 'dataProperties' + $lvl; + var $schemaKeys = Object.keys($schema || {}).filter(notProto), + $pProperties = it.schema.patternProperties || {}, + $pPropertyKeys = Object.keys($pProperties).filter(notProto), + $aProperties = it.schema.additionalProperties, + $someProperties = $schemaKeys.length || $pPropertyKeys.length, + $noAdditional = $aProperties === false, + $additionalIsSchema = typeof $aProperties == 'object' && Object.keys($aProperties).length, + $removeAdditional = it.opts.removeAdditional, + $checkAdditional = $noAdditional || $additionalIsSchema || $removeAdditional, + $ownProperties = it.opts.ownProperties, + $currentBaseId = it.baseId; + var $required = it.schema.required; + if ($required && !(it.opts.$data && $required.$data) && $required.length < it.opts.loopRequired) { + var $requiredHash = it.util.toHash($required); + } + + function notProto(p) { + return p !== '__proto__'; + } + out += 'var ' + ($errs) + ' = errors;var ' + ($nextValid) + ' = true;'; + if ($ownProperties) { + out += ' var ' + ($dataProperties) + ' = undefined;'; + } + if ($checkAdditional) { + if ($ownProperties) { + out += ' ' + ($dataProperties) + ' = ' + ($dataProperties) + ' || Object.keys(' + ($data) + '); for (var ' + ($idx) + '=0; ' + ($idx) + '<' + ($dataProperties) + '.length; ' + ($idx) + '++) { var ' + ($key) + ' = ' + ($dataProperties) + '[' + ($idx) + ']; '; + } else { + out += ' for (var ' + ($key) + ' in ' + ($data) + ') { '; + } + if ($someProperties) { + out += ' var isAdditional' + ($lvl) + ' = !(false '; + if ($schemaKeys.length) { + if ($schemaKeys.length > 8) { + out += ' || validate.schema' + ($schemaPath) + '.hasOwnProperty(' + ($key) + ') '; + } else { + var arr1 = $schemaKeys; + if (arr1) { + var $propertyKey, i1 = -1, + l1 = arr1.length - 1; + while (i1 < l1) { + $propertyKey = arr1[i1 += 1]; + out += ' || ' + ($key) + ' == ' + (it.util.toQuotedString($propertyKey)) + ' '; + } + } + } + } + if ($pPropertyKeys.length) { + var arr2 = $pPropertyKeys; + if (arr2) { + var $pProperty, $i = -1, + l2 = arr2.length - 1; + while ($i < l2) { + $pProperty = arr2[$i += 1]; + out += ' || ' + (it.usePattern($pProperty)) + '.test(' + ($key) + ') '; + } + } + } + out += ' ); if (isAdditional' + ($lvl) + ') { '; + } + if ($removeAdditional == 'all') { + out += ' delete ' + ($data) + '[' + ($key) + ']; '; + } else { + var $currentErrorPath = it.errorPath; + var $additionalProperty = '\' + ' + $key + ' + \''; + if (it.opts._errorDataPathProperty) { + it.errorPath = it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers); + } + if ($noAdditional) { + if ($removeAdditional) { + out += ' delete ' + ($data) + '[' + ($key) + ']; '; + } else { + out += ' ' + ($nextValid) + ' = false; '; + var $currErrSchemaPath = $errSchemaPath; + $errSchemaPath = it.errSchemaPath + '/additionalProperties'; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('additionalProperties') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { additionalProperty: \'' + ($additionalProperty) + '\' } '; + if (it.opts.messages !== false) { + out += ' , message: \''; + if (it.opts._errorDataPathProperty) { + out += 'is an invalid additional property'; + } else { + out += 'should NOT have additional properties'; + } + out += '\' '; + } + if (it.opts.verbose) { + out += ' , schema: false , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + $errSchemaPath = $currErrSchemaPath; + if ($breakOnError) { + out += ' break; '; + } + } + } else if ($additionalIsSchema) { + if ($removeAdditional == 'failing') { + out += ' var ' + ($errs) + ' = errors; '; + var $wasComposite = it.compositeRule; + it.compositeRule = $it.compositeRule = true; + $it.schema = $aProperties; + $it.schemaPath = it.schemaPath + '.additionalProperties'; + $it.errSchemaPath = it.errSchemaPath + '/additionalProperties'; + $it.errorPath = it.opts._errorDataPathProperty ? it.errorPath : it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers); + var $passData = $data + '[' + $key + ']'; + $it.dataPathArr[$dataNxt] = $key; + var $code = it.validate($it); + $it.baseId = $currentBaseId; + if (it.util.varOccurences($code, $nextData) < 2) { + out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; + } else { + out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; + } + out += ' if (!' + ($nextValid) + ') { errors = ' + ($errs) + '; if (validate.errors !== null) { if (errors) validate.errors.length = errors; else validate.errors = null; } delete ' + ($data) + '[' + ($key) + ']; } '; + it.compositeRule = $it.compositeRule = $wasComposite; + } else { + $it.schema = $aProperties; + $it.schemaPath = it.schemaPath + '.additionalProperties'; + $it.errSchemaPath = it.errSchemaPath + '/additionalProperties'; + $it.errorPath = it.opts._errorDataPathProperty ? it.errorPath : it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers); + var $passData = $data + '[' + $key + ']'; + $it.dataPathArr[$dataNxt] = $key; + var $code = it.validate($it); + $it.baseId = $currentBaseId; + if (it.util.varOccurences($code, $nextData) < 2) { + out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; + } else { + out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; + } + if ($breakOnError) { + out += ' if (!' + ($nextValid) + ') break; '; + } + } + } + it.errorPath = $currentErrorPath; + } + if ($someProperties) { + out += ' } '; + } + out += ' } '; + if ($breakOnError) { + out += ' if (' + ($nextValid) + ') { '; + $closingBraces += '}'; + } + } + var $useDefaults = it.opts.useDefaults && !it.compositeRule; + if ($schemaKeys.length) { + var arr3 = $schemaKeys; + if (arr3) { + var $propertyKey, i3 = -1, + l3 = arr3.length - 1; + while (i3 < l3) { + $propertyKey = arr3[i3 += 1]; + var $sch = $schema[$propertyKey]; + if ((it.opts.strictKeywords ? (typeof $sch == 'object' && Object.keys($sch).length > 0) || $sch === false : it.util.schemaHasRules($sch, it.RULES.all))) { + var $prop = it.util.getProperty($propertyKey), + $passData = $data + $prop, + $hasDefault = $useDefaults && $sch.default !== undefined; + $it.schema = $sch; + $it.schemaPath = $schemaPath + $prop; + $it.errSchemaPath = $errSchemaPath + '/' + it.util.escapeFragment($propertyKey); + $it.errorPath = it.util.getPath(it.errorPath, $propertyKey, it.opts.jsonPointers); + $it.dataPathArr[$dataNxt] = it.util.toQuotedString($propertyKey); + var $code = it.validate($it); + $it.baseId = $currentBaseId; + if (it.util.varOccurences($code, $nextData) < 2) { + $code = it.util.varReplace($code, $nextData, $passData); + var $useData = $passData; + } else { + var $useData = $nextData; + out += ' var ' + ($nextData) + ' = ' + ($passData) + '; '; + } + if ($hasDefault) { + out += ' ' + ($code) + ' '; + } else { + if ($requiredHash && $requiredHash[$propertyKey]) { + out += ' if ( ' + ($useData) + ' === undefined '; + if ($ownProperties) { + out += ' || ! Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($propertyKey)) + '\') '; + } + out += ') { ' + ($nextValid) + ' = false; '; + var $currentErrorPath = it.errorPath, + $currErrSchemaPath = $errSchemaPath, + $missingProperty = it.util.escapeQuotes($propertyKey); + if (it.opts._errorDataPathProperty) { + it.errorPath = it.util.getPath($currentErrorPath, $propertyKey, it.opts.jsonPointers); + } + $errSchemaPath = it.errSchemaPath + '/required'; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; + if (it.opts.messages !== false) { + out += ' , message: \''; + if (it.opts._errorDataPathProperty) { + out += 'is a required property'; + } else { + out += 'should have required property \\\'' + ($missingProperty) + '\\\''; + } + out += '\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + $errSchemaPath = $currErrSchemaPath; + it.errorPath = $currentErrorPath; + out += ' } else { '; + } else { + if ($breakOnError) { + out += ' if ( ' + ($useData) + ' === undefined '; + if ($ownProperties) { + out += ' || ! Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($propertyKey)) + '\') '; + } + out += ') { ' + ($nextValid) + ' = true; } else { '; + } else { + out += ' if (' + ($useData) + ' !== undefined '; + if ($ownProperties) { + out += ' && Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($propertyKey)) + '\') '; + } + out += ' ) { '; + } + } + out += ' ' + ($code) + ' } '; + } + } + if ($breakOnError) { + out += ' if (' + ($nextValid) + ') { '; + $closingBraces += '}'; + } + } + } + } + if ($pPropertyKeys.length) { + var arr4 = $pPropertyKeys; + if (arr4) { + var $pProperty, i4 = -1, + l4 = arr4.length - 1; + while (i4 < l4) { + $pProperty = arr4[i4 += 1]; + var $sch = $pProperties[$pProperty]; + if ((it.opts.strictKeywords ? (typeof $sch == 'object' && Object.keys($sch).length > 0) || $sch === false : it.util.schemaHasRules($sch, it.RULES.all))) { + $it.schema = $sch; + $it.schemaPath = it.schemaPath + '.patternProperties' + it.util.getProperty($pProperty); + $it.errSchemaPath = it.errSchemaPath + '/patternProperties/' + it.util.escapeFragment($pProperty); + if ($ownProperties) { + out += ' ' + ($dataProperties) + ' = ' + ($dataProperties) + ' || Object.keys(' + ($data) + '); for (var ' + ($idx) + '=0; ' + ($idx) + '<' + ($dataProperties) + '.length; ' + ($idx) + '++) { var ' + ($key) + ' = ' + ($dataProperties) + '[' + ($idx) + ']; '; + } else { + out += ' for (var ' + ($key) + ' in ' + ($data) + ') { '; + } + out += ' if (' + (it.usePattern($pProperty)) + '.test(' + ($key) + ')) { '; + $it.errorPath = it.util.getPathExpr(it.errorPath, $key, it.opts.jsonPointers); + var $passData = $data + '[' + $key + ']'; + $it.dataPathArr[$dataNxt] = $key; + var $code = it.validate($it); + $it.baseId = $currentBaseId; + if (it.util.varOccurences($code, $nextData) < 2) { + out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; + } else { + out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; + } + if ($breakOnError) { + out += ' if (!' + ($nextValid) + ') break; '; + } + out += ' } '; + if ($breakOnError) { + out += ' else ' + ($nextValid) + ' = true; '; + } + out += ' } '; + if ($breakOnError) { + out += ' if (' + ($nextValid) + ') { '; + $closingBraces += '}'; + } + } + } + } + } + if ($breakOnError) { + out += ' ' + ($closingBraces) + ' if (' + ($errs) + ' == errors) {'; + } + return out; +} + + +/***/ }), + +/***/ 2127: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_propertyNames(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $data = 'data' + ($dataLvl || ''); + var $errs = 'errs__' + $lvl; + var $it = it.util.copy(it); + var $closingBraces = ''; + $it.level++; + var $nextValid = 'valid' + $it.level; + out += 'var ' + ($errs) + ' = errors;'; + if ((it.opts.strictKeywords ? (typeof $schema == 'object' && Object.keys($schema).length > 0) || $schema === false : it.util.schemaHasRules($schema, it.RULES.all))) { + $it.schema = $schema; + $it.schemaPath = $schemaPath; + $it.errSchemaPath = $errSchemaPath; + var $key = 'key' + $lvl, + $idx = 'idx' + $lvl, + $i = 'i' + $lvl, + $invalidName = '\' + ' + $key + ' + \'', + $dataNxt = $it.dataLevel = it.dataLevel + 1, + $nextData = 'data' + $dataNxt, + $dataProperties = 'dataProperties' + $lvl, + $ownProperties = it.opts.ownProperties, + $currentBaseId = it.baseId; + if ($ownProperties) { + out += ' var ' + ($dataProperties) + ' = undefined; '; + } + if ($ownProperties) { + out += ' ' + ($dataProperties) + ' = ' + ($dataProperties) + ' || Object.keys(' + ($data) + '); for (var ' + ($idx) + '=0; ' + ($idx) + '<' + ($dataProperties) + '.length; ' + ($idx) + '++) { var ' + ($key) + ' = ' + ($dataProperties) + '[' + ($idx) + ']; '; + } else { + out += ' for (var ' + ($key) + ' in ' + ($data) + ') { '; + } + out += ' var startErrs' + ($lvl) + ' = errors; '; + var $passData = $key; + var $wasComposite = it.compositeRule; + it.compositeRule = $it.compositeRule = true; + var $code = it.validate($it); + $it.baseId = $currentBaseId; + if (it.util.varOccurences($code, $nextData) < 2) { + out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' '; + } else { + out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' '; + } + it.compositeRule = $it.compositeRule = $wasComposite; + out += ' if (!' + ($nextValid) + ') { for (var ' + ($i) + '=startErrs' + ($lvl) + '; ' + ($i) + ' 0) || $propertySch === false : it.util.schemaHasRules($propertySch, it.RULES.all)))) { + $required[$required.length] = $property; + } + } + } + } else { + var $required = $schema; + } + } + if ($isData || $required.length) { + var $currentErrorPath = it.errorPath, + $loopRequired = $isData || $required.length >= it.opts.loopRequired, + $ownProperties = it.opts.ownProperties; + if ($breakOnError) { + out += ' var missing' + ($lvl) + '; '; + if ($loopRequired) { + if (!$isData) { + out += ' var ' + ($vSchema) + ' = validate.schema' + ($schemaPath) + '; '; + } + var $i = 'i' + $lvl, + $propertyPath = 'schema' + $lvl + '[' + $i + ']', + $missingProperty = '\' + ' + $propertyPath + ' + \''; + if (it.opts._errorDataPathProperty) { + it.errorPath = it.util.getPathExpr($currentErrorPath, $propertyPath, it.opts.jsonPointers); + } + out += ' var ' + ($valid) + ' = true; '; + if ($isData) { + out += ' if (schema' + ($lvl) + ' === undefined) ' + ($valid) + ' = true; else if (!Array.isArray(schema' + ($lvl) + ')) ' + ($valid) + ' = false; else {'; + } + out += ' for (var ' + ($i) + ' = 0; ' + ($i) + ' < ' + ($vSchema) + '.length; ' + ($i) + '++) { ' + ($valid) + ' = ' + ($data) + '[' + ($vSchema) + '[' + ($i) + ']] !== undefined '; + if ($ownProperties) { + out += ' && Object.prototype.hasOwnProperty.call(' + ($data) + ', ' + ($vSchema) + '[' + ($i) + ']) '; + } + out += '; if (!' + ($valid) + ') break; } '; + if ($isData) { + out += ' } '; + } + out += ' if (!' + ($valid) + ') { '; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; + if (it.opts.messages !== false) { + out += ' , message: \''; + if (it.opts._errorDataPathProperty) { + out += 'is a required property'; + } else { + out += 'should have required property \\\'' + ($missingProperty) + '\\\''; + } + out += '\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += ' } else { '; + } else { + out += ' if ( '; + var arr2 = $required; + if (arr2) { + var $propertyKey, $i = -1, + l2 = arr2.length - 1; + while ($i < l2) { + $propertyKey = arr2[$i += 1]; + if ($i) { + out += ' || '; + } + var $prop = it.util.getProperty($propertyKey), + $useData = $data + $prop; + out += ' ( ( ' + ($useData) + ' === undefined '; + if ($ownProperties) { + out += ' || ! Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($propertyKey)) + '\') '; + } + out += ') && (missing' + ($lvl) + ' = ' + (it.util.toQuotedString(it.opts.jsonPointers ? $propertyKey : $prop)) + ') ) '; + } + } + out += ') { '; + var $propertyPath = 'missing' + $lvl, + $missingProperty = '\' + ' + $propertyPath + ' + \''; + if (it.opts._errorDataPathProperty) { + it.errorPath = it.opts.jsonPointers ? it.util.getPathExpr($currentErrorPath, $propertyPath, true) : $currentErrorPath + ' + ' + $propertyPath; + } + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; + if (it.opts.messages !== false) { + out += ' , message: \''; + if (it.opts._errorDataPathProperty) { + out += 'is a required property'; + } else { + out += 'should have required property \\\'' + ($missingProperty) + '\\\''; + } + out += '\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += ' } else { '; + } + } else { + if ($loopRequired) { + if (!$isData) { + out += ' var ' + ($vSchema) + ' = validate.schema' + ($schemaPath) + '; '; + } + var $i = 'i' + $lvl, + $propertyPath = 'schema' + $lvl + '[' + $i + ']', + $missingProperty = '\' + ' + $propertyPath + ' + \''; + if (it.opts._errorDataPathProperty) { + it.errorPath = it.util.getPathExpr($currentErrorPath, $propertyPath, it.opts.jsonPointers); + } + if ($isData) { + out += ' if (' + ($vSchema) + ' && !Array.isArray(' + ($vSchema) + ')) { var err = '; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; + if (it.opts.messages !== false) { + out += ' , message: \''; + if (it.opts._errorDataPathProperty) { + out += 'is a required property'; + } else { + out += 'should have required property \\\'' + ($missingProperty) + '\\\''; + } + out += '\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } else if (' + ($vSchema) + ' !== undefined) { '; + } + out += ' for (var ' + ($i) + ' = 0; ' + ($i) + ' < ' + ($vSchema) + '.length; ' + ($i) + '++) { if (' + ($data) + '[' + ($vSchema) + '[' + ($i) + ']] === undefined '; + if ($ownProperties) { + out += ' || ! Object.prototype.hasOwnProperty.call(' + ($data) + ', ' + ($vSchema) + '[' + ($i) + ']) '; + } + out += ') { var err = '; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; + if (it.opts.messages !== false) { + out += ' , message: \''; + if (it.opts._errorDataPathProperty) { + out += 'is a required property'; + } else { + out += 'should have required property \\\'' + ($missingProperty) + '\\\''; + } + out += '\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } } '; + if ($isData) { + out += ' } '; + } + } else { + var arr3 = $required; + if (arr3) { + var $propertyKey, i3 = -1, + l3 = arr3.length - 1; + while (i3 < l3) { + $propertyKey = arr3[i3 += 1]; + var $prop = it.util.getProperty($propertyKey), + $missingProperty = it.util.escapeQuotes($propertyKey), + $useData = $data + $prop; + if (it.opts._errorDataPathProperty) { + it.errorPath = it.util.getPath($currentErrorPath, $propertyKey, it.opts.jsonPointers); + } + out += ' if ( ' + ($useData) + ' === undefined '; + if ($ownProperties) { + out += ' || ! Object.prototype.hasOwnProperty.call(' + ($data) + ', \'' + (it.util.escapeQuotes($propertyKey)) + '\') '; + } + out += ') { var err = '; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('required') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { missingProperty: \'' + ($missingProperty) + '\' } '; + if (it.opts.messages !== false) { + out += ' , message: \''; + if (it.opts._errorDataPathProperty) { + out += 'is a required property'; + } else { + out += 'should have required property \\\'' + ($missingProperty) + '\\\''; + } + out += '\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } '; + } + } + } + } + it.errorPath = $currentErrorPath; + } else if ($breakOnError) { + out += ' if (true) {'; + } + return out; +} + + +/***/ }), + +/***/ 1985: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_uniqueItems(it, $keyword, $ruleType) { + var out = ' '; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $data = 'data' + ($dataLvl || ''); + var $valid = 'valid' + $lvl; + var $isData = it.opts.$data && $schema && $schema.$data, + $schemaValue; + if ($isData) { + out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; '; + $schemaValue = 'schema' + $lvl; + } else { + $schemaValue = $schema; + } + if (($schema || $isData) && it.opts.uniqueItems !== false) { + if ($isData) { + out += ' var ' + ($valid) + '; if (' + ($schemaValue) + ' === false || ' + ($schemaValue) + ' === undefined) ' + ($valid) + ' = true; else if (typeof ' + ($schemaValue) + ' != \'boolean\') ' + ($valid) + ' = false; else { '; + } + out += ' var i = ' + ($data) + '.length , ' + ($valid) + ' = true , j; if (i > 1) { '; + var $itemType = it.schema.items && it.schema.items.type, + $typeIsArray = Array.isArray($itemType); + if (!$itemType || $itemType == 'object' || $itemType == 'array' || ($typeIsArray && ($itemType.indexOf('object') >= 0 || $itemType.indexOf('array') >= 0))) { + out += ' outer: for (;i--;) { for (j = i; j--;) { if (equal(' + ($data) + '[i], ' + ($data) + '[j])) { ' + ($valid) + ' = false; break outer; } } } '; + } else { + out += ' var itemIndices = {}, item; for (;i--;) { var item = ' + ($data) + '[i]; '; + var $method = 'checkDataType' + ($typeIsArray ? 's' : ''); + out += ' if (' + (it.util[$method]($itemType, 'item', it.opts.strictNumbers, true)) + ') continue; '; + if ($typeIsArray) { + out += ' if (typeof item == \'string\') item = \'"\' + item; '; + } + out += ' if (typeof itemIndices[item] == \'number\') { ' + ($valid) + ' = false; j = itemIndices[item]; break; } itemIndices[item] = i; } '; + } + out += ' } '; + if ($isData) { + out += ' } '; + } + out += ' if (!' + ($valid) + ') { '; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ('uniqueItems') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { i: i, j: j } '; + if (it.opts.messages !== false) { + out += ' , message: \'should NOT have duplicate items (items ## \' + j + \' and \' + i + \' are identical)\' '; + } + if (it.opts.verbose) { + out += ' , schema: '; + if ($isData) { + out += 'validate.schema' + ($schemaPath); + } else { + out += '' + ($schema); + } + out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += ' } '; + if ($breakOnError) { + out += ' else { '; + } + } else { + if ($breakOnError) { + out += ' if (true) { '; + } + } + return out; +} + + +/***/ }), + +/***/ 1869: +/***/ (function(module) { + +"use strict"; + +module.exports = function generate_validate(it, $keyword, $ruleType) { + var out = ''; + var $async = it.schema.$async === true, + $refKeywords = it.util.schemaHasRulesExcept(it.schema, it.RULES.all, '$ref'), + $id = it.self._getId(it.schema); + if (it.opts.strictKeywords) { + var $unknownKwd = it.util.schemaUnknownRules(it.schema, it.RULES.keywords); + if ($unknownKwd) { + var $keywordsMsg = 'unknown keyword: ' + $unknownKwd; + if (it.opts.strictKeywords === 'log') it.logger.warn($keywordsMsg); + else throw new Error($keywordsMsg); + } + } + if (it.isTop) { + out += ' var validate = '; + if ($async) { + it.async = true; + out += 'async '; + } + out += 'function(data, dataPath, parentData, parentDataProperty, rootData) { \'use strict\'; '; + if ($id && (it.opts.sourceCode || it.opts.processCode)) { + out += ' ' + ('/\*# sourceURL=' + $id + ' */') + ' '; + } + } + if (typeof it.schema == 'boolean' || !($refKeywords || it.schema.$ref)) { + var $keyword = 'false schema'; + var $lvl = it.level; + var $dataLvl = it.dataLevel; + var $schema = it.schema[$keyword]; + var $schemaPath = it.schemaPath + it.util.getProperty($keyword); + var $errSchemaPath = it.errSchemaPath + '/' + $keyword; + var $breakOnError = !it.opts.allErrors; + var $errorKeyword; + var $data = 'data' + ($dataLvl || ''); + var $valid = 'valid' + $lvl; + if (it.schema === false) { + if (it.isTop) { + $breakOnError = true; + } else { + out += ' var ' + ($valid) + ' = false; '; + } + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ($errorKeyword || 'false schema') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: {} '; + if (it.opts.messages !== false) { + out += ' , message: \'boolean schema is false\' '; + } + if (it.opts.verbose) { + out += ' , schema: false , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + } else { + if (it.isTop) { + if ($async) { + out += ' return data; '; + } else { + out += ' validate.errors = null; return true; '; + } + } else { + out += ' var ' + ($valid) + ' = true; '; + } + } + if (it.isTop) { + out += ' }; return validate; '; + } + return out; + } + if (it.isTop) { + var $top = it.isTop, + $lvl = it.level = 0, + $dataLvl = it.dataLevel = 0, + $data = 'data'; + it.rootId = it.resolve.fullPath(it.self._getId(it.root.schema)); + it.baseId = it.baseId || it.rootId; + delete it.isTop; + it.dataPathArr = [""]; + if (it.schema.default !== undefined && it.opts.useDefaults && it.opts.strictDefaults) { + var $defaultMsg = 'default is ignored in the schema root'; + if (it.opts.strictDefaults === 'log') it.logger.warn($defaultMsg); + else throw new Error($defaultMsg); + } + out += ' var vErrors = null; '; + out += ' var errors = 0; '; + out += ' if (rootData === undefined) rootData = data; '; + } else { + var $lvl = it.level, + $dataLvl = it.dataLevel, + $data = 'data' + ($dataLvl || ''); + if ($id) it.baseId = it.resolve.url(it.baseId, $id); + if ($async && !it.async) throw new Error('async schema in sync schema'); + out += ' var errs_' + ($lvl) + ' = errors;'; + } + var $valid = 'valid' + $lvl, + $breakOnError = !it.opts.allErrors, + $closingBraces1 = '', + $closingBraces2 = ''; + var $errorKeyword; + var $typeSchema = it.schema.type, + $typeIsArray = Array.isArray($typeSchema); + if ($typeSchema && it.opts.nullable && it.schema.nullable === true) { + if ($typeIsArray) { + if ($typeSchema.indexOf('null') == -1) $typeSchema = $typeSchema.concat('null'); + } else if ($typeSchema != 'null') { + $typeSchema = [$typeSchema, 'null']; + $typeIsArray = true; + } + } + if ($typeIsArray && $typeSchema.length == 1) { + $typeSchema = $typeSchema[0]; + $typeIsArray = false; + } + if (it.schema.$ref && $refKeywords) { + if (it.opts.extendRefs == 'fail') { + throw new Error('$ref: validation keywords used in schema at path "' + it.errSchemaPath + '" (see option extendRefs)'); + } else if (it.opts.extendRefs !== true) { + $refKeywords = false; + it.logger.warn('$ref: keywords ignored in schema at path "' + it.errSchemaPath + '"'); + } + } + if (it.schema.$comment && it.opts.$comment) { + out += ' ' + (it.RULES.all.$comment.code(it, '$comment')); + } + if ($typeSchema) { + if (it.opts.coerceTypes) { + var $coerceToTypes = it.util.coerceToTypes(it.opts.coerceTypes, $typeSchema); + } + var $rulesGroup = it.RULES.types[$typeSchema]; + if ($coerceToTypes || $typeIsArray || $rulesGroup === true || ($rulesGroup && !$shouldUseGroup($rulesGroup))) { + var $schemaPath = it.schemaPath + '.type', + $errSchemaPath = it.errSchemaPath + '/type'; + var $schemaPath = it.schemaPath + '.type', + $errSchemaPath = it.errSchemaPath + '/type', + $method = $typeIsArray ? 'checkDataTypes' : 'checkDataType'; + out += ' if (' + (it.util[$method]($typeSchema, $data, it.opts.strictNumbers, true)) + ') { '; + if ($coerceToTypes) { + var $dataType = 'dataType' + $lvl, + $coerced = 'coerced' + $lvl; + out += ' var ' + ($dataType) + ' = typeof ' + ($data) + '; var ' + ($coerced) + ' = undefined; '; + if (it.opts.coerceTypes == 'array') { + out += ' if (' + ($dataType) + ' == \'object\' && Array.isArray(' + ($data) + ') && ' + ($data) + '.length == 1) { ' + ($data) + ' = ' + ($data) + '[0]; ' + ($dataType) + ' = typeof ' + ($data) + '; if (' + (it.util.checkDataType(it.schema.type, $data, it.opts.strictNumbers)) + ') ' + ($coerced) + ' = ' + ($data) + '; } '; + } + out += ' if (' + ($coerced) + ' !== undefined) ; '; + var arr1 = $coerceToTypes; + if (arr1) { + var $type, $i = -1, + l1 = arr1.length - 1; + while ($i < l1) { + $type = arr1[$i += 1]; + if ($type == 'string') { + out += ' else if (' + ($dataType) + ' == \'number\' || ' + ($dataType) + ' == \'boolean\') ' + ($coerced) + ' = \'\' + ' + ($data) + '; else if (' + ($data) + ' === null) ' + ($coerced) + ' = \'\'; '; + } else if ($type == 'number' || $type == 'integer') { + out += ' else if (' + ($dataType) + ' == \'boolean\' || ' + ($data) + ' === null || (' + ($dataType) + ' == \'string\' && ' + ($data) + ' && ' + ($data) + ' == +' + ($data) + ' '; + if ($type == 'integer') { + out += ' && !(' + ($data) + ' % 1)'; + } + out += ')) ' + ($coerced) + ' = +' + ($data) + '; '; + } else if ($type == 'boolean') { + out += ' else if (' + ($data) + ' === \'false\' || ' + ($data) + ' === 0 || ' + ($data) + ' === null) ' + ($coerced) + ' = false; else if (' + ($data) + ' === \'true\' || ' + ($data) + ' === 1) ' + ($coerced) + ' = true; '; + } else if ($type == 'null') { + out += ' else if (' + ($data) + ' === \'\' || ' + ($data) + ' === 0 || ' + ($data) + ' === false) ' + ($coerced) + ' = null; '; + } else if (it.opts.coerceTypes == 'array' && $type == 'array') { + out += ' else if (' + ($dataType) + ' == \'string\' || ' + ($dataType) + ' == \'number\' || ' + ($dataType) + ' == \'boolean\' || ' + ($data) + ' == null) ' + ($coerced) + ' = [' + ($data) + ']; '; + } + } + } + out += ' else { '; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ($errorKeyword || 'type') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { type: \''; + if ($typeIsArray) { + out += '' + ($typeSchema.join(",")); + } else { + out += '' + ($typeSchema); + } + out += '\' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should be '; + if ($typeIsArray) { + out += '' + ($typeSchema.join(",")); + } else { + out += '' + ($typeSchema); + } + out += '\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += ' } if (' + ($coerced) + ' !== undefined) { '; + var $parentData = $dataLvl ? 'data' + (($dataLvl - 1) || '') : 'parentData', + $parentDataProperty = $dataLvl ? it.dataPathArr[$dataLvl] : 'parentDataProperty'; + out += ' ' + ($data) + ' = ' + ($coerced) + '; '; + if (!$dataLvl) { + out += 'if (' + ($parentData) + ' !== undefined)'; + } + out += ' ' + ($parentData) + '[' + ($parentDataProperty) + '] = ' + ($coerced) + '; } '; + } else { + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ($errorKeyword || 'type') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { type: \''; + if ($typeIsArray) { + out += '' + ($typeSchema.join(",")); + } else { + out += '' + ($typeSchema); + } + out += '\' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should be '; + if ($typeIsArray) { + out += '' + ($typeSchema.join(",")); + } else { + out += '' + ($typeSchema); + } + out += '\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + } + out += ' } '; + } + } + if (it.schema.$ref && !$refKeywords) { + out += ' ' + (it.RULES.all.$ref.code(it, '$ref')) + ' '; + if ($breakOnError) { + out += ' } if (errors === '; + if ($top) { + out += '0'; + } else { + out += 'errs_' + ($lvl); + } + out += ') { '; + $closingBraces2 += '}'; + } + } else { + var arr2 = it.RULES; + if (arr2) { + var $rulesGroup, i2 = -1, + l2 = arr2.length - 1; + while (i2 < l2) { + $rulesGroup = arr2[i2 += 1]; + if ($shouldUseGroup($rulesGroup)) { + if ($rulesGroup.type) { + out += ' if (' + (it.util.checkDataType($rulesGroup.type, $data, it.opts.strictNumbers)) + ') { '; + } + if (it.opts.useDefaults) { + if ($rulesGroup.type == 'object' && it.schema.properties) { + var $schema = it.schema.properties, + $schemaKeys = Object.keys($schema); + var arr3 = $schemaKeys; + if (arr3) { + var $propertyKey, i3 = -1, + l3 = arr3.length - 1; + while (i3 < l3) { + $propertyKey = arr3[i3 += 1]; + var $sch = $schema[$propertyKey]; + if ($sch.default !== undefined) { + var $passData = $data + it.util.getProperty($propertyKey); + if (it.compositeRule) { + if (it.opts.strictDefaults) { + var $defaultMsg = 'default is ignored for: ' + $passData; + if (it.opts.strictDefaults === 'log') it.logger.warn($defaultMsg); + else throw new Error($defaultMsg); + } + } else { + out += ' if (' + ($passData) + ' === undefined '; + if (it.opts.useDefaults == 'empty') { + out += ' || ' + ($passData) + ' === null || ' + ($passData) + ' === \'\' '; + } + out += ' ) ' + ($passData) + ' = '; + if (it.opts.useDefaults == 'shared') { + out += ' ' + (it.useDefault($sch.default)) + ' '; + } else { + out += ' ' + (JSON.stringify($sch.default)) + ' '; + } + out += '; '; + } + } + } + } + } else if ($rulesGroup.type == 'array' && Array.isArray(it.schema.items)) { + var arr4 = it.schema.items; + if (arr4) { + var $sch, $i = -1, + l4 = arr4.length - 1; + while ($i < l4) { + $sch = arr4[$i += 1]; + if ($sch.default !== undefined) { + var $passData = $data + '[' + $i + ']'; + if (it.compositeRule) { + if (it.opts.strictDefaults) { + var $defaultMsg = 'default is ignored for: ' + $passData; + if (it.opts.strictDefaults === 'log') it.logger.warn($defaultMsg); + else throw new Error($defaultMsg); + } + } else { + out += ' if (' + ($passData) + ' === undefined '; + if (it.opts.useDefaults == 'empty') { + out += ' || ' + ($passData) + ' === null || ' + ($passData) + ' === \'\' '; + } + out += ' ) ' + ($passData) + ' = '; + if (it.opts.useDefaults == 'shared') { + out += ' ' + (it.useDefault($sch.default)) + ' '; + } else { + out += ' ' + (JSON.stringify($sch.default)) + ' '; + } + out += '; '; + } + } + } + } + } + } + var arr5 = $rulesGroup.rules; + if (arr5) { + var $rule, i5 = -1, + l5 = arr5.length - 1; + while (i5 < l5) { + $rule = arr5[i5 += 1]; + if ($shouldUseRule($rule)) { + var $code = $rule.code(it, $rule.keyword, $rulesGroup.type); + if ($code) { + out += ' ' + ($code) + ' '; + if ($breakOnError) { + $closingBraces1 += '}'; + } + } + } + } + } + if ($breakOnError) { + out += ' ' + ($closingBraces1) + ' '; + $closingBraces1 = ''; + } + if ($rulesGroup.type) { + out += ' } '; + if ($typeSchema && $typeSchema === $rulesGroup.type && !$coerceToTypes) { + out += ' else { '; + var $schemaPath = it.schemaPath + '.type', + $errSchemaPath = it.errSchemaPath + '/type'; + var $$outStack = $$outStack || []; + $$outStack.push(out); + out = ''; /* istanbul ignore else */ + if (it.createErrors !== false) { + out += ' { keyword: \'' + ($errorKeyword || 'type') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { type: \''; + if ($typeIsArray) { + out += '' + ($typeSchema.join(",")); + } else { + out += '' + ($typeSchema); + } + out += '\' } '; + if (it.opts.messages !== false) { + out += ' , message: \'should be '; + if ($typeIsArray) { + out += '' + ($typeSchema.join(",")); + } else { + out += '' + ($typeSchema); + } + out += '\' '; + } + if (it.opts.verbose) { + out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' '; + } + out += ' } '; + } else { + out += ' {} '; + } + var __err = out; + out = $$outStack.pop(); + if (!it.compositeRule && $breakOnError) { + /* istanbul ignore if */ + if (it.async) { + out += ' throw new ValidationError([' + (__err) + ']); '; + } else { + out += ' validate.errors = [' + (__err) + ']; return false; '; + } + } else { + out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; '; + } + out += ' } '; + } + } + if ($breakOnError) { + out += ' if (errors === '; + if ($top) { + out += '0'; + } else { + out += 'errs_' + ($lvl); + } + out += ') { '; + $closingBraces2 += '}'; + } + } + } + } + } + if ($breakOnError) { + out += ' ' + ($closingBraces2) + ' '; + } + if ($top) { + if ($async) { + out += ' if (errors === 0) return data; '; + out += ' else throw new ValidationError(vErrors); '; + } else { + out += ' validate.errors = vErrors; '; + out += ' return errors === 0; '; + } + out += ' }; return validate;'; + } else { + out += ' var ' + ($valid) + ' = errors === errs_' + ($lvl) + ';'; + } + + function $shouldUseGroup($rulesGroup) { + var rules = $rulesGroup.rules; + for (var i = 0; i < rules.length; i++) + if ($shouldUseRule(rules[i])) return true; + } + + function $shouldUseRule($rule) { + return it.schema[$rule.keyword] !== undefined || ($rule.implements && $ruleImplementsSomeKeyword($rule)); + } + + function $ruleImplementsSomeKeyword($rule) { + var impl = $rule.implements; + for (var i = 0; i < impl.length; i++) + if (it.schema[impl[i]] !== undefined) return true; + } + return out; +} + + +/***/ }), + +/***/ 7931: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +"use strict"; + + +var IDENTIFIER = /^[a-z_$][a-z0-9_$-]*$/i; +var customRuleCode = __webpack_require__(1793); +var definitionSchema = __webpack_require__(5868); + +module.exports = { + add: addKeyword, + get: getKeyword, + remove: removeKeyword, + validate: validateKeyword +}; + + +/** + * Define custom keyword + * @this Ajv + * @param {String} keyword custom keyword, should be unique (including different from all standard, custom and macro keywords). + * @param {Object} definition keyword definition object with properties `type` (type(s) which the keyword applies to), `validate` or `compile`. + * @return {Ajv} this for method chaining + */ +function addKeyword(keyword, definition) { + /* jshint validthis: true */ + /* eslint no-shadow: 0 */ + var RULES = this.RULES; + if (RULES.keywords[keyword]) + throw new Error('Keyword ' + keyword + ' is already defined'); + + if (!IDENTIFIER.test(keyword)) + throw new Error('Keyword ' + keyword + ' is not a valid identifier'); + + if (definition) { + this.validateKeyword(definition, true); + + var dataType = definition.type; + if (Array.isArray(dataType)) { + for (var i=0; i yD ) { return 1; } + } + // natural sorting through split numeric strings and default strings + for(var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) { + // find floats not starting with '0', string or 0 if not defined (Clint Priest) + oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0; + oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0; + // handle numeric vs string comparison - number < string - (Kyle Adams) + if (isNaN(oFxNcL) !== isNaN(oFyNcL)) { return (isNaN(oFxNcL)) ? 1 : -1; } + // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2' + else if (typeof oFxNcL !== typeof oFyNcL) { + oFxNcL += ''; + oFyNcL += ''; + } + if (oFxNcL < oFyNcL) { return -1; } + if (oFxNcL > oFyNcL) { return 1; } + } + return 0; +}; + + +/***/ }), + +/***/ 5156: +/***/ (function(__unused_webpack_module, exports) { + +(function(exports) { + "use strict"; + + function isArray(obj) { + if (obj !== null) { + return Object.prototype.toString.call(obj) === "[object Array]"; + } else { + return false; + } + } + + function isObject(obj) { + if (obj !== null) { + return Object.prototype.toString.call(obj) === "[object Object]"; + } else { + return false; + } + } + + function strictDeepEqual(first, second) { + // Check the scalar case first. + if (first === second) { + return true; + } + + // Check if they are the same type. + var firstType = Object.prototype.toString.call(first); + if (firstType !== Object.prototype.toString.call(second)) { + return false; + } + // We know that first and second have the same type so we can just check the + // first type from now on. + if (isArray(first) === true) { + // Short circuit if they're not the same length; + if (first.length !== second.length) { + return false; + } + for (var i = 0; i < first.length; i++) { + if (strictDeepEqual(first[i], second[i]) === false) { + return false; + } + } + return true; + } + if (isObject(first) === true) { + // An object is equal if it has the same key/value pairs. + var keysSeen = {}; + for (var key in first) { + if (hasOwnProperty.call(first, key)) { + if (strictDeepEqual(first[key], second[key]) === false) { + return false; + } + keysSeen[key] = true; + } + } + // Now check that there aren't any keys in second that weren't + // in first. + for (var key2 in second) { + if (hasOwnProperty.call(second, key2)) { + if (keysSeen[key2] !== true) { + return false; + } + } + } + return true; + } + return false; + } + + function isFalse(obj) { + // From the spec: + // A false value corresponds to the following values: + // Empty list + // Empty object + // Empty string + // False boolean + // null value + + // First check the scalar values. + if (obj === "" || obj === false || obj === null) { + return true; + } else if (isArray(obj) && obj.length === 0) { + // Check for an empty array. + return true; + } else if (isObject(obj)) { + // Check for an empty object. + for (var key in obj) { + // If there are any keys, then + // the object is not empty so the object + // is not false. + if (obj.hasOwnProperty(key)) { + return false; + } + } + return true; + } else { + return false; + } + } + + function objValues(obj) { + var keys = Object.keys(obj); + var values = []; + for (var i = 0; i < keys.length; i++) { + values.push(obj[keys[i]]); + } + return values; + } + + function merge(a, b) { + var merged = {}; + for (var key in a) { + merged[key] = a[key]; + } + for (var key2 in b) { + merged[key2] = b[key2]; + } + return merged; + } + + var trimLeft; + if (typeof String.prototype.trimLeft === "function") { + trimLeft = function(str) { + return str.trimLeft(); + }; + } else { + trimLeft = function(str) { + return str.match(/^\s*(.*)/)[1]; + }; + } + + // Type constants used to define functions. + var TYPE_NUMBER = 0; + var TYPE_ANY = 1; + var TYPE_STRING = 2; + var TYPE_ARRAY = 3; + var TYPE_OBJECT = 4; + var TYPE_BOOLEAN = 5; + var TYPE_EXPREF = 6; + var TYPE_NULL = 7; + var TYPE_ARRAY_NUMBER = 8; + var TYPE_ARRAY_STRING = 9; + + var TOK_EOF = "EOF"; + var TOK_UNQUOTEDIDENTIFIER = "UnquotedIdentifier"; + var TOK_QUOTEDIDENTIFIER = "QuotedIdentifier"; + var TOK_RBRACKET = "Rbracket"; + var TOK_RPAREN = "Rparen"; + var TOK_COMMA = "Comma"; + var TOK_COLON = "Colon"; + var TOK_RBRACE = "Rbrace"; + var TOK_NUMBER = "Number"; + var TOK_CURRENT = "Current"; + var TOK_EXPREF = "Expref"; + var TOK_PIPE = "Pipe"; + var TOK_OR = "Or"; + var TOK_AND = "And"; + var TOK_EQ = "EQ"; + var TOK_GT = "GT"; + var TOK_LT = "LT"; + var TOK_GTE = "GTE"; + var TOK_LTE = "LTE"; + var TOK_NE = "NE"; + var TOK_FLATTEN = "Flatten"; + var TOK_STAR = "Star"; + var TOK_FILTER = "Filter"; + var TOK_DOT = "Dot"; + var TOK_NOT = "Not"; + var TOK_LBRACE = "Lbrace"; + var TOK_LBRACKET = "Lbracket"; + var TOK_LPAREN= "Lparen"; + var TOK_LITERAL= "Literal"; + + // The "&", "[", "<", ">" tokens + // are not in basicToken because + // there are two token variants + // ("&&", "[?", "<=", ">="). This is specially handled + // below. + + var basicTokens = { + ".": TOK_DOT, + "*": TOK_STAR, + ",": TOK_COMMA, + ":": TOK_COLON, + "{": TOK_LBRACE, + "}": TOK_RBRACE, + "]": TOK_RBRACKET, + "(": TOK_LPAREN, + ")": TOK_RPAREN, + "@": TOK_CURRENT + }; + + var operatorStartToken = { + "<": true, + ">": true, + "=": true, + "!": true + }; + + var skipChars = { + " ": true, + "\t": true, + "\n": true + }; + + + function isAlpha(ch) { + return (ch >= "a" && ch <= "z") || + (ch >= "A" && ch <= "Z") || + ch === "_"; + } + + function isNum(ch) { + return (ch >= "0" && ch <= "9") || + ch === "-"; + } + function isAlphaNum(ch) { + return (ch >= "a" && ch <= "z") || + (ch >= "A" && ch <= "Z") || + (ch >= "0" && ch <= "9") || + ch === "_"; + } + + function Lexer() { + } + Lexer.prototype = { + tokenize: function(stream) { + var tokens = []; + this._current = 0; + var start; + var identifier; + var token; + while (this._current < stream.length) { + if (isAlpha(stream[this._current])) { + start = this._current; + identifier = this._consumeUnquotedIdentifier(stream); + tokens.push({type: TOK_UNQUOTEDIDENTIFIER, + value: identifier, + start: start}); + } else if (basicTokens[stream[this._current]] !== undefined) { + tokens.push({type: basicTokens[stream[this._current]], + value: stream[this._current], + start: this._current}); + this._current++; + } else if (isNum(stream[this._current])) { + token = this._consumeNumber(stream); + tokens.push(token); + } else if (stream[this._current] === "[") { + // No need to increment this._current. This happens + // in _consumeLBracket + token = this._consumeLBracket(stream); + tokens.push(token); + } else if (stream[this._current] === "\"") { + start = this._current; + identifier = this._consumeQuotedIdentifier(stream); + tokens.push({type: TOK_QUOTEDIDENTIFIER, + value: identifier, + start: start}); + } else if (stream[this._current] === "'") { + start = this._current; + identifier = this._consumeRawStringLiteral(stream); + tokens.push({type: TOK_LITERAL, + value: identifier, + start: start}); + } else if (stream[this._current] === "`") { + start = this._current; + var literal = this._consumeLiteral(stream); + tokens.push({type: TOK_LITERAL, + value: literal, + start: start}); + } else if (operatorStartToken[stream[this._current]] !== undefined) { + tokens.push(this._consumeOperator(stream)); + } else if (skipChars[stream[this._current]] !== undefined) { + // Ignore whitespace. + this._current++; + } else if (stream[this._current] === "&") { + start = this._current; + this._current++; + if (stream[this._current] === "&") { + this._current++; + tokens.push({type: TOK_AND, value: "&&", start: start}); + } else { + tokens.push({type: TOK_EXPREF, value: "&", start: start}); + } + } else if (stream[this._current] === "|") { + start = this._current; + this._current++; + if (stream[this._current] === "|") { + this._current++; + tokens.push({type: TOK_OR, value: "||", start: start}); + } else { + tokens.push({type: TOK_PIPE, value: "|", start: start}); + } + } else { + var error = new Error("Unknown character:" + stream[this._current]); + error.name = "LexerError"; + throw error; + } + } + return tokens; + }, + + _consumeUnquotedIdentifier: function(stream) { + var start = this._current; + this._current++; + while (this._current < stream.length && isAlphaNum(stream[this._current])) { + this._current++; + } + return stream.slice(start, this._current); + }, + + _consumeQuotedIdentifier: function(stream) { + var start = this._current; + this._current++; + var maxLength = stream.length; + while (stream[this._current] !== "\"" && this._current < maxLength) { + // You can escape a double quote and you can escape an escape. + var current = this._current; + if (stream[current] === "\\" && (stream[current + 1] === "\\" || + stream[current + 1] === "\"")) { + current += 2; + } else { + current++; + } + this._current = current; + } + this._current++; + return JSON.parse(stream.slice(start, this._current)); + }, + + _consumeRawStringLiteral: function(stream) { + var start = this._current; + this._current++; + var maxLength = stream.length; + while (stream[this._current] !== "'" && this._current < maxLength) { + // You can escape a single quote and you can escape an escape. + var current = this._current; + if (stream[current] === "\\" && (stream[current + 1] === "\\" || + stream[current + 1] === "'")) { + current += 2; + } else { + current++; + } + this._current = current; + } + this._current++; + var literal = stream.slice(start + 1, this._current - 1); + return literal.replace("\\'", "'"); + }, + + _consumeNumber: function(stream) { + var start = this._current; + this._current++; + var maxLength = stream.length; + while (isNum(stream[this._current]) && this._current < maxLength) { + this._current++; + } + var value = parseInt(stream.slice(start, this._current)); + return {type: TOK_NUMBER, value: value, start: start}; + }, + + _consumeLBracket: function(stream) { + var start = this._current; + this._current++; + if (stream[this._current] === "?") { + this._current++; + return {type: TOK_FILTER, value: "[?", start: start}; + } else if (stream[this._current] === "]") { + this._current++; + return {type: TOK_FLATTEN, value: "[]", start: start}; + } else { + return {type: TOK_LBRACKET, value: "[", start: start}; + } + }, + + _consumeOperator: function(stream) { + var start = this._current; + var startingChar = stream[start]; + this._current++; + if (startingChar === "!") { + if (stream[this._current] === "=") { + this._current++; + return {type: TOK_NE, value: "!=", start: start}; + } else { + return {type: TOK_NOT, value: "!", start: start}; + } + } else if (startingChar === "<") { + if (stream[this._current] === "=") { + this._current++; + return {type: TOK_LTE, value: "<=", start: start}; + } else { + return {type: TOK_LT, value: "<", start: start}; + } + } else if (startingChar === ">") { + if (stream[this._current] === "=") { + this._current++; + return {type: TOK_GTE, value: ">=", start: start}; + } else { + return {type: TOK_GT, value: ">", start: start}; + } + } else if (startingChar === "=") { + if (stream[this._current] === "=") { + this._current++; + return {type: TOK_EQ, value: "==", start: start}; + } + } + }, + + _consumeLiteral: function(stream) { + this._current++; + var start = this._current; + var maxLength = stream.length; + var literal; + while(stream[this._current] !== "`" && this._current < maxLength) { + // You can escape a literal char or you can escape the escape. + var current = this._current; + if (stream[current] === "\\" && (stream[current + 1] === "\\" || + stream[current + 1] === "`")) { + current += 2; + } else { + current++; + } + this._current = current; + } + var literalString = trimLeft(stream.slice(start, this._current)); + literalString = literalString.replace("\\`", "`"); + if (this._looksLikeJSON(literalString)) { + literal = JSON.parse(literalString); + } else { + // Try to JSON parse it as "" + literal = JSON.parse("\"" + literalString + "\""); + } + // +1 gets us to the ending "`", +1 to move on to the next char. + this._current++; + return literal; + }, + + _looksLikeJSON: function(literalString) { + var startingChars = "[{\""; + var jsonLiterals = ["true", "false", "null"]; + var numberLooking = "-0123456789"; + + if (literalString === "") { + return false; + } else if (startingChars.indexOf(literalString[0]) >= 0) { + return true; + } else if (jsonLiterals.indexOf(literalString) >= 0) { + return true; + } else if (numberLooking.indexOf(literalString[0]) >= 0) { + try { + JSON.parse(literalString); + return true; + } catch (ex) { + return false; + } + } else { + return false; + } + } + }; + + var bindingPower = {}; + bindingPower[TOK_EOF] = 0; + bindingPower[TOK_UNQUOTEDIDENTIFIER] = 0; + bindingPower[TOK_QUOTEDIDENTIFIER] = 0; + bindingPower[TOK_RBRACKET] = 0; + bindingPower[TOK_RPAREN] = 0; + bindingPower[TOK_COMMA] = 0; + bindingPower[TOK_RBRACE] = 0; + bindingPower[TOK_NUMBER] = 0; + bindingPower[TOK_CURRENT] = 0; + bindingPower[TOK_EXPREF] = 0; + bindingPower[TOK_PIPE] = 1; + bindingPower[TOK_OR] = 2; + bindingPower[TOK_AND] = 3; + bindingPower[TOK_EQ] = 5; + bindingPower[TOK_GT] = 5; + bindingPower[TOK_LT] = 5; + bindingPower[TOK_GTE] = 5; + bindingPower[TOK_LTE] = 5; + bindingPower[TOK_NE] = 5; + bindingPower[TOK_FLATTEN] = 9; + bindingPower[TOK_STAR] = 20; + bindingPower[TOK_FILTER] = 21; + bindingPower[TOK_DOT] = 40; + bindingPower[TOK_NOT] = 45; + bindingPower[TOK_LBRACE] = 50; + bindingPower[TOK_LBRACKET] = 55; + bindingPower[TOK_LPAREN] = 60; + + function Parser() { + } + + Parser.prototype = { + parse: function(expression) { + this._loadTokens(expression); + this.index = 0; + var ast = this.expression(0); + if (this._lookahead(0) !== TOK_EOF) { + var t = this._lookaheadToken(0); + var error = new Error( + "Unexpected token type: " + t.type + ", value: " + t.value); + error.name = "ParserError"; + throw error; + } + return ast; + }, + + _loadTokens: function(expression) { + var lexer = new Lexer(); + var tokens = lexer.tokenize(expression); + tokens.push({type: TOK_EOF, value: "", start: expression.length}); + this.tokens = tokens; + }, + + expression: function(rbp) { + var leftToken = this._lookaheadToken(0); + this._advance(); + var left = this.nud(leftToken); + var currentToken = this._lookahead(0); + while (rbp < bindingPower[currentToken]) { + this._advance(); + left = this.led(currentToken, left); + currentToken = this._lookahead(0); + } + return left; + }, + + _lookahead: function(number) { + return this.tokens[this.index + number].type; + }, + + _lookaheadToken: function(number) { + return this.tokens[this.index + number]; + }, + + _advance: function() { + this.index++; + }, + + nud: function(token) { + var left; + var right; + var expression; + switch (token.type) { + case TOK_LITERAL: + return {type: "Literal", value: token.value}; + case TOK_UNQUOTEDIDENTIFIER: + return {type: "Field", name: token.value}; + case TOK_QUOTEDIDENTIFIER: + var node = {type: "Field", name: token.value}; + if (this._lookahead(0) === TOK_LPAREN) { + throw new Error("Quoted identifier not allowed for function names."); + } else { + return node; + } + break; + case TOK_NOT: + right = this.expression(bindingPower.Not); + return {type: "NotExpression", children: [right]}; + case TOK_STAR: + left = {type: "Identity"}; + right = null; + if (this._lookahead(0) === TOK_RBRACKET) { + // This can happen in a multiselect, + // [a, b, *] + right = {type: "Identity"}; + } else { + right = this._parseProjectionRHS(bindingPower.Star); + } + return {type: "ValueProjection", children: [left, right]}; + case TOK_FILTER: + return this.led(token.type, {type: "Identity"}); + case TOK_LBRACE: + return this._parseMultiselectHash(); + case TOK_FLATTEN: + left = {type: TOK_FLATTEN, children: [{type: "Identity"}]}; + right = this._parseProjectionRHS(bindingPower.Flatten); + return {type: "Projection", children: [left, right]}; + case TOK_LBRACKET: + if (this._lookahead(0) === TOK_NUMBER || this._lookahead(0) === TOK_COLON) { + right = this._parseIndexExpression(); + return this._projectIfSlice({type: "Identity"}, right); + } else if (this._lookahead(0) === TOK_STAR && + this._lookahead(1) === TOK_RBRACKET) { + this._advance(); + this._advance(); + right = this._parseProjectionRHS(bindingPower.Star); + return {type: "Projection", + children: [{type: "Identity"}, right]}; + } else { + return this._parseMultiselectList(); + } + break; + case TOK_CURRENT: + return {type: TOK_CURRENT}; + case TOK_EXPREF: + expression = this.expression(bindingPower.Expref); + return {type: "ExpressionReference", children: [expression]}; + case TOK_LPAREN: + var args = []; + while (this._lookahead(0) !== TOK_RPAREN) { + if (this._lookahead(0) === TOK_CURRENT) { + expression = {type: TOK_CURRENT}; + this._advance(); + } else { + expression = this.expression(0); + } + args.push(expression); + } + this._match(TOK_RPAREN); + return args[0]; + default: + this._errorToken(token); + } + }, + + led: function(tokenName, left) { + var right; + switch(tokenName) { + case TOK_DOT: + var rbp = bindingPower.Dot; + if (this._lookahead(0) !== TOK_STAR) { + right = this._parseDotRHS(rbp); + return {type: "Subexpression", children: [left, right]}; + } else { + // Creating a projection. + this._advance(); + right = this._parseProjectionRHS(rbp); + return {type: "ValueProjection", children: [left, right]}; + } + break; + case TOK_PIPE: + right = this.expression(bindingPower.Pipe); + return {type: TOK_PIPE, children: [left, right]}; + case TOK_OR: + right = this.expression(bindingPower.Or); + return {type: "OrExpression", children: [left, right]}; + case TOK_AND: + right = this.expression(bindingPower.And); + return {type: "AndExpression", children: [left, right]}; + case TOK_LPAREN: + var name = left.name; + var args = []; + var expression, node; + while (this._lookahead(0) !== TOK_RPAREN) { + if (this._lookahead(0) === TOK_CURRENT) { + expression = {type: TOK_CURRENT}; + this._advance(); + } else { + expression = this.expression(0); + } + if (this._lookahead(0) === TOK_COMMA) { + this._match(TOK_COMMA); + } + args.push(expression); + } + this._match(TOK_RPAREN); + node = {type: "Function", name: name, children: args}; + return node; + case TOK_FILTER: + var condition = this.expression(0); + this._match(TOK_RBRACKET); + if (this._lookahead(0) === TOK_FLATTEN) { + right = {type: "Identity"}; + } else { + right = this._parseProjectionRHS(bindingPower.Filter); + } + return {type: "FilterProjection", children: [left, right, condition]}; + case TOK_FLATTEN: + var leftNode = {type: TOK_FLATTEN, children: [left]}; + var rightNode = this._parseProjectionRHS(bindingPower.Flatten); + return {type: "Projection", children: [leftNode, rightNode]}; + case TOK_EQ: + case TOK_NE: + case TOK_GT: + case TOK_GTE: + case TOK_LT: + case TOK_LTE: + return this._parseComparator(left, tokenName); + case TOK_LBRACKET: + var token = this._lookaheadToken(0); + if (token.type === TOK_NUMBER || token.type === TOK_COLON) { + right = this._parseIndexExpression(); + return this._projectIfSlice(left, right); + } else { + this._match(TOK_STAR); + this._match(TOK_RBRACKET); + right = this._parseProjectionRHS(bindingPower.Star); + return {type: "Projection", children: [left, right]}; + } + break; + default: + this._errorToken(this._lookaheadToken(0)); + } + }, + + _match: function(tokenType) { + if (this._lookahead(0) === tokenType) { + this._advance(); + } else { + var t = this._lookaheadToken(0); + var error = new Error("Expected " + tokenType + ", got: " + t.type); + error.name = "ParserError"; + throw error; + } + }, + + _errorToken: function(token) { + var error = new Error("Invalid token (" + + token.type + "): \"" + + token.value + "\""); + error.name = "ParserError"; + throw error; + }, + + + _parseIndexExpression: function() { + if (this._lookahead(0) === TOK_COLON || this._lookahead(1) === TOK_COLON) { + return this._parseSliceExpression(); + } else { + var node = { + type: "Index", + value: this._lookaheadToken(0).value}; + this._advance(); + this._match(TOK_RBRACKET); + return node; + } + }, + + _projectIfSlice: function(left, right) { + var indexExpr = {type: "IndexExpression", children: [left, right]}; + if (right.type === "Slice") { + return { + type: "Projection", + children: [indexExpr, this._parseProjectionRHS(bindingPower.Star)] + }; + } else { + return indexExpr; + } + }, + + _parseSliceExpression: function() { + // [start:end:step] where each part is optional, as well as the last + // colon. + var parts = [null, null, null]; + var index = 0; + var currentToken = this._lookahead(0); + while (currentToken !== TOK_RBRACKET && index < 3) { + if (currentToken === TOK_COLON) { + index++; + this._advance(); + } else if (currentToken === TOK_NUMBER) { + parts[index] = this._lookaheadToken(0).value; + this._advance(); + } else { + var t = this._lookahead(0); + var error = new Error("Syntax error, unexpected token: " + + t.value + "(" + t.type + ")"); + error.name = "Parsererror"; + throw error; + } + currentToken = this._lookahead(0); + } + this._match(TOK_RBRACKET); + return { + type: "Slice", + children: parts + }; + }, + + _parseComparator: function(left, comparator) { + var right = this.expression(bindingPower[comparator]); + return {type: "Comparator", name: comparator, children: [left, right]}; + }, + + _parseDotRHS: function(rbp) { + var lookahead = this._lookahead(0); + var exprTokens = [TOK_UNQUOTEDIDENTIFIER, TOK_QUOTEDIDENTIFIER, TOK_STAR]; + if (exprTokens.indexOf(lookahead) >= 0) { + return this.expression(rbp); + } else if (lookahead === TOK_LBRACKET) { + this._match(TOK_LBRACKET); + return this._parseMultiselectList(); + } else if (lookahead === TOK_LBRACE) { + this._match(TOK_LBRACE); + return this._parseMultiselectHash(); + } + }, + + _parseProjectionRHS: function(rbp) { + var right; + if (bindingPower[this._lookahead(0)] < 10) { + right = {type: "Identity"}; + } else if (this._lookahead(0) === TOK_LBRACKET) { + right = this.expression(rbp); + } else if (this._lookahead(0) === TOK_FILTER) { + right = this.expression(rbp); + } else if (this._lookahead(0) === TOK_DOT) { + this._match(TOK_DOT); + right = this._parseDotRHS(rbp); + } else { + var t = this._lookaheadToken(0); + var error = new Error("Sytanx error, unexpected token: " + + t.value + "(" + t.type + ")"); + error.name = "ParserError"; + throw error; + } + return right; + }, + + _parseMultiselectList: function() { + var expressions = []; + while (this._lookahead(0) !== TOK_RBRACKET) { + var expression = this.expression(0); + expressions.push(expression); + if (this._lookahead(0) === TOK_COMMA) { + this._match(TOK_COMMA); + if (this._lookahead(0) === TOK_RBRACKET) { + throw new Error("Unexpected token Rbracket"); + } + } + } + this._match(TOK_RBRACKET); + return {type: "MultiSelectList", children: expressions}; + }, + + _parseMultiselectHash: function() { + var pairs = []; + var identifierTypes = [TOK_UNQUOTEDIDENTIFIER, TOK_QUOTEDIDENTIFIER]; + var keyToken, keyName, value, node; + for (;;) { + keyToken = this._lookaheadToken(0); + if (identifierTypes.indexOf(keyToken.type) < 0) { + throw new Error("Expecting an identifier token, got: " + + keyToken.type); + } + keyName = keyToken.value; + this._advance(); + this._match(TOK_COLON); + value = this.expression(0); + node = {type: "KeyValuePair", name: keyName, value: value}; + pairs.push(node); + if (this._lookahead(0) === TOK_COMMA) { + this._match(TOK_COMMA); + } else if (this._lookahead(0) === TOK_RBRACE) { + this._match(TOK_RBRACE); + break; + } + } + return {type: "MultiSelectHash", children: pairs}; + } + }; + + + function TreeInterpreter(runtime) { + this.runtime = runtime; + } + + TreeInterpreter.prototype = { + search: function(node, value) { + return this.visit(node, value); + }, + + visit: function(node, value) { + var matched, current, result, first, second, field, left, right, collected, i; + switch (node.type) { + case "Field": + if (value === null ) { + return null; + } else if (isObject(value)) { + field = value[node.name]; + if (field === undefined) { + return null; + } else { + return field; + } + } else { + return null; + } + break; + case "Subexpression": + result = this.visit(node.children[0], value); + for (i = 1; i < node.children.length; i++) { + result = this.visit(node.children[1], result); + if (result === null) { + return null; + } + } + return result; + case "IndexExpression": + left = this.visit(node.children[0], value); + right = this.visit(node.children[1], left); + return right; + case "Index": + if (!isArray(value)) { + return null; + } + var index = node.value; + if (index < 0) { + index = value.length + index; + } + result = value[index]; + if (result === undefined) { + result = null; + } + return result; + case "Slice": + if (!isArray(value)) { + return null; + } + var sliceParams = node.children.slice(0); + var computed = this.computeSliceParams(value.length, sliceParams); + var start = computed[0]; + var stop = computed[1]; + var step = computed[2]; + result = []; + if (step > 0) { + for (i = start; i < stop; i += step) { + result.push(value[i]); + } + } else { + for (i = start; i > stop; i += step) { + result.push(value[i]); + } + } + return result; + case "Projection": + // Evaluate left child. + var base = this.visit(node.children[0], value); + if (!isArray(base)) { + return null; + } + collected = []; + for (i = 0; i < base.length; i++) { + current = this.visit(node.children[1], base[i]); + if (current !== null) { + collected.push(current); + } + } + return collected; + case "ValueProjection": + // Evaluate left child. + base = this.visit(node.children[0], value); + if (!isObject(base)) { + return null; + } + collected = []; + var values = objValues(base); + for (i = 0; i < values.length; i++) { + current = this.visit(node.children[1], values[i]); + if (current !== null) { + collected.push(current); + } + } + return collected; + case "FilterProjection": + base = this.visit(node.children[0], value); + if (!isArray(base)) { + return null; + } + var filtered = []; + var finalResults = []; + for (i = 0; i < base.length; i++) { + matched = this.visit(node.children[2], base[i]); + if (!isFalse(matched)) { + filtered.push(base[i]); + } + } + for (var j = 0; j < filtered.length; j++) { + current = this.visit(node.children[1], filtered[j]); + if (current !== null) { + finalResults.push(current); + } + } + return finalResults; + case "Comparator": + first = this.visit(node.children[0], value); + second = this.visit(node.children[1], value); + switch(node.name) { + case TOK_EQ: + result = strictDeepEqual(first, second); + break; + case TOK_NE: + result = !strictDeepEqual(first, second); + break; + case TOK_GT: + result = first > second; + break; + case TOK_GTE: + result = first >= second; + break; + case TOK_LT: + result = first < second; + break; + case TOK_LTE: + result = first <= second; + break; + default: + throw new Error("Unknown comparator: " + node.name); + } + return result; + case TOK_FLATTEN: + var original = this.visit(node.children[0], value); + if (!isArray(original)) { + return null; + } + var merged = []; + for (i = 0; i < original.length; i++) { + current = original[i]; + if (isArray(current)) { + merged.push.apply(merged, current); + } else { + merged.push(current); + } + } + return merged; + case "Identity": + return value; + case "MultiSelectList": + if (value === null) { + return null; + } + collected = []; + for (i = 0; i < node.children.length; i++) { + collected.push(this.visit(node.children[i], value)); + } + return collected; + case "MultiSelectHash": + if (value === null) { + return null; + } + collected = {}; + var child; + for (i = 0; i < node.children.length; i++) { + child = node.children[i]; + collected[child.name] = this.visit(child.value, value); + } + return collected; + case "OrExpression": + matched = this.visit(node.children[0], value); + if (isFalse(matched)) { + matched = this.visit(node.children[1], value); + } + return matched; + case "AndExpression": + first = this.visit(node.children[0], value); + + if (isFalse(first) === true) { + return first; + } + return this.visit(node.children[1], value); + case "NotExpression": + first = this.visit(node.children[0], value); + return isFalse(first); + case "Literal": + return node.value; + case TOK_PIPE: + left = this.visit(node.children[0], value); + return this.visit(node.children[1], left); + case TOK_CURRENT: + return value; + case "Function": + var resolvedArgs = []; + for (i = 0; i < node.children.length; i++) { + resolvedArgs.push(this.visit(node.children[i], value)); + } + return this.runtime.callFunction(node.name, resolvedArgs); + case "ExpressionReference": + var refNode = node.children[0]; + // Tag the node with a specific attribute so the type + // checker verify the type. + refNode.jmespathType = TOK_EXPREF; + return refNode; + default: + throw new Error("Unknown node type: " + node.type); + } + }, + + computeSliceParams: function(arrayLength, sliceParams) { + var start = sliceParams[0]; + var stop = sliceParams[1]; + var step = sliceParams[2]; + var computed = [null, null, null]; + if (step === null) { + step = 1; + } else if (step === 0) { + var error = new Error("Invalid slice, step cannot be 0"); + error.name = "RuntimeError"; + throw error; + } + var stepValueNegative = step < 0 ? true : false; + + if (start === null) { + start = stepValueNegative ? arrayLength - 1 : 0; + } else { + start = this.capSliceRange(arrayLength, start, step); + } + + if (stop === null) { + stop = stepValueNegative ? -1 : arrayLength; + } else { + stop = this.capSliceRange(arrayLength, stop, step); + } + computed[0] = start; + computed[1] = stop; + computed[2] = step; + return computed; + }, + + capSliceRange: function(arrayLength, actualValue, step) { + if (actualValue < 0) { + actualValue += arrayLength; + if (actualValue < 0) { + actualValue = step < 0 ? -1 : 0; + } + } else if (actualValue >= arrayLength) { + actualValue = step < 0 ? arrayLength - 1 : arrayLength; + } + return actualValue; + } + + }; + + function Runtime(interpreter) { + this._interpreter = interpreter; + this.functionTable = { + // name: [function, ] + // The can be: + // + // { + // args: [[type1, type2], [type1, type2]], + // variadic: true|false + // } + // + // Each arg in the arg list is a list of valid types + // (if the function is overloaded and supports multiple + // types. If the type is "any" then no type checking + // occurs on the argument. Variadic is optional + // and if not provided is assumed to be false. + abs: {_func: this._functionAbs, _signature: [{types: [TYPE_NUMBER]}]}, + avg: {_func: this._functionAvg, _signature: [{types: [TYPE_ARRAY_NUMBER]}]}, + ceil: {_func: this._functionCeil, _signature: [{types: [TYPE_NUMBER]}]}, + contains: { + _func: this._functionContains, + _signature: [{types: [TYPE_STRING, TYPE_ARRAY]}, + {types: [TYPE_ANY]}]}, + "ends_with": { + _func: this._functionEndsWith, + _signature: [{types: [TYPE_STRING]}, {types: [TYPE_STRING]}]}, + floor: {_func: this._functionFloor, _signature: [{types: [TYPE_NUMBER]}]}, + length: { + _func: this._functionLength, + _signature: [{types: [TYPE_STRING, TYPE_ARRAY, TYPE_OBJECT]}]}, + map: { + _func: this._functionMap, + _signature: [{types: [TYPE_EXPREF]}, {types: [TYPE_ARRAY]}]}, + max: { + _func: this._functionMax, + _signature: [{types: [TYPE_ARRAY_NUMBER, TYPE_ARRAY_STRING]}]}, + "merge": { + _func: this._functionMerge, + _signature: [{types: [TYPE_OBJECT], variadic: true}] + }, + "max_by": { + _func: this._functionMaxBy, + _signature: [{types: [TYPE_ARRAY]}, {types: [TYPE_EXPREF]}] + }, + sum: {_func: this._functionSum, _signature: [{types: [TYPE_ARRAY_NUMBER]}]}, + "starts_with": { + _func: this._functionStartsWith, + _signature: [{types: [TYPE_STRING]}, {types: [TYPE_STRING]}]}, + min: { + _func: this._functionMin, + _signature: [{types: [TYPE_ARRAY_NUMBER, TYPE_ARRAY_STRING]}]}, + "min_by": { + _func: this._functionMinBy, + _signature: [{types: [TYPE_ARRAY]}, {types: [TYPE_EXPREF]}] + }, + type: {_func: this._functionType, _signature: [{types: [TYPE_ANY]}]}, + keys: {_func: this._functionKeys, _signature: [{types: [TYPE_OBJECT]}]}, + values: {_func: this._functionValues, _signature: [{types: [TYPE_OBJECT]}]}, + sort: {_func: this._functionSort, _signature: [{types: [TYPE_ARRAY_STRING, TYPE_ARRAY_NUMBER]}]}, + "sort_by": { + _func: this._functionSortBy, + _signature: [{types: [TYPE_ARRAY]}, {types: [TYPE_EXPREF]}] + }, + join: { + _func: this._functionJoin, + _signature: [ + {types: [TYPE_STRING]}, + {types: [TYPE_ARRAY_STRING]} + ] + }, + reverse: { + _func: this._functionReverse, + _signature: [{types: [TYPE_STRING, TYPE_ARRAY]}]}, + "to_array": {_func: this._functionToArray, _signature: [{types: [TYPE_ANY]}]}, + "to_string": {_func: this._functionToString, _signature: [{types: [TYPE_ANY]}]}, + "to_number": {_func: this._functionToNumber, _signature: [{types: [TYPE_ANY]}]}, + "not_null": { + _func: this._functionNotNull, + _signature: [{types: [TYPE_ANY], variadic: true}] + } + }; + } + + Runtime.prototype = { + callFunction: function(name, resolvedArgs) { + var functionEntry = this.functionTable[name]; + if (functionEntry === undefined) { + throw new Error("Unknown function: " + name + "()"); + } + this._validateArgs(name, resolvedArgs, functionEntry._signature); + return functionEntry._func.call(this, resolvedArgs); + }, + + _validateArgs: function(name, args, signature) { + // Validating the args requires validating + // the correct arity and the correct type of each arg. + // If the last argument is declared as variadic, then we need + // a minimum number of args to be required. Otherwise it has to + // be an exact amount. + var pluralized; + if (signature[signature.length - 1].variadic) { + if (args.length < signature.length) { + pluralized = signature.length === 1 ? " argument" : " arguments"; + throw new Error("ArgumentError: " + name + "() " + + "takes at least" + signature.length + pluralized + + " but received " + args.length); + } + } else if (args.length !== signature.length) { + pluralized = signature.length === 1 ? " argument" : " arguments"; + throw new Error("ArgumentError: " + name + "() " + + "takes " + signature.length + pluralized + + " but received " + args.length); + } + var currentSpec; + var actualType; + var typeMatched; + for (var i = 0; i < signature.length; i++) { + typeMatched = false; + currentSpec = signature[i].types; + actualType = this._getTypeName(args[i]); + for (var j = 0; j < currentSpec.length; j++) { + if (this._typeMatches(actualType, currentSpec[j], args[i])) { + typeMatched = true; + break; + } + } + if (!typeMatched) { + throw new Error("TypeError: " + name + "() " + + "expected argument " + (i + 1) + + " to be type " + currentSpec + + " but received type " + actualType + + " instead."); + } + } + }, + + _typeMatches: function(actual, expected, argValue) { + if (expected === TYPE_ANY) { + return true; + } + if (expected === TYPE_ARRAY_STRING || + expected === TYPE_ARRAY_NUMBER || + expected === TYPE_ARRAY) { + // The expected type can either just be array, + // or it can require a specific subtype (array of numbers). + // + // The simplest case is if "array" with no subtype is specified. + if (expected === TYPE_ARRAY) { + return actual === TYPE_ARRAY; + } else if (actual === TYPE_ARRAY) { + // Otherwise we need to check subtypes. + // I think this has potential to be improved. + var subtype; + if (expected === TYPE_ARRAY_NUMBER) { + subtype = TYPE_NUMBER; + } else if (expected === TYPE_ARRAY_STRING) { + subtype = TYPE_STRING; + } + for (var i = 0; i < argValue.length; i++) { + if (!this._typeMatches( + this._getTypeName(argValue[i]), subtype, + argValue[i])) { + return false; + } + } + return true; + } + } else { + return actual === expected; + } + }, + _getTypeName: function(obj) { + switch (Object.prototype.toString.call(obj)) { + case "[object String]": + return TYPE_STRING; + case "[object Number]": + return TYPE_NUMBER; + case "[object Array]": + return TYPE_ARRAY; + case "[object Boolean]": + return TYPE_BOOLEAN; + case "[object Null]": + return TYPE_NULL; + case "[object Object]": + // Check if it's an expref. If it has, it's been + // tagged with a jmespathType attr of 'Expref'; + if (obj.jmespathType === TOK_EXPREF) { + return TYPE_EXPREF; + } else { + return TYPE_OBJECT; + } + } + }, + + _functionStartsWith: function(resolvedArgs) { + return resolvedArgs[0].lastIndexOf(resolvedArgs[1]) === 0; + }, + + _functionEndsWith: function(resolvedArgs) { + var searchStr = resolvedArgs[0]; + var suffix = resolvedArgs[1]; + return searchStr.indexOf(suffix, searchStr.length - suffix.length) !== -1; + }, + + _functionReverse: function(resolvedArgs) { + var typeName = this._getTypeName(resolvedArgs[0]); + if (typeName === TYPE_STRING) { + var originalStr = resolvedArgs[0]; + var reversedStr = ""; + for (var i = originalStr.length - 1; i >= 0; i--) { + reversedStr += originalStr[i]; + } + return reversedStr; + } else { + var reversedArray = resolvedArgs[0].slice(0); + reversedArray.reverse(); + return reversedArray; + } + }, + + _functionAbs: function(resolvedArgs) { + return Math.abs(resolvedArgs[0]); + }, + + _functionCeil: function(resolvedArgs) { + return Math.ceil(resolvedArgs[0]); + }, + + _functionAvg: function(resolvedArgs) { + var sum = 0; + var inputArray = resolvedArgs[0]; + for (var i = 0; i < inputArray.length; i++) { + sum += inputArray[i]; + } + return sum / inputArray.length; + }, + + _functionContains: function(resolvedArgs) { + return resolvedArgs[0].indexOf(resolvedArgs[1]) >= 0; + }, + + _functionFloor: function(resolvedArgs) { + return Math.floor(resolvedArgs[0]); + }, + + _functionLength: function(resolvedArgs) { + if (!isObject(resolvedArgs[0])) { + return resolvedArgs[0].length; + } else { + // As far as I can tell, there's no way to get the length + // of an object without O(n) iteration through the object. + return Object.keys(resolvedArgs[0]).length; + } + }, + + _functionMap: function(resolvedArgs) { + var mapped = []; + var interpreter = this._interpreter; + var exprefNode = resolvedArgs[0]; + var elements = resolvedArgs[1]; + for (var i = 0; i < elements.length; i++) { + mapped.push(interpreter.visit(exprefNode, elements[i])); + } + return mapped; + }, + + _functionMerge: function(resolvedArgs) { + var merged = {}; + for (var i = 0; i < resolvedArgs.length; i++) { + var current = resolvedArgs[i]; + for (var key in current) { + merged[key] = current[key]; + } + } + return merged; + }, + + _functionMax: function(resolvedArgs) { + if (resolvedArgs[0].length > 0) { + var typeName = this._getTypeName(resolvedArgs[0][0]); + if (typeName === TYPE_NUMBER) { + return Math.max.apply(Math, resolvedArgs[0]); + } else { + var elements = resolvedArgs[0]; + var maxElement = elements[0]; + for (var i = 1; i < elements.length; i++) { + if (maxElement.localeCompare(elements[i]) < 0) { + maxElement = elements[i]; + } + } + return maxElement; + } + } else { + return null; + } + }, + + _functionMin: function(resolvedArgs) { + if (resolvedArgs[0].length > 0) { + var typeName = this._getTypeName(resolvedArgs[0][0]); + if (typeName === TYPE_NUMBER) { + return Math.min.apply(Math, resolvedArgs[0]); + } else { + var elements = resolvedArgs[0]; + var minElement = elements[0]; + for (var i = 1; i < elements.length; i++) { + if (elements[i].localeCompare(minElement) < 0) { + minElement = elements[i]; + } + } + return minElement; + } + } else { + return null; + } + }, + + _functionSum: function(resolvedArgs) { + var sum = 0; + var listToSum = resolvedArgs[0]; + for (var i = 0; i < listToSum.length; i++) { + sum += listToSum[i]; + } + return sum; + }, + + _functionType: function(resolvedArgs) { + switch (this._getTypeName(resolvedArgs[0])) { + case TYPE_NUMBER: + return "number"; + case TYPE_STRING: + return "string"; + case TYPE_ARRAY: + return "array"; + case TYPE_OBJECT: + return "object"; + case TYPE_BOOLEAN: + return "boolean"; + case TYPE_EXPREF: + return "expref"; + case TYPE_NULL: + return "null"; + } + }, + + _functionKeys: function(resolvedArgs) { + return Object.keys(resolvedArgs[0]); + }, + + _functionValues: function(resolvedArgs) { + var obj = resolvedArgs[0]; + var keys = Object.keys(obj); + var values = []; + for (var i = 0; i < keys.length; i++) { + values.push(obj[keys[i]]); + } + return values; + }, + + _functionJoin: function(resolvedArgs) { + var joinChar = resolvedArgs[0]; + var listJoin = resolvedArgs[1]; + return listJoin.join(joinChar); + }, + + _functionToArray: function(resolvedArgs) { + if (this._getTypeName(resolvedArgs[0]) === TYPE_ARRAY) { + return resolvedArgs[0]; + } else { + return [resolvedArgs[0]]; + } + }, + + _functionToString: function(resolvedArgs) { + if (this._getTypeName(resolvedArgs[0]) === TYPE_STRING) { + return resolvedArgs[0]; + } else { + return JSON.stringify(resolvedArgs[0]); + } + }, + + _functionToNumber: function(resolvedArgs) { + var typeName = this._getTypeName(resolvedArgs[0]); + var convertedValue; + if (typeName === TYPE_NUMBER) { + return resolvedArgs[0]; + } else if (typeName === TYPE_STRING) { + convertedValue = +resolvedArgs[0]; + if (!isNaN(convertedValue)) { + return convertedValue; + } + } + return null; + }, + + _functionNotNull: function(resolvedArgs) { + for (var i = 0; i < resolvedArgs.length; i++) { + if (this._getTypeName(resolvedArgs[i]) !== TYPE_NULL) { + return resolvedArgs[i]; + } + } + return null; + }, + + _functionSort: function(resolvedArgs) { + var sortedArray = resolvedArgs[0].slice(0); + sortedArray.sort(); + return sortedArray; + }, + + _functionSortBy: function(resolvedArgs) { + var sortedArray = resolvedArgs[0].slice(0); + if (sortedArray.length === 0) { + return sortedArray; + } + var interpreter = this._interpreter; + var exprefNode = resolvedArgs[1]; + var requiredType = this._getTypeName( + interpreter.visit(exprefNode, sortedArray[0])); + if ([TYPE_NUMBER, TYPE_STRING].indexOf(requiredType) < 0) { + throw new Error("TypeError"); + } + var that = this; + // In order to get a stable sort out of an unstable + // sort algorithm, we decorate/sort/undecorate (DSU) + // by creating a new list of [index, element] pairs. + // In the cmp function, if the evaluated elements are + // equal, then the index will be used as the tiebreaker. + // After the decorated list has been sorted, it will be + // undecorated to extract the original elements. + var decorated = []; + for (var i = 0; i < sortedArray.length; i++) { + decorated.push([i, sortedArray[i]]); + } + decorated.sort(function(a, b) { + var exprA = interpreter.visit(exprefNode, a[1]); + var exprB = interpreter.visit(exprefNode, b[1]); + if (that._getTypeName(exprA) !== requiredType) { + throw new Error( + "TypeError: expected " + requiredType + ", received " + + that._getTypeName(exprA)); + } else if (that._getTypeName(exprB) !== requiredType) { + throw new Error( + "TypeError: expected " + requiredType + ", received " + + that._getTypeName(exprB)); + } + if (exprA > exprB) { + return 1; + } else if (exprA < exprB) { + return -1; + } else { + // If they're equal compare the items by their + // order to maintain relative order of equal keys + // (i.e. to get a stable sort). + return a[0] - b[0]; + } + }); + // Undecorate: extract out the original list elements. + for (var j = 0; j < decorated.length; j++) { + sortedArray[j] = decorated[j][1]; + } + return sortedArray; + }, + + _functionMaxBy: function(resolvedArgs) { + var exprefNode = resolvedArgs[1]; + var resolvedArray = resolvedArgs[0]; + var keyFunction = this.createKeyFunction(exprefNode, [TYPE_NUMBER, TYPE_STRING]); + var maxNumber = -Infinity; + var maxRecord; + var current; + for (var i = 0; i < resolvedArray.length; i++) { + current = keyFunction(resolvedArray[i]); + if (current > maxNumber) { + maxNumber = current; + maxRecord = resolvedArray[i]; + } + } + return maxRecord; + }, + + _functionMinBy: function(resolvedArgs) { + var exprefNode = resolvedArgs[1]; + var resolvedArray = resolvedArgs[0]; + var keyFunction = this.createKeyFunction(exprefNode, [TYPE_NUMBER, TYPE_STRING]); + var minNumber = Infinity; + var minRecord; + var current; + for (var i = 0; i < resolvedArray.length; i++) { + current = keyFunction(resolvedArray[i]); + if (current < minNumber) { + minNumber = current; + minRecord = resolvedArray[i]; + } + } + return minRecord; + }, + + createKeyFunction: function(exprefNode, allowedTypes) { + var that = this; + var interpreter = this._interpreter; + var keyFunc = function(x) { + var current = interpreter.visit(exprefNode, x); + if (allowedTypes.indexOf(that._getTypeName(current)) < 0) { + var msg = "TypeError: expected one of " + allowedTypes + + ", received " + that._getTypeName(current); + throw new Error(msg); + } + return current; + }; + return keyFunc; + } + + }; + + function compile(stream) { + var parser = new Parser(); + var ast = parser.parse(stream); + return ast; + } + + function tokenize(stream) { + var lexer = new Lexer(); + return lexer.tokenize(stream); + } + + function search(data, expression) { + var parser = new Parser(); + // This needs to be improved. Both the interpreter and runtime depend on + // each other. The runtime needs the interpreter to support exprefs. + // There's likely a clean way to avoid the cyclic dependency. + var runtime = new Runtime(); + var interpreter = new TreeInterpreter(runtime); + runtime._interpreter = interpreter; + var node = parser.parse(expression); + return interpreter.search(node, data); + } + + exports.tokenize = tokenize; + exports.compile = compile; + exports.search = search; + exports.strictDeepEqual = strictDeepEqual; +})( false ? 0 : exports); + + +/***/ }), + +/***/ 500: +/***/ (function(module) { + +"use strict"; + + +var traverse = module.exports = function (schema, opts, cb) { + // Legacy support for v0.3.1 and earlier. + if (typeof opts == 'function') { + cb = opts; + opts = {}; + } + + cb = opts.cb || cb; + var pre = (typeof cb == 'function') ? cb : cb.pre || function() {}; + var post = cb.post || function() {}; + + _traverse(opts, pre, post, schema, '', schema); +}; + + +traverse.keywords = { + additionalItems: true, + items: true, + contains: true, + additionalProperties: true, + propertyNames: true, + not: true +}; + +traverse.arrayKeywords = { + items: true, + allOf: true, + anyOf: true, + oneOf: true +}; + +traverse.propsKeywords = { + definitions: true, + properties: true, + patternProperties: true, + dependencies: true +}; + +traverse.skipKeywords = { + default: true, + enum: true, + const: true, + required: true, + maximum: true, + minimum: true, + exclusiveMaximum: true, + exclusiveMinimum: true, + multipleOf: true, + maxLength: true, + minLength: true, + pattern: true, + format: true, + maxItems: true, + minItems: true, + uniqueItems: true, + maxProperties: true, + minProperties: true +}; + + +function _traverse(opts, pre, post, schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex) { + if (schema && typeof schema == 'object' && !Array.isArray(schema)) { + pre(schema, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parentSchema, keyIndex); + for (var key in schema) { + var sch = schema[key]; + if (Array.isArray(sch)) { + if (key in traverse.arrayKeywords) { + for (var i=0; i= 0) + data = parseNumber(); + else + unexpectedToken(); + } + map(ptr, 'valueEnd'); + whitespace(); + if (topLevel && pos < source.length) unexpectedToken(); + return data; + } + + function whitespace() { + loop: + while (pos < source.length) { + switch (source[pos]) { + case ' ': column++; break; + case '\t': column += 4; break; + case '\r': column = 0; break; + case '\n': column = 0; line++; break; + default: break loop; + } + pos++; + } + } + + function parseString() { + var str = ''; + var char; + while (true) { + char = getChar(); + if (char == '"') { + break; + } else if (char == '\\') { + char = getChar(); + if (char in escapedChars) + str += escapedChars[char]; + else if (char == 'u') + str += getCharCode(); + else + wasUnexpectedToken(); + } else { + str += char; + } + } + return str; + } + + function parseNumber() { + var numStr = ''; + var integer = true; + if (source[pos] == '-') numStr += getChar(); + + numStr += source[pos] == '0' + ? getChar() + : getDigits(); + + if (source[pos] == '.') { + numStr += getChar() + getDigits(); + integer = false; + } + + if (source[pos] == 'e' || source[pos] == 'E') { + numStr += getChar(); + if (source[pos] == '+' || source[pos] == '-') numStr += getChar(); + numStr += getDigits(); + integer = false; + } + + var result = +numStr; + return bigint && integer && (result > Number.MAX_SAFE_INTEGER || result < Number.MIN_SAFE_INTEGER) + ? BigInt(numStr) + : result; + } + + function parseArray(ptr) { + whitespace(); + var arr = []; + var i = 0; + if (getChar() == ']') return arr; + backChar(); + + while (true) { + var itemPtr = ptr + '/' + i; + arr.push(_parse(itemPtr)); + whitespace(); + var char = getChar(); + if (char == ']') break; + if (char != ',') wasUnexpectedToken(); + whitespace(); + i++; + } + return arr; + } + + function parseObject(ptr) { + whitespace(); + var obj = {}; + if (getChar() == '}') return obj; + backChar(); + + while (true) { + var loc = getLoc(); + if (getChar() != '"') wasUnexpectedToken(); + var key = parseString(); + var propPtr = ptr + '/' + escapeJsonPointer(key); + mapLoc(propPtr, 'key', loc); + map(propPtr, 'keyEnd'); + whitespace(); + if (getChar() != ':') wasUnexpectedToken(); + whitespace(); + obj[key] = _parse(propPtr); + whitespace(); + var char = getChar(); + if (char == '}') break; + if (char != ',') wasUnexpectedToken(); + whitespace(); + } + return obj; + } + + function read(str) { + for (var i=0; i= 'a' && char <= 'f') + code += char.charCodeAt() - A_CODE + 10; + else if (char >= '0' && char <= '9') + code += +char; + else + wasUnexpectedToken(); + } + return String.fromCharCode(code); + } + + function getDigits() { + var digits = ''; + while (source[pos] >= '0' && source[pos] <= '9') + digits += getChar(); + + if (digits.length) return digits; + checkUnexpectedEnd(); + unexpectedToken(); + } + + function map(ptr, prop) { + mapLoc(ptr, prop, getLoc()); + } + + function mapLoc(ptr, prop, loc) { + pointers[ptr] = pointers[ptr] || {}; + pointers[ptr][prop] = loc; + } + + function getLoc() { + return { + line: line, + column: column, + pos: pos + }; + } + + function unexpectedToken() { + throw new SyntaxError('Unexpected token ' + source[pos] + ' in JSON at position ' + pos); + } + + function wasUnexpectedToken() { + backChar(); + unexpectedToken(); + } + + function checkUnexpectedEnd() { + if (pos >= source.length) + throw new SyntaxError('Unexpected end of JSON input'); + } +}; + + +__webpack_unused_export__ = function (data, _, options) { + if (!validType(data)) return; + var wsLine = 0; + var wsPos, wsColumn; + var whitespace = typeof options == 'object' + ? options.space + : options; + switch (typeof whitespace) { + case 'number': + var len = whitespace > 10 + ? 10 + : whitespace < 0 + ? 0 + : Math.floor(whitespace); + whitespace = len && repeat(len, ' '); + wsPos = len; + wsColumn = len; + break; + case 'string': + whitespace = whitespace.slice(0, 10); + wsPos = 0; + wsColumn = 0; + for (var j=0; j= 0; +} + + +var ESC_QUOTE = /"|\\/g; +var ESC_B = /[\b]/g; +var ESC_F = /\f/g; +var ESC_N = /\n/g; +var ESC_R = /\r/g; +var ESC_T = /\t/g; +function quoted(str) { + str = str.replace(ESC_QUOTE, '\\$&') + .replace(ESC_F, '\\f') + .replace(ESC_B, '\\b') + .replace(ESC_N, '\\n') + .replace(ESC_R, '\\r') + .replace(ESC_T, '\\t'); + return '"' + str + '"'; +} + + +var ESC_0 = /~/g; +var ESC_1 = /\//g; +function escapeJsonPointer(str) { + return str.replace(ESC_0, '~0') + .replace(ESC_1, '~1'); +} + + +/***/ }), + +/***/ 5755: +/***/ (function(__unused_webpack_module, exports) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.default = JsonRepairError; + +function JsonRepairError(message, char) { + if (!(this instanceof JsonRepairError)) { + throw new SyntaxError('Constructor must be called with the new operator'); + } + + this.message = message + ' (char ' + char + ')'; + this.char = char; + this.stack = new Error().stack; +} + +JsonRepairError.prototype = new Error(); +JsonRepairError.prototype.constructor = Error; + + +/***/ }), + +/***/ 8909: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +module.exports = __webpack_require__(8107).default + + +/***/ }), + +/***/ 8107: +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + +"use strict"; +var __webpack_unused_export__; + + +__webpack_unused_export__ = ({ + value: true +}); +exports.default = jsonrepair; + +var _JsonRepairError = _interopRequireDefault(__webpack_require__(5755)); + +var _stringUtils = __webpack_require__(1536); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// token types enumeration +var DELIMITER = 0; +var NUMBER = 1; +var STRING = 2; +var SYMBOL = 3; +var WHITESPACE = 4; +var COMMENT = 5; +var UNKNOWN = 6; +/** + * @typedef {DELIMITER | NUMBER | STRING | SYMBOL | WHITESPACE | COMMENT | UNKNOWN} TokenType + */ +// map with all delimiters + +var DELIMITERS = { + '': true, + '{': true, + '}': true, + '[': true, + ']': true, + ':': true, + ',': true, + // for JSONP and MongoDB data type notation + '(': true, + ')': true, + ';': true, + // for string concatenation + '+': true +}; // map with all escape characters + +var ESCAPE_CHARACTERS = { + '"': '"', + '\\': '\\', + '/': '/', + b: '\b', + f: '\f', + n: '\n', + r: '\r', + t: '\t' // \u is handled by getToken() + +}; // TODO: can we unify CONTROL_CHARACTERS and ESCAPE_CHARACTERS? + +var CONTROL_CHARACTERS = { + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t' +}; +var SYMBOLS = { + null: 'null', + true: 'true', + false: 'false' +}; +var PYTHON_SYMBOLS = { + None: 'null', + True: 'true', + False: 'false' +}; +var input = ''; // current json text + +var output = ''; // generated output + +var index = 0; // current index in text + +var c = ''; // current token character in text + +var token = ''; // current token + +var tokenType = UNKNOWN; // type of current token + +/** + * Repair a string containing an invalid JSON document. + * For example changes JavaScript notation into JSON notation. + * + * Example: + * + * jsonrepair('{name: \'John\'}") // '{"name": "John"}' + * + * @param {string} text + * @return {string} + */ + +function jsonrepair(text) { + // initialize + input = text; + output = ''; + index = 0; + c = input.charAt(0); + token = ''; + tokenType = UNKNOWN; // get first token + + processNextToken(); + var isRootLevelObject = tokenType === DELIMITER && token === '{'; // parse everything + + parseObject(); + + if (token === '') { + // reached the end of the document properly + return output; + } + + if (isRootLevelObject && tokenIsStartOfValue()) { + // start of a new value after end of the root level object: looks like + // newline delimited JSON -> turn into a root level array + while (tokenIsStartOfValue()) { + output = (0, _stringUtils.insertBeforeLastWhitespace)(output, ','); // parse next newline delimited item + + parseObject(); + } // wrap the output in an array + + + return "[\n".concat(output, "\n]"); + } + + throw new _JsonRepairError.default('Unexpected characters', index - token.length); +} +/** + * Get the next character from the expression. + * The character is stored into the char c. If the end of the expression is + * reached, the function puts an empty string in c. + */ + + +function next() { + index++; + c = input.charAt(index); // Note: not using input[index] because that returns undefined when index is out of range +} +/** + * check whether the current token is the start of a value: + * object, array, number, string, or symbol + * @returns {boolean} + */ + + +function tokenIsStartOfValue() { + return tokenType === DELIMITER && (token === '[' || token === '{') || tokenType === STRING || tokenType === NUMBER || tokenType === SYMBOL; +} +/** + * check whether the current token is the start of a key (or possible key): + * number, string, or symbol + * @returns {boolean} + */ + + +function tokenIsStartOfKey() { + return tokenType === STRING || tokenType === NUMBER || tokenType === SYMBOL; +} +/** + * Process the previous token, and get next token in the current text + */ + + +function processNextToken() { + output += token; + tokenType = UNKNOWN; + token = ''; + getTokenDelimiter(); + + if (tokenType === WHITESPACE) { + // we leave the whitespace as it is, except replacing special white + // space character + token = (0, _stringUtils.normalizeWhitespace)(token); + processNextToken(); + } + + if (tokenType === COMMENT) { + // ignore comments + tokenType = UNKNOWN; + token = ''; + processNextToken(); + } +} // check for delimiters like ':', '{', ']' + + +function getTokenDelimiter() { + if (DELIMITERS[c]) { + tokenType = DELIMITER; + token = c; + next(); + return; + } + + getTokenNumber(); +} // check for a number like "2.3e+5" + + +function getTokenNumber() { + if ((0, _stringUtils.isDigit)(c) || c === '-') { + tokenType = NUMBER; + + if (c === '-') { + token += c; + next(); + + if (!(0, _stringUtils.isDigit)(c)) { + throw new _JsonRepairError.default('Invalid number, digit expected', index); + } + } else if (c === '0') { + token += c; + next(); + } else {// digit 1-9, nothing extra to do + } + + while ((0, _stringUtils.isDigit)(c)) { + token += c; + next(); + } + + if (c === '.') { + token += c; + next(); + + if (!(0, _stringUtils.isDigit)(c)) { + throw new _JsonRepairError.default('Invalid number, digit expected', index); + } + + while ((0, _stringUtils.isDigit)(c)) { + token += c; + next(); + } + } + + if (c === 'e' || c === 'E') { + token += c; + next(); + + if (c === '+' || c === '-') { + token += c; + next(); + } + + if (!(0, _stringUtils.isDigit)(c)) { + throw new _JsonRepairError.default('Invalid number, digit expected', index); + } + + while ((0, _stringUtils.isDigit)(c)) { + token += c; + next(); + } + } + + return; + } + + getTokenString(); +} // get a token string like '"hello world"' + + +function getTokenString() { + if ((0, _stringUtils.isQuote)(c)) { + var quote = (0, _stringUtils.normalizeQuote)(c); + token += '"'; // output valid double quote + + tokenType = STRING; + next(); + + while (c !== '' && (0, _stringUtils.normalizeQuote)(c) !== quote) { + if (c === '\\') { + // handle escape characters + next(); + var unescaped = ESCAPE_CHARACTERS[c]; + + if (unescaped !== undefined) { + token += '\\' + c; + next(); + } else if (c === 'u') { + // parse escaped unicode character, like '\\u260E' + token += "\\u"; + next(); + + for (var u = 0; u < 4; u++) { + if (!(0, _stringUtils.isHex)(c)) { + throw new _JsonRepairError.default('Invalid unicode character', index - token.length); + } + + token += c; + next(); + } + } else if (c === '\'') { + // escaped single quote character -> remove the escape character + token += '\''; + next(); + } else { + throw new _JsonRepairError.default('Invalid escape character "\\' + c + '"', index); + } + } else if (CONTROL_CHARACTERS[c]) { + // unescaped special character + // fix by adding an escape character + token += CONTROL_CHARACTERS[c]; + next(); + } else if (c === '"') { + // unescaped double quote -> escape it + token += '\\"'; + next(); + } else { + // a regular character + token += c; + next(); + } + } + + if ((0, _stringUtils.normalizeQuote)(c) !== quote) { + throw new _JsonRepairError.default('End of string expected', index - token.length); + } + + token += '"'; // output valid double quote + + next(); + return; + } + + getTokenAlpha(); +} // check for symbols (true, false, null) + + +function getTokenAlpha() { + if ((0, _stringUtils.isAlpha)(c)) { + tokenType = SYMBOL; + + while ((0, _stringUtils.isAlpha)(c) || (0, _stringUtils.isDigit)(c) || c === '$') { + token += c; + next(); + } + + return; + } + + getTokenWhitespace(); +} // get whitespaces: space, tab, newline, and carriage return + + +function getTokenWhitespace() { + if ((0, _stringUtils.isWhitespace)(c) || (0, _stringUtils.isSpecialWhitespace)(c)) { + tokenType = WHITESPACE; + + while ((0, _stringUtils.isWhitespace)(c) || (0, _stringUtils.isSpecialWhitespace)(c)) { + token += c; + next(); + } + + return; + } + + getTokenComment(); +} + +function getTokenComment() { + // find a block comment '/* ... */' + if (c === '/' && input[index + 1] === '*') { + tokenType = COMMENT; + + while (c !== '' && (c !== '*' || c === '*' && input[index + 1] !== '/')) { + token += c; + next(); + } + + if (c === '*' && input[index + 1] === '/') { + token += c; + next(); + token += c; + next(); + } + + return; + } // find a comment '// ...' + + + if (c === '/' && input[index + 1] === '/') { + tokenType = COMMENT; + + while (c !== '' && c !== '\n') { + token += c; + next(); + } + + return; + } + + getTokenUnknown(); +} // something unknown is found, wrong characters -> a syntax error + + +function getTokenUnknown() { + tokenType = UNKNOWN; + + while (c !== '') { + token += c; + next(); + } + + throw new _JsonRepairError.default('Syntax error in part "' + token + '"', index - token.length); +} +/** + * Parse an object like '{"key": "value"}' + * @return {*} + */ + + +function parseObject() { + if (tokenType === DELIMITER && token === '{') { + processNextToken(); // TODO: can we make this redundant? + + if (tokenType === DELIMITER && token === '}') { + // empty object + processNextToken(); + return; + } + + while (true) { + // parse key + if (tokenType === SYMBOL || tokenType === NUMBER) { + // unquoted key -> add quotes around it, change it into a string + tokenType = STRING; + token = "\"".concat(token, "\""); + } + + if (tokenType !== STRING) { + // TODO: handle ambiguous cases like '[{"a":1,{"b":2}]' which could be an array with two objects or one + throw new _JsonRepairError.default('Object key expected', index - token.length); + } + + processNextToken(); // parse colon (key/value separator) + + if (tokenType === DELIMITER && token === ':') { + processNextToken(); + } else { + if (tokenIsStartOfValue()) { + // we expect a colon here, but got the start of a value + // -> insert a colon before any inserted whitespaces at the end of output + output = (0, _stringUtils.insertBeforeLastWhitespace)(output, ':'); + } else { + throw new _JsonRepairError.default('Colon expected', index - token.length); + } + } // parse value + + + parseObject(); // parse comma (key/value pair separator) + + if (tokenType === DELIMITER && token === ',') { + processNextToken(); + + if (tokenType === DELIMITER && token === '}') { + // we've just passed a trailing comma -> remove the trailing comma + output = (0, _stringUtils.stripLastOccurrence)(output, ','); + break; + } + } else { + if (tokenIsStartOfKey()) { + // we expect a comma here, but got the start of a new key + // -> insert a comma before any inserted whitespaces at the end of output + output = (0, _stringUtils.insertBeforeLastWhitespace)(output, ','); + } else { + break; + } + } + } + + if (tokenType === DELIMITER && token === '}') { + processNextToken(); + } else { + // missing end bracket -> insert the missing bracket + output = (0, _stringUtils.insertBeforeLastWhitespace)(output, '}'); + } + + return; + } + + parseArray(); +} +/** + * Parse an object like '["item1", "item2", ...]' + */ + + +function parseArray() { + if (tokenType === DELIMITER && token === '[') { + processNextToken(); + + if (tokenType === DELIMITER && token === ']') { + // empty array + processNextToken(); + return; + } + + while (true) { + // parse item + parseObject(); // parse comma (item separator) + + if (tokenType === DELIMITER && token === ',') { + processNextToken(); + + if (tokenType === DELIMITER && token === ']') { + // we've just passed a trailing comma -> remove the trailing comma + output = (0, _stringUtils.stripLastOccurrence)(output, ','); + break; + } + } else { + if (tokenIsStartOfValue()) { + // we expect a comma here, but got the start of a new item + // -> insert a comma before any inserted whitespaces at the end of output + output = (0, _stringUtils.insertBeforeLastWhitespace)(output, ','); + } else { + break; + } + } + } + + if (tokenType === DELIMITER && token === ']') { + processNextToken(); + } else { + // missing end bracket -> insert the missing bracket + output = (0, _stringUtils.insertBeforeLastWhitespace)(output, ']'); + } + + return; + } + + parseString(); +} +/** + * Parse a string enclosed by double quotes "...". Can contain escaped quotes + */ + + +function parseString() { + if (tokenType === STRING) { + processNextToken(); + + while (tokenType === DELIMITER && token === '+') { + // string concatenation like "hello" + "world" + token = ''; // don't output the concatenation + + processNextToken(); + + if (tokenType === STRING) { + // concatenate with the previous string + var endIndex = output.lastIndexOf('"'); + output = output.substring(0, endIndex) + token.substring(1); + token = ''; + processNextToken(); + } + } + + return; + } + + parseNumber(); +} +/** + * Parse a number + */ + + +function parseNumber() { + if (tokenType === NUMBER) { + processNextToken(); + return; + } + + parseSymbol(); +} +/** + * Parse constants true, false, null + */ + + +function parseSymbol() { + if (tokenType === SYMBOL) { + // a supported symbol: true, false, null + if (SYMBOLS[token]) { + processNextToken(); + return; + } // for example replace None with null + + + if (PYTHON_SYMBOLS[token]) { + token = PYTHON_SYMBOLS[token]; + processNextToken(); + return; + } // make a copy of the symbol, let's see what comes next + + + var symbol = token; + var symbolIndex = output.length; + token = ''; + processNextToken(); // if (tokenType === DELIMITER && token === '(') { + + if (tokenType === DELIMITER && token === '(') { + // a MongoDB function call or JSONP call + // Can be a MongoDB data type like in {"_id": ObjectId("123")} + // token = '' // do not output the function name + // processNextToken() + // next() + token = ''; // do not output the ( character + + processNextToken(); // process the part inside the brackets + + parseObject(); // skip the closing bracket ")" and ");" + + if (tokenType === DELIMITER && token === ')') { + token = ''; // do not output the ) character + + processNextToken(); + + if (tokenType === DELIMITER && token === ';') { + token = ''; // do not output the semicolon character + + processNextToken(); + } + } + + return; + } // unknown symbol => turn into in a string + // it is possible that by reading the next token we already inserted + // extra spaces in the output which should be inside the string, + // hence the symbolIndex + + + output = (0, _stringUtils.insertAtIndex)(output, "\"".concat(symbol), symbolIndex); + + while (tokenType === SYMBOL || tokenType === NUMBER) { + processNextToken(); + } + + output += '"'; + return; + } + + parseEnd(); +} +/** + * Evaluated when the expression is not yet ended but expected to end + */ + + +function parseEnd() { + if (token === '') { + // syntax error or unexpected end of expression + throw new _JsonRepairError.default('Unexpected end of json string', index - token.length); + } else { + throw new _JsonRepairError.default('Value expected', index - token.length); + } +} + + +/***/ }), + +/***/ 1536: +/***/ (function(__unused_webpack_module, exports) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.isAlpha = isAlpha; +exports.isHex = isHex; +exports.isDigit = isDigit; +exports.isWhitespace = isWhitespace; +exports.isSpecialWhitespace = isSpecialWhitespace; +exports.normalizeWhitespace = normalizeWhitespace; +exports.isQuote = isQuote; +exports.normalizeQuote = normalizeQuote; +exports.stripLastOccurrence = stripLastOccurrence; +exports.insertBeforeLastWhitespace = insertBeforeLastWhitespace; +exports.insertAtIndex = insertAtIndex; +var SINGLE_QUOTES = ['\'', // quote +"\u2018", // quote left +"\u2019", // quote right +"`", // grave accent +"\xB4" // acute accent +]; +var DOUBLE_QUOTES = ['"', "\u201C", // double quote left +"\u201D" // double quote right +]; +/** + * Check if the given character contains an alpha character, a-z, A-Z, _ + * @param {string} c + * @return {boolean} + */ + +function isAlpha(c) { + return /^[a-zA-Z_]$/.test(c); +} +/** + * Check if the given character contains a hexadecimal character 0-9, a-f, A-F + * @param {string} c + * @return {boolean} + */ + + +function isHex(c) { + return /^[0-9a-fA-F]$/.test(c); +} +/** + * checks if the given char c is a digit + * @param {string} c + * @return {boolean} + */ + + +function isDigit(c) { + return c >= '0' && c <= '9'; +} +/** + * Check if the given character is a whitespace character like space, tab, or + * newline + * @param {string} c + * @return {boolean} + */ + + +function isWhitespace(c) { + return c === ' ' || c === '\t' || c === '\n' || c === '\r'; +} +/** + * Check if the given character is a special whitespace character, some + * unicode variant + * @param {string} c + * @return {boolean} + */ + + +function isSpecialWhitespace(c) { + return c === "\xA0" || c >= "\u2000" && c <= "\u200A" || c === "\u202F" || c === "\u205F" || c === "\u3000"; +} +/** + * Replace speical whitespace characters with regular spaces + * @param {string} text + * @returns {string} + */ + + +function normalizeWhitespace(text) { + var normalized = ''; + + for (var i = 0; i < text.length; i++) { + var char = text[i]; + normalized += isSpecialWhitespace(char) ? ' ' : char; + } + + return normalized; +} +/** + * Test whether the given character is a quote or double quote character. + * Also tests for special variants of quotes. + * @param {string} c + * @returns {boolean} + */ + + +function isQuote(c) { + return SINGLE_QUOTES.includes(c) || DOUBLE_QUOTES.includes(c); +} +/** + * Normalize special double or single quote characters to their regular + * variant ' or " + * @param {string} c + * @returns {string} + */ + + +function normalizeQuote(c) { + if (SINGLE_QUOTES.includes(c)) { + return '\''; + } + + if (DOUBLE_QUOTES.includes(c)) { + return '"'; + } + + return c; +} +/** + * Strip last occurrence of textToStrip from text + * @param {string} text + * @param {string} textToStrip + * @returns {string} + */ + + +function stripLastOccurrence(text, textToStrip) { + var index = text.lastIndexOf(textToStrip); + return index !== -1 ? text.substring(0, index) + text.substring(index + 1) : text; +} +/** + * Insert textToInsert into text before the last whitespace in text + * @param {string} text + * @param {string} textToInsert + * @returns {string} + */ + + +function insertBeforeLastWhitespace(text, textToInsert) { + return text.replace(/\s*$/, function (match) { + return textToInsert + match; + }); +} +/** + * Insert textToInsert at index in text + * @param {string} text + * @param {string} textToInsert + * @param {number} index + * @returns {string} + */ + + +function insertAtIndex(text, textToInsert, index) { + return text.substring(0, index) + textToInsert + text.substring(index); +} + + +/***/ }), + +/***/ 483: +/***/ (function(module, exports) { + +var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/** + * 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 (root, factory) { + "use strict"; + + if (true) { + !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), + __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? + (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + } + else {} +}(this, function () { + + /** + * A self-contained modal library + */ + "use strict"; + + /** Returns whether a value is a dom node */ + function isNode(value) { + if ( typeof Node === "object" ) { + return value instanceof Node; + } + else { + return value && typeof value === "object" && typeof value.nodeType === "number"; + } + } + + /** Returns whether a value is a string */ + function isString(value) { + return typeof value === "string"; + } + + /** + * Generates observable objects that can be watched and triggered + */ + function observable() { + var callbacks = []; + return { + watch: callbacks.push.bind(callbacks), + trigger: function(context, detail) { + + var unprevented = true; + var event = { + detail: detail, + preventDefault: function preventDefault () { + unprevented = false; + } + }; + + for (var i = 0; i < callbacks.length; i++) { + callbacks[i](context, event); + } + + return unprevented; + } + }; + } + + + /** Whether an element is hidden */ + function isHidden ( elem ) { + // @see http://stackoverflow.com/questions/19669786 + return window.getComputedStyle(elem).display === 'none'; + } + + + /** + * A small interface for creating and managing a dom element + */ + function Elem( elem ) { + this.elem = elem; + } + + /** Creates a new div */ + Elem.make = function ( parent, tag ) { + if ( typeof parent === "string" ) { + parent = document.querySelector(parent); + } + var elem = document.createElement(tag || 'div'); + (parent || document.body).appendChild(elem); + return new Elem(elem); + }; + + Elem.prototype = { + + /** Creates a child of this node */ + child: function (tag) { + return Elem.make(this.elem, tag); + }, + + /** Applies a set of styles to an element */ + stylize: function(styles) { + styles = styles || {}; + + if ( typeof styles.opacity !== "undefined" ) { + styles.filter = "alpha(opacity=" + (styles.opacity * 100) + ")"; + } + + for (var prop in styles) { + if (styles.hasOwnProperty(prop)) { + this.elem.style[prop] = styles[prop]; + } + } + + return this; + }, + + /** Adds a class name */ + clazz: function (clazz) { + this.elem.className += " " + clazz; + return this; + }, + + /** Sets the HTML */ + html: function (content) { + if ( isNode(content) ) { + this.elem.appendChild( content ); + } + else { + this.elem.innerHTML = content; + } + return this; + }, + + /** Adds a click handler to this element */ + onClick: function(callback) { + this.elem.addEventListener('click', callback); + return this; + }, + + /** Removes this element from the DOM */ + destroy: function() { + this.elem.parentNode.removeChild(this.elem); + }, + + /** Hides this element */ + hide: function() { + this.elem.style.display = "none"; + }, + + /** Shows this element */ + show: function() { + this.elem.style.display = "block"; + }, + + /** Sets an attribute on this element */ + attr: function ( name, value ) { + if (value !== undefined) { + this.elem.setAttribute(name, value); + } + return this; + }, + + /** Executes a callback on all the ancestors of an element */ + anyAncestor: function ( predicate ) { + var elem = this.elem; + while ( elem ) { + if ( predicate( new Elem(elem) ) ) { + return true; + } + else { + elem = elem.parentNode; + } + } + return false; + }, + + /** Whether this element is visible */ + isVisible: function () { + return !isHidden(this.elem); + } + }; + + + /** Generates the grey-out effect */ + function buildOverlay( getOption, close ) { + return Elem.make( getOption("parent") ) + .clazz("pico-overlay") + .clazz( getOption("overlayClass", "") ) + .stylize({ + display: "none", + position: "fixed", + top: "0px", + left: "0px", + height: "100%", + width: "100%", + zIndex: 10000 + }) + .stylize(getOption('overlayStyles', { + opacity: 0.5, + background: "#000" + })) + .onClick(function () { + if ( getOption('overlayClose', true) ) { + close(); + } + }); + } + + // An auto incrementing ID assigned to each modal + var autoinc = 1; + + /** Builds the content of a modal */ + function buildModal( getOption, close ) { + var width = getOption('width', 'auto'); + if ( typeof width === "number" ) { + width = "" + width + "px"; + } + + var id = getOption("modalId", "pico-" + autoinc++); + + var elem = Elem.make( getOption("parent") ) + .clazz("pico-content") + .clazz( getOption("modalClass", "") ) + .stylize({ + display: 'none', + position: 'fixed', + zIndex: 10001, + left: "50%", + top: "38.1966%", + maxHeight: '90%', + boxSizing: 'border-box', + width: width, + '-ms-transform': 'translate(-50%,-38.1966%)', + '-moz-transform': 'translate(-50%,-38.1966%)', + '-webkit-transform': 'translate(-50%,-38.1966%)', + '-o-transform': 'translate(-50%,-38.1966%)', + transform: 'translate(-50%,-38.1966%)' + }) + .stylize(getOption('modalStyles', { + overflow: 'auto', + backgroundColor: "white", + padding: "20px", + borderRadius: "5px" + })) + .html( getOption('content') ) + .attr("id", id) + .attr("role", "dialog") + .attr("aria-labelledby", getOption("ariaLabelledBy")) + .attr("aria-describedby", getOption("ariaDescribedBy", id)) + .onClick(function (event) { + var isCloseClick = new Elem(event.target).anyAncestor(function (elem) { + return /\bpico-close\b/.test(elem.elem.className); + }); + if ( isCloseClick ) { + close(); + } + }); + + return elem; + } + + /** Builds the close button */ + function buildClose ( elem, getOption ) { + if ( getOption('closeButton', true) ) { + return elem.child('button') + .html( getOption('closeHtml', "×") ) + .clazz("pico-close") + .clazz( getOption("closeClass", "") ) + .stylize( getOption('closeStyles', { + borderRadius: "2px", + border: 0, + padding: 0, + cursor: "pointer", + height: "15px", + width: "15px", + position: "absolute", + top: "5px", + right: "5px", + fontSize: "16px", + textAlign: "center", + lineHeight: "15px", + background: "#CCC" + }) ) + .attr("aria-label", getOption("close-label", "Close")); + } + } + + /** Builds a method that calls a method and returns an element */ + function buildElemAccessor( builder ) { + return function () { + return builder().elem; + }; + } + + + // An observable that is triggered whenever the escape key is pressed + var escapeKey = observable(); + + // An observable that is triggered when the user hits the tab key + var tabKey = observable(); + + /** A global event handler to detect the escape key being pressed */ + document.documentElement.addEventListener('keydown', function onKeyPress (event) { + var keycode = event.which || event.keyCode; + + // If this is the escape key + if ( keycode === 27 ) { + escapeKey.trigger(); + } + + // If this is the tab key + else if ( keycode === 9 ) { + tabKey.trigger(event); + } + }); + + + /** Attaches focus management events */ + function manageFocus ( iface, isEnabled ) { + + /** Whether an element matches a selector */ + function matches ( elem, selector ) { + var fn = elem.msMatchesSelector || elem.webkitMatchesSelector || elem.matches; + return fn.call(elem, selector); + } + + /** + * Returns whether an element is focusable + * @see http://stackoverflow.com/questions/18261595 + */ + function canFocus( elem ) { + if ( + isHidden(elem) || + matches(elem, ":disabled") || + elem.hasAttribute("contenteditable") + ) { + return false; + } + else { + return elem.hasAttribute("tabindex") || + matches(elem, "input,select,textarea,button,a[href],area[href],iframe"); + } + } + + /** Returns the first descendant that can be focused */ + function firstFocusable ( elem ) { + var items = elem.getElementsByTagName("*"); + for (var i = 0; i < items.length; i++) { + if ( canFocus(items[i]) ) { + return items[i]; + } + } + } + + /** Returns the last descendant that can be focused */ + function lastFocusable ( elem ) { + var items = elem.getElementsByTagName("*"); + for (var i = items.length; i--;) { + if ( canFocus(items[i]) ) { + return items[i]; + } + } + } + + // The element focused before the modal opens + var focused; + + // Records the currently focused element so state can be returned + // after the modal closes + iface.beforeShow(function getActiveFocus() { + focused = document.activeElement; + }); + + // Shift focus into the modal + iface.afterShow(function focusModal() { + if ( isEnabled() ) { + var focusable = firstFocusable(iface.modalElem()); + if ( focusable ) { + focusable.focus(); + } + } + }); + + // Restore the previously focused element when the modal closes + iface.afterClose(function returnFocus() { + if ( isEnabled() && focused ) { + focused.focus(); + } + focused = null; + }); + + // Capture tab key presses and loop them within the modal + tabKey.watch(function tabKeyPress (event) { + if ( isEnabled() && iface.isVisible() ) { + var first = firstFocusable(iface.modalElem()); + var last = lastFocusable(iface.modalElem()); + + var from = event.shiftKey ? first : last; + if ( from === document.activeElement ) { + (event.shiftKey ? last : first).focus(); + event.preventDefault(); + } + } + }); + } + + /** Manages setting the 'overflow: hidden' on the body tag */ + function manageBodyOverflow(iface, isEnabled) { + var origOverflow; + var body = new Elem(document.body); + + iface.beforeShow(function () { + // Capture the current values so they can be restored + origOverflow = body.elem.style.overflow; + + if (isEnabled()) { + body.stylize({ overflow: "hidden" }); + } + }); + + iface.afterClose(function () { + body.stylize({ overflow: origOverflow }); + }); + } + + /** + * Displays a modal + */ + return function picoModal(options) { + + if ( isString(options) || isNode(options) ) { + options = { content: options }; + } + + var afterCreateEvent = observable(); + var beforeShowEvent = observable(); + var afterShowEvent = observable(); + var beforeCloseEvent = observable(); + var afterCloseEvent = observable(); + + /** + * Returns a named option if it has been explicitly defined. Otherwise, + * it returns the given default value + */ + function getOption ( opt, defaultValue ) { + var value = options[opt]; + if ( typeof value === "function" ) { + value = value( defaultValue ); + } + return value === undefined ? defaultValue : value; + } + + + // The various DOM elements that constitute the modal + var modalElem = build.bind(window, 'modal'); + var shadowElem = build.bind(window, 'overlay'); + var closeElem = build.bind(window, 'close'); + + // This will eventually contain the modal API returned to the user + var iface; + + + /** Hides this modal */ + function forceClose (detail) { + shadowElem().hide(); + modalElem().hide(); + afterCloseEvent.trigger(iface, detail); + } + + /** Gracefully hides this modal */ + function close (detail) { + if ( beforeCloseEvent.trigger(iface, detail) ) { + forceClose(detail); + } + } + + /** Wraps a method so it returns the modal interface */ + function returnIface ( callback ) { + return function () { + callback.apply(this, arguments); + return iface; + }; + } + + + // The constructed dom nodes + var built; + + /** Builds a method that calls a method and returns an element */ + function build (name, detail) { + if ( !built ) { + var modal = buildModal(getOption, close); + built = { + modal: modal, + overlay: buildOverlay(getOption, close), + close: buildClose(modal, getOption) + }; + afterCreateEvent.trigger(iface, detail); + } + return built[name]; + } + + iface = { + + /** Returns the wrapping modal element */ + modalElem: buildElemAccessor(modalElem), + + /** Returns the close button element */ + closeElem: buildElemAccessor(closeElem), + + /** Returns the overlay element */ + overlayElem: buildElemAccessor(shadowElem), + + /** Builds the dom without showing the modal */ + buildDom: returnIface(build.bind(null, null)), + + /** Returns whether this modal is currently being shown */ + isVisible: function () { + return !!(built && modalElem && modalElem().isVisible()); + }, + + /** Shows this modal */ + show: function (detail) { + if ( beforeShowEvent.trigger(iface, detail) ) { + shadowElem().show(); + closeElem(); + modalElem().show(); + afterShowEvent.trigger(iface, detail); + } + return this; + }, + + /** Hides this modal */ + close: returnIface(close), + + /** + * Force closes this modal. This will not call beforeClose + * events and will just immediately hide the modal + */ + forceClose: returnIface(forceClose), + + /** Destroys this modal */ + destroy: function () { + modalElem().destroy(); + shadowElem().destroy(); + shadowElem = modalElem = closeElem = undefined; + }, + + /** + * Updates the options for this modal. This will only let you + * change options that are re-evaluted regularly, such as + * `overlayClose`. + */ + options: function ( opts ) { + Object.keys(opts).map(function (key) { + options[key] = opts[key]; + }); + }, + + /** Executes after the DOM nodes are created */ + afterCreate: returnIface(afterCreateEvent.watch), + + /** Executes a callback before this modal is closed */ + beforeShow: returnIface(beforeShowEvent.watch), + + /** Executes a callback after this modal is shown */ + afterShow: returnIface(afterShowEvent.watch), + + /** Executes a callback before this modal is closed */ + beforeClose: returnIface(beforeCloseEvent.watch), + + /** Executes a callback after this modal is closed */ + afterClose: returnIface(afterCloseEvent.watch) + }; + + manageFocus(iface, getOption.bind(null, "focus", true)); + + manageBodyOverflow(iface, getOption.bind(null, "bodyOverflow", true)); + + // If a user presses the 'escape' key, close the modal. + escapeKey.watch(function escapeKeyPress () { + if ( getOption("escCloses", true) && iface.isVisible() ) { + iface.close(); + } + }); + + return iface; + }; + +})); + + +/***/ }), + +/***/ 7533: +/***/ (function(__unused_webpack_module, exports) { + +/** @license URI.js v4.4.0 (c) 2011 Gary Court. License: http://github.com/garycourt/uri-js */ +(function (global, factory) { + true ? factory(exports) : + 0; +}(this, (function (exports) { 'use strict'; + +function merge() { + for (var _len = arguments.length, sets = Array(_len), _key = 0; _key < _len; _key++) { + sets[_key] = arguments[_key]; + } + + if (sets.length > 1) { + sets[0] = sets[0].slice(0, -1); + var xl = sets.length - 1; + for (var x = 1; x < xl; ++x) { + sets[x] = sets[x].slice(1, -1); + } + sets[xl] = sets[xl].slice(1); + return sets.join(''); + } else { + return sets[0]; + } +} +function subexp(str) { + return "(?:" + str + ")"; +} +function typeOf(o) { + return o === undefined ? "undefined" : o === null ? "null" : Object.prototype.toString.call(o).split(" ").pop().split("]").shift().toLowerCase(); +} +function toUpperCase(str) { + return str.toUpperCase(); +} +function toArray(obj) { + return obj !== undefined && obj !== null ? obj instanceof Array ? obj : typeof obj.length !== "number" || obj.split || obj.setInterval || obj.call ? [obj] : Array.prototype.slice.call(obj) : []; +} +function assign(target, source) { + var obj = target; + if (source) { + for (var key in source) { + obj[key] = source[key]; + } + } + return obj; +} + +function buildExps(isIRI) { + var ALPHA$$ = "[A-Za-z]", + CR$ = "[\\x0D]", + DIGIT$$ = "[0-9]", + DQUOTE$$ = "[\\x22]", + HEXDIG$$ = merge(DIGIT$$, "[A-Fa-f]"), + //case-insensitive + LF$$ = "[\\x0A]", + SP$$ = "[\\x20]", + PCT_ENCODED$ = subexp(subexp("%[EFef]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%[89A-Fa-f]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%" + HEXDIG$$ + HEXDIG$$)), + //expanded + GEN_DELIMS$$ = "[\\:\\/\\?\\#\\[\\]\\@]", + SUB_DELIMS$$ = "[\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\=]", + RESERVED$$ = merge(GEN_DELIMS$$, SUB_DELIMS$$), + UCSCHAR$$ = isIRI ? "[\\xA0-\\u200D\\u2010-\\u2029\\u202F-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]" : "[]", + //subset, excludes bidi control characters + IPRIVATE$$ = isIRI ? "[\\uE000-\\uF8FF]" : "[]", + //subset + UNRESERVED$$ = merge(ALPHA$$, DIGIT$$, "[\\-\\.\\_\\~]", UCSCHAR$$), + SCHEME$ = subexp(ALPHA$$ + merge(ALPHA$$, DIGIT$$, "[\\+\\-\\.]") + "*"), + USERINFO$ = subexp(subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\:]")) + "*"), + DEC_OCTET$ = subexp(subexp("25[0-5]") + "|" + subexp("2[0-4]" + DIGIT$$) + "|" + subexp("1" + DIGIT$$ + DIGIT$$) + "|" + subexp("[1-9]" + DIGIT$$) + "|" + DIGIT$$), + DEC_OCTET_RELAXED$ = subexp(subexp("25[0-5]") + "|" + subexp("2[0-4]" + DIGIT$$) + "|" + subexp("1" + DIGIT$$ + DIGIT$$) + "|" + subexp("0?[1-9]" + DIGIT$$) + "|0?0?" + DIGIT$$), + //relaxed parsing rules + IPV4ADDRESS$ = subexp(DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$ + "\\." + DEC_OCTET_RELAXED$), + H16$ = subexp(HEXDIG$$ + "{1,4}"), + LS32$ = subexp(subexp(H16$ + "\\:" + H16$) + "|" + IPV4ADDRESS$), + IPV6ADDRESS1$ = subexp(subexp(H16$ + "\\:") + "{6}" + LS32$), + // 6( h16 ":" ) ls32 + IPV6ADDRESS2$ = subexp("\\:\\:" + subexp(H16$ + "\\:") + "{5}" + LS32$), + // "::" 5( h16 ":" ) ls32 + IPV6ADDRESS3$ = subexp(subexp(H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{4}" + LS32$), + //[ h16 ] "::" 4( h16 ":" ) ls32 + IPV6ADDRESS4$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,1}" + H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{3}" + LS32$), + //[ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 + IPV6ADDRESS5$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,2}" + H16$) + "?\\:\\:" + subexp(H16$ + "\\:") + "{2}" + LS32$), + //[ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 + IPV6ADDRESS6$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,3}" + H16$) + "?\\:\\:" + H16$ + "\\:" + LS32$), + //[ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 + IPV6ADDRESS7$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,4}" + H16$) + "?\\:\\:" + LS32$), + //[ *4( h16 ":" ) h16 ] "::" ls32 + IPV6ADDRESS8$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,5}" + H16$) + "?\\:\\:" + H16$), + //[ *5( h16 ":" ) h16 ] "::" h16 + IPV6ADDRESS9$ = subexp(subexp(subexp(H16$ + "\\:") + "{0,6}" + H16$) + "?\\:\\:"), + //[ *6( h16 ":" ) h16 ] "::" + IPV6ADDRESS$ = subexp([IPV6ADDRESS1$, IPV6ADDRESS2$, IPV6ADDRESS3$, IPV6ADDRESS4$, IPV6ADDRESS5$, IPV6ADDRESS6$, IPV6ADDRESS7$, IPV6ADDRESS8$, IPV6ADDRESS9$].join("|")), + ZONEID$ = subexp(subexp(UNRESERVED$$ + "|" + PCT_ENCODED$) + "+"), + //RFC 6874 + IPV6ADDRZ$ = subexp(IPV6ADDRESS$ + "\\%25" + ZONEID$), + //RFC 6874 + IPV6ADDRZ_RELAXED$ = subexp(IPV6ADDRESS$ + subexp("\\%25|\\%(?!" + HEXDIG$$ + "{2})") + ZONEID$), + //RFC 6874, with relaxed parsing rules + IPVFUTURE$ = subexp("[vV]" + HEXDIG$$ + "+\\." + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\:]") + "+"), + IP_LITERAL$ = subexp("\\[" + subexp(IPV6ADDRZ_RELAXED$ + "|" + IPV6ADDRESS$ + "|" + IPVFUTURE$) + "\\]"), + //RFC 6874 + REG_NAME$ = subexp(subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$)) + "*"), + HOST$ = subexp(IP_LITERAL$ + "|" + IPV4ADDRESS$ + "(?!" + REG_NAME$ + ")" + "|" + REG_NAME$), + PORT$ = subexp(DIGIT$$ + "*"), + AUTHORITY$ = subexp(subexp(USERINFO$ + "@") + "?" + HOST$ + subexp("\\:" + PORT$) + "?"), + PCHAR$ = subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\:\\@]")), + SEGMENT$ = subexp(PCHAR$ + "*"), + SEGMENT_NZ$ = subexp(PCHAR$ + "+"), + SEGMENT_NZ_NC$ = subexp(subexp(PCT_ENCODED$ + "|" + merge(UNRESERVED$$, SUB_DELIMS$$, "[\\@]")) + "+"), + PATH_ABEMPTY$ = subexp(subexp("\\/" + SEGMENT$) + "*"), + PATH_ABSOLUTE$ = subexp("\\/" + subexp(SEGMENT_NZ$ + PATH_ABEMPTY$) + "?"), + //simplified + PATH_NOSCHEME$ = subexp(SEGMENT_NZ_NC$ + PATH_ABEMPTY$), + //simplified + PATH_ROOTLESS$ = subexp(SEGMENT_NZ$ + PATH_ABEMPTY$), + //simplified + PATH_EMPTY$ = "(?!" + PCHAR$ + ")", + PATH$ = subexp(PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_NOSCHEME$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$), + QUERY$ = subexp(subexp(PCHAR$ + "|" + merge("[\\/\\?]", IPRIVATE$$)) + "*"), + FRAGMENT$ = subexp(subexp(PCHAR$ + "|[\\/\\?]") + "*"), + HIER_PART$ = subexp(subexp("\\/\\/" + AUTHORITY$ + PATH_ABEMPTY$) + "|" + PATH_ABSOLUTE$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$), + URI$ = subexp(SCHEME$ + "\\:" + HIER_PART$ + subexp("\\?" + QUERY$) + "?" + subexp("\\#" + FRAGMENT$) + "?"), + RELATIVE_PART$ = subexp(subexp("\\/\\/" + AUTHORITY$ + PATH_ABEMPTY$) + "|" + PATH_ABSOLUTE$ + "|" + PATH_NOSCHEME$ + "|" + PATH_EMPTY$), + RELATIVE$ = subexp(RELATIVE_PART$ + subexp("\\?" + QUERY$) + "?" + subexp("\\#" + FRAGMENT$) + "?"), + URI_REFERENCE$ = subexp(URI$ + "|" + RELATIVE$), + ABSOLUTE_URI$ = subexp(SCHEME$ + "\\:" + HIER_PART$ + subexp("\\?" + QUERY$) + "?"), + GENERIC_REF$ = "^(" + SCHEME$ + ")\\:" + subexp(subexp("\\/\\/(" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?)") + "?(" + PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$ + ")") + subexp("\\?(" + QUERY$ + ")") + "?" + subexp("\\#(" + FRAGMENT$ + ")") + "?$", + RELATIVE_REF$ = "^(){0}" + subexp(subexp("\\/\\/(" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?)") + "?(" + PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_NOSCHEME$ + "|" + PATH_EMPTY$ + ")") + subexp("\\?(" + QUERY$ + ")") + "?" + subexp("\\#(" + FRAGMENT$ + ")") + "?$", + ABSOLUTE_REF$ = "^(" + SCHEME$ + ")\\:" + subexp(subexp("\\/\\/(" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?)") + "?(" + PATH_ABEMPTY$ + "|" + PATH_ABSOLUTE$ + "|" + PATH_ROOTLESS$ + "|" + PATH_EMPTY$ + ")") + subexp("\\?(" + QUERY$ + ")") + "?$", + SAMEDOC_REF$ = "^" + subexp("\\#(" + FRAGMENT$ + ")") + "?$", + AUTHORITY_REF$ = "^" + subexp("(" + USERINFO$ + ")@") + "?(" + HOST$ + ")" + subexp("\\:(" + PORT$ + ")") + "?$"; + return { + NOT_SCHEME: new RegExp(merge("[^]", ALPHA$$, DIGIT$$, "[\\+\\-\\.]"), "g"), + NOT_USERINFO: new RegExp(merge("[^\\%\\:]", UNRESERVED$$, SUB_DELIMS$$), "g"), + NOT_HOST: new RegExp(merge("[^\\%\\[\\]\\:]", UNRESERVED$$, SUB_DELIMS$$), "g"), + NOT_PATH: new RegExp(merge("[^\\%\\/\\:\\@]", UNRESERVED$$, SUB_DELIMS$$), "g"), + NOT_PATH_NOSCHEME: new RegExp(merge("[^\\%\\/\\@]", UNRESERVED$$, SUB_DELIMS$$), "g"), + NOT_QUERY: new RegExp(merge("[^\\%]", UNRESERVED$$, SUB_DELIMS$$, "[\\:\\@\\/\\?]", IPRIVATE$$), "g"), + NOT_FRAGMENT: new RegExp(merge("[^\\%]", UNRESERVED$$, SUB_DELIMS$$, "[\\:\\@\\/\\?]"), "g"), + ESCAPE: new RegExp(merge("[^]", UNRESERVED$$, SUB_DELIMS$$), "g"), + UNRESERVED: new RegExp(UNRESERVED$$, "g"), + OTHER_CHARS: new RegExp(merge("[^\\%]", UNRESERVED$$, RESERVED$$), "g"), + PCT_ENCODED: new RegExp(PCT_ENCODED$, "g"), + IPV4ADDRESS: new RegExp("^(" + IPV4ADDRESS$ + ")$"), + IPV6ADDRESS: new RegExp("^\\[?(" + IPV6ADDRESS$ + ")" + subexp(subexp("\\%25|\\%(?!" + HEXDIG$$ + "{2})") + "(" + ZONEID$ + ")") + "?\\]?$") //RFC 6874, with relaxed parsing rules + }; +} +var URI_PROTOCOL = buildExps(false); + +var IRI_PROTOCOL = buildExps(true); + +var slicedToArray = function () { + function sliceIterator(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"]) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + return function (arr, i) { + if (Array.isArray(arr)) { + return arr; + } else if (Symbol.iterator in Object(arr)) { + return sliceIterator(arr, i); + } else { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + }; +}(); + + + + + + + + + + + + + +var toConsumableArray = function (arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } else { + return Array.from(arr); + } +}; + +/** Highest positive signed 32-bit float value */ + +var maxInt = 2147483647; // aka. 0x7FFFFFFF or 2^31-1 + +/** Bootstring parameters */ +var base = 36; +var tMin = 1; +var tMax = 26; +var skew = 38; +var damp = 700; +var initialBias = 72; +var initialN = 128; // 0x80 +var delimiter = '-'; // '\x2D' + +/** Regular expressions */ +var regexPunycode = /^xn--/; +var regexNonASCII = /[^\0-\x7E]/; // non-ASCII chars +var regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g; // RFC 3490 separators + +/** Error messages */ +var errors = { + 'overflow': 'Overflow: input needs wider integers to process', + 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', + 'invalid-input': 'Invalid input' +}; + +/** Convenience shortcuts */ +var baseMinusTMin = base - tMin; +var floor = Math.floor; +var stringFromCharCode = String.fromCharCode; + +/*--------------------------------------------------------------------------*/ + +/** + * A generic error utility function. + * @private + * @param {String} type The error type. + * @returns {Error} Throws a `RangeError` with the applicable error message. + */ +function error$1(type) { + throw new RangeError(errors[type]); +} + +/** + * A generic `Array#map` utility function. + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function that gets called for every array + * item. + * @returns {Array} A new array of values returned by the callback function. + */ +function map(array, fn) { + var result = []; + var length = array.length; + while (length--) { + result[length] = fn(array[length]); + } + return result; +} + +/** + * A simple `Array#map`-like wrapper to work with domain name strings or email + * addresses. + * @private + * @param {String} domain The domain name or email address. + * @param {Function} callback The function that gets called for every + * character. + * @returns {Array} A new string of characters returned by the callback + * function. + */ +function mapDomain(string, fn) { + var parts = string.split('@'); + var result = ''; + if (parts.length > 1) { + // In email addresses, only the domain name should be punycoded. Leave + // the local part (i.e. everything up to `@`) intact. + result = parts[0] + '@'; + string = parts[1]; + } + // Avoid `split(regex)` for IE8 compatibility. See #17. + string = string.replace(regexSeparators, '\x2E'); + var labels = string.split('.'); + var encoded = map(labels, fn).join('.'); + return result + encoded; +} + +/** + * Creates an array containing the numeric code points of each Unicode + * character in the string. While JavaScript uses UCS-2 internally, + * this function will convert a pair of surrogate halves (each of which + * UCS-2 exposes as separate characters) into a single code point, + * matching UTF-16. + * @see `punycode.ucs2.encode` + * @see + * @memberOf punycode.ucs2 + * @name decode + * @param {String} string The Unicode input string (UCS-2). + * @returns {Array} The new array of code points. + */ +function ucs2decode(string) { + var output = []; + var counter = 0; + var length = string.length; + while (counter < length) { + var value = string.charCodeAt(counter++); + if (value >= 0xD800 && value <= 0xDBFF && counter < length) { + // It's a high surrogate, and there is a next character. + var extra = string.charCodeAt(counter++); + if ((extra & 0xFC00) == 0xDC00) { + // Low surrogate. + output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); + } else { + // It's an unmatched surrogate; only append this code unit, in case the + // next code unit is the high surrogate of a surrogate pair. + output.push(value); + counter--; + } + } else { + output.push(value); + } + } + return output; +} + +/** + * Creates a string based on an array of numeric code points. + * @see `punycode.ucs2.decode` + * @memberOf punycode.ucs2 + * @name encode + * @param {Array} codePoints The array of numeric code points. + * @returns {String} The new Unicode string (UCS-2). + */ +var ucs2encode = function ucs2encode(array) { + return String.fromCodePoint.apply(String, toConsumableArray(array)); +}; + +/** + * Converts a basic code point into a digit/integer. + * @see `digitToBasic()` + * @private + * @param {Number} codePoint The basic numeric code point value. + * @returns {Number} The numeric value of a basic code point (for use in + * representing integers) in the range `0` to `base - 1`, or `base` if + * the code point does not represent a value. + */ +var basicToDigit = function basicToDigit(codePoint) { + if (codePoint - 0x30 < 0x0A) { + return codePoint - 0x16; + } + if (codePoint - 0x41 < 0x1A) { + return codePoint - 0x41; + } + if (codePoint - 0x61 < 0x1A) { + return codePoint - 0x61; + } + return base; +}; + +/** + * Converts a digit/integer into a basic code point. + * @see `basicToDigit()` + * @private + * @param {Number} digit The numeric value of a basic code point. + * @returns {Number} The basic code point whose value (when used for + * representing integers) is `digit`, which needs to be in the range + * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is + * used; else, the lowercase form is used. The behavior is undefined + * if `flag` is non-zero and `digit` has no uppercase form. + */ +var digitToBasic = function digitToBasic(digit, flag) { + // 0..25 map to ASCII a..z or A..Z + // 26..35 map to ASCII 0..9 + return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); +}; + +/** + * Bias adaptation function as per section 3.4 of RFC 3492. + * https://tools.ietf.org/html/rfc3492#section-3.4 + * @private + */ +var adapt = function adapt(delta, numPoints, firstTime) { + var k = 0; + delta = firstTime ? floor(delta / damp) : delta >> 1; + delta += floor(delta / numPoints); + for (; /* no initialization */delta > baseMinusTMin * tMax >> 1; k += base) { + delta = floor(delta / baseMinusTMin); + } + return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); +}; + +/** + * Converts a Punycode string of ASCII-only symbols to a string of Unicode + * symbols. + * @memberOf punycode + * @param {String} input The Punycode string of ASCII-only symbols. + * @returns {String} The resulting string of Unicode symbols. + */ +var decode = function decode(input) { + // Don't use UCS-2. + var output = []; + var inputLength = input.length; + var i = 0; + var n = initialN; + var bias = initialBias; + + // Handle the basic code points: let `basic` be the number of input code + // points before the last delimiter, or `0` if there is none, then copy + // the first basic code points to the output. + + var basic = input.lastIndexOf(delimiter); + if (basic < 0) { + basic = 0; + } + + for (var j = 0; j < basic; ++j) { + // if it's not a basic code point + if (input.charCodeAt(j) >= 0x80) { + error$1('not-basic'); + } + output.push(input.charCodeAt(j)); + } + + // Main decoding loop: start just after the last delimiter if any basic code + // points were copied; start at the beginning otherwise. + + for (var index = basic > 0 ? basic + 1 : 0; index < inputLength;) /* no final expression */{ + + // `index` is the index of the next character to be consumed. + // Decode a generalized variable-length integer into `delta`, + // which gets added to `i`. The overflow checking is easier + // if we increase `i` as we go, then subtract off its starting + // value at the end to obtain `delta`. + var oldi = i; + for (var w = 1, k = base;; /* no condition */k += base) { + + if (index >= inputLength) { + error$1('invalid-input'); + } + + var digit = basicToDigit(input.charCodeAt(index++)); + + if (digit >= base || digit > floor((maxInt - i) / w)) { + error$1('overflow'); + } + + i += digit * w; + var t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias; + + if (digit < t) { + break; + } + + var baseMinusT = base - t; + if (w > floor(maxInt / baseMinusT)) { + error$1('overflow'); + } + + w *= baseMinusT; + } + + var out = output.length + 1; + bias = adapt(i - oldi, out, oldi == 0); + + // `i` was supposed to wrap around from `out` to `0`, + // incrementing `n` each time, so we'll fix that now: + if (floor(i / out) > maxInt - n) { + error$1('overflow'); + } + + n += floor(i / out); + i %= out; + + // Insert `n` at position `i` of the output. + output.splice(i++, 0, n); + } + + return String.fromCodePoint.apply(String, output); +}; + +/** + * Converts a string of Unicode symbols (e.g. a domain name label) to a + * Punycode string of ASCII-only symbols. + * @memberOf punycode + * @param {String} input The string of Unicode symbols. + * @returns {String} The resulting Punycode string of ASCII-only symbols. + */ +var encode = function encode(input) { + var output = []; + + // Convert the input in UCS-2 to an array of Unicode code points. + input = ucs2decode(input); + + // Cache the length. + var inputLength = input.length; + + // Initialize the state. + var n = initialN; + var delta = 0; + var bias = initialBias; + + // Handle the basic code points. + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = input[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var _currentValue2 = _step.value; + + if (_currentValue2 < 0x80) { + output.push(stringFromCharCode(_currentValue2)); + } + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + var basicLength = output.length; + var handledCPCount = basicLength; + + // `handledCPCount` is the number of code points that have been handled; + // `basicLength` is the number of basic code points. + + // Finish the basic string with a delimiter unless it's empty. + if (basicLength) { + output.push(delimiter); + } + + // Main encoding loop: + while (handledCPCount < inputLength) { + + // All non-basic code points < n have been handled already. Find the next + // larger one: + var m = maxInt; + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = input[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var currentValue = _step2.value; + + if (currentValue >= n && currentValue < m) { + m = currentValue; + } + } + + // Increase `delta` enough to advance the decoder's state to , + // but guard against overflow. + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + var handledCPCountPlusOne = handledCPCount + 1; + if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { + error$1('overflow'); + } + + delta += (m - n) * handledCPCountPlusOne; + n = m; + + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = input[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var _currentValue = _step3.value; + + if (_currentValue < n && ++delta > maxInt) { + error$1('overflow'); + } + if (_currentValue == n) { + // Represent delta as a generalized variable-length integer. + var q = delta; + for (var k = base;; /* no condition */k += base) { + var t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias; + if (q < t) { + break; + } + var qMinusT = q - t; + var baseMinusT = base - t; + output.push(stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))); + q = floor(qMinusT / baseMinusT); + } + + output.push(stringFromCharCode(digitToBasic(q, 0))); + bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); + delta = 0; + ++handledCPCount; + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3.return) { + _iterator3.return(); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + ++delta; + ++n; + } + return output.join(''); +}; + +/** + * Converts a Punycode string representing a domain name or an email address + * to Unicode. Only the Punycoded parts of the input will be converted, i.e. + * it doesn't matter if you call it on a string that has already been + * converted to Unicode. + * @memberOf punycode + * @param {String} input The Punycoded domain name or email address to + * convert to Unicode. + * @returns {String} The Unicode representation of the given Punycode + * string. + */ +var toUnicode = function toUnicode(input) { + return mapDomain(input, function (string) { + return regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string; + }); +}; + +/** + * Converts a Unicode string representing a domain name or an email address to + * Punycode. Only the non-ASCII parts of the domain name will be converted, + * i.e. it doesn't matter if you call it with a domain that's already in + * ASCII. + * @memberOf punycode + * @param {String} input The domain name or email address to convert, as a + * Unicode string. + * @returns {String} The Punycode representation of the given domain name or + * email address. + */ +var toASCII = function toASCII(input) { + return mapDomain(input, function (string) { + return regexNonASCII.test(string) ? 'xn--' + encode(string) : string; + }); +}; + +/*--------------------------------------------------------------------------*/ + +/** Define the public API */ +var punycode = { + /** + * A string representing the current Punycode.js version number. + * @memberOf punycode + * @type String + */ + 'version': '2.1.0', + /** + * An object of methods to convert from JavaScript's internal character + * representation (UCS-2) to Unicode code points, and back. + * @see + * @memberOf punycode + * @type Object + */ + 'ucs2': { + 'decode': ucs2decode, + 'encode': ucs2encode + }, + 'decode': decode, + 'encode': encode, + 'toASCII': toASCII, + 'toUnicode': toUnicode +}; + +/** + * URI.js + * + * @fileoverview An RFC 3986 compliant, scheme extendable URI parsing/validating/resolving library for JavaScript. + * @author Gary Court + * @see http://github.com/garycourt/uri-js + */ +/** + * Copyright 2011 Gary Court. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY GARY COURT ``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 GARY COURT 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. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of Gary Court. + */ +var SCHEMES = {}; +function pctEncChar(chr) { + var c = chr.charCodeAt(0); + var e = void 0; + if (c < 16) e = "%0" + c.toString(16).toUpperCase();else if (c < 128) e = "%" + c.toString(16).toUpperCase();else if (c < 2048) e = "%" + (c >> 6 | 192).toString(16).toUpperCase() + "%" + (c & 63 | 128).toString(16).toUpperCase();else e = "%" + (c >> 12 | 224).toString(16).toUpperCase() + "%" + (c >> 6 & 63 | 128).toString(16).toUpperCase() + "%" + (c & 63 | 128).toString(16).toUpperCase(); + return e; +} +function pctDecChars(str) { + var newStr = ""; + var i = 0; + var il = str.length; + while (i < il) { + var c = parseInt(str.substr(i + 1, 2), 16); + if (c < 128) { + newStr += String.fromCharCode(c); + i += 3; + } else if (c >= 194 && c < 224) { + if (il - i >= 6) { + var c2 = parseInt(str.substr(i + 4, 2), 16); + newStr += String.fromCharCode((c & 31) << 6 | c2 & 63); + } else { + newStr += str.substr(i, 6); + } + i += 6; + } else if (c >= 224) { + if (il - i >= 9) { + var _c = parseInt(str.substr(i + 4, 2), 16); + var c3 = parseInt(str.substr(i + 7, 2), 16); + newStr += String.fromCharCode((c & 15) << 12 | (_c & 63) << 6 | c3 & 63); + } else { + newStr += str.substr(i, 9); + } + i += 9; + } else { + newStr += str.substr(i, 3); + i += 3; + } + } + return newStr; +} +function _normalizeComponentEncoding(components, protocol) { + function decodeUnreserved(str) { + var decStr = pctDecChars(str); + return !decStr.match(protocol.UNRESERVED) ? str : decStr; + } + if (components.scheme) components.scheme = String(components.scheme).replace(protocol.PCT_ENCODED, decodeUnreserved).toLowerCase().replace(protocol.NOT_SCHEME, ""); + if (components.userinfo !== undefined) components.userinfo = String(components.userinfo).replace(protocol.PCT_ENCODED, decodeUnreserved).replace(protocol.NOT_USERINFO, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); + if (components.host !== undefined) components.host = String(components.host).replace(protocol.PCT_ENCODED, decodeUnreserved).toLowerCase().replace(protocol.NOT_HOST, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); + if (components.path !== undefined) components.path = String(components.path).replace(protocol.PCT_ENCODED, decodeUnreserved).replace(components.scheme ? protocol.NOT_PATH : protocol.NOT_PATH_NOSCHEME, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); + if (components.query !== undefined) components.query = String(components.query).replace(protocol.PCT_ENCODED, decodeUnreserved).replace(protocol.NOT_QUERY, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); + if (components.fragment !== undefined) components.fragment = String(components.fragment).replace(protocol.PCT_ENCODED, decodeUnreserved).replace(protocol.NOT_FRAGMENT, pctEncChar).replace(protocol.PCT_ENCODED, toUpperCase); + return components; +} + +function _stripLeadingZeros(str) { + return str.replace(/^0*(.*)/, "$1") || "0"; +} +function _normalizeIPv4(host, protocol) { + var matches = host.match(protocol.IPV4ADDRESS) || []; + + var _matches = slicedToArray(matches, 2), + address = _matches[1]; + + if (address) { + return address.split(".").map(_stripLeadingZeros).join("."); + } else { + return host; + } +} +function _normalizeIPv6(host, protocol) { + var matches = host.match(protocol.IPV6ADDRESS) || []; + + var _matches2 = slicedToArray(matches, 3), + address = _matches2[1], + zone = _matches2[2]; + + if (address) { + var _address$toLowerCase$ = address.toLowerCase().split('::').reverse(), + _address$toLowerCase$2 = slicedToArray(_address$toLowerCase$, 2), + last = _address$toLowerCase$2[0], + first = _address$toLowerCase$2[1]; + + var firstFields = first ? first.split(":").map(_stripLeadingZeros) : []; + var lastFields = last.split(":").map(_stripLeadingZeros); + var isLastFieldIPv4Address = protocol.IPV4ADDRESS.test(lastFields[lastFields.length - 1]); + var fieldCount = isLastFieldIPv4Address ? 7 : 8; + var lastFieldsStart = lastFields.length - fieldCount; + var fields = Array(fieldCount); + for (var x = 0; x < fieldCount; ++x) { + fields[x] = firstFields[x] || lastFields[lastFieldsStart + x] || ''; + } + if (isLastFieldIPv4Address) { + fields[fieldCount - 1] = _normalizeIPv4(fields[fieldCount - 1], protocol); + } + var allZeroFields = fields.reduce(function (acc, field, index) { + if (!field || field === "0") { + var lastLongest = acc[acc.length - 1]; + if (lastLongest && lastLongest.index + lastLongest.length === index) { + lastLongest.length++; + } else { + acc.push({ index: index, length: 1 }); + } + } + return acc; + }, []); + var longestZeroFields = allZeroFields.sort(function (a, b) { + return b.length - a.length; + })[0]; + var newHost = void 0; + if (longestZeroFields && longestZeroFields.length > 1) { + var newFirst = fields.slice(0, longestZeroFields.index); + var newLast = fields.slice(longestZeroFields.index + longestZeroFields.length); + newHost = newFirst.join(":") + "::" + newLast.join(":"); + } else { + newHost = fields.join(":"); + } + if (zone) { + newHost += "%" + zone; + } + return newHost; + } else { + return host; + } +} +var URI_PARSE = /^(?:([^:\/?#]+):)?(?:\/\/((?:([^\/?#@]*)@)?(\[[^\/?#\]]+\]|[^\/?#:]*)(?:\:(\d*))?))?([^?#]*)(?:\?([^#]*))?(?:#((?:.|\n|\r)*))?/i; +var NO_MATCH_IS_UNDEFINED = "".match(/(){0}/)[1] === undefined; +function parse(uriString) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var components = {}; + var protocol = options.iri !== false ? IRI_PROTOCOL : URI_PROTOCOL; + if (options.reference === "suffix") uriString = (options.scheme ? options.scheme + ":" : "") + "//" + uriString; + var matches = uriString.match(URI_PARSE); + if (matches) { + if (NO_MATCH_IS_UNDEFINED) { + //store each component + components.scheme = matches[1]; + components.userinfo = matches[3]; + components.host = matches[4]; + components.port = parseInt(matches[5], 10); + components.path = matches[6] || ""; + components.query = matches[7]; + components.fragment = matches[8]; + //fix port number + if (isNaN(components.port)) { + components.port = matches[5]; + } + } else { + //IE FIX for improper RegExp matching + //store each component + components.scheme = matches[1] || undefined; + components.userinfo = uriString.indexOf("@") !== -1 ? matches[3] : undefined; + components.host = uriString.indexOf("//") !== -1 ? matches[4] : undefined; + components.port = parseInt(matches[5], 10); + components.path = matches[6] || ""; + components.query = uriString.indexOf("?") !== -1 ? matches[7] : undefined; + components.fragment = uriString.indexOf("#") !== -1 ? matches[8] : undefined; + //fix port number + if (isNaN(components.port)) { + components.port = uriString.match(/\/\/(?:.|\n)*\:(?:\/|\?|\#|$)/) ? matches[4] : undefined; + } + } + if (components.host) { + //normalize IP hosts + components.host = _normalizeIPv6(_normalizeIPv4(components.host, protocol), protocol); + } + //determine reference type + if (components.scheme === undefined && components.userinfo === undefined && components.host === undefined && components.port === undefined && !components.path && components.query === undefined) { + components.reference = "same-document"; + } else if (components.scheme === undefined) { + components.reference = "relative"; + } else if (components.fragment === undefined) { + components.reference = "absolute"; + } else { + components.reference = "uri"; + } + //check for reference errors + if (options.reference && options.reference !== "suffix" && options.reference !== components.reference) { + components.error = components.error || "URI is not a " + options.reference + " reference."; + } + //find scheme handler + var schemeHandler = SCHEMES[(options.scheme || components.scheme || "").toLowerCase()]; + //check if scheme can't handle IRIs + if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) { + //if host component is a domain name + if (components.host && (options.domainHost || schemeHandler && schemeHandler.domainHost)) { + //convert Unicode IDN -> ASCII IDN + try { + components.host = punycode.toASCII(components.host.replace(protocol.PCT_ENCODED, pctDecChars).toLowerCase()); + } catch (e) { + components.error = components.error || "Host's domain name can not be converted to ASCII via punycode: " + e; + } + } + //convert IRI -> URI + _normalizeComponentEncoding(components, URI_PROTOCOL); + } else { + //normalize encodings + _normalizeComponentEncoding(components, protocol); + } + //perform scheme specific parsing + if (schemeHandler && schemeHandler.parse) { + schemeHandler.parse(components, options); + } + } else { + components.error = components.error || "URI can not be parsed."; + } + return components; +} + +function _recomposeAuthority(components, options) { + var protocol = options.iri !== false ? IRI_PROTOCOL : URI_PROTOCOL; + var uriTokens = []; + if (components.userinfo !== undefined) { + uriTokens.push(components.userinfo); + uriTokens.push("@"); + } + if (components.host !== undefined) { + //normalize IP hosts, add brackets and escape zone separator for IPv6 + uriTokens.push(_normalizeIPv6(_normalizeIPv4(String(components.host), protocol), protocol).replace(protocol.IPV6ADDRESS, function (_, $1, $2) { + return "[" + $1 + ($2 ? "%25" + $2 : "") + "]"; + })); + } + if (typeof components.port === "number" || typeof components.port === "string") { + uriTokens.push(":"); + uriTokens.push(String(components.port)); + } + return uriTokens.length ? uriTokens.join("") : undefined; +} + +var RDS1 = /^\.\.?\//; +var RDS2 = /^\/\.(\/|$)/; +var RDS3 = /^\/\.\.(\/|$)/; +var RDS5 = /^\/?(?:.|\n)*?(?=\/|$)/; +function removeDotSegments(input) { + var output = []; + while (input.length) { + if (input.match(RDS1)) { + input = input.replace(RDS1, ""); + } else if (input.match(RDS2)) { + input = input.replace(RDS2, "/"); + } else if (input.match(RDS3)) { + input = input.replace(RDS3, "/"); + output.pop(); + } else if (input === "." || input === "..") { + input = ""; + } else { + var im = input.match(RDS5); + if (im) { + var s = im[0]; + input = input.slice(s.length); + output.push(s); + } else { + throw new Error("Unexpected dot segment condition"); + } + } + } + return output.join(""); +} + +function serialize(components) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var protocol = options.iri ? IRI_PROTOCOL : URI_PROTOCOL; + var uriTokens = []; + //find scheme handler + var schemeHandler = SCHEMES[(options.scheme || components.scheme || "").toLowerCase()]; + //perform scheme specific serialization + if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(components, options); + if (components.host) { + //if host component is an IPv6 address + if (protocol.IPV6ADDRESS.test(components.host)) {} + //TODO: normalize IPv6 address as per RFC 5952 + + //if host component is a domain name + else if (options.domainHost || schemeHandler && schemeHandler.domainHost) { + //convert IDN via punycode + try { + components.host = !options.iri ? punycode.toASCII(components.host.replace(protocol.PCT_ENCODED, pctDecChars).toLowerCase()) : punycode.toUnicode(components.host); + } catch (e) { + components.error = components.error || "Host's domain name can not be converted to " + (!options.iri ? "ASCII" : "Unicode") + " via punycode: " + e; + } + } + } + //normalize encoding + _normalizeComponentEncoding(components, protocol); + if (options.reference !== "suffix" && components.scheme) { + uriTokens.push(components.scheme); + uriTokens.push(":"); + } + var authority = _recomposeAuthority(components, options); + if (authority !== undefined) { + if (options.reference !== "suffix") { + uriTokens.push("//"); + } + uriTokens.push(authority); + if (components.path && components.path.charAt(0) !== "/") { + uriTokens.push("/"); + } + } + if (components.path !== undefined) { + var s = components.path; + if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) { + s = removeDotSegments(s); + } + if (authority === undefined) { + s = s.replace(/^\/\//, "/%2F"); //don't allow the path to start with "//" + } + uriTokens.push(s); + } + if (components.query !== undefined) { + uriTokens.push("?"); + uriTokens.push(components.query); + } + if (components.fragment !== undefined) { + uriTokens.push("#"); + uriTokens.push(components.fragment); + } + return uriTokens.join(""); //merge tokens into a string +} + +function resolveComponents(base, relative) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var skipNormalization = arguments[3]; + + var target = {}; + if (!skipNormalization) { + base = parse(serialize(base, options), options); //normalize base components + relative = parse(serialize(relative, options), options); //normalize relative components + } + options = options || {}; + if (!options.tolerant && relative.scheme) { + target.scheme = relative.scheme; + //target.authority = relative.authority; + target.userinfo = relative.userinfo; + target.host = relative.host; + target.port = relative.port; + target.path = removeDotSegments(relative.path || ""); + target.query = relative.query; + } else { + if (relative.userinfo !== undefined || relative.host !== undefined || relative.port !== undefined) { + //target.authority = relative.authority; + target.userinfo = relative.userinfo; + target.host = relative.host; + target.port = relative.port; + target.path = removeDotSegments(relative.path || ""); + target.query = relative.query; + } else { + if (!relative.path) { + target.path = base.path; + if (relative.query !== undefined) { + target.query = relative.query; + } else { + target.query = base.query; + } + } else { + if (relative.path.charAt(0) === "/") { + target.path = removeDotSegments(relative.path); + } else { + if ((base.userinfo !== undefined || base.host !== undefined || base.port !== undefined) && !base.path) { + target.path = "/" + relative.path; + } else if (!base.path) { + target.path = relative.path; + } else { + target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative.path; + } + target.path = removeDotSegments(target.path); + } + target.query = relative.query; + } + //target.authority = base.authority; + target.userinfo = base.userinfo; + target.host = base.host; + target.port = base.port; + } + target.scheme = base.scheme; + } + target.fragment = relative.fragment; + return target; +} + +function resolve(baseURI, relativeURI, options) { + var schemelessOptions = assign({ scheme: 'null' }, options); + return serialize(resolveComponents(parse(baseURI, schemelessOptions), parse(relativeURI, schemelessOptions), schemelessOptions, true), schemelessOptions); +} + +function normalize(uri, options) { + if (typeof uri === "string") { + uri = serialize(parse(uri, options), options); + } else if (typeOf(uri) === "object") { + uri = parse(serialize(uri, options), options); + } + return uri; +} + +function equal(uriA, uriB, options) { + if (typeof uriA === "string") { + uriA = serialize(parse(uriA, options), options); + } else if (typeOf(uriA) === "object") { + uriA = serialize(uriA, options); + } + if (typeof uriB === "string") { + uriB = serialize(parse(uriB, options), options); + } else if (typeOf(uriB) === "object") { + uriB = serialize(uriB, options); + } + return uriA === uriB; +} + +function escapeComponent(str, options) { + return str && str.toString().replace(!options || !options.iri ? URI_PROTOCOL.ESCAPE : IRI_PROTOCOL.ESCAPE, pctEncChar); +} + +function unescapeComponent(str, options) { + return str && str.toString().replace(!options || !options.iri ? URI_PROTOCOL.PCT_ENCODED : IRI_PROTOCOL.PCT_ENCODED, pctDecChars); +} + +var handler = { + scheme: "http", + domainHost: true, + parse: function parse(components, options) { + //report missing host + if (!components.host) { + components.error = components.error || "HTTP URIs must have a host."; + } + return components; + }, + serialize: function serialize(components, options) { + var secure = String(components.scheme).toLowerCase() === "https"; + //normalize the default port + if (components.port === (secure ? 443 : 80) || components.port === "") { + components.port = undefined; + } + //normalize the empty path + if (!components.path) { + components.path = "/"; + } + //NOTE: We do not parse query strings for HTTP URIs + //as WWW Form Url Encoded query strings are part of the HTML4+ spec, + //and not the HTTP spec. + return components; + } +}; + +var handler$1 = { + scheme: "https", + domainHost: handler.domainHost, + parse: handler.parse, + serialize: handler.serialize +}; + +function isSecure(wsComponents) { + return typeof wsComponents.secure === 'boolean' ? wsComponents.secure : String(wsComponents.scheme).toLowerCase() === "wss"; +} +//RFC 6455 +var handler$2 = { + scheme: "ws", + domainHost: true, + parse: function parse(components, options) { + var wsComponents = components; + //indicate if the secure flag is set + wsComponents.secure = isSecure(wsComponents); + //construct resouce name + wsComponents.resourceName = (wsComponents.path || '/') + (wsComponents.query ? '?' + wsComponents.query : ''); + wsComponents.path = undefined; + wsComponents.query = undefined; + return wsComponents; + }, + serialize: function serialize(wsComponents, options) { + //normalize the default port + if (wsComponents.port === (isSecure(wsComponents) ? 443 : 80) || wsComponents.port === "") { + wsComponents.port = undefined; + } + //ensure scheme matches secure flag + if (typeof wsComponents.secure === 'boolean') { + wsComponents.scheme = wsComponents.secure ? 'wss' : 'ws'; + wsComponents.secure = undefined; + } + //reconstruct path from resource name + if (wsComponents.resourceName) { + var _wsComponents$resourc = wsComponents.resourceName.split('?'), + _wsComponents$resourc2 = slicedToArray(_wsComponents$resourc, 2), + path = _wsComponents$resourc2[0], + query = _wsComponents$resourc2[1]; + + wsComponents.path = path && path !== '/' ? path : undefined; + wsComponents.query = query; + wsComponents.resourceName = undefined; + } + //forbid fragment component + wsComponents.fragment = undefined; + return wsComponents; + } +}; + +var handler$3 = { + scheme: "wss", + domainHost: handler$2.domainHost, + parse: handler$2.parse, + serialize: handler$2.serialize +}; + +var O = {}; +var isIRI = true; +//RFC 3986 +var UNRESERVED$$ = "[A-Za-z0-9\\-\\.\\_\\~" + (isIRI ? "\\xA0-\\u200D\\u2010-\\u2029\\u202F-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF" : "") + "]"; +var HEXDIG$$ = "[0-9A-Fa-f]"; //case-insensitive +var PCT_ENCODED$ = subexp(subexp("%[EFef]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%[89A-Fa-f]" + HEXDIG$$ + "%" + HEXDIG$$ + HEXDIG$$) + "|" + subexp("%" + HEXDIG$$ + HEXDIG$$)); //expanded +//RFC 5322, except these symbols as per RFC 6068: @ : / ? # [ ] & ; = +//const ATEXT$$ = "[A-Za-z0-9\\!\\#\\$\\%\\&\\'\\*\\+\\-\\/\\=\\?\\^\\_\\`\\{\\|\\}\\~]"; +//const WSP$$ = "[\\x20\\x09]"; +//const OBS_QTEXT$$ = "[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]"; //(%d1-8 / %d11-12 / %d14-31 / %d127) +//const QTEXT$$ = merge("[\\x21\\x23-\\x5B\\x5D-\\x7E]", OBS_QTEXT$$); //%d33 / %d35-91 / %d93-126 / obs-qtext +//const VCHAR$$ = "[\\x21-\\x7E]"; +//const WSP$$ = "[\\x20\\x09]"; +//const OBS_QP$ = subexp("\\\\" + merge("[\\x00\\x0D\\x0A]", OBS_QTEXT$$)); //%d0 / CR / LF / obs-qtext +//const FWS$ = subexp(subexp(WSP$$ + "*" + "\\x0D\\x0A") + "?" + WSP$$ + "+"); +//const QUOTED_PAIR$ = subexp(subexp("\\\\" + subexp(VCHAR$$ + "|" + WSP$$)) + "|" + OBS_QP$); +//const QUOTED_STRING$ = subexp('\\"' + subexp(FWS$ + "?" + QCONTENT$) + "*" + FWS$ + "?" + '\\"'); +var ATEXT$$ = "[A-Za-z0-9\\!\\$\\%\\'\\*\\+\\-\\^\\_\\`\\{\\|\\}\\~]"; +var QTEXT$$ = "[\\!\\$\\%\\'\\(\\)\\*\\+\\,\\-\\.0-9\\<\\>A-Z\\x5E-\\x7E]"; +var VCHAR$$ = merge(QTEXT$$, "[\\\"\\\\]"); +var SOME_DELIMS$$ = "[\\!\\$\\'\\(\\)\\*\\+\\,\\;\\:\\@]"; +var UNRESERVED = new RegExp(UNRESERVED$$, "g"); +var PCT_ENCODED = new RegExp(PCT_ENCODED$, "g"); +var NOT_LOCAL_PART = new RegExp(merge("[^]", ATEXT$$, "[\\.]", '[\\"]', VCHAR$$), "g"); +var NOT_HFNAME = new RegExp(merge("[^]", UNRESERVED$$, SOME_DELIMS$$), "g"); +var NOT_HFVALUE = NOT_HFNAME; +function decodeUnreserved(str) { + var decStr = pctDecChars(str); + return !decStr.match(UNRESERVED) ? str : decStr; +} +var handler$4 = { + scheme: "mailto", + parse: function parse$$1(components, options) { + var mailtoComponents = components; + var to = mailtoComponents.to = mailtoComponents.path ? mailtoComponents.path.split(",") : []; + mailtoComponents.path = undefined; + if (mailtoComponents.query) { + var unknownHeaders = false; + var headers = {}; + var hfields = mailtoComponents.query.split("&"); + for (var x = 0, xl = hfields.length; x < xl; ++x) { + var hfield = hfields[x].split("="); + switch (hfield[0]) { + case "to": + var toAddrs = hfield[1].split(","); + for (var _x = 0, _xl = toAddrs.length; _x < _xl; ++_x) { + to.push(toAddrs[_x]); + } + break; + case "subject": + mailtoComponents.subject = unescapeComponent(hfield[1], options); + break; + case "body": + mailtoComponents.body = unescapeComponent(hfield[1], options); + break; + default: + unknownHeaders = true; + headers[unescapeComponent(hfield[0], options)] = unescapeComponent(hfield[1], options); + break; + } + } + if (unknownHeaders) mailtoComponents.headers = headers; + } + mailtoComponents.query = undefined; + for (var _x2 = 0, _xl2 = to.length; _x2 < _xl2; ++_x2) { + var addr = to[_x2].split("@"); + addr[0] = unescapeComponent(addr[0]); + if (!options.unicodeSupport) { + //convert Unicode IDN -> ASCII IDN + try { + addr[1] = punycode.toASCII(unescapeComponent(addr[1], options).toLowerCase()); + } catch (e) { + mailtoComponents.error = mailtoComponents.error || "Email address's domain name can not be converted to ASCII via punycode: " + e; + } + } else { + addr[1] = unescapeComponent(addr[1], options).toLowerCase(); + } + to[_x2] = addr.join("@"); + } + return mailtoComponents; + }, + serialize: function serialize$$1(mailtoComponents, options) { + var components = mailtoComponents; + var to = toArray(mailtoComponents.to); + if (to) { + for (var x = 0, xl = to.length; x < xl; ++x) { + var toAddr = String(to[x]); + var atIdx = toAddr.lastIndexOf("@"); + var localPart = toAddr.slice(0, atIdx).replace(PCT_ENCODED, decodeUnreserved).replace(PCT_ENCODED, toUpperCase).replace(NOT_LOCAL_PART, pctEncChar); + var domain = toAddr.slice(atIdx + 1); + //convert IDN via punycode + try { + domain = !options.iri ? punycode.toASCII(unescapeComponent(domain, options).toLowerCase()) : punycode.toUnicode(domain); + } catch (e) { + components.error = components.error || "Email address's domain name can not be converted to " + (!options.iri ? "ASCII" : "Unicode") + " via punycode: " + e; + } + to[x] = localPart + "@" + domain; + } + components.path = to.join(","); + } + var headers = mailtoComponents.headers = mailtoComponents.headers || {}; + if (mailtoComponents.subject) headers["subject"] = mailtoComponents.subject; + if (mailtoComponents.body) headers["body"] = mailtoComponents.body; + var fields = []; + for (var name in headers) { + if (headers[name] !== O[name]) { + fields.push(name.replace(PCT_ENCODED, decodeUnreserved).replace(PCT_ENCODED, toUpperCase).replace(NOT_HFNAME, pctEncChar) + "=" + headers[name].replace(PCT_ENCODED, decodeUnreserved).replace(PCT_ENCODED, toUpperCase).replace(NOT_HFVALUE, pctEncChar)); + } + } + if (fields.length) { + components.query = fields.join("&"); + } + return components; + } +}; + +var URN_PARSE = /^([^\:]+)\:(.*)/; +//RFC 2141 +var handler$5 = { + scheme: "urn", + parse: function parse$$1(components, options) { + var matches = components.path && components.path.match(URN_PARSE); + var urnComponents = components; + if (matches) { + var scheme = options.scheme || urnComponents.scheme || "urn"; + var nid = matches[1].toLowerCase(); + var nss = matches[2]; + var urnScheme = scheme + ":" + (options.nid || nid); + var schemeHandler = SCHEMES[urnScheme]; + urnComponents.nid = nid; + urnComponents.nss = nss; + urnComponents.path = undefined; + if (schemeHandler) { + urnComponents = schemeHandler.parse(urnComponents, options); + } + } else { + urnComponents.error = urnComponents.error || "URN can not be parsed."; + } + return urnComponents; + }, + serialize: function serialize$$1(urnComponents, options) { + var scheme = options.scheme || urnComponents.scheme || "urn"; + var nid = urnComponents.nid; + var urnScheme = scheme + ":" + (options.nid || nid); + var schemeHandler = SCHEMES[urnScheme]; + if (schemeHandler) { + urnComponents = schemeHandler.serialize(urnComponents, options); + } + var uriComponents = urnComponents; + var nss = urnComponents.nss; + uriComponents.path = (nid || options.nid) + ":" + nss; + return uriComponents; + } +}; + +var UUID = /^[0-9A-Fa-f]{8}(?:\-[0-9A-Fa-f]{4}){3}\-[0-9A-Fa-f]{12}$/; +//RFC 4122 +var handler$6 = { + scheme: "urn:uuid", + parse: function parse(urnComponents, options) { + var uuidComponents = urnComponents; + uuidComponents.uuid = uuidComponents.nss; + uuidComponents.nss = undefined; + if (!options.tolerant && (!uuidComponents.uuid || !uuidComponents.uuid.match(UUID))) { + uuidComponents.error = uuidComponents.error || "UUID is not valid."; + } + return uuidComponents; + }, + serialize: function serialize(uuidComponents, options) { + var urnComponents = uuidComponents; + //normalize UUID + urnComponents.nss = (uuidComponents.uuid || "").toLowerCase(); + return urnComponents; + } +}; + +SCHEMES[handler.scheme] = handler; +SCHEMES[handler$1.scheme] = handler$1; +SCHEMES[handler$2.scheme] = handler$2; +SCHEMES[handler$3.scheme] = handler$3; +SCHEMES[handler$4.scheme] = handler$4; +SCHEMES[handler$5.scheme] = handler$5; +SCHEMES[handler$6.scheme] = handler$6; + +exports.SCHEMES = SCHEMES; +exports.pctEncChar = pctEncChar; +exports.pctDecChars = pctDecChars; +exports.parse = parse; +exports.removeDotSegments = removeDotSegments; +exports.serialize = serialize; +exports.resolveComponents = resolveComponents; +exports.resolve = resolve; +exports.normalize = normalize; +exports.equal = equal; +exports.escapeComponent = escapeComponent; +exports.unescapeComponent = unescapeComponent; + +Object.defineProperty(exports, '__esModule', { value: true }); + +}))); + + +/***/ }), + +/***/ 4049: +/***/ (function(module) { + +/*! + * vanilla-picker v2.11.0 + * https://vanilla-picker.js.org + * + * Copyright 2017-2020 Andreas Borgen (https://github.com/Sphinxxxx), Adam Brooks (https://github.com/dissimulate) + * Released under the ISC license. + */ +(function (global, factory) { + true ? module.exports = factory() : + 0; +}(this, (function () { 'use strict'; + + var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + }; + + var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + var slicedToArray = function () { + function sliceIterator(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"]) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + return function (arr, i) { + if (Array.isArray(arr)) { + return arr; + } else if (Symbol.iterator in Object(arr)) { + return sliceIterator(arr, i); + } else { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + }; + }(); + + String.prototype.startsWith = String.prototype.startsWith || function (needle) { + return this.indexOf(needle) === 0; + }; + String.prototype.padStart = String.prototype.padStart || function (len, pad) { + var str = this;while (str.length < len) { + str = pad + str; + }return str; + }; + + var colorNames = { cb: '0f8ff', tqw: 'aebd7', q: '-ffff', qmrn: '7fffd4', zr: '0ffff', bg: '5f5dc', bsq: 'e4c4', bck: '---', nch: 'ebcd', b: '--ff', bvt: '8a2be2', brwn: 'a52a2a', brw: 'deb887', ctb: '5f9ea0', hrt: '7fff-', chcT: 'd2691e', cr: '7f50', rnw: '6495ed', crns: '8dc', crms: 'dc143c', cn: '-ffff', Db: '--8b', Dcn: '-8b8b', Dgnr: 'b8860b', Dgr: 'a9a9a9', Dgrn: '-64-', Dkhk: 'bdb76b', Dmgn: '8b-8b', Dvgr: '556b2f', Drng: '8c-', Drch: '9932cc', Dr: '8b--', Dsmn: 'e9967a', Dsgr: '8fbc8f', DsTb: '483d8b', DsTg: '2f4f4f', Dtrq: '-ced1', Dvt: '94-d3', ppnk: '1493', pskb: '-bfff', mgr: '696969', grb: '1e90ff', rbrc: 'b22222', rwht: 'af0', stg: '228b22', chs: '-ff', gnsb: 'dcdcdc', st: '8f8ff', g: 'd7-', gnr: 'daa520', gr: '808080', grn: '-8-0', grnw: 'adff2f', hnw: '0fff0', htpn: '69b4', nnr: 'cd5c5c', ng: '4b-82', vr: '0', khk: '0e68c', vnr: 'e6e6fa', nrb: '0f5', wngr: '7cfc-', mnch: 'acd', Lb: 'add8e6', Lcr: '08080', Lcn: 'e0ffff', Lgnr: 'afad2', Lgr: 'd3d3d3', Lgrn: '90ee90', Lpnk: 'b6c1', Lsmn: 'a07a', Lsgr: '20b2aa', Lskb: '87cefa', LsTg: '778899', Lstb: 'b0c4de', Lw: 'e0', m: '-ff-', mgrn: '32cd32', nn: 'af0e6', mgnt: '-ff', mrn: '8--0', mqm: '66cdaa', mmb: '--cd', mmrc: 'ba55d3', mmpr: '9370db', msg: '3cb371', mmsT: '7b68ee', '': '-fa9a', mtr: '48d1cc', mmvt: 'c71585', mnLb: '191970', ntc: '5fffa', mstr: 'e4e1', mccs: 'e4b5', vjw: 'dead', nv: '--80', c: 'df5e6', v: '808-0', vrb: '6b8e23', rng: 'a5-', rngr: '45-', rch: 'da70d6', pgnr: 'eee8aa', pgrn: '98fb98', ptrq: 'afeeee', pvtr: 'db7093', ppwh: 'efd5', pchp: 'dab9', pr: 'cd853f', pnk: 'c0cb', pm: 'dda0dd', pwrb: 'b0e0e6', prp: '8-080', cc: '663399', r: '--', sbr: 'bc8f8f', rb: '4169e1', sbrw: '8b4513', smn: 'a8072', nbr: '4a460', sgrn: '2e8b57', ssh: '5ee', snn: 'a0522d', svr: 'c0c0c0', skb: '87ceeb', sTb: '6a5acd', sTgr: '708090', snw: 'afa', n: '-ff7f', stb: '4682b4', tn: 'd2b48c', t: '-8080', thst: 'd8bfd8', tmT: '6347', trqs: '40e0d0', vt: 'ee82ee', whT: '5deb3', wht: '', hts: '5f5f5', w: '-', wgrn: '9acd32' }; + + function printNum(num) { + var decs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; + + var str = decs > 0 ? num.toFixed(decs).replace(/0+$/, '').replace(/\.$/, '') : num.toString(); + return str || '0'; + } + + var Color = function () { + function Color(r, g, b, a) { + classCallCheck(this, Color); + + + var that = this; + function parseString(input) { + + if (input.startsWith('hsl')) { + var _input$match$map = input.match(/([\-\d\.e]+)/g).map(Number), + _input$match$map2 = slicedToArray(_input$match$map, 4), + h = _input$match$map2[0], + s = _input$match$map2[1], + l = _input$match$map2[2], + _a = _input$match$map2[3]; + + if (_a === undefined) { + _a = 1; + } + + h /= 360; + s /= 100; + l /= 100; + that.hsla = [h, s, l, _a]; + } else if (input.startsWith('rgb')) { + var _input$match$map3 = input.match(/([\-\d\.e]+)/g).map(Number), + _input$match$map4 = slicedToArray(_input$match$map3, 4), + _r = _input$match$map4[0], + _g = _input$match$map4[1], + _b = _input$match$map4[2], + _a2 = _input$match$map4[3]; + + if (_a2 === undefined) { + _a2 = 1; + } + + that.rgba = [_r, _g, _b, _a2]; + } else { + if (input.startsWith('#')) { + that.rgba = Color.hexToRgb(input); + } else { + that.rgba = Color.nameToRgb(input) || Color.hexToRgb(input); + } + } + } + + if (r === undefined) ; else if (Array.isArray(r)) { + this.rgba = r; + } else if (b === undefined) { + var color = r && '' + r; + if (color) { + parseString(color.toLowerCase()); + } + } else { + this.rgba = [r, g, b, a === undefined ? 1 : a]; + } + } + + createClass(Color, [{ + key: 'printRGB', + value: function printRGB(alpha) { + var rgb = alpha ? this.rgba : this.rgba.slice(0, 3), + vals = rgb.map(function (x, i) { + return printNum(x, i === 3 ? 3 : 0); + }); + + return alpha ? 'rgba(' + vals + ')' : 'rgb(' + vals + ')'; + } + }, { + key: 'printHSL', + value: function printHSL(alpha) { + var mults = [360, 100, 100, 1], + suff = ['', '%', '%', '']; + + var hsl = alpha ? this.hsla : this.hsla.slice(0, 3), + vals = hsl.map(function (x, i) { + return printNum(x * mults[i], i === 3 ? 3 : 1) + suff[i]; + }); + + return alpha ? 'hsla(' + vals + ')' : 'hsl(' + vals + ')'; + } + }, { + key: 'printHex', + value: function printHex(alpha) { + var hex = this.hex; + return alpha ? hex : hex.substring(0, 7); + } + }, { + key: 'rgba', + get: function get$$1() { + if (this._rgba) { + return this._rgba; + } + if (!this._hsla) { + throw new Error('No color is set'); + } + + return this._rgba = Color.hslToRgb(this._hsla); + }, + set: function set$$1(rgb) { + if (rgb.length === 3) { + rgb[3] = 1; + } + + this._rgba = rgb; + this._hsla = null; + } + }, { + key: 'rgbString', + get: function get$$1() { + return this.printRGB(); + } + }, { + key: 'rgbaString', + get: function get$$1() { + return this.printRGB(true); + } + }, { + key: 'hsla', + get: function get$$1() { + if (this._hsla) { + return this._hsla; + } + if (!this._rgba) { + throw new Error('No color is set'); + } + + return this._hsla = Color.rgbToHsl(this._rgba); + }, + set: function set$$1(hsl) { + if (hsl.length === 3) { + hsl[3] = 1; + } + + this._hsla = hsl; + this._rgba = null; + } + }, { + key: 'hslString', + get: function get$$1() { + return this.printHSL(); + } + }, { + key: 'hslaString', + get: function get$$1() { + return this.printHSL(true); + } + }, { + key: 'hex', + get: function get$$1() { + var rgb = this.rgba, + hex = rgb.map(function (x, i) { + return i < 3 ? x.toString(16) : Math.round(x * 255).toString(16); + }); + + return '#' + hex.map(function (x) { + return x.padStart(2, '0'); + }).join(''); + }, + set: function set$$1(hex) { + this.rgba = Color.hexToRgb(hex); + } + }], [{ + key: 'hexToRgb', + value: function hexToRgb(input) { + + var hex = (input.startsWith('#') ? input.slice(1) : input).replace(/^(\w{3})$/, '$1F').replace(/^(\w)(\w)(\w)(\w)$/, '$1$1$2$2$3$3$4$4').replace(/^(\w{6})$/, '$1FF'); + + if (!hex.match(/^([0-9a-fA-F]{8})$/)) { + throw new Error('Unknown hex color; ' + input); + } + + var rgba = hex.match(/^(\w\w)(\w\w)(\w\w)(\w\w)$/).slice(1).map(function (x) { + return parseInt(x, 16); + }); + + rgba[3] = rgba[3] / 255; + return rgba; + } + }, { + key: 'nameToRgb', + value: function nameToRgb(input) { + + var hash = input.toLowerCase().replace('at', 'T').replace(/[aeiouyldf]/g, '').replace('ght', 'L').replace('rk', 'D').slice(-5, 4), + hex = colorNames[hash]; + return hex === undefined ? hex : Color.hexToRgb(hex.replace(/\-/g, '00').padStart(6, 'f')); + } + }, { + key: 'rgbToHsl', + value: function rgbToHsl(_ref) { + var _ref2 = slicedToArray(_ref, 4), + r = _ref2[0], + g = _ref2[1], + b = _ref2[2], + a = _ref2[3]; + + r /= 255; + g /= 255; + b /= 255; + + var max = Math.max(r, g, b), + min = Math.min(r, g, b); + var h = void 0, + s = void 0, + l = (max + min) / 2; + + if (max === min) { + h = s = 0; + } else { + var d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0);break; + case g: + h = (b - r) / d + 2;break; + case b: + h = (r - g) / d + 4;break; + } + + h /= 6; + } + + return [h, s, l, a]; + } + }, { + key: 'hslToRgb', + value: function hslToRgb(_ref3) { + var _ref4 = slicedToArray(_ref3, 4), + h = _ref4[0], + s = _ref4[1], + l = _ref4[2], + a = _ref4[3]; + + var r = void 0, + g = void 0, + b = void 0; + + if (s === 0) { + r = g = b = l; + } else { + var hue2rgb = function hue2rgb(p, q, t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; + }; + + var q = l < 0.5 ? l * (1 + s) : l + s - l * s, + p = 2 * l - q; + + r = hue2rgb(p, q, h + 1 / 3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1 / 3); + } + + var rgba = [r * 255, g * 255, b * 255].map(Math.round); + rgba[3] = a; + + return rgba; + } + }]); + return Color; + }(); + + var EventBucket = function () { + function EventBucket() { + classCallCheck(this, EventBucket); + + this._events = []; + } + + createClass(EventBucket, [{ + key: 'add', + value: function add(target, type, handler) { + target.addEventListener(type, handler, false); + this._events.push({ + target: target, + type: type, + handler: handler + }); + } + }, { + key: 'remove', + value: function remove(target, type, handler) { + this._events = this._events.filter(function (e) { + var isMatch = true; + if (target && target !== e.target) { + isMatch = false; + } + if (type && type !== e.type) { + isMatch = false; + } + if (handler && handler !== e.handler) { + isMatch = false; + } + + if (isMatch) { + EventBucket._doRemove(e.target, e.type, e.handler); + } + return !isMatch; + }); + } + }, { + key: 'destroy', + value: function destroy() { + this._events.forEach(function (e) { + return EventBucket._doRemove(e.target, e.type, e.handler); + }); + this._events = []; + } + }], [{ + key: '_doRemove', + value: function _doRemove(target, type, handler) { + target.removeEventListener(type, handler, false); + } + }]); + return EventBucket; + }(); + + function parseHTML(htmlString) { + + var div = document.createElement('div'); + div.innerHTML = htmlString; + return div.firstElementChild; + } + + function dragTrack(eventBucket, area, callback) { + var dragging = false; + + function clamp(val, min, max) { + return Math.max(min, Math.min(val, max)); + } + + function onMove(e, info, starting) { + if (starting) { + dragging = true; + } + if (!dragging) { + return; + } + + e.preventDefault(); + + var bounds = area.getBoundingClientRect(), + w = bounds.width, + h = bounds.height, + x = info.clientX, + y = info.clientY; + + var relX = clamp(x - bounds.left, 0, w), + relY = clamp(y - bounds.top, 0, h); + + callback(relX / w, relY / h); + } + + function onMouse(e, starting) { + var button = e.buttons === undefined ? e.which : e.buttons; + if (button === 1) { + onMove(e, e, starting); + } else { + dragging = false; + } + } + + function onTouch(e, starting) { + if (e.touches.length === 1) { + onMove(e, e.touches[0], starting); + } else { + dragging = false; + } + } + + eventBucket.add(area, 'mousedown', function (e) { + onMouse(e, true); + }); + eventBucket.add(area, 'touchstart', function (e) { + onTouch(e, true); + }); + eventBucket.add(window, 'mousemove', onMouse); + eventBucket.add(area, 'touchmove', onTouch); + eventBucket.add(window, 'mouseup', function (e) { + dragging = false; + }); + eventBucket.add(area, 'touchend', function (e) { + dragging = false; + }); + eventBucket.add(area, 'touchcancel', function (e) { + dragging = false; + }); + } + + var BG_TRANSP = 'url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'2\' height=\'2\'%3E%3Cpath d=\'M1,0H0V1H2V2H1\' fill=\'lightgrey\'/%3E%3C/svg%3E")'; + var HUES = 360; + + var EVENT_KEY = 'keydown', + EVENT_CLICK_OUTSIDE = 'mousedown', + EVENT_TAB_MOVE = 'focusin'; + + function $(selector, context) { + return (context || document).querySelector(selector); + } + + function stopEvent(e) { + + e.preventDefault(); + e.stopPropagation(); + } + function onKey(bucket, target, keys, handler, stop) { + bucket.add(target, EVENT_KEY, function (e) { + if (keys.indexOf(e.key) >= 0) { + if (stop) { + stopEvent(e); + } + handler(e); + } + }); + } + + var _style = document.createElement('style'); + _style.textContent = '.picker_wrapper.no_alpha .picker_alpha{display:none}.picker_wrapper.no_editor .picker_editor{position:absolute;z-index:-1;opacity:0}.picker_wrapper.no_cancel .picker_cancel{display:none}.layout_default.picker_wrapper{display:-webkit-box;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;flex-flow:row wrap;-webkit-box-pack:justify;justify-content:space-between;-webkit-box-align:stretch;align-items:stretch;font-size:10px;width:25em;padding:.5em}.layout_default.picker_wrapper input,.layout_default.picker_wrapper button{font-size:1rem}.layout_default.picker_wrapper>*{margin:.5em}.layout_default.picker_wrapper::before{content:\'\';display:block;width:100%;height:0;-webkit-box-ordinal-group:2;order:1}.layout_default .picker_slider,.layout_default .picker_selector{padding:1em}.layout_default .picker_hue{width:100%}.layout_default .picker_sl{-webkit-box-flex:1;flex:1 1 auto}.layout_default .picker_sl::before{content:\'\';display:block;padding-bottom:100%}.layout_default .picker_editor{-webkit-box-ordinal-group:2;order:1;width:6.5rem}.layout_default .picker_editor input{width:100%;height:100%}.layout_default .picker_sample{-webkit-box-ordinal-group:2;order:1;-webkit-box-flex:1;flex:1 1 auto}.layout_default .picker_done,.layout_default .picker_cancel{-webkit-box-ordinal-group:2;order:1}.picker_wrapper{box-sizing:border-box;background:#f2f2f2;box-shadow:0 0 0 1px silver;cursor:default;font-family:sans-serif;color:#444;pointer-events:auto}.picker_wrapper:focus{outline:none}.picker_wrapper button,.picker_wrapper input{box-sizing:border-box;border:none;box-shadow:0 0 0 1px silver;outline:none}.picker_wrapper button:focus,.picker_wrapper button:active,.picker_wrapper input:focus,.picker_wrapper input:active{box-shadow:0 0 2px 1px dodgerblue}.picker_wrapper button{padding:.4em .6em;cursor:pointer;background-color:whitesmoke;background-image:-webkit-gradient(linear, left bottom, left top, from(gainsboro), to(transparent));background-image:linear-gradient(0deg, gainsboro, transparent)}.picker_wrapper button:active{background-image:-webkit-gradient(linear, left bottom, left top, from(transparent), to(gainsboro));background-image:linear-gradient(0deg, transparent, gainsboro)}.picker_wrapper button:hover{background-color:white}.picker_selector{position:absolute;z-index:1;display:block;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);border:2px solid white;border-radius:100%;box-shadow:0 0 3px 1px #67b9ff;background:currentColor;cursor:pointer}.picker_slider .picker_selector{border-radius:2px}.picker_hue{position:relative;background-image:-webkit-gradient(linear, left top, right top, from(red), color-stop(yellow), color-stop(lime), color-stop(cyan), color-stop(blue), color-stop(magenta), to(red));background-image:linear-gradient(90deg, red, yellow, lime, cyan, blue, magenta, red);box-shadow:0 0 0 1px silver}.picker_sl{position:relative;box-shadow:0 0 0 1px silver;background-image:-webkit-gradient(linear, left top, left bottom, from(white), color-stop(50%, rgba(255,255,255,0))),-webkit-gradient(linear, left bottom, left top, from(black), color-stop(50%, rgba(0,0,0,0))),-webkit-gradient(linear, left top, right top, from(gray), to(rgba(128,128,128,0)));background-image:linear-gradient(180deg, white, rgba(255,255,255,0) 50%),linear-gradient(0deg, black, rgba(0,0,0,0) 50%),linear-gradient(90deg, gray, rgba(128,128,128,0))}.picker_alpha,.picker_sample{position:relative;background:url("data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'2\' height=\'2\'%3E%3Cpath d=\'M1,0H0V1H2V2H1\' fill=\'lightgrey\'/%3E%3C/svg%3E") left top/contain white;box-shadow:0 0 0 1px silver}.picker_alpha .picker_selector,.picker_sample .picker_selector{background:none}.picker_editor input{font-family:monospace;padding:.2em .4em}.picker_sample::before{content:\'\';position:absolute;display:block;width:100%;height:100%;background:currentColor}.picker_arrow{position:absolute;z-index:-1}.picker_wrapper.popup{position:absolute;z-index:2;margin:1.5em}.picker_wrapper.popup,.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{background:#f2f2f2;box-shadow:0 0 10px 1px rgba(0,0,0,0.4)}.picker_wrapper.popup .picker_arrow{width:3em;height:3em;margin:0}.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{content:"";display:block;position:absolute;top:0;left:0;z-index:-99}.picker_wrapper.popup .picker_arrow::before{width:100%;height:100%;-webkit-transform:skew(45deg);transform:skew(45deg);-webkit-transform-origin:0 100%;transform-origin:0 100%}.picker_wrapper.popup .picker_arrow::after{width:150%;height:150%;box-shadow:none}.popup.popup_top{bottom:100%;left:0}.popup.popup_top .picker_arrow{bottom:0;left:0;-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.popup.popup_bottom{top:100%;left:0}.popup.popup_bottom .picker_arrow{top:0;left:0;-webkit-transform:rotate(90deg) scale(1, -1);transform:rotate(90deg) scale(1, -1)}.popup.popup_left{top:0;right:100%}.popup.popup_left .picker_arrow{top:0;right:0;-webkit-transform:scale(-1, 1);transform:scale(-1, 1)}.popup.popup_right{top:0;left:100%}.popup.popup_right .picker_arrow{top:0;left:0}'; + document.documentElement.firstElementChild.appendChild(_style); + + var Picker = function () { + function Picker(options) { + classCallCheck(this, Picker); + + + this.settings = { + + popup: 'right', + layout: 'default', + alpha: true, + editor: true, + editorFormat: 'hex', + cancelButton: false, + defaultColor: '#0cf' + }; + + this._events = new EventBucket(); + + this.onChange = null; + + this.onDone = null; + + this.onOpen = null; + + this.onClose = null; + + this.setOptions(options); + } + + createClass(Picker, [{ + key: 'setOptions', + value: function setOptions(options) { + var _this = this; + + if (!options) { + return; + } + var settings = this.settings; + + function transfer(source, target, skipKeys) { + for (var key in source) { + if (skipKeys && skipKeys.indexOf(key) >= 0) { + continue; + } + + target[key] = source[key]; + } + } + + if (options instanceof HTMLElement) { + settings.parent = options; + } else { + + if (settings.parent && options.parent && settings.parent !== options.parent) { + this._events.remove(settings.parent); + this._popupInited = false; + } + + transfer(options, settings); + + if (options.onChange) { + this.onChange = options.onChange; + } + if (options.onDone) { + this.onDone = options.onDone; + } + if (options.onOpen) { + this.onOpen = options.onOpen; + } + if (options.onClose) { + this.onClose = options.onClose; + } + + var col = options.color || options.colour; + if (col) { + this._setColor(col); + } + } + + var parent = settings.parent; + if (parent && settings.popup && !this._popupInited) { + + var openProxy = function openProxy(e) { + return _this.openHandler(e); + }; + + this._events.add(parent, 'click', openProxy); + + onKey(this._events, parent, [' ', 'Spacebar', 'Enter'], openProxy); + + this._popupInited = true; + } else if (options.parent && !settings.popup) { + this.show(); + } + } + }, { + key: 'openHandler', + value: function openHandler(e) { + if (this.show()) { + + e && e.preventDefault(); + + this.settings.parent.style.pointerEvents = 'none'; + + var toFocus = e && e.type === EVENT_KEY ? this._domEdit : this.domElement; + setTimeout(function () { + return toFocus.focus(); + }, 100); + + if (this.onOpen) { + this.onOpen(this.colour); + } + } + } + }, { + key: 'closeHandler', + value: function closeHandler(e) { + var event = e && e.type; + var doHide = false; + + if (!e) { + doHide = true; + } else if (event === EVENT_CLICK_OUTSIDE || event === EVENT_TAB_MOVE) { + + var knownTime = (this.__containedEvent || 0) + 100; + if (e.timeStamp > knownTime) { + doHide = true; + } + } else { + + stopEvent(e); + + doHide = true; + } + + if (doHide && this.hide()) { + this.settings.parent.style.pointerEvents = ''; + + if (event !== EVENT_CLICK_OUTSIDE) { + this.settings.parent.focus(); + } + + if (this.onClose) { + this.onClose(this.colour); + } + } + } + }, { + key: 'movePopup', + value: function movePopup(options, open) { + + this.closeHandler(); + + this.setOptions(options); + if (open) { + this.openHandler(); + } + } + }, { + key: 'setColor', + value: function setColor(color, silent) { + this._setColor(color, { silent: silent }); + } + }, { + key: '_setColor', + value: function _setColor(color, flags) { + if (typeof color === 'string') { + color = color.trim(); + } + if (!color) { + return; + } + + flags = flags || {}; + var c = void 0; + try { + + c = new Color(color); + } catch (ex) { + if (flags.failSilently) { + return; + } + throw ex; + } + + if (!this.settings.alpha) { + var hsla = c.hsla; + hsla[3] = 1; + c.hsla = hsla; + } + this.colour = this.color = c; + this._setHSLA(null, null, null, null, flags); + } + }, { + key: 'setColour', + value: function setColour(colour, silent) { + this.setColor(colour, silent); + } + }, { + key: 'show', + value: function show() { + var parent = this.settings.parent; + if (!parent) { + return false; + } + + if (this.domElement) { + var toggled = this._toggleDOM(true); + + this._setPosition(); + + return toggled; + } + + var html = this.settings.template || '
    '; + var wrapper = parseHTML(html); + + this.domElement = wrapper; + this._domH = $('.picker_hue', wrapper); + this._domSL = $('.picker_sl', wrapper); + this._domA = $('.picker_alpha', wrapper); + this._domEdit = $('.picker_editor input', wrapper); + this._domSample = $('.picker_sample', wrapper); + this._domOkay = $('.picker_done button', wrapper); + this._domCancel = $('.picker_cancel button', wrapper); + + wrapper.classList.add('layout_' + this.settings.layout); + if (!this.settings.alpha) { + wrapper.classList.add('no_alpha'); + } + if (!this.settings.editor) { + wrapper.classList.add('no_editor'); + } + if (!this.settings.cancelButton) { + wrapper.classList.add('no_cancel'); + } + this._ifPopup(function () { + return wrapper.classList.add('popup'); + }); + + this._setPosition(); + + if (this.colour) { + this._updateUI(); + } else { + this._setColor(this.settings.defaultColor); + } + this._bindEvents(); + + return true; + } + }, { + key: 'hide', + value: function hide() { + return this._toggleDOM(false); + } + }, { + key: 'destroy', + value: function destroy() { + this._events.destroy(); + if (this.domElement) { + this.settings.parent.removeChild(this.domElement); + } + } + }, { + key: '_bindEvents', + value: function _bindEvents() { + var _this2 = this; + + var that = this, + dom = this.domElement, + events = this._events; + + function addEvent(target, type, handler) { + events.add(target, type, handler); + } + + addEvent(dom, 'click', function (e) { + return e.preventDefault(); + }); + + dragTrack(events, this._domH, function (x, y) { + return that._setHSLA(x); + }); + + dragTrack(events, this._domSL, function (x, y) { + return that._setHSLA(null, x, 1 - y); + }); + + if (this.settings.alpha) { + dragTrack(events, this._domA, function (x, y) { + return that._setHSLA(null, null, null, 1 - y); + }); + } + + var editInput = this._domEdit; + { + addEvent(editInput, 'input', function (e) { + that._setColor(this.value, { fromEditor: true, failSilently: true }); + }); + + addEvent(editInput, 'focus', function (e) { + var input = this; + + if (input.selectionStart === input.selectionEnd) { + input.select(); + } + }); + } + + this._ifPopup(function () { + + var popupCloseProxy = function popupCloseProxy(e) { + return _this2.closeHandler(e); + }; + + addEvent(window, EVENT_CLICK_OUTSIDE, popupCloseProxy); + addEvent(window, EVENT_TAB_MOVE, popupCloseProxy); + onKey(events, dom, ['Esc', 'Escape'], popupCloseProxy); + + var timeKeeper = function timeKeeper(e) { + _this2.__containedEvent = e.timeStamp; + }; + addEvent(dom, EVENT_CLICK_OUTSIDE, timeKeeper); + + addEvent(dom, EVENT_TAB_MOVE, timeKeeper); + + addEvent(_this2._domCancel, 'click', popupCloseProxy); + }); + + var onDoneProxy = function onDoneProxy(e) { + _this2._ifPopup(function () { + return _this2.closeHandler(e); + }); + if (_this2.onDone) { + _this2.onDone(_this2.colour); + } + }; + addEvent(this._domOkay, 'click', onDoneProxy); + onKey(events, dom, ['Enter'], onDoneProxy); + } + }, { + key: '_setPosition', + value: function _setPosition() { + var parent = this.settings.parent, + elm = this.domElement; + + if (parent !== elm.parentNode) { + parent.appendChild(elm); + } + + this._ifPopup(function (popup) { + + if (getComputedStyle(parent).position === 'static') { + parent.style.position = 'relative'; + } + + var cssClass = popup === true ? 'popup_right' : 'popup_' + popup; + + ['popup_top', 'popup_bottom', 'popup_left', 'popup_right'].forEach(function (c) { + + if (c === cssClass) { + elm.classList.add(c); + } else { + elm.classList.remove(c); + } + }); + + elm.classList.add(cssClass); + }); + } + }, { + key: '_setHSLA', + value: function _setHSLA(h, s, l, a, flags) { + flags = flags || {}; + + var col = this.colour, + hsla = col.hsla; + + [h, s, l, a].forEach(function (x, i) { + if (x || x === 0) { + hsla[i] = x; + } + }); + col.hsla = hsla; + + this._updateUI(flags); + + if (this.onChange && !flags.silent) { + this.onChange(col); + } + } + }, { + key: '_updateUI', + value: function _updateUI(flags) { + if (!this.domElement) { + return; + } + flags = flags || {}; + + var col = this.colour, + hsl = col.hsla, + cssHue = 'hsl(' + hsl[0] * HUES + ', 100%, 50%)', + cssHSL = col.hslString, + cssHSLA = col.hslaString; + + var uiH = this._domH, + uiSL = this._domSL, + uiA = this._domA, + thumbH = $('.picker_selector', uiH), + thumbSL = $('.picker_selector', uiSL), + thumbA = $('.picker_selector', uiA); + + function posX(parent, child, relX) { + child.style.left = relX * 100 + '%'; + } + function posY(parent, child, relY) { + child.style.top = relY * 100 + '%'; + } + + posX(uiH, thumbH, hsl[0]); + + this._domSL.style.backgroundColor = this._domH.style.color = cssHue; + + posX(uiSL, thumbSL, hsl[1]); + posY(uiSL, thumbSL, 1 - hsl[2]); + + uiSL.style.color = cssHSL; + + posY(uiA, thumbA, 1 - hsl[3]); + + var opaque = cssHSL, + transp = opaque.replace('hsl', 'hsla').replace(')', ', 0)'), + bg = 'linear-gradient(' + [opaque, transp] + ')'; + + this._domA.style.backgroundImage = bg + ', ' + BG_TRANSP; + + if (!flags.fromEditor) { + var format = this.settings.editorFormat, + alpha = this.settings.alpha; + + var value = void 0; + switch (format) { + case 'rgb': + value = col.printRGB(alpha);break; + case 'hsl': + value = col.printHSL(alpha);break; + default: + value = col.printHex(alpha); + } + this._domEdit.value = value; + } + + this._domSample.style.color = cssHSLA; + } + }, { + key: '_ifPopup', + value: function _ifPopup(actionIf, actionElse) { + if (this.settings.parent && this.settings.popup) { + actionIf && actionIf(this.settings.popup); + } else { + actionElse && actionElse(); + } + } + }, { + key: '_toggleDOM', + value: function _toggleDOM(toVisible) { + var dom = this.domElement; + if (!dom) { + return false; + } + + var displayStyle = toVisible ? '' : 'none', + toggle = dom.style.display !== displayStyle; + + if (toggle) { + dom.style.display = displayStyle; + } + return toggle; + } + }], [{ + key: 'StyleElement', + get: function get$$1() { + return _style; + } + }]); + return Picker; + }(); + + return Picker; + +}))); + + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ if(__webpack_module_cache__[moduleId]) { +/******/ return __webpack_module_cache__[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ id: moduleId, +/******/ loaded: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/amd define */ +/******/ !function() { +/******/ __webpack_require__.amdD = function () { +/******/ throw new Error('define cannot be used indirect'); +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/compat get default export */ +/******/ !function() { +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function() { return module['default']; } : +/******/ function() { return module; }; +/******/ __webpack_require__.d(getter, { a: getter }); +/******/ return getter; +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/define property getters */ +/******/ !function() { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = function(exports, definition) { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ !function() { +/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } +/******/ }(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ !function() { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/node module decorator */ +/******/ !function() { +/******/ __webpack_require__.nmd = function(module) { +/******/ module.paths = []; +/******/ if (!module.children) module.children = []; +/******/ return module; +/******/ }; +/******/ }(); +/******/ +/************************************************************************/ +/******/ // module exports must be returned from runtime so entry inlining is disabled +/******/ // startup +/******/ // Load entry module and return exports +/******/ return __webpack_require__(3161); +/******/ })() +; +}); \ No newline at end of file diff --git a/unpacked/panel/vendor/assets/stylesheets/img/jsoneditor-icons.svg b/unpacked/panel/vendor/assets/stylesheets/img/jsoneditor-icons.svg new file mode 100644 index 0000000..c2c2765 --- /dev/null +++ b/unpacked/panel/vendor/assets/stylesheets/img/jsoneditor-icons.svg @@ -0,0 +1,749 @@ + + + JSON Editor Icons + + + + image/svg+xml + + JSON Editor Icons + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/unpacked/panel/vendor/assets/stylesheets/jsoneditor.css b/unpacked/panel/vendor/assets/stylesheets/jsoneditor.css new file mode 100644 index 0000000..7cb9904 --- /dev/null +++ b/unpacked/panel/vendor/assets/stylesheets/jsoneditor.css @@ -0,0 +1,2004 @@ +.jsoneditor input, +.jsoneditor input:not([type]), +.jsoneditor input[type="text"], +.jsoneditor input[type="search"], +.jsoneditor-modal input, +.jsoneditor-modal input:not([type]), +.jsoneditor-modal input[type="text"], +.jsoneditor-modal input[type="search"] { + height: auto; + border: inherit; + box-shadow: none; + font-size: 14px; + box-sizing: inherit; + padding: inherit; + font-family: inherit; + transition: none; + line-height: 16px; +} + +.jsoneditor input:focus, +.jsoneditor input:not([type]):focus, +.jsoneditor input[type="text"]:focus, +.jsoneditor input[type="search"]:focus, +.jsoneditor-modal input:focus, +.jsoneditor-modal input:not([type]):focus, +.jsoneditor-modal input[type="text"]:focus, +.jsoneditor-modal input[type="search"]:focus { + border: inherit; + box-shadow: inherit; +} + +.jsoneditor textarea, +.jsoneditor-modal textarea { + height: inherit; +} + +.jsoneditor select, +.jsoneditor-modal select { + display: inherit; + height: inherit; +} + +.jsoneditor label, +.jsoneditor-modal label { + font-size: inherit; + font-weight: inherit; + color: inherit; +} + +.jsoneditor table, +.jsoneditor-modal table { + border-collapse: collapse; + width: auto; +} + +.jsoneditor td, +.jsoneditor th, +.jsoneditor-modal td, +.jsoneditor-modal th { + padding: 0; + display: table-cell; + text-align: left; + vertical-align: inherit; + border-radius: inherit; +} + +.jsoneditor .autocomplete.dropdown { + position: absolute; + background: #ffffff; + box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3); + border: 1px solid #d3d3d3; + overflow-x: hidden; + overflow-y: auto; + cursor: default; + margin: 0; + padding: 5px; + text-align: left; + outline: 0; + font-family: "dejavu sans mono", "droid sans mono", consolas, monaco, "lucida console", "courier new", courier, monospace, sans-serif; + font-size: 10pt; +} + +.jsoneditor .autocomplete.dropdown .item { + color: #333; +} + +.jsoneditor .autocomplete.dropdown .item.hover { + background-color: #ddd; +} + +.jsoneditor .autocomplete.hint { + color: #aaa; + top: 4px; + left: 4px; +} + +.jsoneditor-contextmenu-root { + position: relative; + width: 0; + height: 0; +} + +.jsoneditor-contextmenu { + position: absolute; + box-sizing: content-box; + z-index: 2; +} + +.jsoneditor-contextmenu .jsoneditor-menu { + position: relative; + left: 0; + top: 0; + width: 128px; + height: auto; + background: #ffffff; + border: 1px solid #d3d3d3; + box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3); + list-style: none; + margin: 0; + padding: 0; +} + +.jsoneditor-contextmenu .jsoneditor-menu button { + position: relative; + padding: 0 8px 0 0; + margin: 0; + width: 128px; + height: auto; + border: none; + cursor: pointer; + color: #4d4d4d; + background: transparent; + font-size: 10pt; + font-family: arial, sans-serif; + box-sizing: border-box; + text-align: left; +} + +.jsoneditor-contextmenu .jsoneditor-menu button::-moz-focus-inner { + padding: 0; + border: 0; +} + +.jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-default { + width: 96px; +} + +.jsoneditor-contextmenu .jsoneditor-menu button.jsoneditor-expand { + float: right; + width: 32px; + height: 24px; + border-left: 1px solid #e5e5e5; +} + +.jsoneditor-contextmenu .jsoneditor-menu li { + overflow: hidden; +} + +.jsoneditor-contextmenu .jsoneditor-menu li ul { + display: none; + position: relative; + left: -10px; + top: 0; + border: none; + box-shadow: inset 0 0 10px rgba(128, 128, 128, 0.5); + padding: 0 10px; + -webkit-transition: all 0.3s ease-out; + -moz-transition: all 0.3s ease-out; + -o-transition: all 0.3s ease-out; + transition: all 0.3s ease-out; +} + +.jsoneditor-contextmenu .jsoneditor-menu li ul .jsoneditor-icon { + margin-left: 24px; +} + +.jsoneditor-contextmenu .jsoneditor-menu li ul li button { + padding-left: 24px; + animation: all ease-in-out 1s; +} + +.jsoneditor-contextmenu .jsoneditor-menu li button .jsoneditor-expand { + position: absolute; + top: 0; + right: 0; + width: 24px; + height: 24px; + padding: 0; + margin: 0 4px 0 0; + background: url("img/jsoneditor-icons.svg") 0 -72px; +} + +.jsoneditor-contextmenu .jsoneditor-icon { + position: absolute; + top: 0; + left: 0; + width: 24px; + height: 24px; + border: none; + padding: 0; + margin: 0; + background-image: url("img/jsoneditor-icons.svg"); +} + +.jsoneditor-contextmenu .jsoneditor-text { + padding: 4px 0 4px 24px; + word-wrap: break-word; +} + +.jsoneditor-contextmenu .jsoneditor-text.jsoneditor-right-margin { + padding-right: 24px; +} + +.jsoneditor-contextmenu .jsoneditor-separator { + height: 0; + border-top: 1px solid #e5e5e5; + padding-top: 5px; + margin-top: 5px; +} + +.jsoneditor-contextmenu button.jsoneditor-remove .jsoneditor-icon { + background-position: -24px 0; +} + +.jsoneditor-contextmenu button.jsoneditor-append .jsoneditor-icon { + background-position: 0 0; +} + +.jsoneditor-contextmenu button.jsoneditor-insert .jsoneditor-icon { + background-position: 0 0; +} + +.jsoneditor-contextmenu button.jsoneditor-duplicate .jsoneditor-icon { + background-position: -48px 0; +} + +.jsoneditor-contextmenu button.jsoneditor-sort-asc .jsoneditor-icon { + background-position: -168px 0; +} + +.jsoneditor-contextmenu button.jsoneditor-sort-desc .jsoneditor-icon { + background-position: -192px 0; +} + +.jsoneditor-contextmenu button.jsoneditor-transform .jsoneditor-icon { + background-position: -216px 0; +} + +.jsoneditor-contextmenu button.jsoneditor-extract .jsoneditor-icon { + background-position: 0 -24px; +} + +.jsoneditor-contextmenu button.jsoneditor-type-string .jsoneditor-icon { + background-position: -144px 0; +} + +.jsoneditor-contextmenu button.jsoneditor-type-auto .jsoneditor-icon { + background-position: -120px 0; +} + +.jsoneditor-contextmenu button.jsoneditor-type-object .jsoneditor-icon { + background-position: -72px 0; +} + +.jsoneditor-contextmenu button.jsoneditor-type-array .jsoneditor-icon { + background-position: -96px 0; +} + +.jsoneditor-contextmenu button.jsoneditor-type-modes .jsoneditor-icon { + background-image: none; + width: 6px; +} + +.jsoneditor-contextmenu ul, +.jsoneditor-contextmenu li { + box-sizing: content-box; + position: relative; +} + +.jsoneditor-contextmenu .jsoneditor-menu button:hover, +.jsoneditor-contextmenu .jsoneditor-menu button:focus { + color: #1a1a1a; + background-color: #f5f5f5; + outline: none; +} + +.jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected, +.jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:hover, +.jsoneditor-contextmenu .jsoneditor-menu li button.jsoneditor-selected:focus { + color: #ffffff; + background-color: #ee422e; +} + +.jsoneditor-contextmenu .jsoneditor-menu li ul li button:hover, +.jsoneditor-contextmenu .jsoneditor-menu li ul li button:focus { + background-color: #f5f5f5; +} + +.jsoneditor-modal { + max-width: 95%; + border-radius: 2px !important; + padding: 45px 15px 15px 15px !important; + box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3); + color: #4d4d4d; + line-height: 1.3em; +} + +.jsoneditor-modal.jsoneditor-modal-transform { + width: 600px !important; +} + +.jsoneditor-modal .pico-modal-header { + position: absolute; + box-sizing: border-box; + top: 0; + left: 0; + width: 100%; + padding: 0 10px; + height: 30px; + line-height: 30px; + font-family: arial, sans-serif; + font-size: 11pt; + background: #3883fa; + color: #ffffff; +} + +.jsoneditor-modal table { + width: 100%; +} + +.jsoneditor-modal table td { + padding: 3px 0; +} + +.jsoneditor-modal table td.jsoneditor-modal-input { + text-align: right; + padding-right: 0; + white-space: nowrap; +} + +.jsoneditor-modal table td.jsoneditor-modal-actions { + padding-top: 15px; +} + +.jsoneditor-modal table th { + vertical-align: middle; +} + +.jsoneditor-modal p:first-child { + margin-top: 0; +} + +.jsoneditor-modal a { + color: #3883fa; +} + +.jsoneditor-modal .jsoneditor-jmespath-block { + margin-bottom: 10px; +} + +.jsoneditor-modal .pico-close { + background: none !important; + font-size: 24px !important; + top: 7px !important; + right: 7px !important; + color: #ffffff; +} + +.jsoneditor-modal input { + padding: 4px; +} + +.jsoneditor-modal input[type="text"] { + cursor: inherit; +} + +.jsoneditor-modal input[disabled] { + background: #d3d3d3; + color: #808080; +} + +.jsoneditor-modal .jsoneditor-select-wrapper { + position: relative; + display: inline-block; +} + +.jsoneditor-modal .jsoneditor-select-wrapper:after { + content: ""; + width: 0; + height: 0; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + border-top: 6px solid #666; + position: absolute; + right: 8px; + top: 14px; + pointer-events: none; +} + +.jsoneditor-modal select { + padding: 3px 24px 3px 10px; + min-width: 180px; + max-width: 350px; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + text-indent: 0; + text-overflow: ""; + font-size: 10pt; + line-height: 1.5em; +} + +.jsoneditor-modal select::-ms-expand { + display: none; +} + +.jsoneditor-modal .jsoneditor-button-group input { + padding: 4px 10px; + margin: 0; + border-radius: 0; + border-left-style: none; +} + +.jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-first { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; + border-left-style: solid; +} + +.jsoneditor-modal .jsoneditor-button-group input.jsoneditor-button-last { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} + +.jsoneditor-modal .jsoneditor-transform-preview { + background: #f5f5f5; + height: 200px; +} + +.jsoneditor-modal .jsoneditor-transform-preview.jsoneditor-error { + color: #ee422e; +} + +.jsoneditor-modal .jsoneditor-jmespath-wizard { + line-height: 1.2em; + width: 100%; + padding: 0; + border-radius: 3px; +} + +.jsoneditor-modal .jsoneditor-jmespath-label { + font-weight: bold; + color: dodgerblue; + margin-top: 20px; + margin-bottom: 5px; +} + +.jsoneditor-modal .jsoneditor-jmespath-wizard-table { + width: 100%; + border-collapse: collapse; +} + +.jsoneditor-modal .jsoneditor-jmespath-wizard-label { + font-style: italic; + margin: 4px 0 2px 0; +} + +.jsoneditor-modal .jsoneditor-inline { + position: relative; + display: inline-block; + width: 100%; + padding-top: 2px; + padding-bottom: 2px; +} + +.jsoneditor-modal .jsoneditor-inline:not(:last-child) { + padding-right: 2px; +} + +.jsoneditor-modal .jsoneditor-jmespath-filter { + display: flex; + flex-wrap: wrap; +} + +.jsoneditor-modal .jsoneditor-jmespath-filter-field { + width: 180px; +} + +.jsoneditor-modal .jsoneditor-jmespath-filter-relation { + width: 100px; +} + +.jsoneditor-modal .jsoneditor-jmespath-filter-value { + min-width: 180px; + flex: 1; +} + +.jsoneditor-modal .jsoneditor-jmespath-sort-field { + width: 170px; +} + +.jsoneditor-modal .jsoneditor-jmespath-sort-order { + width: 150px; +} + +.jsoneditor-modal .jsoneditor-jmespath-select-fields { + width: 100%; +} + +.jsoneditor-modal .selectr-selected { + border-color: #d3d3d3; + padding: 4px 28px 4px 8px; +} + +.jsoneditor-modal .selectr-selected .selectr-tag { + background-color: #3883fa; + border-radius: 5px; +} + +.jsoneditor-modal table th, +.jsoneditor-modal table td { + text-align: left; + vertical-align: middle; + font-weight: normal; + color: #4d4d4d; + border-spacing: 0; + border-collapse: collapse; +} + +.jsoneditor-modal select, +.jsoneditor-modal textarea, +.jsoneditor-modal input, +.jsoneditor-modal input[type="text"], +.jsoneditor-modal input[type="text"]:focus, +.jsoneditor-modal #query { + background: #ffffff; + border: 1px solid #d3d3d3; + color: #4d4d4d; + border-radius: 3px; + padding: 4px; +} + +.jsoneditor-modal, +.jsoneditor-modal table td, +.jsoneditor-modal table th, +.jsoneditor-modal select, +.jsoneditor-modal option, +.jsoneditor-modal textarea, +.jsoneditor-modal input, +.jsoneditor-modal input[type="text"], +.jsoneditor-modal #query { + font-size: 10.5pt; + font-family: arial, sans-serif; +} + +.jsoneditor-modal #query, +.jsoneditor-modal .jsoneditor-transform-preview { + font-family: "dejavu sans mono", "droid sans mono", consolas, monaco, "lucida console", "courier new", courier, monospace, sans-serif; + font-size: 10pt; + width: 100%; + box-sizing: border-box; +} + +.jsoneditor-modal input[type="button"], +.jsoneditor-modal input[type="submit"] { + background: #f5f5f5; + padding: 4px 20px; +} + +.jsoneditor-modal select, +.jsoneditor-modal input { + cursor: pointer; +} + +.jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-asc input.jsoneditor-button-asc, +.jsoneditor-modal .jsoneditor-button-group.jsoneditor-button-group-value-desc input.jsoneditor-button-desc { + background: #3883fa; + border-color: #3883fa; + color: #ffffff; +} + +.jsoneditor { + color: #1a1a1a; + border: thin solid #3883fa; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + width: 100%; + height: 100%; + position: relative; + padding: 0; + line-height: 100%; +} + +div.jsoneditor-field, +div.jsoneditor-value, +div.jsoneditor-readonly, +div.jsoneditor-default { + border: 1px solid transparent; + min-height: 16px; + min-width: 32px; + padding: 2px; + margin: 1px; + word-wrap: break-word; + float: left; +} + +div.jsoneditor-field p, +div.jsoneditor-value p { + margin: 0; +} + +div.jsoneditor-value { + word-break: break-word; +} + +div.jsoneditor-value.jsoneditor-empty::after { + content: "value"; +} + +div.jsoneditor-value.jsoneditor-string { + color: #006000; +} + +div.jsoneditor-value.jsoneditor-number { + color: #ee422e; +} + +div.jsoneditor-value.jsoneditor-boolean { + color: #ff8c00; +} + +div.jsoneditor-value.jsoneditor-null { + color: #004ed0; +} + +div.jsoneditor-value.jsoneditor-color-value { + color: #1a1a1a; +} + +div.jsoneditor-value.jsoneditor-invalid { + color: #1a1a1a; +} + +div.jsoneditor-readonly { + min-width: 16px; + color: #808080; +} + +div.jsoneditor-empty { + border-color: #d3d3d3; + border-style: dashed; + border-radius: 2px; +} + +div.jsoneditor-field.jsoneditor-empty::after { + content: "field"; +} + +div.jsoneditor td { + vertical-align: top; +} + +div.jsoneditor td.jsoneditor-separator { + padding: 3px 0; + vertical-align: top; + color: #808080; +} + +div.jsoneditor td.jsoneditor-tree { + vertical-align: top; +} + +div.jsoneditor.busy pre.jsoneditor-preview { + background: #f5f5f5; + color: #808080; +} + +div.jsoneditor.busy div.jsoneditor-busy { + display: inherit; +} + +div.jsoneditor code.jsoneditor-preview { + background: none; +} + +div.jsoneditor.jsoneditor-mode-preview pre.jsoneditor-preview { + width: 100%; + height: 100%; + box-sizing: border-box; + overflow: auto; + padding: 2px; + margin: 0; + white-space: pre-wrap; + word-break: break-all; +} + +div.jsoneditor-default { + color: #808080; + padding-left: 10px; +} + +div.jsoneditor-tree { + width: 100%; + height: 100%; + position: relative; + overflow: auto; +} + +div.jsoneditor-tree button.jsoneditor-button { + width: 24px; + height: 24px; + padding: 0; + margin: 0; + border: none; + cursor: pointer; + background: transparent url("img/jsoneditor-icons.svg"); +} + +div.jsoneditor-tree button.jsoneditor-button:focus { + background-color: #f5f5f5; + outline: #e5e5e5 solid 1px; +} + +div.jsoneditor-tree button.jsoneditor-collapsed { + background-position: 0 -48px; +} + +div.jsoneditor-tree button.jsoneditor-expanded { + background-position: 0 -72px; +} + +div.jsoneditor-tree button.jsoneditor-contextmenu-button { + background-position: -48px -72px; +} + +div.jsoneditor-tree button.jsoneditor-invisible { + visibility: hidden; + background: none; +} + +div.jsoneditor-tree button.jsoneditor-dragarea { + background: url("img/jsoneditor-icons.svg") -72px -72px; + cursor: move; +} + +div.jsoneditor-tree *:focus { + outline: none; +} + +div.jsoneditor-tree div.jsoneditor-show-more { + display: inline-block; + padding: 3px 4px; + margin: 2px 0; + background-color: #e5e5e5; + border-radius: 3px; + color: #808080; + font-family: arial, sans-serif; + font-size: 10pt; +} + +div.jsoneditor-tree div.jsoneditor-show-more a { + display: inline-block; + color: #808080; +} + +div.jsoneditor-tree div.jsoneditor-color { + display: inline-block; + width: 12px; + height: 12px; + margin: 4px; + border: 1px solid #808080; + cursor: pointer; +} + +div.jsoneditor-tree div.jsoneditor-date { + background: #a1a1a1; + color: #ffffff; + font-family: arial, sans-serif; + border-radius: 3px; + display: inline-block; + padding: 3px; + margin: 0 3px; +} + +div.jsoneditor-tree table.jsoneditor-tree { + border-collapse: collapse; + border-spacing: 0; + width: 100%; +} + +div.jsoneditor-tree .jsoneditor-button.jsoneditor-schema-error { + width: 24px; + height: 24px; + padding: 0; + margin: 0 4px 0 0; + background: url("img/jsoneditor-icons.svg") -168px -48px; +} + +div.jsoneditor-outer { + position: static; + width: 100%; + height: 100%; + margin: 0; + padding: 0; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +div.jsoneditor-outer.has-nav-bar { + margin-top: -26px; + padding-top: 26px; +} + +div.jsoneditor-outer.has-nav-bar.has-main-menu-bar { + margin-top: -61px; + padding-top: 61px; +} + +div.jsoneditor-outer.has-status-bar { + margin-bottom: -26px; + padding-bottom: 26px; +} + +div.jsoneditor-outer.has-main-menu-bar { + margin-top: -35px; + padding-top: 35px; +} + +div.jsoneditor-busy { + position: absolute; + top: 15%; + left: 0; + box-sizing: border-box; + width: 100%; + text-align: center; + display: none; +} + +div.jsoneditor-busy span { + background-color: #ffffab; + border: 1px solid #ffee00; + border-radius: 3px; + padding: 5px 15px; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.4); +} + +div.jsoneditor-field.jsoneditor-empty::after, +div.jsoneditor-value.jsoneditor-empty::after { + pointer-events: none; + color: #d3d3d3; + font-size: 8pt; +} + +div.jsoneditor-value.jsoneditor-url, +a.jsoneditor-value.jsoneditor-url { + color: #006000; + text-decoration: underline; +} + +a.jsoneditor-value.jsoneditor-url { + display: inline-block; + padding: 2px; + margin: 2px; +} + +a.jsoneditor-value.jsoneditor-url:hover, +a.jsoneditor-value.jsoneditor-url:focus { + color: #ee422e; +} + +div.jsoneditor-field[contenteditable="true"]:focus, +div.jsoneditor-field[contenteditable="true"]:hover, +div.jsoneditor-value[contenteditable="true"]:focus, +div.jsoneditor-value[contenteditable="true"]:hover, +div.jsoneditor-field.jsoneditor-highlight, +div.jsoneditor-value.jsoneditor-highlight { + background-color: #ffffab; + border: 1px solid #ffee00; + border-radius: 2px; +} + +div.jsoneditor-field.jsoneditor-highlight-active, +div.jsoneditor-field.jsoneditor-highlight-active:focus, +div.jsoneditor-field.jsoneditor-highlight-active:hover, +div.jsoneditor-value.jsoneditor-highlight-active, +div.jsoneditor-value.jsoneditor-highlight-active:focus, +div.jsoneditor-value.jsoneditor-highlight-active:hover { + background-color: #ffee00; + border: 1px solid #ffc700; + border-radius: 2px; +} + +div.jsoneditor-value.jsoneditor-object, +div.jsoneditor-value.jsoneditor-array { + min-width: 16px; +} + +div.jsoneditor-tree button.jsoneditor-contextmenu-button:hover, +div.jsoneditor-tree button.jsoneditor-contextmenu-button:focus, +div.jsoneditor-tree button.jsoneditor-contextmenu-button.jsoneditor-selected, +tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button { + background-position: -48px -48px; +} + +div.jsoneditor-tree div.jsoneditor-show-more a:hover, +div.jsoneditor-tree div.jsoneditor-show-more a:focus { + color: #ee422e; +} + +textarea.jsoneditor-text, +.ace-jsoneditor { + min-height: 150px; +} + +textarea.jsoneditor-text *, +.ace-jsoneditor * { + font-family: "dejavu sans mono", "droid sans mono", consolas, monaco, "lucida console", "courier new", courier, monospace, sans-serif; +} + +textarea.jsoneditor-text { + width: 100%; + height: 100%; + margin: 0; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + outline-width: 0; + border: none; + background-color: #ffffff; + resize: none; +} + +tr.jsoneditor-highlight, +tr.jsoneditor-selected { + background-color: #d3d3d3; +} + +tr.jsoneditor-selected button.jsoneditor-dragarea, +tr.jsoneditor-selected button.jsoneditor-contextmenu-button { + visibility: hidden; +} + +tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea, +tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-contextmenu-button { + visibility: visible; +} + +div.jsoneditor-tree button.jsoneditor-dragarea:hover, +div.jsoneditor-tree button.jsoneditor-dragarea:focus, +tr.jsoneditor-selected.jsoneditor-first button.jsoneditor-dragarea { + background-position: -72px -48px; +} + +div.jsoneditor tr, +div.jsoneditor th, +div.jsoneditor td { + padding: 0; + margin: 0; +} + +div.jsoneditor-field, +div.jsoneditor-value, +div.jsoneditor td, +div.jsoneditor th, +div.jsoneditor textarea, +pre.jsoneditor-preview, +.jsoneditor-schema-error, +.jsoneditor-popover { + font-family: "dejavu sans mono", "droid sans mono", consolas, monaco, "lucida console", "courier new", courier, monospace, sans-serif; + font-size: 10pt; + color: #1a1a1a; +} + +.jsoneditor-schema-error { + cursor: default; + display: inline-block; + height: 24px; + line-height: 24px; + position: relative; + text-align: center; + width: 24px; +} + +.jsoneditor-popover { + background-color: #4c4c4c; + border-radius: 3px; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.4); + color: #ffffff; + padding: 7px 10px; + position: absolute; + cursor: auto; + width: 200px; +} + +.jsoneditor-popover.jsoneditor-above { + bottom: 32px; + left: -98px; +} + +.jsoneditor-popover.jsoneditor-above:before { + border-top: 7px solid #4c4c4c; + bottom: -7px; +} + +.jsoneditor-popover.jsoneditor-below { + top: 32px; + left: -98px; +} + +.jsoneditor-popover.jsoneditor-below:before { + border-bottom: 7px solid #4c4c4c; + top: -7px; +} + +.jsoneditor-popover.jsoneditor-left { + top: -7px; + right: 32px; +} + +.jsoneditor-popover.jsoneditor-left:before { + border-left: 7px solid #4c4c4c; + border-top: 7px solid transparent; + border-bottom: 7px solid transparent; + content: ""; + top: 19px; + right: -14px; + left: inherit; + margin-left: inherit; + margin-top: -7px; + position: absolute; +} + +.jsoneditor-popover.jsoneditor-right { + top: -7px; + left: 32px; +} + +.jsoneditor-popover.jsoneditor-right:before { + border-right: 7px solid #4c4c4c; + border-top: 7px solid transparent; + border-bottom: 7px solid transparent; + content: ""; + top: 19px; + left: -14px; + margin-left: inherit; + margin-top: -7px; + position: absolute; +} + +.jsoneditor-popover:before { + border-right: 7px solid transparent; + border-left: 7px solid transparent; + content: ""; + display: block; + left: 50%; + margin-left: -7px; + position: absolute; +} + +.jsoneditor-text-errors tr.jump-to-line:hover { + text-decoration: underline; + cursor: pointer; +} + +.jsoneditor-schema-error:hover .jsoneditor-popover, +.jsoneditor-schema-error:focus .jsoneditor-popover { + display: block; + animation: fade-in 0.3s linear 1, move-up 0.3s linear 1; +} + +@keyframes fade-in { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + +/* JSON schema errors displayed at the bottom of the editor in mode text and code */ + +.jsoneditor .jsoneditor-validation-errors-container { + max-height: 130px; + overflow-y: auto; +} + +.jsoneditor .jsoneditor-validation-errors { + width: 100%; + overflow: hidden; +} + +.jsoneditor .jsoneditor-additional-errors { + position: absolute; + margin: auto; + bottom: 31px; + left: calc(50% - 92px); + color: #808080; + background-color: #ebebeb; + padding: 7px 15px; + border-radius: 8px; +} + +.jsoneditor .jsoneditor-additional-errors.visible { + visibility: visible; + opacity: 1; + transition: opacity 2s linear; +} + +.jsoneditor .jsoneditor-additional-errors.hidden { + visibility: hidden; + opacity: 0; + transition: visibility 0s 2s, opacity 2s linear; +} + +.jsoneditor .jsoneditor-text-errors { + width: 100%; + border-collapse: collapse; + border-top: 1px solid #ffc700; +} + +.jsoneditor .jsoneditor-text-errors td { + padding: 3px 6px; + vertical-align: middle; +} + +.jsoneditor .jsoneditor-text-errors td pre { + margin: 0; + white-space: normal; +} + +.jsoneditor .jsoneditor-text-errors tr { + background-color: #ffffab; +} + +.jsoneditor .jsoneditor-text-errors tr.parse-error { + background-color: #ee2e2e70; +} + +.jsoneditor-text-errors .jsoneditor-schema-error { + border: none; + width: 24px; + height: 24px; + padding: 0; + margin: 0 4px 0 0; + cursor: pointer; +} + +.jsoneditor-text-errors tr .jsoneditor-schema-error { + background: url("img/jsoneditor-icons.svg") -168px -48px; +} + +.jsoneditor-text-errors tr.parse-error .jsoneditor-schema-error { + background: url("img/jsoneditor-icons.svg") -25px 0px; +} + +.jsoneditor-anchor { + cursor: pointer; +} + +.jsoneditor-anchor .picker_wrapper.popup.popup_bottom { + top: 28px; + left: -10px; +} + +.fadein { + -webkit-animation: fadein 0.3s; + animation: fadein 0.3s; + -moz-animation: fadein 0.3s; + -o-animation: fadein 0.3s; +} + +@keyframes fadein { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +.jsoneditor-modal input[type="search"].selectr-input { + border: 1px solid #d3d3d3; + width: calc(100% - 4px); + margin: 2px; + padding: 4px; + box-sizing: border-box; +} + +.jsoneditor-modal button.selectr-input-clear { + right: 8px; +} + +.jsoneditor-menu { + width: 100%; + height: 35px; + padding: 2px; + margin: 0; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + color: #ffffff; + background-color: #3883fa; + border-bottom: 1px solid #3883fa; +} + +.jsoneditor-menu > button, +.jsoneditor-menu > .jsoneditor-modes > button { + width: 26px; + height: 26px; + margin: 2px; + padding: 0; + border-radius: 2px; + border: 1px solid transparent; + background: transparent url("img/jsoneditor-icons.svg"); + color: #ffffff; + opacity: 0.8; + font-family: arial, sans-serif; + font-size: 10pt; + float: left; +} + +.jsoneditor-menu > button:hover, +.jsoneditor-menu > .jsoneditor-modes > button:hover { + background-color: rgba(255, 255, 255, 0.2); + border: 1px solid rgba(255, 255, 255, 0.4); +} + +.jsoneditor-menu > button:focus, +.jsoneditor-menu > button:active, +.jsoneditor-menu > .jsoneditor-modes > button:focus, +.jsoneditor-menu > .jsoneditor-modes > button:active { + background-color: rgba(255, 255, 255, 0.3); +} + +.jsoneditor-menu > button:disabled, +.jsoneditor-menu > .jsoneditor-modes > button:disabled { + opacity: 0.5; + background-color: transparent; + border: none; +} + +.jsoneditor-menu > button.jsoneditor-collapse-all { + background-position: 0 -96px; +} + +.jsoneditor-menu > button.jsoneditor-expand-all { + background-position: 0 -120px; +} + +.jsoneditor-menu > button.jsoneditor-sort { + background-position: -120px -96px; +} + +.jsoneditor-menu > button.jsoneditor-transform { + background-position: -144px -96px; +} + +.jsoneditor.jsoneditor-mode-view > .jsoneditor-menu > button.jsoneditor-sort, +.jsoneditor.jsoneditor-mode-form > .jsoneditor-menu > button.jsoneditor-sort, +.jsoneditor.jsoneditor-mode-view > .jsoneditor-menu > button.jsoneditor-transform, +.jsoneditor.jsoneditor-mode-form > .jsoneditor-menu > button.jsoneditor-transform { + display: none; +} + +.jsoneditor-menu > button.jsoneditor-undo { + background-position: -24px -96px; +} + +.jsoneditor-menu > button.jsoneditor-undo:disabled { + background-position: -24px -120px; +} + +.jsoneditor-menu > button.jsoneditor-redo { + background-position: -48px -96px; +} + +.jsoneditor-menu > button.jsoneditor-redo:disabled { + background-position: -48px -120px; +} + +.jsoneditor-menu > button.jsoneditor-compact { + background-position: -72px -96px; +} + +.jsoneditor-menu > button.jsoneditor-format { + background-position: -72px -120px; +} + +.jsoneditor-menu > button.jsoneditor-repair { + background-position: -96px -96px; +} + +.jsoneditor-menu > .jsoneditor-modes { + display: inline-block; + float: left; +} + +.jsoneditor-menu > .jsoneditor-modes > button { + background-image: none; + width: auto; + padding-left: 6px; + padding-right: 6px; +} + +.jsoneditor-menu > button.jsoneditor-separator, +.jsoneditor-menu > .jsoneditor-modes > button.jsoneditor-separator { + margin-left: 10px; +} + +.jsoneditor-menu a { + font-family: arial, sans-serif; + font-size: 10pt; + color: #ffffff; + opacity: 0.8; + vertical-align: middle; +} + +.jsoneditor-menu a:hover { + opacity: 1; +} + +.jsoneditor-menu a.jsoneditor-poweredBy { + font-size: 8pt; + position: absolute; + right: 0; + top: 0; + padding: 10px; +} + +.jsoneditor-navigation-bar { + width: 100%; + height: 26px; + line-height: 26px; + padding: 0; + margin: 0; + border-bottom: 1px solid #d3d3d3; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + color: #808080; + background-color: #ebebeb; + overflow: hidden; + font-family: arial, sans-serif; + font-size: 10pt; +} + +.jsoneditor-search { + font-family: arial, sans-serif; + position: absolute; + right: 4px; + top: 4px; + border-collapse: collapse; + border-spacing: 0; + display: flex; +} + +.jsoneditor-search input { + color: #1a1a1a; + width: 120px; + border: none; + outline: none; + margin: 1px; + line-height: 20px; + font-family: arial, sans-serif; +} + +.jsoneditor-search button { + width: 16px; + height: 24px; + padding: 0; + margin: 0; + border: none; + background: url("img/jsoneditor-icons.svg"); + vertical-align: top; +} + +.jsoneditor-search button:hover { + background-color: transparent; +} + +.jsoneditor-search button.jsoneditor-refresh { + width: 18px; + background-position: -99px -73px; +} + +.jsoneditor-search button.jsoneditor-next { + cursor: pointer; + background-position: -124px -73px; +} + +.jsoneditor-search button.jsoneditor-next:hover { + background-position: -124px -49px; +} + +.jsoneditor-search button.jsoneditor-previous { + cursor: pointer; + background-position: -148px -73px; + margin-right: 2px; +} + +.jsoneditor-search button.jsoneditor-previous:hover { + background-position: -148px -49px; +} + +.jsoneditor-results { + font-family: arial, sans-serif; + color: #ffffff; + padding-right: 5px; + line-height: 26px; +} + +.jsoneditor-frame { + border: 1px solid transparent; + background-color: #ffffff; + padding: 0 2px; + margin: 0; +} + +.jsoneditor-statusbar { + line-height: 26px; + height: 26px; + color: #808080; + background-color: #ebebeb; + border-top: 1px solid #d3d3d3; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + font-size: 10pt; +} + +.jsoneditor-statusbar > .jsoneditor-curserinfo-val { + margin-right: 12px; +} + +.jsoneditor-statusbar > .jsoneditor-curserinfo-count { + margin-left: 4px; +} + +.jsoneditor-statusbar > .jsoneditor-validation-error-icon { + float: right; + width: 24px; + height: 24px; + padding: 0; + margin-top: 1px; + background: url("img/jsoneditor-icons.svg") -168px -48px; + cursor: pointer; +} + +.jsoneditor-statusbar > .jsoneditor-validation-error-count { + float: right; + margin: 0 4px 0 0; + cursor: pointer; +} + +.jsoneditor-statusbar > .jsoneditor-parse-error-icon { + float: right; + width: 24px; + height: 24px; + padding: 0; + margin: 1px; + background: url("img/jsoneditor-icons.svg") -25px 0px; +} + +.jsoneditor-statusbar .jsoneditor-array-info a { + color: inherit; +} + +div.jsoneditor-statusbar > .jsoneditor-curserinfo-label, +div.jsoneditor-statusbar > .jsoneditor-size-info { + margin: 0 4px; +} + +.jsoneditor-treepath { + padding: 0 5px; + overflow: hidden; + white-space: nowrap; + outline: none; +} + +.jsoneditor-treepath.show-all { + word-wrap: break-word; + white-space: normal; + position: absolute; + background-color: #ebebeb; + z-index: 1; + box-shadow: 2px 2px 12px rgba(128, 128, 128, 0.3); +} + +.jsoneditor-treepath.show-all span.jsoneditor-treepath-show-all-btn { + display: none; +} + +.jsoneditor-treepath div.jsoneditor-contextmenu-root { + position: absolute; + left: 0; +} + +.jsoneditor-treepath .jsoneditor-treepath-show-all-btn { + position: absolute; + background-color: #ebebeb; + left: 0; + height: 20px; + padding: 0 3px; + cursor: pointer; +} + +.jsoneditor-treepath .jsoneditor-treepath-element { + margin: 1px; + font-family: arial, sans-serif; + font-size: 10pt; +} + +.jsoneditor-treepath .jsoneditor-treepath-seperator { + margin: 2px; + font-size: 9pt; + font-family: arial, sans-serif; +} + +.jsoneditor-treepath span.jsoneditor-treepath-element:hover, +.jsoneditor-treepath span.jsoneditor-treepath-seperator:hover { + cursor: pointer; + text-decoration: underline; +} + +/*! + * Selectr 2.4.0 + * https://github.com/Mobius1/Selectr + * + * Released under the MIT license + */ + +.selectr-container { + position: relative; +} + +.selectr-container li { + list-style: none; +} + +.selectr-hidden { + position: absolute; + overflow: hidden; + clip: rect(0px, 0px, 0px, 0px); + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + border: 0 none; +} + +.selectr-visible { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + opacity: 0; + z-index: 11; +} + +.selectr-desktop.multiple .selectr-visible { + display: none; +} + +.selectr-desktop.multiple.native-open .selectr-visible { + top: 100%; + min-height: 200px !important; + height: auto; + opacity: 1; + display: block; +} + +.selectr-container.multiple.selectr-mobile .selectr-selected { + z-index: 0; +} + +.selectr-selected { + position: relative; + z-index: 1; + box-sizing: border-box; + width: 100%; + padding: 7px 28px 7px 14px; + cursor: pointer; + border: 1px solid #999999; + border-radius: 3px; + background-color: #ffffff; +} + +.selectr-selected::before { + position: absolute; + top: 50%; + right: 10px; + width: 0; + height: 0; + content: ''; + -o-transform: rotate(0deg) translate3d(0px, -50%, 0px); + -ms-transform: rotate(0deg) translate3d(0px, -50%, 0px); + -moz-transform: rotate(0deg) translate3d(0px, -50%, 0px); + -webkit-transform: rotate(0deg) translate3d(0px, -50%, 0px); + transform: rotate(0deg) translate3d(0px, -50%, 0px); + border-width: 4px 4px 0 4px; + border-style: solid; + border-color: #6c7a86 transparent transparent; +} + +.selectr-container.open .selectr-selected::before, +.selectr-container.native-open .selectr-selected::before { + border-width: 0 4px 4px 4px; + border-style: solid; + border-color: transparent transparent #6c7a86; +} + +.selectr-label { + display: none; + overflow: hidden; + width: 100%; + white-space: nowrap; + text-overflow: ellipsis; +} + +.selectr-placeholder { + color: #6c7a86; +} + +.selectr-tags { + margin: 0; + padding: 0; + white-space: normal; +} + +.has-selected .selectr-tags { + margin: 0 0 -2px; +} + +.selectr-tag { + list-style: none; + position: relative; + float: left; + padding: 2px 25px 2px 8px; + margin: 0 2px 2px 0; + cursor: default; + color: #ffffff; + border: medium none; + border-radius: 10px; + background: #acb7bf none repeat scroll 0 0; +} + +.selectr-container.multiple.has-selected .selectr-selected { + padding: 5px 28px 5px 5px; +} + +.selectr-options-container { + position: absolute; + z-index: 10000; + top: calc(100% - 1px); + left: 0; + display: none; + box-sizing: border-box; + width: 100%; + border-width: 0 1px 1px; + border-style: solid; + border-color: transparent #999999 #999999; + border-radius: 0 0 3px 3px; + background-color: #ffffff; +} + +.selectr-container.open .selectr-options-container { + display: block; +} + +.selectr-input-container { + position: relative; + display: none; +} + +.selectr-clear, +.selectr-input-clear, +.selectr-tag-remove { + position: absolute; + top: 50%; + right: 22px; + width: 20px; + height: 20px; + padding: 0; + cursor: pointer; + -o-transform: translate3d(0px, -50%, 0px); + -ms-transform: translate3d(0px, -50%, 0px); + -moz-transform: translate3d(0px, -50%, 0px); + -webkit-transform: translate3d(0px, -50%, 0px); + transform: translate3d(0px, -50%, 0px); + border: medium none; + background-color: transparent; + z-index: 11; +} + +.selectr-clear, +.selectr-input-clear { + display: none; +} + +.selectr-container.has-selected .selectr-clear, +.selectr-input-container.active .selectr-input-clear { + display: block; +} + +.selectr-selected .selectr-tag-remove { + right: 2px; +} + +.selectr-clear::before, +.selectr-clear::after, +.selectr-input-clear::before, +.selectr-input-clear::after, +.selectr-tag-remove::before, +.selectr-tag-remove::after { + position: absolute; + top: 5px; + left: 9px; + width: 2px; + height: 10px; + content: ' '; + background-color: #6c7a86; +} + +.selectr-tag-remove::before, +.selectr-tag-remove::after { + top: 4px; + width: 3px; + height: 12px; + background-color: #ffffff; +} + +.selectr-clear:before, +.selectr-input-clear::before, +.selectr-tag-remove::before { + -o-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -webkit-transform: rotate(45deg); + transform: rotate(45deg); +} + +.selectr-clear:after, +.selectr-input-clear::after, +.selectr-tag-remove::after { + -o-transform: rotate(-45deg); + -ms-transform: rotate(-45deg); + -moz-transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); +} + +.selectr-input-container.active, +.selectr-input-container.active .selectr-clear { + display: block; +} + +.selectr-input { + top: 5px; + left: 5px; + box-sizing: border-box; + width: calc(100% - 30px); + margin: 10px 15px; + padding: 7px 30px 7px 9px; + border: 1px solid #999999; + border-radius: 3px; +} + +.selectr-notice { + display: none; + box-sizing: border-box; + width: 100%; + padding: 8px 16px; + border-top: 1px solid #999999; + border-radius: 0 0 3px 3px; + background-color: #ffffff; +} + +.selectr-container.notice .selectr-notice { + display: block; +} + +.selectr-container.notice .selectr-selected { + border-radius: 3px 3px 0 0; +} + +.selectr-options { + position: relative; + top: calc(100% + 2px); + display: none; + overflow-x: auto; + overflow-y: scroll; + max-height: 200px; + margin: 0; + padding: 0; +} + +.selectr-container.open .selectr-options, +.selectr-container.open .selectr-input-container, +.selectr-container.notice .selectr-options-container { + display: block; +} + +.selectr-option { + position: relative; + display: block; + padding: 5px 20px; + list-style: outside none none; + cursor: pointer; + font-weight: normal; +} + +.selectr-options.optgroups > .selectr-option { + padding-left: 25px; +} + +.selectr-optgroup { + font-weight: bold; + padding: 0; +} + +.selectr-optgroup--label { + font-weight: bold; + margin-top: 10px; + padding: 5px 15px; +} + +.selectr-match { + text-decoration: underline; +} + +.selectr-option.selected { + background-color: #ddd; +} + +.selectr-option.active { + color: #ffffff; + background-color: #5897fb; +} + +.selectr-option.disabled { + opacity: 0.4; +} + +.selectr-option.excluded { + display: none; +} + +.selectr-container.open .selectr-selected { + border-color: #999999 #999999 transparent #999999; + border-radius: 3px 3px 0 0; +} + +.selectr-container.open .selectr-selected::after { + -o-transform: rotate(180deg) translate3d(0px, 50%, 0px); + -ms-transform: rotate(180deg) translate3d(0px, 50%, 0px); + -moz-transform: rotate(180deg) translate3d(0px, 50%, 0px); + -webkit-transform: rotate(180deg) translate3d(0px, 50%, 0px); + transform: rotate(180deg) translate3d(0px, 50%, 0px); +} + +.selectr-disabled { + opacity: .6; +} + +.selectr-empty, +.has-selected .selectr-placeholder { + display: none; +} + +.has-selected .selectr-label { + display: block; +} + +/* TAGGABLE */ + +.taggable .selectr-selected { + padding: 4px 28px 4px 4px; +} + +.taggable .selectr-selected::after { + display: table; + content: " "; + clear: both; +} + +.taggable .selectr-label { + width: auto; +} + +.taggable .selectr-tags { + float: left; + display: block; +} + +.taggable .selectr-placeholder { + display: none; +} + +.input-tag { + float: left; + min-width: 90px; + width: auto; +} + +.selectr-tag-input { + border: medium none; + padding: 3px 10px; + width: 100%; + font-family: inherit; + font-weight: inherit; + font-size: inherit; +} + +.selectr-input-container.loading::after { + position: absolute; + top: 50%; + right: 20px; + width: 20px; + height: 20px; + content: ''; + -o-transform: translate3d(0px, -50%, 0px); + -ms-transform: translate3d(0px, -50%, 0px); + -moz-transform: translate3d(0px, -50%, 0px); + -webkit-transform: translate3d(0px, -50%, 0px); + transform: translate3d(0px, -50%, 0px); + -o-transform-origin: 50% 0 0; + -ms-transform-origin: 50% 0 0; + -moz-transform-origin: 50% 0 0; + -webkit-transform-origin: 50% 0 0; + transform-origin: 50% 0 0; + -moz-animation: 500ms linear 0s normal forwards infinite running spin; + -webkit-animation: 500ms linear 0s normal forwards infinite running spin; + animation: 500ms linear 0s normal forwards infinite running spin; + border-width: 3px; + border-style: solid; + border-color: #aaa #ddd #ddd; + border-radius: 50%; +} + +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg) translate3d(0px, -50%, 0px); + transform: rotate(0deg) translate3d(0px, -50%, 0px); + } + + 100% { + -webkit-transform: rotate(360deg) translate3d(0px, -50%, 0px); + transform: rotate(360deg) translate3d(0px, -50%, 0px); + } +} + +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg) translate3d(0px, -50%, 0px); + transform: rotate(0deg) translate3d(0px, -50%, 0px); + } + + 100% { + -webkit-transform: rotate(360deg) translate3d(0px, -50%, 0px); + transform: rotate(360deg) translate3d(0px, -50%, 0px); + } +} + +.selectr-container.open.inverted .selectr-selected { + border-color: transparent #999999 #999999; + border-radius: 0 0 3px 3px; +} + +.selectr-container.inverted .selectr-options-container { + border-width: 1px 1px 0; + border-color: #999999 #999999 transparent; + border-radius: 3px 3px 0 0; + background-color: #ffffff; +} + +.selectr-container.inverted .selectr-options-container { + top: auto; + bottom: calc(100% - 1px); +} + +.selectr-container ::-webkit-input-placeholder { + color: #6c7a86; + opacity: 1; +} + +.selectr-container ::-moz-placeholder { + color: #6c7a86; + opacity: 1; +} + +.selectr-container :-ms-input-placeholder { + color: #6c7a86; + opacity: 1; +} + +.selectr-container ::placeholder { + color: #6c7a86; + opacity: 1; +} \ No newline at end of file