diff --git a/.eslintignore b/.eslintignore index a764b1f6..4deafc0f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,5 @@ test/unit/coverage/** test/unit/*.js test/e2e/*.js -src/muya/lib/assets/symbolIcon/index.js src/renderer/assets/symbolIcon/index.js +src/muya/lib/assets/libs/*.js diff --git a/package-lock.json b/package-lock.json index 55b3b381..6ed05c80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "marktext", - "version": "0.13.53", + "version": "0.13.54", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -425,8 +425,7 @@ "abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", - "dev": true + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=" }, "accepts": { "version": "1.3.3", @@ -609,8 +608,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { "version": "3.2.1", @@ -636,31 +634,31 @@ } }, "app-builder-bin": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-2.1.2.tgz", - "integrity": "sha512-PZJspzAqB0+z60OalXChP9I05BzODd/ffDz6RvTmDG3qclr7YrnpqzvPF+T7vGVtk2nN7syuveTQROJfXcB8xA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-2.1.4.tgz", + "integrity": "sha512-i5ZfZtnAQqVZXpFYpvkQK/V0p9RwJjCW7X3CRcyDrnR3p1mQRoRTMSfPrtGTo1ens7kTfzk2S2i0QXq+gEplLg==", "dev": true }, "app-builder-lib": { - "version": "20.28.4", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-20.28.4.tgz", - "integrity": "sha512-RY4/NJs1HCFWAOpLMivuDzbesU5VyaZVKuQllxgCNZ56+ihgO5aGexla2DVjG/bBQleWfF3DPnEsF3sbZPlpHw==", + "version": "20.29.0", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-20.29.0.tgz", + "integrity": "sha512-pXIHWNdeQ+jqI5xv4L274YZo2AOSotXsH9/Q83+qgiAa62F/PIWgcd0LWWa//CD929+FrRFEgBq9sagh9uUTHw==", "dev": true, "requires": { "7zip-bin": "~4.0.2", - "app-builder-bin": "2.1.2", + "app-builder-bin": "2.1.4", "async-exit-hook": "^2.0.1", "bluebird-lst": "^1.0.5", - "builder-util": "6.1.3", - "builder-util-runtime": "4.4.1", + "builder-util": "7.0.0", + "builder-util-runtime": "5.0.0", "chromium-pickle-js": "^0.2.0", - "debug": "^3.1.0", + "debug": "^4.1.0", "ejs": "^2.6.1", - "electron-osx-sign": "0.4.10", - "electron-publish": "20.28.3", + "electron-osx-sign": "0.4.11", + "electron-publish": "20.29.0", "fs-extra-p": "^4.6.1", "hosted-git-info": "^2.7.1", - "is-ci": "^1.2.0", + "is-ci": "^1.2.1", "isbinaryfile": "^3.0.3", "js-yaml": "^3.12.0", "lazy-val": "^1.0.3", @@ -669,10 +667,19 @@ "plist": "^3.0.1", "read-config-file": "3.1.2", "sanitize-filename": "^1.6.1", - "semver": "^5.5.1", + "semver": "^5.6.0", "temp-file": "^3.1.3" }, "dependencies": { + "debug": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz", + "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, "hosted-git-info": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", @@ -688,10 +695,16 @@ "buffer-alloc": "^1.2.0" } }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true } } @@ -699,8 +712,7 @@ "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" }, "archiver": { "version": "2.1.1", @@ -743,6 +755,16 @@ "readable-stream": "^2.0.0" } }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -2150,12 +2172,20 @@ "dev": true }, "bluebird-lst": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.5.tgz", - "integrity": "sha512-Ey0bDNys5qpYPhZ/oQ9vOEvD0TYQDTILMXWP2iGfvMg7rSDde+oV4aQQgqRH+CvBFNz2BSDQnPGMUl6LKBUUQA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.6.tgz", + "integrity": "sha512-CBWFoPuUPpcvMUxfyr8DKdI5d4kjxFl1h39+VbKxP3KJWJHEsLtuT4pPLkjpxCGU6Ask21tvbnftWXdqIxYldQ==", "dev": true, "requires": { - "bluebird": "^3.5.1" + "bluebird": "^3.5.2" + }, + "dependencies": { + "bluebird": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz", + "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==", + "dev": true + } } }, "bn.js": { @@ -2456,31 +2486,46 @@ "dev": true }, "builder-util": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-6.1.3.tgz", - "integrity": "sha512-MXeARNff9KHlzJYGJcAhLI/tpE57PmUnleaYfL22IE+viRt192Yr3wQL444ztsA+LUHJ8d12moUoG00jh1hfLA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-7.0.0.tgz", + "integrity": "sha512-GnszunK4uX1F8XP4U01m47VME0UQo97wM1i8h77j6+7V0xMz8faL9BHdv2O8/iOZ8HjfKSRJ+1v7RHohF6H0lA==", "dev": true, "requires": { "7zip-bin": "~4.0.2", - "app-builder-bin": "2.1.2", + "app-builder-bin": "2.1.4", "bluebird-lst": "^1.0.5", - "builder-util-runtime": "^4.4.1", + "builder-util-runtime": "^5.0.0", "chalk": "^2.4.1", - "debug": "^3.1.0", + "debug": "^4.1.0", "fs-extra-p": "^4.6.1", - "is-ci": "^1.2.0", + "is-ci": "^1.2.1", "js-yaml": "^3.12.0", "lazy-val": "^1.0.3", - "semver": "^5.5.1", + "semver": "^5.6.0", "source-map-support": "^0.5.9", "stat-mode": "^0.2.2", "temp-file": "^3.1.3" }, "dependencies": { + "debug": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz", + "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true }, "source-map": { @@ -2502,15 +2547,32 @@ } }, "builder-util-runtime": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-4.4.1.tgz", - "integrity": "sha512-8L2pbL6D3VdI1f8OMknlZJpw0c7KK15BRz3cY77AOUElc4XlCv2UhVV01jJM7+6Lx7henaQh80ALULp64eFYAQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-5.0.0.tgz", + "integrity": "sha512-mTyLqmzdPzavKQNAfxcGu6kqaDiPCtFKJG+nNO9SYfL6lY7VgTUW+45iXhowc5ElmPj0eSTDaIGlScxVMwFUEA==", "dev": true, "requires": { "bluebird-lst": "^1.0.5", - "debug": "^3.1.0", + "debug": "^4.1.0", "fs-extra-p": "^4.6.1", "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz", + "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } } }, "builtin-modules": { @@ -2621,6 +2683,24 @@ "integrity": "sha512-iHK48UR/InydhpPAzgSmsJXRAR925T0kwJhZ1wk0xRatpGMvi2f06LABg6HXfV4WW4P2wChzlcFa/TEmbTyXQA==", "dev": true }, + "canvas": { + "version": "1.6.13", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-1.6.13.tgz", + "integrity": "sha512-XAfzfEOHZ3JIPjEV+WSI6PpISgUta3dgmndWbsajotz+0TQOX/jDpp2kawjRERatOGv9sMMzk5auB3GKEKA6hg==", + "optional": true, + "requires": { + "nan": "^2.10.0" + } + }, + "canvas-prebuilt": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/canvas-prebuilt/-/canvas-prebuilt-1.6.11.tgz", + "integrity": "sha512-ayBAayYLgFbGBX+cwtOzM4iEQP4XB5DuBbtjgvAwQ66/FMzSR7DhlCqtDZIq9UBbpFCb1QpyDgUNVclHDdBixg==", + "optional": true, + "requires": { + "node-pre-gyp": "^0.10.0" + } + }, "capture-stack-trace": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", @@ -2775,8 +2855,7 @@ "chownr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", - "dev": true + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" }, "chrome-trace-event": { "version": "1.0.0", @@ -2881,7 +2960,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, "requires": { "string-width": "^2.1.1", "strip-ansi": "^4.0.0", @@ -2891,14 +2969,12 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -2935,8 +3011,7 @@ "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "codemirror": { "version": "5.40.2", @@ -3003,8 +3078,7 @@ "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" }, "commondir": { "version": "1.0.1", @@ -3168,6 +3242,11 @@ "date-now": "^0.1.4" } }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, "consolidate": { "version": "0.15.1", "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", @@ -3619,6 +3698,296 @@ "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", "dev": true }, + "d3": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-4.13.0.tgz", + "integrity": "sha512-l8c4+0SldjVKLaE2WG++EQlqD7mh/dmQjvi2L2lKPadAVC+TbJC4ci7Uk9bRi+To0+ansgsS0iWfPjD7DBy+FQ==", + "requires": { + "d3-array": "1.2.1", + "d3-axis": "1.0.8", + "d3-brush": "1.0.4", + "d3-chord": "1.0.4", + "d3-collection": "1.0.4", + "d3-color": "1.0.3", + "d3-dispatch": "1.0.3", + "d3-drag": "1.2.1", + "d3-dsv": "1.0.8", + "d3-ease": "1.0.3", + "d3-force": "1.1.0", + "d3-format": "1.2.2", + "d3-geo": "1.9.1", + "d3-hierarchy": "1.1.5", + "d3-interpolate": "1.1.6", + "d3-path": "1.0.5", + "d3-polygon": "1.0.3", + "d3-quadtree": "1.0.3", + "d3-queue": "3.0.7", + "d3-random": "1.1.0", + "d3-request": "1.0.6", + "d3-scale": "1.0.7", + "d3-selection": "1.3.0", + "d3-shape": "1.2.0", + "d3-time": "1.0.8", + "d3-time-format": "2.1.1", + "d3-timer": "1.0.7", + "d3-transition": "1.1.1", + "d3-voronoi": "1.1.2", + "d3-zoom": "1.7.1" + } + }, + "d3-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.1.tgz", + "integrity": "sha512-CyINJQ0SOUHojDdFDH4JEM0552vCR1utGyLHegJHyYH0JyCpSeTPxi4OBqHMA2jJZq4NH782LtaJWBImqI/HBw==" + }, + "d3-axis": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.8.tgz", + "integrity": "sha1-MacFoLU15ldZ3hQXOjGTMTfxjvo=" + }, + "d3-brush": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.4.tgz", + "integrity": "sha1-AMLyOAGfJPbAoZSibUGhUw/+e8Q=", + "requires": { + "d3-dispatch": "1", + "d3-drag": "1", + "d3-interpolate": "1", + "d3-selection": "1", + "d3-transition": "1" + } + }, + "d3-chord": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.4.tgz", + "integrity": "sha1-fexPC6iG9xP+ERxF92NBT290yiw=", + "requires": { + "d3-array": "1", + "d3-path": "1" + } + }, + "d3-collection": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.4.tgz", + "integrity": "sha1-NC39EoN8kJdPM/HMCnha6lcNzcI=" + }, + "d3-color": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.0.3.tgz", + "integrity": "sha1-vHZD/KjlOoNH4vva/6I2eWtYUJs=" + }, + "d3-contour": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-1.3.2.tgz", + "integrity": "sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg==", + "requires": { + "d3-array": "^1.1.1" + } + }, + "d3-dispatch": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.3.tgz", + "integrity": "sha1-RuFJHqqbWMNY/OW+TovtYm54cfg=" + }, + "d3-drag": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.1.tgz", + "integrity": "sha512-Cg8/K2rTtzxzrb0fmnYOUeZHvwa4PHzwXOLZZPwtEs2SKLLKLXeYwZKBB+DlOxUvFmarOnmt//cU4+3US2lyyQ==", + "requires": { + "d3-dispatch": "1", + "d3-selection": "1" + } + }, + "d3-dsv": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.0.8.tgz", + "integrity": "sha512-IVCJpQ+YGe3qu6odkPQI0KPqfxkhbP/oM1XhhE/DFiYmcXKfCRub4KXyiuehV1d4drjWVXHUWx4gHqhdZb6n/A==", + "requires": { + "commander": "2", + "iconv-lite": "0.4", + "rw": "1" + } + }, + "d3-ease": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.3.tgz", + "integrity": "sha1-aL+8NJM4o4DETYrMT7wzBKotjA4=" + }, + "d3-force": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.1.0.tgz", + "integrity": "sha512-2HVQz3/VCQs0QeRNZTYb7GxoUCeb6bOzMp/cGcLa87awY9ZsPvXOGeZm0iaGBjXic6I1ysKwMn+g+5jSAdzwcg==", + "requires": { + "d3-collection": "1", + "d3-dispatch": "1", + "d3-quadtree": "1", + "d3-timer": "1" + } + }, + "d3-format": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.2.2.tgz", + "integrity": "sha512-zH9CfF/3C8zUI47nsiKfD0+AGDEuM8LwBIP7pBVpyR4l/sKkZqITmMtxRp04rwBrlshIZ17XeFAaovN3++wzkw==" + }, + "d3-geo": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.9.1.tgz", + "integrity": "sha512-l9wL/cEQkyZQYXw3xbmLsH3eQ5ij+icNfo4r0GrLa5rOCZR/e/3am45IQ0FvQ5uMsv+77zBRunLc9ufTWSQYFA==", + "requires": { + "d3-array": "1" + } + }, + "d3-hierarchy": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.5.tgz", + "integrity": "sha1-ochFxC+Eoga88cAcAQmOpN2qeiY=" + }, + "d3-interpolate": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.1.6.tgz", + "integrity": "sha512-mOnv5a+pZzkNIHtw/V6I+w9Lqm9L5bG3OTXPM5A+QO0yyVMQ4W1uZhR+VOJmazaOZXri2ppbiZ5BUNWT0pFM9A==", + "requires": { + "d3-color": "1" + } + }, + "d3-path": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.5.tgz", + "integrity": "sha1-JB6xhJvZ6egCHA0KeZ+KDo5EF2Q=" + }, + "d3-polygon": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.3.tgz", + "integrity": "sha1-FoiOkCZGCTPysXllKtN4Ik04LGI=" + }, + "d3-quadtree": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.3.tgz", + "integrity": "sha1-rHmH4+I/6AWpkPKOG1DTj8uCJDg=" + }, + "d3-queue": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/d3-queue/-/d3-queue-3.0.7.tgz", + "integrity": "sha1-yTouVLQXwJWRKdfXP2z31Ckudhg=" + }, + "d3-random": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.0.tgz", + "integrity": "sha1-ZkLlBsb6OmSFldKyRpeIqNElKdM=" + }, + "d3-request": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-request/-/d3-request-1.0.6.tgz", + "integrity": "sha512-FJj8ySY6GYuAJHZMaCQ83xEYE4KbkPkmxZ3Hu6zA1xxG2GD+z6P+Lyp+zjdsHf0xEbp2xcluDI50rCS855EQ6w==", + "requires": { + "d3-collection": "1", + "d3-dispatch": "1", + "d3-dsv": "1", + "xmlhttprequest": "1" + } + }, + "d3-scale": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-1.0.7.tgz", + "integrity": "sha512-KvU92czp2/qse5tUfGms6Kjig0AhHOwkzXG0+PqIJB3ke0WUv088AHMZI0OssO9NCkXt4RP8yju9rpH8aGB7Lw==", + "requires": { + "d3-array": "^1.2.0", + "d3-collection": "1", + "d3-color": "1", + "d3-format": "1", + "d3-interpolate": "1", + "d3-time": "1", + "d3-time-format": "2" + } + }, + "d3-scale-chromatic": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.3.3.tgz", + "integrity": "sha512-BWTipif1CimXcYfT02LKjAyItX5gKiwxuPRgr4xM58JwlLocWbjPLI7aMEjkcoOQXMkYsmNsvv3d2yl/OKuHHw==", + "requires": { + "d3-color": "1", + "d3-interpolate": "1" + } + }, + "d3-selection": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.3.0.tgz", + "integrity": "sha512-qgpUOg9tl5CirdqESUAu0t9MU/t3O9klYfGfyKsXEmhyxyzLpzpeh08gaxBUTQw1uXIOkr/30Ut2YRjSSxlmHA==" + }, + "d3-shape": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.2.0.tgz", + "integrity": "sha1-RdAVOPBkuv0F6j1tLLdI/YxB93c=", + "requires": { + "d3-path": "1" + } + }, + "d3-time": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.8.tgz", + "integrity": "sha512-YRZkNhphZh3KcnBfitvF3c6E0JOFGikHZ4YqD+Lzv83ZHn1/u6yGenRU1m+KAk9J1GnZMnKcrtfvSktlA1DXNQ==" + }, + "d3-time-format": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.1.1.tgz", + "integrity": "sha512-8kAkymq2WMfzW7e+s/IUNAtN/y3gZXGRrdGfo6R8NKPAA85UBTxZg5E61bR6nLwjPjj4d3zywSQe1CkYLPFyrw==", + "requires": { + "d3-time": "1" + } + }, + "d3-timer": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.7.tgz", + "integrity": "sha512-vMZXR88XujmG/L5oB96NNKH5lCWwiLM/S2HyyAQLcjWJCloK5shxta4CwOFYLZoY3AWX73v8Lgv4cCAdWtRmOA==" + }, + "d3-transition": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.1.1.tgz", + "integrity": "sha512-xeg8oggyQ+y5eb4J13iDgKIjUcEfIOZs2BqV/eEmXm2twx80wTzJ4tB4vaZ5BKfz7XsI/DFmQL5me6O27/5ykQ==", + "requires": { + "d3-color": "1", + "d3-dispatch": "1", + "d3-ease": "1", + "d3-interpolate": "1", + "d3-selection": "^1.1.0", + "d3-timer": "1" + } + }, + "d3-voronoi": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.2.tgz", + "integrity": "sha1-Fodmfo8TotFYyAwUgMWinLDYlzw=" + }, + "d3-zoom": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.7.1.tgz", + "integrity": "sha512-sZHQ55DGq5BZBFGnRshUT8tm2sfhPHFnOlmPbbwTkAoPeVdRTkB4Xsf9GCY0TSHrTD8PeJPZGmP/TpGicwJDJQ==", + "requires": { + "d3-dispatch": "1", + "d3-drag": "1", + "d3-interpolate": "1", + "d3-selection": "1", + "d3-transition": "1" + } + }, + "dagre-d3-renderer": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/dagre-d3-renderer/-/dagre-d3-renderer-0.5.8.tgz", + "integrity": "sha512-XH2a86isUHRxzIYbjQVEuZtJnWEufb64H5DuXIUmn8esuB40jgLEbUUclulWOW62/ZoXlj2ZDyL8SJ+YRxs+jQ==", + "requires": { + "dagre-layout": "^0.8.8", + "lodash": "^4.17.5" + } + }, + "dagre-layout": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/dagre-layout/-/dagre-layout-0.8.8.tgz", + "integrity": "sha512-ZNV15T9za7X+fV8Z07IZquUKugCxm5owoiPPxfEx6OJRD331nkiIaF3vSt0JEY5FkrY0KfRQxcpQ3SpXB7pLPQ==", + "requires": { + "graphlibrary": "^2.2.0", + "lodash": "^4.17.5" + } + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -3708,8 +4077,7 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "deep-is": { "version": "0.1.3", @@ -3864,6 +4232,12 @@ "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", "optional": true }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "optional": true + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -3895,6 +4269,12 @@ "repeating": "^2.0.0" } }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "optional": true + }, "detect-node": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", @@ -3968,14 +4348,14 @@ } }, "dmg-builder": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-5.3.1.tgz", - "integrity": "sha512-/+vtqlgvTtha/4Gc76XIRKS2KzYO58sTWXhZ/kgfNr05ZXY6bIw26v7xDu8ZBpTYnfWI09JRZTMv1yIXT/vvfg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-6.0.0.tgz", + "integrity": "sha512-nGeCoIctKP48QhohyQ6Uxx754XKyfVa5nx8YK6STIxTXoGTDWR/dwy8m4iCkM77//sd2wMdP9KYsUDuPxtbpLA==", "dev": true, "requires": { - "app-builder-lib": "~20.28.3", + "app-builder-lib": "~20.29.0", "bluebird-lst": "^1.0.5", - "builder-util": "~6.1.3", + "builder-util": "~7.0.0", "fs-extra-p": "^4.6.1", "iconv-lite": "^0.4.24", "js-yaml": "^3.12.0", @@ -4133,9 +4513,9 @@ } }, "dotenv": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.0.0.tgz", - "integrity": "sha512-FlWbnhgjtwD+uNLUGHbMykMOYQaTivdHEmYwAKFjn6GKe/CqY0fNae93ZHTd20snh9ZLr8mTzIL9m0APQ1pjQg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.1.0.tgz", + "integrity": "sha512-/veDn2ztgRlB7gKmE3i9f6CmDIyXAy6d5nBq+whO9SLX+Zs1sXEgFLPi+aSuWqUuusMfbi84fT8j34fs1HaYUw==", "dev": true }, "dotenv-expand": { @@ -4190,9 +4570,9 @@ "dev": true }, "electron": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/electron/-/electron-3.0.5.tgz", - "integrity": "sha512-rcHNbhSGfj80Av5p06LgIUxN8wQbrdx8yblikJamDezqxe0B11CJSEJuidz6TJoCRDZuWHt+P5xMAEhp92ZUcA==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/electron/-/electron-3.0.7.tgz", + "integrity": "sha512-c/pww23/oPm3wt/wPshuAQCH4ooysS29a9fahxpvYP3ghFZ0zFHN3BWR/WHIEIqPGXWMTD4XbsD7lUtRZEZB+g==", "dev": true, "requires": { "@types/node": "^8.0.24", @@ -4201,24 +4581,24 @@ } }, "electron-builder": { - "version": "20.28.4", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-20.28.4.tgz", - "integrity": "sha512-JMOzMfx9BrC9SJr6+UacuvQZmuodL02Zua8iFn0l5bv32GkWcNj1D6FwybV33BpsmdQ8sF1SkQj+7L+FEIxang==", + "version": "20.29.0", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-20.29.0.tgz", + "integrity": "sha512-i1v5dD0u8tu5rq8Nq3DohEj/Gm7WKSysvlbeb5oCvmJ0YslbsQm/Iq6SGLTmJbXlYp3hoL3djuBaWC+oM2hagw==", "dev": true, "requires": { - "app-builder-lib": "20.28.4", + "app-builder-lib": "20.29.0", "bluebird-lst": "^1.0.5", - "builder-util": "6.1.3", - "builder-util-runtime": "4.4.1", + "builder-util": "7.0.0", + "builder-util-runtime": "5.0.0", "chalk": "^2.4.1", - "dmg-builder": "5.3.1", + "dmg-builder": "6.0.0", "fs-extra-p": "^4.6.1", - "is-ci": "^1.2.0", + "is-ci": "^1.2.1", "lazy-val": "^1.0.3", "read-config-file": "3.1.2", "sanitize-filename": "^1.6.1", "update-notifier": "^2.5.0", - "yargs": "^12.0.1" + "yargs": "^12.0.2" } }, "electron-chromedriver": { @@ -4319,9 +4699,9 @@ } }, "electron-osx-sign": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.10.tgz", - "integrity": "sha1-vk87ibKnWh3F8eckkIGrKSnKOiY=", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.11.tgz", + "integrity": "sha512-VVd40nrnVqymvFrY9ZkOYgHJOvexHHYTR3di/SN+mjJ0OWhR1I8BRVj3U+Yamw6hnkZZNKZp52rqL5EFAAPFkQ==", "dev": true, "requires": { "bluebird": "^3.5.0", @@ -4329,7 +4709,7 @@ "debug": "^2.6.8", "isbinaryfile": "^3.0.2", "minimist": "^1.2.0", - "plist": "^2.1.0" + "plist": "^3.0.1" }, "dependencies": { "debug": { @@ -4340,29 +4720,18 @@ "requires": { "ms": "2.0.0" } - }, - "plist": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/plist/-/plist-2.1.0.tgz", - "integrity": "sha1-V8zbeggh3yGDEhejytVOPhRqECU=", - "dev": true, - "requires": { - "base64-js": "1.2.0", - "xmlbuilder": "8.2.2", - "xmldom": "0.1.x" - } } } }, "electron-publish": { - "version": "20.28.3", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-20.28.3.tgz", - "integrity": "sha512-/2t5zk9EKgH7p7rFZ+ynTKLmpKGF9bktMP2UR6u4bbPz9w4r3WEUbPOeZ1TLqUCAqdfZECcj4ThjrlcAJTghCA==", + "version": "20.29.0", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-20.29.0.tgz", + "integrity": "sha512-Kc5u5YaJLcGWPrp3bFk8NdrYk5gNVG4lZqbAIZnYNPuOLMCNgUk4UqrONO6iuAE6x/vWOoovszf1gGIT7G01UA==", "dev": true, "requires": { "bluebird-lst": "^1.0.5", - "builder-util": "~6.1.3", - "builder-util-runtime": "^4.4.1", + "builder-util": "~7.0.0", + "builder-util-runtime": "^5.0.0", "chalk": "^2.4.1", "fs-extra-p": "^4.6.1", "lazy-val": "^1.0.3", @@ -4376,26 +4745,26 @@ "dev": true }, "electron-updater": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-3.1.2.tgz", - "integrity": "sha512-y3n37O01pdynMJHhJbOd2UVhVrmDW6zLvR2SOZ+gk3S6r16872+0nNbC48GXWwc26lTeus/Zja/XUpiqrvdw4A==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-3.1.6.tgz", + "integrity": "sha512-ZzNrFqvJJmG2O0qEVhAhI25WqJx6Nq3lNlXvBvX3i0zqWtAuSmcAdCbq4VyDymun/glsZ4bD3ZzATcIk3sYygg==", "dev": true, "requires": { "bluebird-lst": "^1.0.5", - "builder-util-runtime": "~4.4.1", + "builder-util-runtime": "~5.0.0", "electron-is-dev": "^0.3.0", "fs-extra-p": "^4.6.1", "js-yaml": "^3.12.0", "lazy-val": "^1.0.3", "lodash.isequal": "^4.5.0", - "semver": "^5.5.1", + "semver": "^5.6.0", "source-map-support": "^0.5.9" }, "dependencies": { "semver": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", - "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true }, "source-map": { @@ -4417,9 +4786,9 @@ } }, "electron-window-state": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/electron-window-state/-/electron-window-state-5.0.1.tgz", - "integrity": "sha512-9NE2mB8ZM9IZpVexdBVNbJLXkBByTZYArHMuwtA04U5R3ajl6IE82v3UkmSuf0hWczP0+is/4vLIqNkJwdvCrQ==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/electron-window-state/-/electron-window-state-5.0.2.tgz", + "integrity": "sha512-fcSS+ZxfY8K14Ig7XI0/PHZ54wBr1LEPEgMTRlFn799xDQJ9UsP8Ti+NNb7JhvRaJBsL7MWvtY6vWBk4BpVfMw==", "dev": true, "requires": { "deep-equal": "^1.0.1", @@ -4671,6 +5040,11 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "escaper": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/escaper/-/escaper-2.5.3.tgz", + "integrity": "sha512-QGb9sFxBVpbzMggrKTX0ry1oiI4CSDAl9vIL702hzl1jGW8VZs7qfqTRX7WDOjoNDoEVGcEtu1ZOQgReSfT2kQ==" + }, "escodegen": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz", @@ -5061,6 +5435,16 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, + "eve": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/eve/-/eve-0.5.4.tgz", + "integrity": "sha1-Z9CAuXJSkdfjieNMJoYN2X8d66o=" + }, + "eve-raphael": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/eve-raphael/-/eve-raphael-0.5.0.tgz", + "integrity": "sha1-F8dUt5K+7z+maE15z1pHxjxM2jA=" + }, "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", @@ -5744,6 +6128,14 @@ "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", "dev": true }, + "flowchart.js": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/flowchart.js/-/flowchart.js-1.11.3.tgz", + "integrity": "sha512-Hk5vKKsEjYp/Vt4gSRBx39z+6OLwkg3top/EQ4antpZXCVrHLajVGWEqhCPeEBixhzDxAtHdRn4aFEtRhlTzHA==", + "requires": { + "raphael": "2.2.7" + } + }, "flush-write-stream": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", @@ -5866,6 +6258,15 @@ } } }, + "fs-minipass": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", + "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -5881,8 +6282,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "1.2.4", @@ -6363,6 +6763,33 @@ "resolved": "https://registry.npmjs.org/fuzzaldrin/-/fuzzaldrin-2.1.0.tgz", "integrity": "sha1-kCBMPi/appQbso0WZF1BgGOpDps=" }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, "gaze": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", @@ -6375,8 +6802,7 @@ "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" }, "get-func-name": { "version": "2.0.0", @@ -6393,8 +6819,7 @@ "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" }, "get-value": { "version": "2.0.6", @@ -6418,7 +6843,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6574,6 +6998,14 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, + "graphlibrary": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/graphlibrary/-/graphlibrary-2.2.0.tgz", + "integrity": "sha512-XTcvT55L8u4MBZrM37zXoUxsgxs/7sow7YSygd9CIwfWTVO8RVu7AYXhhCiTuFEf+APKgx6Jk4SuQbYR0vYKmQ==", + "requires": { + "lodash": "^4.17.5" + } + }, "gray-matter": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-2.1.1.tgz", @@ -6769,6 +7201,12 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "optional": true + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -6827,8 +7265,7 @@ "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" }, "header-case": { "version": "1.0.1", @@ -7041,7 +7478,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -7079,6 +7515,15 @@ "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", "dev": true }, + "ignore-walk": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", + "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, "image-size": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", @@ -7212,7 +7657,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -7226,8 +7670,7 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "inject-loader": { "version": "4.0.1", @@ -7306,8 +7749,7 @@ "invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" }, "ip": { "version": "1.1.5", @@ -7473,7 +7915,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, "requires": { "number-is-nan": "^1.0.0" } @@ -7621,6 +8062,11 @@ "has": "^1.0.1" } }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" + }, "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", @@ -7636,8 +8082,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "is-symbol": { "version": "1.0.1", @@ -7690,8 +8135,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { "version": "3.0.1", @@ -8041,12 +8485,25 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "~0.0.0" + } + }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "json-stringify-pretty-compact": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-1.2.0.tgz", + "integrity": "sha512-/11Pj1OyX814QMKO7K8l85SHPTr/KsFxHp8GE2zVa0BtJgGimDjXHfM3FhC7keQdWDea7+nXf+f1de7ATZcZkQ==" + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -8072,6 +8529,11 @@ "graceful-fs": "^4.1.6" } }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -8368,17 +8830,17 @@ } }, "katex": { - "version": "0.10.0-rc.1", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.10.0-rc.1.tgz", - "integrity": "sha512-JmnreLp0lWPA1z1krzO5drN1qBrkhqzMg5qv0l5y+Fr97sqgOuh37k9ky7VD1k/Ec+yvOe2BptiYSR9OoShkFg==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.10.0.tgz", + "integrity": "sha512-/WRvx+L1eVBrLwX7QzKU1dQuaGnE7E8hDvx3VWfZh9HbMiCfsKWJNnYZ0S8ZMDAfAyDSofdyXIrH/hujF1fYXg==", "requires": { "commander": "^2.16.0" }, "dependencies": { "commander": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", - "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==" + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" } } }, @@ -8447,7 +8909,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, "requires": { "invert-kv": "^2.0.0" } @@ -9034,7 +9495,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.2.tgz", "integrity": "sha512-UN1dNocxQq44IhJyMI4TU8phc2m9BddacHRPRjKGLYaF0jqd3xLz0jS0skpAU9WgYyoR4gHtUpzytNBS385FWQ==", - "dev": true, "requires": { "p-defer": "^1.0.0" } @@ -9113,7 +9573,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz", "integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==", - "dev": true, "requires": { "map-age-cleaner": "^0.1.1", "mimic-fn": "^1.0.0", @@ -9180,6 +9639,21 @@ } } }, + "mermaid": { + "version": "8.0.0-rc.8", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-8.0.0-rc.8.tgz", + "integrity": "sha512-GbF9jHWfqE7YGx9vQySmBxy2Ahlclxmpk4tJ9ntNyafENl96s96ggUK/NQS5ydYoFab6MavTm4YMTIPKqWVvPQ==", + "requires": { + "d3": "^4.13.0", + "dagre-d3-renderer": "^0.5.8", + "dagre-layout": "^0.8.8", + "graphlibrary": "^2.2.0", + "he": "^1.1.1", + "lodash": "^4.17.5", + "moment": "^2.21.0", + "scope-css": "^1.0.5" + } + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -9238,8 +9712,7 @@ "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" }, "mini-css-extract-plugin": { "version": "0.4.3", @@ -9277,6 +9750,31 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, + "minipass": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", + "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + }, + "dependencies": { + "yallist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", + "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=" + } + } + }, + "minizlib": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.1.tgz", + "integrity": "sha512-TrfjCjk4jLhcJyGMYymBH6oTXcWjYbUAXTHDbtnWHjZC25h0cdajHuPE1zxb4DVmu8crfh+HwH/WMuyLG0nHBg==", + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, "minstache": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minstache/-/minstache-1.2.0.tgz", @@ -9344,7 +9842,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, "requires": { "minimist": "0.0.8" }, @@ -9352,8 +9849,7 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" } } }, @@ -9426,6 +9922,11 @@ } } }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -9570,6 +10071,28 @@ "xml-char-classes": "^1.0.0" } }, + "needle": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.4.tgz", + "integrity": "sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA==", + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "optional": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -9585,8 +10108,7 @@ "nice-try": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz", - "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==", - "dev": true + "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==" }, "no-case": { "version": "2.3.2", @@ -9597,6 +10119,11 @@ "lower-case": "^1.1.1" } }, + "node-fetch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.2.0.tgz", + "integrity": "sha512-OayFWziIxiHY8bCUyLX6sTpDH8Jsbp4FfYd1j1f7vZyfgkcOnAyM4oQR16f8a0s7Gl/viMGRey8eScYk4V4EZA==" + }, "node-forge": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", @@ -9659,6 +10186,36 @@ "integrity": "sha1-x5fvUQle1YWZArFX9jhPY2HgWug=", "dev": true }, + "node-pre-gyp": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz", + "integrity": "sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A==", + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + }, + "dependencies": { + "nopt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + } + } + }, "node-releases": { "version": "1.0.0-alpha.11", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.0.0-alpha.11.tgz", @@ -12791,21 +13348,48 @@ } } }, + "npm-bundled": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.5.tgz", + "integrity": "sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g==", + "optional": true + }, "npm-install-package": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/npm-install-package/-/npm-install-package-2.1.0.tgz", "integrity": "sha1-1+/jz816sAYUuJbqUxGdyaslkSU=", "dev": true }, + "npm-packlist": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.12.tgz", + "integrity": "sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g==", + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, "requires": { "path-key": "^2.0.0" } }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, "nth-check": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", @@ -12850,8 +13434,7 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "nwsapi": { "version": "2.0.9", @@ -12987,7 +13570,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -13077,14 +13659,12 @@ "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-locale": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.0.1.tgz", "integrity": "sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw==", - "dev": true, "requires": { "execa": "^0.10.0", "lcid": "^2.0.0", @@ -13095,7 +13675,6 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -13108,7 +13687,6 @@ "version": "0.10.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", - "dev": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^3.0.0", @@ -13124,26 +13702,32 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } }, "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-is-promise": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", - "dev": true + "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=" }, "p-limit": { "version": "1.3.0", @@ -13360,8 +13944,7 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" }, "path-is-absolute": { "version": "1.0.1", @@ -13377,8 +13960,7 @@ "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "path-parse": { "version": "1.0.6", @@ -13487,12 +14069,6 @@ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", "dev": true - }, - "xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", - "dev": true } } }, @@ -15362,6 +15938,14 @@ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", "dev": true }, + "raphael": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/raphael/-/raphael-2.2.7.tgz", + "integrity": "sha1-IxsZFB+NCGmG2PrOtm+LVi7iyBA=", + "requires": { + "eve-raphael": "0.5.0" + } + }, "raw-body": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", @@ -15389,7 +15973,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -15440,7 +16023,7 @@ }, "json5": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { @@ -15853,8 +16436,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-from-string": { "version": "2.0.2", @@ -15865,8 +16447,7 @@ "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" }, "require-uncached": { "version": "1.0.3", @@ -15960,7 +16541,6 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, "requires": { "glob": "^7.0.5" } @@ -15993,6 +16573,11 @@ "aproba": "^1.1.1" } }, + "rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" + }, "rx-lite": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", @@ -16077,6 +16662,16 @@ } } }, + "scope-css": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/scope-css/-/scope-css-1.2.1.tgz", + "integrity": "sha512-UjLRmyEYaDNiOS673xlVkZFlVCtckJR/dKgr434VMm7Lb+AOOqXKdAcY7PpGlJYErjXXJzKN7HWo4uRPiZZG0Q==", + "requires": { + "escaper": "^2.5.3", + "slugify": "^1.3.1", + "strip-css-comments": "^3.0.0" + } + }, "select": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", @@ -16101,8 +16696,7 @@ "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" }, "semver-diff": { "version": "2.1.0", @@ -16224,8 +16818,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-getter": { "version": "0.1.0", @@ -16287,7 +16880,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, "requires": { "shebang-regex": "^1.0.0" } @@ -16295,14 +16887,12 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "single-line-log": { "version": "1.1.2", @@ -16336,6 +16926,11 @@ } } }, + "slugify": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.3.2.tgz", + "integrity": "sha512-RB7T2QO4+F8zc5UA+yujQb8V5GDmyiGzCW7e/x5CyKUEx0xzI9Hz5ptOS85GDBHlDx6LDooyHxw5FwKkximL5Q==" + }, "snabbdom": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-0.7.2.tgz", @@ -16469,6 +17064,14 @@ } } }, + "snapsvg": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/snapsvg/-/snapsvg-0.5.1.tgz", + "integrity": "sha1-DK9Sx5GJopB0b8RGzF6GP2vd3+M=", + "requires": { + "eve": "~0.5.1" + } + }, "socket.io": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.3.tgz", @@ -16933,7 +17536,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -16944,7 +17546,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -16963,7 +17564,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" }, @@ -16971,8 +17571,7 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" } } }, @@ -16990,11 +17589,18 @@ "resolved": "https://registry.npmjs.org/strip-color/-/strip-color-0.1.0.tgz", "integrity": "sha1-EG9l09PmotlAHKwOsM6LinArT3s=" }, + "strip-css-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-css-comments/-/strip-css-comments-3.0.0.tgz", + "integrity": "sha1-elYl7/iisibPiUehElTaluE9rok=", + "requires": { + "is-regexp": "^1.0.0" + } + }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, "strip-indent": { "version": "1.0.1", @@ -17008,8 +17614,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "style-loader": { "version": "0.23.0", @@ -17426,6 +18031,29 @@ "integrity": "sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg==", "dev": true }, + "tar": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.6.tgz", + "integrity": "sha512-tMkTnh9EdzxyfW+6GK6fCahagXsnYk6kE6S9Gr9pjVdys769+laCTbodXDhPAjzVtEBazRgP0gYqOjnk9dQzLg==", + "optional": true, + "requires": { + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.3", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + }, + "dependencies": { + "yallist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", + "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", + "optional": true + } + } + }, "tar-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", @@ -17752,6 +18380,14 @@ "resolved": "https://registry.npmjs.org/toml/-/toml-2.3.3.tgz", "integrity": "sha512-O7L5hhSQHxuufWUdcTRPfuTh3phKfAZ/dqfxZFoxPCj2RYmpaSGLEIs016FCXItQwNr08yefUB5TSjzRYnajTA==" }, + "topojson-client": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.0.0.tgz", + "integrity": "sha1-H5kpOnfvQqRI0DKoGqmCtz82DS8=", + "requires": { + "commander": "2" + } + }, "toposort": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", @@ -17818,8 +18454,7 @@ "tslib": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "dev": true + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" }, "tty-browserify": { "version": "0.0.0", @@ -17987,6 +18622,11 @@ "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", "dev": true }, + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, "underscore.string": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz", @@ -18324,6 +18964,512 @@ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", "dev": true }, + "vega": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/vega/-/vega-4.3.0.tgz", + "integrity": "sha512-edZvfqA3mekllovh0rcVNNDI+BNVoFmtPvgFnZ2NR1pXnTjuxY/Qs+UjFNWsAI8gJVAPL3bOeM3QXt2zBAr2qA==", + "requires": { + "canvas": "^1.6.13", + "canvas-prebuilt": "1.6.11", + "vega-lib": "4.3.0", + "vega-parser": "3.8.0", + "vega-typings": "*", + "yargs": "12" + } + }, + "vega-canvas": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vega-canvas/-/vega-canvas-1.1.0.tgz", + "integrity": "sha512-0RBwjnrFf4VRhNm5ICY+o1/q6mynli+VheOXKGML9mElRsplZgzd/pv9NnNRNigU+M66Kr7zUpskoakh8EhW9Q==" + }, + "vega-crossfilter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vega-crossfilter/-/vega-crossfilter-3.0.0.tgz", + "integrity": "sha512-h8HLc0YGaCFx3XTJYe2ixDQKHErvAFmFCE5EzLf7qmoWKtfXvXqB0+YcV/h5XC6VmLdUwFzMah+deDjIwncq7g==", + "requires": { + "d3-array": "^1.2.1", + "vega-dataflow": "^4.0.0", + "vega-util": "^1.7.0" + } + }, + "vega-dataflow": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/vega-dataflow/-/vega-dataflow-4.0.4.tgz", + "integrity": "sha1-4vS0gFYY0BwLgzqTSE08JEZ1+6M=", + "requires": { + "vega-loader": "^3.0.1", + "vega-util": "^1.7.0" + } + }, + "vega-embed": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/vega-embed/-/vega-embed-3.21.1.tgz", + "integrity": "sha512-9F1AFe9CQHQDBu7x0rtQlAEMPi7Ta1qvs6mOQKgOHMF4vTL2Qx2Jugb4rs4PW4U/Iw8cgPTRRrEMACIRtMPrBA==", + "requires": { + "d3-selection": "^1.3.2", + "json-stringify-pretty-compact": "^1.2.0", + "semver": "^5.6.0", + "vega-lib": "^4.3.0", + "vega-lite": "^3.0.0-rc8 || ^2.6.0", + "vega-schema-url-parser": "^1.1.0", + "vega-themes": "^2.1.1", + "vega-tooltip": "^0.13.0" + }, + "dependencies": { + "d3-selection": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.3.2.tgz", + "integrity": "sha512-OoXdv1nZ7h2aKMVg3kaUFbLLK5jXUFAMLD/Tu5JA96mjf8f2a9ZUESGY+C36t8R1WFeWk/e55hy54Ml2I62CRQ==" + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" + } + } + }, + "vega-encode": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vega-encode/-/vega-encode-3.2.0.tgz", + "integrity": "sha512-GQPBo3HDzlTTgieuVdDSgHfjO1XIAbpvsHMmxv156sfNsC2Iv/HdNdw58ajCrmRHz5RQbagniJVY7MJq8ZWkqg==", + "requires": { + "d3-array": "^1.2.4", + "d3-format": "^1.3.2", + "d3-interpolate": "^1.3.2", + "vega-dataflow": "^4.0.4", + "vega-scale": "^2.5.0", + "vega-util": "^1.7.0" + }, + "dependencies": { + "d3-array": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" + }, + "d3-format": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.3.2.tgz", + "integrity": "sha512-Z18Dprj96ExragQ0DeGi+SYPQ7pPfRMtUXtsg/ChVIKNBCzjO8XYJvRTC1usblx52lqge56V5ect+frYTQc8WQ==" + }, + "d3-interpolate": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.3.2.tgz", + "integrity": "sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w==", + "requires": { + "d3-color": "1" + } + } + } + }, + "vega-event-selector": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vega-event-selector/-/vega-event-selector-2.0.0.tgz", + "integrity": "sha512-EZeStM/7LNfJiRuop0lvhOR52Q1l9i/EIYUnm/XddhjR+UqhPkeCmZcffMTr41z3aGm/zciVLlKanUWNT+jQ1A==" + }, + "vega-expression": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/vega-expression/-/vega-expression-2.4.0.tgz", + "integrity": "sha512-Ti2rqnXscu281omgAukd37yDcw2AjETshB8tWcTOciFPUkfLQKwL6d1UIuIq4RkWuKDTU9Htd2UCpvFDu+O1eQ==", + "requires": { + "vega-util": "^1.7.0" + } + }, + "vega-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vega-force/-/vega-force-3.0.0.tgz", + "integrity": "sha512-Uar26RDxDQEpIdWBIFKnOr6/B30RU8/2qBtoiux1C3goZIWBRkXNlCR5kMDkll8Mg60deD6ynflsXXNwyGS69w==", + "requires": { + "d3-force": "^1.1.0", + "vega-dataflow": "^4.0.0", + "vega-util": "^1.7.0" + } + }, + "vega-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vega-geo/-/vega-geo-3.1.0.tgz", + "integrity": "sha1-ICLw3GEhmVhbENInSWf+6U11BbQ=", + "requires": { + "d3-array": "^1.2.1", + "d3-contour": "^1.3.0", + "d3-geo": "^1.10.0", + "vega-dataflow": "^4.0.3", + "vega-projection": "^1.2.0", + "vega-util": "^1.7.0" + }, + "dependencies": { + "d3-geo": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.11.1.tgz", + "integrity": "sha512-GsG7x9G9sykseLviOVSJ3h5yjw0ItLopOtuDQKUt1TRklEegCw5WAmnIpYYiCkSH/QgUMleAeE2xZK38Qb+1+Q==", + "requires": { + "d3-array": "1" + } + } + } + }, + "vega-hierarchy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vega-hierarchy/-/vega-hierarchy-3.1.0.tgz", + "integrity": "sha512-zPxOsQbswVDMfn9JdDG0ihZA4qhQL5WJxBsSRFsMeuyDTFuE6biBInpm/g0QDGmHMF2EOY4AwD2WRyF+jAyTqw==", + "requires": { + "d3-collection": "^1.0.7", + "d3-hierarchy": "^1.1.8", + "vega-dataflow": "^4.0.4", + "vega-util": "^1.7.0" + }, + "dependencies": { + "d3-collection": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz", + "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==" + }, + "d3-hierarchy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz", + "integrity": "sha512-L+GHMSZNwTpiq4rt9GEsNcpLa4M96lXMR8M/nMG9p5hBE0jy6C+3hWtyZMenPQdwla249iJy7Nx0uKt3n+u9+w==" + } + } + }, + "vega-lib": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/vega-lib/-/vega-lib-4.3.0.tgz", + "integrity": "sha512-NNTpxpUAQfFUqkf6XnsL5nko9sCIQPMRe5AZI9Bsb8mHaA0oukAV1dPIb57MIYZg/wYwtrvc6EwhKxsjCQZHnA==", + "requires": { + "vega-crossfilter": "^3.0.0", + "vega-dataflow": "^4.0.4", + "vega-encode": "^3.2.0", + "vega-event-selector": "^2.0.0", + "vega-expression": "^2.4.0", + "vega-force": "^3.0.0", + "vega-geo": "^3.1.0", + "vega-hierarchy": "^3.1.0", + "vega-loader": "^3.0.1", + "vega-parser": "^3.8.0", + "vega-projection": "^1.2.0", + "vega-runtime": "^3.1.1", + "vega-scale": "^2.5.0", + "vega-scenegraph": "^3.2.3", + "vega-statistics": "^1.2.2", + "vega-transforms": "^2.3.0", + "vega-typings": "*", + "vega-util": "^1.7.0", + "vega-view": "^3.4.0", + "vega-view-transforms": "^2.0.3", + "vega-voronoi": "^3.0.0", + "vega-wordcloud": "^3.0.0" + } + }, + "vega-lite": { + "version": "3.0.0-rc8", + "resolved": "https://registry.npmjs.org/vega-lite/-/vega-lite-3.0.0-rc8.tgz", + "integrity": "sha512-lvD3KAyBI4OFi4EGauRLEuy+XO55klyFAuRcyrCcNfIkvLZjQtVQw//tg7bytDX5IfY//Pwv8zdlFH25Yx2R3A==", + "requires": { + "fast-deep-equal": "^2.0.1", + "json-stable-stringify": "^1.0.1", + "json-stringify-pretty-compact": "^1.2.0", + "tslib": "^1.9.3", + "vega-event-selector": "^2.0.0", + "vega-typings": "0.3.48", + "vega-util": "^1.7.0", + "yargs": "^12.0.2" + }, + "dependencies": { + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + } + } + }, + "vega-loader": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vega-loader/-/vega-loader-3.0.1.tgz", + "integrity": "sha1-coQmtU503n28kdQY4FIwvH7iOog=", + "requires": { + "d3-dsv": "^1.0.8", + "d3-time-format": "^2.1.1", + "node-fetch": "^2.1.2", + "topojson-client": "^3.0.0", + "vega-util": "^1.7.0" + } + }, + "vega-parser": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/vega-parser/-/vega-parser-3.8.0.tgz", + "integrity": "sha512-kO8uZHjUq4fnBtiegueNmDP0dzckRW9zbZp285Ece1V6qRPmkatQSMcMQkc3RWqAjz76ty2I/qt1LcgMJXfeQw==", + "requires": { + "d3-array": "^1.2.4", + "d3-color": "^1.2.3", + "d3-format": "^1.3.2", + "d3-geo": "^1.11.1", + "d3-time-format": "^2.1.3", + "vega-dataflow": "^4.0.4", + "vega-event-selector": "^2.0.0", + "vega-expression": "^2.4.0", + "vega-scale": "^2.5.0", + "vega-scenegraph": "^3.2.3", + "vega-statistics": "^1.2.2", + "vega-util": "^1.7.0" + }, + "dependencies": { + "d3-array": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" + }, + "d3-color": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.2.3.tgz", + "integrity": "sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw==" + }, + "d3-format": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.3.2.tgz", + "integrity": "sha512-Z18Dprj96ExragQ0DeGi+SYPQ7pPfRMtUXtsg/ChVIKNBCzjO8XYJvRTC1usblx52lqge56V5ect+frYTQc8WQ==" + }, + "d3-geo": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.11.1.tgz", + "integrity": "sha512-GsG7x9G9sykseLviOVSJ3h5yjw0ItLopOtuDQKUt1TRklEegCw5WAmnIpYYiCkSH/QgUMleAeE2xZK38Qb+1+Q==", + "requires": { + "d3-array": "1" + } + }, + "d3-time-format": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.1.3.tgz", + "integrity": "sha512-6k0a2rZryzGm5Ihx+aFMuO1GgelgIz+7HhB4PH4OEndD5q2zGn1mDfRdNrulspOfR6JXkb2sThhDK41CSK85QA==", + "requires": { + "d3-time": "1" + } + } + } + }, + "vega-projection": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vega-projection/-/vega-projection-1.2.0.tgz", + "integrity": "sha1-gSyVUlHatJX9qD2UBrpy2YM6IBQ=", + "requires": { + "d3-geo": "^1.10.0" + }, + "dependencies": { + "d3-geo": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.11.1.tgz", + "integrity": "sha512-GsG7x9G9sykseLviOVSJ3h5yjw0ItLopOtuDQKUt1TRklEegCw5WAmnIpYYiCkSH/QgUMleAeE2xZK38Qb+1+Q==", + "requires": { + "d3-array": "1" + } + } + } + }, + "vega-runtime": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/vega-runtime/-/vega-runtime-3.1.1.tgz", + "integrity": "sha512-blO3qROr+Rmy/X50tskG5iKmG/hzL55sdw/tly4VIStJ7sVE4ivc0iqyVuka7ID88ft3iVieljZGExAldP/S8w==", + "requires": { + "vega-dataflow": "^4.0.4", + "vega-util": "^1.7.0" + } + }, + "vega-scale": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/vega-scale/-/vega-scale-2.5.0.tgz", + "integrity": "sha512-dDpVyQClEpZuR03c71jAPoBSHhkRYc+iyNerA9UeZYbOJZK/yhsicgbifXUEMz5cmJBdGIMFugbw/FBtmzeFQQ==", + "requires": { + "d3-array": "^1.2.4", + "d3-interpolate": "^1.3.2", + "d3-scale": "^2.1.2", + "d3-scale-chromatic": "^1.3.3", + "d3-time": "^1.0.10", + "vega-util": "^1.7.0" + }, + "dependencies": { + "d3-array": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" + }, + "d3-interpolate": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.3.2.tgz", + "integrity": "sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w==", + "requires": { + "d3-color": "1" + } + }, + "d3-scale": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.1.2.tgz", + "integrity": "sha512-bESpd64ylaKzCDzvULcmHKZTlzA/6DGSVwx7QSDj/EnX9cpSevsdiwdHFYI9ouo9tNBbV3v5xztHS2uFeOzh8Q==", + "requires": { + "d3-array": "^1.2.0", + "d3-collection": "1", + "d3-format": "1", + "d3-interpolate": "1", + "d3-time": "1", + "d3-time-format": "2" + } + }, + "d3-time": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.10.tgz", + "integrity": "sha512-hF+NTLCaJHF/JqHN5hE8HVGAXPStEq6/omumPE/SxyHVrR7/qQxusFDo0t0c/44+sCGHthC7yNGFZIEgju0P8g==" + } + } + }, + "vega-scenegraph": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/vega-scenegraph/-/vega-scenegraph-3.2.3.tgz", + "integrity": "sha512-L4mZ6LpEKvW5Q0c8gyqozGuoY5miJI4DiRipiAG0BQ6rB67tK+8qlaTfslX4tNBz88mu+CyVO9ZjNW/M4nBI3w==", + "requires": { + "d3-path": "^1.0.7", + "d3-shape": "^1.2.2", + "vega-canvas": "^1.1.0", + "vega-loader": "^3.0.1", + "vega-util": "^1.7.0" + }, + "dependencies": { + "d3-path": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.7.tgz", + "integrity": "sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA==" + }, + "d3-shape": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.2.2.tgz", + "integrity": "sha512-hUGEozlKecFZ2bOSNt7ENex+4Tk9uc/m0TtTEHBvitCBxUNjhzm5hS2GrrVRD/ae4IylSmxGeqX5tWC2rASMlQ==", + "requires": { + "d3-path": "1" + } + } + } + }, + "vega-schema-url-parser": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vega-schema-url-parser/-/vega-schema-url-parser-1.1.0.tgz", + "integrity": "sha512-Tc85J2ofMZZOsxiqDM9sbvfsa+Vdo3GwNLjEEsPOsCDeYqsUHKAlc1IpbbhPLZ6jusyM9Lk0e1izF64GGklFDg==" + }, + "vega-statistics": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/vega-statistics/-/vega-statistics-1.2.2.tgz", + "integrity": "sha512-8izr76Ub5n7vSV+I72t07LOGpgynXN1/0Kbrxpw4LaPEHPG4OWORiZczEypL2VWWGXU8GBVaXHSlrJvyWujo9A==", + "requires": { + "d3-array": "^1.2.4" + }, + "dependencies": { + "d3-array": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" + } + } + }, + "vega-themes": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/vega-themes/-/vega-themes-2.1.1.tgz", + "integrity": "sha512-K85RHCskSxf6/EqhRn3s1l/BqOkNV3+FjJMtb6dsays8g/HZAmUMSS2E0ind0inK5SmrMsseenqtgDBFL+GxFw==", + "requires": { + "vega-typings": "^0.3.4" + } + }, + "vega-tooltip": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/vega-tooltip/-/vega-tooltip-0.13.0.tgz", + "integrity": "sha512-NbeHzpxwKZ+yk+CION3wRH66rx9XGx5v6M82LT6qSIAnUrH8eh+sFtjK6pO7ErXGF5AieAhg8Hfb/NvC8uNMuA==", + "requires": { + "vega-util": "^1.7.0" + } + }, + "vega-transforms": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/vega-transforms/-/vega-transforms-2.3.0.tgz", + "integrity": "sha512-iTcnKTAOMIDs2pYj82P6izEymXF04niMpAu8697aNUOe+6KsHjpJDV8EvBlHbcB6mZ99GwvtgTPzdV/2enb5eA==", + "requires": { + "d3-array": "^1.2.4", + "vega-dataflow": "^4.0.4", + "vega-statistics": "^1.2.2", + "vega-util": "^1.7.0" + }, + "dependencies": { + "d3-array": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" + } + } + }, + "vega-typings": { + "version": "0.3.48", + "resolved": "https://registry.npmjs.org/vega-typings/-/vega-typings-0.3.48.tgz", + "integrity": "sha512-88dMuJuDzUyvqI0M2Vhzwl5QfWwXXXG8W1/sTtHTpQspPb+oJ1sKHKQ5ke2cUE24273nPgl+7JbaV8EAW7vxgw==", + "requires": { + "vega-util": "^1.7.0" + } + }, + "vega-util": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vega-util/-/vega-util-1.7.0.tgz", + "integrity": "sha512-IlmYqW0t3UP8AJX4QuOOm5cMPKPOUa8fSTcCvNkfVOR5zvMNFKCVhoZmJSXgcbEhkfboB+ysI2aaWOeW2kKBog==" + }, + "vega-view": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/vega-view/-/vega-view-3.4.0.tgz", + "integrity": "sha512-QLWYNaoA/m6M4n2CG98rsdgGbkjLTlFtUQleK9oy4XdTkSZSSwwVt/j3xDSCn1gvWMB7rxdBqisFnMi7oxSfOw==", + "requires": { + "d3-array": "^1.2.4", + "d3-timer": "^1.0.9", + "vega-dataflow": "^4.0.4", + "vega-parser": "^3.8.0", + "vega-runtime": "^3.1.1", + "vega-scenegraph": "^3.2.3", + "vega-util": "^1.7.0" + }, + "dependencies": { + "d3-array": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" + }, + "d3-timer": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.9.tgz", + "integrity": "sha512-rT34J5HnQUHhcLvhSB9GjCkN0Ddd5Y8nCwDBG2u6wQEeYxT/Lf51fTFFkldeib/sE/J0clIe0pnCfs6g/lRbyg==" + } + } + }, + "vega-view-transforms": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/vega-view-transforms/-/vega-view-transforms-2.0.3.tgz", + "integrity": "sha512-m42sP2G72KIIEhbno5P3wYXuGe4C5fj0ztfg1TrSEmGsIHOqoehRvte/1e9q/dV+1rB3TqfcWXgQVEDHCFLEvQ==", + "requires": { + "vega-dataflow": "^4.0.4", + "vega-scenegraph": "^3.2.3", + "vega-util": "^1.7.0" + } + }, + "vega-voronoi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vega-voronoi/-/vega-voronoi-3.0.0.tgz", + "integrity": "sha512-ZkQw4UprxqiS3IjrdLOoQq1oEeH0REqWonf7Wz5zt2pKDHyMPlFX89EueoDYOKnfQjk9/7IiptBDK1ruAbDNiQ==", + "requires": { + "d3-voronoi": "^1.1.2", + "vega-dataflow": "^4.0.0", + "vega-util": "^1.7.0" + } + }, + "vega-wordcloud": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vega-wordcloud/-/vega-wordcloud-3.0.0.tgz", + "integrity": "sha512-/2F09L2tNTQ8aqK/ZLjd7m+fYwJR8/waE8YWuexLZob4+4BEByzqFfRMATE39ZpdTHOreCEQ5uUKyvv0qA6O0A==", + "requires": { + "vega-canvas": "^1.0.1", + "vega-dataflow": "^4.0.0", + "vega-scale": "^2.1.1", + "vega-statistics": "^1.2.1", + "vega-util": "^1.7.0" + } + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -19086,7 +20232,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -19094,13 +20239,21 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } }, "widest-line": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.0.tgz", - "integrity": "sha1-AUKk6KJD+IgsAjOqDgKBqnYVInM=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", "dev": true, "requires": { "string-width": "^2.1.1" @@ -19192,7 +20345,6 @@ "version": "2.1.0", "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" @@ -19202,7 +20354,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -19212,8 +20363,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "0.2.1", @@ -19267,9 +20417,9 @@ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" }, "xmlbuilder": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz", - "integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M=", + "version": "9.0.7", + "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, "xmldom": { @@ -19278,6 +20428,11 @@ "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=", "dev": true }, + "xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" + }, "xmlhttprequest-ssl": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", @@ -19287,8 +20442,7 @@ "xregexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", - "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==", - "dev": true + "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==" }, "xtend": { "version": "4.0.1", @@ -19299,8 +20453,7 @@ "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "yallist": { "version": "2.1.2", @@ -19312,7 +20465,6 @@ "version": "12.0.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.2.tgz", "integrity": "sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==", - "dev": true, "requires": { "cliui": "^4.0.0", "decamelize": "^2.0.0", @@ -19332,7 +20484,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz", "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==", - "dev": true, "requires": { "xregexp": "4.0.0" } @@ -19341,7 +20492,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, "requires": { "locate-path": "^3.0.0" } @@ -19349,14 +20499,12 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -19366,7 +20514,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz", "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", - "dev": true, "requires": { "p-try": "^2.0.0" } @@ -19375,7 +20522,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, "requires": { "p-limit": "^2.0.0" } @@ -19383,14 +20529,12 @@ "p-try": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==" }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -19402,7 +20546,6 @@ "version": "10.1.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", - "dev": true, "requires": { "camelcase": "^4.1.0" }, @@ -19410,8 +20553,7 @@ "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" } } }, diff --git a/package.json b/package.json index 5783df03..fff3a4b2 100644 --- a/package.json +++ b/package.json @@ -136,18 +136,25 @@ "dompurify": "^1.0.8", "element-ui": "^2.4.7", "file-icons-js": "^1.0.3", + "flowchart.js": "^1.11.3", "fs-extra": "^7.0.0", "fuzzaldrin": "^2.1.0", "github-markdown-css": "^2.10.0", "html-tags": "^2.0.0", - "katex": "^0.10.0-rc.1", + "katex": "^0.10.0", "markdown-toc": "^1.2.0", + "mermaid": "^8.0.0-rc.8", "popper.js": "^1.14.4", "prismjs2": "^1.15.0", "snabbdom": "^0.7.2", "snabbdom-to-html": "^5.1.1", + "snapsvg": "^0.5.1", "turndown": "^5.0.1", "turndown-plugin-gfm": "^1.0.2", + "underscore": "^1.9.1", + "vega": "^4.3.0", + "vega-embed": "^3.21.1", + "vega-lite": "^3.0.0-rc8", "vue": "^2.5.17", "vue-electron": "^1.0.6", "vuex": "^3.0.1" @@ -170,12 +177,12 @@ "css-loader": "^1.0.0", "del": "^3.0.0", "devtron": "^1.4.0", - "electron": "^3.0.5", - "electron-builder": "^20.28.4", + "electron": "^3.0.7", + "electron-builder": "^20.29.0", "electron-debug": "^2.0.0", "electron-devtools-installer": "^2.2.4", - "electron-updater": "^3.1.2", - "electron-window-state": "^5.0.1", + "electron-updater": "^3.1.6", + "electron-window-state": "^5.0.2", "eslint": "^4.19.1", "eslint-config-standard": "^11.0.0", "eslint-friendly-formatter": "^4.0.1", diff --git a/src/main/menus/view.js b/src/main/menus/view.js index c0d7091f..9090c8b4 100755 --- a/src/main/menus/view.js +++ b/src/main/menus/view.js @@ -80,7 +80,7 @@ let viewMenu = { }] } -if (process.env.NODE_ENV !== 'production' || process.env.NODE_ENV === 'development') { +if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'development') { // add devtool when development viewMenu.submenu.push({ label: 'Toggle Developer Tools', diff --git a/src/muya/lib/assets/icons/chart.svg b/src/muya/lib/assets/icons/chart.svg new file mode 100644 index 00000000..f6fa0164 --- /dev/null +++ b/src/muya/lib/assets/icons/chart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/muya/lib/assets/icons/flowchart.svg b/src/muya/lib/assets/icons/flowchart.svg new file mode 100644 index 00000000..c3e1f0d2 --- /dev/null +++ b/src/muya/lib/assets/icons/flowchart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/muya/lib/assets/icons/mermaid.svg b/src/muya/lib/assets/icons/mermaid.svg new file mode 100644 index 00000000..4fac6e39 --- /dev/null +++ b/src/muya/lib/assets/icons/mermaid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/muya/lib/assets/icons/sequence.svg b/src/muya/lib/assets/icons/sequence.svg new file mode 100644 index 00000000..90fefede --- /dev/null +++ b/src/muya/lib/assets/icons/sequence.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/muya/lib/assets/libs/raphael.js b/src/muya/lib/assets/libs/raphael.js new file mode 100644 index 00000000..4433e001 --- /dev/null +++ b/src/muya/lib/assets/libs/raphael.js @@ -0,0 +1,142 @@ +// ┌───────────────────────────────────────────────────────────────────────────────────────────────────────┐ \\ +// │ Raphaël 2.2.0 - JavaScript Vector Library │ \\ +// ├───────────────────────────────────────────────────────────────────────────────────────────────────────┤ \\ +// │ Copyright © 2008-2016 Dmitry Baranovskiy (http://raphaeljs.com) │ \\ +// │ Copyright © 2008-2016 Sencha Labs (http://sencha.com) │ \\ +// ├───────────────────────────────────────────────────────────────────────────────────────────────────────┤ \\ +// │ Licensed under the MIT (https://github.com/DmitryBaranovskiy/raphael/blob/master/license.txt) license.│ \\ +// └───────────────────────────────────────────────────────────────────────────────────────────────────────┘ \\ + +(function webpackUniversalModuleDefinition(root, factory) { + root["Raphael"] = factory(); +})(window, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = "./dev/raphael.amd.js"); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "./dev/raphael.amd.js": +/*!****************************!*\ + !*** ./dev/raphael.amd.js ***! + \****************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! ./raphael.core */ \"./dev/raphael.core.js\"), __webpack_require__(/*! ./raphael.svg */ \"./dev/raphael.svg.js\"), __webpack_require__(/*! ./raphael.vml */ \"./dev/raphael.vml.js\")], __WEBPACK_AMD_DEFINE_RESULT__ = (function(R) {\n\n return R;\n\n}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9kZXYvcmFwaGFlbC5hbWQuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9SYXBoYWVsLy4vZGV2L3JhcGhhZWwuYW1kLmpzPzM1NjQiXSwic291cmNlc0NvbnRlbnQiOlsiZGVmaW5lKFtcIi4vcmFwaGFlbC5jb3JlXCIsIFwiLi9yYXBoYWVsLnN2Z1wiLCBcIi4vcmFwaGFlbC52bWxcIl0sIGZ1bmN0aW9uKFIpIHtcblxuICAgIHJldHVybiBSO1xuXG59KTsiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./dev/raphael.amd.js\n"); + +/***/ }), + +/***/ "./dev/raphael.core.js": +/*!*****************************!*\ + !*** ./dev/raphael.core.js ***! + \*****************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! eve */ \"./node_modules/eve-raphael/eve.js\")], __WEBPACK_AMD_DEFINE_RESULT__ = (function(eve) {\n\n /*\\\n * Raphael\n [ method ]\n **\n * Creates a canvas object on which to draw.\n * You must do this first, as all future calls to drawing methods\n * from this instance will be bound to this canvas.\n > Parameters\n **\n - container (HTMLElement|string) DOM element or its ID which is going to be a parent for drawing surface\n - width (number)\n - height (number)\n - callback (function) #optional callback function which is going to be executed in the context of newly created paper\n * or\n - x (number)\n - y (number)\n - width (number)\n - height (number)\n - callback (function) #optional callback function which is going to be executed in the context of newly created paper\n * or\n - all (array) (first 3 or 4 elements in the array are equal to [containerID, width, height] or [x, y, width, height]. The rest are element descriptions in format {type: type, }). See @Paper.add.\n - callback (function) #optional callback function which is going to be executed in the context of newly created paper\n * or\n - onReadyCallback (function) function that is going to be called on DOM ready event. You can also subscribe to this event via Eve’s “DOMLoad” event. In this case method returns `undefined`.\n = (object) @Paper\n > Usage\n | // Each of the following examples create a canvas\n | // that is 320px wide by 200px high.\n | // Canvas is created at the viewport’s 10,50 coordinate.\n | var paper = Raphael(10, 50, 320, 200);\n | // Canvas is created at the top left corner of the #notepad element\n | // (or its top right corner in dir=\"rtl\" elements)\n | var paper = Raphael(document.getElementById(\"notepad\"), 320, 200);\n | // Same as above\n | var paper = Raphael(\"notepad\", 320, 200);\n | // Image dump\n | var set = Raphael([\"notepad\", 320, 200, {\n | type: \"rect\",\n | x: 10,\n | y: 10,\n | width: 25,\n | height: 25,\n | stroke: \"#f00\"\n | }, {\n | type: \"text\",\n | x: 30,\n | y: 40,\n | text: \"Dump\"\n | }]);\n \\*/\n function R(first) {\n if (R.is(first, \"function\")) {\n return loaded ? first() : eve.on(\"raphael.DOMload\", first);\n } else if (R.is(first, array)) {\n return R._engine.create[apply](R, first.splice(0, 3 + R.is(first[0], nu))).add(first);\n } else {\n var args = Array.prototype.slice.call(arguments, 0);\n if (R.is(args[args.length - 1], \"function\")) {\n var f = args.pop();\n return loaded ? f.call(R._engine.create[apply](R, args)) : eve.on(\"raphael.DOMload\", function () {\n f.call(R._engine.create[apply](R, args));\n });\n } else {\n return R._engine.create[apply](R, arguments);\n }\n }\n }\n R.version = \"2.2.0\";\n R.eve = eve;\n var loaded,\n separator = /[, ]+/,\n elements = {circle: 1, rect: 1, path: 1, ellipse: 1, text: 1, image: 1},\n formatrg = /\\{(\\d+)\\}/g,\n proto = \"prototype\",\n has = \"hasOwnProperty\",\n g = {\n doc: document,\n win: window\n },\n oldRaphael = {\n was: Object.prototype[has].call(g.win, \"Raphael\"),\n is: g.win.Raphael\n },\n Paper = function () {\n /*\\\n * Paper.ca\n [ property (object) ]\n **\n * Shortcut for @Paper.customAttributes\n \\*/\n /*\\\n * Paper.customAttributes\n [ property (object) ]\n **\n * If you have a set of attributes that you would like to represent\n * as a function of some number you can do it easily with custom attributes:\n > Usage\n | paper.customAttributes.hue = function (num) {\n | num = num % 1;\n | return {fill: \"hsb(\" + num + \", 0.75, 1)\"};\n | };\n | // Custom attribute “hue” will change fill\n | // to be given hue with fixed saturation and brightness.\n | // Now you can use it like this:\n | var c = paper.circle(10, 10, 10).attr({hue: .45});\n | // or even like this:\n | c.animate({hue: 1}, 1e3);\n |\n | // You could also create custom attribute\n | // with multiple parameters:\n | paper.customAttributes.hsb = function (h, s, b) {\n | return {fill: \"hsb(\" + [h, s, b].join(\",\") + \")\"};\n | };\n | c.attr({hsb: \"0.5 .8 1\"});\n | c.animate({hsb: [1, 0, 0.5]}, 1e3);\n \\*/\n this.ca = this.customAttributes = {};\n },\n paperproto,\n appendChild = \"appendChild\",\n apply = \"apply\",\n concat = \"concat\",\n supportsTouch = ('ontouchstart' in g.win) || g.win.DocumentTouch && g.doc instanceof DocumentTouch, //taken from Modernizr touch test\n E = \"\",\n S = \" \",\n Str = String,\n split = \"split\",\n events = \"click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel\"[split](S),\n touchMap = {\n mousedown: \"touchstart\",\n mousemove: \"touchmove\",\n mouseup: \"touchend\"\n },\n lowerCase = Str.prototype.toLowerCase,\n math = Math,\n mmax = math.max,\n mmin = math.min,\n abs = math.abs,\n pow = math.pow,\n PI = math.PI,\n nu = \"number\",\n string = \"string\",\n array = \"array\",\n toString = \"toString\",\n fillString = \"fill\",\n objectToString = Object.prototype.toString,\n paper = {},\n push = \"push\",\n ISURL = R._ISURL = /^url\\(['\"]?(.+?)['\"]?\\)$/i,\n colourRegExp = /^\\s*((#[a-f\\d]{6})|(#[a-f\\d]{3})|rgba?\\(\\s*([\\d\\.]+%?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+%?(?:\\s*,\\s*[\\d\\.]+%?)?)\\s*\\)|hsba?\\(\\s*([\\d\\.]+(?:deg|\\xb0|%)?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+(?:%?\\s*,\\s*[\\d\\.]+)?)%?\\s*\\)|hsla?\\(\\s*([\\d\\.]+(?:deg|\\xb0|%)?\\s*,\\s*[\\d\\.]+%?\\s*,\\s*[\\d\\.]+(?:%?\\s*,\\s*[\\d\\.]+)?)%?\\s*\\))\\s*$/i,\n isnan = {\"NaN\": 1, \"Infinity\": 1, \"-Infinity\": 1},\n bezierrg = /^(?:cubic-)?bezier\\(([^,]+),([^,]+),([^,]+),([^\\)]+)\\)/,\n round = math.round,\n setAttribute = \"setAttribute\",\n toFloat = parseFloat,\n toInt = parseInt,\n upperCase = Str.prototype.toUpperCase,\n availableAttrs = R._availableAttrs = {\n \"arrow-end\": \"none\",\n \"arrow-start\": \"none\",\n blur: 0,\n \"clip-rect\": \"0 0 1e9 1e9\",\n cursor: \"default\",\n cx: 0,\n cy: 0,\n fill: \"#fff\",\n \"fill-opacity\": 1,\n font: '10px \"Arial\"',\n \"font-family\": '\"Arial\"',\n \"font-size\": \"10\",\n \"font-style\": \"normal\",\n \"font-weight\": 400,\n gradient: 0,\n height: 0,\n href: \"http://raphaeljs.com/\",\n \"letter-spacing\": 0,\n opacity: 1,\n path: \"M0,0\",\n r: 0,\n rx: 0,\n ry: 0,\n src: \"\",\n stroke: \"#000\",\n \"stroke-dasharray\": \"\",\n \"stroke-linecap\": \"butt\",\n \"stroke-linejoin\": \"butt\",\n \"stroke-miterlimit\": 0,\n \"stroke-opacity\": 1,\n \"stroke-width\": 1,\n target: \"_blank\",\n \"text-anchor\": \"middle\",\n title: \"Raphael\",\n transform: \"\",\n width: 0,\n x: 0,\n y: 0,\n \"class\": \"\"\n },\n availableAnimAttrs = R._availableAnimAttrs = {\n blur: nu,\n \"clip-rect\": \"csv\",\n cx: nu,\n cy: nu,\n fill: \"colour\",\n \"fill-opacity\": nu,\n \"font-size\": nu,\n height: nu,\n opacity: nu,\n path: \"path\",\n r: nu,\n rx: nu,\n ry: nu,\n stroke: \"colour\",\n \"stroke-opacity\": nu,\n \"stroke-width\": nu,\n transform: \"transform\",\n width: nu,\n x: nu,\n y: nu\n },\n whitespace = /[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]/g,\n commaSpaces = /[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*/,\n hsrg = {hs: 1, rg: 1},\n p2s = /,?([achlmqrstvxz]),?/gi,\n pathCommand = /([achlmrqstvz])[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029,]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*)+)/ig,\n tCommand = /([rstm])[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029,]*((-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*)+)/ig,\n pathValues = /(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,?[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*/ig,\n radial_gradient = R._radial_gradient = /^r(?:\\(([^,]+?)[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*,[\\x09\\x0a\\x0b\\x0c\\x0d\\x20\\xa0\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029]*([^\\)]+?)\\))?/,\n eldata = {},\n sortByKey = function (a, b) {\n return a.key - b.key;\n },\n sortByNumber = function (a, b) {\n return toFloat(a) - toFloat(b);\n },\n fun = function () {},\n pipe = function (x) {\n return x;\n },\n rectPath = R._rectPath = function (x, y, w, h, r) {\n if (r) {\n return [[\"M\", x + r, y], [\"l\", w - r * 2, 0], [\"a\", r, r, 0, 0, 1, r, r], [\"l\", 0, h - r * 2], [\"a\", r, r, 0, 0, 1, -r, r], [\"l\", r * 2 - w, 0], [\"a\", r, r, 0, 0, 1, -r, -r], [\"l\", 0, r * 2 - h], [\"a\", r, r, 0, 0, 1, r, -r], [\"z\"]];\n }\n return [[\"M\", x, y], [\"l\", w, 0], [\"l\", 0, h], [\"l\", -w, 0], [\"z\"]];\n },\n ellipsePath = function (x, y, rx, ry) {\n if (ry == null) {\n ry = rx;\n }\n return [[\"M\", x, y], [\"m\", 0, -ry], [\"a\", rx, ry, 0, 1, 1, 0, 2 * ry], [\"a\", rx, ry, 0, 1, 1, 0, -2 * ry], [\"z\"]];\n },\n getPath = R._getPath = {\n path: function (el) {\n return el.attr(\"path\");\n },\n circle: function (el) {\n var a = el.attrs;\n return ellipsePath(a.cx, a.cy, a.r);\n },\n ellipse: function (el) {\n var a = el.attrs;\n return ellipsePath(a.cx, a.cy, a.rx, a.ry);\n },\n rect: function (el) {\n var a = el.attrs;\n return rectPath(a.x, a.y, a.width, a.height, a.r);\n },\n image: function (el) {\n var a = el.attrs;\n return rectPath(a.x, a.y, a.width, a.height);\n },\n text: function (el) {\n var bbox = el._getBBox();\n return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);\n },\n set : function(el) {\n var bbox = el._getBBox();\n return rectPath(bbox.x, bbox.y, bbox.width, bbox.height);\n }\n },\n /*\\\n * Raphael.mapPath\n [ method ]\n **\n * Transform the path string with given matrix.\n > Parameters\n - path (string) path string\n - matrix (object) see @Matrix\n = (string) transformed path string\n \\*/\n mapPath = R.mapPath = function (path, matrix) {\n if (!matrix) {\n return path;\n }\n var x, y, i, j, ii, jj, pathi;\n path = path2curve(path);\n for (i = 0, ii = path.length; i < ii; i++) {\n pathi = path[i];\n for (j = 1, jj = pathi.length; j < jj; j += 2) {\n x = matrix.x(pathi[j], pathi[j + 1]);\n y = matrix.y(pathi[j], pathi[j + 1]);\n pathi[j] = x;\n pathi[j + 1] = y;\n }\n }\n return path;\n };\n\n R._g = g;\n /*\\\n * Raphael.type\n [ property (string) ]\n **\n * Can be “SVG”, “VML” or empty, depending on browser support.\n \\*/\n R.type = (g.win.SVGAngle || g.doc.implementation.hasFeature(\"http://www.w3.org/TR/SVG11/feature#BasicStructure\", \"1.1\") ? \"SVG\" : \"VML\");\n if (R.type == \"VML\") {\n var d = g.doc.createElement(\"div\"),\n b;\n d.innerHTML = '';\n b = d.firstChild;\n b.style.behavior = \"url(#default#VML)\";\n if (!(b && typeof b.adj == \"object\")) {\n return (R.type = E);\n }\n d = null;\n }\n /*\\\n * Raphael.svg\n [ property (boolean) ]\n **\n * `true` if browser supports SVG.\n \\*/\n /*\\\n * Raphael.vml\n [ property (boolean) ]\n **\n * `true` if browser supports VML.\n \\*/\n R.svg = !(R.vml = R.type == \"VML\");\n R._Paper = Paper;\n /*\\\n * Raphael.fn\n [ property (object) ]\n **\n * You can add your own method to the canvas. For example if you want to draw a pie chart,\n * you can create your own pie chart function and ship it as a Raphaël plugin. To do this\n * you need to extend the `Raphael.fn` object. You should modify the `fn` object before a\n * Raphaël instance is created, otherwise it will take no effect. Please note that the\n * ability for namespaced plugins was removed in Raphael 2.0. It is up to the plugin to\n * ensure any namespacing ensures proper context.\n > Usage\n | Raphael.fn.arrow = function (x1, y1, x2, y2, size) {\n | return this.path( ... );\n | };\n | // or create namespace\n | Raphael.fn.mystuff = {\n | arrow: function () {…},\n | star: function () {…},\n | // etc…\n | };\n | var paper = Raphael(10, 10, 630, 480);\n | // then use it\n | paper.arrow(10, 10, 30, 30, 5).attr({fill: \"#f00\"});\n | paper.mystuff.arrow();\n | paper.mystuff.star();\n \\*/\n R.fn = paperproto = Paper.prototype = R.prototype;\n R._id = 0;\n /*\\\n * Raphael.is\n [ method ]\n **\n * Handful of replacements for `typeof` operator.\n > Parameters\n - o (…) any object or primitive\n - type (string) name of the type, i.e. “string”, “function”, “number”, etc.\n = (boolean) is given value is of given type\n \\*/\n R.is = function (o, type) {\n type = lowerCase.call(type);\n if (type == \"finite\") {\n return !isnan[has](+o);\n }\n if (type == \"array\") {\n return o instanceof Array;\n }\n return (type == \"null\" && o === null) ||\n (type == typeof o && o !== null) ||\n (type == \"object\" && o === Object(o)) ||\n (type == \"array\" && Array.isArray && Array.isArray(o)) ||\n objectToString.call(o).slice(8, -1).toLowerCase() == type;\n };\n\n function clone(obj) {\n if (typeof obj == \"function\" || Object(obj) !== obj) {\n return obj;\n }\n var res = new obj.constructor;\n for (var key in obj) if (obj[has](key)) {\n res[key] = clone(obj[key]);\n }\n return res;\n }\n\n /*\\\n * Raphael.angle\n [ method ]\n **\n * Returns angle between two or three points\n > Parameters\n - x1 (number) x coord of first point\n - y1 (number) y coord of first point\n - x2 (number) x coord of second point\n - y2 (number) y coord of second point\n - x3 (number) #optional x coord of third point\n - y3 (number) #optional y coord of third point\n = (number) angle in degrees.\n \\*/\n R.angle = function (x1, y1, x2, y2, x3, y3) {\n if (x3 == null) {\n var x = x1 - x2,\n y = y1 - y2;\n if (!x && !y) {\n return 0;\n }\n return (180 + math.atan2(-y, -x) * 180 / PI + 360) % 360;\n } else {\n return R.angle(x1, y1, x3, y3) - R.angle(x2, y2, x3, y3);\n }\n };\n /*\\\n * Raphael.rad\n [ method ]\n **\n * Transform angle to radians\n > Parameters\n - deg (number) angle in degrees\n = (number) angle in radians.\n \\*/\n R.rad = function (deg) {\n return deg % 360 * PI / 180;\n };\n /*\\\n * Raphael.deg\n [ method ]\n **\n * Transform angle to degrees\n > Parameters\n - rad (number) angle in radians\n = (number) angle in degrees.\n \\*/\n R.deg = function (rad) {\n return Math.round ((rad * 180 / PI% 360)* 1000) / 1000;\n };\n /*\\\n * Raphael.snapTo\n [ method ]\n **\n * Snaps given value to given grid.\n > Parameters\n - values (array|number) given array of values or step of the grid\n - value (number) value to adjust\n - tolerance (number) #optional tolerance for snapping. Default is `10`.\n = (number) adjusted value.\n \\*/\n R.snapTo = function (values, value, tolerance) {\n tolerance = R.is(tolerance, \"finite\") ? tolerance : 10;\n if (R.is(values, array)) {\n var i = values.length;\n while (i--) if (abs(values[i] - value) <= tolerance) {\n return values[i];\n }\n } else {\n values = +values;\n var rem = value % values;\n if (rem < tolerance) {\n return value - rem;\n }\n if (rem > values - tolerance) {\n return value - rem + values;\n }\n }\n return value;\n };\n\n /*\\\n * Raphael.createUUID\n [ method ]\n **\n * Returns RFC4122, version 4 ID\n \\*/\n var createUUID = R.createUUID = (function (uuidRegEx, uuidReplacer) {\n return function () {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(uuidRegEx, uuidReplacer).toUpperCase();\n };\n })(/[xy]/g, function (c) {\n var r = math.random() * 16 | 0,\n v = c == \"x\" ? r : (r & 3 | 8);\n return v.toString(16);\n });\n\n /*\\\n * Raphael.setWindow\n [ method ]\n **\n * Used when you need to draw in `<iframe>`. Switched window to the iframe one.\n > Parameters\n - newwin (window) new window object\n \\*/\n R.setWindow = function (newwin) {\n eve(\"raphael.setWindow\", R, g.win, newwin);\n g.win = newwin;\n g.doc = g.win.document;\n if (R._engine.initWin) {\n R._engine.initWin(g.win);\n }\n };\n var toHex = function (color) {\n if (R.vml) {\n // http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/\n var trim = /^\\s+|\\s+$/g;\n var bod;\n try {\n var docum = new ActiveXObject(\"htmlfile\");\n docum.write(\"\");\n docum.close();\n bod = docum.body;\n } catch(e) {\n bod = createPopup().document.body;\n }\n var range = bod.createTextRange();\n toHex = cacher(function (color) {\n try {\n bod.style.color = Str(color).replace(trim, E);\n var value = range.queryCommandValue(\"ForeColor\");\n value = ((value & 255) << 16) | (value & 65280) | ((value & 16711680) >>> 16);\n return \"#\" + (\"000000\" + value.toString(16)).slice(-6);\n } catch(e) {\n return \"none\";\n }\n });\n } else {\n var i = g.doc.createElement(\"i\");\n i.title = \"Rapha\\xebl Colour Picker\";\n i.style.display = \"none\";\n g.doc.body.appendChild(i);\n toHex = cacher(function (color) {\n i.style.color = color;\n return g.doc.defaultView.getComputedStyle(i, E).getPropertyValue(\"color\");\n });\n }\n return toHex(color);\n },\n hsbtoString = function () {\n return \"hsb(\" + [this.h, this.s, this.b] + \")\";\n },\n hsltoString = function () {\n return \"hsl(\" + [this.h, this.s, this.l] + \")\";\n },\n rgbtoString = function () {\n return this.hex;\n },\n prepareRGB = function (r, g, b) {\n if (g == null && R.is(r, \"object\") && \"r\" in r && \"g\" in r && \"b\" in r) {\n b = r.b;\n g = r.g;\n r = r.r;\n }\n if (g == null && R.is(r, string)) {\n var clr = R.getRGB(r);\n r = clr.r;\n g = clr.g;\n b = clr.b;\n }\n if (r > 1 || g > 1 || b > 1) {\n r /= 255;\n g /= 255;\n b /= 255;\n }\n\n return [r, g, b];\n },\n packageRGB = function (r, g, b, o) {\n r *= 255;\n g *= 255;\n b *= 255;\n var rgb = {\n r: r,\n g: g,\n b: b,\n hex: R.rgb(r, g, b),\n toString: rgbtoString\n };\n R.is(o, \"finite\") && (rgb.opacity = o);\n return rgb;\n };\n\n /*\\\n * Raphael.color\n [ method ]\n **\n * Parses the color string and returns object with all values for the given color.\n > Parameters\n - clr (string) color string in one of the supported formats (see @Raphael.getRGB)\n = (object) Combined RGB & HSB object in format:\n o {\n o r (number) red,\n o g (number) green,\n o b (number) blue,\n o hex (string) color in HTML/CSS format: #••••••,\n o error (boolean) `true` if string can’t be parsed,\n o h (number) hue,\n o s (number) saturation,\n o v (number) value (brightness),\n o l (number) lightness\n o }\n \\*/\n R.color = function (clr) {\n var rgb;\n if (R.is(clr, \"object\") && \"h\" in clr && \"s\" in clr && \"b\" in clr) {\n rgb = R.hsb2rgb(clr);\n clr.r = rgb.r;\n clr.g = rgb.g;\n clr.b = rgb.b;\n clr.hex = rgb.hex;\n } else if (R.is(clr, \"object\") && \"h\" in clr && \"s\" in clr && \"l\" in clr) {\n rgb = R.hsl2rgb(clr);\n clr.r = rgb.r;\n clr.g = rgb.g;\n clr.b = rgb.b;\n clr.hex = rgb.hex;\n } else {\n if (R.is(clr, \"string\")) {\n clr = R.getRGB(clr);\n }\n if (R.is(clr, \"object\") && \"r\" in clr && \"g\" in clr && \"b\" in clr) {\n rgb = R.rgb2hsl(clr);\n clr.h = rgb.h;\n clr.s = rgb.s;\n clr.l = rgb.l;\n rgb = R.rgb2hsb(clr);\n clr.v = rgb.b;\n } else {\n clr = {hex: \"none\"};\n clr.r = clr.g = clr.b = clr.h = clr.s = clr.v = clr.l = -1;\n }\n }\n clr.toString = rgbtoString;\n return clr;\n };\n /*\\\n * Raphael.hsb2rgb\n [ method ]\n **\n * Converts HSB values to RGB object.\n > Parameters\n - h (number) hue\n - s (number) saturation\n - v (number) value or brightness\n = (object) RGB object in format:\n o {\n o r (number) red,\n o g (number) green,\n o b (number) blue,\n o hex (string) color in HTML/CSS format: #••••••\n o }\n \\*/\n R.hsb2rgb = function (h, s, v, o) {\n if (this.is(h, \"object\") && \"h\" in h && \"s\" in h && \"b\" in h) {\n v = h.b;\n s = h.s;\n o = h.o;\n h = h.h;\n }\n h *= 360;\n var R, G, B, X, C;\n h = (h % 360) / 60;\n C = v * s;\n X = C * (1 - abs(h % 2 - 1));\n R = G = B = v - C;\n\n h = ~~h;\n R += [C, X, 0, 0, X, C][h];\n G += [X, C, C, X, 0, 0][h];\n B += [0, 0, X, C, C, X][h];\n return packageRGB(R, G, B, o);\n };\n /*\\\n * Raphael.hsl2rgb\n [ method ]\n **\n * Converts HSL values to RGB object.\n > Parameters\n - h (number) hue\n - s (number) saturation\n - l (number) luminosity\n = (object) RGB object in format:\n o {\n o r (number) red,\n o g (number) green,\n o b (number) blue,\n o hex (string) color in HTML/CSS format: #••••••\n o }\n \\*/\n R.hsl2rgb = function (h, s, l, o) {\n if (this.is(h, \"object\") && \"h\" in h && \"s\" in h && \"l\" in h) {\n l = h.l;\n s = h.s;\n h = h.h;\n }\n if (h > 1 || s > 1 || l > 1) {\n h /= 360;\n s /= 100;\n l /= 100;\n }\n h *= 360;\n var R, G, B, X, C;\n h = (h % 360) / 60;\n C = 2 * s * (l < .5 ? l : 1 - l);\n X = C * (1 - abs(h % 2 - 1));\n R = G = B = l - C / 2;\n\n h = ~~h;\n R += [C, X, 0, 0, X, C][h];\n G += [X, C, C, X, 0, 0][h];\n B += [0, 0, X, C, C, X][h];\n return packageRGB(R, G, B, o);\n };\n /*\\\n * Raphael.rgb2hsb\n [ method ]\n **\n * Converts RGB values to HSB object.\n > Parameters\n - r (number) red\n - g (number) green\n - b (number) blue\n = (object) HSB object in format:\n o {\n o h (number) hue\n o s (number) saturation\n o b (number) brightness\n o }\n \\*/\n R.rgb2hsb = function (r, g, b) {\n b = prepareRGB(r, g, b);\n r = b[0];\n g = b[1];\n b = b[2];\n\n var H, S, V, C;\n V = mmax(r, g, b);\n C = V - mmin(r, g, b);\n H = (C == 0 ? null :\n V == r ? (g - b) / C :\n V == g ? (b - r) / C + 2 :\n (r - g) / C + 4\n );\n H = ((H + 360) % 6) * 60 / 360;\n S = C == 0 ? 0 : C / V;\n return {h: H, s: S, b: V, toString: hsbtoString};\n };\n /*\\\n * Raphael.rgb2hsl\n [ method ]\n **\n * Converts RGB values to HSL object.\n > Parameters\n - r (number) red\n - g (number) green\n - b (number) blue\n = (object) HSL object in format:\n o {\n o h (number) hue\n o s (number) saturation\n o l (number) luminosity\n o }\n \\*/\n R.rgb2hsl = function (r, g, b) {\n b = prepareRGB(r, g, b);\n r = b[0];\n g = b[1];\n b = b[2];\n\n var H, S, L, M, m, C;\n M = mmax(r, g, b);\n m = mmin(r, g, b);\n C = M - m;\n H = (C == 0 ? null :\n M == r ? (g - b) / C :\n M == g ? (b - r) / C + 2 :\n (r - g) / C + 4);\n H = ((H + 360) % 6) * 60 / 360;\n L = (M + m) / 2;\n S = (C == 0 ? 0 :\n L < .5 ? C / (2 * L) :\n C / (2 - 2 * L));\n return {h: H, s: S, l: L, toString: hsltoString};\n };\n R._path2string = function () {\n return this.join(\",\").replace(p2s, \"$1\");\n };\n function repush(array, item) {\n for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) {\n return array.push(array.splice(i, 1)[0]);\n }\n }\n function cacher(f, scope, postprocessor) {\n function newf() {\n var arg = Array.prototype.slice.call(arguments, 0),\n args = arg.join(\"\\u2400\"),\n cache = newf.cache = newf.cache || {},\n count = newf.count = newf.count || [];\n if (cache[has](args)) {\n repush(count, args);\n return postprocessor ? postprocessor(cache[args]) : cache[args];\n }\n count.length >= 1e3 && delete cache[count.shift()];\n count.push(args);\n cache[args] = f[apply](scope, arg);\n return postprocessor ? postprocessor(cache[args]) : cache[args];\n }\n return newf;\n }\n\n var preload = R._preload = function (src, f) {\n var img = g.doc.createElement(\"img\");\n img.style.cssText = \"position:absolute;left:-9999em;top:-9999em\";\n img.onload = function () {\n f.call(this);\n this.onload = null;\n g.doc.body.removeChild(this);\n };\n img.onerror = function () {\n g.doc.body.removeChild(this);\n };\n g.doc.body.appendChild(img);\n img.src = src;\n };\n\n function clrToString() {\n return this.hex;\n }\n\n /*\\\n * Raphael.getRGB\n [ method ]\n **\n * Parses colour string as RGB object\n > Parameters\n - colour (string) colour string in one of formats:\n # \n = (object) RGB object in format:\n o {\n o r (number) red,\n o g (number) green,\n o b (number) blue\n o hex (string) color in HTML/CSS format: #••••••,\n o error (boolean) true if string can’t be parsed\n o }\n \\*/\n R.getRGB = cacher(function (colour) {\n if (!colour || !!((colour = Str(colour)).indexOf(\"-\") + 1)) {\n return {r: -1, g: -1, b: -1, hex: \"none\", error: 1, toString: clrToString};\n }\n if (colour == \"none\") {\n return {r: -1, g: -1, b: -1, hex: \"none\", toString: clrToString};\n }\n !(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == \"#\") && (colour = toHex(colour));\n var res,\n red,\n green,\n blue,\n opacity,\n t,\n values,\n rgb = colour.match(colourRegExp);\n if (rgb) {\n if (rgb[2]) {\n blue = toInt(rgb[2].substring(5), 16);\n green = toInt(rgb[2].substring(3, 5), 16);\n red = toInt(rgb[2].substring(1, 3), 16);\n }\n if (rgb[3]) {\n blue = toInt((t = rgb[3].charAt(3)) + t, 16);\n green = toInt((t = rgb[3].charAt(2)) + t, 16);\n red = toInt((t = rgb[3].charAt(1)) + t, 16);\n }\n if (rgb[4]) {\n values = rgb[4][split](commaSpaces);\n red = toFloat(values[0]);\n values[0].slice(-1) == \"%\" && (red *= 2.55);\n green = toFloat(values[1]);\n values[1].slice(-1) == \"%\" && (green *= 2.55);\n blue = toFloat(values[2]);\n values[2].slice(-1) == \"%\" && (blue *= 2.55);\n rgb[1].toLowerCase().slice(0, 4) == \"rgba\" && (opacity = toFloat(values[3]));\n values[3] && values[3].slice(-1) == \"%\" && (opacity /= 100);\n }\n if (rgb[5]) {\n values = rgb[5][split](commaSpaces);\n red = toFloat(values[0]);\n values[0].slice(-1) == \"%\" && (red *= 2.55);\n green = toFloat(values[1]);\n values[1].slice(-1) == \"%\" && (green *= 2.55);\n blue = toFloat(values[2]);\n values[2].slice(-1) == \"%\" && (blue *= 2.55);\n (values[0].slice(-3) == \"deg\" || values[0].slice(-1) == \"\\xb0\") && (red /= 360);\n rgb[1].toLowerCase().slice(0, 4) == \"hsba\" && (opacity = toFloat(values[3]));\n values[3] && values[3].slice(-1) == \"%\" && (opacity /= 100);\n return R.hsb2rgb(red, green, blue, opacity);\n }\n if (rgb[6]) {\n values = rgb[6][split](commaSpaces);\n red = toFloat(values[0]);\n values[0].slice(-1) == \"%\" && (red *= 2.55);\n green = toFloat(values[1]);\n values[1].slice(-1) == \"%\" && (green *= 2.55);\n blue = toFloat(values[2]);\n values[2].slice(-1) == \"%\" && (blue *= 2.55);\n (values[0].slice(-3) == \"deg\" || values[0].slice(-1) == \"\\xb0\") && (red /= 360);\n rgb[1].toLowerCase().slice(0, 4) == \"hsla\" && (opacity = toFloat(values[3]));\n values[3] && values[3].slice(-1) == \"%\" && (opacity /= 100);\n return R.hsl2rgb(red, green, blue, opacity);\n }\n rgb = {r: red, g: green, b: blue, toString: clrToString};\n rgb.hex = \"#\" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1);\n R.is(opacity, \"finite\") && (rgb.opacity = opacity);\n return rgb;\n }\n return {r: -1, g: -1, b: -1, hex: \"none\", error: 1, toString: clrToString};\n }, R);\n /*\\\n * Raphael.hsb\n [ method ]\n **\n * Converts HSB values to hex representation of the colour.\n > Parameters\n - h (number) hue\n - s (number) saturation\n - b (number) value or brightness\n = (string) hex representation of the colour.\n \\*/\n R.hsb = cacher(function (h, s, b) {\n return R.hsb2rgb(h, s, b).hex;\n });\n /*\\\n * Raphael.hsl\n [ method ]\n **\n * Converts HSL values to hex representation of the colour.\n > Parameters\n - h (number) hue\n - s (number) saturation\n - l (number) luminosity\n = (string) hex representation of the colour.\n \\*/\n R.hsl = cacher(function (h, s, l) {\n return R.hsl2rgb(h, s, l).hex;\n });\n /*\\\n * Raphael.rgb\n [ method ]\n **\n * Converts RGB values to hex representation of the colour.\n > Parameters\n - r (number) red\n - g (number) green\n - b (number) blue\n = (string) hex representation of the colour.\n \\*/\n R.rgb = cacher(function (r, g, b) {\n function round(x) { return (x + 0.5) | 0; }\n return \"#\" + (16777216 | round(b) | (round(g) << 8) | (round(r) << 16)).toString(16).slice(1);\n });\n /*\\\n * Raphael.getColor\n [ method ]\n **\n * On each call returns next colour in the spectrum. To reset it back to red call @Raphael.getColor.reset\n > Parameters\n - value (number) #optional brightness, default is `0.75`\n = (string) hex representation of the colour.\n \\*/\n R.getColor = function (value) {\n var start = this.getColor.start = this.getColor.start || {h: 0, s: 1, b: value || .75},\n rgb = this.hsb2rgb(start.h, start.s, start.b);\n start.h += .075;\n if (start.h > 1) {\n start.h = 0;\n start.s -= .2;\n start.s <= 0 && (this.getColor.start = {h: 0, s: 1, b: start.b});\n }\n return rgb.hex;\n };\n /*\\\n * Raphael.getColor.reset\n [ method ]\n **\n * Resets spectrum position for @Raphael.getColor back to red.\n \\*/\n R.getColor.reset = function () {\n delete this.start;\n };\n\n // http://schepers.cc/getting-to-the-point\n function catmullRom2bezier(crp, z) {\n var d = [];\n for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) {\n var p = [\n {x: +crp[i - 2], y: +crp[i - 1]},\n {x: +crp[i], y: +crp[i + 1]},\n {x: +crp[i + 2], y: +crp[i + 3]},\n {x: +crp[i + 4], y: +crp[i + 5]}\n ];\n if (z) {\n if (!i) {\n p[0] = {x: +crp[iLen - 2], y: +crp[iLen - 1]};\n } else if (iLen - 4 == i) {\n p[3] = {x: +crp[0], y: +crp[1]};\n } else if (iLen - 2 == i) {\n p[2] = {x: +crp[0], y: +crp[1]};\n p[3] = {x: +crp[2], y: +crp[3]};\n }\n } else {\n if (iLen - 4 == i) {\n p[3] = p[2];\n } else if (!i) {\n p[0] = {x: +crp[i], y: +crp[i + 1]};\n }\n }\n d.push([\"C\",\n (-p[0].x + 6 * p[1].x + p[2].x) / 6,\n (-p[0].y + 6 * p[1].y + p[2].y) / 6,\n (p[1].x + 6 * p[2].x - p[3].x) / 6,\n (p[1].y + 6*p[2].y - p[3].y) / 6,\n p[2].x,\n p[2].y\n ]);\n }\n\n return d;\n }\n /*\\\n * Raphael.parsePathString\n [ method ]\n **\n * Utility method\n **\n * Parses given path string into an array of arrays of path segments.\n > Parameters\n - pathString (string|array) path string or array of segments (in the last case it will be returned straight away)\n = (array) array of segments.\n \\*/\n R.parsePathString = function (pathString) {\n if (!pathString) {\n return null;\n }\n var pth = paths(pathString);\n if (pth.arr) {\n return pathClone(pth.arr);\n }\n\n var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0},\n data = [];\n if (R.is(pathString, array) && R.is(pathString[0], array)) { // rough assumption\n data = pathClone(pathString);\n }\n if (!data.length) {\n Str(pathString).replace(pathCommand, function (a, b, c) {\n var params = [],\n name = b.toLowerCase();\n c.replace(pathValues, function (a, b) {\n b && params.push(+b);\n });\n if (name == \"m\" && params.length > 2) {\n data.push([b][concat](params.splice(0, 2)));\n name = \"l\";\n b = b == \"m\" ? \"l\" : \"L\";\n }\n if (name == \"r\") {\n data.push([b][concat](params));\n } else while (params.length >= paramCounts[name]) {\n data.push([b][concat](params.splice(0, paramCounts[name])));\n if (!paramCounts[name]) {\n break;\n }\n }\n });\n }\n data.toString = R._path2string;\n pth.arr = pathClone(data);\n return data;\n };\n /*\\\n * Raphael.parseTransformString\n [ method ]\n **\n * Utility method\n **\n * Parses given path string into an array of transformations.\n > Parameters\n - TString (string|array) transform string or array of transformations (in the last case it will be returned straight away)\n = (array) array of transformations.\n \\*/\n R.parseTransformString = cacher(function (TString) {\n if (!TString) {\n return null;\n }\n var paramCounts = {r: 3, s: 4, t: 2, m: 6},\n data = [];\n if (R.is(TString, array) && R.is(TString[0], array)) { // rough assumption\n data = pathClone(TString);\n }\n if (!data.length) {\n Str(TString).replace(tCommand, function (a, b, c) {\n var params = [],\n name = lowerCase.call(b);\n c.replace(pathValues, function (a, b) {\n b && params.push(+b);\n });\n data.push([b][concat](params));\n });\n }\n data.toString = R._path2string;\n return data;\n });\n // PATHS\n var paths = function (ps) {\n var p = paths.ps = paths.ps || {};\n if (p[ps]) {\n p[ps].sleep = 100;\n } else {\n p[ps] = {\n sleep: 100\n };\n }\n setTimeout(function () {\n for (var key in p) if (p[has](key) && key != ps) {\n p[key].sleep--;\n !p[key].sleep && delete p[key];\n }\n });\n return p[ps];\n };\n /*\\\n * Raphael.findDotsAtSegment\n [ method ]\n **\n * Utility method\n **\n * Find dot coordinates on the given cubic bezier curve at the given t.\n > Parameters\n - p1x (number) x of the first point of the curve\n - p1y (number) y of the first point of the curve\n - c1x (number) x of the first anchor of the curve\n - c1y (number) y of the first anchor of the curve\n - c2x (number) x of the second anchor of the curve\n - c2y (number) y of the second anchor of the curve\n - p2x (number) x of the second point of the curve\n - p2y (number) y of the second point of the curve\n - t (number) position on the curve (0..1)\n = (object) point information in format:\n o {\n o x: (number) x coordinate of the point\n o y: (number) y coordinate of the point\n o m: {\n o x: (number) x coordinate of the left anchor\n o y: (number) y coordinate of the left anchor\n o }\n o n: {\n o x: (number) x coordinate of the right anchor\n o y: (number) y coordinate of the right anchor\n o }\n o start: {\n o x: (number) x coordinate of the start of the curve\n o y: (number) y coordinate of the start of the curve\n o }\n o end: {\n o x: (number) x coordinate of the end of the curve\n o y: (number) y coordinate of the end of the curve\n o }\n o alpha: (number) angle of the curve derivative at the point\n o }\n \\*/\n R.findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {\n var t1 = 1 - t,\n t13 = pow(t1, 3),\n t12 = pow(t1, 2),\n t2 = t * t,\n t3 = t2 * t,\n x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x,\n y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y,\n mx = p1x + 2 * t * (c1x - p1x) + t2 * (c2x - 2 * c1x + p1x),\n my = p1y + 2 * t * (c1y - p1y) + t2 * (c2y - 2 * c1y + p1y),\n nx = c1x + 2 * t * (c2x - c1x) + t2 * (p2x - 2 * c2x + c1x),\n ny = c1y + 2 * t * (c2y - c1y) + t2 * (p2y - 2 * c2y + c1y),\n ax = t1 * p1x + t * c1x,\n ay = t1 * p1y + t * c1y,\n cx = t1 * c2x + t * p2x,\n cy = t1 * c2y + t * p2y,\n alpha = (90 - math.atan2(mx - nx, my - ny) * 180 / PI);\n (mx > nx || my < ny) && (alpha += 180);\n return {\n x: x,\n y: y,\n m: {x: mx, y: my},\n n: {x: nx, y: ny},\n start: {x: ax, y: ay},\n end: {x: cx, y: cy},\n alpha: alpha\n };\n };\n /*\\\n * Raphael.bezierBBox\n [ method ]\n **\n * Utility method\n **\n * Return bounding box of a given cubic bezier curve\n > Parameters\n - p1x (number) x of the first point of the curve\n - p1y (number) y of the first point of the curve\n - c1x (number) x of the first anchor of the curve\n - c1y (number) y of the first anchor of the curve\n - c2x (number) x of the second anchor of the curve\n - c2y (number) y of the second anchor of the curve\n - p2x (number) x of the second point of the curve\n - p2y (number) y of the second point of the curve\n * or\n - bez (array) array of six points for bezier curve\n = (object) point information in format:\n o {\n o min: {\n o x: (number) x coordinate of the left point\n o y: (number) y coordinate of the top point\n o }\n o max: {\n o x: (number) x coordinate of the right point\n o y: (number) y coordinate of the bottom point\n o }\n o }\n \\*/\n R.bezierBBox = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {\n if (!R.is(p1x, \"array\")) {\n p1x = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y];\n }\n var bbox = curveDim.apply(null, p1x);\n return {\n x: bbox.min.x,\n y: bbox.min.y,\n x2: bbox.max.x,\n y2: bbox.max.y,\n width: bbox.max.x - bbox.min.x,\n height: bbox.max.y - bbox.min.y\n };\n };\n /*\\\n * Raphael.isPointInsideBBox\n [ method ]\n **\n * Utility method\n **\n * Returns `true` if given point is inside bounding boxes.\n > Parameters\n - bbox (string) bounding box\n - x (string) x coordinate of the point\n - y (string) y coordinate of the point\n = (boolean) `true` if point inside\n \\*/\n R.isPointInsideBBox = function (bbox, x, y) {\n return x >= bbox.x && x <= bbox.x2 && y >= bbox.y && y <= bbox.y2;\n };\n /*\\\n * Raphael.isBBoxIntersect\n [ method ]\n **\n * Utility method\n **\n * Returns `true` if two bounding boxes intersect\n > Parameters\n - bbox1 (string) first bounding box\n - bbox2 (string) second bounding box\n = (boolean) `true` if they intersect\n \\*/\n R.isBBoxIntersect = function (bbox1, bbox2) {\n var i = R.isPointInsideBBox;\n return i(bbox2, bbox1.x, bbox1.y)\n || i(bbox2, bbox1.x2, bbox1.y)\n || i(bbox2, bbox1.x, bbox1.y2)\n || i(bbox2, bbox1.x2, bbox1.y2)\n || i(bbox1, bbox2.x, bbox2.y)\n || i(bbox1, bbox2.x2, bbox2.y)\n || i(bbox1, bbox2.x, bbox2.y2)\n || i(bbox1, bbox2.x2, bbox2.y2)\n || (bbox1.x < bbox2.x2 && bbox1.x > bbox2.x || bbox2.x < bbox1.x2 && bbox2.x > bbox1.x)\n && (bbox1.y < bbox2.y2 && bbox1.y > bbox2.y || bbox2.y < bbox1.y2 && bbox2.y > bbox1.y);\n };\n function base3(t, p1, p2, p3, p4) {\n var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4,\n t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3;\n return t * t2 - 3 * p1 + 3 * p2;\n }\n function bezlen(x1, y1, x2, y2, x3, y3, x4, y4, z) {\n if (z == null) {\n z = 1;\n }\n z = z > 1 ? 1 : z < 0 ? 0 : z;\n var z2 = z / 2,\n n = 12,\n Tvalues = [-0.1252,0.1252,-0.3678,0.3678,-0.5873,0.5873,-0.7699,0.7699,-0.9041,0.9041,-0.9816,0.9816],\n Cvalues = [0.2491,0.2491,0.2335,0.2335,0.2032,0.2032,0.1601,0.1601,0.1069,0.1069,0.0472,0.0472],\n sum = 0;\n for (var i = 0; i < n; i++) {\n var ct = z2 * Tvalues[i] + z2,\n xbase = base3(ct, x1, x2, x3, x4),\n ybase = base3(ct, y1, y2, y3, y4),\n comb = xbase * xbase + ybase * ybase;\n sum += Cvalues[i] * math.sqrt(comb);\n }\n return z2 * sum;\n }\n function getTatLen(x1, y1, x2, y2, x3, y3, x4, y4, ll) {\n if (ll < 0 || bezlen(x1, y1, x2, y2, x3, y3, x4, y4) < ll) {\n return;\n }\n var t = 1,\n step = t / 2,\n t2 = t - step,\n l,\n e = .01;\n l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2);\n while (abs(l - ll) > e) {\n step /= 2;\n t2 += (l < ll ? 1 : -1) * step;\n l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2);\n }\n return t2;\n }\n function intersect(x1, y1, x2, y2, x3, y3, x4, y4) {\n if (\n mmax(x1, x2) < mmin(x3, x4) ||\n mmin(x1, x2) > mmax(x3, x4) ||\n mmax(y1, y2) < mmin(y3, y4) ||\n mmin(y1, y2) > mmax(y3, y4)\n ) {\n return;\n }\n var nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4),\n ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4),\n denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);\n\n if (!denominator) {\n return;\n }\n var px = nx / denominator,\n py = ny / denominator,\n px2 = +px.toFixed(2),\n py2 = +py.toFixed(2);\n if (\n px2 < +mmin(x1, x2).toFixed(2) ||\n px2 > +mmax(x1, x2).toFixed(2) ||\n px2 < +mmin(x3, x4).toFixed(2) ||\n px2 > +mmax(x3, x4).toFixed(2) ||\n py2 < +mmin(y1, y2).toFixed(2) ||\n py2 > +mmax(y1, y2).toFixed(2) ||\n py2 < +mmin(y3, y4).toFixed(2) ||\n py2 > +mmax(y3, y4).toFixed(2)\n ) {\n return;\n }\n return {x: px, y: py};\n }\n function inter(bez1, bez2) {\n return interHelper(bez1, bez2);\n }\n function interCount(bez1, bez2) {\n return interHelper(bez1, bez2, 1);\n }\n function interHelper(bez1, bez2, justCount) {\n var bbox1 = R.bezierBBox(bez1),\n bbox2 = R.bezierBBox(bez2);\n if (!R.isBBoxIntersect(bbox1, bbox2)) {\n return justCount ? 0 : [];\n }\n var l1 = bezlen.apply(0, bez1),\n l2 = bezlen.apply(0, bez2),\n n1 = mmax(~~(l1 / 5), 1),\n n2 = mmax(~~(l2 / 5), 1),\n dots1 = [],\n dots2 = [],\n xy = {},\n res = justCount ? 0 : [];\n for (var i = 0; i < n1 + 1; i++) {\n var p = R.findDotsAtSegment.apply(R, bez1.concat(i / n1));\n dots1.push({x: p.x, y: p.y, t: i / n1});\n }\n for (i = 0; i < n2 + 1; i++) {\n p = R.findDotsAtSegment.apply(R, bez2.concat(i / n2));\n dots2.push({x: p.x, y: p.y, t: i / n2});\n }\n for (i = 0; i < n1; i++) {\n for (var j = 0; j < n2; j++) {\n var di = dots1[i],\n di1 = dots1[i + 1],\n dj = dots2[j],\n dj1 = dots2[j + 1],\n ci = abs(di1.x - di.x) < .001 ? \"y\" : \"x\",\n cj = abs(dj1.x - dj.x) < .001 ? \"y\" : \"x\",\n is = intersect(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y);\n if (is) {\n if (xy[is.x.toFixed(4)] == is.y.toFixed(4)) {\n continue;\n }\n xy[is.x.toFixed(4)] = is.y.toFixed(4);\n var t1 = di.t + abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t),\n t2 = dj.t + abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t);\n if (t1 >= 0 && t1 <= 1.001 && t2 >= 0 && t2 <= 1.001) {\n if (justCount) {\n res++;\n } else {\n res.push({\n x: is.x,\n y: is.y,\n t1: mmin(t1, 1),\n t2: mmin(t2, 1)\n });\n }\n }\n }\n }\n }\n return res;\n }\n /*\\\n * Raphael.pathIntersection\n [ method ]\n **\n * Utility method\n **\n * Finds intersections of two paths\n > Parameters\n - path1 (string) path string\n - path2 (string) path string\n = (array) dots of intersection\n o [\n o {\n o x: (number) x coordinate of the point\n o y: (number) y coordinate of the point\n o t1: (number) t value for segment of path1\n o t2: (number) t value for segment of path2\n o segment1: (number) order number for segment of path1\n o segment2: (number) order number for segment of path2\n o bez1: (array) eight coordinates representing beziér curve for the segment of path1\n o bez2: (array) eight coordinates representing beziér curve for the segment of path2\n o }\n o ]\n \\*/\n R.pathIntersection = function (path1, path2) {\n return interPathHelper(path1, path2);\n };\n R.pathIntersectionNumber = function (path1, path2) {\n return interPathHelper(path1, path2, 1);\n };\n function interPathHelper(path1, path2, justCount) {\n path1 = R._path2curve(path1);\n path2 = R._path2curve(path2);\n var x1, y1, x2, y2, x1m, y1m, x2m, y2m, bez1, bez2,\n res = justCount ? 0 : [];\n for (var i = 0, ii = path1.length; i < ii; i++) {\n var pi = path1[i];\n if (pi[0] == \"M\") {\n x1 = x1m = pi[1];\n y1 = y1m = pi[2];\n } else {\n if (pi[0] == \"C\") {\n bez1 = [x1, y1].concat(pi.slice(1));\n x1 = bez1[6];\n y1 = bez1[7];\n } else {\n bez1 = [x1, y1, x1, y1, x1m, y1m, x1m, y1m];\n x1 = x1m;\n y1 = y1m;\n }\n for (var j = 0, jj = path2.length; j < jj; j++) {\n var pj = path2[j];\n if (pj[0] == \"M\") {\n x2 = x2m = pj[1];\n y2 = y2m = pj[2];\n } else {\n if (pj[0] == \"C\") {\n bez2 = [x2, y2].concat(pj.slice(1));\n x2 = bez2[6];\n y2 = bez2[7];\n } else {\n bez2 = [x2, y2, x2, y2, x2m, y2m, x2m, y2m];\n x2 = x2m;\n y2 = y2m;\n }\n var intr = interHelper(bez1, bez2, justCount);\n if (justCount) {\n res += intr;\n } else {\n for (var k = 0, kk = intr.length; k < kk; k++) {\n intr[k].segment1 = i;\n intr[k].segment2 = j;\n intr[k].bez1 = bez1;\n intr[k].bez2 = bez2;\n }\n res = res.concat(intr);\n }\n }\n }\n }\n }\n return res;\n }\n /*\\\n * Raphael.isPointInsidePath\n [ method ]\n **\n * Utility method\n **\n * Returns `true` if given point is inside a given closed path.\n > Parameters\n - path (string) path string\n - x (number) x of the point\n - y (number) y of the point\n = (boolean) true, if point is inside the path\n \\*/\n R.isPointInsidePath = function (path, x, y) {\n var bbox = R.pathBBox(path);\n return R.isPointInsideBBox(bbox, x, y) &&\n interPathHelper(path, [[\"M\", x, y], [\"H\", bbox.x2 + 10]], 1) % 2 == 1;\n };\n R._removedFactory = function (methodname) {\n return function () {\n eve(\"raphael.log\", null, \"Rapha\\xebl: you are calling to method \\u201c\" + methodname + \"\\u201d of removed object\", methodname);\n };\n };\n /*\\\n * Raphael.pathBBox\n [ method ]\n **\n * Utility method\n **\n * Return bounding box of a given path\n > Parameters\n - path (string) path string\n = (object) bounding box\n o {\n o x: (number) x coordinate of the left top point of the box\n o y: (number) y coordinate of the left top point of the box\n o x2: (number) x coordinate of the right bottom point of the box\n o y2: (number) y coordinate of the right bottom point of the box\n o width: (number) width of the box\n o height: (number) height of the box\n o cx: (number) x coordinate of the center of the box\n o cy: (number) y coordinate of the center of the box\n o }\n \\*/\n var pathDimensions = R.pathBBox = function (path) {\n var pth = paths(path);\n if (pth.bbox) {\n return clone(pth.bbox);\n }\n if (!path) {\n return {x: 0, y: 0, width: 0, height: 0, x2: 0, y2: 0};\n }\n path = path2curve(path);\n var x = 0,\n y = 0,\n X = [],\n Y = [],\n p;\n for (var i = 0, ii = path.length; i < ii; i++) {\n p = path[i];\n if (p[0] == \"M\") {\n x = p[1];\n y = p[2];\n X.push(x);\n Y.push(y);\n } else {\n var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);\n X = X[concat](dim.min.x, dim.max.x);\n Y = Y[concat](dim.min.y, dim.max.y);\n x = p[5];\n y = p[6];\n }\n }\n var xmin = mmin[apply](0, X),\n ymin = mmin[apply](0, Y),\n xmax = mmax[apply](0, X),\n ymax = mmax[apply](0, Y),\n width = xmax - xmin,\n height = ymax - ymin,\n bb = {\n x: xmin,\n y: ymin,\n x2: xmax,\n y2: ymax,\n width: width,\n height: height,\n cx: xmin + width / 2,\n cy: ymin + height / 2\n };\n pth.bbox = clone(bb);\n return bb;\n },\n pathClone = function (pathArray) {\n var res = clone(pathArray);\n res.toString = R._path2string;\n return res;\n },\n pathToRelative = R._pathToRelative = function (pathArray) {\n var pth = paths(pathArray);\n if (pth.rel) {\n return pathClone(pth.rel);\n }\n if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption\n pathArray = R.parsePathString(pathArray);\n }\n var res = [],\n x = 0,\n y = 0,\n mx = 0,\n my = 0,\n start = 0;\n if (pathArray[0][0] == \"M\") {\n x = pathArray[0][1];\n y = pathArray[0][2];\n mx = x;\n my = y;\n start++;\n res.push([\"M\", x, y]);\n }\n for (var i = start, ii = pathArray.length; i < ii; i++) {\n var r = res[i] = [],\n pa = pathArray[i];\n if (pa[0] != lowerCase.call(pa[0])) {\n r[0] = lowerCase.call(pa[0]);\n switch (r[0]) {\n case \"a\":\n r[1] = pa[1];\n r[2] = pa[2];\n r[3] = pa[3];\n r[4] = pa[4];\n r[5] = pa[5];\n r[6] = +(pa[6] - x).toFixed(3);\n r[7] = +(pa[7] - y).toFixed(3);\n break;\n case \"v\":\n r[1] = +(pa[1] - y).toFixed(3);\n break;\n case \"m\":\n mx = pa[1];\n my = pa[2];\n default:\n for (var j = 1, jj = pa.length; j < jj; j++) {\n r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3);\n }\n }\n } else {\n r = res[i] = [];\n if (pa[0] == \"m\") {\n mx = pa[1] + x;\n my = pa[2] + y;\n }\n for (var k = 0, kk = pa.length; k < kk; k++) {\n res[i][k] = pa[k];\n }\n }\n var len = res[i].length;\n switch (res[i][0]) {\n case \"z\":\n x = mx;\n y = my;\n break;\n case \"h\":\n x += +res[i][len - 1];\n break;\n case \"v\":\n y += +res[i][len - 1];\n break;\n default:\n x += +res[i][len - 2];\n y += +res[i][len - 1];\n }\n }\n res.toString = R._path2string;\n pth.rel = pathClone(res);\n return res;\n },\n pathToAbsolute = R._pathToAbsolute = function (pathArray) {\n var pth = paths(pathArray);\n if (pth.abs) {\n return pathClone(pth.abs);\n }\n if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption\n pathArray = R.parsePathString(pathArray);\n }\n if (!pathArray || !pathArray.length) {\n return [[\"M\", 0, 0]];\n }\n var res = [],\n x = 0,\n y = 0,\n mx = 0,\n my = 0,\n start = 0;\n if (pathArray[0][0] == \"M\") {\n x = +pathArray[0][1];\n y = +pathArray[0][2];\n mx = x;\n my = y;\n start++;\n res[0] = [\"M\", x, y];\n }\n var crz = pathArray.length == 3 && pathArray[0][0] == \"M\" && pathArray[1][0].toUpperCase() == \"R\" && pathArray[2][0].toUpperCase() == \"Z\";\n for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) {\n res.push(r = []);\n pa = pathArray[i];\n if (pa[0] != upperCase.call(pa[0])) {\n r[0] = upperCase.call(pa[0]);\n switch (r[0]) {\n case \"A\":\n r[1] = pa[1];\n r[2] = pa[2];\n r[3] = pa[3];\n r[4] = pa[4];\n r[5] = pa[5];\n r[6] = +(pa[6] + x);\n r[7] = +(pa[7] + y);\n break;\n case \"V\":\n r[1] = +pa[1] + y;\n break;\n case \"H\":\n r[1] = +pa[1] + x;\n break;\n case \"R\":\n var dots = [x, y][concat](pa.slice(1));\n for (var j = 2, jj = dots.length; j < jj; j++) {\n dots[j] = +dots[j] + x;\n dots[++j] = +dots[j] + y;\n }\n res.pop();\n res = res[concat](catmullRom2bezier(dots, crz));\n break;\n case \"M\":\n mx = +pa[1] + x;\n my = +pa[2] + y;\n default:\n for (j = 1, jj = pa.length; j < jj; j++) {\n r[j] = +pa[j] + ((j % 2) ? x : y);\n }\n }\n } else if (pa[0] == \"R\") {\n dots = [x, y][concat](pa.slice(1));\n res.pop();\n res = res[concat](catmullRom2bezier(dots, crz));\n r = [\"R\"][concat](pa.slice(-2));\n } else {\n for (var k = 0, kk = pa.length; k < kk; k++) {\n r[k] = pa[k];\n }\n }\n switch (r[0]) {\n case \"Z\":\n x = mx;\n y = my;\n break;\n case \"H\":\n x = r[1];\n break;\n case \"V\":\n y = r[1];\n break;\n case \"M\":\n mx = r[r.length - 2];\n my = r[r.length - 1];\n default:\n x = r[r.length - 2];\n y = r[r.length - 1];\n }\n }\n res.toString = R._path2string;\n pth.abs = pathClone(res);\n return res;\n },\n l2c = function (x1, y1, x2, y2) {\n return [x1, y1, x2, y2, x2, y2];\n },\n q2c = function (x1, y1, ax, ay, x2, y2) {\n var _13 = 1 / 3,\n _23 = 2 / 3;\n return [\n _13 * x1 + _23 * ax,\n _13 * y1 + _23 * ay,\n _13 * x2 + _23 * ax,\n _13 * y2 + _23 * ay,\n x2,\n y2\n ];\n },\n a2c = function (x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {\n // for more information of where this math came from visit:\n // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes\n var _120 = PI * 120 / 180,\n rad = PI / 180 * (+angle || 0),\n res = [],\n xy,\n rotate = cacher(function (x, y, rad) {\n var X = x * math.cos(rad) - y * math.sin(rad),\n Y = x * math.sin(rad) + y * math.cos(rad);\n return {x: X, y: Y};\n });\n if (!recursive) {\n xy = rotate(x1, y1, -rad);\n x1 = xy.x;\n y1 = xy.y;\n xy = rotate(x2, y2, -rad);\n x2 = xy.x;\n y2 = xy.y;\n var cos = math.cos(PI / 180 * angle),\n sin = math.sin(PI / 180 * angle),\n x = (x1 - x2) / 2,\n y = (y1 - y2) / 2;\n var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);\n if (h > 1) {\n h = math.sqrt(h);\n rx = h * rx;\n ry = h * ry;\n }\n var rx2 = rx * rx,\n ry2 = ry * ry,\n k = (large_arc_flag == sweep_flag ? -1 : 1) *\n math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),\n cx = k * rx * y / ry + (x1 + x2) / 2,\n cy = k * -ry * x / rx + (y1 + y2) / 2,\n f1 = math.asin(((y1 - cy) / ry).toFixed(9)),\n f2 = math.asin(((y2 - cy) / ry).toFixed(9));\n\n f1 = x1 < cx ? PI - f1 : f1;\n f2 = x2 < cx ? PI - f2 : f2;\n f1 < 0 && (f1 = PI * 2 + f1);\n f2 < 0 && (f2 = PI * 2 + f2);\n if (sweep_flag && f1 > f2) {\n f1 = f1 - PI * 2;\n }\n if (!sweep_flag && f2 > f1) {\n f2 = f2 - PI * 2;\n }\n } else {\n f1 = recursive[0];\n f2 = recursive[1];\n cx = recursive[2];\n cy = recursive[3];\n }\n var df = f2 - f1;\n if (abs(df) > _120) {\n var f2old = f2,\n x2old = x2,\n y2old = y2;\n f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);\n x2 = cx + rx * math.cos(f2);\n y2 = cy + ry * math.sin(f2);\n res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);\n }\n df = f2 - f1;\n var c1 = math.cos(f1),\n s1 = math.sin(f1),\n c2 = math.cos(f2),\n s2 = math.sin(f2),\n t = math.tan(df / 4),\n hx = 4 / 3 * rx * t,\n hy = 4 / 3 * ry * t,\n m1 = [x1, y1],\n m2 = [x1 + hx * s1, y1 - hy * c1],\n m3 = [x2 + hx * s2, y2 - hy * c2],\n m4 = [x2, y2];\n m2[0] = 2 * m1[0] - m2[0];\n m2[1] = 2 * m1[1] - m2[1];\n if (recursive) {\n return [m2, m3, m4][concat](res);\n } else {\n res = [m2, m3, m4][concat](res).join()[split](\",\");\n var newres = [];\n for (var i = 0, ii = res.length; i < ii; i++) {\n newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;\n }\n return newres;\n }\n },\n findDotAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) {\n var t1 = 1 - t;\n return {\n x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x,\n y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y\n };\n },\n curveDim = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {\n var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x),\n b = 2 * (c1x - p1x) - 2 * (c2x - c1x),\n c = p1x - c1x,\n t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a,\n t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a,\n y = [p1y, p2y],\n x = [p1x, p2x],\n dot;\n abs(t1) > \"1e12\" && (t1 = .5);\n abs(t2) > \"1e12\" && (t2 = .5);\n if (t1 > 0 && t1 < 1) {\n dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);\n x.push(dot.x);\n y.push(dot.y);\n }\n if (t2 > 0 && t2 < 1) {\n dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);\n x.push(dot.x);\n y.push(dot.y);\n }\n a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y);\n b = 2 * (c1y - p1y) - 2 * (c2y - c1y);\n c = p1y - c1y;\n t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a;\n t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a;\n abs(t1) > \"1e12\" && (t1 = .5);\n abs(t2) > \"1e12\" && (t2 = .5);\n if (t1 > 0 && t1 < 1) {\n dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1);\n x.push(dot.x);\n y.push(dot.y);\n }\n if (t2 > 0 && t2 < 1) {\n dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2);\n x.push(dot.x);\n y.push(dot.y);\n }\n return {\n min: {x: mmin[apply](0, x), y: mmin[apply](0, y)},\n max: {x: mmax[apply](0, x), y: mmax[apply](0, y)}\n };\n }),\n path2curve = R._path2curve = cacher(function (path, path2) {\n var pth = !path2 && paths(path);\n if (!path2 && pth.curve) {\n return pathClone(pth.curve);\n }\n var p = pathToAbsolute(path),\n p2 = path2 && pathToAbsolute(path2),\n attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},\n attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null},\n processPath = function (path, d, pcom) {\n var nx, ny, tq = {T:1, Q:1};\n if (!path) {\n return [\"C\", d.x, d.y, d.x, d.y, d.x, d.y];\n }\n !(path[0] in tq) && (d.qx = d.qy = null);\n switch (path[0]) {\n case \"M\":\n d.X = path[1];\n d.Y = path[2];\n break;\n case \"A\":\n path = [\"C\"][concat](a2c[apply](0, [d.x, d.y][concat](path.slice(1))));\n break;\n case \"S\":\n if (pcom == \"C\" || pcom == \"S\") { // In \"S\" case we have to take into account, if the previous command is C/S.\n nx = d.x * 2 - d.bx; // And reflect the previous\n ny = d.y * 2 - d.by; // command's control point relative to the current point.\n }\n else { // or some else or nothing\n nx = d.x;\n ny = d.y;\n }\n path = [\"C\", nx, ny][concat](path.slice(1));\n break;\n case \"T\":\n if (pcom == \"Q\" || pcom == \"T\") { // In \"T\" case we have to take into account, if the previous command is Q/T.\n d.qx = d.x * 2 - d.qx; // And make a reflection similar\n d.qy = d.y * 2 - d.qy; // to case \"S\".\n }\n else { // or something else or nothing\n d.qx = d.x;\n d.qy = d.y;\n }\n path = [\"C\"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2]));\n break;\n case \"Q\":\n d.qx = path[1];\n d.qy = path[2];\n path = [\"C\"][concat](q2c(d.x, d.y, path[1], path[2], path[3], path[4]));\n break;\n case \"L\":\n path = [\"C\"][concat](l2c(d.x, d.y, path[1], path[2]));\n break;\n case \"H\":\n path = [\"C\"][concat](l2c(d.x, d.y, path[1], d.y));\n break;\n case \"V\":\n path = [\"C\"][concat](l2c(d.x, d.y, d.x, path[1]));\n break;\n case \"Z\":\n path = [\"C\"][concat](l2c(d.x, d.y, d.X, d.Y));\n break;\n }\n return path;\n },\n fixArc = function (pp, i) {\n if (pp[i].length > 7) {\n pp[i].shift();\n var pi = pp[i];\n while (pi.length) {\n pcoms1[i]=\"A\"; // if created multiple C:s, their original seg is saved\n p2 && (pcoms2[i]=\"A\"); // the same as above\n pp.splice(i++, 0, [\"C\"][concat](pi.splice(0, 6)));\n }\n pp.splice(i, 1);\n ii = mmax(p.length, p2 && p2.length || 0);\n }\n },\n fixM = function (path1, path2, a1, a2, i) {\n if (path1 && path2 && path1[i][0] == \"M\" && path2[i][0] != \"M\") {\n path2.splice(i, 0, [\"M\", a2.x, a2.y]);\n a1.bx = 0;\n a1.by = 0;\n a1.x = path1[i][1];\n a1.y = path1[i][2];\n ii = mmax(p.length, p2 && p2.length || 0);\n }\n },\n pcoms1 = [], // path commands of original path p\n pcoms2 = [], // path commands of original path p2\n pfirst = \"\", // temporary holder for original path command\n pcom = \"\"; // holder for previous path command of original path\n for (var i = 0, ii = mmax(p.length, p2 && p2.length || 0); i < ii; i++) {\n p[i] && (pfirst = p[i][0]); // save current path command\n\n if (pfirst != \"C\") // C is not saved yet, because it may be result of conversion\n {\n pcoms1[i] = pfirst; // Save current path command\n i && ( pcom = pcoms1[i-1]); // Get previous path command pcom\n }\n p[i] = processPath(p[i], attrs, pcom); // Previous path command is inputted to processPath\n\n if (pcoms1[i] != \"A\" && pfirst == \"C\") pcoms1[i] = \"C\"; // A is the only command\n // which may produce multiple C:s\n // so we have to make sure that C is also C in original path\n\n fixArc(p, i); // fixArc adds also the right amount of A:s to pcoms1\n\n if (p2) { // the same procedures is done to p2\n p2[i] && (pfirst = p2[i][0]);\n if (pfirst != \"C\")\n {\n pcoms2[i] = pfirst;\n i && (pcom = pcoms2[i-1]);\n }\n p2[i] = processPath(p2[i], attrs2, pcom);\n\n if (pcoms2[i]!=\"A\" && pfirst==\"C\") pcoms2[i]=\"C\";\n\n fixArc(p2, i);\n }\n fixM(p, p2, attrs, attrs2, i);\n fixM(p2, p, attrs2, attrs, i);\n var seg = p[i],\n seg2 = p2 && p2[i],\n seglen = seg.length,\n seg2len = p2 && seg2.length;\n attrs.x = seg[seglen - 2];\n attrs.y = seg[seglen - 1];\n attrs.bx = toFloat(seg[seglen - 4]) || attrs.x;\n attrs.by = toFloat(seg[seglen - 3]) || attrs.y;\n attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x);\n attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y);\n attrs2.x = p2 && seg2[seg2len - 2];\n attrs2.y = p2 && seg2[seg2len - 1];\n }\n if (!p2) {\n pth.curve = pathClone(p);\n }\n return p2 ? [p, p2] : p;\n }, null, pathClone),\n parseDots = R._parseDots = cacher(function (gradient) {\n var dots = [];\n for (var i = 0, ii = gradient.length; i < ii; i++) {\n var dot = {},\n par = gradient[i].match(/^([^:]*):?([\\d\\.]*)/);\n dot.color = R.getRGB(par[1]);\n if (dot.color.error) {\n return null;\n }\n dot.opacity = dot.color.opacity;\n dot.color = dot.color.hex;\n par[2] && (dot.offset = par[2] + \"%\");\n dots.push(dot);\n }\n for (i = 1, ii = dots.length - 1; i < ii; i++) {\n if (!dots[i].offset) {\n var start = toFloat(dots[i - 1].offset || 0),\n end = 0;\n for (var j = i + 1; j < ii; j++) {\n if (dots[j].offset) {\n end = dots[j].offset;\n break;\n }\n }\n if (!end) {\n end = 100;\n j = ii;\n }\n end = toFloat(end);\n var d = (end - start) / (j - i + 1);\n for (; i < j; i++) {\n start += d;\n dots[i].offset = start + \"%\";\n }\n }\n }\n return dots;\n }),\n tear = R._tear = function (el, paper) {\n el == paper.top && (paper.top = el.prev);\n el == paper.bottom && (paper.bottom = el.next);\n el.next && (el.next.prev = el.prev);\n el.prev && (el.prev.next = el.next);\n },\n tofront = R._tofront = function (el, paper) {\n if (paper.top === el) {\n return;\n }\n tear(el, paper);\n el.next = null;\n el.prev = paper.top;\n paper.top.next = el;\n paper.top = el;\n },\n toback = R._toback = function (el, paper) {\n if (paper.bottom === el) {\n return;\n }\n tear(el, paper);\n el.next = paper.bottom;\n el.prev = null;\n paper.bottom.prev = el;\n paper.bottom = el;\n },\n insertafter = R._insertafter = function (el, el2, paper) {\n tear(el, paper);\n el2 == paper.top && (paper.top = el);\n el2.next && (el2.next.prev = el);\n el.next = el2.next;\n el.prev = el2;\n el2.next = el;\n },\n insertbefore = R._insertbefore = function (el, el2, paper) {\n tear(el, paper);\n el2 == paper.bottom && (paper.bottom = el);\n el2.prev && (el2.prev.next = el);\n el.prev = el2.prev;\n el2.prev = el;\n el.next = el2;\n },\n /*\\\n * Raphael.toMatrix\n [ method ]\n **\n * Utility method\n **\n * Returns matrix of transformations applied to a given path\n > Parameters\n - path (string) path string\n - transform (string|array) transformation string\n = (object) @Matrix\n \\*/\n toMatrix = R.toMatrix = function (path, transform) {\n var bb = pathDimensions(path),\n el = {\n _: {\n transform: E\n },\n getBBox: function () {\n return bb;\n }\n };\n extractTransform(el, transform);\n return el.matrix;\n },\n /*\\\n * Raphael.transformPath\n [ method ]\n **\n * Utility method\n **\n * Returns path transformed by a given transformation\n > Parameters\n - path (string) path string\n - transform (string|array) transformation string\n = (string) path\n \\*/\n transformPath = R.transformPath = function (path, transform) {\n return mapPath(path, toMatrix(path, transform));\n },\n extractTransform = R._extractTransform = function (el, tstr) {\n if (tstr == null) {\n return el._.transform;\n }\n tstr = Str(tstr).replace(/\\.{3}|\\u2026/g, el._.transform || E);\n var tdata = R.parseTransformString(tstr),\n deg = 0,\n dx = 0,\n dy = 0,\n sx = 1,\n sy = 1,\n _ = el._,\n m = new Matrix;\n _.transform = tdata || [];\n if (tdata) {\n for (var i = 0, ii = tdata.length; i < ii; i++) {\n var t = tdata[i],\n tlen = t.length,\n command = Str(t[0]).toLowerCase(),\n absolute = t[0] != command,\n inver = absolute ? m.invert() : 0,\n x1,\n y1,\n x2,\n y2,\n bb;\n if (command == \"t\" && tlen == 3) {\n if (absolute) {\n x1 = inver.x(0, 0);\n y1 = inver.y(0, 0);\n x2 = inver.x(t[1], t[2]);\n y2 = inver.y(t[1], t[2]);\n m.translate(x2 - x1, y2 - y1);\n } else {\n m.translate(t[1], t[2]);\n }\n } else if (command == \"r\") {\n if (tlen == 2) {\n bb = bb || el.getBBox(1);\n m.rotate(t[1], bb.x + bb.width / 2, bb.y + bb.height / 2);\n deg += t[1];\n } else if (tlen == 4) {\n if (absolute) {\n x2 = inver.x(t[2], t[3]);\n y2 = inver.y(t[2], t[3]);\n m.rotate(t[1], x2, y2);\n } else {\n m.rotate(t[1], t[2], t[3]);\n }\n deg += t[1];\n }\n } else if (command == \"s\") {\n if (tlen == 2 || tlen == 3) {\n bb = bb || el.getBBox(1);\n m.scale(t[1], t[tlen - 1], bb.x + bb.width / 2, bb.y + bb.height / 2);\n sx *= t[1];\n sy *= t[tlen - 1];\n } else if (tlen == 5) {\n if (absolute) {\n x2 = inver.x(t[3], t[4]);\n y2 = inver.y(t[3], t[4]);\n m.scale(t[1], t[2], x2, y2);\n } else {\n m.scale(t[1], t[2], t[3], t[4]);\n }\n sx *= t[1];\n sy *= t[2];\n }\n } else if (command == \"m\" && tlen == 7) {\n m.add(t[1], t[2], t[3], t[4], t[5], t[6]);\n }\n _.dirtyT = 1;\n el.matrix = m;\n }\n }\n\n /*\\\n * Element.matrix\n [ property (object) ]\n **\n * Keeps @Matrix object, which represents element transformation\n \\*/\n el.matrix = m;\n\n _.sx = sx;\n _.sy = sy;\n _.deg = deg;\n _.dx = dx = m.e;\n _.dy = dy = m.f;\n\n if (sx == 1 && sy == 1 && !deg && _.bbox) {\n _.bbox.x += +dx;\n _.bbox.y += +dy;\n } else {\n _.dirtyT = 1;\n }\n },\n getEmpty = function (item) {\n var l = item[0];\n switch (l.toLowerCase()) {\n case \"t\": return [l, 0, 0];\n case \"m\": return [l, 1, 0, 0, 1, 0, 0];\n case \"r\": if (item.length == 4) {\n return [l, 0, item[2], item[3]];\n } else {\n return [l, 0];\n }\n case \"s\": if (item.length == 5) {\n return [l, 1, 1, item[3], item[4]];\n } else if (item.length == 3) {\n return [l, 1, 1];\n } else {\n return [l, 1];\n }\n }\n },\n equaliseTransform = R._equaliseTransform = function (t1, t2) {\n t2 = Str(t2).replace(/\\.{3}|\\u2026/g, t1);\n t1 = R.parseTransformString(t1) || [];\n t2 = R.parseTransformString(t2) || [];\n var maxlength = mmax(t1.length, t2.length),\n from = [],\n to = [],\n i = 0, j, jj,\n tt1, tt2;\n for (; i < maxlength; i++) {\n tt1 = t1[i] || getEmpty(t2[i]);\n tt2 = t2[i] || getEmpty(tt1);\n if ((tt1[0] != tt2[0]) ||\n (tt1[0].toLowerCase() == \"r\" && (tt1[2] != tt2[2] || tt1[3] != tt2[3])) ||\n (tt1[0].toLowerCase() == \"s\" && (tt1[3] != tt2[3] || tt1[4] != tt2[4]))\n ) {\n return;\n }\n from[i] = [];\n to[i] = [];\n for (j = 0, jj = mmax(tt1.length, tt2.length); j < jj; j++) {\n j in tt1 && (from[i][j] = tt1[j]);\n j in tt2 && (to[i][j] = tt2[j]);\n }\n }\n return {\n from: from,\n to: to\n };\n };\n R._getContainer = function (x, y, w, h) {\n var container;\n container = h == null && !R.is(x, \"object\") ? g.doc.getElementById(x) : x;\n if (container == null) {\n return;\n }\n if (container.tagName) {\n if (y == null) {\n return {\n container: container,\n width: container.style.pixelWidth || container.offsetWidth,\n height: container.style.pixelHeight || container.offsetHeight\n };\n } else {\n return {\n container: container,\n width: y,\n height: w\n };\n }\n }\n return {\n container: 1,\n x: x,\n y: y,\n width: w,\n height: h\n };\n };\n /*\\\n * Raphael.pathToRelative\n [ method ]\n **\n * Utility method\n **\n * Converts path to relative form\n > Parameters\n - pathString (string|array) path string or array of segments\n = (array) array of segments.\n \\*/\n R.pathToRelative = pathToRelative;\n R._engine = {};\n /*\\\n * Raphael.path2curve\n [ method ]\n **\n * Utility method\n **\n * Converts path to a new path where all segments are cubic bezier curves.\n > Parameters\n - pathString (string|array) path string or array of segments\n = (array) array of segments.\n \\*/\n R.path2curve = path2curve;\n /*\\\n * Raphael.matrix\n [ method ]\n **\n * Utility method\n **\n * Returns matrix based on given parameters.\n > Parameters\n - a (number)\n - b (number)\n - c (number)\n - d (number)\n - e (number)\n - f (number)\n = (object) @Matrix\n \\*/\n R.matrix = function (a, b, c, d, e, f) {\n return new Matrix(a, b, c, d, e, f);\n };\n function Matrix(a, b, c, d, e, f) {\n if (a != null) {\n this.a = +a;\n this.b = +b;\n this.c = +c;\n this.d = +d;\n this.e = +e;\n this.f = +f;\n } else {\n this.a = 1;\n this.b = 0;\n this.c = 0;\n this.d = 1;\n this.e = 0;\n this.f = 0;\n }\n }\n (function (matrixproto) {\n /*\\\n * Matrix.add\n [ method ]\n **\n * Adds given matrix to existing one.\n > Parameters\n - a (number)\n - b (number)\n - c (number)\n - d (number)\n - e (number)\n - f (number)\n or\n - matrix (object) @Matrix\n \\*/\n matrixproto.add = function (a, b, c, d, e, f) {\n var out = [[], [], []],\n m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]],\n matrix = [[a, c, e], [b, d, f], [0, 0, 1]],\n x, y, z, res;\n\n if (a && a instanceof Matrix) {\n matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]];\n }\n\n for (x = 0; x < 3; x++) {\n for (y = 0; y < 3; y++) {\n res = 0;\n for (z = 0; z < 3; z++) {\n res += m[x][z] * matrix[z][y];\n }\n out[x][y] = res;\n }\n }\n this.a = out[0][0];\n this.b = out[1][0];\n this.c = out[0][1];\n this.d = out[1][1];\n this.e = out[0][2];\n this.f = out[1][2];\n };\n /*\\\n * Matrix.invert\n [ method ]\n **\n * Returns inverted version of the matrix\n = (object) @Matrix\n \\*/\n matrixproto.invert = function () {\n var me = this,\n x = me.a * me.d - me.b * me.c;\n return new Matrix(me.d / x, -me.b / x, -me.c / x, me.a / x, (me.c * me.f - me.d * me.e) / x, (me.b * me.e - me.a * me.f) / x);\n };\n /*\\\n * Matrix.clone\n [ method ]\n **\n * Returns copy of the matrix\n = (object) @Matrix\n \\*/\n matrixproto.clone = function () {\n return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f);\n };\n /*\\\n * Matrix.translate\n [ method ]\n **\n * Translate the matrix\n > Parameters\n - x (number)\n - y (number)\n \\*/\n matrixproto.translate = function (x, y) {\n this.add(1, 0, 0, 1, x, y);\n };\n /*\\\n * Matrix.scale\n [ method ]\n **\n * Scales the matrix\n > Parameters\n - x (number)\n - y (number) #optional\n - cx (number) #optional\n - cy (number) #optional\n \\*/\n matrixproto.scale = function (x, y, cx, cy) {\n y == null && (y = x);\n (cx || cy) && this.add(1, 0, 0, 1, cx, cy);\n this.add(x, 0, 0, y, 0, 0);\n (cx || cy) && this.add(1, 0, 0, 1, -cx, -cy);\n };\n /*\\\n * Matrix.rotate\n [ method ]\n **\n * Rotates the matrix\n > Parameters\n - a (number)\n - x (number)\n - y (number)\n \\*/\n matrixproto.rotate = function (a, x, y) {\n a = R.rad(a);\n x = x || 0;\n y = y || 0;\n var cos = +math.cos(a).toFixed(9),\n sin = +math.sin(a).toFixed(9);\n this.add(cos, sin, -sin, cos, x, y);\n this.add(1, 0, 0, 1, -x, -y);\n };\n /*\\\n * Matrix.x\n [ method ]\n **\n * Return x coordinate for given point after transformation described by the matrix. See also @Matrix.y\n > Parameters\n - x (number)\n - y (number)\n = (number) x\n \\*/\n matrixproto.x = function (x, y) {\n return x * this.a + y * this.c + this.e;\n };\n /*\\\n * Matrix.y\n [ method ]\n **\n * Return y coordinate for given point after transformation described by the matrix. See also @Matrix.x\n > Parameters\n - x (number)\n - y (number)\n = (number) y\n \\*/\n matrixproto.y = function (x, y) {\n return x * this.b + y * this.d + this.f;\n };\n matrixproto.get = function (i) {\n return +this[Str.fromCharCode(97 + i)].toFixed(4);\n };\n matrixproto.toString = function () {\n return R.svg ?\n \"matrix(\" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + \")\" :\n [this.get(0), this.get(2), this.get(1), this.get(3), 0, 0].join();\n };\n matrixproto.toFilter = function () {\n return \"progid:DXImageTransform.Microsoft.Matrix(M11=\" + this.get(0) +\n \", M12=\" + this.get(2) + \", M21=\" + this.get(1) + \", M22=\" + this.get(3) +\n \", Dx=\" + this.get(4) + \", Dy=\" + this.get(5) + \", sizingmethod='auto expand')\";\n };\n matrixproto.offset = function () {\n return [this.e.toFixed(4), this.f.toFixed(4)];\n };\n function norm(a) {\n return a[0] * a[0] + a[1] * a[1];\n }\n function normalize(a) {\n var mag = math.sqrt(norm(a));\n a[0] && (a[0] /= mag);\n a[1] && (a[1] /= mag);\n }\n /*\\\n * Matrix.split\n [ method ]\n **\n * Splits matrix into primitive transformations\n = (object) in format:\n o dx (number) translation by x\n o dy (number) translation by y\n o scalex (number) scale by x\n o scaley (number) scale by y\n o shear (number) shear\n o rotate (number) rotation in deg\n o isSimple (boolean) could it be represented via simple transformations\n \\*/\n matrixproto.split = function () {\n var out = {};\n // translation\n out.dx = this.e;\n out.dy = this.f;\n\n // scale and shear\n var row = [[this.a, this.c], [this.b, this.d]];\n out.scalex = math.sqrt(norm(row[0]));\n normalize(row[0]);\n\n out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1];\n row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear];\n\n out.scaley = math.sqrt(norm(row[1]));\n normalize(row[1]);\n out.shear /= out.scaley;\n\n // rotation\n var sin = -row[0][1],\n cos = row[1][1];\n if (cos < 0) {\n out.rotate = R.deg(math.acos(cos));\n if (sin < 0) {\n out.rotate = 360 - out.rotate;\n }\n } else {\n out.rotate = R.deg(math.asin(sin));\n }\n\n out.isSimple = !+out.shear.toFixed(9) && (out.scalex.toFixed(9) == out.scaley.toFixed(9) || !out.rotate);\n out.isSuperSimple = !+out.shear.toFixed(9) && out.scalex.toFixed(9) == out.scaley.toFixed(9) && !out.rotate;\n out.noRotation = !+out.shear.toFixed(9) && !out.rotate;\n return out;\n };\n /*\\\n * Matrix.toTransformString\n [ method ]\n **\n * Return transform string that represents given matrix\n = (string) transform string\n \\*/\n matrixproto.toTransformString = function (shorter) {\n var s = shorter || this[split]();\n if (s.isSimple) {\n s.scalex = +s.scalex.toFixed(4);\n s.scaley = +s.scaley.toFixed(4);\n s.rotate = +s.rotate.toFixed(4);\n return (s.dx || s.dy ? \"t\" + [s.dx, s.dy] : E) +\n (s.scalex != 1 || s.scaley != 1 ? \"s\" + [s.scalex, s.scaley, 0, 0] : E) +\n (s.rotate ? \"r\" + [s.rotate, 0, 0] : E);\n } else {\n return \"m\" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)];\n }\n };\n })(Matrix.prototype);\n\n var preventDefault = function () {\n this.returnValue = false;\n },\n preventTouch = function () {\n return this.originalEvent.preventDefault();\n },\n stopPropagation = function () {\n this.cancelBubble = true;\n },\n stopTouch = function () {\n return this.originalEvent.stopPropagation();\n },\n getEventPosition = function (e) {\n var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,\n scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft;\n\n return {\n x: e.clientX + scrollX,\n y: e.clientY + scrollY\n };\n },\n addEvent = (function () {\n if (g.doc.addEventListener) {\n return function (obj, type, fn, element) {\n var f = function (e) {\n var pos = getEventPosition(e);\n return fn.call(element, e, pos.x, pos.y);\n };\n obj.addEventListener(type, f, false);\n\n if (supportsTouch && touchMap[type]) {\n var _f = function (e) {\n var pos = getEventPosition(e),\n olde = e;\n\n for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) {\n if (e.targetTouches[i].target == obj) {\n e = e.targetTouches[i];\n e.originalEvent = olde;\n e.preventDefault = preventTouch;\n e.stopPropagation = stopTouch;\n break;\n }\n }\n\n return fn.call(element, e, pos.x, pos.y);\n };\n obj.addEventListener(touchMap[type], _f, false);\n }\n\n return function () {\n obj.removeEventListener(type, f, false);\n\n if (supportsTouch && touchMap[type])\n obj.removeEventListener(touchMap[type], _f, false);\n\n return true;\n };\n };\n } else if (g.doc.attachEvent) {\n return function (obj, type, fn, element) {\n var f = function (e) {\n e = e || g.win.event;\n var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,\n scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft,\n x = e.clientX + scrollX,\n y = e.clientY + scrollY;\n e.preventDefault = e.preventDefault || preventDefault;\n e.stopPropagation = e.stopPropagation || stopPropagation;\n return fn.call(element, e, x, y);\n };\n obj.attachEvent(\"on\" + type, f);\n var detacher = function () {\n obj.detachEvent(\"on\" + type, f);\n return true;\n };\n return detacher;\n };\n }\n })(),\n drag = [],\n dragMove = function (e) {\n var x = e.clientX,\n y = e.clientY,\n scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,\n scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft,\n dragi,\n j = drag.length;\n while (j--) {\n dragi = drag[j];\n if (supportsTouch && e.touches) {\n var i = e.touches.length,\n touch;\n while (i--) {\n touch = e.touches[i];\n if (touch.identifier == dragi.el._drag.id) {\n x = touch.clientX;\n y = touch.clientY;\n (e.originalEvent ? e.originalEvent : e).preventDefault();\n break;\n }\n }\n } else {\n e.preventDefault();\n }\n var node = dragi.el.node,\n o,\n next = node.nextSibling,\n parent = node.parentNode,\n display = node.style.display;\n g.win.opera && parent.removeChild(node);\n node.style.display = \"none\";\n o = dragi.el.paper.getElementByPoint(x, y);\n node.style.display = display;\n g.win.opera && (next ? parent.insertBefore(node, next) : parent.appendChild(node));\n o && eve(\"raphael.drag.over.\" + dragi.el.id, dragi.el, o);\n x += scrollX;\n y += scrollY;\n eve(\"raphael.drag.move.\" + dragi.el.id, dragi.move_scope || dragi.el, x - dragi.el._drag.x, y - dragi.el._drag.y, x, y, e);\n }\n },\n dragUp = function (e) {\n R.unmousemove(dragMove).unmouseup(dragUp);\n var i = drag.length,\n dragi;\n while (i--) {\n dragi = drag[i];\n dragi.el._drag = {};\n eve(\"raphael.drag.end.\" + dragi.el.id, dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e);\n }\n drag = [];\n },\n /*\\\n * Raphael.el\n [ property (object) ]\n **\n * You can add your own method to elements. This is useful when you want to hack default functionality or\n * want to wrap some common transformation or attributes in one method. In difference to canvas methods,\n * you can redefine element method at any time. Expending element methods wouldn’t affect set.\n > Usage\n | Raphael.el.red = function () {\n | this.attr({fill: \"#f00\"});\n | };\n | // then use it\n | paper.circle(100, 100, 20).red();\n \\*/\n elproto = R.el = {};\n /*\\\n * Element.click\n [ method ]\n **\n * Adds event handler for click for the element.\n > Parameters\n - handler (function) handler for the event\n = (object) @Element\n \\*/\n /*\\\n * Element.unclick\n [ method ]\n **\n * Removes event handler for click for the element.\n > Parameters\n - handler (function) #optional handler for the event\n = (object) @Element\n \\*/\n\n /*\\\n * Element.dblclick\n [ method ]\n **\n * Adds event handler for double click for the element.\n > Parameters\n - handler (function) handler for the event\n = (object) @Element\n \\*/\n /*\\\n * Element.undblclick\n [ method ]\n **\n * Removes event handler for double click for the element.\n > Parameters\n - handler (function) #optional handler for the event\n = (object) @Element\n \\*/\n\n /*\\\n * Element.mousedown\n [ method ]\n **\n * Adds event handler for mousedown for the element.\n > Parameters\n - handler (function) handler for the event\n = (object) @Element\n \\*/\n /*\\\n * Element.unmousedown\n [ method ]\n **\n * Removes event handler for mousedown for the element.\n > Parameters\n - handler (function) #optional handler for the event\n = (object) @Element\n \\*/\n\n /*\\\n * Element.mousemove\n [ method ]\n **\n * Adds event handler for mousemove for the element.\n > Parameters\n - handler (function) handler for the event\n = (object) @Element\n \\*/\n /*\\\n * Element.unmousemove\n [ method ]\n **\n * Removes event handler for mousemove for the element.\n > Parameters\n - handler (function) #optional handler for the event\n = (object) @Element\n \\*/\n\n /*\\\n * Element.mouseout\n [ method ]\n **\n * Adds event handler for mouseout for the element.\n > Parameters\n - handler (function) handler for the event\n = (object) @Element\n \\*/\n /*\\\n * Element.unmouseout\n [ method ]\n **\n * Removes event handler for mouseout for the element.\n > Parameters\n - handler (function) #optional handler for the event\n = (object) @Element\n \\*/\n\n /*\\\n * Element.mouseover\n [ method ]\n **\n * Adds event handler for mouseover for the element.\n > Parameters\n - handler (function) handler for the event\n = (object) @Element\n \\*/\n /*\\\n * Element.unmouseover\n [ method ]\n **\n * Removes event handler for mouseover for the element.\n > Parameters\n - handler (function) #optional handler for the event\n = (object) @Element\n \\*/\n\n /*\\\n * Element.mouseup\n [ method ]\n **\n * Adds event handler for mouseup for the element.\n > Parameters\n - handler (function) handler for the event\n = (object) @Element\n \\*/\n /*\\\n * Element.unmouseup\n [ method ]\n **\n * Removes event handler for mouseup for the element.\n > Parameters\n - handler (function) #optional handler for the event\n = (object) @Element\n \\*/\n\n /*\\\n * Element.touchstart\n [ method ]\n **\n * Adds event handler for touchstart for the element.\n > Parameters\n - handler (function) handler for the event\n = (object) @Element\n \\*/\n /*\\\n * Element.untouchstart\n [ method ]\n **\n * Removes event handler for touchstart for the element.\n > Parameters\n - handler (function) #optional handler for the event\n = (object) @Element\n \\*/\n\n /*\\\n * Element.touchmove\n [ method ]\n **\n * Adds event handler for touchmove for the element.\n > Parameters\n - handler (function) handler for the event\n = (object) @Element\n \\*/\n /*\\\n * Element.untouchmove\n [ method ]\n **\n * Removes event handler for touchmove for the element.\n > Parameters\n - handler (function) #optional handler for the event\n = (object) @Element\n \\*/\n\n /*\\\n * Element.touchend\n [ method ]\n **\n * Adds event handler for touchend for the element.\n > Parameters\n - handler (function) handler for the event\n = (object) @Element\n \\*/\n /*\\\n * Element.untouchend\n [ method ]\n **\n * Removes event handler for touchend for the element.\n > Parameters\n - handler (function) #optional handler for the event\n = (object) @Element\n \\*/\n\n /*\\\n * Element.touchcancel\n [ method ]\n **\n * Adds event handler for touchcancel for the element.\n > Parameters\n - handler (function) handler for the event\n = (object) @Element\n \\*/\n /*\\\n * Element.untouchcancel\n [ method ]\n **\n * Removes event handler for touchcancel for the element.\n > Parameters\n - handler (function) #optional handler for the event\n = (object) @Element\n \\*/\n for (var i = events.length; i--;) {\n (function (eventName) {\n R[eventName] = elproto[eventName] = function (fn, scope) {\n if (R.is(fn, \"function\")) {\n this.events = this.events || [];\n this.events.push({name: eventName, f: fn, unbind: addEvent(this.shape || this.node || g.doc, eventName, fn, scope || this)});\n }\n return this;\n };\n R[\"un\" + eventName] = elproto[\"un\" + eventName] = function (fn) {\n var events = this.events || [],\n l = events.length;\n while (l--){\n if (events[l].name == eventName && (R.is(fn, \"undefined\") || events[l].f == fn)) {\n events[l].unbind();\n events.splice(l, 1);\n !events.length && delete this.events;\n }\n }\n return this;\n };\n })(events[i]);\n }\n\n /*\\\n * Element.data\n [ method ]\n **\n * Adds or retrieves given value associated with given key.\n **\n * See also @Element.removeData\n > Parameters\n - key (string) key to store data\n - value (any) #optional value to store\n = (object) @Element\n * or, if value is not specified:\n = (any) value\n * or, if key and value are not specified:\n = (object) Key/value pairs for all the data associated with the element.\n > Usage\n | for (var i = 0, i < 5, i++) {\n | paper.circle(10 + 15 * i, 10, 10)\n | .attr({fill: \"#000\"})\n | .data(\"i\", i)\n | .click(function () {\n | alert(this.data(\"i\"));\n | });\n | }\n \\*/\n elproto.data = function (key, value) {\n var data = eldata[this.id] = eldata[this.id] || {};\n if (arguments.length == 0) {\n return data;\n }\n if (arguments.length == 1) {\n if (R.is(key, \"object\")) {\n for (var i in key) if (key[has](i)) {\n this.data(i, key[i]);\n }\n return this;\n }\n eve(\"raphael.data.get.\" + this.id, this, data[key], key);\n return data[key];\n }\n data[key] = value;\n eve(\"raphael.data.set.\" + this.id, this, value, key);\n return this;\n };\n /*\\\n * Element.removeData\n [ method ]\n **\n * Removes value associated with an element by given key.\n * If key is not provided, removes all the data of the element.\n > Parameters\n - key (string) #optional key\n = (object) @Element\n \\*/\n elproto.removeData = function (key) {\n if (key == null) {\n eldata[this.id] = {};\n } else {\n eldata[this.id] && delete eldata[this.id][key];\n }\n return this;\n };\n /*\\\n * Element.getData\n [ method ]\n **\n * Retrieves the element data\n = (object) data\n \\*/\n elproto.getData = function () {\n return clone(eldata[this.id] || {});\n };\n /*\\\n * Element.hover\n [ method ]\n **\n * Adds event handlers for hover for the element.\n > Parameters\n - f_in (function) handler for hover in\n - f_out (function) handler for hover out\n - icontext (object) #optional context for hover in handler\n - ocontext (object) #optional context for hover out handler\n = (object) @Element\n \\*/\n elproto.hover = function (f_in, f_out, scope_in, scope_out) {\n return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in);\n };\n /*\\\n * Element.unhover\n [ method ]\n **\n * Removes event handlers for hover for the element.\n > Parameters\n - f_in (function) handler for hover in\n - f_out (function) handler for hover out\n = (object) @Element\n \\*/\n elproto.unhover = function (f_in, f_out) {\n return this.unmouseover(f_in).unmouseout(f_out);\n };\n var draggable = [];\n /*\\\n * Element.drag\n [ method ]\n **\n * Adds event handlers for drag of the element.\n > Parameters\n - onmove (function) handler for moving\n - onstart (function) handler for drag start\n - onend (function) handler for drag end\n - mcontext (object) #optional context for moving handler\n - scontext (object) #optional context for drag start handler\n - econtext (object) #optional context for drag end handler\n * Additionally following `drag` events will be triggered: `drag.start.` on start,\n * `drag.end.` on end and `drag.move.` on every move. When element will be dragged over another element\n * `drag.over.` will be fired as well.\n *\n * Start event and start handler will be called in specified context or in context of the element with following parameters:\n o x (number) x position of the mouse\n o y (number) y position of the mouse\n o event (object) DOM event object\n * Move event and move handler will be called in specified context or in context of the element with following parameters:\n o dx (number) shift by x from the start point\n o dy (number) shift by y from the start point\n o x (number) x position of the mouse\n o y (number) y position of the mouse\n o event (object) DOM event object\n * End event and end handler will be called in specified context or in context of the element with following parameters:\n o event (object) DOM event object\n = (object) @Element\n \\*/\n elproto.drag = function (onmove, onstart, onend, move_scope, start_scope, end_scope) {\n function start(e) {\n (e.originalEvent || e).preventDefault();\n var x = e.clientX,\n y = e.clientY,\n scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop,\n scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft;\n this._drag.id = e.identifier;\n if (supportsTouch && e.touches) {\n var i = e.touches.length, touch;\n while (i--) {\n touch = e.touches[i];\n this._drag.id = touch.identifier;\n if (touch.identifier == this._drag.id) {\n x = touch.clientX;\n y = touch.clientY;\n break;\n }\n }\n }\n this._drag.x = x + scrollX;\n this._drag.y = y + scrollY;\n !drag.length && R.mousemove(dragMove).mouseup(dragUp);\n drag.push({el: this, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope});\n onstart && eve.on(\"raphael.drag.start.\" + this.id, onstart);\n onmove && eve.on(\"raphael.drag.move.\" + this.id, onmove);\n onend && eve.on(\"raphael.drag.end.\" + this.id, onend);\n eve(\"raphael.drag.start.\" + this.id, start_scope || move_scope || this, e.clientX + scrollX, e.clientY + scrollY, e);\n }\n this._drag = {};\n draggable.push({el: this, start: start});\n this.mousedown(start);\n return this;\n };\n /*\\\n * Element.onDragOver\n [ method ]\n **\n * Shortcut for assigning event handler for `drag.over.` event, where id is id of the element (see @Element.id).\n > Parameters\n - f (function) handler for event, first argument would be the element you are dragging over\n \\*/\n elproto.onDragOver = function (f) {\n f ? eve.on(\"raphael.drag.over.\" + this.id, f) : eve.unbind(\"raphael.drag.over.\" + this.id);\n };\n /*\\\n * Element.undrag\n [ method ]\n **\n * Removes all drag event handlers from given element.\n \\*/\n elproto.undrag = function () {\n var i = draggable.length;\n while (i--) if (draggable[i].el == this) {\n this.unmousedown(draggable[i].start);\n draggable.splice(i, 1);\n eve.unbind(\"raphael.drag.*.\" + this.id);\n }\n !draggable.length && R.unmousemove(dragMove).unmouseup(dragUp);\n drag = [];\n };\n /*\\\n * Paper.circle\n [ method ]\n **\n * Draws a circle.\n **\n > Parameters\n **\n - x (number) x coordinate of the centre\n - y (number) y coordinate of the centre\n - r (number) radius\n = (object) Raphaël element object with type “circle”\n **\n > Usage\n | var c = paper.circle(50, 50, 40);\n \\*/\n paperproto.circle = function (x, y, r) {\n var out = R._engine.circle(this, x || 0, y || 0, r || 0);\n this.__set__ && this.__set__.push(out);\n return out;\n };\n /*\\\n * Paper.rect\n [ method ]\n *\n * Draws a rectangle.\n **\n > Parameters\n **\n - x (number) x coordinate of the top left corner\n - y (number) y coordinate of the top left corner\n - width (number) width\n - height (number) height\n - r (number) #optional radius for rounded corners, default is 0\n = (object) Raphaël element object with type “rect”\n **\n > Usage\n | // regular rectangle\n | var c = paper.rect(10, 10, 50, 50);\n | // rectangle with rounded corners\n | var c = paper.rect(40, 40, 50, 50, 10);\n \\*/\n paperproto.rect = function (x, y, w, h, r) {\n var out = R._engine.rect(this, x || 0, y || 0, w || 0, h || 0, r || 0);\n this.__set__ && this.__set__.push(out);\n return out;\n };\n /*\\\n * Paper.ellipse\n [ method ]\n **\n * Draws an ellipse.\n **\n > Parameters\n **\n - x (number) x coordinate of the centre\n - y (number) y coordinate of the centre\n - rx (number) horizontal radius\n - ry (number) vertical radius\n = (object) Raphaël element object with type “ellipse”\n **\n > Usage\n | var c = paper.ellipse(50, 50, 40, 20);\n \\*/\n paperproto.ellipse = function (x, y, rx, ry) {\n var out = R._engine.ellipse(this, x || 0, y || 0, rx || 0, ry || 0);\n this.__set__ && this.__set__.push(out);\n return out;\n };\n /*\\\n * Paper.path\n [ method ]\n **\n * Creates a path element by given path data string.\n > Parameters\n - pathString (string) #optional path string in SVG format.\n * Path string consists of one-letter commands, followed by comma seprarated arguments in numercal form. Example:\n | \"M10,20L30,40\"\n * Here we can see two commands: “M”, with arguments `(10, 20)` and “L” with arguments `(30, 40)`. Upper case letter mean command is absolute, lower case—relative.\n *\n #

Here is short list of commands available, for more details see SVG path string format.

\n # \n # \n # \n # \n # \n # \n # \n # \n # \n # \n # \n #
CommandNameParameters
Mmoveto(x y)+
Zclosepath(none)
Llineto(x y)+
Hhorizontal linetox+
Vvertical linetoy+
Ccurveto(x1 y1 x2 y2 x y)+
Ssmooth curveto(x2 y2 x y)+
Qquadratic Bézier curveto(x1 y1 x y)+
Tsmooth quadratic Bézier curveto(x y)+
Aelliptical arc(rx ry x-axis-rotation large-arc-flag sweep-flag x y)+
RCatmull-Rom curveto*x1 y1 (x y)+
\n * * “Catmull-Rom curveto” is a not standard SVG command and added in 2.0 to make life easier.\n * Note: there is a special case when path consist of just three commands: “M10,10R…z”. In this case path will smoothly connects to its beginning.\n > Usage\n | var c = paper.path(\"M10 10L90 90\");\n | // draw a diagonal line:\n | // move to 10,10, line to 90,90\n * For example of path strings, check out these icons: http://raphaeljs.com/icons/\n \\*/\n paperproto.path = function (pathString) {\n pathString && !R.is(pathString, string) && !R.is(pathString[0], array) && (pathString += E);\n var out = R._engine.path(R.format[apply](R, arguments), this);\n this.__set__ && this.__set__.push(out);\n return out;\n };\n /*\\\n * Paper.image\n [ method ]\n **\n * Embeds an image into the surface.\n **\n > Parameters\n **\n - src (string) URI of the source image\n - x (number) x coordinate position\n - y (number) y coordinate position\n - width (number) width of the image\n - height (number) height of the image\n = (object) Raphaël element object with type “image”\n **\n > Usage\n | var c = paper.image(\"apple.png\", 10, 10, 80, 80);\n \\*/\n paperproto.image = function (src, x, y, w, h) {\n var out = R._engine.image(this, src || \"about:blank\", x || 0, y || 0, w || 0, h || 0);\n this.__set__ && this.__set__.push(out);\n return out;\n };\n /*\\\n * Paper.text\n [ method ]\n **\n * Draws a text string. If you need line breaks, put “\\n” in the string.\n **\n > Parameters\n **\n - x (number) x coordinate position\n - y (number) y coordinate position\n - text (string) The text string to draw\n = (object) Raphaël element object with type “text”\n **\n > Usage\n | var t = paper.text(50, 50, \"Raphaël\\nkicks\\nbutt!\");\n \\*/\n paperproto.text = function (x, y, text) {\n var out = R._engine.text(this, x || 0, y || 0, Str(text));\n this.__set__ && this.__set__.push(out);\n return out;\n };\n /*\\\n * Paper.set\n [ method ]\n **\n * Creates array-like object to keep and operate several elements at once.\n * Warning: it doesn’t create any elements for itself in the page, it just groups existing elements.\n * Sets act as pseudo elements — all methods available to an element can be used on a set.\n = (object) array-like object that represents set of elements\n **\n > Usage\n | var st = paper.set();\n | st.push(\n | paper.circle(10, 10, 5),\n | paper.circle(30, 10, 5)\n | );\n | st.attr({fill: \"red\"}); // changes the fill of both circles\n \\*/\n paperproto.set = function (itemsArray) {\n !R.is(itemsArray, \"array\") && (itemsArray = Array.prototype.splice.call(arguments, 0, arguments.length));\n var out = new Set(itemsArray);\n this.__set__ && this.__set__.push(out);\n out[\"paper\"] = this;\n out[\"type\"] = \"set\";\n return out;\n };\n /*\\\n * Paper.setStart\n [ method ]\n **\n * Creates @Paper.set. All elements that will be created after calling this method and before calling\n * @Paper.setFinish will be added to the set.\n **\n > Usage\n | paper.setStart();\n | paper.circle(10, 10, 5),\n | paper.circle(30, 10, 5)\n | var st = paper.setFinish();\n | st.attr({fill: \"red\"}); // changes the fill of both circles\n \\*/\n paperproto.setStart = function (set) {\n this.__set__ = set || this.set();\n };\n /*\\\n * Paper.setFinish\n [ method ]\n **\n * See @Paper.setStart. This method finishes catching and returns resulting set.\n **\n = (object) set\n \\*/\n paperproto.setFinish = function (set) {\n var out = this.__set__;\n delete this.__set__;\n return out;\n };\n /*\\\n * Paper.getSize\n [ method ]\n **\n * Obtains current paper actual size.\n **\n = (object)\n \\*/\n paperproto.getSize = function () {\n var container = this.canvas.parentNode;\n return {\n width: container.offsetWidth,\n height: container.offsetHeight\n };\n };\n /*\\\n * Paper.setSize\n [ method ]\n **\n * If you need to change dimensions of the canvas call this method\n **\n > Parameters\n **\n - width (number) new width of the canvas\n - height (number) new height of the canvas\n \\*/\n paperproto.setSize = function (width, height) {\n return R._engine.setSize.call(this, width, height);\n };\n /*\\\n * Paper.setViewBox\n [ method ]\n **\n * Sets the view box of the paper. Practically it gives you ability to zoom and pan whole paper surface by\n * specifying new boundaries.\n **\n > Parameters\n **\n - x (number) new x position, default is `0`\n - y (number) new y position, default is `0`\n - w (number) new width of the canvas\n - h (number) new height of the canvas\n - fit (boolean) `true` if you want graphics to fit into new boundary box\n \\*/\n paperproto.setViewBox = function (x, y, w, h, fit) {\n return R._engine.setViewBox.call(this, x, y, w, h, fit);\n };\n /*\\\n * Paper.top\n [ property ]\n **\n * Points to the topmost element on the paper\n \\*/\n /*\\\n * Paper.bottom\n [ property ]\n **\n * Points to the bottom element on the paper\n \\*/\n paperproto.top = paperproto.bottom = null;\n /*\\\n * Paper.raphael\n [ property ]\n **\n * Points to the @Raphael object/function\n \\*/\n paperproto.raphael = R;\n var getOffset = function (elem) {\n var box = elem.getBoundingClientRect(),\n doc = elem.ownerDocument,\n body = doc.body,\n docElem = doc.documentElement,\n clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,\n top = box.top + (g.win.pageYOffset || docElem.scrollTop || body.scrollTop ) - clientTop,\n left = box.left + (g.win.pageXOffset || docElem.scrollLeft || body.scrollLeft) - clientLeft;\n return {\n y: top,\n x: left\n };\n };\n /*\\\n * Paper.getElementByPoint\n [ method ]\n **\n * Returns you topmost element under given point.\n **\n = (object) Raphaël element object\n > Parameters\n **\n - x (number) x coordinate from the top left corner of the window\n - y (number) y coordinate from the top left corner of the window\n > Usage\n | paper.getElementByPoint(mouseX, mouseY).attr({stroke: \"#f00\"});\n \\*/\n paperproto.getElementByPoint = function (x, y) {\n var paper = this,\n svg = paper.canvas,\n target = g.doc.elementFromPoint(x, y);\n if (g.win.opera && target.tagName == \"svg\") {\n var so = getOffset(svg),\n sr = svg.createSVGRect();\n sr.x = x - so.x;\n sr.y = y - so.y;\n sr.width = sr.height = 1;\n var hits = svg.getIntersectionList(sr, null);\n if (hits.length) {\n target = hits[hits.length - 1];\n }\n }\n if (!target) {\n return null;\n }\n while (target.parentNode && target != svg.parentNode && !target.raphael) {\n target = target.parentNode;\n }\n target == paper.canvas.parentNode && (target = svg);\n target = target && target.raphael ? paper.getById(target.raphaelid) : null;\n return target;\n };\n\n /*\\\n * Paper.getElementsByBBox\n [ method ]\n **\n * Returns set of elements that have an intersecting bounding box\n **\n > Parameters\n **\n - bbox (object) bbox to check with\n = (object) @Set\n \\*/\n paperproto.getElementsByBBox = function (bbox) {\n var set = this.set();\n this.forEach(function (el) {\n if (R.isBBoxIntersect(el.getBBox(), bbox)) {\n set.push(el);\n }\n });\n return set;\n };\n\n /*\\\n * Paper.getById\n [ method ]\n **\n * Returns you element by its internal ID.\n **\n > Parameters\n **\n - id (number) id\n = (object) Raphaël element object\n \\*/\n paperproto.getById = function (id) {\n var bot = this.bottom;\n while (bot) {\n if (bot.id == id) {\n return bot;\n }\n bot = bot.next;\n }\n return null;\n };\n /*\\\n * Paper.forEach\n [ method ]\n **\n * Executes given function for each element on the paper\n *\n * If callback function returns `false` it will stop loop running.\n **\n > Parameters\n **\n - callback (function) function to run\n - thisArg (object) context object for the callback\n = (object) Paper object\n > Usage\n | paper.forEach(function (el) {\n | el.attr({ stroke: \"blue\" });\n | });\n \\*/\n paperproto.forEach = function (callback, thisArg) {\n var bot = this.bottom;\n while (bot) {\n if (callback.call(thisArg, bot) === false) {\n return this;\n }\n bot = bot.next;\n }\n return this;\n };\n /*\\\n * Paper.getElementsByPoint\n [ method ]\n **\n * Returns set of elements that have common point inside\n **\n > Parameters\n **\n - x (number) x coordinate of the point\n - y (number) y coordinate of the point\n = (object) @Set\n \\*/\n paperproto.getElementsByPoint = function (x, y) {\n var set = this.set();\n this.forEach(function (el) {\n if (el.isPointInside(x, y)) {\n set.push(el);\n }\n });\n return set;\n };\n function x_y() {\n return this.x + S + this.y;\n }\n function x_y_w_h() {\n return this.x + S + this.y + S + this.width + \" \\xd7 \" + this.height;\n }\n /*\\\n * Element.isPointInside\n [ method ]\n **\n * Determine if given point is inside this element’s shape\n **\n > Parameters\n **\n - x (number) x coordinate of the point\n - y (number) y coordinate of the point\n = (boolean) `true` if point inside the shape\n \\*/\n elproto.isPointInside = function (x, y) {\n var rp = this.realPath = getPath[this.type](this);\n if (this.attr('transform') && this.attr('transform').length) {\n rp = R.transformPath(rp, this.attr('transform'));\n }\n return R.isPointInsidePath(rp, x, y);\n };\n /*\\\n * Element.getBBox\n [ method ]\n **\n * Return bounding box for a given element\n **\n > Parameters\n **\n - isWithoutTransform (boolean) flag, `true` if you want to have bounding box before transformations. Default is `false`.\n = (object) Bounding box object:\n o {\n o x: (number) top left corner x\n o y: (number) top left corner y\n o x2: (number) bottom right corner x\n o y2: (number) bottom right corner y\n o width: (number) width\n o height: (number) height\n o }\n \\*/\n elproto.getBBox = function (isWithoutTransform) {\n if (this.removed) {\n return {};\n }\n var _ = this._;\n if (isWithoutTransform) {\n if (_.dirty || !_.bboxwt) {\n this.realPath = getPath[this.type](this);\n _.bboxwt = pathDimensions(this.realPath);\n _.bboxwt.toString = x_y_w_h;\n _.dirty = 0;\n }\n return _.bboxwt;\n }\n if (_.dirty || _.dirtyT || !_.bbox) {\n if (_.dirty || !this.realPath) {\n _.bboxwt = 0;\n this.realPath = getPath[this.type](this);\n }\n _.bbox = pathDimensions(mapPath(this.realPath, this.matrix));\n _.bbox.toString = x_y_w_h;\n _.dirty = _.dirtyT = 0;\n }\n return _.bbox;\n };\n /*\\\n * Element.clone\n [ method ]\n **\n = (object) clone of a given element\n **\n \\*/\n elproto.clone = function () {\n if (this.removed) {\n return null;\n }\n var out = this.paper[this.type]().attr(this.attr());\n this.__set__ && this.__set__.push(out);\n return out;\n };\n /*\\\n * Element.glow\n [ method ]\n **\n * Return set of elements that create glow-like effect around given element. See @Paper.set.\n *\n * Note: Glow is not connected to the element. If you change element attributes it won’t adjust itself.\n **\n > Parameters\n **\n - glow (object) #optional parameters object with all properties optional:\n o {\n o width (number) size of the glow, default is `10`\n o fill (boolean) will it be filled, default is `false`\n o opacity (number) opacity, default is `0.5`\n o offsetx (number) horizontal offset, default is `0`\n o offsety (number) vertical offset, default is `0`\n o color (string) glow colour, default is `black`\n o }\n = (object) @Paper.set of elements that represents glow\n \\*/\n elproto.glow = function (glow) {\n if (this.type == \"text\") {\n return null;\n }\n glow = glow || {};\n var s = {\n width: (glow.width || 10) + (+this.attr(\"stroke-width\") || 1),\n fill: glow.fill || false,\n opacity: glow.opacity == null ? .5 : glow.opacity,\n offsetx: glow.offsetx || 0,\n offsety: glow.offsety || 0,\n color: glow.color || \"#000\"\n },\n c = s.width / 2,\n r = this.paper,\n out = r.set(),\n path = this.realPath || getPath[this.type](this);\n path = this.matrix ? mapPath(path, this.matrix) : path;\n for (var i = 1; i < c + 1; i++) {\n out.push(r.path(path).attr({\n stroke: s.color,\n fill: s.fill ? s.color : \"none\",\n \"stroke-linejoin\": \"round\",\n \"stroke-linecap\": \"round\",\n \"stroke-width\": +(s.width / c * i).toFixed(3),\n opacity: +(s.opacity / c).toFixed(3)\n }));\n }\n return out.insertBefore(this).translate(s.offsetx, s.offsety);\n };\n var curveslengths = {},\n getPointAtSegmentLength = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) {\n if (length == null) {\n return bezlen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y);\n } else {\n return R.findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, getTatLen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length));\n }\n },\n getLengthFactory = function (istotal, subpath) {\n return function (path, length, onlystart) {\n path = path2curve(path);\n var x, y, p, l, sp = \"\", subpaths = {}, point,\n len = 0;\n for (var i = 0, ii = path.length; i < ii; i++) {\n p = path[i];\n if (p[0] == \"M\") {\n x = +p[1];\n y = +p[2];\n } else {\n l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]);\n if (len + l > length) {\n if (subpath && !subpaths.start) {\n point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);\n sp += [\"C\" + point.start.x, point.start.y, point.m.x, point.m.y, point.x, point.y];\n if (onlystart) {return sp;}\n subpaths.start = sp;\n sp = [\"M\" + point.x, point.y + \"C\" + point.n.x, point.n.y, point.end.x, point.end.y, p[5], p[6]].join();\n len += l;\n x = +p[5];\n y = +p[6];\n continue;\n }\n if (!istotal && !subpath) {\n point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len);\n return {x: point.x, y: point.y, alpha: point.alpha};\n }\n }\n len += l;\n x = +p[5];\n y = +p[6];\n }\n sp += p.shift() + p;\n }\n subpaths.end = sp;\n point = istotal ? len : subpath ? subpaths : R.findDotsAtSegment(x, y, p[0], p[1], p[2], p[3], p[4], p[5], 1);\n point.alpha && (point = {x: point.x, y: point.y, alpha: point.alpha});\n return point;\n };\n };\n var getTotalLength = getLengthFactory(1),\n getPointAtLength = getLengthFactory(),\n getSubpathsAtLength = getLengthFactory(0, 1);\n /*\\\n * Raphael.getTotalLength\n [ method ]\n **\n * Returns length of the given path in pixels.\n **\n > Parameters\n **\n - path (string) SVG path string.\n **\n = (number) length.\n \\*/\n R.getTotalLength = getTotalLength;\n /*\\\n * Raphael.getPointAtLength\n [ method ]\n **\n * Return coordinates of the point located at the given length on the given path.\n **\n > Parameters\n **\n - path (string) SVG path string\n - length (number)\n **\n = (object) representation of the point:\n o {\n o x: (number) x coordinate\n o y: (number) y coordinate\n o alpha: (number) angle of derivative\n o }\n \\*/\n R.getPointAtLength = getPointAtLength;\n /*\\\n * Raphael.getSubpath\n [ method ]\n **\n * Return subpath of a given path from given length to given length.\n **\n > Parameters\n **\n - path (string) SVG path string\n - from (number) position of the start of the segment\n - to (number) position of the end of the segment\n **\n = (string) pathstring for the segment\n \\*/\n R.getSubpath = function (path, from, to) {\n if (this.getTotalLength(path) - to < 1e-6) {\n return getSubpathsAtLength(path, from).end;\n }\n var a = getSubpathsAtLength(path, to, 1);\n return from ? getSubpathsAtLength(a, from).end : a;\n };\n /*\\\n * Element.getTotalLength\n [ method ]\n **\n * Returns length of the path in pixels. Only works for element of “path” type.\n = (number) length.\n \\*/\n elproto.getTotalLength = function () {\n var path = this.getPath();\n if (!path) {\n return;\n }\n\n if (this.node.getTotalLength) {\n return this.node.getTotalLength();\n }\n\n return getTotalLength(path);\n };\n /*\\\n * Element.getPointAtLength\n [ method ]\n **\n * Return coordinates of the point located at the given length on the given path. Only works for element of “path” type.\n **\n > Parameters\n **\n - length (number)\n **\n = (object) representation of the point:\n o {\n o x: (number) x coordinate\n o y: (number) y coordinate\n o alpha: (number) angle of derivative\n o }\n \\*/\n elproto.getPointAtLength = function (length) {\n var path = this.getPath();\n if (!path) {\n return;\n }\n\n return getPointAtLength(path, length);\n };\n /*\\\n * Element.getPath\n [ method ]\n **\n * Returns path of the element. Only works for elements of “path” type and simple elements like circle.\n = (object) path\n **\n \\*/\n elproto.getPath = function () {\n var path,\n getPath = R._getPath[this.type];\n\n if (this.type == \"text\" || this.type == \"set\") {\n return;\n }\n\n if (getPath) {\n path = getPath(this);\n }\n\n return path;\n };\n /*\\\n * Element.getSubpath\n [ method ]\n **\n * Return subpath of a given element from given length to given length. Only works for element of “path” type.\n **\n > Parameters\n **\n - from (number) position of the start of the segment\n - to (number) position of the end of the segment\n **\n = (string) pathstring for the segment\n \\*/\n elproto.getSubpath = function (from, to) {\n var path = this.getPath();\n if (!path) {\n return;\n }\n\n return R.getSubpath(path, from, to);\n };\n /*\\\n * Raphael.easing_formulas\n [ property ]\n **\n * Object that contains easing formulas for animation. You could extend it with your own. By default it has following list of easing:\n #
    \n #
  • “linear”
  • \n #
  • “<” or “easeIn” or “ease-in”
  • \n #
  • “>” or “easeOut” or “ease-out”
  • \n #
  • “<>” or “easeInOut” or “ease-in-out”
  • \n #
  • “backIn” or “back-in”
  • \n #
  • “backOut” or “back-out”
  • \n #
  • “elastic”
  • \n #
  • “bounce”
  • \n #
\n #

See also Easing demo.

\n \\*/\n var ef = R.easing_formulas = {\n linear: function (n) {\n return n;\n },\n \"<\": function (n) {\n return pow(n, 1.7);\n },\n \">\": function (n) {\n return pow(n, .48);\n },\n \"<>\": function (n) {\n var q = .48 - n / 1.04,\n Q = math.sqrt(.1734 + q * q),\n x = Q - q,\n X = pow(abs(x), 1 / 3) * (x < 0 ? -1 : 1),\n y = -Q - q,\n Y = pow(abs(y), 1 / 3) * (y < 0 ? -1 : 1),\n t = X + Y + .5;\n return (1 - t) * 3 * t * t + t * t * t;\n },\n backIn: function (n) {\n var s = 1.70158;\n return n * n * ((s + 1) * n - s);\n },\n backOut: function (n) {\n n = n - 1;\n var s = 1.70158;\n return n * n * ((s + 1) * n + s) + 1;\n },\n elastic: function (n) {\n if (n == !!n) {\n return n;\n }\n return pow(2, -10 * n) * math.sin((n - .075) * (2 * PI) / .3) + 1;\n },\n bounce: function (n) {\n var s = 7.5625,\n p = 2.75,\n l;\n if (n < (1 / p)) {\n l = s * n * n;\n } else {\n if (n < (2 / p)) {\n n -= (1.5 / p);\n l = s * n * n + .75;\n } else {\n if (n < (2.5 / p)) {\n n -= (2.25 / p);\n l = s * n * n + .9375;\n } else {\n n -= (2.625 / p);\n l = s * n * n + .984375;\n }\n }\n }\n return l;\n }\n };\n ef.easeIn = ef[\"ease-in\"] = ef[\"<\"];\n ef.easeOut = ef[\"ease-out\"] = ef[\">\"];\n ef.easeInOut = ef[\"ease-in-out\"] = ef[\"<>\"];\n ef[\"back-in\"] = ef.backIn;\n ef[\"back-out\"] = ef.backOut;\n\n var animationElements = [],\n requestAnimFrame = window.requestAnimationFrame ||\n window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n window.msRequestAnimationFrame ||\n function (callback) {\n setTimeout(callback, 16);\n },\n animation = function () {\n var Now = +new Date,\n l = 0;\n for (; l < animationElements.length; l++) {\n var e = animationElements[l];\n if (e.el.removed || e.paused) {\n continue;\n }\n var time = Now - e.start,\n ms = e.ms,\n easing = e.easing,\n from = e.from,\n diff = e.diff,\n to = e.to,\n t = e.t,\n that = e.el,\n set = {},\n now,\n init = {},\n key;\n if (e.initstatus) {\n time = (e.initstatus * e.anim.top - e.prev) / (e.percent - e.prev) * ms;\n e.status = e.initstatus;\n delete e.initstatus;\n e.stop && animationElements.splice(l--, 1);\n } else {\n e.status = (e.prev + (e.percent - e.prev) * (time / ms)) / e.anim.top;\n }\n if (time < 0) {\n continue;\n }\n if (time < ms) {\n var pos = easing(time / ms);\n for (var attr in from) if (from[has](attr)) {\n switch (availableAnimAttrs[attr]) {\n case nu:\n now = +from[attr] + pos * ms * diff[attr];\n break;\n case \"colour\":\n now = \"rgb(\" + [\n upto255(round(from[attr].r + pos * ms * diff[attr].r)),\n upto255(round(from[attr].g + pos * ms * diff[attr].g)),\n upto255(round(from[attr].b + pos * ms * diff[attr].b))\n ].join(\",\") + \")\";\n break;\n case \"path\":\n now = [];\n for (var i = 0, ii = from[attr].length; i < ii; i++) {\n now[i] = [from[attr][i][0]];\n for (var j = 1, jj = from[attr][i].length; j < jj; j++) {\n now[i][j] = +from[attr][i][j] + pos * ms * diff[attr][i][j];\n }\n now[i] = now[i].join(S);\n }\n now = now.join(S);\n break;\n case \"transform\":\n if (diff[attr].real) {\n now = [];\n for (i = 0, ii = from[attr].length; i < ii; i++) {\n now[i] = [from[attr][i][0]];\n for (j = 1, jj = from[attr][i].length; j < jj; j++) {\n now[i][j] = from[attr][i][j] + pos * ms * diff[attr][i][j];\n }\n }\n } else {\n var get = function (i) {\n return +from[attr][i] + pos * ms * diff[attr][i];\n };\n // now = [[\"r\", get(2), 0, 0], [\"t\", get(3), get(4)], [\"s\", get(0), get(1), 0, 0]];\n now = [[\"m\", get(0), get(1), get(2), get(3), get(4), get(5)]];\n }\n break;\n case \"csv\":\n if (attr == \"clip-rect\") {\n now = [];\n i = 4;\n while (i--) {\n now[i] = +from[attr][i] + pos * ms * diff[attr][i];\n }\n }\n break;\n default:\n var from2 = [][concat](from[attr]);\n now = [];\n i = that.paper.customAttributes[attr].length;\n while (i--) {\n now[i] = +from2[i] + pos * ms * diff[attr][i];\n }\n break;\n }\n set[attr] = now;\n }\n that.attr(set);\n (function (id, that, anim) {\n setTimeout(function () {\n eve(\"raphael.anim.frame.\" + id, that, anim);\n });\n })(that.id, that, e.anim);\n } else {\n (function(f, el, a) {\n setTimeout(function() {\n eve(\"raphael.anim.frame.\" + el.id, el, a);\n eve(\"raphael.anim.finish.\" + el.id, el, a);\n R.is(f, \"function\") && f.call(el);\n });\n })(e.callback, that, e.anim);\n that.attr(to);\n animationElements.splice(l--, 1);\n if (e.repeat > 1 && !e.next) {\n for (key in to) if (to[has](key)) {\n init[key] = e.totalOrigin[key];\n }\n e.el.attr(init);\n runAnimation(e.anim, e.el, e.anim.percents[0], null, e.totalOrigin, e.repeat - 1);\n }\n if (e.next && !e.stop) {\n runAnimation(e.anim, e.el, e.next, null, e.totalOrigin, e.repeat);\n }\n }\n }\n animationElements.length && requestAnimFrame(animation);\n },\n upto255 = function (color) {\n return color > 255 ? 255 : color < 0 ? 0 : color;\n };\n /*\\\n * Element.animateWith\n [ method ]\n **\n * Acts similar to @Element.animate, but ensure that given animation runs in sync with another given element.\n **\n > Parameters\n **\n - el (object) element to sync with\n - anim (object) animation to sync with\n - params (object) #optional final attributes for the element, see also @Element.attr\n - ms (number) #optional number of milliseconds for animation to run\n - easing (string) #optional easing type. Accept on of @Raphael.easing_formulas or CSS format: `cubic‐bezier(XX, XX, XX, XX)`\n - callback (function) #optional callback function. Will be called at the end of animation.\n * or\n - element (object) element to sync with\n - anim (object) animation to sync with\n - animation (object) #optional animation object, see @Raphael.animation\n **\n = (object) original element\n \\*/\n elproto.animateWith = function (el, anim, params, ms, easing, callback) {\n var element = this;\n if (element.removed) {\n callback && callback.call(element);\n return element;\n }\n var a = params instanceof Animation ? params : R.animation(params, ms, easing, callback),\n x, y;\n runAnimation(a, element, a.percents[0], null, element.attr());\n for (var i = 0, ii = animationElements.length; i < ii; i++) {\n if (animationElements[i].anim == anim && animationElements[i].el == el) {\n animationElements[ii - 1].start = animationElements[i].start;\n break;\n }\n }\n return element;\n //\n //\n // var a = params ? R.animation(params, ms, easing, callback) : anim,\n // status = element.status(anim);\n // return this.animate(a).status(a, status * anim.ms / a.ms);\n };\n function CubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration) {\n var cx = 3 * p1x,\n bx = 3 * (p2x - p1x) - cx,\n ax = 1 - cx - bx,\n cy = 3 * p1y,\n by = 3 * (p2y - p1y) - cy,\n ay = 1 - cy - by;\n function sampleCurveX(t) {\n return ((ax * t + bx) * t + cx) * t;\n }\n function solve(x, epsilon) {\n var t = solveCurveX(x, epsilon);\n return ((ay * t + by) * t + cy) * t;\n }\n function solveCurveX(x, epsilon) {\n var t0, t1, t2, x2, d2, i;\n for(t2 = x, i = 0; i < 8; i++) {\n x2 = sampleCurveX(t2) - x;\n if (abs(x2) < epsilon) {\n return t2;\n }\n d2 = (3 * ax * t2 + 2 * bx) * t2 + cx;\n if (abs(d2) < 1e-6) {\n break;\n }\n t2 = t2 - x2 / d2;\n }\n t0 = 0;\n t1 = 1;\n t2 = x;\n if (t2 < t0) {\n return t0;\n }\n if (t2 > t1) {\n return t1;\n }\n while (t0 < t1) {\n x2 = sampleCurveX(t2);\n if (abs(x2 - x) < epsilon) {\n return t2;\n }\n if (x > x2) {\n t0 = t2;\n } else {\n t1 = t2;\n }\n t2 = (t1 - t0) / 2 + t0;\n }\n return t2;\n }\n return solve(t, 1 / (200 * duration));\n }\n elproto.onAnimation = function (f) {\n f ? eve.on(\"raphael.anim.frame.\" + this.id, f) : eve.unbind(\"raphael.anim.frame.\" + this.id);\n return this;\n };\n function Animation(anim, ms) {\n var percents = [],\n newAnim = {};\n this.ms = ms;\n this.times = 1;\n if (anim) {\n for (var attr in anim) if (anim[has](attr)) {\n newAnim[toFloat(attr)] = anim[attr];\n percents.push(toFloat(attr));\n }\n percents.sort(sortByNumber);\n }\n this.anim = newAnim;\n this.top = percents[percents.length - 1];\n this.percents = percents;\n }\n /*\\\n * Animation.delay\n [ method ]\n **\n * Creates a copy of existing animation object with given delay.\n **\n > Parameters\n **\n - delay (number) number of ms to pass between animation start and actual animation\n **\n = (object) new altered Animation object\n | var anim = Raphael.animation({cx: 10, cy: 20}, 2e3);\n | circle1.animate(anim); // run the given animation immediately\n | circle2.animate(anim.delay(500)); // run the given animation after 500 ms\n \\*/\n Animation.prototype.delay = function (delay) {\n var a = new Animation(this.anim, this.ms);\n a.times = this.times;\n a.del = +delay || 0;\n return a;\n };\n /*\\\n * Animation.repeat\n [ method ]\n **\n * Creates a copy of existing animation object with given repetition.\n **\n > Parameters\n **\n - repeat (number) number iterations of animation. For infinite animation pass `Infinity`\n **\n = (object) new altered Animation object\n \\*/\n Animation.prototype.repeat = function (times) {\n var a = new Animation(this.anim, this.ms);\n a.del = this.del;\n a.times = math.floor(mmax(times, 0)) || 1;\n return a;\n };\n function runAnimation(anim, element, percent, status, totalOrigin, times) {\n percent = toFloat(percent);\n var params,\n isInAnim,\n isInAnimSet,\n percents = [],\n next,\n prev,\n timestamp,\n ms = anim.ms,\n from = {},\n to = {},\n diff = {};\n if (status) {\n for (i = 0, ii = animationElements.length; i < ii; i++) {\n var e = animationElements[i];\n if (e.el.id == element.id && e.anim == anim) {\n if (e.percent != percent) {\n animationElements.splice(i, 1);\n isInAnimSet = 1;\n } else {\n isInAnim = e;\n }\n element.attr(e.totalOrigin);\n break;\n }\n }\n } else {\n status = +to; // NaN\n }\n for (var i = 0, ii = anim.percents.length; i < ii; i++) {\n if (anim.percents[i] == percent || anim.percents[i] > status * anim.top) {\n percent = anim.percents[i];\n prev = anim.percents[i - 1] || 0;\n ms = ms / anim.top * (percent - prev);\n next = anim.percents[i + 1];\n params = anim.anim[percent];\n break;\n } else if (status) {\n element.attr(anim.anim[anim.percents[i]]);\n }\n }\n if (!params) {\n return;\n }\n if (!isInAnim) {\n for (var attr in params) if (params[has](attr)) {\n if (availableAnimAttrs[has](attr) || element.paper.customAttributes[has](attr)) {\n from[attr] = element.attr(attr);\n (from[attr] == null) && (from[attr] = availableAttrs[attr]);\n to[attr] = params[attr];\n switch (availableAnimAttrs[attr]) {\n case nu:\n diff[attr] = (to[attr] - from[attr]) / ms;\n break;\n case \"colour\":\n from[attr] = R.getRGB(from[attr]);\n var toColour = R.getRGB(to[attr]);\n diff[attr] = {\n r: (toColour.r - from[attr].r) / ms,\n g: (toColour.g - from[attr].g) / ms,\n b: (toColour.b - from[attr].b) / ms\n };\n break;\n case \"path\":\n var pathes = path2curve(from[attr], to[attr]),\n toPath = pathes[1];\n from[attr] = pathes[0];\n diff[attr] = [];\n for (i = 0, ii = from[attr].length; i < ii; i++) {\n diff[attr][i] = [0];\n for (var j = 1, jj = from[attr][i].length; j < jj; j++) {\n diff[attr][i][j] = (toPath[i][j] - from[attr][i][j]) / ms;\n }\n }\n break;\n case \"transform\":\n var _ = element._,\n eq = equaliseTransform(_[attr], to[attr]);\n if (eq) {\n from[attr] = eq.from;\n to[attr] = eq.to;\n diff[attr] = [];\n diff[attr].real = true;\n for (i = 0, ii = from[attr].length; i < ii; i++) {\n diff[attr][i] = [from[attr][i][0]];\n for (j = 1, jj = from[attr][i].length; j < jj; j++) {\n diff[attr][i][j] = (to[attr][i][j] - from[attr][i][j]) / ms;\n }\n }\n } else {\n var m = (element.matrix || new Matrix),\n to2 = {\n _: {transform: _.transform},\n getBBox: function () {\n return element.getBBox(1);\n }\n };\n from[attr] = [\n m.a,\n m.b,\n m.c,\n m.d,\n m.e,\n m.f\n ];\n extractTransform(to2, to[attr]);\n to[attr] = to2._.transform;\n diff[attr] = [\n (to2.matrix.a - m.a) / ms,\n (to2.matrix.b - m.b) / ms,\n (to2.matrix.c - m.c) / ms,\n (to2.matrix.d - m.d) / ms,\n (to2.matrix.e - m.e) / ms,\n (to2.matrix.f - m.f) / ms\n ];\n // from[attr] = [_.sx, _.sy, _.deg, _.dx, _.dy];\n // var to2 = {_:{}, getBBox: function () { return element.getBBox(); }};\n // extractTransform(to2, to[attr]);\n // diff[attr] = [\n // (to2._.sx - _.sx) / ms,\n // (to2._.sy - _.sy) / ms,\n // (to2._.deg - _.deg) / ms,\n // (to2._.dx - _.dx) / ms,\n // (to2._.dy - _.dy) / ms\n // ];\n }\n break;\n case \"csv\":\n var values = Str(params[attr])[split](separator),\n from2 = Str(from[attr])[split](separator);\n if (attr == \"clip-rect\") {\n from[attr] = from2;\n diff[attr] = [];\n i = from2.length;\n while (i--) {\n diff[attr][i] = (values[i] - from[attr][i]) / ms;\n }\n }\n to[attr] = values;\n break;\n default:\n values = [][concat](params[attr]);\n from2 = [][concat](from[attr]);\n diff[attr] = [];\n i = element.paper.customAttributes[attr].length;\n while (i--) {\n diff[attr][i] = ((values[i] || 0) - (from2[i] || 0)) / ms;\n }\n break;\n }\n }\n }\n var easing = params.easing,\n easyeasy = R.easing_formulas[easing];\n if (!easyeasy) {\n easyeasy = Str(easing).match(bezierrg);\n if (easyeasy && easyeasy.length == 5) {\n var curve = easyeasy;\n easyeasy = function (t) {\n return CubicBezierAtTime(t, +curve[1], +curve[2], +curve[3], +curve[4], ms);\n };\n } else {\n easyeasy = pipe;\n }\n }\n timestamp = params.start || anim.start || +new Date;\n e = {\n anim: anim,\n percent: percent,\n timestamp: timestamp,\n start: timestamp + (anim.del || 0),\n status: 0,\n initstatus: status || 0,\n stop: false,\n ms: ms,\n easing: easyeasy,\n from: from,\n diff: diff,\n to: to,\n el: element,\n callback: params.callback,\n prev: prev,\n next: next,\n repeat: times || anim.times,\n origin: element.attr(),\n totalOrigin: totalOrigin\n };\n animationElements.push(e);\n if (status && !isInAnim && !isInAnimSet) {\n e.stop = true;\n e.start = new Date - ms * status;\n if (animationElements.length == 1) {\n return animation();\n }\n }\n if (isInAnimSet) {\n e.start = new Date - e.ms * status;\n }\n animationElements.length == 1 && requestAnimFrame(animation);\n } else {\n isInAnim.initstatus = status;\n isInAnim.start = new Date - isInAnim.ms * status;\n }\n eve(\"raphael.anim.start.\" + element.id, element, anim);\n }\n /*\\\n * Raphael.animation\n [ method ]\n **\n * Creates an animation object that can be passed to the @Element.animate or @Element.animateWith methods.\n * See also @Animation.delay and @Animation.repeat methods.\n **\n > Parameters\n **\n - params (object) final attributes for the element, see also @Element.attr\n - ms (number) number of milliseconds for animation to run\n - easing (string) #optional easing type. Accept one of @Raphael.easing_formulas or CSS format: `cubic‐bezier(XX, XX, XX, XX)`\n - callback (function) #optional callback function. Will be called at the end of animation.\n **\n = (object) @Animation\n \\*/\n R.animation = function (params, ms, easing, callback) {\n if (params instanceof Animation) {\n return params;\n }\n if (R.is(easing, \"function\") || !easing) {\n callback = callback || easing || null;\n easing = null;\n }\n params = Object(params);\n ms = +ms || 0;\n var p = {},\n json,\n attr;\n for (attr in params) if (params[has](attr) && toFloat(attr) != attr && toFloat(attr) + \"%\" != attr) {\n json = true;\n p[attr] = params[attr];\n }\n if (!json) {\n // if percent-like syntax is used and end-of-all animation callback used\n if(callback){\n // find the last one\n var lastKey = 0;\n for(var i in params){\n var percent = toInt(i);\n if(params[has](i) && percent > lastKey){\n lastKey = percent;\n }\n }\n lastKey += '%';\n // if already defined callback in the last keyframe, skip\n !params[lastKey].callback && (params[lastKey].callback = callback);\n }\n return new Animation(params, ms);\n } else {\n easing && (p.easing = easing);\n callback && (p.callback = callback);\n return new Animation({100: p}, ms);\n }\n };\n /*\\\n * Element.animate\n [ method ]\n **\n * Creates and starts animation for given element.\n **\n > Parameters\n **\n - params (object) final attributes for the element, see also @Element.attr\n - ms (number) number of milliseconds for animation to run\n - easing (string) #optional easing type. Accept one of @Raphael.easing_formulas or CSS format: `cubic‐bezier(XX, XX, XX, XX)`\n - callback (function) #optional callback function. Will be called at the end of animation.\n * or\n - animation (object) animation object, see @Raphael.animation\n **\n = (object) original element\n \\*/\n elproto.animate = function (params, ms, easing, callback) {\n var element = this;\n if (element.removed) {\n callback && callback.call(element);\n return element;\n }\n var anim = params instanceof Animation ? params : R.animation(params, ms, easing, callback);\n runAnimation(anim, element, anim.percents[0], null, element.attr());\n return element;\n };\n /*\\\n * Element.setTime\n [ method ]\n **\n * Sets the status of animation of the element in milliseconds. Similar to @Element.status method.\n **\n > Parameters\n **\n - anim (object) animation object\n - value (number) number of milliseconds from the beginning of the animation\n **\n = (object) original element if `value` is specified\n * Note, that during animation following events are triggered:\n *\n * On each animation frame event `anim.frame.`, on start `anim.start.` and on end `anim.finish.`.\n \\*/\n elproto.setTime = function (anim, value) {\n if (anim && value != null) {\n this.status(anim, mmin(value, anim.ms) / anim.ms);\n }\n return this;\n };\n /*\\\n * Element.status\n [ method ]\n **\n * Gets or sets the status of animation of the element.\n **\n > Parameters\n **\n - anim (object) #optional animation object\n - value (number) #optional 0 – 1. If specified, method works like a setter and sets the status of a given animation to the value. This will cause animation to jump to the given position.\n **\n = (number) status\n * or\n = (array) status if `anim` is not specified. Array of objects in format:\n o {\n o anim: (object) animation object\n o status: (number) status\n o }\n * or\n = (object) original element if `value` is specified\n \\*/\n elproto.status = function (anim, value) {\n var out = [],\n i = 0,\n len,\n e;\n if (value != null) {\n runAnimation(anim, this, -1, mmin(value, 1));\n return this;\n } else {\n len = animationElements.length;\n for (; i < len; i++) {\n e = animationElements[i];\n if (e.el.id == this.id && (!anim || e.anim == anim)) {\n if (anim) {\n return e.status;\n }\n out.push({\n anim: e.anim,\n status: e.status\n });\n }\n }\n if (anim) {\n return 0;\n }\n return out;\n }\n };\n /*\\\n * Element.pause\n [ method ]\n **\n * Stops animation of the element with ability to resume it later on.\n **\n > Parameters\n **\n - anim (object) #optional animation object\n **\n = (object) original element\n \\*/\n elproto.pause = function (anim) {\n for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {\n if (eve(\"raphael.anim.pause.\" + this.id, this, animationElements[i].anim) !== false) {\n animationElements[i].paused = true;\n }\n }\n return this;\n };\n /*\\\n * Element.resume\n [ method ]\n **\n * Resumes animation if it was paused with @Element.pause method.\n **\n > Parameters\n **\n - anim (object) #optional animation object\n **\n = (object) original element\n \\*/\n elproto.resume = function (anim) {\n for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {\n var e = animationElements[i];\n if (eve(\"raphael.anim.resume.\" + this.id, this, e.anim) !== false) {\n delete e.paused;\n this.status(e.anim, e.status);\n }\n }\n return this;\n };\n /*\\\n * Element.stop\n [ method ]\n **\n * Stops animation of the element.\n **\n > Parameters\n **\n - anim (object) #optional animation object\n **\n = (object) original element\n \\*/\n elproto.stop = function (anim) {\n for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) {\n if (eve(\"raphael.anim.stop.\" + this.id, this, animationElements[i].anim) !== false) {\n animationElements.splice(i--, 1);\n }\n }\n return this;\n };\n function stopAnimation(paper) {\n for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.paper == paper) {\n animationElements.splice(i--, 1);\n }\n }\n eve.on(\"raphael.remove\", stopAnimation);\n eve.on(\"raphael.clear\", stopAnimation);\n elproto.toString = function () {\n return \"Rapha\\xebl\\u2019s object\";\n };\n\n // Set\n var Set = function (items) {\n this.items = [];\n this.length = 0;\n this.type = \"set\";\n if (items) {\n for (var i = 0, ii = items.length; i < ii; i++) {\n if (items[i] && (items[i].constructor == elproto.constructor || items[i].constructor == Set)) {\n this[this.items.length] = this.items[this.items.length] = items[i];\n this.length++;\n }\n }\n }\n },\n setproto = Set.prototype;\n /*\\\n * Set.push\n [ method ]\n **\n * Adds each argument to the current set.\n = (object) original element\n \\*/\n setproto.push = function () {\n var item,\n len;\n for (var i = 0, ii = arguments.length; i < ii; i++) {\n item = arguments[i];\n if (item && (item.constructor == elproto.constructor || item.constructor == Set)) {\n len = this.items.length;\n this[len] = this.items[len] = item;\n this.length++;\n }\n }\n return this;\n };\n /*\\\n * Set.pop\n [ method ]\n **\n * Removes last element and returns it.\n = (object) element\n \\*/\n setproto.pop = function () {\n this.length && delete this[this.length--];\n return this.items.pop();\n };\n /*\\\n * Set.forEach\n [ method ]\n **\n * Executes given function for each element in the set.\n *\n * If function returns `false` it will stop loop running.\n **\n > Parameters\n **\n - callback (function) function to run\n - thisArg (object) context object for the callback\n = (object) Set object\n \\*/\n setproto.forEach = function (callback, thisArg) {\n for (var i = 0, ii = this.items.length; i < ii; i++) {\n if (callback.call(thisArg, this.items[i], i) === false) {\n return this;\n }\n }\n return this;\n };\n for (var method in elproto) if (elproto[has](method)) {\n setproto[method] = (function (methodname) {\n return function () {\n var arg = arguments;\n return this.forEach(function (el) {\n el[methodname][apply](el, arg);\n });\n };\n })(method);\n }\n setproto.attr = function (name, value) {\n if (name && R.is(name, array) && R.is(name[0], \"object\")) {\n for (var j = 0, jj = name.length; j < jj; j++) {\n this.items[j].attr(name[j]);\n }\n } else {\n for (var i = 0, ii = this.items.length; i < ii; i++) {\n this.items[i].attr(name, value);\n }\n }\n return this;\n };\n /*\\\n * Set.clear\n [ method ]\n **\n * Removes all elements from the set\n \\*/\n setproto.clear = function () {\n while (this.length) {\n this.pop();\n }\n };\n /*\\\n * Set.splice\n [ method ]\n **\n * Removes given element from the set\n **\n > Parameters\n **\n - index (number) position of the deletion\n - count (number) number of element to remove\n - insertion… (object) #optional elements to insert\n = (object) set elements that were deleted\n \\*/\n setproto.splice = function (index, count, insertion) {\n index = index < 0 ? mmax(this.length + index, 0) : index;\n count = mmax(0, mmin(this.length - index, count));\n var tail = [],\n todel = [],\n args = [],\n i;\n for (i = 2; i < arguments.length; i++) {\n args.push(arguments[i]);\n }\n for (i = 0; i < count; i++) {\n todel.push(this[index + i]);\n }\n for (; i < this.length - index; i++) {\n tail.push(this[index + i]);\n }\n var arglen = args.length;\n for (i = 0; i < arglen + tail.length; i++) {\n this.items[index + i] = this[index + i] = i < arglen ? args[i] : tail[i - arglen];\n }\n i = this.items.length = this.length -= count - arglen;\n while (this[i]) {\n delete this[i++];\n }\n return new Set(todel);\n };\n /*\\\n * Set.exclude\n [ method ]\n **\n * Removes given element from the set\n **\n > Parameters\n **\n - element (object) element to remove\n = (boolean) `true` if object was found & removed from the set\n \\*/\n setproto.exclude = function (el) {\n for (var i = 0, ii = this.length; i < ii; i++) if (this[i] == el) {\n this.splice(i, 1);\n return true;\n }\n };\n setproto.animate = function (params, ms, easing, callback) {\n (R.is(easing, \"function\") || !easing) && (callback = easing || null);\n var len = this.items.length,\n i = len,\n item,\n set = this,\n collector;\n if (!len) {\n return this;\n }\n callback && (collector = function () {\n !--len && callback.call(set);\n });\n easing = R.is(easing, string) ? easing : collector;\n var anim = R.animation(params, ms, easing, collector);\n item = this.items[--i].animate(anim);\n while (i--) {\n this.items[i] && !this.items[i].removed && this.items[i].animateWith(item, anim, anim);\n (this.items[i] && !this.items[i].removed) || len--;\n }\n return this;\n };\n setproto.insertAfter = function (el) {\n var i = this.items.length;\n while (i--) {\n this.items[i].insertAfter(el);\n }\n return this;\n };\n setproto.getBBox = function () {\n var x = [],\n y = [],\n x2 = [],\n y2 = [];\n for (var i = this.items.length; i--;) if (!this.items[i].removed) {\n var box = this.items[i].getBBox();\n x.push(box.x);\n y.push(box.y);\n x2.push(box.x + box.width);\n y2.push(box.y + box.height);\n }\n x = mmin[apply](0, x);\n y = mmin[apply](0, y);\n x2 = mmax[apply](0, x2);\n y2 = mmax[apply](0, y2);\n return {\n x: x,\n y: y,\n x2: x2,\n y2: y2,\n width: x2 - x,\n height: y2 - y\n };\n };\n setproto.clone = function (s) {\n s = this.paper.set();\n for (var i = 0, ii = this.items.length; i < ii; i++) {\n s.push(this.items[i].clone());\n }\n return s;\n };\n setproto.toString = function () {\n return \"Rapha\\xebl\\u2018s set\";\n };\n\n setproto.glow = function(glowConfig) {\n var ret = this.paper.set();\n this.forEach(function(shape, index){\n var g = shape.glow(glowConfig);\n if(g != null){\n g.forEach(function(shape2, index2){\n ret.push(shape2);\n });\n }\n });\n return ret;\n };\n\n\n /*\\\n * Set.isPointInside\n [ method ]\n **\n * Determine if given point is inside this set’s elements\n **\n > Parameters\n **\n - x (number) x coordinate of the point\n - y (number) y coordinate of the point\n = (boolean) `true` if point is inside any of the set's elements\n \\*/\n setproto.isPointInside = function (x, y) {\n var isPointInside = false;\n this.forEach(function (el) {\n if (el.isPointInside(x, y)) {\n isPointInside = true;\n return false; // stop loop\n }\n });\n return isPointInside;\n };\n\n /*\\\n * Raphael.registerFont\n [ method ]\n **\n * Adds given font to the registered set of fonts for Raphaël. Should be used as an internal call from within Cufón’s font file.\n * Returns original parameter, so it could be used with chaining.\n # More about Cufón and how to convert your font form TTF, OTF, etc to JavaScript file.\n **\n > Parameters\n **\n - font (object) the font to register\n = (object) the font you passed in\n > Usage\n | Cufon.registerFont(Raphael.registerFont({…}));\n \\*/\n R.registerFont = function (font) {\n if (!font.face) {\n return font;\n }\n this.fonts = this.fonts || {};\n var fontcopy = {\n w: font.w,\n face: {},\n glyphs: {}\n },\n family = font.face[\"font-family\"];\n for (var prop in font.face) if (font.face[has](prop)) {\n fontcopy.face[prop] = font.face[prop];\n }\n if (this.fonts[family]) {\n this.fonts[family].push(fontcopy);\n } else {\n this.fonts[family] = [fontcopy];\n }\n if (!font.svg) {\n fontcopy.face[\"units-per-em\"] = toInt(font.face[\"units-per-em\"], 10);\n for (var glyph in font.glyphs) if (font.glyphs[has](glyph)) {\n var path = font.glyphs[glyph];\n fontcopy.glyphs[glyph] = {\n w: path.w,\n k: {},\n d: path.d && \"M\" + path.d.replace(/[mlcxtrv]/g, function (command) {\n return {l: \"L\", c: \"C\", x: \"z\", t: \"m\", r: \"l\", v: \"c\"}[command] || \"M\";\n }) + \"z\"\n };\n if (path.k) {\n for (var k in path.k) if (path[has](k)) {\n fontcopy.glyphs[glyph].k[k] = path.k[k];\n }\n }\n }\n }\n return font;\n };\n /*\\\n * Paper.getFont\n [ method ]\n **\n * Finds font object in the registered fonts by given parameters. You could specify only one word from the font name, like “Myriad” for “Myriad Pro”.\n **\n > Parameters\n **\n - family (string) font family name or any word from it\n - weight (string) #optional font weight\n - style (string) #optional font style\n - stretch (string) #optional font stretch\n = (object) the font object\n > Usage\n | paper.print(100, 100, \"Test string\", paper.getFont(\"Times\", 800), 30);\n \\*/\n paperproto.getFont = function (family, weight, style, stretch) {\n stretch = stretch || \"normal\";\n style = style || \"normal\";\n weight = +weight || {normal: 400, bold: 700, lighter: 300, bolder: 800}[weight] || 400;\n if (!R.fonts) {\n return;\n }\n var font = R.fonts[family];\n if (!font) {\n var name = new RegExp(\"(^|\\\\s)\" + family.replace(/[^\\w\\d\\s+!~.:_-]/g, E) + \"(\\\\s|$)\", \"i\");\n for (var fontName in R.fonts) if (R.fonts[has](fontName)) {\n if (name.test(fontName)) {\n font = R.fonts[fontName];\n break;\n }\n }\n }\n var thefont;\n if (font) {\n for (var i = 0, ii = font.length; i < ii; i++) {\n thefont = font[i];\n if (thefont.face[\"font-weight\"] == weight && (thefont.face[\"font-style\"] == style || !thefont.face[\"font-style\"]) && thefont.face[\"font-stretch\"] == stretch) {\n break;\n }\n }\n }\n return thefont;\n };\n /*\\\n * Paper.print\n [ method ]\n **\n * Creates path that represent given text written using given font at given position with given size.\n * Result of the method is path element that contains whole text as a separate path.\n **\n > Parameters\n **\n - x (number) x position of the text\n - y (number) y position of the text\n - string (string) text to print\n - font (object) font object, see @Paper.getFont\n - size (number) #optional size of the font, default is `16`\n - origin (string) #optional could be `\"baseline\"` or `\"middle\"`, default is `\"middle\"`\n - letter_spacing (number) #optional number in range `-1..1`, default is `0`\n - line_spacing (number) #optional number in range `1..3`, default is `1`\n = (object) resulting path element, which consist of all letters\n > Usage\n | var txt = r.print(10, 50, \"print\", r.getFont(\"Museo\"), 30).attr({fill: \"#fff\"});\n \\*/\n paperproto.print = function (x, y, string, font, size, origin, letter_spacing, line_spacing) {\n origin = origin || \"middle\"; // baseline|middle\n letter_spacing = mmax(mmin(letter_spacing || 0, 1), -1);\n line_spacing = mmax(mmin(line_spacing || 1, 3), 1);\n var letters = Str(string)[split](E),\n shift = 0,\n notfirst = 0,\n path = E,\n scale;\n R.is(font, \"string\") && (font = this.getFont(font));\n if (font) {\n scale = (size || 16) / font.face[\"units-per-em\"];\n var bb = font.face.bbox[split](separator),\n top = +bb[0],\n lineHeight = bb[3] - bb[1],\n shifty = 0,\n height = +bb[1] + (origin == \"baseline\" ? lineHeight + (+font.face.descent) : lineHeight / 2);\n for (var i = 0, ii = letters.length; i < ii; i++) {\n if (letters[i] == \"\\n\") {\n shift = 0;\n curr = 0;\n notfirst = 0;\n shifty += lineHeight * line_spacing;\n } else {\n var prev = notfirst && font.glyphs[letters[i - 1]] || {},\n curr = font.glyphs[letters[i]];\n shift += notfirst ? (prev.w || font.w) + (prev.k && prev.k[letters[i]] || 0) + (font.w * letter_spacing) : 0;\n notfirst = 1;\n }\n if (curr && curr.d) {\n path += R.transformPath(curr.d, [\"t\", shift * scale, shifty * scale, \"s\", scale, scale, top, height, \"t\", (x - top) / scale, (y - height) / scale]);\n }\n }\n }\n return this.path(path).attr({\n fill: \"#000\",\n stroke: \"none\"\n });\n };\n\n /*\\\n * Paper.add\n [ method ]\n **\n * Imports elements in JSON array in format `{type: type, }`\n **\n > Parameters\n **\n - json (array)\n = (object) resulting set of imported elements\n > Usage\n | paper.add([\n | {\n | type: \"circle\",\n | cx: 10,\n | cy: 10,\n | r: 5\n | },\n | {\n | type: \"rect\",\n | x: 10,\n | y: 10,\n | width: 10,\n | height: 10,\n | fill: \"#fc0\"\n | }\n | ]);\n \\*/\n paperproto.add = function (json) {\n if (R.is(json, \"array\")) {\n var res = this.set(),\n i = 0,\n ii = json.length,\n j;\n for (; i < ii; i++) {\n j = json[i] || {};\n elements[has](j.type) && res.push(this[j.type]().attr(j));\n }\n }\n return res;\n };\n\n /*\\\n * Raphael.format\n [ method ]\n **\n * Simple format function. Replaces construction of type “`{}`” to the corresponding argument.\n **\n > Parameters\n **\n - token (string) string to format\n - … (string) rest of arguments will be treated as parameters for replacement\n = (string) formated string\n > Usage\n | var x = 10,\n | y = 20,\n | width = 40,\n | height = 50;\n | // this will draw a rectangular shape equivalent to \"M10,20h40v50h-40z\"\n | paper.path(Raphael.format(\"M{0},{1}h{2}v{3}h{4}z\", x, y, width, height, -width));\n \\*/\n R.format = function (token, params) {\n var args = R.is(params, array) ? [0][concat](params) : arguments;\n token && R.is(token, string) && args.length - 1 && (token = token.replace(formatrg, function (str, i) {\n return args[++i] == null ? E : args[i];\n }));\n return token || E;\n };\n /*\\\n * Raphael.fullfill\n [ method ]\n **\n * A little bit more advanced format function than @Raphael.format. Replaces construction of type “`{}`” to the corresponding argument.\n **\n > Parameters\n **\n - token (string) string to format\n - json (object) object which properties will be used as a replacement\n = (string) formated string\n > Usage\n | // this will draw a rectangular shape equivalent to \"M10,20h40v50h-40z\"\n | paper.path(Raphael.fullfill(\"M{x},{y}h{dim.width}v{dim.height}h{dim['negative width']}z\", {\n | x: 10,\n | y: 20,\n | dim: {\n | width: 40,\n | height: 50,\n | \"negative width\": -40\n | }\n | }));\n \\*/\n R.fullfill = (function () {\n var tokenRegex = /\\{([^\\}]+)\\}/g,\n objNotationRegex = /(?:(?:^|\\.)(.+?)(?=\\[|\\.|$|\\()|\\[('|\")(.+?)\\2\\])(\\(\\))?/g, // matches .xxxxx or [\"xxxxx\"] to run over object properties\n replacer = function (all, key, obj) {\n var res = obj;\n key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) {\n name = name || quotedName;\n if (res) {\n if (name in res) {\n res = res[name];\n }\n typeof res == \"function\" && isFunc && (res = res());\n }\n });\n res = (res == null || res == obj ? all : res) + \"\";\n return res;\n };\n return function (str, obj) {\n return String(str).replace(tokenRegex, function (all, key) {\n return replacer(all, key, obj);\n });\n };\n })();\n /*\\\n * Raphael.ninja\n [ method ]\n **\n * If you want to leave no trace of Raphaël (Well, Raphaël creates only one global variable `Raphael`, but anyway.) You can use `ninja` method.\n * Beware, that in this case plugins could stop working, because they are depending on global variable existence.\n **\n = (object) Raphael object\n > Usage\n | (function (local_raphael) {\n | var paper = local_raphael(10, 10, 320, 200);\n | …\n | })(Raphael.ninja());\n \\*/\n R.ninja = function () {\n if (oldRaphael.was) {\n g.win.Raphael = oldRaphael.is;\n } else {\n // IE8 raises an error when deleting window property\n window.Raphael = undefined;\n try {\n delete window.Raphael;\n } catch(e) {}\n }\n return R;\n };\n /*\\\n * Raphael.st\n [ property (object) ]\n **\n * You can add your own method to elements and sets. It is wise to add a set method for each element method\n * you added, so you will be able to call the same method on sets too.\n **\n * See also @Raphael.el.\n > Usage\n | Raphael.el.red = function () {\n | this.attr({fill: \"#f00\"});\n | };\n | Raphael.st.red = function () {\n | this.forEach(function (el) {\n | el.red();\n | });\n | };\n | // then use it\n | paper.set(paper.circle(100, 100, 20), paper.circle(110, 100, 20)).red();\n \\*/\n R.st = setproto;\n\n eve.on(\"raphael.DOMload\", function () {\n loaded = true;\n });\n\n // Firefox <3.6 fix: http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html\n (function (doc, loaded, f) {\n if (doc.readyState == null && doc.addEventListener){\n doc.addEventListener(loaded, f = function () {\n doc.removeEventListener(loaded, f, false);\n doc.readyState = \"complete\";\n }, false);\n doc.readyState = \"loading\";\n }\n function isLoaded() {\n (/in/).test(doc.readyState) ? setTimeout(isLoaded, 9) : R.eve(\"raphael.DOMload\");\n }\n isLoaded();\n })(document, \"DOMContentLoaded\");\n\n return R;\n}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9kZXYvcmFwaGFlbC5jb3JlLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vUmFwaGFlbC8uL2Rldi9yYXBoYWVsLmNvcmUuanM/OTRkOSJdLCJzb3VyY2VzQ29udGVudCI6WyJkZWZpbmUoW1wiZXZlXCJdLCBmdW5jdGlvbihldmUpIHtcblxuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBDcmVhdGVzIGEgY2FudmFzIG9iamVjdCBvbiB3aGljaCB0byBkcmF3LlxuICAgICAqIFlvdSBtdXN0IGRvIHRoaXMgZmlyc3QsIGFzIGFsbCBmdXR1cmUgY2FsbHMgdG8gZHJhd2luZyBtZXRob2RzXG4gICAgICogZnJvbSB0aGlzIGluc3RhbmNlIHdpbGwgYmUgYm91bmQgdG8gdGhpcyBjYW52YXMuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGNvbnRhaW5lciAoSFRNTEVsZW1lbnR8c3RyaW5nKSBET00gZWxlbWVudCBvciBpdHMgSUQgd2hpY2ggaXMgZ29pbmcgdG8gYmUgYSBwYXJlbnQgZm9yIGRyYXdpbmcgc3VyZmFjZVxuICAgICAtIHdpZHRoIChudW1iZXIpXG4gICAgIC0gaGVpZ2h0IChudW1iZXIpXG4gICAgIC0gY2FsbGJhY2sgKGZ1bmN0aW9uKSAjb3B0aW9uYWwgY2FsbGJhY2sgZnVuY3Rpb24gd2hpY2ggaXMgZ29pbmcgdG8gYmUgZXhlY3V0ZWQgaW4gdGhlIGNvbnRleHQgb2YgbmV3bHkgY3JlYXRlZCBwYXBlclxuICAgICAqIG9yXG4gICAgIC0geCAobnVtYmVyKVxuICAgICAtIHkgKG51bWJlcilcbiAgICAgLSB3aWR0aCAobnVtYmVyKVxuICAgICAtIGhlaWdodCAobnVtYmVyKVxuICAgICAtIGNhbGxiYWNrIChmdW5jdGlvbikgI29wdGlvbmFsIGNhbGxiYWNrIGZ1bmN0aW9uIHdoaWNoIGlzIGdvaW5nIHRvIGJlIGV4ZWN1dGVkIGluIHRoZSBjb250ZXh0IG9mIG5ld2x5IGNyZWF0ZWQgcGFwZXJcbiAgICAgKiBvclxuICAgICAtIGFsbCAoYXJyYXkpIChmaXJzdCAzIG9yIDQgZWxlbWVudHMgaW4gdGhlIGFycmF5IGFyZSBlcXVhbCB0byBbY29udGFpbmVySUQsIHdpZHRoLCBoZWlnaHRdIG9yIFt4LCB5LCB3aWR0aCwgaGVpZ2h0XS4gVGhlIHJlc3QgYXJlIGVsZW1lbnQgZGVzY3JpcHRpb25zIGluIGZvcm1hdCB7dHlwZTogdHlwZSwgPGF0dHJpYnV0ZXM+fSkuIFNlZSBAUGFwZXIuYWRkLlxuICAgICAtIGNhbGxiYWNrIChmdW5jdGlvbikgI29wdGlvbmFsIGNhbGxiYWNrIGZ1bmN0aW9uIHdoaWNoIGlzIGdvaW5nIHRvIGJlIGV4ZWN1dGVkIGluIHRoZSBjb250ZXh0IG9mIG5ld2x5IGNyZWF0ZWQgcGFwZXJcbiAgICAgKiBvclxuICAgICAtIG9uUmVhZHlDYWxsYmFjayAoZnVuY3Rpb24pIGZ1bmN0aW9uIHRoYXQgaXMgZ29pbmcgdG8gYmUgY2FsbGVkIG9uIERPTSByZWFkeSBldmVudC4gWW91IGNhbiBhbHNvIHN1YnNjcmliZSB0byB0aGlzIGV2ZW50IHZpYSBFdmXigJlzIOKAnERPTUxvYWTigJ0gZXZlbnQuIEluIHRoaXMgY2FzZSBtZXRob2QgcmV0dXJucyBgdW5kZWZpbmVkYC5cbiAgICAgPSAob2JqZWN0KSBAUGFwZXJcbiAgICAgPiBVc2FnZVxuICAgICB8IC8vIEVhY2ggb2YgdGhlIGZvbGxvd2luZyBleGFtcGxlcyBjcmVhdGUgYSBjYW52YXNcbiAgICAgfCAvLyB0aGF0IGlzIDMyMHB4IHdpZGUgYnkgMjAwcHggaGlnaC5cbiAgICAgfCAvLyBDYW52YXMgaXMgY3JlYXRlZCBhdCB0aGUgdmlld3BvcnTigJlzIDEwLDUwIGNvb3JkaW5hdGUuXG4gICAgIHwgdmFyIHBhcGVyID0gUmFwaGFlbCgxMCwgNTAsIDMyMCwgMjAwKTtcbiAgICAgfCAvLyBDYW52YXMgaXMgY3JlYXRlZCBhdCB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSAjbm90ZXBhZCBlbGVtZW50XG4gICAgIHwgLy8gKG9yIGl0cyB0b3AgcmlnaHQgY29ybmVyIGluIGRpcj1cInJ0bFwiIGVsZW1lbnRzKVxuICAgICB8IHZhciBwYXBlciA9IFJhcGhhZWwoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJub3RlcGFkXCIpLCAzMjAsIDIwMCk7XG4gICAgIHwgLy8gU2FtZSBhcyBhYm92ZVxuICAgICB8IHZhciBwYXBlciA9IFJhcGhhZWwoXCJub3RlcGFkXCIsIDMyMCwgMjAwKTtcbiAgICAgfCAvLyBJbWFnZSBkdW1wXG4gICAgIHwgdmFyIHNldCA9IFJhcGhhZWwoW1wibm90ZXBhZFwiLCAzMjAsIDIwMCwge1xuICAgICB8ICAgICB0eXBlOiBcInJlY3RcIixcbiAgICAgfCAgICAgeDogMTAsXG4gICAgIHwgICAgIHk6IDEwLFxuICAgICB8ICAgICB3aWR0aDogMjUsXG4gICAgIHwgICAgIGhlaWdodDogMjUsXG4gICAgIHwgICAgIHN0cm9rZTogXCIjZjAwXCJcbiAgICAgfCB9LCB7XG4gICAgIHwgICAgIHR5cGU6IFwidGV4dFwiLFxuICAgICB8ICAgICB4OiAzMCxcbiAgICAgfCAgICAgeTogNDAsXG4gICAgIHwgICAgIHRleHQ6IFwiRHVtcFwiXG4gICAgIHwgfV0pO1xuICAgIFxcKi9cbiAgICBmdW5jdGlvbiBSKGZpcnN0KSB7XG4gICAgICAgIGlmIChSLmlzKGZpcnN0LCBcImZ1bmN0aW9uXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gbG9hZGVkID8gZmlyc3QoKSA6IGV2ZS5vbihcInJhcGhhZWwuRE9NbG9hZFwiLCBmaXJzdCk7XG4gICAgICAgIH0gZWxzZSBpZiAoUi5pcyhmaXJzdCwgYXJyYXkpKSB7XG4gICAgICAgICAgICByZXR1cm4gUi5fZW5naW5lLmNyZWF0ZVthcHBseV0oUiwgZmlyc3Quc3BsaWNlKDAsIDMgKyBSLmlzKGZpcnN0WzBdLCBudSkpKS5hZGQoZmlyc3QpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuICAgICAgICAgICAgaWYgKFIuaXMoYXJnc1thcmdzLmxlbmd0aCAtIDFdLCBcImZ1bmN0aW9uXCIpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGYgPSBhcmdzLnBvcCgpO1xuICAgICAgICAgICAgICAgIHJldHVybiBsb2FkZWQgPyBmLmNhbGwoUi5fZW5naW5lLmNyZWF0ZVthcHBseV0oUiwgYXJncykpIDogZXZlLm9uKFwicmFwaGFlbC5ET01sb2FkXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgZi5jYWxsKFIuX2VuZ2luZS5jcmVhdGVbYXBwbHldKFIsIGFyZ3MpKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFIuX2VuZ2luZS5jcmVhdGVbYXBwbHldKFIsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgUi52ZXJzaW9uID0gXCIyLjIuMFwiO1xuICAgIFIuZXZlID0gZXZlO1xuICAgIHZhciBsb2FkZWQsXG4gICAgICAgIHNlcGFyYXRvciA9IC9bLCBdKy8sXG4gICAgICAgIGVsZW1lbnRzID0ge2NpcmNsZTogMSwgcmVjdDogMSwgcGF0aDogMSwgZWxsaXBzZTogMSwgdGV4dDogMSwgaW1hZ2U6IDF9LFxuICAgICAgICBmb3JtYXRyZyA9IC9cXHsoXFxkKylcXH0vZyxcbiAgICAgICAgcHJvdG8gPSBcInByb3RvdHlwZVwiLFxuICAgICAgICBoYXMgPSBcImhhc093blByb3BlcnR5XCIsXG4gICAgICAgIGcgPSB7XG4gICAgICAgICAgICBkb2M6IGRvY3VtZW50LFxuICAgICAgICAgICAgd2luOiB3aW5kb3dcbiAgICAgICAgfSxcbiAgICAgICAgb2xkUmFwaGFlbCA9IHtcbiAgICAgICAgICAgIHdhczogT2JqZWN0LnByb3RvdHlwZVtoYXNdLmNhbGwoZy53aW4sIFwiUmFwaGFlbFwiKSxcbiAgICAgICAgICAgIGlzOiBnLndpbi5SYXBoYWVsXG4gICAgICAgIH0sXG4gICAgICAgIFBhcGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLypcXFxuICAgICAgICAgICAgICogUGFwZXIuY2FcbiAgICAgICAgICAgICBbIHByb3BlcnR5IChvYmplY3QpIF1cbiAgICAgICAgICAgICAqKlxuICAgICAgICAgICAgICogU2hvcnRjdXQgZm9yIEBQYXBlci5jdXN0b21BdHRyaWJ1dGVzXG4gICAgICAgICAgICBcXCovXG4gICAgICAgICAgICAvKlxcXG4gICAgICAgICAgICAgKiBQYXBlci5jdXN0b21BdHRyaWJ1dGVzXG4gICAgICAgICAgICAgWyBwcm9wZXJ0eSAob2JqZWN0KSBdXG4gICAgICAgICAgICAgKipcbiAgICAgICAgICAgICAqIElmIHlvdSBoYXZlIGEgc2V0IG9mIGF0dHJpYnV0ZXMgdGhhdCB5b3Ugd291bGQgbGlrZSB0byByZXByZXNlbnRcbiAgICAgICAgICAgICAqIGFzIGEgZnVuY3Rpb24gb2Ygc29tZSBudW1iZXIgeW91IGNhbiBkbyBpdCBlYXNpbHkgd2l0aCBjdXN0b20gYXR0cmlidXRlczpcbiAgICAgICAgICAgICA+IFVzYWdlXG4gICAgICAgICAgICAgfCBwYXBlci5jdXN0b21BdHRyaWJ1dGVzLmh1ZSA9IGZ1bmN0aW9uIChudW0pIHtcbiAgICAgICAgICAgICB8ICAgICBudW0gPSBudW0gJSAxO1xuICAgICAgICAgICAgIHwgICAgIHJldHVybiB7ZmlsbDogXCJoc2IoXCIgKyBudW0gKyBcIiwgMC43NSwgMSlcIn07XG4gICAgICAgICAgICAgfCB9O1xuICAgICAgICAgICAgIHwgLy8gQ3VzdG9tIGF0dHJpYnV0ZSDigJxodWXigJ0gd2lsbCBjaGFuZ2UgZmlsbFxuICAgICAgICAgICAgIHwgLy8gdG8gYmUgZ2l2ZW4gaHVlIHdpdGggZml4ZWQgc2F0dXJhdGlvbiBhbmQgYnJpZ2h0bmVzcy5cbiAgICAgICAgICAgICB8IC8vIE5vdyB5b3UgY2FuIHVzZSBpdCBsaWtlIHRoaXM6XG4gICAgICAgICAgICAgfCB2YXIgYyA9IHBhcGVyLmNpcmNsZSgxMCwgMTAsIDEwKS5hdHRyKHtodWU6IC40NX0pO1xuICAgICAgICAgICAgIHwgLy8gb3IgZXZlbiBsaWtlIHRoaXM6XG4gICAgICAgICAgICAgfCBjLmFuaW1hdGUoe2h1ZTogMX0sIDFlMyk7XG4gICAgICAgICAgICAgfFxuICAgICAgICAgICAgIHwgLy8gWW91IGNvdWxkIGFsc28gY3JlYXRlIGN1c3RvbSBhdHRyaWJ1dGVcbiAgICAgICAgICAgICB8IC8vIHdpdGggbXVsdGlwbGUgcGFyYW1ldGVyczpcbiAgICAgICAgICAgICB8IHBhcGVyLmN1c3RvbUF0dHJpYnV0ZXMuaHNiID0gZnVuY3Rpb24gKGgsIHMsIGIpIHtcbiAgICAgICAgICAgICB8ICAgICByZXR1cm4ge2ZpbGw6IFwiaHNiKFwiICsgW2gsIHMsIGJdLmpvaW4oXCIsXCIpICsgXCIpXCJ9O1xuICAgICAgICAgICAgIHwgfTtcbiAgICAgICAgICAgICB8IGMuYXR0cih7aHNiOiBcIjAuNSAuOCAxXCJ9KTtcbiAgICAgICAgICAgICB8IGMuYW5pbWF0ZSh7aHNiOiBbMSwgMCwgMC41XX0sIDFlMyk7XG4gICAgICAgICAgICBcXCovXG4gICAgICAgICAgICB0aGlzLmNhID0gdGhpcy5jdXN0b21BdHRyaWJ1dGVzID0ge307XG4gICAgICAgIH0sXG4gICAgICAgIHBhcGVycHJvdG8sXG4gICAgICAgIGFwcGVuZENoaWxkID0gXCJhcHBlbmRDaGlsZFwiLFxuICAgICAgICBhcHBseSA9IFwiYXBwbHlcIixcbiAgICAgICAgY29uY2F0ID0gXCJjb25jYXRcIixcbiAgICAgICAgc3VwcG9ydHNUb3VjaCA9ICgnb250b3VjaHN0YXJ0JyBpbiBnLndpbikgfHwgZy53aW4uRG9jdW1lbnRUb3VjaCAmJiBnLmRvYyBpbnN0YW5jZW9mIERvY3VtZW50VG91Y2gsIC8vdGFrZW4gZnJvbSBNb2Rlcm5penIgdG91Y2ggdGVzdFxuICAgICAgICBFID0gXCJcIixcbiAgICAgICAgUyA9IFwiIFwiLFxuICAgICAgICBTdHIgPSBTdHJpbmcsXG4gICAgICAgIHNwbGl0ID0gXCJzcGxpdFwiLFxuICAgICAgICBldmVudHMgPSBcImNsaWNrIGRibGNsaWNrIG1vdXNlZG93biBtb3VzZW1vdmUgbW91c2VvdXQgbW91c2VvdmVyIG1vdXNldXAgdG91Y2hzdGFydCB0b3VjaG1vdmUgdG91Y2hlbmQgdG91Y2hjYW5jZWxcIltzcGxpdF0oUyksXG4gICAgICAgIHRvdWNoTWFwID0ge1xuICAgICAgICAgICAgbW91c2Vkb3duOiBcInRvdWNoc3RhcnRcIixcbiAgICAgICAgICAgIG1vdXNlbW92ZTogXCJ0b3VjaG1vdmVcIixcbiAgICAgICAgICAgIG1vdXNldXA6IFwidG91Y2hlbmRcIlxuICAgICAgICB9LFxuICAgICAgICBsb3dlckNhc2UgPSBTdHIucHJvdG90eXBlLnRvTG93ZXJDYXNlLFxuICAgICAgICBtYXRoID0gTWF0aCxcbiAgICAgICAgbW1heCA9IG1hdGgubWF4LFxuICAgICAgICBtbWluID0gbWF0aC5taW4sXG4gICAgICAgIGFicyA9IG1hdGguYWJzLFxuICAgICAgICBwb3cgPSBtYXRoLnBvdyxcbiAgICAgICAgUEkgPSBtYXRoLlBJLFxuICAgICAgICBudSA9IFwibnVtYmVyXCIsXG4gICAgICAgIHN0cmluZyA9IFwic3RyaW5nXCIsXG4gICAgICAgIGFycmF5ID0gXCJhcnJheVwiLFxuICAgICAgICB0b1N0cmluZyA9IFwidG9TdHJpbmdcIixcbiAgICAgICAgZmlsbFN0cmluZyA9IFwiZmlsbFwiLFxuICAgICAgICBvYmplY3RUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcsXG4gICAgICAgIHBhcGVyID0ge30sXG4gICAgICAgIHB1c2ggPSBcInB1c2hcIixcbiAgICAgICAgSVNVUkwgPSBSLl9JU1VSTCA9IC9edXJsXFwoWydcIl0/KC4rPylbJ1wiXT9cXCkkL2ksXG4gICAgICAgIGNvbG91clJlZ0V4cCA9IC9eXFxzKigoI1thLWZcXGRdezZ9KXwoI1thLWZcXGRdezN9KXxyZ2JhP1xcKFxccyooW1xcZFxcLl0rJT9cXHMqLFxccypbXFxkXFwuXSslP1xccyosXFxzKltcXGRcXC5dKyU/KD86XFxzKixcXHMqW1xcZFxcLl0rJT8pPylcXHMqXFwpfGhzYmE/XFwoXFxzKihbXFxkXFwuXSsoPzpkZWd8XFx4YjB8JSk/XFxzKixcXHMqW1xcZFxcLl0rJT9cXHMqLFxccypbXFxkXFwuXSsoPzolP1xccyosXFxzKltcXGRcXC5dKyk/KSU/XFxzKlxcKXxoc2xhP1xcKFxccyooW1xcZFxcLl0rKD86ZGVnfFxceGIwfCUpP1xccyosXFxzKltcXGRcXC5dKyU/XFxzKixcXHMqW1xcZFxcLl0rKD86JT9cXHMqLFxccypbXFxkXFwuXSspPyklP1xccypcXCkpXFxzKiQvaSxcbiAgICAgICAgaXNuYW4gPSB7XCJOYU5cIjogMSwgXCJJbmZpbml0eVwiOiAxLCBcIi1JbmZpbml0eVwiOiAxfSxcbiAgICAgICAgYmV6aWVycmcgPSAvXig/OmN1YmljLSk/YmV6aWVyXFwoKFteLF0rKSwoW14sXSspLChbXixdKyksKFteXFwpXSspXFwpLyxcbiAgICAgICAgcm91bmQgPSBtYXRoLnJvdW5kLFxuICAgICAgICBzZXRBdHRyaWJ1dGUgPSBcInNldEF0dHJpYnV0ZVwiLFxuICAgICAgICB0b0Zsb2F0ID0gcGFyc2VGbG9hdCxcbiAgICAgICAgdG9JbnQgPSBwYXJzZUludCxcbiAgICAgICAgdXBwZXJDYXNlID0gU3RyLnByb3RvdHlwZS50b1VwcGVyQ2FzZSxcbiAgICAgICAgYXZhaWxhYmxlQXR0cnMgPSBSLl9hdmFpbGFibGVBdHRycyA9IHtcbiAgICAgICAgICAgIFwiYXJyb3ctZW5kXCI6IFwibm9uZVwiLFxuICAgICAgICAgICAgXCJhcnJvdy1zdGFydFwiOiBcIm5vbmVcIixcbiAgICAgICAgICAgIGJsdXI6IDAsXG4gICAgICAgICAgICBcImNsaXAtcmVjdFwiOiBcIjAgMCAxZTkgMWU5XCIsXG4gICAgICAgICAgICBjdXJzb3I6IFwiZGVmYXVsdFwiLFxuICAgICAgICAgICAgY3g6IDAsXG4gICAgICAgICAgICBjeTogMCxcbiAgICAgICAgICAgIGZpbGw6IFwiI2ZmZlwiLFxuICAgICAgICAgICAgXCJmaWxsLW9wYWNpdHlcIjogMSxcbiAgICAgICAgICAgIGZvbnQ6ICcxMHB4IFwiQXJpYWxcIicsXG4gICAgICAgICAgICBcImZvbnQtZmFtaWx5XCI6ICdcIkFyaWFsXCInLFxuICAgICAgICAgICAgXCJmb250LXNpemVcIjogXCIxMFwiLFxuICAgICAgICAgICAgXCJmb250LXN0eWxlXCI6IFwibm9ybWFsXCIsXG4gICAgICAgICAgICBcImZvbnQtd2VpZ2h0XCI6IDQwMCxcbiAgICAgICAgICAgIGdyYWRpZW50OiAwLFxuICAgICAgICAgICAgaGVpZ2h0OiAwLFxuICAgICAgICAgICAgaHJlZjogXCJodHRwOi8vcmFwaGFlbGpzLmNvbS9cIixcbiAgICAgICAgICAgIFwibGV0dGVyLXNwYWNpbmdcIjogMCxcbiAgICAgICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICAgICAgICBwYXRoOiBcIk0wLDBcIixcbiAgICAgICAgICAgIHI6IDAsXG4gICAgICAgICAgICByeDogMCxcbiAgICAgICAgICAgIHJ5OiAwLFxuICAgICAgICAgICAgc3JjOiBcIlwiLFxuICAgICAgICAgICAgc3Ryb2tlOiBcIiMwMDBcIixcbiAgICAgICAgICAgIFwic3Ryb2tlLWRhc2hhcnJheVwiOiBcIlwiLFxuICAgICAgICAgICAgXCJzdHJva2UtbGluZWNhcFwiOiBcImJ1dHRcIixcbiAgICAgICAgICAgIFwic3Ryb2tlLWxpbmVqb2luXCI6IFwiYnV0dFwiLFxuICAgICAgICAgICAgXCJzdHJva2UtbWl0ZXJsaW1pdFwiOiAwLFxuICAgICAgICAgICAgXCJzdHJva2Utb3BhY2l0eVwiOiAxLFxuICAgICAgICAgICAgXCJzdHJva2Utd2lkdGhcIjogMSxcbiAgICAgICAgICAgIHRhcmdldDogXCJfYmxhbmtcIixcbiAgICAgICAgICAgIFwidGV4dC1hbmNob3JcIjogXCJtaWRkbGVcIixcbiAgICAgICAgICAgIHRpdGxlOiBcIlJhcGhhZWxcIixcbiAgICAgICAgICAgIHRyYW5zZm9ybTogXCJcIixcbiAgICAgICAgICAgIHdpZHRoOiAwLFxuICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgIHk6IDAsXG4gICAgICAgICAgICBcImNsYXNzXCI6IFwiXCJcbiAgICAgICAgfSxcbiAgICAgICAgYXZhaWxhYmxlQW5pbUF0dHJzID0gUi5fYXZhaWxhYmxlQW5pbUF0dHJzID0ge1xuICAgICAgICAgICAgYmx1cjogbnUsXG4gICAgICAgICAgICBcImNsaXAtcmVjdFwiOiBcImNzdlwiLFxuICAgICAgICAgICAgY3g6IG51LFxuICAgICAgICAgICAgY3k6IG51LFxuICAgICAgICAgICAgZmlsbDogXCJjb2xvdXJcIixcbiAgICAgICAgICAgIFwiZmlsbC1vcGFjaXR5XCI6IG51LFxuICAgICAgICAgICAgXCJmb250LXNpemVcIjogbnUsXG4gICAgICAgICAgICBoZWlnaHQ6IG51LFxuICAgICAgICAgICAgb3BhY2l0eTogbnUsXG4gICAgICAgICAgICBwYXRoOiBcInBhdGhcIixcbiAgICAgICAgICAgIHI6IG51LFxuICAgICAgICAgICAgcng6IG51LFxuICAgICAgICAgICAgcnk6IG51LFxuICAgICAgICAgICAgc3Ryb2tlOiBcImNvbG91clwiLFxuICAgICAgICAgICAgXCJzdHJva2Utb3BhY2l0eVwiOiBudSxcbiAgICAgICAgICAgIFwic3Ryb2tlLXdpZHRoXCI6IG51LFxuICAgICAgICAgICAgdHJhbnNmb3JtOiBcInRyYW5zZm9ybVwiLFxuICAgICAgICAgICAgd2lkdGg6IG51LFxuICAgICAgICAgICAgeDogbnUsXG4gICAgICAgICAgICB5OiBudVxuICAgICAgICB9LFxuICAgICAgICB3aGl0ZXNwYWNlID0gL1tcXHgwOVxceDBhXFx4MGJcXHgwY1xceDBkXFx4MjBcXHhhMFxcdTE2ODBcXHUxODBlXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwM1xcdTIwMDRcXHUyMDA1XFx1MjAwNlxcdTIwMDdcXHUyMDA4XFx1MjAwOVxcdTIwMGFcXHUyMDJmXFx1MjA1ZlxcdTMwMDBcXHUyMDI4XFx1MjAyOV0vZyxcbiAgICAgICAgY29tbWFTcGFjZXMgPSAvW1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5XSosW1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5XSovLFxuICAgICAgICBoc3JnID0ge2hzOiAxLCByZzogMX0sXG4gICAgICAgIHAycyA9IC8sPyhbYWNobG1xcnN0dnh6XSksPy9naSxcbiAgICAgICAgcGF0aENvbW1hbmQgPSAvKFthY2hsbXJxc3R2el0pW1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5LF0qKCgtP1xcZCpcXC4/XFxkKig/OmVbXFwtK10/XFxkKyk/W1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5XSosP1tcXHgwOVxceDBhXFx4MGJcXHgwY1xceDBkXFx4MjBcXHhhMFxcdTE2ODBcXHUxODBlXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwM1xcdTIwMDRcXHUyMDA1XFx1MjAwNlxcdTIwMDdcXHUyMDA4XFx1MjAwOVxcdTIwMGFcXHUyMDJmXFx1MjA1ZlxcdTMwMDBcXHUyMDI4XFx1MjAyOV0qKSspL2lnLFxuICAgICAgICB0Q29tbWFuZCA9IC8oW3JzdG1dKVtcXHgwOVxceDBhXFx4MGJcXHgwY1xceDBkXFx4MjBcXHhhMFxcdTE2ODBcXHUxODBlXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwM1xcdTIwMDRcXHUyMDA1XFx1MjAwNlxcdTIwMDdcXHUyMDA4XFx1MjAwOVxcdTIwMGFcXHUyMDJmXFx1MjA1ZlxcdTMwMDBcXHUyMDI4XFx1MjAyOSxdKigoLT9cXGQqXFwuP1xcZCooPzplW1xcLStdP1xcZCspP1tcXHgwOVxceDBhXFx4MGJcXHgwY1xceDBkXFx4MjBcXHhhMFxcdTE2ODBcXHUxODBlXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwM1xcdTIwMDRcXHUyMDA1XFx1MjAwNlxcdTIwMDdcXHUyMDA4XFx1MjAwOVxcdTIwMGFcXHUyMDJmXFx1MjA1ZlxcdTMwMDBcXHUyMDI4XFx1MjAyOV0qLD9bXFx4MDlcXHgwYVxceDBiXFx4MGNcXHgwZFxceDIwXFx4YTBcXHUxNjgwXFx1MTgwZVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDNcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBhXFx1MjAyZlxcdTIwNWZcXHUzMDAwXFx1MjAyOFxcdTIwMjldKikrKS9pZyxcbiAgICAgICAgcGF0aFZhbHVlcyA9IC8oLT9cXGQqXFwuP1xcZCooPzplW1xcLStdP1xcZCspPylbXFx4MDlcXHgwYVxceDBiXFx4MGNcXHgwZFxceDIwXFx4YTBcXHUxNjgwXFx1MTgwZVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDNcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBhXFx1MjAyZlxcdTIwNWZcXHUzMDAwXFx1MjAyOFxcdTIwMjldKiw/W1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5XSovaWcsXG4gICAgICAgIHJhZGlhbF9ncmFkaWVudCA9IFIuX3JhZGlhbF9ncmFkaWVudCA9IC9ecig/OlxcKChbXixdKz8pW1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5XSosW1xceDA5XFx4MGFcXHgwYlxceDBjXFx4MGRcXHgyMFxceGEwXFx1MTY4MFxcdTE4MGVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwYVxcdTIwMmZcXHUyMDVmXFx1MzAwMFxcdTIwMjhcXHUyMDI5XSooW15cXCldKz8pXFwpKT8vLFxuICAgICAgICBlbGRhdGEgPSB7fSxcbiAgICAgICAgc29ydEJ5S2V5ID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgIHJldHVybiBhLmtleSAtIGIua2V5O1xuICAgICAgICB9LFxuICAgICAgICBzb3J0QnlOdW1iZXIgPSBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgcmV0dXJuIHRvRmxvYXQoYSkgLSB0b0Zsb2F0KGIpO1xuICAgICAgICB9LFxuICAgICAgICBmdW4gPSBmdW5jdGlvbiAoKSB7fSxcbiAgICAgICAgcGlwZSA9IGZ1bmN0aW9uICh4KSB7XG4gICAgICAgICAgICByZXR1cm4geDtcbiAgICAgICAgfSxcbiAgICAgICAgcmVjdFBhdGggPSBSLl9yZWN0UGF0aCA9IGZ1bmN0aW9uICh4LCB5LCB3LCBoLCByKSB7XG4gICAgICAgICAgICBpZiAocikge1xuICAgICAgICAgICAgICAgIHJldHVybiBbW1wiTVwiLCB4ICsgciwgeV0sIFtcImxcIiwgdyAtIHIgKiAyLCAwXSwgW1wiYVwiLCByLCByLCAwLCAwLCAxLCByLCByXSwgW1wibFwiLCAwLCBoIC0gciAqIDJdLCBbXCJhXCIsIHIsIHIsIDAsIDAsIDEsIC1yLCByXSwgW1wibFwiLCByICogMiAtIHcsIDBdLCBbXCJhXCIsIHIsIHIsIDAsIDAsIDEsIC1yLCAtcl0sIFtcImxcIiwgMCwgciAqIDIgLSBoXSwgW1wiYVwiLCByLCByLCAwLCAwLCAxLCByLCAtcl0sIFtcInpcIl1dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFtbXCJNXCIsIHgsIHldLCBbXCJsXCIsIHcsIDBdLCBbXCJsXCIsIDAsIGhdLCBbXCJsXCIsIC13LCAwXSwgW1wielwiXV07XG4gICAgICAgIH0sXG4gICAgICAgIGVsbGlwc2VQYXRoID0gZnVuY3Rpb24gKHgsIHksIHJ4LCByeSkge1xuICAgICAgICAgICAgaWYgKHJ5ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByeSA9IHJ4O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFtbXCJNXCIsIHgsIHldLCBbXCJtXCIsIDAsIC1yeV0sIFtcImFcIiwgcngsIHJ5LCAwLCAxLCAxLCAwLCAyICogcnldLCBbXCJhXCIsIHJ4LCByeSwgMCwgMSwgMSwgMCwgLTIgKiByeV0sIFtcInpcIl1dO1xuICAgICAgICB9LFxuICAgICAgICBnZXRQYXRoID0gUi5fZ2V0UGF0aCA9IHtcbiAgICAgICAgICAgIHBhdGg6IGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBlbC5hdHRyKFwicGF0aFwiKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjaXJjbGU6IGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgICAgIHZhciBhID0gZWwuYXR0cnM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGVsbGlwc2VQYXRoKGEuY3gsIGEuY3ksIGEucik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZWxsaXBzZTogZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICAgICAgdmFyIGEgPSBlbC5hdHRycztcbiAgICAgICAgICAgICAgICByZXR1cm4gZWxsaXBzZVBhdGgoYS5jeCwgYS5jeSwgYS5yeCwgYS5yeSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVjdDogZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICAgICAgdmFyIGEgPSBlbC5hdHRycztcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVjdFBhdGgoYS54LCBhLnksIGEud2lkdGgsIGEuaGVpZ2h0LCBhLnIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGltYWdlOiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgICAgICB2YXIgYSA9IGVsLmF0dHJzO1xuICAgICAgICAgICAgICAgIHJldHVybiByZWN0UGF0aChhLngsIGEueSwgYS53aWR0aCwgYS5oZWlnaHQpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRleHQ6IGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgICAgIHZhciBiYm94ID0gZWwuX2dldEJCb3goKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVjdFBhdGgoYmJveC54LCBiYm94LnksIGJib3gud2lkdGgsIGJib3guaGVpZ2h0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgOiBmdW5jdGlvbihlbCkge1xuICAgICAgICAgICAgICAgIHZhciBiYm94ID0gZWwuX2dldEJCb3goKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVjdFBhdGgoYmJveC54LCBiYm94LnksIGJib3gud2lkdGgsIGJib3guaGVpZ2h0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgLypcXFxuICAgICAgICAgKiBSYXBoYWVsLm1hcFBhdGhcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICoqXG4gICAgICAgICAqIFRyYW5zZm9ybSB0aGUgcGF0aCBzdHJpbmcgd2l0aCBnaXZlbiBtYXRyaXguXG4gICAgICAgICA+IFBhcmFtZXRlcnNcbiAgICAgICAgIC0gcGF0aCAoc3RyaW5nKSBwYXRoIHN0cmluZ1xuICAgICAgICAgLSBtYXRyaXggKG9iamVjdCkgc2VlIEBNYXRyaXhcbiAgICAgICAgID0gKHN0cmluZykgdHJhbnNmb3JtZWQgcGF0aCBzdHJpbmdcbiAgICAgICAgXFwqL1xuICAgICAgICBtYXBQYXRoID0gUi5tYXBQYXRoID0gZnVuY3Rpb24gKHBhdGgsIG1hdHJpeCkge1xuICAgICAgICAgICAgaWYgKCFtYXRyaXgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGF0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB4LCB5LCBpLCBqLCBpaSwgamosIHBhdGhpO1xuICAgICAgICAgICAgcGF0aCA9IHBhdGgyY3VydmUocGF0aCk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBpaSA9IHBhdGgubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgIHBhdGhpID0gcGF0aFtpXTtcbiAgICAgICAgICAgICAgICBmb3IgKGogPSAxLCBqaiA9IHBhdGhpLmxlbmd0aDsgaiA8IGpqOyBqICs9IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgeCA9IG1hdHJpeC54KHBhdGhpW2pdLCBwYXRoaVtqICsgMV0pO1xuICAgICAgICAgICAgICAgICAgICB5ID0gbWF0cml4LnkocGF0aGlbal0sIHBhdGhpW2ogKyAxXSk7XG4gICAgICAgICAgICAgICAgICAgIHBhdGhpW2pdID0geDtcbiAgICAgICAgICAgICAgICAgICAgcGF0aGlbaiArIDFdID0geTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcGF0aDtcbiAgICAgICAgfTtcblxuICAgIFIuX2cgPSBnO1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnR5cGVcbiAgICAgWyBwcm9wZXJ0eSAoc3RyaW5nKSBdXG4gICAgICoqXG4gICAgICogQ2FuIGJlIOKAnFNWR+KAnSwg4oCcVk1M4oCdIG9yIGVtcHR5LCBkZXBlbmRpbmcgb24gYnJvd3NlciBzdXBwb3J0LlxuICAgIFxcKi9cbiAgICBSLnR5cGUgPSAoZy53aW4uU1ZHQW5nbGUgfHwgZy5kb2MuaW1wbGVtZW50YXRpb24uaGFzRmVhdHVyZShcImh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ZlYXR1cmUjQmFzaWNTdHJ1Y3R1cmVcIiwgXCIxLjFcIikgPyBcIlNWR1wiIDogXCJWTUxcIik7XG4gICAgaWYgKFIudHlwZSA9PSBcIlZNTFwiKSB7XG4gICAgICAgIHZhciBkID0gZy5kb2MuY3JlYXRlRWxlbWVudChcImRpdlwiKSxcbiAgICAgICAgICAgIGI7XG4gICAgICAgIGQuaW5uZXJIVE1MID0gJzx2OnNoYXBlIGFkaj1cIjFcIi8+JztcbiAgICAgICAgYiA9IGQuZmlyc3RDaGlsZDtcbiAgICAgICAgYi5zdHlsZS5iZWhhdmlvciA9IFwidXJsKCNkZWZhdWx0I1ZNTClcIjtcbiAgICAgICAgaWYgKCEoYiAmJiB0eXBlb2YgYi5hZGogPT0gXCJvYmplY3RcIikpIHtcbiAgICAgICAgICAgIHJldHVybiAoUi50eXBlID0gRSk7XG4gICAgICAgIH1cbiAgICAgICAgZCA9IG51bGw7XG4gICAgfVxuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnN2Z1xuICAgICBbIHByb3BlcnR5IChib29sZWFuKSBdXG4gICAgICoqXG4gICAgICogYHRydWVgIGlmIGJyb3dzZXIgc3VwcG9ydHMgU1ZHLlxuICAgIFxcKi9cbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC52bWxcbiAgICAgWyBwcm9wZXJ0eSAoYm9vbGVhbikgXVxuICAgICAqKlxuICAgICAqIGB0cnVlYCBpZiBicm93c2VyIHN1cHBvcnRzIFZNTC5cbiAgICBcXCovXG4gICAgUi5zdmcgPSAhKFIudm1sID0gUi50eXBlID09IFwiVk1MXCIpO1xuICAgIFIuX1BhcGVyID0gUGFwZXI7XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZm5cbiAgICAgWyBwcm9wZXJ0eSAob2JqZWN0KSBdXG4gICAgICoqXG4gICAgICogWW91IGNhbiBhZGQgeW91ciBvd24gbWV0aG9kIHRvIHRoZSBjYW52YXMuIEZvciBleGFtcGxlIGlmIHlvdSB3YW50IHRvIGRyYXcgYSBwaWUgY2hhcnQsXG4gICAgICogeW91IGNhbiBjcmVhdGUgeW91ciBvd24gcGllIGNoYXJ0IGZ1bmN0aW9uIGFuZCBzaGlwIGl0IGFzIGEgUmFwaGHDq2wgcGx1Z2luLiBUbyBkbyB0aGlzXG4gICAgICogeW91IG5lZWQgdG8gZXh0ZW5kIHRoZSBgUmFwaGFlbC5mbmAgb2JqZWN0LiBZb3Ugc2hvdWxkIG1vZGlmeSB0aGUgYGZuYCBvYmplY3QgYmVmb3JlIGFcbiAgICAgKiBSYXBoYcOrbCBpbnN0YW5jZSBpcyBjcmVhdGVkLCBvdGhlcndpc2UgaXQgd2lsbCB0YWtlIG5vIGVmZmVjdC4gUGxlYXNlIG5vdGUgdGhhdCB0aGVcbiAgICAgKiBhYmlsaXR5IGZvciBuYW1lc3BhY2VkIHBsdWdpbnMgd2FzIHJlbW92ZWQgaW4gUmFwaGFlbCAyLjAuIEl0IGlzIHVwIHRvIHRoZSBwbHVnaW4gdG9cbiAgICAgKiBlbnN1cmUgYW55IG5hbWVzcGFjaW5nIGVuc3VyZXMgcHJvcGVyIGNvbnRleHQuXG4gICAgID4gVXNhZ2VcbiAgICAgfCBSYXBoYWVsLmZuLmFycm93ID0gZnVuY3Rpb24gKHgxLCB5MSwgeDIsIHkyLCBzaXplKSB7XG4gICAgIHwgICAgIHJldHVybiB0aGlzLnBhdGgoIC4uLiApO1xuICAgICB8IH07XG4gICAgIHwgLy8gb3IgY3JlYXRlIG5hbWVzcGFjZVxuICAgICB8IFJhcGhhZWwuZm4ubXlzdHVmZiA9IHtcbiAgICAgfCAgICAgYXJyb3c6IGZ1bmN0aW9uICgpIHvigKZ9LFxuICAgICB8ICAgICBzdGFyOiBmdW5jdGlvbiAoKSB74oCmfSxcbiAgICAgfCAgICAgLy8gZXRj4oCmXG4gICAgIHwgfTtcbiAgICAgfCB2YXIgcGFwZXIgPSBSYXBoYWVsKDEwLCAxMCwgNjMwLCA0ODApO1xuICAgICB8IC8vIHRoZW4gdXNlIGl0XG4gICAgIHwgcGFwZXIuYXJyb3coMTAsIDEwLCAzMCwgMzAsIDUpLmF0dHIoe2ZpbGw6IFwiI2YwMFwifSk7XG4gICAgIHwgcGFwZXIubXlzdHVmZi5hcnJvdygpO1xuICAgICB8IHBhcGVyLm15c3R1ZmYuc3RhcigpO1xuICAgIFxcKi9cbiAgICBSLmZuID0gcGFwZXJwcm90byA9IFBhcGVyLnByb3RvdHlwZSA9IFIucHJvdG90eXBlO1xuICAgIFIuX2lkID0gMDtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5pc1xuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogSGFuZGZ1bCBvZiByZXBsYWNlbWVudHMgZm9yIGB0eXBlb2ZgIG9wZXJhdG9yLlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBvICjigKYpIGFueSBvYmplY3Qgb3IgcHJpbWl0aXZlXG4gICAgIC0gdHlwZSAoc3RyaW5nKSBuYW1lIG9mIHRoZSB0eXBlLCBpLmUuIOKAnHN0cmluZ+KAnSwg4oCcZnVuY3Rpb27igJ0sIOKAnG51bWJlcuKAnSwgZXRjLlxuICAgICA9IChib29sZWFuKSBpcyBnaXZlbiB2YWx1ZSBpcyBvZiBnaXZlbiB0eXBlXG4gICAgXFwqL1xuICAgIFIuaXMgPSBmdW5jdGlvbiAobywgdHlwZSkge1xuICAgICAgICB0eXBlID0gbG93ZXJDYXNlLmNhbGwodHlwZSk7XG4gICAgICAgIGlmICh0eXBlID09IFwiZmluaXRlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiAhaXNuYW5baGFzXSgrbyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT0gXCJhcnJheVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gbyBpbnN0YW5jZW9mIEFycmF5O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAgKHR5cGUgPT0gXCJudWxsXCIgJiYgbyA9PT0gbnVsbCkgfHxcbiAgICAgICAgICAgICAgICAodHlwZSA9PSB0eXBlb2YgbyAmJiBvICE9PSBudWxsKSB8fFxuICAgICAgICAgICAgICAgICh0eXBlID09IFwib2JqZWN0XCIgJiYgbyA9PT0gT2JqZWN0KG8pKSB8fFxuICAgICAgICAgICAgICAgICh0eXBlID09IFwiYXJyYXlcIiAmJiBBcnJheS5pc0FycmF5ICYmIEFycmF5LmlzQXJyYXkobykpIHx8XG4gICAgICAgICAgICAgICAgb2JqZWN0VG9TdHJpbmcuY2FsbChvKS5zbGljZSg4LCAtMSkudG9Mb3dlckNhc2UoKSA9PSB0eXBlO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBjbG9uZShvYmopIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmogPT0gXCJmdW5jdGlvblwiIHx8IE9iamVjdChvYmopICE9PSBvYmopIHtcbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJlcyA9IG5ldyBvYmouY29uc3RydWN0b3I7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIGlmIChvYmpbaGFzXShrZXkpKSB7XG4gICAgICAgICAgICByZXNba2V5XSA9IGNsb25lKG9ialtrZXldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLmFuZ2xlXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZXR1cm5zIGFuZ2xlIGJldHdlZW4gdHdvIG9yIHRocmVlIHBvaW50c1xuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSB4MSAobnVtYmVyKSB4IGNvb3JkIG9mIGZpcnN0IHBvaW50XG4gICAgIC0geTEgKG51bWJlcikgeSBjb29yZCBvZiBmaXJzdCBwb2ludFxuICAgICAtIHgyIChudW1iZXIpIHggY29vcmQgb2Ygc2Vjb25kIHBvaW50XG4gICAgIC0geTIgKG51bWJlcikgeSBjb29yZCBvZiBzZWNvbmQgcG9pbnRcbiAgICAgLSB4MyAobnVtYmVyKSAjb3B0aW9uYWwgeCBjb29yZCBvZiB0aGlyZCBwb2ludFxuICAgICAtIHkzIChudW1iZXIpICNvcHRpb25hbCB5IGNvb3JkIG9mIHRoaXJkIHBvaW50XG4gICAgID0gKG51bWJlcikgYW5nbGUgaW4gZGVncmVlcy5cbiAgICBcXCovXG4gICAgUi5hbmdsZSA9IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5MiwgeDMsIHkzKSB7XG4gICAgICAgIGlmICh4MyA9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgeCA9IHgxIC0geDIsXG4gICAgICAgICAgICAgICAgeSA9IHkxIC0geTI7XG4gICAgICAgICAgICBpZiAoIXggJiYgIXkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAoMTgwICsgbWF0aC5hdGFuMigteSwgLXgpICogMTgwIC8gUEkgKyAzNjApICUgMzYwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFIuYW5nbGUoeDEsIHkxLCB4MywgeTMpIC0gUi5hbmdsZSh4MiwgeTIsIHgzLCB5Myk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnJhZFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogVHJhbnNmb3JtIGFuZ2xlIHRvIHJhZGlhbnNcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gZGVnIChudW1iZXIpIGFuZ2xlIGluIGRlZ3JlZXNcbiAgICAgPSAobnVtYmVyKSBhbmdsZSBpbiByYWRpYW5zLlxuICAgIFxcKi9cbiAgICBSLnJhZCA9IGZ1bmN0aW9uIChkZWcpIHtcbiAgICAgICAgcmV0dXJuIGRlZyAlIDM2MCAqIFBJIC8gMTgwO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZGVnXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBUcmFuc2Zvcm0gYW5nbGUgdG8gZGVncmVlc1xuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSByYWQgKG51bWJlcikgYW5nbGUgaW4gcmFkaWFuc1xuICAgICA9IChudW1iZXIpIGFuZ2xlIGluIGRlZ3JlZXMuXG4gICAgXFwqL1xuICAgIFIuZGVnID0gZnVuY3Rpb24gKHJhZCkge1xuICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCAoKHJhZCAqIDE4MCAvIFBJJSAzNjApKiAxMDAwKSAvIDEwMDA7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5zbmFwVG9cbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFNuYXBzIGdpdmVuIHZhbHVlIHRvIGdpdmVuIGdyaWQuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIHZhbHVlcyAoYXJyYXl8bnVtYmVyKSBnaXZlbiBhcnJheSBvZiB2YWx1ZXMgb3Igc3RlcCBvZiB0aGUgZ3JpZFxuICAgICAtIHZhbHVlIChudW1iZXIpIHZhbHVlIHRvIGFkanVzdFxuICAgICAtIHRvbGVyYW5jZSAobnVtYmVyKSAjb3B0aW9uYWwgdG9sZXJhbmNlIGZvciBzbmFwcGluZy4gRGVmYXVsdCBpcyBgMTBgLlxuICAgICA9IChudW1iZXIpIGFkanVzdGVkIHZhbHVlLlxuICAgIFxcKi9cbiAgICBSLnNuYXBUbyA9IGZ1bmN0aW9uICh2YWx1ZXMsIHZhbHVlLCB0b2xlcmFuY2UpIHtcbiAgICAgICAgdG9sZXJhbmNlID0gUi5pcyh0b2xlcmFuY2UsIFwiZmluaXRlXCIpID8gdG9sZXJhbmNlIDogMTA7XG4gICAgICAgIGlmIChSLmlzKHZhbHVlcywgYXJyYXkpKSB7XG4gICAgICAgICAgICB2YXIgaSA9IHZhbHVlcy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSBpZiAoYWJzKHZhbHVlc1tpXSAtIHZhbHVlKSA8PSB0b2xlcmFuY2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVzW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWVzID0gK3ZhbHVlcztcbiAgICAgICAgICAgIHZhciByZW0gPSB2YWx1ZSAlIHZhbHVlcztcbiAgICAgICAgICAgIGlmIChyZW0gPCB0b2xlcmFuY2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUgLSByZW07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVtID4gdmFsdWVzIC0gdG9sZXJhbmNlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlIC0gcmVtICsgdmFsdWVzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuY3JlYXRlVVVJRFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJucyBSRkM0MTIyLCB2ZXJzaW9uIDQgSURcbiAgICBcXCovXG4gICAgdmFyIGNyZWF0ZVVVSUQgPSBSLmNyZWF0ZVVVSUQgPSAoZnVuY3Rpb24gKHV1aWRSZWdFeCwgdXVpZFJlcGxhY2VyKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJ4eHh4eHh4eC14eHh4LTR4eHgteXh4eC14eHh4eHh4eHh4eHhcIi5yZXBsYWNlKHV1aWRSZWdFeCwgdXVpZFJlcGxhY2VyKS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICB9O1xuICAgIH0pKC9beHldL2csIGZ1bmN0aW9uIChjKSB7XG4gICAgICAgIHZhciByID0gbWF0aC5yYW5kb20oKSAqIDE2IHwgMCxcbiAgICAgICAgICAgIHYgPSBjID09IFwieFwiID8gciA6IChyICYgMyB8IDgpO1xuICAgICAgICByZXR1cm4gdi50b1N0cmluZygxNik7XG4gICAgfSk7XG5cbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5zZXRXaW5kb3dcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFVzZWQgd2hlbiB5b3UgbmVlZCB0byBkcmF3IGluIGAmbHQ7aWZyYW1lPmAuIFN3aXRjaGVkIHdpbmRvdyB0byB0aGUgaWZyYW1lIG9uZS5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gbmV3d2luICh3aW5kb3cpIG5ldyB3aW5kb3cgb2JqZWN0XG4gICAgXFwqL1xuICAgIFIuc2V0V2luZG93ID0gZnVuY3Rpb24gKG5ld3dpbikge1xuICAgICAgICBldmUoXCJyYXBoYWVsLnNldFdpbmRvd1wiLCBSLCBnLndpbiwgbmV3d2luKTtcbiAgICAgICAgZy53aW4gPSBuZXd3aW47XG4gICAgICAgIGcuZG9jID0gZy53aW4uZG9jdW1lbnQ7XG4gICAgICAgIGlmIChSLl9lbmdpbmUuaW5pdFdpbikge1xuICAgICAgICAgICAgUi5fZW5naW5lLmluaXRXaW4oZy53aW4pO1xuICAgICAgICB9XG4gICAgfTtcbiAgICB2YXIgdG9IZXggPSBmdW5jdGlvbiAoY29sb3IpIHtcbiAgICAgICAgaWYgKFIudm1sKSB7XG4gICAgICAgICAgICAvLyBodHRwOi8vZGVhbi5lZHdhcmRzLm5hbWUvd2VibG9nLzIwMDkvMTAvY29udmVydC1hbnktY29sb3VyLXZhbHVlLXRvLWhleC1pbi1tc2llL1xuICAgICAgICAgICAgdmFyIHRyaW0gPSAvXlxccyt8XFxzKyQvZztcbiAgICAgICAgICAgIHZhciBib2Q7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHZhciBkb2N1bSA9IG5ldyBBY3RpdmVYT2JqZWN0KFwiaHRtbGZpbGVcIik7XG4gICAgICAgICAgICAgICAgZG9jdW0ud3JpdGUoXCI8Ym9keT5cIik7XG4gICAgICAgICAgICAgICAgZG9jdW0uY2xvc2UoKTtcbiAgICAgICAgICAgICAgICBib2QgPSBkb2N1bS5ib2R5O1xuICAgICAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICAgICAgYm9kID0gY3JlYXRlUG9wdXAoKS5kb2N1bWVudC5ib2R5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHJhbmdlID0gYm9kLmNyZWF0ZVRleHRSYW5nZSgpO1xuICAgICAgICAgICAgdG9IZXggPSBjYWNoZXIoZnVuY3Rpb24gKGNvbG9yKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgYm9kLnN0eWxlLmNvbG9yID0gU3RyKGNvbG9yKS5yZXBsYWNlKHRyaW0sIEUpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSByYW5nZS5xdWVyeUNvbW1hbmRWYWx1ZShcIkZvcmVDb2xvclwiKTtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAoKHZhbHVlICYgMjU1KSA8PCAxNikgfCAodmFsdWUgJiA2NTI4MCkgfCAoKHZhbHVlICYgMTY3MTE2ODApID4+PiAxNik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIiNcIiArIChcIjAwMDAwMFwiICsgdmFsdWUudG9TdHJpbmcoMTYpKS5zbGljZSgtNik7XG4gICAgICAgICAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm5vbmVcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBpID0gZy5kb2MuY3JlYXRlRWxlbWVudChcImlcIik7XG4gICAgICAgICAgICBpLnRpdGxlID0gXCJSYXBoYVxceGVibCBDb2xvdXIgUGlja2VyXCI7XG4gICAgICAgICAgICBpLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICAgICAgICAgIGcuZG9jLmJvZHkuYXBwZW5kQ2hpbGQoaSk7XG4gICAgICAgICAgICB0b0hleCA9IGNhY2hlcihmdW5jdGlvbiAoY29sb3IpIHtcbiAgICAgICAgICAgICAgICBpLnN0eWxlLmNvbG9yID0gY29sb3I7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGcuZG9jLmRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGUoaSwgRSkuZ2V0UHJvcGVydHlWYWx1ZShcImNvbG9yXCIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRvSGV4KGNvbG9yKTtcbiAgICB9LFxuICAgIGhzYnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gXCJoc2IoXCIgKyBbdGhpcy5oLCB0aGlzLnMsIHRoaXMuYl0gKyBcIilcIjtcbiAgICB9LFxuICAgIGhzbHRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gXCJoc2woXCIgKyBbdGhpcy5oLCB0aGlzLnMsIHRoaXMubF0gKyBcIilcIjtcbiAgICB9LFxuICAgIHJnYnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5oZXg7XG4gICAgfSxcbiAgICBwcmVwYXJlUkdCID0gZnVuY3Rpb24gKHIsIGcsIGIpIHtcbiAgICAgICAgaWYgKGcgPT0gbnVsbCAmJiBSLmlzKHIsIFwib2JqZWN0XCIpICYmIFwiclwiIGluIHIgJiYgXCJnXCIgaW4gciAmJiBcImJcIiBpbiByKSB7XG4gICAgICAgICAgICBiID0gci5iO1xuICAgICAgICAgICAgZyA9IHIuZztcbiAgICAgICAgICAgIHIgPSByLnI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGcgPT0gbnVsbCAmJiBSLmlzKHIsIHN0cmluZykpIHtcbiAgICAgICAgICAgIHZhciBjbHIgPSBSLmdldFJHQihyKTtcbiAgICAgICAgICAgIHIgPSBjbHIucjtcbiAgICAgICAgICAgIGcgPSBjbHIuZztcbiAgICAgICAgICAgIGIgPSBjbHIuYjtcbiAgICAgICAgfVxuICAgICAgICBpZiAociA+IDEgfHwgZyA+IDEgfHwgYiA+IDEpIHtcbiAgICAgICAgICAgIHIgLz0gMjU1O1xuICAgICAgICAgICAgZyAvPSAyNTU7XG4gICAgICAgICAgICBiIC89IDI1NTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBbciwgZywgYl07XG4gICAgfSxcbiAgICBwYWNrYWdlUkdCID0gZnVuY3Rpb24gKHIsIGcsIGIsIG8pIHtcbiAgICAgICAgciAqPSAyNTU7XG4gICAgICAgIGcgKj0gMjU1O1xuICAgICAgICBiICo9IDI1NTtcbiAgICAgICAgdmFyIHJnYiA9IHtcbiAgICAgICAgICAgIHI6IHIsXG4gICAgICAgICAgICBnOiBnLFxuICAgICAgICAgICAgYjogYixcbiAgICAgICAgICAgIGhleDogUi5yZ2IociwgZywgYiksXG4gICAgICAgICAgICB0b1N0cmluZzogcmdidG9TdHJpbmdcbiAgICAgICAgfTtcbiAgICAgICAgUi5pcyhvLCBcImZpbml0ZVwiKSAmJiAocmdiLm9wYWNpdHkgPSBvKTtcbiAgICAgICAgcmV0dXJuIHJnYjtcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuY29sb3JcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFBhcnNlcyB0aGUgY29sb3Igc3RyaW5nIGFuZCByZXR1cm5zIG9iamVjdCB3aXRoIGFsbCB2YWx1ZXMgZm9yIHRoZSBnaXZlbiBjb2xvci5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gY2xyIChzdHJpbmcpIGNvbG9yIHN0cmluZyBpbiBvbmUgb2YgdGhlIHN1cHBvcnRlZCBmb3JtYXRzIChzZWUgQFJhcGhhZWwuZ2V0UkdCKVxuICAgICA9IChvYmplY3QpIENvbWJpbmVkIFJHQiAmIEhTQiBvYmplY3QgaW4gZm9ybWF0OlxuICAgICBvIHtcbiAgICAgbyAgICAgciAobnVtYmVyKSByZWQsXG4gICAgIG8gICAgIGcgKG51bWJlcikgZ3JlZW4sXG4gICAgIG8gICAgIGIgKG51bWJlcikgYmx1ZSxcbiAgICAgbyAgICAgaGV4IChzdHJpbmcpIGNvbG9yIGluIEhUTUwvQ1NTIGZvcm1hdDogI+KAouKAouKAouKAouKAouKAoixcbiAgICAgbyAgICAgZXJyb3IgKGJvb2xlYW4pIGB0cnVlYCBpZiBzdHJpbmcgY2Fu4oCZdCBiZSBwYXJzZWQsXG4gICAgIG8gICAgIGggKG51bWJlcikgaHVlLFxuICAgICBvICAgICBzIChudW1iZXIpIHNhdHVyYXRpb24sXG4gICAgIG8gICAgIHYgKG51bWJlcikgdmFsdWUgKGJyaWdodG5lc3MpLFxuICAgICBvICAgICBsIChudW1iZXIpIGxpZ2h0bmVzc1xuICAgICBvIH1cbiAgICBcXCovXG4gICAgUi5jb2xvciA9IGZ1bmN0aW9uIChjbHIpIHtcbiAgICAgICAgdmFyIHJnYjtcbiAgICAgICAgaWYgKFIuaXMoY2xyLCBcIm9iamVjdFwiKSAmJiBcImhcIiBpbiBjbHIgJiYgXCJzXCIgaW4gY2xyICYmIFwiYlwiIGluIGNscikge1xuICAgICAgICAgICAgcmdiID0gUi5oc2IycmdiKGNscik7XG4gICAgICAgICAgICBjbHIuciA9IHJnYi5yO1xuICAgICAgICAgICAgY2xyLmcgPSByZ2IuZztcbiAgICAgICAgICAgIGNsci5iID0gcmdiLmI7XG4gICAgICAgICAgICBjbHIuaGV4ID0gcmdiLmhleDtcbiAgICAgICAgfSBlbHNlIGlmIChSLmlzKGNsciwgXCJvYmplY3RcIikgJiYgXCJoXCIgaW4gY2xyICYmIFwic1wiIGluIGNsciAmJiBcImxcIiBpbiBjbHIpIHtcbiAgICAgICAgICAgIHJnYiA9IFIuaHNsMnJnYihjbHIpO1xuICAgICAgICAgICAgY2xyLnIgPSByZ2IucjtcbiAgICAgICAgICAgIGNsci5nID0gcmdiLmc7XG4gICAgICAgICAgICBjbHIuYiA9IHJnYi5iO1xuICAgICAgICAgICAgY2xyLmhleCA9IHJnYi5oZXg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoUi5pcyhjbHIsIFwic3RyaW5nXCIpKSB7XG4gICAgICAgICAgICAgICAgY2xyID0gUi5nZXRSR0IoY2xyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChSLmlzKGNsciwgXCJvYmplY3RcIikgJiYgXCJyXCIgaW4gY2xyICYmIFwiZ1wiIGluIGNsciAmJiBcImJcIiBpbiBjbHIpIHtcbiAgICAgICAgICAgICAgICByZ2IgPSBSLnJnYjJoc2woY2xyKTtcbiAgICAgICAgICAgICAgICBjbHIuaCA9IHJnYi5oO1xuICAgICAgICAgICAgICAgIGNsci5zID0gcmdiLnM7XG4gICAgICAgICAgICAgICAgY2xyLmwgPSByZ2IubDtcbiAgICAgICAgICAgICAgICByZ2IgPSBSLnJnYjJoc2IoY2xyKTtcbiAgICAgICAgICAgICAgICBjbHIudiA9IHJnYi5iO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjbHIgPSB7aGV4OiBcIm5vbmVcIn07XG4gICAgICAgICAgICAgICAgY2xyLnIgPSBjbHIuZyA9IGNsci5iID0gY2xyLmggPSBjbHIucyA9IGNsci52ID0gY2xyLmwgPSAtMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjbHIudG9TdHJpbmcgPSByZ2J0b1N0cmluZztcbiAgICAgICAgcmV0dXJuIGNscjtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLmhzYjJyZ2JcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIENvbnZlcnRzIEhTQiB2YWx1ZXMgdG8gUkdCIG9iamVjdC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaCAobnVtYmVyKSBodWVcbiAgICAgLSBzIChudW1iZXIpIHNhdHVyYXRpb25cbiAgICAgLSB2IChudW1iZXIpIHZhbHVlIG9yIGJyaWdodG5lc3NcbiAgICAgPSAob2JqZWN0KSBSR0Igb2JqZWN0IGluIGZvcm1hdDpcbiAgICAgbyB7XG4gICAgIG8gICAgIHIgKG51bWJlcikgcmVkLFxuICAgICBvICAgICBnIChudW1iZXIpIGdyZWVuLFxuICAgICBvICAgICBiIChudW1iZXIpIGJsdWUsXG4gICAgIG8gICAgIGhleCAoc3RyaW5nKSBjb2xvciBpbiBIVE1ML0NTUyBmb3JtYXQ6ICPigKLigKLigKLigKLigKLigKJcbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIFIuaHNiMnJnYiA9IGZ1bmN0aW9uIChoLCBzLCB2LCBvKSB7XG4gICAgICAgIGlmICh0aGlzLmlzKGgsIFwib2JqZWN0XCIpICYmIFwiaFwiIGluIGggJiYgXCJzXCIgaW4gaCAmJiBcImJcIiBpbiBoKSB7XG4gICAgICAgICAgICB2ID0gaC5iO1xuICAgICAgICAgICAgcyA9IGgucztcbiAgICAgICAgICAgIG8gPSBoLm87XG4gICAgICAgICAgICBoID0gaC5oO1xuICAgICAgICB9XG4gICAgICAgIGggKj0gMzYwO1xuICAgICAgICB2YXIgUiwgRywgQiwgWCwgQztcbiAgICAgICAgaCA9IChoICUgMzYwKSAvIDYwO1xuICAgICAgICBDID0gdiAqIHM7XG4gICAgICAgIFggPSBDICogKDEgLSBhYnMoaCAlIDIgLSAxKSk7XG4gICAgICAgIFIgPSBHID0gQiA9IHYgLSBDO1xuXG4gICAgICAgIGggPSB+fmg7XG4gICAgICAgIFIgKz0gW0MsIFgsIDAsIDAsIFgsIENdW2hdO1xuICAgICAgICBHICs9IFtYLCBDLCBDLCBYLCAwLCAwXVtoXTtcbiAgICAgICAgQiArPSBbMCwgMCwgWCwgQywgQywgWF1baF07XG4gICAgICAgIHJldHVybiBwYWNrYWdlUkdCKFIsIEcsIEIsIG8pO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuaHNsMnJnYlxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQ29udmVydHMgSFNMIHZhbHVlcyB0byBSR0Igb2JqZWN0LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoIChudW1iZXIpIGh1ZVxuICAgICAtIHMgKG51bWJlcikgc2F0dXJhdGlvblxuICAgICAtIGwgKG51bWJlcikgbHVtaW5vc2l0eVxuICAgICA9IChvYmplY3QpIFJHQiBvYmplY3QgaW4gZm9ybWF0OlxuICAgICBvIHtcbiAgICAgbyAgICAgciAobnVtYmVyKSByZWQsXG4gICAgIG8gICAgIGcgKG51bWJlcikgZ3JlZW4sXG4gICAgIG8gICAgIGIgKG51bWJlcikgYmx1ZSxcbiAgICAgbyAgICAgaGV4IChzdHJpbmcpIGNvbG9yIGluIEhUTUwvQ1NTIGZvcm1hdDogI+KAouKAouKAouKAouKAouKAolxuICAgICBvIH1cbiAgICBcXCovXG4gICAgUi5oc2wycmdiID0gZnVuY3Rpb24gKGgsIHMsIGwsIG8pIHtcbiAgICAgICAgaWYgKHRoaXMuaXMoaCwgXCJvYmplY3RcIikgJiYgXCJoXCIgaW4gaCAmJiBcInNcIiBpbiBoICYmIFwibFwiIGluIGgpIHtcbiAgICAgICAgICAgIGwgPSBoLmw7XG4gICAgICAgICAgICBzID0gaC5zO1xuICAgICAgICAgICAgaCA9IGguaDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaCA+IDEgfHwgcyA+IDEgfHwgbCA+IDEpIHtcbiAgICAgICAgICAgIGggLz0gMzYwO1xuICAgICAgICAgICAgcyAvPSAxMDA7XG4gICAgICAgICAgICBsIC89IDEwMDtcbiAgICAgICAgfVxuICAgICAgICBoICo9IDM2MDtcbiAgICAgICAgdmFyIFIsIEcsIEIsIFgsIEM7XG4gICAgICAgIGggPSAoaCAlIDM2MCkgLyA2MDtcbiAgICAgICAgQyA9IDIgKiBzICogKGwgPCAuNSA/IGwgOiAxIC0gbCk7XG4gICAgICAgIFggPSBDICogKDEgLSBhYnMoaCAlIDIgLSAxKSk7XG4gICAgICAgIFIgPSBHID0gQiA9IGwgLSBDIC8gMjtcblxuICAgICAgICBoID0gfn5oO1xuICAgICAgICBSICs9IFtDLCBYLCAwLCAwLCBYLCBDXVtoXTtcbiAgICAgICAgRyArPSBbWCwgQywgQywgWCwgMCwgMF1baF07XG4gICAgICAgIEIgKz0gWzAsIDAsIFgsIEMsIEMsIFhdW2hdO1xuICAgICAgICByZXR1cm4gcGFja2FnZVJHQihSLCBHLCBCLCBvKTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnJnYjJoc2JcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIENvbnZlcnRzIFJHQiB2YWx1ZXMgdG8gSFNCIG9iamVjdC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gciAobnVtYmVyKSByZWRcbiAgICAgLSBnIChudW1iZXIpIGdyZWVuXG4gICAgIC0gYiAobnVtYmVyKSBibHVlXG4gICAgID0gKG9iamVjdCkgSFNCIG9iamVjdCBpbiBmb3JtYXQ6XG4gICAgIG8ge1xuICAgICBvICAgICBoIChudW1iZXIpIGh1ZVxuICAgICBvICAgICBzIChudW1iZXIpIHNhdHVyYXRpb25cbiAgICAgbyAgICAgYiAobnVtYmVyKSBicmlnaHRuZXNzXG4gICAgIG8gfVxuICAgIFxcKi9cbiAgICBSLnJnYjJoc2IgPSBmdW5jdGlvbiAociwgZywgYikge1xuICAgICAgICBiID0gcHJlcGFyZVJHQihyLCBnLCBiKTtcbiAgICAgICAgciA9IGJbMF07XG4gICAgICAgIGcgPSBiWzFdO1xuICAgICAgICBiID0gYlsyXTtcblxuICAgICAgICB2YXIgSCwgUywgViwgQztcbiAgICAgICAgViA9IG1tYXgociwgZywgYik7XG4gICAgICAgIEMgPSBWIC0gbW1pbihyLCBnLCBiKTtcbiAgICAgICAgSCA9IChDID09IDAgPyBudWxsIDpcbiAgICAgICAgICAgICBWID09IHIgPyAoZyAtIGIpIC8gQyA6XG4gICAgICAgICAgICAgViA9PSBnID8gKGIgLSByKSAvIEMgKyAyIDpcbiAgICAgICAgICAgICAgICAgICAgICAociAtIGcpIC8gQyArIDRcbiAgICAgICAgICAgICk7XG4gICAgICAgIEggPSAoKEggKyAzNjApICUgNikgKiA2MCAvIDM2MDtcbiAgICAgICAgUyA9IEMgPT0gMCA/IDAgOiBDIC8gVjtcbiAgICAgICAgcmV0dXJuIHtoOiBILCBzOiBTLCBiOiBWLCB0b1N0cmluZzogaHNidG9TdHJpbmd9O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwucmdiMmhzbFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQ29udmVydHMgUkdCIHZhbHVlcyB0byBIU0wgb2JqZWN0LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSByIChudW1iZXIpIHJlZFxuICAgICAtIGcgKG51bWJlcikgZ3JlZW5cbiAgICAgLSBiIChudW1iZXIpIGJsdWVcbiAgICAgPSAob2JqZWN0KSBIU0wgb2JqZWN0IGluIGZvcm1hdDpcbiAgICAgbyB7XG4gICAgIG8gICAgIGggKG51bWJlcikgaHVlXG4gICAgIG8gICAgIHMgKG51bWJlcikgc2F0dXJhdGlvblxuICAgICBvICAgICBsIChudW1iZXIpIGx1bWlub3NpdHlcbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIFIucmdiMmhzbCA9IGZ1bmN0aW9uIChyLCBnLCBiKSB7XG4gICAgICAgIGIgPSBwcmVwYXJlUkdCKHIsIGcsIGIpO1xuICAgICAgICByID0gYlswXTtcbiAgICAgICAgZyA9IGJbMV07XG4gICAgICAgIGIgPSBiWzJdO1xuXG4gICAgICAgIHZhciBILCBTLCBMLCBNLCBtLCBDO1xuICAgICAgICBNID0gbW1heChyLCBnLCBiKTtcbiAgICAgICAgbSA9IG1taW4ociwgZywgYik7XG4gICAgICAgIEMgPSBNIC0gbTtcbiAgICAgICAgSCA9IChDID09IDAgPyBudWxsIDpcbiAgICAgICAgICAgICBNID09IHIgPyAoZyAtIGIpIC8gQyA6XG4gICAgICAgICAgICAgTSA9PSBnID8gKGIgLSByKSAvIEMgKyAyIDpcbiAgICAgICAgICAgICAgICAgICAgICAociAtIGcpIC8gQyArIDQpO1xuICAgICAgICBIID0gKChIICsgMzYwKSAlIDYpICogNjAgLyAzNjA7XG4gICAgICAgIEwgPSAoTSArIG0pIC8gMjtcbiAgICAgICAgUyA9IChDID09IDAgPyAwIDpcbiAgICAgICAgICAgICBMIDwgLjUgPyBDIC8gKDIgKiBMKSA6XG4gICAgICAgICAgICAgICAgICAgICAgQyAvICgyIC0gMiAqIEwpKTtcbiAgICAgICAgcmV0dXJuIHtoOiBILCBzOiBTLCBsOiBMLCB0b1N0cmluZzogaHNsdG9TdHJpbmd9O1xuICAgIH07XG4gICAgUi5fcGF0aDJzdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmpvaW4oXCIsXCIpLnJlcGxhY2UocDJzLCBcIiQxXCIpO1xuICAgIH07XG4gICAgZnVuY3Rpb24gcmVwdXNoKGFycmF5LCBpdGVtKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGFycmF5Lmxlbmd0aDsgaSA8IGlpOyBpKyspIGlmIChhcnJheVtpXSA9PT0gaXRlbSkge1xuICAgICAgICAgICAgcmV0dXJuIGFycmF5LnB1c2goYXJyYXkuc3BsaWNlKGksIDEpWzBdKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmdW5jdGlvbiBjYWNoZXIoZiwgc2NvcGUsIHBvc3Rwcm9jZXNzb3IpIHtcbiAgICAgICAgZnVuY3Rpb24gbmV3ZigpIHtcbiAgICAgICAgICAgIHZhciBhcmcgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApLFxuICAgICAgICAgICAgICAgIGFyZ3MgPSBhcmcuam9pbihcIlxcdTI0MDBcIiksXG4gICAgICAgICAgICAgICAgY2FjaGUgPSBuZXdmLmNhY2hlID0gbmV3Zi5jYWNoZSB8fCB7fSxcbiAgICAgICAgICAgICAgICBjb3VudCA9IG5ld2YuY291bnQgPSBuZXdmLmNvdW50IHx8IFtdO1xuICAgICAgICAgICAgaWYgKGNhY2hlW2hhc10oYXJncykpIHtcbiAgICAgICAgICAgICAgICByZXB1c2goY291bnQsIGFyZ3MpO1xuICAgICAgICAgICAgICAgIHJldHVybiBwb3N0cHJvY2Vzc29yID8gcG9zdHByb2Nlc3NvcihjYWNoZVthcmdzXSkgOiBjYWNoZVthcmdzXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvdW50Lmxlbmd0aCA+PSAxZTMgJiYgZGVsZXRlIGNhY2hlW2NvdW50LnNoaWZ0KCldO1xuICAgICAgICAgICAgY291bnQucHVzaChhcmdzKTtcbiAgICAgICAgICAgIGNhY2hlW2FyZ3NdID0gZlthcHBseV0oc2NvcGUsIGFyZyk7XG4gICAgICAgICAgICByZXR1cm4gcG9zdHByb2Nlc3NvciA/IHBvc3Rwcm9jZXNzb3IoY2FjaGVbYXJnc10pIDogY2FjaGVbYXJnc107XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ld2Y7XG4gICAgfVxuXG4gICAgdmFyIHByZWxvYWQgPSBSLl9wcmVsb2FkID0gZnVuY3Rpb24gKHNyYywgZikge1xuICAgICAgICB2YXIgaW1nID0gZy5kb2MuY3JlYXRlRWxlbWVudChcImltZ1wiKTtcbiAgICAgICAgaW1nLnN0eWxlLmNzc1RleHQgPSBcInBvc2l0aW9uOmFic29sdXRlO2xlZnQ6LTk5OTllbTt0b3A6LTk5OTllbVwiO1xuICAgICAgICBpbWcub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZi5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5vbmxvYWQgPSBudWxsO1xuICAgICAgICAgICAgZy5kb2MuYm9keS5yZW1vdmVDaGlsZCh0aGlzKTtcbiAgICAgICAgfTtcbiAgICAgICAgaW1nLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBnLmRvYy5ib2R5LnJlbW92ZUNoaWxkKHRoaXMpO1xuICAgICAgICB9O1xuICAgICAgICBnLmRvYy5ib2R5LmFwcGVuZENoaWxkKGltZyk7XG4gICAgICAgIGltZy5zcmMgPSBzcmM7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGNsclRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5oZXg7XG4gICAgfVxuXG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZ2V0UkdCXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBQYXJzZXMgY29sb3VyIHN0cmluZyBhcyBSR0Igb2JqZWN0XG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIGNvbG91ciAoc3RyaW5nKSBjb2xvdXIgc3RyaW5nIGluIG9uZSBvZiBmb3JtYXRzOlxuICAgICAjIDx1bD5cbiAgICAgIyAgICAgPGxpPkNvbG91ciBuYW1lICjigJw8Y29kZT5yZWQ8L2NvZGU+4oCdLCDigJw8Y29kZT5ncmVlbjwvY29kZT7igJ0sIOKAnDxjb2RlPmNvcm5mbG93ZXJibHVlPC9jb2RlPuKAnSwgZXRjKTwvbGk+XG4gICAgICMgICAgIDxsaT4j4oCi4oCi4oCiIOKAlCBzaG9ydGVuZWQgSFRNTCBjb2xvdXI6ICjigJw8Y29kZT4jMDAwPC9jb2RlPuKAnSwg4oCcPGNvZGU+I2ZjMDwvY29kZT7igJ0sIGV0Yyk8L2xpPlxuICAgICAjICAgICA8bGk+I+KAouKAouKAouKAouKAouKAoiDigJQgZnVsbCBsZW5ndGggSFRNTCBjb2xvdXI6ICjigJw8Y29kZT4jMDAwMDAwPC9jb2RlPuKAnSwg4oCcPGNvZGU+I2JkMjMwMDwvY29kZT7igJ0pPC9saT5cbiAgICAgIyAgICAgPGxpPnJnYijigKLigKLigKIsIOKAouKAouKAoiwg4oCi4oCi4oCiKSDigJQgcmVkLCBncmVlbiBhbmQgYmx1ZSBjaGFubmVsc+KAmSB2YWx1ZXM6ICjigJw8Y29kZT5yZ2IoMjAwLCZuYnNwOzEwMCwmbmJzcDswKTwvY29kZT7igJ0pPC9saT5cbiAgICAgIyAgICAgPGxpPnJnYijigKLigKLigKIlLCDigKLigKLigKIlLCDigKLigKLigKIlKSDigJQgc2FtZSBhcyBhYm92ZSwgYnV0IGluICU6ICjigJw8Y29kZT5yZ2IoMTAwJSwmbmJzcDsxNzUlLCZuYnNwOzAlKTwvY29kZT7igJ0pPC9saT5cbiAgICAgIyAgICAgPGxpPmhzYijigKLigKLigKIsIOKAouKAouKAoiwg4oCi4oCi4oCiKSDigJQgaHVlLCBzYXR1cmF0aW9uIGFuZCBicmlnaHRuZXNzIHZhbHVlczogKOKAnDxjb2RlPmhzYigwLjUsJm5ic3A7MC4yNSwmbmJzcDsxKTwvY29kZT7igJ0pPC9saT5cbiAgICAgIyAgICAgPGxpPmhzYijigKLigKLigKIlLCDigKLigKLigKIlLCDigKLigKLigKIlKSDigJQgc2FtZSBhcyBhYm92ZSwgYnV0IGluICU8L2xpPlxuICAgICAjICAgICA8bGk+aHNsKOKAouKAouKAoiwg4oCi4oCi4oCiLCDigKLigKLigKIpIOKAlCBzYW1lIGFzIGhzYjwvbGk+XG4gICAgICMgICAgIDxsaT5oc2wo4oCi4oCi4oCiJSwg4oCi4oCi4oCiJSwg4oCi4oCi4oCiJSkg4oCUIHNhbWUgYXMgaHNiPC9saT5cbiAgICAgIyA8L3VsPlxuICAgICA9IChvYmplY3QpIFJHQiBvYmplY3QgaW4gZm9ybWF0OlxuICAgICBvIHtcbiAgICAgbyAgICAgciAobnVtYmVyKSByZWQsXG4gICAgIG8gICAgIGcgKG51bWJlcikgZ3JlZW4sXG4gICAgIG8gICAgIGIgKG51bWJlcikgYmx1ZVxuICAgICBvICAgICBoZXggKHN0cmluZykgY29sb3IgaW4gSFRNTC9DU1MgZm9ybWF0OiAj4oCi4oCi4oCi4oCi4oCi4oCiLFxuICAgICBvICAgICBlcnJvciAoYm9vbGVhbikgdHJ1ZSBpZiBzdHJpbmcgY2Fu4oCZdCBiZSBwYXJzZWRcbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIFIuZ2V0UkdCID0gY2FjaGVyKGZ1bmN0aW9uIChjb2xvdXIpIHtcbiAgICAgICAgaWYgKCFjb2xvdXIgfHwgISEoKGNvbG91ciA9IFN0cihjb2xvdXIpKS5pbmRleE9mKFwiLVwiKSArIDEpKSB7XG4gICAgICAgICAgICByZXR1cm4ge3I6IC0xLCBnOiAtMSwgYjogLTEsIGhleDogXCJub25lXCIsIGVycm9yOiAxLCB0b1N0cmluZzogY2xyVG9TdHJpbmd9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb2xvdXIgPT0gXCJub25lXCIpIHtcbiAgICAgICAgICAgIHJldHVybiB7cjogLTEsIGc6IC0xLCBiOiAtMSwgaGV4OiBcIm5vbmVcIiwgdG9TdHJpbmc6IGNsclRvU3RyaW5nfTtcbiAgICAgICAgfVxuICAgICAgICAhKGhzcmdbaGFzXShjb2xvdXIudG9Mb3dlckNhc2UoKS5zdWJzdHJpbmcoMCwgMikpIHx8IGNvbG91ci5jaGFyQXQoKSA9PSBcIiNcIikgJiYgKGNvbG91ciA9IHRvSGV4KGNvbG91cikpO1xuICAgICAgICB2YXIgcmVzLFxuICAgICAgICAgICAgcmVkLFxuICAgICAgICAgICAgZ3JlZW4sXG4gICAgICAgICAgICBibHVlLFxuICAgICAgICAgICAgb3BhY2l0eSxcbiAgICAgICAgICAgIHQsXG4gICAgICAgICAgICB2YWx1ZXMsXG4gICAgICAgICAgICByZ2IgPSBjb2xvdXIubWF0Y2goY29sb3VyUmVnRXhwKTtcbiAgICAgICAgaWYgKHJnYikge1xuICAgICAgICAgICAgaWYgKHJnYlsyXSkge1xuICAgICAgICAgICAgICAgIGJsdWUgPSB0b0ludChyZ2JbMl0uc3Vic3RyaW5nKDUpLCAxNik7XG4gICAgICAgICAgICAgICAgZ3JlZW4gPSB0b0ludChyZ2JbMl0uc3Vic3RyaW5nKDMsIDUpLCAxNik7XG4gICAgICAgICAgICAgICAgcmVkID0gdG9JbnQocmdiWzJdLnN1YnN0cmluZygxLCAzKSwgMTYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJnYlszXSkge1xuICAgICAgICAgICAgICAgIGJsdWUgPSB0b0ludCgodCA9IHJnYlszXS5jaGFyQXQoMykpICsgdCwgMTYpO1xuICAgICAgICAgICAgICAgIGdyZWVuID0gdG9JbnQoKHQgPSByZ2JbM10uY2hhckF0KDIpKSArIHQsIDE2KTtcbiAgICAgICAgICAgICAgICByZWQgPSB0b0ludCgodCA9IHJnYlszXS5jaGFyQXQoMSkpICsgdCwgMTYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJnYls0XSkge1xuICAgICAgICAgICAgICAgIHZhbHVlcyA9IHJnYls0XVtzcGxpdF0oY29tbWFTcGFjZXMpO1xuICAgICAgICAgICAgICAgIHJlZCA9IHRvRmxvYXQodmFsdWVzWzBdKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbMF0uc2xpY2UoLTEpID09IFwiJVwiICYmIChyZWQgKj0gMi41NSk7XG4gICAgICAgICAgICAgICAgZ3JlZW4gPSB0b0Zsb2F0KHZhbHVlc1sxXSk7XG4gICAgICAgICAgICAgICAgdmFsdWVzWzFdLnNsaWNlKC0xKSA9PSBcIiVcIiAmJiAoZ3JlZW4gKj0gMi41NSk7XG4gICAgICAgICAgICAgICAgYmx1ZSA9IHRvRmxvYXQodmFsdWVzWzJdKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbMl0uc2xpY2UoLTEpID09IFwiJVwiICYmIChibHVlICo9IDIuNTUpO1xuICAgICAgICAgICAgICAgIHJnYlsxXS50b0xvd2VyQ2FzZSgpLnNsaWNlKDAsIDQpID09IFwicmdiYVwiICYmIChvcGFjaXR5ID0gdG9GbG9hdCh2YWx1ZXNbM10pKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbM10gJiYgdmFsdWVzWzNdLnNsaWNlKC0xKSA9PSBcIiVcIiAmJiAob3BhY2l0eSAvPSAxMDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJnYls1XSkge1xuICAgICAgICAgICAgICAgIHZhbHVlcyA9IHJnYls1XVtzcGxpdF0oY29tbWFTcGFjZXMpO1xuICAgICAgICAgICAgICAgIHJlZCA9IHRvRmxvYXQodmFsdWVzWzBdKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbMF0uc2xpY2UoLTEpID09IFwiJVwiICYmIChyZWQgKj0gMi41NSk7XG4gICAgICAgICAgICAgICAgZ3JlZW4gPSB0b0Zsb2F0KHZhbHVlc1sxXSk7XG4gICAgICAgICAgICAgICAgdmFsdWVzWzFdLnNsaWNlKC0xKSA9PSBcIiVcIiAmJiAoZ3JlZW4gKj0gMi41NSk7XG4gICAgICAgICAgICAgICAgYmx1ZSA9IHRvRmxvYXQodmFsdWVzWzJdKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbMl0uc2xpY2UoLTEpID09IFwiJVwiICYmIChibHVlICo9IDIuNTUpO1xuICAgICAgICAgICAgICAgICh2YWx1ZXNbMF0uc2xpY2UoLTMpID09IFwiZGVnXCIgfHwgdmFsdWVzWzBdLnNsaWNlKC0xKSA9PSBcIlxceGIwXCIpICYmIChyZWQgLz0gMzYwKTtcbiAgICAgICAgICAgICAgICByZ2JbMV0udG9Mb3dlckNhc2UoKS5zbGljZSgwLCA0KSA9PSBcImhzYmFcIiAmJiAob3BhY2l0eSA9IHRvRmxvYXQodmFsdWVzWzNdKSk7XG4gICAgICAgICAgICAgICAgdmFsdWVzWzNdICYmIHZhbHVlc1szXS5zbGljZSgtMSkgPT0gXCIlXCIgJiYgKG9wYWNpdHkgLz0gMTAwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gUi5oc2IycmdiKHJlZCwgZ3JlZW4sIGJsdWUsIG9wYWNpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJnYls2XSkge1xuICAgICAgICAgICAgICAgIHZhbHVlcyA9IHJnYls2XVtzcGxpdF0oY29tbWFTcGFjZXMpO1xuICAgICAgICAgICAgICAgIHJlZCA9IHRvRmxvYXQodmFsdWVzWzBdKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbMF0uc2xpY2UoLTEpID09IFwiJVwiICYmIChyZWQgKj0gMi41NSk7XG4gICAgICAgICAgICAgICAgZ3JlZW4gPSB0b0Zsb2F0KHZhbHVlc1sxXSk7XG4gICAgICAgICAgICAgICAgdmFsdWVzWzFdLnNsaWNlKC0xKSA9PSBcIiVcIiAmJiAoZ3JlZW4gKj0gMi41NSk7XG4gICAgICAgICAgICAgICAgYmx1ZSA9IHRvRmxvYXQodmFsdWVzWzJdKTtcbiAgICAgICAgICAgICAgICB2YWx1ZXNbMl0uc2xpY2UoLTEpID09IFwiJVwiICYmIChibHVlICo9IDIuNTUpO1xuICAgICAgICAgICAgICAgICh2YWx1ZXNbMF0uc2xpY2UoLTMpID09IFwiZGVnXCIgfHwgdmFsdWVzWzBdLnNsaWNlKC0xKSA9PSBcIlxceGIwXCIpICYmIChyZWQgLz0gMzYwKTtcbiAgICAgICAgICAgICAgICByZ2JbMV0udG9Mb3dlckNhc2UoKS5zbGljZSgwLCA0KSA9PSBcImhzbGFcIiAmJiAob3BhY2l0eSA9IHRvRmxvYXQodmFsdWVzWzNdKSk7XG4gICAgICAgICAgICAgICAgdmFsdWVzWzNdICYmIHZhbHVlc1szXS5zbGljZSgtMSkgPT0gXCIlXCIgJiYgKG9wYWNpdHkgLz0gMTAwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gUi5oc2wycmdiKHJlZCwgZ3JlZW4sIGJsdWUsIG9wYWNpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmdiID0ge3I6IHJlZCwgZzogZ3JlZW4sIGI6IGJsdWUsIHRvU3RyaW5nOiBjbHJUb1N0cmluZ307XG4gICAgICAgICAgICByZ2IuaGV4ID0gXCIjXCIgKyAoMTY3NzcyMTYgfCBibHVlIHwgKGdyZWVuIDw8IDgpIHwgKHJlZCA8PCAxNikpLnRvU3RyaW5nKDE2KS5zbGljZSgxKTtcbiAgICAgICAgICAgIFIuaXMob3BhY2l0eSwgXCJmaW5pdGVcIikgJiYgKHJnYi5vcGFjaXR5ID0gb3BhY2l0eSk7XG4gICAgICAgICAgICByZXR1cm4gcmdiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7cjogLTEsIGc6IC0xLCBiOiAtMSwgaGV4OiBcIm5vbmVcIiwgZXJyb3I6IDEsIHRvU3RyaW5nOiBjbHJUb1N0cmluZ307XG4gICAgfSwgUik7XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuaHNiXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBDb252ZXJ0cyBIU0IgdmFsdWVzIHRvIGhleCByZXByZXNlbnRhdGlvbiBvZiB0aGUgY29sb3VyLlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoIChudW1iZXIpIGh1ZVxuICAgICAtIHMgKG51bWJlcikgc2F0dXJhdGlvblxuICAgICAtIGIgKG51bWJlcikgdmFsdWUgb3IgYnJpZ2h0bmVzc1xuICAgICA9IChzdHJpbmcpIGhleCByZXByZXNlbnRhdGlvbiBvZiB0aGUgY29sb3VyLlxuICAgIFxcKi9cbiAgICBSLmhzYiA9IGNhY2hlcihmdW5jdGlvbiAoaCwgcywgYikge1xuICAgICAgICByZXR1cm4gUi5oc2IycmdiKGgsIHMsIGIpLmhleDtcbiAgICB9KTtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5oc2xcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIENvbnZlcnRzIEhTTCB2YWx1ZXMgdG8gaGV4IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjb2xvdXIuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIGggKG51bWJlcikgaHVlXG4gICAgIC0gcyAobnVtYmVyKSBzYXR1cmF0aW9uXG4gICAgIC0gbCAobnVtYmVyKSBsdW1pbm9zaXR5XG4gICAgID0gKHN0cmluZykgaGV4IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjb2xvdXIuXG4gICAgXFwqL1xuICAgIFIuaHNsID0gY2FjaGVyKGZ1bmN0aW9uIChoLCBzLCBsKSB7XG4gICAgICAgIHJldHVybiBSLmhzbDJyZ2IoaCwgcywgbCkuaGV4O1xuICAgIH0pO1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnJnYlxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQ29udmVydHMgUkdCIHZhbHVlcyB0byBoZXggcmVwcmVzZW50YXRpb24gb2YgdGhlIGNvbG91ci5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gciAobnVtYmVyKSByZWRcbiAgICAgLSBnIChudW1iZXIpIGdyZWVuXG4gICAgIC0gYiAobnVtYmVyKSBibHVlXG4gICAgID0gKHN0cmluZykgaGV4IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjb2xvdXIuXG4gICAgXFwqL1xuICAgIFIucmdiID0gY2FjaGVyKGZ1bmN0aW9uIChyLCBnLCBiKSB7XG4gICAgICAgIGZ1bmN0aW9uIHJvdW5kKHgpIHsgcmV0dXJuICh4ICsgMC41KSB8IDA7IH1cbiAgICAgICAgcmV0dXJuIFwiI1wiICsgKDE2Nzc3MjE2IHwgcm91bmQoYikgfCAocm91bmQoZykgPDwgOCkgfCAocm91bmQocikgPDwgMTYpKS50b1N0cmluZygxNikuc2xpY2UoMSk7XG4gICAgfSk7XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZ2V0Q29sb3JcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIE9uIGVhY2ggY2FsbCByZXR1cm5zIG5leHQgY29sb3VyIGluIHRoZSBzcGVjdHJ1bS4gVG8gcmVzZXQgaXQgYmFjayB0byByZWQgY2FsbCBAUmFwaGFlbC5nZXRDb2xvci5yZXNldFxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSB2YWx1ZSAobnVtYmVyKSAjb3B0aW9uYWwgYnJpZ2h0bmVzcywgZGVmYXVsdCBpcyBgMC43NWBcbiAgICAgPSAoc3RyaW5nKSBoZXggcmVwcmVzZW50YXRpb24gb2YgdGhlIGNvbG91ci5cbiAgICBcXCovXG4gICAgUi5nZXRDb2xvciA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgc3RhcnQgPSB0aGlzLmdldENvbG9yLnN0YXJ0ID0gdGhpcy5nZXRDb2xvci5zdGFydCB8fCB7aDogMCwgczogMSwgYjogdmFsdWUgfHwgLjc1fSxcbiAgICAgICAgICAgIHJnYiA9IHRoaXMuaHNiMnJnYihzdGFydC5oLCBzdGFydC5zLCBzdGFydC5iKTtcbiAgICAgICAgc3RhcnQuaCArPSAuMDc1O1xuICAgICAgICBpZiAoc3RhcnQuaCA+IDEpIHtcbiAgICAgICAgICAgIHN0YXJ0LmggPSAwO1xuICAgICAgICAgICAgc3RhcnQucyAtPSAuMjtcbiAgICAgICAgICAgIHN0YXJ0LnMgPD0gMCAmJiAodGhpcy5nZXRDb2xvci5zdGFydCA9IHtoOiAwLCBzOiAxLCBiOiBzdGFydC5ifSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJnYi5oZXg7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5nZXRDb2xvci5yZXNldFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVzZXRzIHNwZWN0cnVtIHBvc2l0aW9uIGZvciBAUmFwaGFlbC5nZXRDb2xvciBiYWNrIHRvIHJlZC5cbiAgICBcXCovXG4gICAgUi5nZXRDb2xvci5yZXNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuc3RhcnQ7XG4gICAgfTtcblxuICAgIC8vIGh0dHA6Ly9zY2hlcGVycy5jYy9nZXR0aW5nLXRvLXRoZS1wb2ludFxuICAgIGZ1bmN0aW9uIGNhdG11bGxSb20yYmV6aWVyKGNycCwgeikge1xuICAgICAgICB2YXIgZCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgaUxlbiA9IGNycC5sZW5ndGg7IGlMZW4gLSAyICogIXogPiBpOyBpICs9IDIpIHtcbiAgICAgICAgICAgIHZhciBwID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAge3g6ICtjcnBbaSAtIDJdLCB5OiArY3JwW2kgLSAxXX0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7eDogK2NycFtpXSwgICAgIHk6ICtjcnBbaSArIDFdfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHt4OiArY3JwW2kgKyAyXSwgeTogK2NycFtpICsgM119LFxuICAgICAgICAgICAgICAgICAgICAgICAge3g6ICtjcnBbaSArIDRdLCB5OiArY3JwW2kgKyA1XX1cbiAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIGlmICh6KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFpKSB7XG4gICAgICAgICAgICAgICAgICAgIHBbMF0gPSB7eDogK2NycFtpTGVuIC0gMl0sIHk6ICtjcnBbaUxlbiAtIDFdfTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlMZW4gLSA0ID09IGkpIHtcbiAgICAgICAgICAgICAgICAgICAgcFszXSA9IHt4OiArY3JwWzBdLCB5OiArY3JwWzFdfTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlMZW4gLSAyID09IGkpIHtcbiAgICAgICAgICAgICAgICAgICAgcFsyXSA9IHt4OiArY3JwWzBdLCB5OiArY3JwWzFdfTtcbiAgICAgICAgICAgICAgICAgICAgcFszXSA9IHt4OiArY3JwWzJdLCB5OiArY3JwWzNdfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChpTGVuIC0gNCA9PSBpKSB7XG4gICAgICAgICAgICAgICAgICAgIHBbM10gPSBwWzJdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWkpIHtcbiAgICAgICAgICAgICAgICAgICAgcFswXSA9IHt4OiArY3JwW2ldLCB5OiArY3JwW2kgKyAxXX07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZC5wdXNoKFtcIkNcIixcbiAgICAgICAgICAgICAgICAgICgtcFswXS54ICsgNiAqIHBbMV0ueCArIHBbMl0ueCkgLyA2LFxuICAgICAgICAgICAgICAgICAgKC1wWzBdLnkgKyA2ICogcFsxXS55ICsgcFsyXS55KSAvIDYsXG4gICAgICAgICAgICAgICAgICAocFsxXS54ICsgNiAqIHBbMl0ueCAtIHBbM10ueCkgLyA2LFxuICAgICAgICAgICAgICAgICAgKHBbMV0ueSArIDYqcFsyXS55IC0gcFszXS55KSAvIDYsXG4gICAgICAgICAgICAgICAgICBwWzJdLngsXG4gICAgICAgICAgICAgICAgICBwWzJdLnlcbiAgICAgICAgICAgIF0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGQ7XG4gICAgfVxuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnBhcnNlUGF0aFN0cmluZ1xuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogVXRpbGl0eSBtZXRob2RcbiAgICAgKipcbiAgICAgKiBQYXJzZXMgZ2l2ZW4gcGF0aCBzdHJpbmcgaW50byBhbiBhcnJheSBvZiBhcnJheXMgb2YgcGF0aCBzZWdtZW50cy5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gcGF0aFN0cmluZyAoc3RyaW5nfGFycmF5KSBwYXRoIHN0cmluZyBvciBhcnJheSBvZiBzZWdtZW50cyAoaW4gdGhlIGxhc3QgY2FzZSBpdCB3aWxsIGJlIHJldHVybmVkIHN0cmFpZ2h0IGF3YXkpXG4gICAgID0gKGFycmF5KSBhcnJheSBvZiBzZWdtZW50cy5cbiAgICBcXCovXG4gICAgUi5wYXJzZVBhdGhTdHJpbmcgPSBmdW5jdGlvbiAocGF0aFN0cmluZykge1xuICAgICAgICBpZiAoIXBhdGhTdHJpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwdGggPSBwYXRocyhwYXRoU3RyaW5nKTtcbiAgICAgICAgaWYgKHB0aC5hcnIpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXRoQ2xvbmUocHRoLmFycik7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcGFyYW1Db3VudHMgPSB7YTogNywgYzogNiwgaDogMSwgbDogMiwgbTogMiwgcjogNCwgcTogNCwgczogNCwgdDogMiwgdjogMSwgejogMH0sXG4gICAgICAgICAgICBkYXRhID0gW107XG4gICAgICAgIGlmIChSLmlzKHBhdGhTdHJpbmcsIGFycmF5KSAmJiBSLmlzKHBhdGhTdHJpbmdbMF0sIGFycmF5KSkgeyAvLyByb3VnaCBhc3N1bXB0aW9uXG4gICAgICAgICAgICBkYXRhID0gcGF0aENsb25lKHBhdGhTdHJpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgIFN0cihwYXRoU3RyaW5nKS5yZXBsYWNlKHBhdGhDb21tYW5kLCBmdW5jdGlvbiAoYSwgYiwgYykge1xuICAgICAgICAgICAgICAgIHZhciBwYXJhbXMgPSBbXSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGIudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgICAgICBjLnJlcGxhY2UocGF0aFZhbHVlcywgZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgICAgICAgICAgYiAmJiBwYXJhbXMucHVzaCgrYik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKG5hbWUgPT0gXCJtXCIgJiYgcGFyYW1zLmxlbmd0aCA+IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5wdXNoKFtiXVtjb25jYXRdKHBhcmFtcy5zcGxpY2UoMCwgMikpKTtcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IFwibFwiO1xuICAgICAgICAgICAgICAgICAgICBiID0gYiA9PSBcIm1cIiA/IFwibFwiIDogXCJMXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChuYW1lID09IFwiclwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGEucHVzaChbYl1bY29uY2F0XShwYXJhbXMpKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Ugd2hpbGUgKHBhcmFtcy5sZW5ndGggPj0gcGFyYW1Db3VudHNbbmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5wdXNoKFtiXVtjb25jYXRdKHBhcmFtcy5zcGxpY2UoMCwgcGFyYW1Db3VudHNbbmFtZV0pKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghcGFyYW1Db3VudHNbbmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZGF0YS50b1N0cmluZyA9IFIuX3BhdGgyc3RyaW5nO1xuICAgICAgICBwdGguYXJyID0gcGF0aENsb25lKGRhdGEpO1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnBhcnNlVHJhbnNmb3JtU3RyaW5nXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBVdGlsaXR5IG1ldGhvZFxuICAgICAqKlxuICAgICAqIFBhcnNlcyBnaXZlbiBwYXRoIHN0cmluZyBpbnRvIGFuIGFycmF5IG9mIHRyYW5zZm9ybWF0aW9ucy5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gVFN0cmluZyAoc3RyaW5nfGFycmF5KSB0cmFuc2Zvcm0gc3RyaW5nIG9yIGFycmF5IG9mIHRyYW5zZm9ybWF0aW9ucyAoaW4gdGhlIGxhc3QgY2FzZSBpdCB3aWxsIGJlIHJldHVybmVkIHN0cmFpZ2h0IGF3YXkpXG4gICAgID0gKGFycmF5KSBhcnJheSBvZiB0cmFuc2Zvcm1hdGlvbnMuXG4gICAgXFwqL1xuICAgIFIucGFyc2VUcmFuc2Zvcm1TdHJpbmcgPSBjYWNoZXIoZnVuY3Rpb24gKFRTdHJpbmcpIHtcbiAgICAgICAgaWYgKCFUU3RyaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcGFyYW1Db3VudHMgPSB7cjogMywgczogNCwgdDogMiwgbTogNn0sXG4gICAgICAgICAgICBkYXRhID0gW107XG4gICAgICAgIGlmIChSLmlzKFRTdHJpbmcsIGFycmF5KSAmJiBSLmlzKFRTdHJpbmdbMF0sIGFycmF5KSkgeyAvLyByb3VnaCBhc3N1bXB0aW9uXG4gICAgICAgICAgICBkYXRhID0gcGF0aENsb25lKFRTdHJpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgIFN0cihUU3RyaW5nKS5yZXBsYWNlKHRDb21tYW5kLCBmdW5jdGlvbiAoYSwgYiwgYykge1xuICAgICAgICAgICAgICAgIHZhciBwYXJhbXMgPSBbXSxcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGxvd2VyQ2FzZS5jYWxsKGIpO1xuICAgICAgICAgICAgICAgIGMucmVwbGFjZShwYXRoVmFsdWVzLCBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgICAgICBiICYmIHBhcmFtcy5wdXNoKCtiKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBkYXRhLnB1c2goW2JdW2NvbmNhdF0ocGFyYW1zKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBkYXRhLnRvU3RyaW5nID0gUi5fcGF0aDJzdHJpbmc7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH0pO1xuICAgIC8vIFBBVEhTXG4gICAgdmFyIHBhdGhzID0gZnVuY3Rpb24gKHBzKSB7XG4gICAgICAgIHZhciBwID0gcGF0aHMucHMgPSBwYXRocy5wcyB8fCB7fTtcbiAgICAgICAgaWYgKHBbcHNdKSB7XG4gICAgICAgICAgICBwW3BzXS5zbGVlcCA9IDEwMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBbcHNdID0ge1xuICAgICAgICAgICAgICAgIHNsZWVwOiAxMDBcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gcCkgaWYgKHBbaGFzXShrZXkpICYmIGtleSAhPSBwcykge1xuICAgICAgICAgICAgICAgIHBba2V5XS5zbGVlcC0tO1xuICAgICAgICAgICAgICAgICFwW2tleV0uc2xlZXAgJiYgZGVsZXRlIHBba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwW3BzXTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLmZpbmREb3RzQXRTZWdtZW50XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBVdGlsaXR5IG1ldGhvZFxuICAgICAqKlxuICAgICAqIEZpbmQgZG90IGNvb3JkaW5hdGVzIG9uIHRoZSBnaXZlbiBjdWJpYyBiZXppZXIgY3VydmUgYXQgdGhlIGdpdmVuIHQuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIHAxeCAobnVtYmVyKSB4IG9mIHRoZSBmaXJzdCBwb2ludCBvZiB0aGUgY3VydmVcbiAgICAgLSBwMXkgKG51bWJlcikgeSBvZiB0aGUgZmlyc3QgcG9pbnQgb2YgdGhlIGN1cnZlXG4gICAgIC0gYzF4IChudW1iZXIpIHggb2YgdGhlIGZpcnN0IGFuY2hvciBvZiB0aGUgY3VydmVcbiAgICAgLSBjMXkgKG51bWJlcikgeSBvZiB0aGUgZmlyc3QgYW5jaG9yIG9mIHRoZSBjdXJ2ZVxuICAgICAtIGMyeCAobnVtYmVyKSB4IG9mIHRoZSBzZWNvbmQgYW5jaG9yIG9mIHRoZSBjdXJ2ZVxuICAgICAtIGMyeSAobnVtYmVyKSB5IG9mIHRoZSBzZWNvbmQgYW5jaG9yIG9mIHRoZSBjdXJ2ZVxuICAgICAtIHAyeCAobnVtYmVyKSB4IG9mIHRoZSBzZWNvbmQgcG9pbnQgb2YgdGhlIGN1cnZlXG4gICAgIC0gcDJ5IChudW1iZXIpIHkgb2YgdGhlIHNlY29uZCBwb2ludCBvZiB0aGUgY3VydmVcbiAgICAgLSB0IChudW1iZXIpIHBvc2l0aW9uIG9uIHRoZSBjdXJ2ZSAoMC4uMSlcbiAgICAgPSAob2JqZWN0KSBwb2ludCBpbmZvcm1hdGlvbiBpbiBmb3JtYXQ6XG4gICAgIG8ge1xuICAgICBvICAgICB4OiAobnVtYmVyKSB4IGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50XG4gICAgIG8gICAgIHk6IChudW1iZXIpIHkgY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnRcbiAgICAgbyAgICAgbToge1xuICAgICBvICAgICAgICAgeDogKG51bWJlcikgeCBjb29yZGluYXRlIG9mIHRoZSBsZWZ0IGFuY2hvclxuICAgICBvICAgICAgICAgeTogKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSBsZWZ0IGFuY2hvclxuICAgICBvICAgICB9XG4gICAgIG8gICAgIG46IHtcbiAgICAgbyAgICAgICAgIHg6IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgcmlnaHQgYW5jaG9yXG4gICAgIG8gICAgICAgICB5OiAobnVtYmVyKSB5IGNvb3JkaW5hdGUgb2YgdGhlIHJpZ2h0IGFuY2hvclxuICAgICBvICAgICB9XG4gICAgIG8gICAgIHN0YXJ0OiB7XG4gICAgIG8gICAgICAgICB4OiAobnVtYmVyKSB4IGNvb3JkaW5hdGUgb2YgdGhlIHN0YXJ0IG9mIHRoZSBjdXJ2ZVxuICAgICBvICAgICAgICAgeTogKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSBzdGFydCBvZiB0aGUgY3VydmVcbiAgICAgbyAgICAgfVxuICAgICBvICAgICBlbmQ6IHtcbiAgICAgbyAgICAgICAgIHg6IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgZW5kIG9mIHRoZSBjdXJ2ZVxuICAgICBvICAgICAgICAgeTogKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSBlbmQgb2YgdGhlIGN1cnZlXG4gICAgIG8gICAgIH1cbiAgICAgbyAgICAgYWxwaGE6IChudW1iZXIpIGFuZ2xlIG9mIHRoZSBjdXJ2ZSBkZXJpdmF0aXZlIGF0IHRoZSBwb2ludFxuICAgICBvIH1cbiAgICBcXCovXG4gICAgUi5maW5kRG90c0F0U2VnbWVudCA9IGZ1bmN0aW9uIChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSwgdCkge1xuICAgICAgICB2YXIgdDEgPSAxIC0gdCxcbiAgICAgICAgICAgIHQxMyA9IHBvdyh0MSwgMyksXG4gICAgICAgICAgICB0MTIgPSBwb3codDEsIDIpLFxuICAgICAgICAgICAgdDIgPSB0ICogdCxcbiAgICAgICAgICAgIHQzID0gdDIgKiB0LFxuICAgICAgICAgICAgeCA9IHQxMyAqIHAxeCArIHQxMiAqIDMgKiB0ICogYzF4ICsgdDEgKiAzICogdCAqIHQgKiBjMnggKyB0MyAqIHAyeCxcbiAgICAgICAgICAgIHkgPSB0MTMgKiBwMXkgKyB0MTIgKiAzICogdCAqIGMxeSArIHQxICogMyAqIHQgKiB0ICogYzJ5ICsgdDMgKiBwMnksXG4gICAgICAgICAgICBteCA9IHAxeCArIDIgKiB0ICogKGMxeCAtIHAxeCkgKyB0MiAqIChjMnggLSAyICogYzF4ICsgcDF4KSxcbiAgICAgICAgICAgIG15ID0gcDF5ICsgMiAqIHQgKiAoYzF5IC0gcDF5KSArIHQyICogKGMyeSAtIDIgKiBjMXkgKyBwMXkpLFxuICAgICAgICAgICAgbnggPSBjMXggKyAyICogdCAqIChjMnggLSBjMXgpICsgdDIgKiAocDJ4IC0gMiAqIGMyeCArIGMxeCksXG4gICAgICAgICAgICBueSA9IGMxeSArIDIgKiB0ICogKGMyeSAtIGMxeSkgKyB0MiAqIChwMnkgLSAyICogYzJ5ICsgYzF5KSxcbiAgICAgICAgICAgIGF4ID0gdDEgKiBwMXggKyB0ICogYzF4LFxuICAgICAgICAgICAgYXkgPSB0MSAqIHAxeSArIHQgKiBjMXksXG4gICAgICAgICAgICBjeCA9IHQxICogYzJ4ICsgdCAqIHAyeCxcbiAgICAgICAgICAgIGN5ID0gdDEgKiBjMnkgKyB0ICogcDJ5LFxuICAgICAgICAgICAgYWxwaGEgPSAoOTAgLSBtYXRoLmF0YW4yKG14IC0gbngsIG15IC0gbnkpICogMTgwIC8gUEkpO1xuICAgICAgICAobXggPiBueCB8fCBteSA8IG55KSAmJiAoYWxwaGEgKz0gMTgwKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICB5OiB5LFxuICAgICAgICAgICAgbToge3g6IG14LCB5OiBteX0sXG4gICAgICAgICAgICBuOiB7eDogbngsIHk6IG55fSxcbiAgICAgICAgICAgIHN0YXJ0OiB7eDogYXgsIHk6IGF5fSxcbiAgICAgICAgICAgIGVuZDoge3g6IGN4LCB5OiBjeX0sXG4gICAgICAgICAgICBhbHBoYTogYWxwaGFcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLmJlemllckJCb3hcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFV0aWxpdHkgbWV0aG9kXG4gICAgICoqXG4gICAgICogUmV0dXJuIGJvdW5kaW5nIGJveCBvZiBhIGdpdmVuIGN1YmljIGJlemllciBjdXJ2ZVxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBwMXggKG51bWJlcikgeCBvZiB0aGUgZmlyc3QgcG9pbnQgb2YgdGhlIGN1cnZlXG4gICAgIC0gcDF5IChudW1iZXIpIHkgb2YgdGhlIGZpcnN0IHBvaW50IG9mIHRoZSBjdXJ2ZVxuICAgICAtIGMxeCAobnVtYmVyKSB4IG9mIHRoZSBmaXJzdCBhbmNob3Igb2YgdGhlIGN1cnZlXG4gICAgIC0gYzF5IChudW1iZXIpIHkgb2YgdGhlIGZpcnN0IGFuY2hvciBvZiB0aGUgY3VydmVcbiAgICAgLSBjMnggKG51bWJlcikgeCBvZiB0aGUgc2Vjb25kIGFuY2hvciBvZiB0aGUgY3VydmVcbiAgICAgLSBjMnkgKG51bWJlcikgeSBvZiB0aGUgc2Vjb25kIGFuY2hvciBvZiB0aGUgY3VydmVcbiAgICAgLSBwMnggKG51bWJlcikgeCBvZiB0aGUgc2Vjb25kIHBvaW50IG9mIHRoZSBjdXJ2ZVxuICAgICAtIHAyeSAobnVtYmVyKSB5IG9mIHRoZSBzZWNvbmQgcG9pbnQgb2YgdGhlIGN1cnZlXG4gICAgICogb3JcbiAgICAgLSBiZXogKGFycmF5KSBhcnJheSBvZiBzaXggcG9pbnRzIGZvciBiZXppZXIgY3VydmVcbiAgICAgPSAob2JqZWN0KSBwb2ludCBpbmZvcm1hdGlvbiBpbiBmb3JtYXQ6XG4gICAgIG8ge1xuICAgICBvICAgICBtaW46IHtcbiAgICAgbyAgICAgICAgIHg6IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgbGVmdCBwb2ludFxuICAgICBvICAgICAgICAgeTogKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSB0b3AgcG9pbnRcbiAgICAgbyAgICAgfVxuICAgICBvICAgICBtYXg6IHtcbiAgICAgbyAgICAgICAgIHg6IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgcmlnaHQgcG9pbnRcbiAgICAgbyAgICAgICAgIHk6IChudW1iZXIpIHkgY29vcmRpbmF0ZSBvZiB0aGUgYm90dG9tIHBvaW50XG4gICAgIG8gICAgIH1cbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIFIuYmV6aWVyQkJveCA9IGZ1bmN0aW9uIChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSkge1xuICAgICAgICBpZiAoIVIuaXMocDF4LCBcImFycmF5XCIpKSB7XG4gICAgICAgICAgICBwMXggPSBbcDF4LCBwMXksIGMxeCwgYzF5LCBjMngsIGMyeSwgcDJ4LCBwMnldO1xuICAgICAgICB9XG4gICAgICAgIHZhciBiYm94ID0gY3VydmVEaW0uYXBwbHkobnVsbCwgcDF4KTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IGJib3gubWluLngsXG4gICAgICAgICAgICB5OiBiYm94Lm1pbi55LFxuICAgICAgICAgICAgeDI6IGJib3gubWF4LngsXG4gICAgICAgICAgICB5MjogYmJveC5tYXgueSxcbiAgICAgICAgICAgIHdpZHRoOiBiYm94Lm1heC54IC0gYmJveC5taW4ueCxcbiAgICAgICAgICAgIGhlaWdodDogYmJveC5tYXgueSAtIGJib3gubWluLnlcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLmlzUG9pbnRJbnNpZGVCQm94XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBVdGlsaXR5IG1ldGhvZFxuICAgICAqKlxuICAgICAqIFJldHVybnMgYHRydWVgIGlmIGdpdmVuIHBvaW50IGlzIGluc2lkZSBib3VuZGluZyBib3hlcy5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gYmJveCAoc3RyaW5nKSBib3VuZGluZyBib3hcbiAgICAgLSB4IChzdHJpbmcpIHggY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnRcbiAgICAgLSB5IChzdHJpbmcpIHkgY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnRcbiAgICAgPSAoYm9vbGVhbikgYHRydWVgIGlmIHBvaW50IGluc2lkZVxuICAgIFxcKi9cbiAgICBSLmlzUG9pbnRJbnNpZGVCQm94ID0gZnVuY3Rpb24gKGJib3gsIHgsIHkpIHtcbiAgICAgICAgcmV0dXJuIHggPj0gYmJveC54ICYmIHggPD0gYmJveC54MiAmJiB5ID49IGJib3gueSAmJiB5IDw9IGJib3gueTI7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5pc0JCb3hJbnRlcnNlY3RcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFV0aWxpdHkgbWV0aG9kXG4gICAgICoqXG4gICAgICogUmV0dXJucyBgdHJ1ZWAgaWYgdHdvIGJvdW5kaW5nIGJveGVzIGludGVyc2VjdFxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBiYm94MSAoc3RyaW5nKSBmaXJzdCBib3VuZGluZyBib3hcbiAgICAgLSBiYm94MiAoc3RyaW5nKSBzZWNvbmQgYm91bmRpbmcgYm94XG4gICAgID0gKGJvb2xlYW4pIGB0cnVlYCBpZiB0aGV5IGludGVyc2VjdFxuICAgIFxcKi9cbiAgICBSLmlzQkJveEludGVyc2VjdCA9IGZ1bmN0aW9uIChiYm94MSwgYmJveDIpIHtcbiAgICAgICAgdmFyIGkgPSBSLmlzUG9pbnRJbnNpZGVCQm94O1xuICAgICAgICByZXR1cm4gaShiYm94MiwgYmJveDEueCwgYmJveDEueSlcbiAgICAgICAgICAgIHx8IGkoYmJveDIsIGJib3gxLngyLCBiYm94MS55KVxuICAgICAgICAgICAgfHwgaShiYm94MiwgYmJveDEueCwgYmJveDEueTIpXG4gICAgICAgICAgICB8fCBpKGJib3gyLCBiYm94MS54MiwgYmJveDEueTIpXG4gICAgICAgICAgICB8fCBpKGJib3gxLCBiYm94Mi54LCBiYm94Mi55KVxuICAgICAgICAgICAgfHwgaShiYm94MSwgYmJveDIueDIsIGJib3gyLnkpXG4gICAgICAgICAgICB8fCBpKGJib3gxLCBiYm94Mi54LCBiYm94Mi55MilcbiAgICAgICAgICAgIHx8IGkoYmJveDEsIGJib3gyLngyLCBiYm94Mi55MilcbiAgICAgICAgICAgIHx8IChiYm94MS54IDwgYmJveDIueDIgJiYgYmJveDEueCA+IGJib3gyLnggfHwgYmJveDIueCA8IGJib3gxLngyICYmIGJib3gyLnggPiBiYm94MS54KVxuICAgICAgICAgICAgJiYgKGJib3gxLnkgPCBiYm94Mi55MiAmJiBiYm94MS55ID4gYmJveDIueSB8fCBiYm94Mi55IDwgYmJveDEueTIgJiYgYmJveDIueSA+IGJib3gxLnkpO1xuICAgIH07XG4gICAgZnVuY3Rpb24gYmFzZTModCwgcDEsIHAyLCBwMywgcDQpIHtcbiAgICAgICAgdmFyIHQxID0gLTMgKiBwMSArIDkgKiBwMiAtIDkgKiBwMyArIDMgKiBwNCxcbiAgICAgICAgICAgIHQyID0gdCAqIHQxICsgNiAqIHAxIC0gMTIgKiBwMiArIDYgKiBwMztcbiAgICAgICAgcmV0dXJuIHQgKiB0MiAtIDMgKiBwMSArIDMgKiBwMjtcbiAgICB9XG4gICAgZnVuY3Rpb24gYmV6bGVuKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHg0LCB5NCwgeikge1xuICAgICAgICBpZiAoeiA9PSBudWxsKSB7XG4gICAgICAgICAgICB6ID0gMTtcbiAgICAgICAgfVxuICAgICAgICB6ID0geiA+IDEgPyAxIDogeiA8IDAgPyAwIDogejtcbiAgICAgICAgdmFyIHoyID0geiAvIDIsXG4gICAgICAgICAgICBuID0gMTIsXG4gICAgICAgICAgICBUdmFsdWVzID0gWy0wLjEyNTIsMC4xMjUyLC0wLjM2NzgsMC4zNjc4LC0wLjU4NzMsMC41ODczLC0wLjc2OTksMC43Njk5LC0wLjkwNDEsMC45MDQxLC0wLjk4MTYsMC45ODE2XSxcbiAgICAgICAgICAgIEN2YWx1ZXMgPSBbMC4yNDkxLDAuMjQ5MSwwLjIzMzUsMC4yMzM1LDAuMjAzMiwwLjIwMzIsMC4xNjAxLDAuMTYwMSwwLjEwNjksMC4xMDY5LDAuMDQ3MiwwLjA0NzJdLFxuICAgICAgICAgICAgc3VtID0gMDtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBjdCA9IHoyICogVHZhbHVlc1tpXSArIHoyLFxuICAgICAgICAgICAgICAgIHhiYXNlID0gYmFzZTMoY3QsIHgxLCB4MiwgeDMsIHg0KSxcbiAgICAgICAgICAgICAgICB5YmFzZSA9IGJhc2UzKGN0LCB5MSwgeTIsIHkzLCB5NCksXG4gICAgICAgICAgICAgICAgY29tYiA9IHhiYXNlICogeGJhc2UgKyB5YmFzZSAqIHliYXNlO1xuICAgICAgICAgICAgc3VtICs9IEN2YWx1ZXNbaV0gKiBtYXRoLnNxcnQoY29tYik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHoyICogc3VtO1xuICAgIH1cbiAgICBmdW5jdGlvbiBnZXRUYXRMZW4oeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCBsbCkge1xuICAgICAgICBpZiAobGwgPCAwIHx8IGJlemxlbih4MSwgeTEsIHgyLCB5MiwgeDMsIHkzLCB4NCwgeTQpIDwgbGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdCA9IDEsXG4gICAgICAgICAgICBzdGVwID0gdCAvIDIsXG4gICAgICAgICAgICB0MiA9IHQgLSBzdGVwLFxuICAgICAgICAgICAgbCxcbiAgICAgICAgICAgIGUgPSAuMDE7XG4gICAgICAgIGwgPSBiZXpsZW4oeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCB0Mik7XG4gICAgICAgIHdoaWxlIChhYnMobCAtIGxsKSA+IGUpIHtcbiAgICAgICAgICAgIHN0ZXAgLz0gMjtcbiAgICAgICAgICAgIHQyICs9IChsIDwgbGwgPyAxIDogLTEpICogc3RlcDtcbiAgICAgICAgICAgIGwgPSBiZXpsZW4oeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0LCB0Mik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQyO1xuICAgIH1cbiAgICBmdW5jdGlvbiBpbnRlcnNlY3QoeDEsIHkxLCB4MiwgeTIsIHgzLCB5MywgeDQsIHk0KSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIG1tYXgoeDEsIHgyKSA8IG1taW4oeDMsIHg0KSB8fFxuICAgICAgICAgICAgbW1pbih4MSwgeDIpID4gbW1heCh4MywgeDQpIHx8XG4gICAgICAgICAgICBtbWF4KHkxLCB5MikgPCBtbWluKHkzLCB5NCkgfHxcbiAgICAgICAgICAgIG1taW4oeTEsIHkyKSA+IG1tYXgoeTMsIHk0KVxuICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbnggPSAoeDEgKiB5MiAtIHkxICogeDIpICogKHgzIC0geDQpIC0gKHgxIC0geDIpICogKHgzICogeTQgLSB5MyAqIHg0KSxcbiAgICAgICAgICAgIG55ID0gKHgxICogeTIgLSB5MSAqIHgyKSAqICh5MyAtIHk0KSAtICh5MSAtIHkyKSAqICh4MyAqIHk0IC0geTMgKiB4NCksXG4gICAgICAgICAgICBkZW5vbWluYXRvciA9ICh4MSAtIHgyKSAqICh5MyAtIHk0KSAtICh5MSAtIHkyKSAqICh4MyAtIHg0KTtcblxuICAgICAgICBpZiAoIWRlbm9taW5hdG9yKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHB4ID0gbnggLyBkZW5vbWluYXRvcixcbiAgICAgICAgICAgIHB5ID0gbnkgLyBkZW5vbWluYXRvcixcbiAgICAgICAgICAgIHB4MiA9ICtweC50b0ZpeGVkKDIpLFxuICAgICAgICAgICAgcHkyID0gK3B5LnRvRml4ZWQoMik7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHB4MiA8ICttbWluKHgxLCB4MikudG9GaXhlZCgyKSB8fFxuICAgICAgICAgICAgcHgyID4gK21tYXgoeDEsIHgyKS50b0ZpeGVkKDIpIHx8XG4gICAgICAgICAgICBweDIgPCArbW1pbih4MywgeDQpLnRvRml4ZWQoMikgfHxcbiAgICAgICAgICAgIHB4MiA+ICttbWF4KHgzLCB4NCkudG9GaXhlZCgyKSB8fFxuICAgICAgICAgICAgcHkyIDwgK21taW4oeTEsIHkyKS50b0ZpeGVkKDIpIHx8XG4gICAgICAgICAgICBweTIgPiArbW1heCh5MSwgeTIpLnRvRml4ZWQoMikgfHxcbiAgICAgICAgICAgIHB5MiA8ICttbWluKHkzLCB5NCkudG9GaXhlZCgyKSB8fFxuICAgICAgICAgICAgcHkyID4gK21tYXgoeTMsIHk0KS50b0ZpeGVkKDIpXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7eDogcHgsIHk6IHB5fTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaW50ZXIoYmV6MSwgYmV6Mikge1xuICAgICAgICByZXR1cm4gaW50ZXJIZWxwZXIoYmV6MSwgYmV6Mik7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGludGVyQ291bnQoYmV6MSwgYmV6Mikge1xuICAgICAgICByZXR1cm4gaW50ZXJIZWxwZXIoYmV6MSwgYmV6MiwgMSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGludGVySGVscGVyKGJlejEsIGJlejIsIGp1c3RDb3VudCkge1xuICAgICAgICB2YXIgYmJveDEgPSBSLmJlemllckJCb3goYmV6MSksXG4gICAgICAgICAgICBiYm94MiA9IFIuYmV6aWVyQkJveChiZXoyKTtcbiAgICAgICAgaWYgKCFSLmlzQkJveEludGVyc2VjdChiYm94MSwgYmJveDIpKSB7XG4gICAgICAgICAgICByZXR1cm4ganVzdENvdW50ID8gMCA6IFtdO1xuICAgICAgICB9XG4gICAgICAgIHZhciBsMSA9IGJlemxlbi5hcHBseSgwLCBiZXoxKSxcbiAgICAgICAgICAgIGwyID0gYmV6bGVuLmFwcGx5KDAsIGJlejIpLFxuICAgICAgICAgICAgbjEgPSBtbWF4KH5+KGwxIC8gNSksIDEpLFxuICAgICAgICAgICAgbjIgPSBtbWF4KH5+KGwyIC8gNSksIDEpLFxuICAgICAgICAgICAgZG90czEgPSBbXSxcbiAgICAgICAgICAgIGRvdHMyID0gW10sXG4gICAgICAgICAgICB4eSA9IHt9LFxuICAgICAgICAgICAgcmVzID0ganVzdENvdW50ID8gMCA6IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG4xICsgMTsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgcCA9IFIuZmluZERvdHNBdFNlZ21lbnQuYXBwbHkoUiwgYmV6MS5jb25jYXQoaSAvIG4xKSk7XG4gICAgICAgICAgICBkb3RzMS5wdXNoKHt4OiBwLngsIHk6IHAueSwgdDogaSAvIG4xfSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IG4yICsgMTsgaSsrKSB7XG4gICAgICAgICAgICBwID0gUi5maW5kRG90c0F0U2VnbWVudC5hcHBseShSLCBiZXoyLmNvbmNhdChpIC8gbjIpKTtcbiAgICAgICAgICAgIGRvdHMyLnB1c2goe3g6IHAueCwgeTogcC55LCB0OiBpIC8gbjJ9KTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbjE7IGkrKykge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBuMjsgaisrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRpID0gZG90czFbaV0sXG4gICAgICAgICAgICAgICAgICAgIGRpMSA9IGRvdHMxW2kgKyAxXSxcbiAgICAgICAgICAgICAgICAgICAgZGogPSBkb3RzMltqXSxcbiAgICAgICAgICAgICAgICAgICAgZGoxID0gZG90czJbaiArIDFdLFxuICAgICAgICAgICAgICAgICAgICBjaSA9IGFicyhkaTEueCAtIGRpLngpIDwgLjAwMSA/IFwieVwiIDogXCJ4XCIsXG4gICAgICAgICAgICAgICAgICAgIGNqID0gYWJzKGRqMS54IC0gZGoueCkgPCAuMDAxID8gXCJ5XCIgOiBcInhcIixcbiAgICAgICAgICAgICAgICAgICAgaXMgPSBpbnRlcnNlY3QoZGkueCwgZGkueSwgZGkxLngsIGRpMS55LCBkai54LCBkai55LCBkajEueCwgZGoxLnkpO1xuICAgICAgICAgICAgICAgIGlmIChpcykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoeHlbaXMueC50b0ZpeGVkKDQpXSA9PSBpcy55LnRvRml4ZWQoNCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHh5W2lzLngudG9GaXhlZCg0KV0gPSBpcy55LnRvRml4ZWQoNCk7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0MSA9IGRpLnQgKyBhYnMoKGlzW2NpXSAtIGRpW2NpXSkgLyAoZGkxW2NpXSAtIGRpW2NpXSkpICogKGRpMS50IC0gZGkudCksXG4gICAgICAgICAgICAgICAgICAgICAgICB0MiA9IGRqLnQgKyBhYnMoKGlzW2NqXSAtIGRqW2NqXSkgLyAoZGoxW2NqXSAtIGRqW2NqXSkpICogKGRqMS50IC0gZGoudCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0MSA+PSAwICYmIHQxIDw9IDEuMDAxICYmIHQyID49IDAgJiYgdDIgPD0gMS4wMDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqdXN0Q291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXMrKztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBpcy54LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBpcy55LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0MTogbW1pbih0MSwgMSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQyOiBtbWluKHQyLCAxKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnBhdGhJbnRlcnNlY3Rpb25cbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFV0aWxpdHkgbWV0aG9kXG4gICAgICoqXG4gICAgICogRmluZHMgaW50ZXJzZWN0aW9ucyBvZiB0d28gcGF0aHNcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gcGF0aDEgKHN0cmluZykgcGF0aCBzdHJpbmdcbiAgICAgLSBwYXRoMiAoc3RyaW5nKSBwYXRoIHN0cmluZ1xuICAgICA9IChhcnJheSkgZG90cyBvZiBpbnRlcnNlY3Rpb25cbiAgICAgbyBbXG4gICAgIG8gICAgIHtcbiAgICAgbyAgICAgICAgIHg6IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnRcbiAgICAgbyAgICAgICAgIHk6IChudW1iZXIpIHkgY29vcmRpbmF0ZSBvZiB0aGUgcG9pbnRcbiAgICAgbyAgICAgICAgIHQxOiAobnVtYmVyKSB0IHZhbHVlIGZvciBzZWdtZW50IG9mIHBhdGgxXG4gICAgIG8gICAgICAgICB0MjogKG51bWJlcikgdCB2YWx1ZSBmb3Igc2VnbWVudCBvZiBwYXRoMlxuICAgICBvICAgICAgICAgc2VnbWVudDE6IChudW1iZXIpIG9yZGVyIG51bWJlciBmb3Igc2VnbWVudCBvZiBwYXRoMVxuICAgICBvICAgICAgICAgc2VnbWVudDI6IChudW1iZXIpIG9yZGVyIG51bWJlciBmb3Igc2VnbWVudCBvZiBwYXRoMlxuICAgICBvICAgICAgICAgYmV6MTogKGFycmF5KSBlaWdodCBjb29yZGluYXRlcyByZXByZXNlbnRpbmcgYmV6acOpciBjdXJ2ZSBmb3IgdGhlIHNlZ21lbnQgb2YgcGF0aDFcbiAgICAgbyAgICAgICAgIGJlejI6IChhcnJheSkgZWlnaHQgY29vcmRpbmF0ZXMgcmVwcmVzZW50aW5nIGJlemnDqXIgY3VydmUgZm9yIHRoZSBzZWdtZW50IG9mIHBhdGgyXG4gICAgIG8gICAgIH1cbiAgICAgbyBdXG4gICAgXFwqL1xuICAgIFIucGF0aEludGVyc2VjdGlvbiA9IGZ1bmN0aW9uIChwYXRoMSwgcGF0aDIpIHtcbiAgICAgICAgcmV0dXJuIGludGVyUGF0aEhlbHBlcihwYXRoMSwgcGF0aDIpO1xuICAgIH07XG4gICAgUi5wYXRoSW50ZXJzZWN0aW9uTnVtYmVyID0gZnVuY3Rpb24gKHBhdGgxLCBwYXRoMikge1xuICAgICAgICByZXR1cm4gaW50ZXJQYXRoSGVscGVyKHBhdGgxLCBwYXRoMiwgMSk7XG4gICAgfTtcbiAgICBmdW5jdGlvbiBpbnRlclBhdGhIZWxwZXIocGF0aDEsIHBhdGgyLCBqdXN0Q291bnQpIHtcbiAgICAgICAgcGF0aDEgPSBSLl9wYXRoMmN1cnZlKHBhdGgxKTtcbiAgICAgICAgcGF0aDIgPSBSLl9wYXRoMmN1cnZlKHBhdGgyKTtcbiAgICAgICAgdmFyIHgxLCB5MSwgeDIsIHkyLCB4MW0sIHkxbSwgeDJtLCB5Mm0sIGJlejEsIGJlejIsXG4gICAgICAgICAgICByZXMgPSBqdXN0Q291bnQgPyAwIDogW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHBhdGgxLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBwaSA9IHBhdGgxW2ldO1xuICAgICAgICAgICAgaWYgKHBpWzBdID09IFwiTVwiKSB7XG4gICAgICAgICAgICAgICAgeDEgPSB4MW0gPSBwaVsxXTtcbiAgICAgICAgICAgICAgICB5MSA9IHkxbSA9IHBpWzJdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAocGlbMF0gPT0gXCJDXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgYmV6MSA9IFt4MSwgeTFdLmNvbmNhdChwaS5zbGljZSgxKSk7XG4gICAgICAgICAgICAgICAgICAgIHgxID0gYmV6MVs2XTtcbiAgICAgICAgICAgICAgICAgICAgeTEgPSBiZXoxWzddO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGJlejEgPSBbeDEsIHkxLCB4MSwgeTEsIHgxbSwgeTFtLCB4MW0sIHkxbV07XG4gICAgICAgICAgICAgICAgICAgIHgxID0geDFtO1xuICAgICAgICAgICAgICAgICAgICB5MSA9IHkxbTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGpqID0gcGF0aDIubGVuZ3RoOyBqIDwgamo7IGorKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcGogPSBwYXRoMltqXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBqWzBdID09IFwiTVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB4MiA9IHgybSA9IHBqWzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgeTIgPSB5Mm0gPSBwalsyXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwalswXSA9PSBcIkNcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlejIgPSBbeDIsIHkyXS5jb25jYXQocGouc2xpY2UoMSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHgyID0gYmV6Mls2XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5MiA9IGJlejJbN107XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlejIgPSBbeDIsIHkyLCB4MiwgeTIsIHgybSwgeTJtLCB4Mm0sIHkybV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDIgPSB4Mm07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTIgPSB5Mm07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW50ciA9IGludGVySGVscGVyKGJlejEsIGJlejIsIGp1c3RDb3VudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoanVzdENvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzICs9IGludHI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGsgPSAwLCBrayA9IGludHIubGVuZ3RoOyBrIDwga2s7IGsrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRyW2tdLnNlZ21lbnQxID0gaTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50cltrXS5zZWdtZW50MiA9IGo7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHJba10uYmV6MSA9IGJlejE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludHJba10uYmV6MiA9IGJlejI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcyA9IHJlcy5jb25jYXQoaW50cik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuaXNQb2ludEluc2lkZVBhdGhcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFV0aWxpdHkgbWV0aG9kXG4gICAgICoqXG4gICAgICogUmV0dXJucyBgdHJ1ZWAgaWYgZ2l2ZW4gcG9pbnQgaXMgaW5zaWRlIGEgZ2l2ZW4gY2xvc2VkIHBhdGguXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIHBhdGggKHN0cmluZykgcGF0aCBzdHJpbmdcbiAgICAgLSB4IChudW1iZXIpIHggb2YgdGhlIHBvaW50XG4gICAgIC0geSAobnVtYmVyKSB5IG9mIHRoZSBwb2ludFxuICAgICA9IChib29sZWFuKSB0cnVlLCBpZiBwb2ludCBpcyBpbnNpZGUgdGhlIHBhdGhcbiAgICBcXCovXG4gICAgUi5pc1BvaW50SW5zaWRlUGF0aCA9IGZ1bmN0aW9uIChwYXRoLCB4LCB5KSB7XG4gICAgICAgIHZhciBiYm94ID0gUi5wYXRoQkJveChwYXRoKTtcbiAgICAgICAgcmV0dXJuIFIuaXNQb2ludEluc2lkZUJCb3goYmJveCwgeCwgeSkgJiZcbiAgICAgICAgICAgICAgIGludGVyUGF0aEhlbHBlcihwYXRoLCBbW1wiTVwiLCB4LCB5XSwgW1wiSFwiLCBiYm94LngyICsgMTBdXSwgMSkgJSAyID09IDE7XG4gICAgfTtcbiAgICBSLl9yZW1vdmVkRmFjdG9yeSA9IGZ1bmN0aW9uIChtZXRob2RuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBldmUoXCJyYXBoYWVsLmxvZ1wiLCBudWxsLCBcIlJhcGhhXFx4ZWJsOiB5b3UgYXJlIGNhbGxpbmcgdG8gbWV0aG9kIFxcdTIwMWNcIiArIG1ldGhvZG5hbWUgKyBcIlxcdTIwMWQgb2YgcmVtb3ZlZCBvYmplY3RcIiwgbWV0aG9kbmFtZSk7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5wYXRoQkJveFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogVXRpbGl0eSBtZXRob2RcbiAgICAgKipcbiAgICAgKiBSZXR1cm4gYm91bmRpbmcgYm94IG9mIGEgZ2l2ZW4gcGF0aFxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBwYXRoIChzdHJpbmcpIHBhdGggc3RyaW5nXG4gICAgID0gKG9iamVjdCkgYm91bmRpbmcgYm94XG4gICAgIG8ge1xuICAgICBvICAgICB4OiAobnVtYmVyKSB4IGNvb3JkaW5hdGUgb2YgdGhlIGxlZnQgdG9wIHBvaW50IG9mIHRoZSBib3hcbiAgICAgbyAgICAgeTogKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSBsZWZ0IHRvcCBwb2ludCBvZiB0aGUgYm94XG4gICAgIG8gICAgIHgyOiAobnVtYmVyKSB4IGNvb3JkaW5hdGUgb2YgdGhlIHJpZ2h0IGJvdHRvbSBwb2ludCBvZiB0aGUgYm94XG4gICAgIG8gICAgIHkyOiAobnVtYmVyKSB5IGNvb3JkaW5hdGUgb2YgdGhlIHJpZ2h0IGJvdHRvbSBwb2ludCBvZiB0aGUgYm94XG4gICAgIG8gICAgIHdpZHRoOiAobnVtYmVyKSB3aWR0aCBvZiB0aGUgYm94XG4gICAgIG8gICAgIGhlaWdodDogKG51bWJlcikgaGVpZ2h0IG9mIHRoZSBib3hcbiAgICAgbyAgICAgY3g6IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgY2VudGVyIG9mIHRoZSBib3hcbiAgICAgbyAgICAgY3k6IChudW1iZXIpIHkgY29vcmRpbmF0ZSBvZiB0aGUgY2VudGVyIG9mIHRoZSBib3hcbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIHZhciBwYXRoRGltZW5zaW9ucyA9IFIucGF0aEJCb3ggPSBmdW5jdGlvbiAocGF0aCkge1xuICAgICAgICB2YXIgcHRoID0gcGF0aHMocGF0aCk7XG4gICAgICAgIGlmIChwdGguYmJveCkge1xuICAgICAgICAgICAgcmV0dXJuIGNsb25lKHB0aC5iYm94KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXBhdGgpIHtcbiAgICAgICAgICAgIHJldHVybiB7eDogMCwgeTogMCwgd2lkdGg6IDAsIGhlaWdodDogMCwgeDI6IDAsIHkyOiAwfTtcbiAgICAgICAgfVxuICAgICAgICBwYXRoID0gcGF0aDJjdXJ2ZShwYXRoKTtcbiAgICAgICAgdmFyIHggPSAwLFxuICAgICAgICAgICAgeSA9IDAsXG4gICAgICAgICAgICBYID0gW10sXG4gICAgICAgICAgICBZID0gW10sXG4gICAgICAgICAgICBwO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBwYXRoLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgIHAgPSBwYXRoW2ldO1xuICAgICAgICAgICAgaWYgKHBbMF0gPT0gXCJNXCIpIHtcbiAgICAgICAgICAgICAgICB4ID0gcFsxXTtcbiAgICAgICAgICAgICAgICB5ID0gcFsyXTtcbiAgICAgICAgICAgICAgICBYLnB1c2goeCk7XG4gICAgICAgICAgICAgICAgWS5wdXNoKHkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgZGltID0gY3VydmVEaW0oeCwgeSwgcFsxXSwgcFsyXSwgcFszXSwgcFs0XSwgcFs1XSwgcFs2XSk7XG4gICAgICAgICAgICAgICAgWCA9IFhbY29uY2F0XShkaW0ubWluLngsIGRpbS5tYXgueCk7XG4gICAgICAgICAgICAgICAgWSA9IFlbY29uY2F0XShkaW0ubWluLnksIGRpbS5tYXgueSk7XG4gICAgICAgICAgICAgICAgeCA9IHBbNV07XG4gICAgICAgICAgICAgICAgeSA9IHBbNl07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHhtaW4gPSBtbWluW2FwcGx5XSgwLCBYKSxcbiAgICAgICAgICAgIHltaW4gPSBtbWluW2FwcGx5XSgwLCBZKSxcbiAgICAgICAgICAgIHhtYXggPSBtbWF4W2FwcGx5XSgwLCBYKSxcbiAgICAgICAgICAgIHltYXggPSBtbWF4W2FwcGx5XSgwLCBZKSxcbiAgICAgICAgICAgIHdpZHRoID0geG1heCAtIHhtaW4sXG4gICAgICAgICAgICBoZWlnaHQgPSB5bWF4IC0geW1pbixcbiAgICAgICAgICAgICAgICBiYiA9IHtcbiAgICAgICAgICAgICAgICB4OiB4bWluLFxuICAgICAgICAgICAgICAgIHk6IHltaW4sXG4gICAgICAgICAgICAgICAgeDI6IHhtYXgsXG4gICAgICAgICAgICAgICAgeTI6IHltYXgsXG4gICAgICAgICAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogaGVpZ2h0LFxuICAgICAgICAgICAgICAgIGN4OiB4bWluICsgd2lkdGggLyAyLFxuICAgICAgICAgICAgICAgIGN5OiB5bWluICsgaGVpZ2h0IC8gMlxuICAgICAgICAgICAgfTtcbiAgICAgICAgcHRoLmJib3ggPSBjbG9uZShiYik7XG4gICAgICAgIHJldHVybiBiYjtcbiAgICB9LFxuICAgICAgICBwYXRoQ2xvbmUgPSBmdW5jdGlvbiAocGF0aEFycmF5KSB7XG4gICAgICAgICAgICB2YXIgcmVzID0gY2xvbmUocGF0aEFycmF5KTtcbiAgICAgICAgICAgIHJlcy50b1N0cmluZyA9IFIuX3BhdGgyc3RyaW5nO1xuICAgICAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgICAgfSxcbiAgICAgICAgcGF0aFRvUmVsYXRpdmUgPSBSLl9wYXRoVG9SZWxhdGl2ZSA9IGZ1bmN0aW9uIChwYXRoQXJyYXkpIHtcbiAgICAgICAgICAgIHZhciBwdGggPSBwYXRocyhwYXRoQXJyYXkpO1xuICAgICAgICAgICAgaWYgKHB0aC5yZWwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGF0aENsb25lKHB0aC5yZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFSLmlzKHBhdGhBcnJheSwgYXJyYXkpIHx8ICFSLmlzKHBhdGhBcnJheSAmJiBwYXRoQXJyYXlbMF0sIGFycmF5KSkgeyAvLyByb3VnaCBhc3N1bXB0aW9uXG4gICAgICAgICAgICAgICAgcGF0aEFycmF5ID0gUi5wYXJzZVBhdGhTdHJpbmcocGF0aEFycmF5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciByZXMgPSBbXSxcbiAgICAgICAgICAgICAgICB4ID0gMCxcbiAgICAgICAgICAgICAgICB5ID0gMCxcbiAgICAgICAgICAgICAgICBteCA9IDAsXG4gICAgICAgICAgICAgICAgbXkgPSAwLFxuICAgICAgICAgICAgICAgIHN0YXJ0ID0gMDtcbiAgICAgICAgICAgIGlmIChwYXRoQXJyYXlbMF1bMF0gPT0gXCJNXCIpIHtcbiAgICAgICAgICAgICAgICB4ID0gcGF0aEFycmF5WzBdWzFdO1xuICAgICAgICAgICAgICAgIHkgPSBwYXRoQXJyYXlbMF1bMl07XG4gICAgICAgICAgICAgICAgbXggPSB4O1xuICAgICAgICAgICAgICAgIG15ID0geTtcbiAgICAgICAgICAgICAgICBzdGFydCsrO1xuICAgICAgICAgICAgICAgIHJlcy5wdXNoKFtcIk1cIiwgeCwgeV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0LCBpaSA9IHBhdGhBcnJheS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHIgPSByZXNbaV0gPSBbXSxcbiAgICAgICAgICAgICAgICAgICAgcGEgPSBwYXRoQXJyYXlbaV07XG4gICAgICAgICAgICAgICAgaWYgKHBhWzBdICE9IGxvd2VyQ2FzZS5jYWxsKHBhWzBdKSkge1xuICAgICAgICAgICAgICAgICAgICByWzBdID0gbG93ZXJDYXNlLmNhbGwocGFbMF0pO1xuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHJbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJhXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgclsxXSA9IHBhWzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJbMl0gPSBwYVsyXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByWzNdID0gcGFbM107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcls0XSA9IHBhWzRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJbNV0gPSBwYVs1XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByWzZdID0gKyhwYVs2XSAtIHgpLnRvRml4ZWQoMyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcls3XSA9ICsocGFbN10gLSB5KS50b0ZpeGVkKDMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcInZcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByWzFdID0gKyhwYVsxXSAtIHkpLnRvRml4ZWQoMyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwibVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG14ID0gcGFbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbXkgPSBwYVsyXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDEsIGpqID0gcGEubGVuZ3RoOyBqIDwgamo7IGorKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByW2pdID0gKyhwYVtqXSAtICgoaiAlIDIpID8geCA6IHkpKS50b0ZpeGVkKDMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHIgPSByZXNbaV0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhWzBdID09IFwibVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBteCA9IHBhWzFdICsgeDtcbiAgICAgICAgICAgICAgICAgICAgICAgIG15ID0gcGFbMl0gKyB5O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGsgPSAwLCBrayA9IHBhLmxlbmd0aDsgayA8IGtrOyBrKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc1tpXVtrXSA9IHBhW2tdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBsZW4gPSByZXNbaV0ubGVuZ3RoO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAocmVzW2ldWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJ6XCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB4ID0gbXg7XG4gICAgICAgICAgICAgICAgICAgICAgICB5ID0gbXk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImhcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gK3Jlc1tpXVtsZW4gLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwidlwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgeSArPSArcmVzW2ldW2xlbiAtIDFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICB4ICs9ICtyZXNbaV1bbGVuIC0gMl07XG4gICAgICAgICAgICAgICAgICAgICAgICB5ICs9ICtyZXNbaV1bbGVuIC0gMV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzLnRvU3RyaW5nID0gUi5fcGF0aDJzdHJpbmc7XG4gICAgICAgICAgICBwdGgucmVsID0gcGF0aENsb25lKHJlcyk7XG4gICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9LFxuICAgICAgICBwYXRoVG9BYnNvbHV0ZSA9IFIuX3BhdGhUb0Fic29sdXRlID0gZnVuY3Rpb24gKHBhdGhBcnJheSkge1xuICAgICAgICAgICAgdmFyIHB0aCA9IHBhdGhzKHBhdGhBcnJheSk7XG4gICAgICAgICAgICBpZiAocHRoLmFicykge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXRoQ2xvbmUocHRoLmFicyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIVIuaXMocGF0aEFycmF5LCBhcnJheSkgfHwgIVIuaXMocGF0aEFycmF5ICYmIHBhdGhBcnJheVswXSwgYXJyYXkpKSB7IC8vIHJvdWdoIGFzc3VtcHRpb25cbiAgICAgICAgICAgICAgICBwYXRoQXJyYXkgPSBSLnBhcnNlUGF0aFN0cmluZyhwYXRoQXJyYXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFwYXRoQXJyYXkgfHwgIXBhdGhBcnJheS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW1tcIk1cIiwgMCwgMF1dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHJlcyA9IFtdLFxuICAgICAgICAgICAgICAgIHggPSAwLFxuICAgICAgICAgICAgICAgIHkgPSAwLFxuICAgICAgICAgICAgICAgIG14ID0gMCxcbiAgICAgICAgICAgICAgICBteSA9IDAsXG4gICAgICAgICAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgICAgICAgaWYgKHBhdGhBcnJheVswXVswXSA9PSBcIk1cIikge1xuICAgICAgICAgICAgICAgIHggPSArcGF0aEFycmF5WzBdWzFdO1xuICAgICAgICAgICAgICAgIHkgPSArcGF0aEFycmF5WzBdWzJdO1xuICAgICAgICAgICAgICAgIG14ID0geDtcbiAgICAgICAgICAgICAgICBteSA9IHk7XG4gICAgICAgICAgICAgICAgc3RhcnQrKztcbiAgICAgICAgICAgICAgICByZXNbMF0gPSBbXCJNXCIsIHgsIHldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGNyeiA9IHBhdGhBcnJheS5sZW5ndGggPT0gMyAmJiBwYXRoQXJyYXlbMF1bMF0gPT0gXCJNXCIgJiYgcGF0aEFycmF5WzFdWzBdLnRvVXBwZXJDYXNlKCkgPT0gXCJSXCIgJiYgcGF0aEFycmF5WzJdWzBdLnRvVXBwZXJDYXNlKCkgPT0gXCJaXCI7XG4gICAgICAgICAgICBmb3IgKHZhciByLCBwYSwgaSA9IHN0YXJ0LCBpaSA9IHBhdGhBcnJheS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcmVzLnB1c2gociA9IFtdKTtcbiAgICAgICAgICAgICAgICBwYSA9IHBhdGhBcnJheVtpXTtcbiAgICAgICAgICAgICAgICBpZiAocGFbMF0gIT0gdXBwZXJDYXNlLmNhbGwocGFbMF0pKSB7XG4gICAgICAgICAgICAgICAgICAgIHJbMF0gPSB1cHBlckNhc2UuY2FsbChwYVswXSk7XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoclswXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcIkFcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByWzFdID0gcGFbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgclsyXSA9IHBhWzJdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJbM10gPSBwYVszXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByWzRdID0gcGFbNF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcls1XSA9IHBhWzVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJbNl0gPSArKHBhWzZdICsgeCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcls3XSA9ICsocGFbN10gKyB5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJWXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgclsxXSA9ICtwYVsxXSArIHk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwiSFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJbMV0gPSArcGFbMV0gKyB4O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcIlJcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZG90cyA9IFt4LCB5XVtjb25jYXRdKHBhLnNsaWNlKDEpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMiwgamogPSBkb3RzLmxlbmd0aDsgaiA8IGpqOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG90c1tqXSA9ICtkb3RzW2pdICsgeDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG90c1srK2pdID0gK2RvdHNbal0gKyB5O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXMucG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzID0gcmVzW2NvbmNhdF0oY2F0bXVsbFJvbTJiZXppZXIoZG90cywgY3J6KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwiTVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG14ID0gK3BhWzFdICsgeDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBteSA9ICtwYVsyXSArIHk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDEsIGpqID0gcGEubGVuZ3RoOyBqIDwgamo7IGorKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByW2pdID0gK3BhW2pdICsgKChqICUgMikgPyB4IDogeSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYVswXSA9PSBcIlJcIikge1xuICAgICAgICAgICAgICAgICAgICBkb3RzID0gW3gsIHldW2NvbmNhdF0ocGEuc2xpY2UoMSkpO1xuICAgICAgICAgICAgICAgICAgICByZXMucG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIHJlcyA9IHJlc1tjb25jYXRdKGNhdG11bGxSb20yYmV6aWVyKGRvdHMsIGNyeikpO1xuICAgICAgICAgICAgICAgICAgICByID0gW1wiUlwiXVtjb25jYXRdKHBhLnNsaWNlKC0yKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgayA9IDAsIGtrID0gcGEubGVuZ3RoOyBrIDwga2s7IGsrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcltrXSA9IHBhW2tdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN3aXRjaCAoclswXSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiWlwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgeCA9IG14O1xuICAgICAgICAgICAgICAgICAgICAgICAgeSA9IG15O1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJIXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB4ID0gclsxXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiVlwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHJbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIk1cIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIG14ID0gcltyLmxlbmd0aCAtIDJdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbXkgPSByW3IubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICB4ID0gcltyLmxlbmd0aCAtIDJdO1xuICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHJbci5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXMudG9TdHJpbmcgPSBSLl9wYXRoMnN0cmluZztcbiAgICAgICAgICAgIHB0aC5hYnMgPSBwYXRoQ2xvbmUocmVzKTtcbiAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgIH0sXG4gICAgICAgIGwyYyA9IGZ1bmN0aW9uICh4MSwgeTEsIHgyLCB5Mikge1xuICAgICAgICAgICAgcmV0dXJuIFt4MSwgeTEsIHgyLCB5MiwgeDIsIHkyXTtcbiAgICAgICAgfSxcbiAgICAgICAgcTJjID0gZnVuY3Rpb24gKHgxLCB5MSwgYXgsIGF5LCB4MiwgeTIpIHtcbiAgICAgICAgICAgIHZhciBfMTMgPSAxIC8gMyxcbiAgICAgICAgICAgICAgICBfMjMgPSAyIC8gMztcbiAgICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAgICAgICAgIF8xMyAqIHgxICsgXzIzICogYXgsXG4gICAgICAgICAgICAgICAgICAgIF8xMyAqIHkxICsgXzIzICogYXksXG4gICAgICAgICAgICAgICAgICAgIF8xMyAqIHgyICsgXzIzICogYXgsXG4gICAgICAgICAgICAgICAgICAgIF8xMyAqIHkyICsgXzIzICogYXksXG4gICAgICAgICAgICAgICAgICAgIHgyLFxuICAgICAgICAgICAgICAgICAgICB5MlxuICAgICAgICAgICAgICAgIF07XG4gICAgICAgIH0sXG4gICAgICAgIGEyYyA9IGZ1bmN0aW9uICh4MSwgeTEsIHJ4LCByeSwgYW5nbGUsIGxhcmdlX2FyY19mbGFnLCBzd2VlcF9mbGFnLCB4MiwgeTIsIHJlY3Vyc2l2ZSkge1xuICAgICAgICAgICAgLy8gZm9yIG1vcmUgaW5mb3JtYXRpb24gb2Ygd2hlcmUgdGhpcyBtYXRoIGNhbWUgZnJvbSB2aXNpdDpcbiAgICAgICAgICAgIC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL1NWRzExL2ltcGxub3RlLmh0bWwjQXJjSW1wbGVtZW50YXRpb25Ob3Rlc1xuICAgICAgICAgICAgdmFyIF8xMjAgPSBQSSAqIDEyMCAvIDE4MCxcbiAgICAgICAgICAgICAgICByYWQgPSBQSSAvIDE4MCAqICgrYW5nbGUgfHwgMCksXG4gICAgICAgICAgICAgICAgcmVzID0gW10sXG4gICAgICAgICAgICAgICAgeHksXG4gICAgICAgICAgICAgICAgcm90YXRlID0gY2FjaGVyKGZ1bmN0aW9uICh4LCB5LCByYWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIFggPSB4ICogbWF0aC5jb3MocmFkKSAtIHkgKiBtYXRoLnNpbihyYWQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgWSA9IHggKiBtYXRoLnNpbihyYWQpICsgeSAqIG1hdGguY29zKHJhZCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7eDogWCwgeTogWX07XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoIXJlY3Vyc2l2ZSkge1xuICAgICAgICAgICAgICAgIHh5ID0gcm90YXRlKHgxLCB5MSwgLXJhZCk7XG4gICAgICAgICAgICAgICAgeDEgPSB4eS54O1xuICAgICAgICAgICAgICAgIHkxID0geHkueTtcbiAgICAgICAgICAgICAgICB4eSA9IHJvdGF0ZSh4MiwgeTIsIC1yYWQpO1xuICAgICAgICAgICAgICAgIHgyID0geHkueDtcbiAgICAgICAgICAgICAgICB5MiA9IHh5Lnk7XG4gICAgICAgICAgICAgICAgdmFyIGNvcyA9IG1hdGguY29zKFBJIC8gMTgwICogYW5nbGUpLFxuICAgICAgICAgICAgICAgICAgICBzaW4gPSBtYXRoLnNpbihQSSAvIDE4MCAqIGFuZ2xlKSxcbiAgICAgICAgICAgICAgICAgICAgeCA9ICh4MSAtIHgyKSAvIDIsXG4gICAgICAgICAgICAgICAgICAgIHkgPSAoeTEgLSB5MikgLyAyO1xuICAgICAgICAgICAgICAgIHZhciBoID0gKHggKiB4KSAvIChyeCAqIHJ4KSArICh5ICogeSkgLyAocnkgKiByeSk7XG4gICAgICAgICAgICAgICAgaWYgKGggPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGggPSBtYXRoLnNxcnQoaCk7XG4gICAgICAgICAgICAgICAgICAgIHJ4ID0gaCAqIHJ4O1xuICAgICAgICAgICAgICAgICAgICByeSA9IGggKiByeTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIHJ4MiA9IHJ4ICogcngsXG4gICAgICAgICAgICAgICAgICAgIHJ5MiA9IHJ5ICogcnksXG4gICAgICAgICAgICAgICAgICAgIGsgPSAobGFyZ2VfYXJjX2ZsYWcgPT0gc3dlZXBfZmxhZyA/IC0xIDogMSkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgbWF0aC5zcXJ0KGFicygocngyICogcnkyIC0gcngyICogeSAqIHkgLSByeTIgKiB4ICogeCkgLyAocngyICogeSAqIHkgKyByeTIgKiB4ICogeCkpKSxcbiAgICAgICAgICAgICAgICAgICAgY3ggPSBrICogcnggKiB5IC8gcnkgKyAoeDEgKyB4MikgLyAyLFxuICAgICAgICAgICAgICAgICAgICBjeSA9IGsgKiAtcnkgKiB4IC8gcnggKyAoeTEgKyB5MikgLyAyLFxuICAgICAgICAgICAgICAgICAgICBmMSA9IG1hdGguYXNpbigoKHkxIC0gY3kpIC8gcnkpLnRvRml4ZWQoOSkpLFxuICAgICAgICAgICAgICAgICAgICBmMiA9IG1hdGguYXNpbigoKHkyIC0gY3kpIC8gcnkpLnRvRml4ZWQoOSkpO1xuXG4gICAgICAgICAgICAgICAgZjEgPSB4MSA8IGN4ID8gUEkgLSBmMSA6IGYxO1xuICAgICAgICAgICAgICAgIGYyID0geDIgPCBjeCA/IFBJIC0gZjIgOiBmMjtcbiAgICAgICAgICAgICAgICBmMSA8IDAgJiYgKGYxID0gUEkgKiAyICsgZjEpO1xuICAgICAgICAgICAgICAgIGYyIDwgMCAmJiAoZjIgPSBQSSAqIDIgKyBmMik7XG4gICAgICAgICAgICAgICAgaWYgKHN3ZWVwX2ZsYWcgJiYgZjEgPiBmMikge1xuICAgICAgICAgICAgICAgICAgICBmMSA9IGYxIC0gUEkgKiAyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXN3ZWVwX2ZsYWcgJiYgZjIgPiBmMSkge1xuICAgICAgICAgICAgICAgICAgICBmMiA9IGYyIC0gUEkgKiAyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZjEgPSByZWN1cnNpdmVbMF07XG4gICAgICAgICAgICAgICAgZjIgPSByZWN1cnNpdmVbMV07XG4gICAgICAgICAgICAgICAgY3ggPSByZWN1cnNpdmVbMl07XG4gICAgICAgICAgICAgICAgY3kgPSByZWN1cnNpdmVbM107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZGYgPSBmMiAtIGYxO1xuICAgICAgICAgICAgaWYgKGFicyhkZikgPiBfMTIwKSB7XG4gICAgICAgICAgICAgICAgdmFyIGYyb2xkID0gZjIsXG4gICAgICAgICAgICAgICAgICAgIHgyb2xkID0geDIsXG4gICAgICAgICAgICAgICAgICAgIHkyb2xkID0geTI7XG4gICAgICAgICAgICAgICAgZjIgPSBmMSArIF8xMjAgKiAoc3dlZXBfZmxhZyAmJiBmMiA+IGYxID8gMSA6IC0xKTtcbiAgICAgICAgICAgICAgICB4MiA9IGN4ICsgcnggKiBtYXRoLmNvcyhmMik7XG4gICAgICAgICAgICAgICAgeTIgPSBjeSArIHJ5ICogbWF0aC5zaW4oZjIpO1xuICAgICAgICAgICAgICAgIHJlcyA9IGEyYyh4MiwgeTIsIHJ4LCByeSwgYW5nbGUsIDAsIHN3ZWVwX2ZsYWcsIHgyb2xkLCB5Mm9sZCwgW2YyLCBmMm9sZCwgY3gsIGN5XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZiA9IGYyIC0gZjE7XG4gICAgICAgICAgICB2YXIgYzEgPSBtYXRoLmNvcyhmMSksXG4gICAgICAgICAgICAgICAgczEgPSBtYXRoLnNpbihmMSksXG4gICAgICAgICAgICAgICAgYzIgPSBtYXRoLmNvcyhmMiksXG4gICAgICAgICAgICAgICAgczIgPSBtYXRoLnNpbihmMiksXG4gICAgICAgICAgICAgICAgdCA9IG1hdGgudGFuKGRmIC8gNCksXG4gICAgICAgICAgICAgICAgaHggPSA0IC8gMyAqIHJ4ICogdCxcbiAgICAgICAgICAgICAgICBoeSA9IDQgLyAzICogcnkgKiB0LFxuICAgICAgICAgICAgICAgIG0xID0gW3gxLCB5MV0sXG4gICAgICAgICAgICAgICAgbTIgPSBbeDEgKyBoeCAqIHMxLCB5MSAtIGh5ICogYzFdLFxuICAgICAgICAgICAgICAgIG0zID0gW3gyICsgaHggKiBzMiwgeTIgLSBoeSAqIGMyXSxcbiAgICAgICAgICAgICAgICBtNCA9IFt4MiwgeTJdO1xuICAgICAgICAgICAgbTJbMF0gPSAyICogbTFbMF0gLSBtMlswXTtcbiAgICAgICAgICAgIG0yWzFdID0gMiAqIG0xWzFdIC0gbTJbMV07XG4gICAgICAgICAgICBpZiAocmVjdXJzaXZlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFttMiwgbTMsIG00XVtjb25jYXRdKHJlcyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlcyA9IFttMiwgbTMsIG00XVtjb25jYXRdKHJlcykuam9pbigpW3NwbGl0XShcIixcIik7XG4gICAgICAgICAgICAgICAgdmFyIG5ld3JlcyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHJlcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ld3Jlc1tpXSA9IGkgJSAyID8gcm90YXRlKHJlc1tpIC0gMV0sIHJlc1tpXSwgcmFkKS55IDogcm90YXRlKHJlc1tpXSwgcmVzW2kgKyAxXSwgcmFkKS54O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3cmVzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBmaW5kRG90QXRTZWdtZW50ID0gZnVuY3Rpb24gKHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5LCB0KSB7XG4gICAgICAgICAgICB2YXIgdDEgPSAxIC0gdDtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgeDogcG93KHQxLCAzKSAqIHAxeCArIHBvdyh0MSwgMikgKiAzICogdCAqIGMxeCArIHQxICogMyAqIHQgKiB0ICogYzJ4ICsgcG93KHQsIDMpICogcDJ4LFxuICAgICAgICAgICAgICAgIHk6IHBvdyh0MSwgMykgKiBwMXkgKyBwb3codDEsIDIpICogMyAqIHQgKiBjMXkgKyB0MSAqIDMgKiB0ICogdCAqIGMyeSArIHBvdyh0LCAzKSAqIHAyeVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgICAgY3VydmVEaW0gPSBjYWNoZXIoZnVuY3Rpb24gKHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5KSB7XG4gICAgICAgICAgICB2YXIgYSA9IChjMnggLSAyICogYzF4ICsgcDF4KSAtIChwMnggLSAyICogYzJ4ICsgYzF4KSxcbiAgICAgICAgICAgICAgICBiID0gMiAqIChjMXggLSBwMXgpIC0gMiAqIChjMnggLSBjMXgpLFxuICAgICAgICAgICAgICAgIGMgPSBwMXggLSBjMXgsXG4gICAgICAgICAgICAgICAgdDEgPSAoLWIgKyBtYXRoLnNxcnQoYiAqIGIgLSA0ICogYSAqIGMpKSAvIDIgLyBhLFxuICAgICAgICAgICAgICAgIHQyID0gKC1iIC0gbWF0aC5zcXJ0KGIgKiBiIC0gNCAqIGEgKiBjKSkgLyAyIC8gYSxcbiAgICAgICAgICAgICAgICB5ID0gW3AxeSwgcDJ5XSxcbiAgICAgICAgICAgICAgICB4ID0gW3AxeCwgcDJ4XSxcbiAgICAgICAgICAgICAgICBkb3Q7XG4gICAgICAgICAgICBhYnModDEpID4gXCIxZTEyXCIgJiYgKHQxID0gLjUpO1xuICAgICAgICAgICAgYWJzKHQyKSA+IFwiMWUxMlwiICYmICh0MiA9IC41KTtcbiAgICAgICAgICAgIGlmICh0MSA+IDAgJiYgdDEgPCAxKSB7XG4gICAgICAgICAgICAgICAgZG90ID0gZmluZERvdEF0U2VnbWVudChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSwgdDEpO1xuICAgICAgICAgICAgICAgIHgucHVzaChkb3QueCk7XG4gICAgICAgICAgICAgICAgeS5wdXNoKGRvdC55KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0MiA+IDAgJiYgdDIgPCAxKSB7XG4gICAgICAgICAgICAgICAgZG90ID0gZmluZERvdEF0U2VnbWVudChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSwgdDIpO1xuICAgICAgICAgICAgICAgIHgucHVzaChkb3QueCk7XG4gICAgICAgICAgICAgICAgeS5wdXNoKGRvdC55KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGEgPSAoYzJ5IC0gMiAqIGMxeSArIHAxeSkgLSAocDJ5IC0gMiAqIGMyeSArIGMxeSk7XG4gICAgICAgICAgICBiID0gMiAqIChjMXkgLSBwMXkpIC0gMiAqIChjMnkgLSBjMXkpO1xuICAgICAgICAgICAgYyA9IHAxeSAtIGMxeTtcbiAgICAgICAgICAgIHQxID0gKC1iICsgbWF0aC5zcXJ0KGIgKiBiIC0gNCAqIGEgKiBjKSkgLyAyIC8gYTtcbiAgICAgICAgICAgIHQyID0gKC1iIC0gbWF0aC5zcXJ0KGIgKiBiIC0gNCAqIGEgKiBjKSkgLyAyIC8gYTtcbiAgICAgICAgICAgIGFicyh0MSkgPiBcIjFlMTJcIiAmJiAodDEgPSAuNSk7XG4gICAgICAgICAgICBhYnModDIpID4gXCIxZTEyXCIgJiYgKHQyID0gLjUpO1xuICAgICAgICAgICAgaWYgKHQxID4gMCAmJiB0MSA8IDEpIHtcbiAgICAgICAgICAgICAgICBkb3QgPSBmaW5kRG90QXRTZWdtZW50KHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5LCB0MSk7XG4gICAgICAgICAgICAgICAgeC5wdXNoKGRvdC54KTtcbiAgICAgICAgICAgICAgICB5LnB1c2goZG90LnkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHQyID4gMCAmJiB0MiA8IDEpIHtcbiAgICAgICAgICAgICAgICBkb3QgPSBmaW5kRG90QXRTZWdtZW50KHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5LCB0Mik7XG4gICAgICAgICAgICAgICAgeC5wdXNoKGRvdC54KTtcbiAgICAgICAgICAgICAgICB5LnB1c2goZG90LnkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBtaW46IHt4OiBtbWluW2FwcGx5XSgwLCB4KSwgeTogbW1pblthcHBseV0oMCwgeSl9LFxuICAgICAgICAgICAgICAgIG1heDoge3g6IG1tYXhbYXBwbHldKDAsIHgpLCB5OiBtbWF4W2FwcGx5XSgwLCB5KX1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pLFxuICAgICAgICBwYXRoMmN1cnZlID0gUi5fcGF0aDJjdXJ2ZSA9IGNhY2hlcihmdW5jdGlvbiAocGF0aCwgcGF0aDIpIHtcbiAgICAgICAgICAgIHZhciBwdGggPSAhcGF0aDIgJiYgcGF0aHMocGF0aCk7XG4gICAgICAgICAgICBpZiAoIXBhdGgyICYmIHB0aC5jdXJ2ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXRoQ2xvbmUocHRoLmN1cnZlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBwID0gcGF0aFRvQWJzb2x1dGUocGF0aCksXG4gICAgICAgICAgICAgICAgcDIgPSBwYXRoMiAmJiBwYXRoVG9BYnNvbHV0ZShwYXRoMiksXG4gICAgICAgICAgICAgICAgYXR0cnMgPSB7eDogMCwgeTogMCwgYng6IDAsIGJ5OiAwLCBYOiAwLCBZOiAwLCBxeDogbnVsbCwgcXk6IG51bGx9LFxuICAgICAgICAgICAgICAgIGF0dHJzMiA9IHt4OiAwLCB5OiAwLCBieDogMCwgYnk6IDAsIFg6IDAsIFk6IDAsIHF4OiBudWxsLCBxeTogbnVsbH0sXG4gICAgICAgICAgICAgICAgcHJvY2Vzc1BhdGggPSBmdW5jdGlvbiAocGF0aCwgZCwgcGNvbSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgbngsIG55LCB0cSA9IHtUOjEsIFE6MX07XG4gICAgICAgICAgICAgICAgICAgIGlmICghcGF0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtcIkNcIiwgZC54LCBkLnksIGQueCwgZC55LCBkLngsIGQueV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgIShwYXRoWzBdIGluIHRxKSAmJiAoZC5xeCA9IGQucXkgPSBudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChwYXRoWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwiTVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQuWCA9IHBhdGhbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5ZID0gcGF0aFsyXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJBXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IFtcIkNcIl1bY29uY2F0XShhMmNbYXBwbHldKDAsIFtkLngsIGQueV1bY29uY2F0XShwYXRoLnNsaWNlKDEpKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcIlNcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGNvbSA9PSBcIkNcIiB8fCBwY29tID09IFwiU1wiKSB7IC8vIEluIFwiU1wiIGNhc2Ugd2UgaGF2ZSB0byB0YWtlIGludG8gYWNjb3VudCwgaWYgdGhlIHByZXZpb3VzIGNvbW1hbmQgaXMgQy9TLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBueCA9IGQueCAqIDIgLSBkLmJ4OyAgICAgICAgICAvLyBBbmQgcmVmbGVjdCB0aGUgcHJldmlvdXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnkgPSBkLnkgKiAyIC0gZC5ieTsgICAgICAgICAgLy8gY29tbWFuZCdzIGNvbnRyb2wgcG9pbnQgcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnQgcG9pbnQuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvciBzb21lIGVsc2Ugb3Igbm90aGluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBueCA9IGQueDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnkgPSBkLnk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBbXCJDXCIsIG54LCBueV1bY29uY2F0XShwYXRoLnNsaWNlKDEpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJUXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBjb20gPT0gXCJRXCIgfHwgcGNvbSA9PSBcIlRcIikgeyAvLyBJbiBcIlRcIiBjYXNlIHdlIGhhdmUgdG8gdGFrZSBpbnRvIGFjY291bnQsIGlmIHRoZSBwcmV2aW91cyBjb21tYW5kIGlzIFEvVC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5xeCA9IGQueCAqIDIgLSBkLnF4OyAgICAgICAgLy8gQW5kIG1ha2UgYSByZWZsZWN0aW9uIHNpbWlsYXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5xeSA9IGQueSAqIDIgLSBkLnF5OyAgICAgICAgLy8gdG8gY2FzZSBcIlNcIi5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9yIHNvbWV0aGluZyBlbHNlIG9yIG5vdGhpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5xeCA9IGQueDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5xeSA9IGQueTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IFtcIkNcIl1bY29uY2F0XShxMmMoZC54LCBkLnksIGQucXgsIGQucXksIHBhdGhbMV0sIHBhdGhbMl0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJRXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5xeCA9IHBhdGhbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZC5xeSA9IHBhdGhbMl07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IFtcIkNcIl1bY29uY2F0XShxMmMoZC54LCBkLnksIHBhdGhbMV0sIHBhdGhbMl0sIHBhdGhbM10sIHBhdGhbNF0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJMXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IFtcIkNcIl1bY29uY2F0XShsMmMoZC54LCBkLnksIHBhdGhbMV0sIHBhdGhbMl0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJIXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aCA9IFtcIkNcIl1bY29uY2F0XShsMmMoZC54LCBkLnksIHBhdGhbMV0sIGQueSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcIlZcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRoID0gW1wiQ1wiXVtjb25jYXRdKGwyYyhkLngsIGQueSwgZC54LCBwYXRoWzFdKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwiWlwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGggPSBbXCJDXCJdW2NvbmNhdF0obDJjKGQueCwgZC55LCBkLlgsIGQuWSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXRoO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZml4QXJjID0gZnVuY3Rpb24gKHBwLCBpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwcFtpXS5sZW5ndGggPiA3KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcFtpXS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBpID0gcHBbaV07XG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocGkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGNvbXMxW2ldPVwiQVwiOyAvLyBpZiBjcmVhdGVkIG11bHRpcGxlIEM6cywgdGhlaXIgb3JpZ2luYWwgc2VnIGlzIHNhdmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcDIgJiYgKHBjb21zMltpXT1cIkFcIik7IC8vIHRoZSBzYW1lIGFzIGFib3ZlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHAuc3BsaWNlKGkrKywgMCwgW1wiQ1wiXVtjb25jYXRdKHBpLnNwbGljZSgwLCA2KSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcHAuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWkgPSBtbWF4KHAubGVuZ3RoLCBwMiAmJiBwMi5sZW5ndGggfHwgMCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGZpeE0gPSBmdW5jdGlvbiAocGF0aDEsIHBhdGgyLCBhMSwgYTIsIGkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhdGgxICYmIHBhdGgyICYmIHBhdGgxW2ldWzBdID09IFwiTVwiICYmIHBhdGgyW2ldWzBdICE9IFwiTVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXRoMi5zcGxpY2UoaSwgMCwgW1wiTVwiLCBhMi54LCBhMi55XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhMS5ieCA9IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICBhMS5ieSA9IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICBhMS54ID0gcGF0aDFbaV1bMV07XG4gICAgICAgICAgICAgICAgICAgICAgICBhMS55ID0gcGF0aDFbaV1bMl07XG4gICAgICAgICAgICAgICAgICAgICAgICBpaSA9IG1tYXgocC5sZW5ndGgsIHAyICYmIHAyLmxlbmd0aCB8fCAwKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcGNvbXMxID0gW10sIC8vIHBhdGggY29tbWFuZHMgb2Ygb3JpZ2luYWwgcGF0aCBwXG4gICAgICAgICAgICAgICAgcGNvbXMyID0gW10sIC8vIHBhdGggY29tbWFuZHMgb2Ygb3JpZ2luYWwgcGF0aCBwMlxuICAgICAgICAgICAgICAgIHBmaXJzdCA9IFwiXCIsIC8vIHRlbXBvcmFyeSBob2xkZXIgZm9yIG9yaWdpbmFsIHBhdGggY29tbWFuZFxuICAgICAgICAgICAgICAgIHBjb20gPSBcIlwiOyAvLyBob2xkZXIgZm9yIHByZXZpb3VzIHBhdGggY29tbWFuZCBvZiBvcmlnaW5hbCBwYXRoXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBtbWF4KHAubGVuZ3RoLCBwMiAmJiBwMi5sZW5ndGggfHwgMCk7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcFtpXSAmJiAocGZpcnN0ID0gcFtpXVswXSk7IC8vIHNhdmUgY3VycmVudCBwYXRoIGNvbW1hbmRcblxuICAgICAgICAgICAgICAgIGlmIChwZmlyc3QgIT0gXCJDXCIpIC8vIEMgaXMgbm90IHNhdmVkIHlldCwgYmVjYXVzZSBpdCBtYXkgYmUgcmVzdWx0IG9mIGNvbnZlcnNpb25cbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHBjb21zMVtpXSA9IHBmaXJzdDsgLy8gU2F2ZSBjdXJyZW50IHBhdGggY29tbWFuZFxuICAgICAgICAgICAgICAgICAgICBpICYmICggcGNvbSA9IHBjb21zMVtpLTFdKTsgLy8gR2V0IHByZXZpb3VzIHBhdGggY29tbWFuZCBwY29tXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBbaV0gPSBwcm9jZXNzUGF0aChwW2ldLCBhdHRycywgcGNvbSk7IC8vIFByZXZpb3VzIHBhdGggY29tbWFuZCBpcyBpbnB1dHRlZCB0byBwcm9jZXNzUGF0aFxuXG4gICAgICAgICAgICAgICAgaWYgKHBjb21zMVtpXSAhPSBcIkFcIiAmJiBwZmlyc3QgPT0gXCJDXCIpIHBjb21zMVtpXSA9IFwiQ1wiOyAvLyBBIGlzIHRoZSBvbmx5IGNvbW1hbmRcbiAgICAgICAgICAgICAgICAvLyB3aGljaCBtYXkgcHJvZHVjZSBtdWx0aXBsZSBDOnNcbiAgICAgICAgICAgICAgICAvLyBzbyB3ZSBoYXZlIHRvIG1ha2Ugc3VyZSB0aGF0IEMgaXMgYWxzbyBDIGluIG9yaWdpbmFsIHBhdGhcblxuICAgICAgICAgICAgICAgIGZpeEFyYyhwLCBpKTsgLy8gZml4QXJjIGFkZHMgYWxzbyB0aGUgcmlnaHQgYW1vdW50IG9mIEE6cyB0byBwY29tczFcblxuICAgICAgICAgICAgICAgIGlmIChwMikgeyAvLyB0aGUgc2FtZSBwcm9jZWR1cmVzIGlzIGRvbmUgdG8gcDJcbiAgICAgICAgICAgICAgICAgICAgcDJbaV0gJiYgKHBmaXJzdCA9IHAyW2ldWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBmaXJzdCAhPSBcIkNcIilcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGNvbXMyW2ldID0gcGZpcnN0O1xuICAgICAgICAgICAgICAgICAgICAgICAgaSAmJiAocGNvbSA9IHBjb21zMltpLTFdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBwMltpXSA9IHByb2Nlc3NQYXRoKHAyW2ldLCBhdHRyczIsIHBjb20pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwY29tczJbaV0hPVwiQVwiICYmIHBmaXJzdD09XCJDXCIpIHBjb21zMltpXT1cIkNcIjtcblxuICAgICAgICAgICAgICAgICAgICBmaXhBcmMocDIsIGkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmaXhNKHAsIHAyLCBhdHRycywgYXR0cnMyLCBpKTtcbiAgICAgICAgICAgICAgICBmaXhNKHAyLCBwLCBhdHRyczIsIGF0dHJzLCBpKTtcbiAgICAgICAgICAgICAgICB2YXIgc2VnID0gcFtpXSxcbiAgICAgICAgICAgICAgICAgICAgc2VnMiA9IHAyICYmIHAyW2ldLFxuICAgICAgICAgICAgICAgICAgICBzZWdsZW4gPSBzZWcubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICBzZWcybGVuID0gcDIgJiYgc2VnMi5sZW5ndGg7XG4gICAgICAgICAgICAgICAgYXR0cnMueCA9IHNlZ1tzZWdsZW4gLSAyXTtcbiAgICAgICAgICAgICAgICBhdHRycy55ID0gc2VnW3NlZ2xlbiAtIDFdO1xuICAgICAgICAgICAgICAgIGF0dHJzLmJ4ID0gdG9GbG9hdChzZWdbc2VnbGVuIC0gNF0pIHx8IGF0dHJzLng7XG4gICAgICAgICAgICAgICAgYXR0cnMuYnkgPSB0b0Zsb2F0KHNlZ1tzZWdsZW4gLSAzXSkgfHwgYXR0cnMueTtcbiAgICAgICAgICAgICAgICBhdHRyczIuYnggPSBwMiAmJiAodG9GbG9hdChzZWcyW3NlZzJsZW4gLSA0XSkgfHwgYXR0cnMyLngpO1xuICAgICAgICAgICAgICAgIGF0dHJzMi5ieSA9IHAyICYmICh0b0Zsb2F0KHNlZzJbc2VnMmxlbiAtIDNdKSB8fCBhdHRyczIueSk7XG4gICAgICAgICAgICAgICAgYXR0cnMyLnggPSBwMiAmJiBzZWcyW3NlZzJsZW4gLSAyXTtcbiAgICAgICAgICAgICAgICBhdHRyczIueSA9IHAyICYmIHNlZzJbc2VnMmxlbiAtIDFdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFwMikge1xuICAgICAgICAgICAgICAgIHB0aC5jdXJ2ZSA9IHBhdGhDbG9uZShwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwMiA/IFtwLCBwMl0gOiBwO1xuICAgICAgICB9LCBudWxsLCBwYXRoQ2xvbmUpLFxuICAgICAgICBwYXJzZURvdHMgPSBSLl9wYXJzZURvdHMgPSBjYWNoZXIoZnVuY3Rpb24gKGdyYWRpZW50KSB7XG4gICAgICAgICAgICB2YXIgZG90cyA9IFtdO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZ3JhZGllbnQubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBkb3QgPSB7fSxcbiAgICAgICAgICAgICAgICAgICAgcGFyID0gZ3JhZGllbnRbaV0ubWF0Y2goL14oW146XSopOj8oW1xcZFxcLl0qKS8pO1xuICAgICAgICAgICAgICAgIGRvdC5jb2xvciA9IFIuZ2V0UkdCKHBhclsxXSk7XG4gICAgICAgICAgICAgICAgaWYgKGRvdC5jb2xvci5lcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZG90Lm9wYWNpdHkgPSBkb3QuY29sb3Iub3BhY2l0eTtcbiAgICAgICAgICAgICAgICBkb3QuY29sb3IgPSBkb3QuY29sb3IuaGV4O1xuICAgICAgICAgICAgICAgIHBhclsyXSAmJiAoZG90Lm9mZnNldCA9IHBhclsyXSArIFwiJVwiKTtcbiAgICAgICAgICAgICAgICBkb3RzLnB1c2goZG90KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoaSA9IDEsIGlpID0gZG90cy5sZW5ndGggLSAxOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghZG90c1tpXS5vZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0YXJ0ID0gdG9GbG9hdChkb3RzW2kgLSAxXS5vZmZzZXQgfHwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmQgPSAwO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gaSArIDE7IGogPCBpaTsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG90c1tqXS5vZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmQgPSBkb3RzW2pdLm9mZnNldDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIWVuZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZW5kID0gMTAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgaiA9IGlpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVuZCA9IHRvRmxvYXQoZW5kKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGQgPSAoZW5kIC0gc3RhcnQpIC8gKGogLSBpICsgMSk7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgajsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydCArPSBkO1xuICAgICAgICAgICAgICAgICAgICAgICAgZG90c1tpXS5vZmZzZXQgPSBzdGFydCArIFwiJVwiO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRvdHM7XG4gICAgICAgIH0pLFxuICAgICAgICB0ZWFyID0gUi5fdGVhciA9IGZ1bmN0aW9uIChlbCwgcGFwZXIpIHtcbiAgICAgICAgICAgIGVsID09IHBhcGVyLnRvcCAmJiAocGFwZXIudG9wID0gZWwucHJldik7XG4gICAgICAgICAgICBlbCA9PSBwYXBlci5ib3R0b20gJiYgKHBhcGVyLmJvdHRvbSA9IGVsLm5leHQpO1xuICAgICAgICAgICAgZWwubmV4dCAmJiAoZWwubmV4dC5wcmV2ID0gZWwucHJldik7XG4gICAgICAgICAgICBlbC5wcmV2ICYmIChlbC5wcmV2Lm5leHQgPSBlbC5uZXh0KTtcbiAgICAgICAgfSxcbiAgICAgICAgdG9mcm9udCA9IFIuX3RvZnJvbnQgPSBmdW5jdGlvbiAoZWwsIHBhcGVyKSB7XG4gICAgICAgICAgICBpZiAocGFwZXIudG9wID09PSBlbCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRlYXIoZWwsIHBhcGVyKTtcbiAgICAgICAgICAgIGVsLm5leHQgPSBudWxsO1xuICAgICAgICAgICAgZWwucHJldiA9IHBhcGVyLnRvcDtcbiAgICAgICAgICAgIHBhcGVyLnRvcC5uZXh0ID0gZWw7XG4gICAgICAgICAgICBwYXBlci50b3AgPSBlbDtcbiAgICAgICAgfSxcbiAgICAgICAgdG9iYWNrID0gUi5fdG9iYWNrID0gZnVuY3Rpb24gKGVsLCBwYXBlcikge1xuICAgICAgICAgICAgaWYgKHBhcGVyLmJvdHRvbSA9PT0gZWwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ZWFyKGVsLCBwYXBlcik7XG4gICAgICAgICAgICBlbC5uZXh0ID0gcGFwZXIuYm90dG9tO1xuICAgICAgICAgICAgZWwucHJldiA9IG51bGw7XG4gICAgICAgICAgICBwYXBlci5ib3R0b20ucHJldiA9IGVsO1xuICAgICAgICAgICAgcGFwZXIuYm90dG9tID0gZWw7XG4gICAgICAgIH0sXG4gICAgICAgIGluc2VydGFmdGVyID0gUi5faW5zZXJ0YWZ0ZXIgPSBmdW5jdGlvbiAoZWwsIGVsMiwgcGFwZXIpIHtcbiAgICAgICAgICAgIHRlYXIoZWwsIHBhcGVyKTtcbiAgICAgICAgICAgIGVsMiA9PSBwYXBlci50b3AgJiYgKHBhcGVyLnRvcCA9IGVsKTtcbiAgICAgICAgICAgIGVsMi5uZXh0ICYmIChlbDIubmV4dC5wcmV2ID0gZWwpO1xuICAgICAgICAgICAgZWwubmV4dCA9IGVsMi5uZXh0O1xuICAgICAgICAgICAgZWwucHJldiA9IGVsMjtcbiAgICAgICAgICAgIGVsMi5uZXh0ID0gZWw7XG4gICAgICAgIH0sXG4gICAgICAgIGluc2VydGJlZm9yZSA9IFIuX2luc2VydGJlZm9yZSA9IGZ1bmN0aW9uIChlbCwgZWwyLCBwYXBlcikge1xuICAgICAgICAgICAgdGVhcihlbCwgcGFwZXIpO1xuICAgICAgICAgICAgZWwyID09IHBhcGVyLmJvdHRvbSAmJiAocGFwZXIuYm90dG9tID0gZWwpO1xuICAgICAgICAgICAgZWwyLnByZXYgJiYgKGVsMi5wcmV2Lm5leHQgPSBlbCk7XG4gICAgICAgICAgICBlbC5wcmV2ID0gZWwyLnByZXY7XG4gICAgICAgICAgICBlbDIucHJldiA9IGVsO1xuICAgICAgICAgICAgZWwubmV4dCA9IGVsMjtcbiAgICAgICAgfSxcbiAgICAgICAgLypcXFxuICAgICAgICAgKiBSYXBoYWVsLnRvTWF0cml4XG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqKlxuICAgICAgICAgKiBVdGlsaXR5IG1ldGhvZFxuICAgICAgICAgKipcbiAgICAgICAgICogUmV0dXJucyBtYXRyaXggb2YgdHJhbnNmb3JtYXRpb25zIGFwcGxpZWQgdG8gYSBnaXZlbiBwYXRoXG4gICAgICAgICA+IFBhcmFtZXRlcnNcbiAgICAgICAgIC0gcGF0aCAoc3RyaW5nKSBwYXRoIHN0cmluZ1xuICAgICAgICAgLSB0cmFuc2Zvcm0gKHN0cmluZ3xhcnJheSkgdHJhbnNmb3JtYXRpb24gc3RyaW5nXG4gICAgICAgICA9IChvYmplY3QpIEBNYXRyaXhcbiAgICAgICAgXFwqL1xuICAgICAgICB0b01hdHJpeCA9IFIudG9NYXRyaXggPSBmdW5jdGlvbiAocGF0aCwgdHJhbnNmb3JtKSB7XG4gICAgICAgICAgICB2YXIgYmIgPSBwYXRoRGltZW5zaW9ucyhwYXRoKSxcbiAgICAgICAgICAgICAgICBlbCA9IHtcbiAgICAgICAgICAgICAgICAgICAgXzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtOiBFXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGdldEJCb3g6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBiYjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICBleHRyYWN0VHJhbnNmb3JtKGVsLCB0cmFuc2Zvcm0pO1xuICAgICAgICAgICAgcmV0dXJuIGVsLm1hdHJpeDtcbiAgICAgICAgfSxcbiAgICAgICAgLypcXFxuICAgICAgICAgKiBSYXBoYWVsLnRyYW5zZm9ybVBhdGhcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICoqXG4gICAgICAgICAqIFV0aWxpdHkgbWV0aG9kXG4gICAgICAgICAqKlxuICAgICAgICAgKiBSZXR1cm5zIHBhdGggdHJhbnNmb3JtZWQgYnkgYSBnaXZlbiB0cmFuc2Zvcm1hdGlvblxuICAgICAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICAgICAtIHBhdGggKHN0cmluZykgcGF0aCBzdHJpbmdcbiAgICAgICAgIC0gdHJhbnNmb3JtIChzdHJpbmd8YXJyYXkpIHRyYW5zZm9ybWF0aW9uIHN0cmluZ1xuICAgICAgICAgPSAoc3RyaW5nKSBwYXRoXG4gICAgICAgIFxcKi9cbiAgICAgICAgdHJhbnNmb3JtUGF0aCA9IFIudHJhbnNmb3JtUGF0aCA9IGZ1bmN0aW9uIChwYXRoLCB0cmFuc2Zvcm0pIHtcbiAgICAgICAgICAgIHJldHVybiBtYXBQYXRoKHBhdGgsIHRvTWF0cml4KHBhdGgsIHRyYW5zZm9ybSkpO1xuICAgICAgICB9LFxuICAgICAgICBleHRyYWN0VHJhbnNmb3JtID0gUi5fZXh0cmFjdFRyYW5zZm9ybSA9IGZ1bmN0aW9uIChlbCwgdHN0cikge1xuICAgICAgICAgICAgaWYgKHRzdHIgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBlbC5fLnRyYW5zZm9ybTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRzdHIgPSBTdHIodHN0cikucmVwbGFjZSgvXFwuezN9fFxcdTIwMjYvZywgZWwuXy50cmFuc2Zvcm0gfHwgRSk7XG4gICAgICAgICAgICB2YXIgdGRhdGEgPSBSLnBhcnNlVHJhbnNmb3JtU3RyaW5nKHRzdHIpLFxuICAgICAgICAgICAgICAgIGRlZyA9IDAsXG4gICAgICAgICAgICAgICAgZHggPSAwLFxuICAgICAgICAgICAgICAgIGR5ID0gMCxcbiAgICAgICAgICAgICAgICBzeCA9IDEsXG4gICAgICAgICAgICAgICAgc3kgPSAxLFxuICAgICAgICAgICAgICAgIF8gPSBlbC5fLFxuICAgICAgICAgICAgICAgIG0gPSBuZXcgTWF0cml4O1xuICAgICAgICAgICAgXy50cmFuc2Zvcm0gPSB0ZGF0YSB8fCBbXTtcbiAgICAgICAgICAgIGlmICh0ZGF0YSkge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRkYXRhLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHQgPSB0ZGF0YVtpXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRsZW4gPSB0Lmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQgPSBTdHIodFswXSkudG9Mb3dlckNhc2UoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFic29sdXRlID0gdFswXSAhPSBjb21tYW5kLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW52ZXIgPSBhYnNvbHV0ZSA/IG0uaW52ZXJ0KCkgOiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgeDEsXG4gICAgICAgICAgICAgICAgICAgICAgICB5MSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHgyLFxuICAgICAgICAgICAgICAgICAgICAgICAgeTIsXG4gICAgICAgICAgICAgICAgICAgICAgICBiYjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbW1hbmQgPT0gXCJ0XCIgJiYgdGxlbiA9PSAzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWJzb2x1dGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4MSA9IGludmVyLngoMCwgMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTEgPSBpbnZlci55KDAsIDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHgyID0gaW52ZXIueCh0WzFdLCB0WzJdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5MiA9IGludmVyLnkodFsxXSwgdFsyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbS50cmFuc2xhdGUoeDIgLSB4MSwgeTIgLSB5MSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0udHJhbnNsYXRlKHRbMV0sIHRbMl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmQgPT0gXCJyXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0bGVuID09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYiA9IGJiIHx8IGVsLmdldEJCb3goMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbS5yb3RhdGUodFsxXSwgYmIueCArIGJiLndpZHRoIC8gMiwgYmIueSArIGJiLmhlaWdodCAvIDIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZyArPSB0WzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0bGVuID09IDQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWJzb2x1dGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDIgPSBpbnZlci54KHRbMl0sIHRbM10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5MiA9IGludmVyLnkodFsyXSwgdFszXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0ucm90YXRlKHRbMV0sIHgyLCB5Mik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbS5yb3RhdGUodFsxXSwgdFsyXSwgdFszXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZyArPSB0WzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNvbW1hbmQgPT0gXCJzXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0bGVuID09IDIgfHwgdGxlbiA9PSAzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYmIgPSBiYiB8fCBlbC5nZXRCQm94KDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uc2NhbGUodFsxXSwgdFt0bGVuIC0gMV0sIGJiLnggKyBiYi53aWR0aCAvIDIsIGJiLnkgKyBiYi5oZWlnaHQgLyAyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeCAqPSB0WzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5ICo9IHRbdGxlbiAtIDFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0bGVuID09IDUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWJzb2x1dGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDIgPSBpbnZlci54KHRbM10sIHRbNF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5MiA9IGludmVyLnkodFszXSwgdFs0XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uc2NhbGUodFsxXSwgdFsyXSwgeDIsIHkyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtLnNjYWxlKHRbMV0sIHRbMl0sIHRbM10sIHRbNF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeCAqPSB0WzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5ICo9IHRbMl07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY29tbWFuZCA9PSBcIm1cIiAmJiB0bGVuID09IDcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG0uYWRkKHRbMV0sIHRbMl0sIHRbM10sIHRbNF0sIHRbNV0sIHRbNl0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF8uZGlydHlUID0gMTtcbiAgICAgICAgICAgICAgICAgICAgZWwubWF0cml4ID0gbTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8qXFxcbiAgICAgICAgICAgICAqIEVsZW1lbnQubWF0cml4XG4gICAgICAgICAgICAgWyBwcm9wZXJ0eSAob2JqZWN0KSBdXG4gICAgICAgICAgICAgKipcbiAgICAgICAgICAgICAqIEtlZXBzIEBNYXRyaXggb2JqZWN0LCB3aGljaCByZXByZXNlbnRzIGVsZW1lbnQgdHJhbnNmb3JtYXRpb25cbiAgICAgICAgICAgIFxcKi9cbiAgICAgICAgICAgIGVsLm1hdHJpeCA9IG07XG5cbiAgICAgICAgICAgIF8uc3ggPSBzeDtcbiAgICAgICAgICAgIF8uc3kgPSBzeTtcbiAgICAgICAgICAgIF8uZGVnID0gZGVnO1xuICAgICAgICAgICAgXy5keCA9IGR4ID0gbS5lO1xuICAgICAgICAgICAgXy5keSA9IGR5ID0gbS5mO1xuXG4gICAgICAgICAgICBpZiAoc3ggPT0gMSAmJiBzeSA9PSAxICYmICFkZWcgJiYgXy5iYm94KSB7XG4gICAgICAgICAgICAgICAgXy5iYm94LnggKz0gK2R4O1xuICAgICAgICAgICAgICAgIF8uYmJveC55ICs9ICtkeTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgXy5kaXJ0eVQgPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBnZXRFbXB0eSA9IGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICB2YXIgbCA9IGl0ZW1bMF07XG4gICAgICAgICAgICBzd2l0Y2ggKGwudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJ0XCI6IHJldHVybiBbbCwgMCwgMF07XG4gICAgICAgICAgICAgICAgY2FzZSBcIm1cIjogcmV0dXJuIFtsLCAxLCAwLCAwLCAxLCAwLCAwXTtcbiAgICAgICAgICAgICAgICBjYXNlIFwiclwiOiBpZiAoaXRlbS5sZW5ndGggPT0gNCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gW2wsIDAsIGl0ZW1bMl0sIGl0ZW1bM11dO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbbCwgMF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgXCJzXCI6IGlmIChpdGVtLmxlbmd0aCA9PSA1KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbbCwgMSwgMSwgaXRlbVszXSwgaXRlbVs0XV07XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpdGVtLmxlbmd0aCA9PSAzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbbCwgMSwgMV07XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtsLCAxXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGVxdWFsaXNlVHJhbnNmb3JtID0gUi5fZXF1YWxpc2VUcmFuc2Zvcm0gPSBmdW5jdGlvbiAodDEsIHQyKSB7XG4gICAgICAgICAgICB0MiA9IFN0cih0MikucmVwbGFjZSgvXFwuezN9fFxcdTIwMjYvZywgdDEpO1xuICAgICAgICAgICAgdDEgPSBSLnBhcnNlVHJhbnNmb3JtU3RyaW5nKHQxKSB8fCBbXTtcbiAgICAgICAgICAgIHQyID0gUi5wYXJzZVRyYW5zZm9ybVN0cmluZyh0MikgfHwgW107XG4gICAgICAgICAgICB2YXIgbWF4bGVuZ3RoID0gbW1heCh0MS5sZW5ndGgsIHQyLmxlbmd0aCksXG4gICAgICAgICAgICAgICAgZnJvbSA9IFtdLFxuICAgICAgICAgICAgICAgIHRvID0gW10sXG4gICAgICAgICAgICAgICAgaSA9IDAsIGosIGpqLFxuICAgICAgICAgICAgICAgIHR0MSwgdHQyO1xuICAgICAgICAgICAgZm9yICg7IGkgPCBtYXhsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHR0MSA9IHQxW2ldIHx8IGdldEVtcHR5KHQyW2ldKTtcbiAgICAgICAgICAgICAgICB0dDIgPSB0MltpXSB8fCBnZXRFbXB0eSh0dDEpO1xuICAgICAgICAgICAgICAgIGlmICgodHQxWzBdICE9IHR0MlswXSkgfHxcbiAgICAgICAgICAgICAgICAgICAgKHR0MVswXS50b0xvd2VyQ2FzZSgpID09IFwiclwiICYmICh0dDFbMl0gIT0gdHQyWzJdIHx8IHR0MVszXSAhPSB0dDJbM10pKSB8fFxuICAgICAgICAgICAgICAgICAgICAodHQxWzBdLnRvTG93ZXJDYXNlKCkgPT0gXCJzXCIgJiYgKHR0MVszXSAhPSB0dDJbM10gfHwgdHQxWzRdICE9IHR0Mls0XSkpXG4gICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZyb21baV0gPSBbXTtcbiAgICAgICAgICAgICAgICB0b1tpXSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAoaiA9IDAsIGpqID0gbW1heCh0dDEubGVuZ3RoLCB0dDIubGVuZ3RoKTsgaiA8IGpqOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaiBpbiB0dDEgJiYgKGZyb21baV1bal0gPSB0dDFbal0pO1xuICAgICAgICAgICAgICAgICAgICBqIGluIHR0MiAmJiAodG9baV1bal0gPSB0dDJbal0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZnJvbTogZnJvbSxcbiAgICAgICAgICAgICAgICB0bzogdG9cbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgUi5fZ2V0Q29udGFpbmVyID0gZnVuY3Rpb24gKHgsIHksIHcsIGgpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lcjtcbiAgICAgICAgY29udGFpbmVyID0gaCA9PSBudWxsICYmICFSLmlzKHgsIFwib2JqZWN0XCIpID8gZy5kb2MuZ2V0RWxlbWVudEJ5SWQoeCkgOiB4O1xuICAgICAgICBpZiAoY29udGFpbmVyID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29udGFpbmVyLnRhZ05hbWUpIHtcbiAgICAgICAgICAgIGlmICh5ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBjb250YWluZXI6IGNvbnRhaW5lcixcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGNvbnRhaW5lci5zdHlsZS5waXhlbFdpZHRoIHx8IGNvbnRhaW5lci5vZmZzZXRXaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBjb250YWluZXIuc3R5bGUucGl4ZWxIZWlnaHQgfHwgY29udGFpbmVyLm9mZnNldEhlaWdodFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lcjogY29udGFpbmVyLFxuICAgICAgICAgICAgICAgICAgICB3aWR0aDogeSxcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiB3XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGFpbmVyOiAxLFxuICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgIHk6IHksXG4gICAgICAgICAgICB3aWR0aDogdyxcbiAgICAgICAgICAgIGhlaWdodDogaFxuICAgICAgICB9O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwucGF0aFRvUmVsYXRpdmVcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFV0aWxpdHkgbWV0aG9kXG4gICAgICoqXG4gICAgICogQ29udmVydHMgcGF0aCB0byByZWxhdGl2ZSBmb3JtXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIHBhdGhTdHJpbmcgKHN0cmluZ3xhcnJheSkgcGF0aCBzdHJpbmcgb3IgYXJyYXkgb2Ygc2VnbWVudHNcbiAgICAgPSAoYXJyYXkpIGFycmF5IG9mIHNlZ21lbnRzLlxuICAgIFxcKi9cbiAgICBSLnBhdGhUb1JlbGF0aXZlID0gcGF0aFRvUmVsYXRpdmU7XG4gICAgUi5fZW5naW5lID0ge307XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwucGF0aDJjdXJ2ZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogVXRpbGl0eSBtZXRob2RcbiAgICAgKipcbiAgICAgKiBDb252ZXJ0cyBwYXRoIHRvIGEgbmV3IHBhdGggd2hlcmUgYWxsIHNlZ21lbnRzIGFyZSBjdWJpYyBiZXppZXIgY3VydmVzLlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBwYXRoU3RyaW5nIChzdHJpbmd8YXJyYXkpIHBhdGggc3RyaW5nIG9yIGFycmF5IG9mIHNlZ21lbnRzXG4gICAgID0gKGFycmF5KSBhcnJheSBvZiBzZWdtZW50cy5cbiAgICBcXCovXG4gICAgUi5wYXRoMmN1cnZlID0gcGF0aDJjdXJ2ZTtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5tYXRyaXhcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFV0aWxpdHkgbWV0aG9kXG4gICAgICoqXG4gICAgICogUmV0dXJucyBtYXRyaXggYmFzZWQgb24gZ2l2ZW4gcGFyYW1ldGVycy5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gYSAobnVtYmVyKVxuICAgICAtIGIgKG51bWJlcilcbiAgICAgLSBjIChudW1iZXIpXG4gICAgIC0gZCAobnVtYmVyKVxuICAgICAtIGUgKG51bWJlcilcbiAgICAgLSBmIChudW1iZXIpXG4gICAgID0gKG9iamVjdCkgQE1hdHJpeFxuICAgIFxcKi9cbiAgICBSLm1hdHJpeCA9IGZ1bmN0aW9uIChhLCBiLCBjLCBkLCBlLCBmKSB7XG4gICAgICAgIHJldHVybiBuZXcgTWF0cml4KGEsIGIsIGMsIGQsIGUsIGYpO1xuICAgIH07XG4gICAgZnVuY3Rpb24gTWF0cml4KGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgICAgICAgaWYgKGEgIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5hID0gK2E7XG4gICAgICAgICAgICB0aGlzLmIgPSArYjtcbiAgICAgICAgICAgIHRoaXMuYyA9ICtjO1xuICAgICAgICAgICAgdGhpcy5kID0gK2Q7XG4gICAgICAgICAgICB0aGlzLmUgPSArZTtcbiAgICAgICAgICAgIHRoaXMuZiA9ICtmO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hID0gMTtcbiAgICAgICAgICAgIHRoaXMuYiA9IDA7XG4gICAgICAgICAgICB0aGlzLmMgPSAwO1xuICAgICAgICAgICAgdGhpcy5kID0gMTtcbiAgICAgICAgICAgIHRoaXMuZSA9IDA7XG4gICAgICAgICAgICB0aGlzLmYgPSAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIChmdW5jdGlvbiAobWF0cml4cHJvdG8pIHtcbiAgICAgICAgLypcXFxuICAgICAgICAgKiBNYXRyaXguYWRkXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqKlxuICAgICAgICAgKiBBZGRzIGdpdmVuIG1hdHJpeCB0byBleGlzdGluZyBvbmUuXG4gICAgICAgICA+IFBhcmFtZXRlcnNcbiAgICAgICAgIC0gYSAobnVtYmVyKVxuICAgICAgICAgLSBiIChudW1iZXIpXG4gICAgICAgICAtIGMgKG51bWJlcilcbiAgICAgICAgIC0gZCAobnVtYmVyKVxuICAgICAgICAgLSBlIChudW1iZXIpXG4gICAgICAgICAtIGYgKG51bWJlcilcbiAgICAgICAgIG9yXG4gICAgICAgICAtIG1hdHJpeCAob2JqZWN0KSBATWF0cml4XG4gICAgICAgIFxcKi9cbiAgICAgICAgbWF0cml4cHJvdG8uYWRkID0gZnVuY3Rpb24gKGEsIGIsIGMsIGQsIGUsIGYpIHtcbiAgICAgICAgICAgIHZhciBvdXQgPSBbW10sIFtdLCBbXV0sXG4gICAgICAgICAgICAgICAgbSA9IFtbdGhpcy5hLCB0aGlzLmMsIHRoaXMuZV0sIFt0aGlzLmIsIHRoaXMuZCwgdGhpcy5mXSwgWzAsIDAsIDFdXSxcbiAgICAgICAgICAgICAgICBtYXRyaXggPSBbW2EsIGMsIGVdLCBbYiwgZCwgZl0sIFswLCAwLCAxXV0sXG4gICAgICAgICAgICAgICAgeCwgeSwgeiwgcmVzO1xuXG4gICAgICAgICAgICBpZiAoYSAmJiBhIGluc3RhbmNlb2YgTWF0cml4KSB7XG4gICAgICAgICAgICAgICAgbWF0cml4ID0gW1thLmEsIGEuYywgYS5lXSwgW2EuYiwgYS5kLCBhLmZdLCBbMCwgMCwgMV1dO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgMzsgeCsrKSB7XG4gICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IDM7IHkrKykge1xuICAgICAgICAgICAgICAgICAgICByZXMgPSAwO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHogPSAwOyB6IDwgMzsgeisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXMgKz0gbVt4XVt6XSAqIG1hdHJpeFt6XVt5XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBvdXRbeF1beV0gPSByZXM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5hID0gb3V0WzBdWzBdO1xuICAgICAgICAgICAgdGhpcy5iID0gb3V0WzFdWzBdO1xuICAgICAgICAgICAgdGhpcy5jID0gb3V0WzBdWzFdO1xuICAgICAgICAgICAgdGhpcy5kID0gb3V0WzFdWzFdO1xuICAgICAgICAgICAgdGhpcy5lID0gb3V0WzBdWzJdO1xuICAgICAgICAgICAgdGhpcy5mID0gb3V0WzFdWzJdO1xuICAgICAgICB9O1xuICAgICAgICAvKlxcXG4gICAgICAgICAqIE1hdHJpeC5pbnZlcnRcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICoqXG4gICAgICAgICAqIFJldHVybnMgaW52ZXJ0ZWQgdmVyc2lvbiBvZiB0aGUgbWF0cml4XG4gICAgICAgICA9IChvYmplY3QpIEBNYXRyaXhcbiAgICAgICAgXFwqL1xuICAgICAgICBtYXRyaXhwcm90by5pbnZlcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgbWUgPSB0aGlzLFxuICAgICAgICAgICAgICAgIHggPSBtZS5hICogbWUuZCAtIG1lLmIgKiBtZS5jO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXRyaXgobWUuZCAvIHgsIC1tZS5iIC8geCwgLW1lLmMgLyB4LCBtZS5hIC8geCwgKG1lLmMgKiBtZS5mIC0gbWUuZCAqIG1lLmUpIC8geCwgKG1lLmIgKiBtZS5lIC0gbWUuYSAqIG1lLmYpIC8geCk7XG4gICAgICAgIH07XG4gICAgICAgIC8qXFxcbiAgICAgICAgICogTWF0cml4LmNsb25lXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqKlxuICAgICAgICAgKiBSZXR1cm5zIGNvcHkgb2YgdGhlIG1hdHJpeFxuICAgICAgICAgPSAob2JqZWN0KSBATWF0cml4XG4gICAgICAgIFxcKi9cbiAgICAgICAgbWF0cml4cHJvdG8uY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IE1hdHJpeCh0aGlzLmEsIHRoaXMuYiwgdGhpcy5jLCB0aGlzLmQsIHRoaXMuZSwgdGhpcy5mKTtcbiAgICAgICAgfTtcbiAgICAgICAgLypcXFxuICAgICAgICAgKiBNYXRyaXgudHJhbnNsYXRlXG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqKlxuICAgICAgICAgKiBUcmFuc2xhdGUgdGhlIG1hdHJpeFxuICAgICAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICAgICAtIHggKG51bWJlcilcbiAgICAgICAgIC0geSAobnVtYmVyKVxuICAgICAgICBcXCovXG4gICAgICAgIG1hdHJpeHByb3RvLnRyYW5zbGF0ZSA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgICAgICB0aGlzLmFkZCgxLCAwLCAwLCAxLCB4LCB5KTtcbiAgICAgICAgfTtcbiAgICAgICAgLypcXFxuICAgICAgICAgKiBNYXRyaXguc2NhbGVcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICoqXG4gICAgICAgICAqIFNjYWxlcyB0aGUgbWF0cml4XG4gICAgICAgICA+IFBhcmFtZXRlcnNcbiAgICAgICAgIC0geCAobnVtYmVyKVxuICAgICAgICAgLSB5IChudW1iZXIpICNvcHRpb25hbFxuICAgICAgICAgLSBjeCAobnVtYmVyKSAjb3B0aW9uYWxcbiAgICAgICAgIC0gY3kgKG51bWJlcikgI29wdGlvbmFsXG4gICAgICAgIFxcKi9cbiAgICAgICAgbWF0cml4cHJvdG8uc2NhbGUgPSBmdW5jdGlvbiAoeCwgeSwgY3gsIGN5KSB7XG4gICAgICAgICAgICB5ID09IG51bGwgJiYgKHkgPSB4KTtcbiAgICAgICAgICAgIChjeCB8fCBjeSkgJiYgdGhpcy5hZGQoMSwgMCwgMCwgMSwgY3gsIGN5KTtcbiAgICAgICAgICAgIHRoaXMuYWRkKHgsIDAsIDAsIHksIDAsIDApO1xuICAgICAgICAgICAgKGN4IHx8IGN5KSAmJiB0aGlzLmFkZCgxLCAwLCAwLCAxLCAtY3gsIC1jeSk7XG4gICAgICAgIH07XG4gICAgICAgIC8qXFxcbiAgICAgICAgICogTWF0cml4LnJvdGF0ZVxuICAgICAgICAgWyBtZXRob2QgXVxuICAgICAgICAgKipcbiAgICAgICAgICogUm90YXRlcyB0aGUgbWF0cml4XG4gICAgICAgICA+IFBhcmFtZXRlcnNcbiAgICAgICAgIC0gYSAobnVtYmVyKVxuICAgICAgICAgLSB4IChudW1iZXIpXG4gICAgICAgICAtIHkgKG51bWJlcilcbiAgICAgICAgXFwqL1xuICAgICAgICBtYXRyaXhwcm90by5yb3RhdGUgPSBmdW5jdGlvbiAoYSwgeCwgeSkge1xuICAgICAgICAgICAgYSA9IFIucmFkKGEpO1xuICAgICAgICAgICAgeCA9IHggfHwgMDtcbiAgICAgICAgICAgIHkgPSB5IHx8IDA7XG4gICAgICAgICAgICB2YXIgY29zID0gK21hdGguY29zKGEpLnRvRml4ZWQoOSksXG4gICAgICAgICAgICAgICAgc2luID0gK21hdGguc2luKGEpLnRvRml4ZWQoOSk7XG4gICAgICAgICAgICB0aGlzLmFkZChjb3MsIHNpbiwgLXNpbiwgY29zLCB4LCB5KTtcbiAgICAgICAgICAgIHRoaXMuYWRkKDEsIDAsIDAsIDEsIC14LCAteSk7XG4gICAgICAgIH07XG4gICAgICAgIC8qXFxcbiAgICAgICAgICogTWF0cml4LnhcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICoqXG4gICAgICAgICAqIFJldHVybiB4IGNvb3JkaW5hdGUgZm9yIGdpdmVuIHBvaW50IGFmdGVyIHRyYW5zZm9ybWF0aW9uIGRlc2NyaWJlZCBieSB0aGUgbWF0cml4LiBTZWUgYWxzbyBATWF0cml4LnlcbiAgICAgICAgID4gUGFyYW1ldGVyc1xuICAgICAgICAgLSB4IChudW1iZXIpXG4gICAgICAgICAtIHkgKG51bWJlcilcbiAgICAgICAgID0gKG51bWJlcikgeFxuICAgICAgICBcXCovXG4gICAgICAgIG1hdHJpeHByb3RvLnggPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICAgICAgcmV0dXJuIHggKiB0aGlzLmEgKyB5ICogdGhpcy5jICsgdGhpcy5lO1xuICAgICAgICB9O1xuICAgICAgICAvKlxcXG4gICAgICAgICAqIE1hdHJpeC55XG4gICAgICAgICBbIG1ldGhvZCBdXG4gICAgICAgICAqKlxuICAgICAgICAgKiBSZXR1cm4geSBjb29yZGluYXRlIGZvciBnaXZlbiBwb2ludCBhZnRlciB0cmFuc2Zvcm1hdGlvbiBkZXNjcmliZWQgYnkgdGhlIG1hdHJpeC4gU2VlIGFsc28gQE1hdHJpeC54XG4gICAgICAgICA+IFBhcmFtZXRlcnNcbiAgICAgICAgIC0geCAobnVtYmVyKVxuICAgICAgICAgLSB5IChudW1iZXIpXG4gICAgICAgICA9IChudW1iZXIpIHlcbiAgICAgICAgXFwqL1xuICAgICAgICBtYXRyaXhwcm90by55ID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICAgICAgICAgIHJldHVybiB4ICogdGhpcy5iICsgeSAqIHRoaXMuZCArIHRoaXMuZjtcbiAgICAgICAgfTtcbiAgICAgICAgbWF0cml4cHJvdG8uZ2V0ID0gZnVuY3Rpb24gKGkpIHtcbiAgICAgICAgICAgIHJldHVybiArdGhpc1tTdHIuZnJvbUNoYXJDb2RlKDk3ICsgaSldLnRvRml4ZWQoNCk7XG4gICAgICAgIH07XG4gICAgICAgIG1hdHJpeHByb3RvLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIFIuc3ZnID9cbiAgICAgICAgICAgICAgICBcIm1hdHJpeChcIiArIFt0aGlzLmdldCgwKSwgdGhpcy5nZXQoMSksIHRoaXMuZ2V0KDIpLCB0aGlzLmdldCgzKSwgdGhpcy5nZXQoNCksIHRoaXMuZ2V0KDUpXS5qb2luKCkgKyBcIilcIiA6XG4gICAgICAgICAgICAgICAgW3RoaXMuZ2V0KDApLCB0aGlzLmdldCgyKSwgdGhpcy5nZXQoMSksIHRoaXMuZ2V0KDMpLCAwLCAwXS5qb2luKCk7XG4gICAgICAgIH07XG4gICAgICAgIG1hdHJpeHByb3RvLnRvRmlsdGVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIFwicHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0Lk1hdHJpeChNMTE9XCIgKyB0aGlzLmdldCgwKSArXG4gICAgICAgICAgICAgICAgXCIsIE0xMj1cIiArIHRoaXMuZ2V0KDIpICsgXCIsIE0yMT1cIiArIHRoaXMuZ2V0KDEpICsgXCIsIE0yMj1cIiArIHRoaXMuZ2V0KDMpICtcbiAgICAgICAgICAgICAgICBcIiwgRHg9XCIgKyB0aGlzLmdldCg0KSArIFwiLCBEeT1cIiArIHRoaXMuZ2V0KDUpICsgXCIsIHNpemluZ21ldGhvZD0nYXV0byBleHBhbmQnKVwiO1xuICAgICAgICB9O1xuICAgICAgICBtYXRyaXhwcm90by5vZmZzZXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gW3RoaXMuZS50b0ZpeGVkKDQpLCB0aGlzLmYudG9GaXhlZCg0KV07XG4gICAgICAgIH07XG4gICAgICAgIGZ1bmN0aW9uIG5vcm0oYSkge1xuICAgICAgICAgICAgcmV0dXJuIGFbMF0gKiBhWzBdICsgYVsxXSAqIGFbMV07XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gbm9ybWFsaXplKGEpIHtcbiAgICAgICAgICAgIHZhciBtYWcgPSBtYXRoLnNxcnQobm9ybShhKSk7XG4gICAgICAgICAgICBhWzBdICYmIChhWzBdIC89IG1hZyk7XG4gICAgICAgICAgICBhWzFdICYmIChhWzFdIC89IG1hZyk7XG4gICAgICAgIH1cbiAgICAgICAgLypcXFxuICAgICAgICAgKiBNYXRyaXguc3BsaXRcbiAgICAgICAgIFsgbWV0aG9kIF1cbiAgICAgICAgICoqXG4gICAgICAgICAqIFNwbGl0cyBtYXRyaXggaW50byBwcmltaXRpdmUgdHJhbnNmb3JtYXRpb25zXG4gICAgICAgICA9IChvYmplY3QpIGluIGZvcm1hdDpcbiAgICAgICAgIG8gZHggKG51bWJlcikgdHJhbnNsYXRpb24gYnkgeFxuICAgICAgICAgbyBkeSAobnVtYmVyKSB0cmFuc2xhdGlvbiBieSB5XG4gICAgICAgICBvIHNjYWxleCAobnVtYmVyKSBzY2FsZSBieSB4XG4gICAgICAgICBvIHNjYWxleSAobnVtYmVyKSBzY2FsZSBieSB5XG4gICAgICAgICBvIHNoZWFyIChudW1iZXIpIHNoZWFyXG4gICAgICAgICBvIHJvdGF0ZSAobnVtYmVyKSByb3RhdGlvbiBpbiBkZWdcbiAgICAgICAgIG8gaXNTaW1wbGUgKGJvb2xlYW4pIGNvdWxkIGl0IGJlIHJlcHJlc2VudGVkIHZpYSBzaW1wbGUgdHJhbnNmb3JtYXRpb25zXG4gICAgICAgIFxcKi9cbiAgICAgICAgbWF0cml4cHJvdG8uc3BsaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgb3V0ID0ge307XG4gICAgICAgICAgICAvLyB0cmFuc2xhdGlvblxuICAgICAgICAgICAgb3V0LmR4ID0gdGhpcy5lO1xuICAgICAgICAgICAgb3V0LmR5ID0gdGhpcy5mO1xuXG4gICAgICAgICAgICAvLyBzY2FsZSBhbmQgc2hlYXJcbiAgICAgICAgICAgIHZhciByb3cgPSBbW3RoaXMuYSwgdGhpcy5jXSwgW3RoaXMuYiwgdGhpcy5kXV07XG4gICAgICAgICAgICBvdXQuc2NhbGV4ID0gbWF0aC5zcXJ0KG5vcm0ocm93WzBdKSk7XG4gICAgICAgICAgICBub3JtYWxpemUocm93WzBdKTtcblxuICAgICAgICAgICAgb3V0LnNoZWFyID0gcm93WzBdWzBdICogcm93WzFdWzBdICsgcm93WzBdWzFdICogcm93WzFdWzFdO1xuICAgICAgICAgICAgcm93WzFdID0gW3Jvd1sxXVswXSAtIHJvd1swXVswXSAqIG91dC5zaGVhciwgcm93WzFdWzFdIC0gcm93WzBdWzFdICogb3V0LnNoZWFyXTtcblxuICAgICAgICAgICAgb3V0LnNjYWxleSA9IG1hdGguc3FydChub3JtKHJvd1sxXSkpO1xuICAgICAgICAgICAgbm9ybWFsaXplKHJvd1sxXSk7XG4gICAgICAgICAgICBvdXQuc2hlYXIgLz0gb3V0LnNjYWxleTtcblxuICAgICAgICAgICAgLy8gcm90YXRpb25cbiAgICAgICAgICAgIHZhciBzaW4gPSAtcm93WzBdWzFdLFxuICAgICAgICAgICAgICAgIGNvcyA9IHJvd1sxXVsxXTtcbiAgICAgICAgICAgIGlmIChjb3MgPCAwKSB7XG4gICAgICAgICAgICAgICAgb3V0LnJvdGF0ZSA9IFIuZGVnKG1hdGguYWNvcyhjb3MpKTtcbiAgICAgICAgICAgICAgICBpZiAoc2luIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICBvdXQucm90YXRlID0gMzYwIC0gb3V0LnJvdGF0ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG91dC5yb3RhdGUgPSBSLmRlZyhtYXRoLmFzaW4oc2luKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG91dC5pc1NpbXBsZSA9ICErb3V0LnNoZWFyLnRvRml4ZWQoOSkgJiYgKG91dC5zY2FsZXgudG9GaXhlZCg5KSA9PSBvdXQuc2NhbGV5LnRvRml4ZWQoOSkgfHwgIW91dC5yb3RhdGUpO1xuICAgICAgICAgICAgb3V0LmlzU3VwZXJTaW1wbGUgPSAhK291dC5zaGVhci50b0ZpeGVkKDkpICYmIG91dC5zY2FsZXgudG9GaXhlZCg5KSA9PSBvdXQuc2NhbGV5LnRvRml4ZWQoOSkgJiYgIW91dC5yb3RhdGU7XG4gICAgICAgICAgICBvdXQubm9Sb3RhdGlvbiA9ICErb3V0LnNoZWFyLnRvRml4ZWQoOSkgJiYgIW91dC5yb3RhdGU7XG4gICAgICAgICAgICByZXR1cm4gb3V0O1xuICAgICAgICB9O1xuICAgICAgICAvKlxcXG4gICAgICAgICAqIE1hdHJpeC50b1RyYW5zZm9ybVN0cmluZ1xuICAgICAgICAgWyBtZXRob2QgXVxuICAgICAgICAgKipcbiAgICAgICAgICogUmV0dXJuIHRyYW5zZm9ybSBzdHJpbmcgdGhhdCByZXByZXNlbnRzIGdpdmVuIG1hdHJpeFxuICAgICAgICAgPSAoc3RyaW5nKSB0cmFuc2Zvcm0gc3RyaW5nXG4gICAgICAgIFxcKi9cbiAgICAgICAgbWF0cml4cHJvdG8udG9UcmFuc2Zvcm1TdHJpbmcgPSBmdW5jdGlvbiAoc2hvcnRlcikge1xuICAgICAgICAgICAgdmFyIHMgPSBzaG9ydGVyIHx8IHRoaXNbc3BsaXRdKCk7XG4gICAgICAgICAgICBpZiAocy5pc1NpbXBsZSkge1xuICAgICAgICAgICAgICAgIHMuc2NhbGV4ID0gK3Muc2NhbGV4LnRvRml4ZWQoNCk7XG4gICAgICAgICAgICAgICAgcy5zY2FsZXkgPSArcy5zY2FsZXkudG9GaXhlZCg0KTtcbiAgICAgICAgICAgICAgICBzLnJvdGF0ZSA9ICtzLnJvdGF0ZS50b0ZpeGVkKDQpO1xuICAgICAgICAgICAgICAgIHJldHVybiAgKHMuZHggfHwgcy5keSA/IFwidFwiICsgW3MuZHgsIHMuZHldIDogRSkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgKHMuc2NhbGV4ICE9IDEgfHwgcy5zY2FsZXkgIT0gMSA/IFwic1wiICsgW3Muc2NhbGV4LCBzLnNjYWxleSwgMCwgMF0gOiBFKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAocy5yb3RhdGUgPyBcInJcIiArIFtzLnJvdGF0ZSwgMCwgMF0gOiBFKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwibVwiICsgW3RoaXMuZ2V0KDApLCB0aGlzLmdldCgxKSwgdGhpcy5nZXQoMiksIHRoaXMuZ2V0KDMpLCB0aGlzLmdldCg0KSwgdGhpcy5nZXQoNSldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pKE1hdHJpeC5wcm90b3R5cGUpO1xuXG4gICAgdmFyIHByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJldHVyblZhbHVlID0gZmFsc2U7XG4gICAgfSxcbiAgICBwcmV2ZW50VG91Y2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9yaWdpbmFsRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9LFxuICAgIHN0b3BQcm9wYWdhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jYW5jZWxCdWJibGUgPSB0cnVlO1xuICAgIH0sXG4gICAgc3RvcFRvdWNoID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5vcmlnaW5hbEV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0sXG4gICAgZ2V0RXZlbnRQb3NpdGlvbiA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHZhciBzY3JvbGxZID0gZy5kb2MuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBnLmRvYy5ib2R5LnNjcm9sbFRvcCxcbiAgICAgICAgICAgIHNjcm9sbFggPSBnLmRvYy5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdCB8fCBnLmRvYy5ib2R5LnNjcm9sbExlZnQ7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IGUuY2xpZW50WCArIHNjcm9sbFgsXG4gICAgICAgICAgICB5OiBlLmNsaWVudFkgKyBzY3JvbGxZXG4gICAgICAgIH07XG4gICAgfSxcbiAgICBhZGRFdmVudCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChnLmRvYy5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG9iaiwgdHlwZSwgZm4sIGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgZiA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSBnZXRFdmVudFBvc2l0aW9uKGUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZm4uY2FsbChlbGVtZW50LCBlLCBwb3MueCwgcG9zLnkpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgb2JqLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgZiwgZmFsc2UpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHN1cHBvcnRzVG91Y2ggJiYgdG91Y2hNYXBbdHlwZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIF9mID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSBnZXRFdmVudFBvc2l0aW9uKGUpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZGUgPSBlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBlLnRhcmdldFRvdWNoZXMgJiYgZS50YXJnZXRUb3VjaGVzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZS50YXJnZXRUb3VjaGVzW2ldLnRhcmdldCA9PSBvYmopIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZSA9IGUudGFyZ2V0VG91Y2hlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5vcmlnaW5hbEV2ZW50ID0gb2xkZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCA9IHByZXZlbnRUb3VjaDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24gPSBzdG9wVG91Y2g7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZuLmNhbGwoZWxlbWVudCwgZSwgcG9zLngsIHBvcy55KTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgb2JqLmFkZEV2ZW50TGlzdGVuZXIodG91Y2hNYXBbdHlwZV0sIF9mLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgb2JqLnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgZiwgZmFsc2UpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChzdXBwb3J0c1RvdWNoICYmIHRvdWNoTWFwW3R5cGVdKVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnJlbW92ZUV2ZW50TGlzdGVuZXIodG91Y2hNYXBbdHlwZV0sIF9mLCBmYWxzZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSBpZiAoZy5kb2MuYXR0YWNoRXZlbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAob2JqLCB0eXBlLCBmbiwgZWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHZhciBmID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZSA9IGUgfHwgZy53aW4uZXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxZID0gZy5kb2MuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBnLmRvYy5ib2R5LnNjcm9sbFRvcCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFggPSBnLmRvYy5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdCB8fCBnLmRvYy5ib2R5LnNjcm9sbExlZnQsXG4gICAgICAgICAgICAgICAgICAgICAgICB4ID0gZS5jbGllbnRYICsgc2Nyb2xsWCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBlLmNsaWVudFkgKyBzY3JvbGxZO1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0ID0gZS5wcmV2ZW50RGVmYXVsdCB8fCBwcmV2ZW50RGVmYXVsdDtcbiAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24gPSBlLnN0b3BQcm9wYWdhdGlvbiB8fCBzdG9wUHJvcGFnYXRpb247XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmbi5jYWxsKGVsZW1lbnQsIGUsIHgsIHkpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgb2JqLmF0dGFjaEV2ZW50KFwib25cIiArIHR5cGUsIGYpO1xuICAgICAgICAgICAgICAgIHZhciBkZXRhY2hlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgb2JqLmRldGFjaEV2ZW50KFwib25cIiArIHR5cGUsIGYpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJldHVybiBkZXRhY2hlcjtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9KSgpLFxuICAgIGRyYWcgPSBbXSxcbiAgICBkcmFnTW92ZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHZhciB4ID0gZS5jbGllbnRYLFxuICAgICAgICAgICAgeSA9IGUuY2xpZW50WSxcbiAgICAgICAgICAgIHNjcm9sbFkgPSBnLmRvYy5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wIHx8IGcuZG9jLmJvZHkuc2Nyb2xsVG9wLFxuICAgICAgICAgICAgc2Nyb2xsWCA9IGcuZG9jLmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0IHx8IGcuZG9jLmJvZHkuc2Nyb2xsTGVmdCxcbiAgICAgICAgICAgIGRyYWdpLFxuICAgICAgICAgICAgaiA9IGRyYWcubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoai0tKSB7XG4gICAgICAgICAgICBkcmFnaSA9IGRyYWdbal07XG4gICAgICAgICAgICBpZiAoc3VwcG9ydHNUb3VjaCAmJiBlLnRvdWNoZXMpIHtcbiAgICAgICAgICAgICAgICB2YXIgaSA9IGUudG91Y2hlcy5sZW5ndGgsXG4gICAgICAgICAgICAgICAgICAgIHRvdWNoO1xuICAgICAgICAgICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgdG91Y2ggPSBlLnRvdWNoZXNbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmICh0b3VjaC5pZGVudGlmaWVyID09IGRyYWdpLmVsLl9kcmFnLmlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB4ID0gdG91Y2guY2xpZW50WDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHkgPSB0b3VjaC5jbGllbnRZO1xuICAgICAgICAgICAgICAgICAgICAgICAgKGUub3JpZ2luYWxFdmVudCA/IGUub3JpZ2luYWxFdmVudCA6IGUpLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIG5vZGUgPSBkcmFnaS5lbC5ub2RlLFxuICAgICAgICAgICAgICAgIG8sXG4gICAgICAgICAgICAgICAgbmV4dCA9IG5vZGUubmV4dFNpYmxpbmcsXG4gICAgICAgICAgICAgICAgcGFyZW50ID0gbm9kZS5wYXJlbnROb2RlLFxuICAgICAgICAgICAgICAgIGRpc3BsYXkgPSBub2RlLnN0eWxlLmRpc3BsYXk7XG4gICAgICAgICAgICBnLndpbi5vcGVyYSAmJiBwYXJlbnQucmVtb3ZlQ2hpbGQobm9kZSk7XG4gICAgICAgICAgICBub2RlLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICAgICAgICAgIG8gPSBkcmFnaS5lbC5wYXBlci5nZXRFbGVtZW50QnlQb2ludCh4LCB5KTtcbiAgICAgICAgICAgIG5vZGUuc3R5bGUuZGlzcGxheSA9IGRpc3BsYXk7XG4gICAgICAgICAgICBnLndpbi5vcGVyYSAmJiAobmV4dCA/IHBhcmVudC5pbnNlcnRCZWZvcmUobm9kZSwgbmV4dCkgOiBwYXJlbnQuYXBwZW5kQ2hpbGQobm9kZSkpO1xuICAgICAgICAgICAgbyAmJiBldmUoXCJyYXBoYWVsLmRyYWcub3Zlci5cIiArIGRyYWdpLmVsLmlkLCBkcmFnaS5lbCwgbyk7XG4gICAgICAgICAgICB4ICs9IHNjcm9sbFg7XG4gICAgICAgICAgICB5ICs9IHNjcm9sbFk7XG4gICAgICAgICAgICBldmUoXCJyYXBoYWVsLmRyYWcubW92ZS5cIiArIGRyYWdpLmVsLmlkLCBkcmFnaS5tb3ZlX3Njb3BlIHx8IGRyYWdpLmVsLCB4IC0gZHJhZ2kuZWwuX2RyYWcueCwgeSAtIGRyYWdpLmVsLl9kcmFnLnksIHgsIHksIGUpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBkcmFnVXAgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICBSLnVubW91c2Vtb3ZlKGRyYWdNb3ZlKS51bm1vdXNldXAoZHJhZ1VwKTtcbiAgICAgICAgdmFyIGkgPSBkcmFnLmxlbmd0aCxcbiAgICAgICAgICAgIGRyYWdpO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBkcmFnaSA9IGRyYWdbaV07XG4gICAgICAgICAgICBkcmFnaS5lbC5fZHJhZyA9IHt9O1xuICAgICAgICAgICAgZXZlKFwicmFwaGFlbC5kcmFnLmVuZC5cIiArIGRyYWdpLmVsLmlkLCBkcmFnaS5lbmRfc2NvcGUgfHwgZHJhZ2kuc3RhcnRfc2NvcGUgfHwgZHJhZ2kubW92ZV9zY29wZSB8fCBkcmFnaS5lbCwgZSk7XG4gICAgICAgIH1cbiAgICAgICAgZHJhZyA9IFtdO1xuICAgIH0sXG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZWxcbiAgICAgWyBwcm9wZXJ0eSAob2JqZWN0KSBdXG4gICAgICoqXG4gICAgICogWW91IGNhbiBhZGQgeW91ciBvd24gbWV0aG9kIHRvIGVsZW1lbnRzLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHlvdSB3YW50IHRvIGhhY2sgZGVmYXVsdCBmdW5jdGlvbmFsaXR5IG9yXG4gICAgICogd2FudCB0byB3cmFwIHNvbWUgY29tbW9uIHRyYW5zZm9ybWF0aW9uIG9yIGF0dHJpYnV0ZXMgaW4gb25lIG1ldGhvZC4gSW4gZGlmZmVyZW5jZSB0byBjYW52YXMgbWV0aG9kcyxcbiAgICAgKiB5b3UgY2FuIHJlZGVmaW5lIGVsZW1lbnQgbWV0aG9kIGF0IGFueSB0aW1lLiBFeHBlbmRpbmcgZWxlbWVudCBtZXRob2RzIHdvdWxkbuKAmXQgYWZmZWN0IHNldC5cbiAgICAgPiBVc2FnZVxuICAgICB8IFJhcGhhZWwuZWwucmVkID0gZnVuY3Rpb24gKCkge1xuICAgICB8ICAgICB0aGlzLmF0dHIoe2ZpbGw6IFwiI2YwMFwifSk7XG4gICAgIHwgfTtcbiAgICAgfCAvLyB0aGVuIHVzZSBpdFxuICAgICB8IHBhcGVyLmNpcmNsZSgxMDAsIDEwMCwgMjApLnJlZCgpO1xuICAgIFxcKi9cbiAgICBlbHByb3RvID0gUi5lbCA9IHt9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LmNsaWNrXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBZGRzIGV2ZW50IGhhbmRsZXIgZm9yIGNsaWNrIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnVuY2xpY2tcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZXZlbnQgaGFuZGxlciBmb3IgY2xpY2sgZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoYW5kbGVyIChmdW5jdGlvbikgI29wdGlvbmFsIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuXG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuZGJsY2xpY2tcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEFkZHMgZXZlbnQgaGFuZGxlciBmb3IgZG91YmxlIGNsaWNrIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnVuZGJsY2xpY2tcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZXZlbnQgaGFuZGxlciBmb3IgZG91YmxlIGNsaWNrIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pICNvcHRpb25hbCBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cblxuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50Lm1vdXNlZG93blxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQWRkcyBldmVudCBoYW5kbGVyIGZvciBtb3VzZWRvd24gZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoYW5kbGVyIChmdW5jdGlvbikgaGFuZGxlciBmb3IgdGhlIGV2ZW50XG4gICAgID0gKG9iamVjdCkgQEVsZW1lbnRcbiAgICBcXCovXG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQudW5tb3VzZWRvd25cbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZXZlbnQgaGFuZGxlciBmb3IgbW91c2Vkb3duIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pICNvcHRpb25hbCBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cblxuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50Lm1vdXNlbW92ZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQWRkcyBldmVudCBoYW5kbGVyIGZvciBtb3VzZW1vdmUgZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoYW5kbGVyIChmdW5jdGlvbikgaGFuZGxlciBmb3IgdGhlIGV2ZW50XG4gICAgID0gKG9iamVjdCkgQEVsZW1lbnRcbiAgICBcXCovXG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQudW5tb3VzZW1vdmVcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZXZlbnQgaGFuZGxlciBmb3IgbW91c2Vtb3ZlIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pICNvcHRpb25hbCBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cblxuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50Lm1vdXNlb3V0XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBZGRzIGV2ZW50IGhhbmRsZXIgZm9yIG1vdXNlb3V0IGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnVubW91c2VvdXRcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZXZlbnQgaGFuZGxlciBmb3IgbW91c2VvdXQgZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoYW5kbGVyIChmdW5jdGlvbikgI29wdGlvbmFsIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuXG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQubW91c2VvdmVyXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBZGRzIGV2ZW50IGhhbmRsZXIgZm9yIG1vdXNlb3ZlciBmb3IgdGhlIGVsZW1lbnQuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIGhhbmRsZXIgKGZ1bmN0aW9uKSBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cbiAgICAvKlxcXG4gICAgICogRWxlbWVudC51bm1vdXNlb3ZlclxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVtb3ZlcyBldmVudCBoYW5kbGVyIGZvciBtb3VzZW92ZXIgZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoYW5kbGVyIChmdW5jdGlvbikgI29wdGlvbmFsIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuXG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQubW91c2V1cFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQWRkcyBldmVudCBoYW5kbGVyIGZvciBtb3VzZXVwIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnVubW91c2V1cFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVtb3ZlcyBldmVudCBoYW5kbGVyIGZvciBtb3VzZXVwIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pICNvcHRpb25hbCBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cblxuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnRvdWNoc3RhcnRcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEFkZHMgZXZlbnQgaGFuZGxlciBmb3IgdG91Y2hzdGFydCBmb3IgdGhlIGVsZW1lbnQuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIGhhbmRsZXIgKGZ1bmN0aW9uKSBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cbiAgICAvKlxcXG4gICAgICogRWxlbWVudC51bnRvdWNoc3RhcnRcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZXZlbnQgaGFuZGxlciBmb3IgdG91Y2hzdGFydCBmb3IgdGhlIGVsZW1lbnQuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIGhhbmRsZXIgKGZ1bmN0aW9uKSAjb3B0aW9uYWwgaGFuZGxlciBmb3IgdGhlIGV2ZW50XG4gICAgID0gKG9iamVjdCkgQEVsZW1lbnRcbiAgICBcXCovXG5cbiAgICAvKlxcXG4gICAgICogRWxlbWVudC50b3VjaG1vdmVcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEFkZHMgZXZlbnQgaGFuZGxlciBmb3IgdG91Y2htb3ZlIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnVudG91Y2htb3ZlXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZW1vdmVzIGV2ZW50IGhhbmRsZXIgZm9yIHRvdWNobW92ZSBmb3IgdGhlIGVsZW1lbnQuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIGhhbmRsZXIgKGZ1bmN0aW9uKSAjb3B0aW9uYWwgaGFuZGxlciBmb3IgdGhlIGV2ZW50XG4gICAgID0gKG9iamVjdCkgQEVsZW1lbnRcbiAgICBcXCovXG5cbiAgICAvKlxcXG4gICAgICogRWxlbWVudC50b3VjaGVuZFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQWRkcyBldmVudCBoYW5kbGVyIGZvciB0b3VjaGVuZCBmb3IgdGhlIGVsZW1lbnQuXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIGhhbmRsZXIgKGZ1bmN0aW9uKSBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cbiAgICAvKlxcXG4gICAgICogRWxlbWVudC51bnRvdWNoZW5kXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZW1vdmVzIGV2ZW50IGhhbmRsZXIgZm9yIHRvdWNoZW5kIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pICNvcHRpb25hbCBoYW5kbGVyIGZvciB0aGUgZXZlbnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cblxuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnRvdWNoY2FuY2VsXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBZGRzIGV2ZW50IGhhbmRsZXIgZm9yIHRvdWNoY2FuY2VsIGZvciB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gaGFuZGxlciAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnVudG91Y2hjYW5jZWxcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZXZlbnQgaGFuZGxlciBmb3IgdG91Y2hjYW5jZWwgZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBoYW5kbGVyIChmdW5jdGlvbikgI29wdGlvbmFsIGhhbmRsZXIgZm9yIHRoZSBldmVudFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIGZvciAodmFyIGkgPSBldmVudHMubGVuZ3RoOyBpLS07KSB7XG4gICAgICAgIChmdW5jdGlvbiAoZXZlbnROYW1lKSB7XG4gICAgICAgICAgICBSW2V2ZW50TmFtZV0gPSBlbHByb3RvW2V2ZW50TmFtZV0gPSBmdW5jdGlvbiAoZm4sIHNjb3BlKSB7XG4gICAgICAgICAgICAgICAgaWYgKFIuaXMoZm4sIFwiZnVuY3Rpb25cIikpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudHMgPSB0aGlzLmV2ZW50cyB8fCBbXTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ldmVudHMucHVzaCh7bmFtZTogZXZlbnROYW1lLCBmOiBmbiwgdW5iaW5kOiBhZGRFdmVudCh0aGlzLnNoYXBlIHx8IHRoaXMubm9kZSB8fCBnLmRvYywgZXZlbnROYW1lLCBmbiwgc2NvcGUgfHwgdGhpcyl9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgUltcInVuXCIgKyBldmVudE5hbWVdID0gZWxwcm90b1tcInVuXCIgKyBldmVudE5hbWVdID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgICAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuZXZlbnRzIHx8IFtdLFxuICAgICAgICAgICAgICAgICAgICBsID0gZXZlbnRzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICB3aGlsZSAobC0tKXtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50c1tsXS5uYW1lID09IGV2ZW50TmFtZSAmJiAoUi5pcyhmbiwgXCJ1bmRlZmluZWRcIikgfHwgZXZlbnRzW2xdLmYgPT0gZm4pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudHNbbF0udW5iaW5kKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudHMuc3BsaWNlKGwsIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgIWV2ZW50cy5sZW5ndGggJiYgZGVsZXRlIHRoaXMuZXZlbnRzO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkoZXZlbnRzW2ldKTtcbiAgICB9XG5cbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5kYXRhXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBZGRzIG9yIHJldHJpZXZlcyBnaXZlbiB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggZ2l2ZW4ga2V5LlxuICAgICAqKlxuICAgICAqIFNlZSBhbHNvIEBFbGVtZW50LnJlbW92ZURhdGFcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0ga2V5IChzdHJpbmcpIGtleSB0byBzdG9yZSBkYXRhXG4gICAgIC0gdmFsdWUgKGFueSkgI29wdGlvbmFsIHZhbHVlIHRvIHN0b3JlXG4gICAgID0gKG9iamVjdCkgQEVsZW1lbnRcbiAgICAgKiBvciwgaWYgdmFsdWUgaXMgbm90IHNwZWNpZmllZDpcbiAgICAgPSAoYW55KSB2YWx1ZVxuICAgICAqIG9yLCBpZiBrZXkgYW5kIHZhbHVlIGFyZSBub3Qgc3BlY2lmaWVkOlxuICAgICA9IChvYmplY3QpIEtleS92YWx1ZSBwYWlycyBmb3IgYWxsIHRoZSBkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgZWxlbWVudC5cbiAgICAgPiBVc2FnZVxuICAgICB8IGZvciAodmFyIGkgPSAwLCBpIDwgNSwgaSsrKSB7XG4gICAgIHwgICAgIHBhcGVyLmNpcmNsZSgxMCArIDE1ICogaSwgMTAsIDEwKVxuICAgICB8ICAgICAgICAgIC5hdHRyKHtmaWxsOiBcIiMwMDBcIn0pXG4gICAgIHwgICAgICAgICAgLmRhdGEoXCJpXCIsIGkpXG4gICAgIHwgICAgICAgICAgLmNsaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgfCAgICAgICAgICAgICBhbGVydCh0aGlzLmRhdGEoXCJpXCIpKTtcbiAgICAgfCAgICAgICAgICB9KTtcbiAgICAgfCB9XG4gICAgXFwqL1xuICAgIGVscHJvdG8uZGF0YSA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICAgIHZhciBkYXRhID0gZWxkYXRhW3RoaXMuaWRdID0gZWxkYXRhW3RoaXMuaWRdIHx8IHt9O1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAxKSB7XG4gICAgICAgICAgICBpZiAoUi5pcyhrZXksIFwib2JqZWN0XCIpKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBrZXkpIGlmIChrZXlbaGFzXShpKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGEoaSwga2V5W2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBldmUoXCJyYXBoYWVsLmRhdGEuZ2V0LlwiICsgdGhpcy5pZCwgdGhpcywgZGF0YVtrZXldLCBrZXkpO1xuICAgICAgICAgICAgcmV0dXJuIGRhdGFba2V5XTtcbiAgICAgICAgfVxuICAgICAgICBkYXRhW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgZXZlKFwicmFwaGFlbC5kYXRhLnNldC5cIiArIHRoaXMuaWQsIHRoaXMsIHZhbHVlLCBrZXkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnJlbW92ZURhdGFcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIGFuIGVsZW1lbnQgYnkgZ2l2ZW4ga2V5LlxuICAgICAqIElmIGtleSBpcyBub3QgcHJvdmlkZWQsIHJlbW92ZXMgYWxsIHRoZSBkYXRhIG9mIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBrZXkgKHN0cmluZykgI29wdGlvbmFsIGtleVxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIGVscHJvdG8ucmVtb3ZlRGF0YSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgaWYgKGtleSA9PSBudWxsKSB7XG4gICAgICAgICAgICBlbGRhdGFbdGhpcy5pZF0gPSB7fTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGVsZGF0YVt0aGlzLmlkXSAmJiBkZWxldGUgZWxkYXRhW3RoaXMuaWRdW2tleV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAgLypcXFxuICAgICAqIEVsZW1lbnQuZ2V0RGF0YVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0cmlldmVzIHRoZSBlbGVtZW50IGRhdGFcbiAgICAgPSAob2JqZWN0KSBkYXRhXG4gICAgXFwqL1xuICAgIGVscHJvdG8uZ2V0RGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGNsb25lKGVsZGF0YVt0aGlzLmlkXSB8fCB7fSk7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5ob3ZlclxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQWRkcyBldmVudCBoYW5kbGVycyBmb3IgaG92ZXIgZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBmX2luIChmdW5jdGlvbikgaGFuZGxlciBmb3IgaG92ZXIgaW5cbiAgICAgLSBmX291dCAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIGhvdmVyIG91dFxuICAgICAtIGljb250ZXh0IChvYmplY3QpICNvcHRpb25hbCBjb250ZXh0IGZvciBob3ZlciBpbiBoYW5kbGVyXG4gICAgIC0gb2NvbnRleHQgKG9iamVjdCkgI29wdGlvbmFsIGNvbnRleHQgZm9yIGhvdmVyIG91dCBoYW5kbGVyXG4gICAgID0gKG9iamVjdCkgQEVsZW1lbnRcbiAgICBcXCovXG4gICAgZWxwcm90by5ob3ZlciA9IGZ1bmN0aW9uIChmX2luLCBmX291dCwgc2NvcGVfaW4sIHNjb3BlX291dCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tb3VzZW92ZXIoZl9pbiwgc2NvcGVfaW4pLm1vdXNlb3V0KGZfb3V0LCBzY29wZV9vdXQgfHwgc2NvcGVfaW4pO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQudW5ob3ZlclxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVtb3ZlcyBldmVudCBoYW5kbGVycyBmb3IgaG92ZXIgZm9yIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBmX2luIChmdW5jdGlvbikgaGFuZGxlciBmb3IgaG92ZXIgaW5cbiAgICAgLSBmX291dCAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIGhvdmVyIG91dFxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIGVscHJvdG8udW5ob3ZlciA9IGZ1bmN0aW9uIChmX2luLCBmX291dCkge1xuICAgICAgICByZXR1cm4gdGhpcy51bm1vdXNlb3ZlcihmX2luKS51bm1vdXNlb3V0KGZfb3V0KTtcbiAgICB9O1xuICAgIHZhciBkcmFnZ2FibGUgPSBbXTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5kcmFnXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBZGRzIGV2ZW50IGhhbmRsZXJzIGZvciBkcmFnIG9mIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBvbm1vdmUgKGZ1bmN0aW9uKSBoYW5kbGVyIGZvciBtb3ZpbmdcbiAgICAgLSBvbnN0YXJ0IChmdW5jdGlvbikgaGFuZGxlciBmb3IgZHJhZyBzdGFydFxuICAgICAtIG9uZW5kIChmdW5jdGlvbikgaGFuZGxlciBmb3IgZHJhZyBlbmRcbiAgICAgLSBtY29udGV4dCAob2JqZWN0KSAjb3B0aW9uYWwgY29udGV4dCBmb3IgbW92aW5nIGhhbmRsZXJcbiAgICAgLSBzY29udGV4dCAob2JqZWN0KSAjb3B0aW9uYWwgY29udGV4dCBmb3IgZHJhZyBzdGFydCBoYW5kbGVyXG4gICAgIC0gZWNvbnRleHQgKG9iamVjdCkgI29wdGlvbmFsIGNvbnRleHQgZm9yIGRyYWcgZW5kIGhhbmRsZXJcbiAgICAgKiBBZGRpdGlvbmFsbHkgZm9sbG93aW5nIGBkcmFnYCBldmVudHMgd2lsbCBiZSB0cmlnZ2VyZWQ6IGBkcmFnLnN0YXJ0LjxpZD5gIG9uIHN0YXJ0LFxuICAgICAqIGBkcmFnLmVuZC48aWQ+YCBvbiBlbmQgYW5kIGBkcmFnLm1vdmUuPGlkPmAgb24gZXZlcnkgbW92ZS4gV2hlbiBlbGVtZW50IHdpbGwgYmUgZHJhZ2dlZCBvdmVyIGFub3RoZXIgZWxlbWVudFxuICAgICAqIGBkcmFnLm92ZXIuPGlkPmAgd2lsbCBiZSBmaXJlZCBhcyB3ZWxsLlxuICAgICAqXG4gICAgICogU3RhcnQgZXZlbnQgYW5kIHN0YXJ0IGhhbmRsZXIgd2lsbCBiZSBjYWxsZWQgaW4gc3BlY2lmaWVkIGNvbnRleHQgb3IgaW4gY29udGV4dCBvZiB0aGUgZWxlbWVudCB3aXRoIGZvbGxvd2luZyBwYXJhbWV0ZXJzOlxuICAgICBvIHggKG51bWJlcikgeCBwb3NpdGlvbiBvZiB0aGUgbW91c2VcbiAgICAgbyB5IChudW1iZXIpIHkgcG9zaXRpb24gb2YgdGhlIG1vdXNlXG4gICAgIG8gZXZlbnQgKG9iamVjdCkgRE9NIGV2ZW50IG9iamVjdFxuICAgICAqIE1vdmUgZXZlbnQgYW5kIG1vdmUgaGFuZGxlciB3aWxsIGJlIGNhbGxlZCBpbiBzcGVjaWZpZWQgY29udGV4dCBvciBpbiBjb250ZXh0IG9mIHRoZSBlbGVtZW50IHdpdGggZm9sbG93aW5nIHBhcmFtZXRlcnM6XG4gICAgIG8gZHggKG51bWJlcikgc2hpZnQgYnkgeCBmcm9tIHRoZSBzdGFydCBwb2ludFxuICAgICBvIGR5IChudW1iZXIpIHNoaWZ0IGJ5IHkgZnJvbSB0aGUgc3RhcnQgcG9pbnRcbiAgICAgbyB4IChudW1iZXIpIHggcG9zaXRpb24gb2YgdGhlIG1vdXNlXG4gICAgIG8geSAobnVtYmVyKSB5IHBvc2l0aW9uIG9mIHRoZSBtb3VzZVxuICAgICBvIGV2ZW50IChvYmplY3QpIERPTSBldmVudCBvYmplY3RcbiAgICAgKiBFbmQgZXZlbnQgYW5kIGVuZCBoYW5kbGVyIHdpbGwgYmUgY2FsbGVkIGluIHNwZWNpZmllZCBjb250ZXh0IG9yIGluIGNvbnRleHQgb2YgdGhlIGVsZW1lbnQgd2l0aCBmb2xsb3dpbmcgcGFyYW1ldGVyczpcbiAgICAgbyBldmVudCAob2JqZWN0KSBET00gZXZlbnQgb2JqZWN0XG4gICAgID0gKG9iamVjdCkgQEVsZW1lbnRcbiAgICBcXCovXG4gICAgZWxwcm90by5kcmFnID0gZnVuY3Rpb24gKG9ubW92ZSwgb25zdGFydCwgb25lbmQsIG1vdmVfc2NvcGUsIHN0YXJ0X3Njb3BlLCBlbmRfc2NvcGUpIHtcbiAgICAgICAgZnVuY3Rpb24gc3RhcnQoZSkge1xuICAgICAgICAgICAgKGUub3JpZ2luYWxFdmVudCB8fCBlKS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdmFyIHggPSBlLmNsaWVudFgsXG4gICAgICAgICAgICAgICAgeSA9IGUuY2xpZW50WSxcbiAgICAgICAgICAgICAgICBzY3JvbGxZID0gZy5kb2MuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBnLmRvYy5ib2R5LnNjcm9sbFRvcCxcbiAgICAgICAgICAgICAgICBzY3JvbGxYID0gZy5kb2MuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQgfHwgZy5kb2MuYm9keS5zY3JvbGxMZWZ0O1xuICAgICAgICAgICAgdGhpcy5fZHJhZy5pZCA9IGUuaWRlbnRpZmllcjtcbiAgICAgICAgICAgIGlmIChzdXBwb3J0c1RvdWNoICYmIGUudG91Y2hlcykge1xuICAgICAgICAgICAgICAgIHZhciBpID0gZS50b3VjaGVzLmxlbmd0aCwgdG91Y2g7XG4gICAgICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgICAgICB0b3VjaCA9IGUudG91Y2hlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZHJhZy5pZCA9IHRvdWNoLmlkZW50aWZpZXI7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0b3VjaC5pZGVudGlmaWVyID09IHRoaXMuX2RyYWcuaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHggPSB0b3VjaC5jbGllbnRYO1xuICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHRvdWNoLmNsaWVudFk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2RyYWcueCA9IHggKyBzY3JvbGxYO1xuICAgICAgICAgICAgdGhpcy5fZHJhZy55ID0geSArIHNjcm9sbFk7XG4gICAgICAgICAgICAhZHJhZy5sZW5ndGggJiYgUi5tb3VzZW1vdmUoZHJhZ01vdmUpLm1vdXNldXAoZHJhZ1VwKTtcbiAgICAgICAgICAgIGRyYWcucHVzaCh7ZWw6IHRoaXMsIG1vdmVfc2NvcGU6IG1vdmVfc2NvcGUsIHN0YXJ0X3Njb3BlOiBzdGFydF9zY29wZSwgZW5kX3Njb3BlOiBlbmRfc2NvcGV9KTtcbiAgICAgICAgICAgIG9uc3RhcnQgJiYgZXZlLm9uKFwicmFwaGFlbC5kcmFnLnN0YXJ0LlwiICsgdGhpcy5pZCwgb25zdGFydCk7XG4gICAgICAgICAgICBvbm1vdmUgJiYgZXZlLm9uKFwicmFwaGFlbC5kcmFnLm1vdmUuXCIgKyB0aGlzLmlkLCBvbm1vdmUpO1xuICAgICAgICAgICAgb25lbmQgJiYgZXZlLm9uKFwicmFwaGFlbC5kcmFnLmVuZC5cIiArIHRoaXMuaWQsIG9uZW5kKTtcbiAgICAgICAgICAgIGV2ZShcInJhcGhhZWwuZHJhZy5zdGFydC5cIiArIHRoaXMuaWQsIHN0YXJ0X3Njb3BlIHx8IG1vdmVfc2NvcGUgfHwgdGhpcywgZS5jbGllbnRYICsgc2Nyb2xsWCwgZS5jbGllbnRZICsgc2Nyb2xsWSwgZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZHJhZyA9IHt9O1xuICAgICAgICBkcmFnZ2FibGUucHVzaCh7ZWw6IHRoaXMsIHN0YXJ0OiBzdGFydH0pO1xuICAgICAgICB0aGlzLm1vdXNlZG93bihzdGFydCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQub25EcmFnT3ZlclxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogU2hvcnRjdXQgZm9yIGFzc2lnbmluZyBldmVudCBoYW5kbGVyIGZvciBgZHJhZy5vdmVyLjxpZD5gIGV2ZW50LCB3aGVyZSBpZCBpcyBpZCBvZiB0aGUgZWxlbWVudCAoc2VlIEBFbGVtZW50LmlkKS5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gZiAoZnVuY3Rpb24pIGhhbmRsZXIgZm9yIGV2ZW50LCBmaXJzdCBhcmd1bWVudCB3b3VsZCBiZSB0aGUgZWxlbWVudCB5b3UgYXJlIGRyYWdnaW5nIG92ZXJcbiAgICBcXCovXG4gICAgZWxwcm90by5vbkRyYWdPdmVyID0gZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgZiA/IGV2ZS5vbihcInJhcGhhZWwuZHJhZy5vdmVyLlwiICsgdGhpcy5pZCwgZikgOiBldmUudW5iaW5kKFwicmFwaGFlbC5kcmFnLm92ZXIuXCIgKyB0aGlzLmlkKTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnVuZHJhZ1xuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVtb3ZlcyBhbGwgZHJhZyBldmVudCBoYW5kbGVycyBmcm9tIGdpdmVuIGVsZW1lbnQuXG4gICAgXFwqL1xuICAgIGVscHJvdG8udW5kcmFnID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgaSA9IGRyYWdnYWJsZS5sZW5ndGg7XG4gICAgICAgIHdoaWxlIChpLS0pIGlmIChkcmFnZ2FibGVbaV0uZWwgPT0gdGhpcykge1xuICAgICAgICAgICAgdGhpcy51bm1vdXNlZG93bihkcmFnZ2FibGVbaV0uc3RhcnQpO1xuICAgICAgICAgICAgZHJhZ2dhYmxlLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgIGV2ZS51bmJpbmQoXCJyYXBoYWVsLmRyYWcuKi5cIiArIHRoaXMuaWQpO1xuICAgICAgICB9XG4gICAgICAgICFkcmFnZ2FibGUubGVuZ3RoICYmIFIudW5tb3VzZW1vdmUoZHJhZ01vdmUpLnVubW91c2V1cChkcmFnVXApO1xuICAgICAgICBkcmFnID0gW107XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUGFwZXIuY2lyY2xlXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBEcmF3cyBhIGNpcmNsZS5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0geCAobnVtYmVyKSB4IGNvb3JkaW5hdGUgb2YgdGhlIGNlbnRyZVxuICAgICAtIHkgKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSBjZW50cmVcbiAgICAgLSByIChudW1iZXIpIHJhZGl1c1xuICAgICA9IChvYmplY3QpIFJhcGhhw6tsIGVsZW1lbnQgb2JqZWN0IHdpdGggdHlwZSDigJxjaXJjbGXigJ1cbiAgICAgKipcbiAgICAgPiBVc2FnZVxuICAgICB8IHZhciBjID0gcGFwZXIuY2lyY2xlKDUwLCA1MCwgNDApO1xuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLmNpcmNsZSA9IGZ1bmN0aW9uICh4LCB5LCByKSB7XG4gICAgICAgIHZhciBvdXQgPSBSLl9lbmdpbmUuY2lyY2xlKHRoaXMsIHggfHwgMCwgeSB8fCAwLCByIHx8IDApO1xuICAgICAgICB0aGlzLl9fc2V0X18gJiYgdGhpcy5fX3NldF9fLnB1c2gob3V0KTtcbiAgICAgICAgcmV0dXJuIG91dDtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5yZWN0XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKlxuICAgICAqIERyYXdzIGEgcmVjdGFuZ2xlLlxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSB4IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgdG9wIGxlZnQgY29ybmVyXG4gICAgIC0geSAobnVtYmVyKSB5IGNvb3JkaW5hdGUgb2YgdGhlIHRvcCBsZWZ0IGNvcm5lclxuICAgICAtIHdpZHRoIChudW1iZXIpIHdpZHRoXG4gICAgIC0gaGVpZ2h0IChudW1iZXIpIGhlaWdodFxuICAgICAtIHIgKG51bWJlcikgI29wdGlvbmFsIHJhZGl1cyBmb3Igcm91bmRlZCBjb3JuZXJzLCBkZWZhdWx0IGlzIDBcbiAgICAgPSAob2JqZWN0KSBSYXBoYcOrbCBlbGVtZW50IG9iamVjdCB3aXRoIHR5cGUg4oCccmVjdOKAnVxuICAgICAqKlxuICAgICA+IFVzYWdlXG4gICAgIHwgLy8gcmVndWxhciByZWN0YW5nbGVcbiAgICAgfCB2YXIgYyA9IHBhcGVyLnJlY3QoMTAsIDEwLCA1MCwgNTApO1xuICAgICB8IC8vIHJlY3RhbmdsZSB3aXRoIHJvdW5kZWQgY29ybmVyc1xuICAgICB8IHZhciBjID0gcGFwZXIucmVjdCg0MCwgNDAsIDUwLCA1MCwgMTApO1xuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLnJlY3QgPSBmdW5jdGlvbiAoeCwgeSwgdywgaCwgcikge1xuICAgICAgICB2YXIgb3V0ID0gUi5fZW5naW5lLnJlY3QodGhpcywgeCB8fCAwLCB5IHx8IDAsIHcgfHwgMCwgaCB8fCAwLCByIHx8IDApO1xuICAgICAgICB0aGlzLl9fc2V0X18gJiYgdGhpcy5fX3NldF9fLnB1c2gob3V0KTtcbiAgICAgICAgcmV0dXJuIG91dDtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5lbGxpcHNlXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBEcmF3cyBhbiBlbGxpcHNlLlxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSB4IChudW1iZXIpIHggY29vcmRpbmF0ZSBvZiB0aGUgY2VudHJlXG4gICAgIC0geSAobnVtYmVyKSB5IGNvb3JkaW5hdGUgb2YgdGhlIGNlbnRyZVxuICAgICAtIHJ4IChudW1iZXIpIGhvcml6b250YWwgcmFkaXVzXG4gICAgIC0gcnkgKG51bWJlcikgdmVydGljYWwgcmFkaXVzXG4gICAgID0gKG9iamVjdCkgUmFwaGHDq2wgZWxlbWVudCBvYmplY3Qgd2l0aCB0eXBlIOKAnGVsbGlwc2XigJ1cbiAgICAgKipcbiAgICAgPiBVc2FnZVxuICAgICB8IHZhciBjID0gcGFwZXIuZWxsaXBzZSg1MCwgNTAsIDQwLCAyMCk7XG4gICAgXFwqL1xuICAgIHBhcGVycHJvdG8uZWxsaXBzZSA9IGZ1bmN0aW9uICh4LCB5LCByeCwgcnkpIHtcbiAgICAgICAgdmFyIG91dCA9IFIuX2VuZ2luZS5lbGxpcHNlKHRoaXMsIHggfHwgMCwgeSB8fCAwLCByeCB8fCAwLCByeSB8fCAwKTtcbiAgICAgICAgdGhpcy5fX3NldF9fICYmIHRoaXMuX19zZXRfXy5wdXNoKG91dCk7XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUGFwZXIucGF0aFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQ3JlYXRlcyBhIHBhdGggZWxlbWVudCBieSBnaXZlbiBwYXRoIGRhdGEgc3RyaW5nLlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBwYXRoU3RyaW5nIChzdHJpbmcpICNvcHRpb25hbCBwYXRoIHN0cmluZyBpbiBTVkcgZm9ybWF0LlxuICAgICAqIFBhdGggc3RyaW5nIGNvbnNpc3RzIG9mIG9uZS1sZXR0ZXIgY29tbWFuZHMsIGZvbGxvd2VkIGJ5IGNvbW1hIHNlcHJhcmF0ZWQgYXJndW1lbnRzIGluIG51bWVyY2FsIGZvcm0uIEV4YW1wbGU6XG4gICAgIHwgXCJNMTAsMjBMMzAsNDBcIlxuICAgICAqIEhlcmUgd2UgY2FuIHNlZSB0d28gY29tbWFuZHM6IOKAnE3igJ0sIHdpdGggYXJndW1lbnRzIGAoMTAsIDIwKWAgYW5kIOKAnEzigJ0gd2l0aCBhcmd1bWVudHMgYCgzMCwgNDApYC4gVXBwZXIgY2FzZSBsZXR0ZXIgbWVhbiBjb21tYW5kIGlzIGFic29sdXRlLCBsb3dlciBjYXNl4oCUcmVsYXRpdmUuXG4gICAgICpcbiAgICAgIyA8cD5IZXJlIGlzIHNob3J0IGxpc3Qgb2YgY29tbWFuZHMgYXZhaWxhYmxlLCBmb3IgbW9yZSBkZXRhaWxzIHNlZSA8YSBocmVmPVwiaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHL3BhdGhzLmh0bWwjUGF0aERhdGFcIiB0aXRsZT1cIkRldGFpbHMgb2YgYSBwYXRoJ3MgZGF0YSBhdHRyaWJ1dGUncyBmb3JtYXQgYXJlIGRlc2NyaWJlZCBpbiB0aGUgU1ZHIHNwZWNpZmljYXRpb24uXCI+U1ZHIHBhdGggc3RyaW5nIGZvcm1hdDwvYT4uPC9wPlxuICAgICAjIDx0YWJsZT48dGhlYWQ+PHRyPjx0aD5Db21tYW5kPC90aD48dGg+TmFtZTwvdGg+PHRoPlBhcmFtZXRlcnM8L3RoPjwvdHI+PC90aGVhZD48dGJvZHk+XG4gICAgICMgPHRyPjx0ZD5NPC90ZD48dGQ+bW92ZXRvPC90ZD48dGQ+KHggeSkrPC90ZD48L3RyPlxuICAgICAjIDx0cj48dGQ+WjwvdGQ+PHRkPmNsb3NlcGF0aDwvdGQ+PHRkPihub25lKTwvdGQ+PC90cj5cbiAgICAgIyA8dHI+PHRkPkw8L3RkPjx0ZD5saW5ldG88L3RkPjx0ZD4oeCB5KSs8L3RkPjwvdHI+XG4gICAgICMgPHRyPjx0ZD5IPC90ZD48dGQ+aG9yaXpvbnRhbCBsaW5ldG88L3RkPjx0ZD54KzwvdGQ+PC90cj5cbiAgICAgIyA8dHI+PHRkPlY8L3RkPjx0ZD52ZXJ0aWNhbCBsaW5ldG88L3RkPjx0ZD55KzwvdGQ+PC90cj5cbiAgICAgIyA8dHI+PHRkPkM8L3RkPjx0ZD5jdXJ2ZXRvPC90ZD48dGQ+KHgxIHkxIHgyIHkyIHggeSkrPC90ZD48L3RyPlxuICAgICAjIDx0cj48dGQ+UzwvdGQ+PHRkPnNtb290aCBjdXJ2ZXRvPC90ZD48dGQ+KHgyIHkyIHggeSkrPC90ZD48L3RyPlxuICAgICAjIDx0cj48dGQ+UTwvdGQ+PHRkPnF1YWRyYXRpYyBCw6l6aWVyIGN1cnZldG88L3RkPjx0ZD4oeDEgeTEgeCB5KSs8L3RkPjwvdHI+XG4gICAgICMgPHRyPjx0ZD5UPC90ZD48dGQ+c21vb3RoIHF1YWRyYXRpYyBCw6l6aWVyIGN1cnZldG88L3RkPjx0ZD4oeCB5KSs8L3RkPjwvdHI+XG4gICAgICMgPHRyPjx0ZD5BPC90ZD48dGQ+ZWxsaXB0aWNhbCBhcmM8L3RkPjx0ZD4ocnggcnkgeC1heGlzLXJvdGF0aW9uIGxhcmdlLWFyYy1mbGFnIHN3ZWVwLWZsYWcgeCB5KSs8L3RkPjwvdHI+XG4gICAgICMgPHRyPjx0ZD5SPC90ZD48dGQ+PGEgaHJlZj1cImh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ2F0bXVsbOKAk1JvbV9zcGxpbmUjQ2F0bXVsbC5FMi44MC45M1JvbV9zcGxpbmVcIj5DYXRtdWxsLVJvbSBjdXJ2ZXRvPC9hPio8L3RkPjx0ZD54MSB5MSAoeCB5KSs8L3RkPjwvdHI+PC90Ym9keT48L3RhYmxlPlxuICAgICAqICog4oCcQ2F0bXVsbC1Sb20gY3VydmV0b+KAnSBpcyBhIG5vdCBzdGFuZGFyZCBTVkcgY29tbWFuZCBhbmQgYWRkZWQgaW4gMi4wIHRvIG1ha2UgbGlmZSBlYXNpZXIuXG4gICAgICogTm90ZTogdGhlcmUgaXMgYSBzcGVjaWFsIGNhc2Ugd2hlbiBwYXRoIGNvbnNpc3Qgb2YganVzdCB0aHJlZSBjb21tYW5kczog4oCcTTEwLDEwUuKApnrigJ0uIEluIHRoaXMgY2FzZSBwYXRoIHdpbGwgc21vb3RobHkgY29ubmVjdHMgdG8gaXRzIGJlZ2lubmluZy5cbiAgICAgPiBVc2FnZVxuICAgICB8IHZhciBjID0gcGFwZXIucGF0aChcIk0xMCAxMEw5MCA5MFwiKTtcbiAgICAgfCAvLyBkcmF3IGEgZGlhZ29uYWwgbGluZTpcbiAgICAgfCAvLyBtb3ZlIHRvIDEwLDEwLCBsaW5lIHRvIDkwLDkwXG4gICAgICogRm9yIGV4YW1wbGUgb2YgcGF0aCBzdHJpbmdzLCBjaGVjayBvdXQgdGhlc2UgaWNvbnM6IGh0dHA6Ly9yYXBoYWVsanMuY29tL2ljb25zL1xuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLnBhdGggPSBmdW5jdGlvbiAocGF0aFN0cmluZykge1xuICAgICAgICBwYXRoU3RyaW5nICYmICFSLmlzKHBhdGhTdHJpbmcsIHN0cmluZykgJiYgIVIuaXMocGF0aFN0cmluZ1swXSwgYXJyYXkpICYmIChwYXRoU3RyaW5nICs9IEUpO1xuICAgICAgICB2YXIgb3V0ID0gUi5fZW5naW5lLnBhdGgoUi5mb3JtYXRbYXBwbHldKFIsIGFyZ3VtZW50cyksIHRoaXMpO1xuICAgICAgICB0aGlzLl9fc2V0X18gJiYgdGhpcy5fX3NldF9fLnB1c2gob3V0KTtcbiAgICAgICAgcmV0dXJuIG91dDtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5pbWFnZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogRW1iZWRzIGFuIGltYWdlIGludG8gdGhlIHN1cmZhY2UuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIHNyYyAoc3RyaW5nKSBVUkkgb2YgdGhlIHNvdXJjZSBpbWFnZVxuICAgICAtIHggKG51bWJlcikgeCBjb29yZGluYXRlIHBvc2l0aW9uXG4gICAgIC0geSAobnVtYmVyKSB5IGNvb3JkaW5hdGUgcG9zaXRpb25cbiAgICAgLSB3aWR0aCAobnVtYmVyKSB3aWR0aCBvZiB0aGUgaW1hZ2VcbiAgICAgLSBoZWlnaHQgKG51bWJlcikgaGVpZ2h0IG9mIHRoZSBpbWFnZVxuICAgICA9IChvYmplY3QpIFJhcGhhw6tsIGVsZW1lbnQgb2JqZWN0IHdpdGggdHlwZSDigJxpbWFnZeKAnVxuICAgICAqKlxuICAgICA+IFVzYWdlXG4gICAgIHwgdmFyIGMgPSBwYXBlci5pbWFnZShcImFwcGxlLnBuZ1wiLCAxMCwgMTAsIDgwLCA4MCk7XG4gICAgXFwqL1xuICAgIHBhcGVycHJvdG8uaW1hZ2UgPSBmdW5jdGlvbiAoc3JjLCB4LCB5LCB3LCBoKSB7XG4gICAgICAgIHZhciBvdXQgPSBSLl9lbmdpbmUuaW1hZ2UodGhpcywgc3JjIHx8IFwiYWJvdXQ6YmxhbmtcIiwgeCB8fCAwLCB5IHx8IDAsIHcgfHwgMCwgaCB8fCAwKTtcbiAgICAgICAgdGhpcy5fX3NldF9fICYmIHRoaXMuX19zZXRfXy5wdXNoKG91dCk7XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUGFwZXIudGV4dFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogRHJhd3MgYSB0ZXh0IHN0cmluZy4gSWYgeW91IG5lZWQgbGluZSBicmVha3MsIHB1dCDigJxcXG7igJ0gaW4gdGhlIHN0cmluZy5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0geCAobnVtYmVyKSB4IGNvb3JkaW5hdGUgcG9zaXRpb25cbiAgICAgLSB5IChudW1iZXIpIHkgY29vcmRpbmF0ZSBwb3NpdGlvblxuICAgICAtIHRleHQgKHN0cmluZykgVGhlIHRleHQgc3RyaW5nIHRvIGRyYXdcbiAgICAgPSAob2JqZWN0KSBSYXBoYcOrbCBlbGVtZW50IG9iamVjdCB3aXRoIHR5cGUg4oCcdGV4dOKAnVxuICAgICAqKlxuICAgICA+IFVzYWdlXG4gICAgIHwgdmFyIHQgPSBwYXBlci50ZXh0KDUwLCA1MCwgXCJSYXBoYcOrbFxcbmtpY2tzXFxuYnV0dCFcIik7XG4gICAgXFwqL1xuICAgIHBhcGVycHJvdG8udGV4dCA9IGZ1bmN0aW9uICh4LCB5LCB0ZXh0KSB7XG4gICAgICAgIHZhciBvdXQgPSBSLl9lbmdpbmUudGV4dCh0aGlzLCB4IHx8IDAsIHkgfHwgMCwgU3RyKHRleHQpKTtcbiAgICAgICAgdGhpcy5fX3NldF9fICYmIHRoaXMuX19zZXRfXy5wdXNoKG91dCk7XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUGFwZXIuc2V0XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBDcmVhdGVzIGFycmF5LWxpa2Ugb2JqZWN0IHRvIGtlZXAgYW5kIG9wZXJhdGUgc2V2ZXJhbCBlbGVtZW50cyBhdCBvbmNlLlxuICAgICAqIFdhcm5pbmc6IGl0IGRvZXNu4oCZdCBjcmVhdGUgYW55IGVsZW1lbnRzIGZvciBpdHNlbGYgaW4gdGhlIHBhZ2UsIGl0IGp1c3QgZ3JvdXBzIGV4aXN0aW5nIGVsZW1lbnRzLlxuICAgICAqIFNldHMgYWN0IGFzIHBzZXVkbyBlbGVtZW50cyDigJQgYWxsIG1ldGhvZHMgYXZhaWxhYmxlIHRvIGFuIGVsZW1lbnQgY2FuIGJlIHVzZWQgb24gYSBzZXQuXG4gICAgID0gKG9iamVjdCkgYXJyYXktbGlrZSBvYmplY3QgdGhhdCByZXByZXNlbnRzIHNldCBvZiBlbGVtZW50c1xuICAgICAqKlxuICAgICA+IFVzYWdlXG4gICAgIHwgdmFyIHN0ID0gcGFwZXIuc2V0KCk7XG4gICAgIHwgc3QucHVzaChcbiAgICAgfCAgICAgcGFwZXIuY2lyY2xlKDEwLCAxMCwgNSksXG4gICAgIHwgICAgIHBhcGVyLmNpcmNsZSgzMCwgMTAsIDUpXG4gICAgIHwgKTtcbiAgICAgfCBzdC5hdHRyKHtmaWxsOiBcInJlZFwifSk7IC8vIGNoYW5nZXMgdGhlIGZpbGwgb2YgYm90aCBjaXJjbGVzXG4gICAgXFwqL1xuICAgIHBhcGVycHJvdG8uc2V0ID0gZnVuY3Rpb24gKGl0ZW1zQXJyYXkpIHtcbiAgICAgICAgIVIuaXMoaXRlbXNBcnJheSwgXCJhcnJheVwiKSAmJiAoaXRlbXNBcnJheSA9IEFycmF5LnByb3RvdHlwZS5zcGxpY2UuY2FsbChhcmd1bWVudHMsIDAsIGFyZ3VtZW50cy5sZW5ndGgpKTtcbiAgICAgICAgdmFyIG91dCA9IG5ldyBTZXQoaXRlbXNBcnJheSk7XG4gICAgICAgIHRoaXMuX19zZXRfXyAmJiB0aGlzLl9fc2V0X18ucHVzaChvdXQpO1xuICAgICAgICBvdXRbXCJwYXBlclwiXSA9IHRoaXM7XG4gICAgICAgIG91dFtcInR5cGVcIl0gPSBcInNldFwiO1xuICAgICAgICByZXR1cm4gb3V0O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFBhcGVyLnNldFN0YXJ0XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBDcmVhdGVzIEBQYXBlci5zZXQuIEFsbCBlbGVtZW50cyB0aGF0IHdpbGwgYmUgY3JlYXRlZCBhZnRlciBjYWxsaW5nIHRoaXMgbWV0aG9kIGFuZCBiZWZvcmUgY2FsbGluZ1xuICAgICAqIEBQYXBlci5zZXRGaW5pc2ggd2lsbCBiZSBhZGRlZCB0byB0aGUgc2V0LlxuICAgICAqKlxuICAgICA+IFVzYWdlXG4gICAgIHwgcGFwZXIuc2V0U3RhcnQoKTtcbiAgICAgfCBwYXBlci5jaXJjbGUoMTAsIDEwLCA1KSxcbiAgICAgfCBwYXBlci5jaXJjbGUoMzAsIDEwLCA1KVxuICAgICB8IHZhciBzdCA9IHBhcGVyLnNldEZpbmlzaCgpO1xuICAgICB8IHN0LmF0dHIoe2ZpbGw6IFwicmVkXCJ9KTsgLy8gY2hhbmdlcyB0aGUgZmlsbCBvZiBib3RoIGNpcmNsZXNcbiAgICBcXCovXG4gICAgcGFwZXJwcm90by5zZXRTdGFydCA9IGZ1bmN0aW9uIChzZXQpIHtcbiAgICAgICAgdGhpcy5fX3NldF9fID0gc2V0IHx8IHRoaXMuc2V0KCk7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogUGFwZXIuc2V0RmluaXNoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBTZWUgQFBhcGVyLnNldFN0YXJ0LiBUaGlzIG1ldGhvZCBmaW5pc2hlcyBjYXRjaGluZyBhbmQgcmV0dXJucyByZXN1bHRpbmcgc2V0LlxuICAgICAqKlxuICAgICA9IChvYmplY3QpIHNldFxuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLnNldEZpbmlzaCA9IGZ1bmN0aW9uIChzZXQpIHtcbiAgICAgICAgdmFyIG91dCA9IHRoaXMuX19zZXRfXztcbiAgICAgICAgZGVsZXRlIHRoaXMuX19zZXRfXztcbiAgICAgICAgcmV0dXJuIG91dDtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5nZXRTaXplXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBPYnRhaW5zIGN1cnJlbnQgcGFwZXIgYWN0dWFsIHNpemUuXG4gICAgICoqXG4gICAgID0gKG9iamVjdClcbiAgICAgXFwqL1xuICAgIHBhcGVycHJvdG8uZ2V0U2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuY2FudmFzLnBhcmVudE5vZGU7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB3aWR0aDogY29udGFpbmVyLm9mZnNldFdpZHRoLFxuICAgICAgICAgICAgaGVpZ2h0OiBjb250YWluZXIub2Zmc2V0SGVpZ2h0XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAvKlxcXG4gICAgICogUGFwZXIuc2V0U2l6ZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogSWYgeW91IG5lZWQgdG8gY2hhbmdlIGRpbWVuc2lvbnMgb2YgdGhlIGNhbnZhcyBjYWxsIHRoaXMgbWV0aG9kXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIHdpZHRoIChudW1iZXIpIG5ldyB3aWR0aCBvZiB0aGUgY2FudmFzXG4gICAgIC0gaGVpZ2h0IChudW1iZXIpIG5ldyBoZWlnaHQgb2YgdGhlIGNhbnZhc1xuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLnNldFNpemUgPSBmdW5jdGlvbiAod2lkdGgsIGhlaWdodCkge1xuICAgICAgICByZXR1cm4gUi5fZW5naW5lLnNldFNpemUuY2FsbCh0aGlzLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5zZXRWaWV3Qm94XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBTZXRzIHRoZSB2aWV3IGJveCBvZiB0aGUgcGFwZXIuIFByYWN0aWNhbGx5IGl0IGdpdmVzIHlvdSBhYmlsaXR5IHRvIHpvb20gYW5kIHBhbiB3aG9sZSBwYXBlciBzdXJmYWNlIGJ5XG4gICAgICogc3BlY2lmeWluZyBuZXcgYm91bmRhcmllcy5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0geCAobnVtYmVyKSBuZXcgeCBwb3NpdGlvbiwgZGVmYXVsdCBpcyBgMGBcbiAgICAgLSB5IChudW1iZXIpIG5ldyB5IHBvc2l0aW9uLCBkZWZhdWx0IGlzIGAwYFxuICAgICAtIHcgKG51bWJlcikgbmV3IHdpZHRoIG9mIHRoZSBjYW52YXNcbiAgICAgLSBoIChudW1iZXIpIG5ldyBoZWlnaHQgb2YgdGhlIGNhbnZhc1xuICAgICAtIGZpdCAoYm9vbGVhbikgYHRydWVgIGlmIHlvdSB3YW50IGdyYXBoaWNzIHRvIGZpdCBpbnRvIG5ldyBib3VuZGFyeSBib3hcbiAgICBcXCovXG4gICAgcGFwZXJwcm90by5zZXRWaWV3Qm94ID0gZnVuY3Rpb24gKHgsIHksIHcsIGgsIGZpdCkge1xuICAgICAgICByZXR1cm4gUi5fZW5naW5lLnNldFZpZXdCb3guY2FsbCh0aGlzLCB4LCB5LCB3LCBoLCBmaXQpO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFBhcGVyLnRvcFxuICAgICBbIHByb3BlcnR5IF1cbiAgICAgKipcbiAgICAgKiBQb2ludHMgdG8gdGhlIHRvcG1vc3QgZWxlbWVudCBvbiB0aGUgcGFwZXJcbiAgICBcXCovXG4gICAgLypcXFxuICAgICAqIFBhcGVyLmJvdHRvbVxuICAgICBbIHByb3BlcnR5IF1cbiAgICAgKipcbiAgICAgKiBQb2ludHMgdG8gdGhlIGJvdHRvbSBlbGVtZW50IG9uIHRoZSBwYXBlclxuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLnRvcCA9IHBhcGVycHJvdG8uYm90dG9tID0gbnVsbDtcbiAgICAvKlxcXG4gICAgICogUGFwZXIucmFwaGFlbFxuICAgICBbIHByb3BlcnR5IF1cbiAgICAgKipcbiAgICAgKiBQb2ludHMgdG8gdGhlIEBSYXBoYWVsIG9iamVjdC9mdW5jdGlvblxuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLnJhcGhhZWwgPSBSO1xuICAgIHZhciBnZXRPZmZzZXQgPSBmdW5jdGlvbiAoZWxlbSkge1xuICAgICAgICB2YXIgYm94ID0gZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxcbiAgICAgICAgICAgIGRvYyA9IGVsZW0ub3duZXJEb2N1bWVudCxcbiAgICAgICAgICAgIGJvZHkgPSBkb2MuYm9keSxcbiAgICAgICAgICAgIGRvY0VsZW0gPSBkb2MuZG9jdW1lbnRFbGVtZW50LFxuICAgICAgICAgICAgY2xpZW50VG9wID0gZG9jRWxlbS5jbGllbnRUb3AgfHwgYm9keS5jbGllbnRUb3AgfHwgMCwgY2xpZW50TGVmdCA9IGRvY0VsZW0uY2xpZW50TGVmdCB8fCBib2R5LmNsaWVudExlZnQgfHwgMCxcbiAgICAgICAgICAgIHRvcCAgPSBib3gudG9wICArIChnLndpbi5wYWdlWU9mZnNldCB8fCBkb2NFbGVtLnNjcm9sbFRvcCB8fCBib2R5LnNjcm9sbFRvcCApIC0gY2xpZW50VG9wLFxuICAgICAgICAgICAgbGVmdCA9IGJveC5sZWZ0ICsgKGcud2luLnBhZ2VYT2Zmc2V0IHx8IGRvY0VsZW0uc2Nyb2xsTGVmdCB8fCBib2R5LnNjcm9sbExlZnQpIC0gY2xpZW50TGVmdDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHk6IHRvcCxcbiAgICAgICAgICAgIHg6IGxlZnRcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5nZXRFbGVtZW50QnlQb2ludFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJucyB5b3UgdG9wbW9zdCBlbGVtZW50IHVuZGVyIGdpdmVuIHBvaW50LlxuICAgICAqKlxuICAgICA9IChvYmplY3QpIFJhcGhhw6tsIGVsZW1lbnQgb2JqZWN0XG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIHggKG51bWJlcikgeCBjb29yZGluYXRlIGZyb20gdGhlIHRvcCBsZWZ0IGNvcm5lciBvZiB0aGUgd2luZG93XG4gICAgIC0geSAobnVtYmVyKSB5IGNvb3JkaW5hdGUgZnJvbSB0aGUgdG9wIGxlZnQgY29ybmVyIG9mIHRoZSB3aW5kb3dcbiAgICAgPiBVc2FnZVxuICAgICB8IHBhcGVyLmdldEVsZW1lbnRCeVBvaW50KG1vdXNlWCwgbW91c2VZKS5hdHRyKHtzdHJva2U6IFwiI2YwMFwifSk7XG4gICAgXFwqL1xuICAgIHBhcGVycHJvdG8uZ2V0RWxlbWVudEJ5UG9pbnQgPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICB2YXIgcGFwZXIgPSB0aGlzLFxuICAgICAgICAgICAgc3ZnID0gcGFwZXIuY2FudmFzLFxuICAgICAgICAgICAgdGFyZ2V0ID0gZy5kb2MuZWxlbWVudEZyb21Qb2ludCh4LCB5KTtcbiAgICAgICAgaWYgKGcud2luLm9wZXJhICYmIHRhcmdldC50YWdOYW1lID09IFwic3ZnXCIpIHtcbiAgICAgICAgICAgIHZhciBzbyA9IGdldE9mZnNldChzdmcpLFxuICAgICAgICAgICAgICAgIHNyID0gc3ZnLmNyZWF0ZVNWR1JlY3QoKTtcbiAgICAgICAgICAgIHNyLnggPSB4IC0gc28ueDtcbiAgICAgICAgICAgIHNyLnkgPSB5IC0gc28ueTtcbiAgICAgICAgICAgIHNyLndpZHRoID0gc3IuaGVpZ2h0ID0gMTtcbiAgICAgICAgICAgIHZhciBoaXRzID0gc3ZnLmdldEludGVyc2VjdGlvbkxpc3Qoc3IsIG51bGwpO1xuICAgICAgICAgICAgaWYgKGhpdHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0ID0gaGl0c1toaXRzLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAodGFyZ2V0LnBhcmVudE5vZGUgJiYgdGFyZ2V0ICE9IHN2Zy5wYXJlbnROb2RlICYmICF0YXJnZXQucmFwaGFlbCkge1xuICAgICAgICAgICAgdGFyZ2V0ID0gdGFyZ2V0LnBhcmVudE5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgdGFyZ2V0ID09IHBhcGVyLmNhbnZhcy5wYXJlbnROb2RlICYmICh0YXJnZXQgPSBzdmcpO1xuICAgICAgICB0YXJnZXQgPSB0YXJnZXQgJiYgdGFyZ2V0LnJhcGhhZWwgPyBwYXBlci5nZXRCeUlkKHRhcmdldC5yYXBoYWVsaWQpIDogbnVsbDtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIFBhcGVyLmdldEVsZW1lbnRzQnlCQm94XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZXR1cm5zIHNldCBvZiBlbGVtZW50cyB0aGF0IGhhdmUgYW4gaW50ZXJzZWN0aW5nIGJvdW5kaW5nIGJveFxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSBiYm94IChvYmplY3QpIGJib3ggdG8gY2hlY2sgd2l0aFxuICAgICA9IChvYmplY3QpIEBTZXRcbiAgICAgXFwqL1xuICAgIHBhcGVycHJvdG8uZ2V0RWxlbWVudHNCeUJCb3ggPSBmdW5jdGlvbiAoYmJveCkge1xuICAgICAgICB2YXIgc2V0ID0gdGhpcy5zZXQoKTtcbiAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgaWYgKFIuaXNCQm94SW50ZXJzZWN0KGVsLmdldEJCb3goKSwgYmJveCkpIHtcbiAgICAgICAgICAgICAgICBzZXQucHVzaChlbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2V0O1xuICAgIH07XG5cbiAgICAvKlxcXG4gICAgICogUGFwZXIuZ2V0QnlJZFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJucyB5b3UgZWxlbWVudCBieSBpdHMgaW50ZXJuYWwgSUQuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGlkIChudW1iZXIpIGlkXG4gICAgID0gKG9iamVjdCkgUmFwaGHDq2wgZWxlbWVudCBvYmplY3RcbiAgICBcXCovXG4gICAgcGFwZXJwcm90by5nZXRCeUlkID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICAgIHZhciBib3QgPSB0aGlzLmJvdHRvbTtcbiAgICAgICAgd2hpbGUgKGJvdCkge1xuICAgICAgICAgICAgaWYgKGJvdC5pZCA9PSBpZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBib3Q7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBib3QgPSBib3QubmV4dDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5mb3JFYWNoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBFeGVjdXRlcyBnaXZlbiBmdW5jdGlvbiBmb3IgZWFjaCBlbGVtZW50IG9uIHRoZSBwYXBlclxuICAgICAqXG4gICAgICogSWYgY2FsbGJhY2sgZnVuY3Rpb24gcmV0dXJucyBgZmFsc2VgIGl0IHdpbGwgc3RvcCBsb29wIHJ1bm5pbmcuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGNhbGxiYWNrIChmdW5jdGlvbikgZnVuY3Rpb24gdG8gcnVuXG4gICAgIC0gdGhpc0FyZyAob2JqZWN0KSBjb250ZXh0IG9iamVjdCBmb3IgdGhlIGNhbGxiYWNrXG4gICAgID0gKG9iamVjdCkgUGFwZXIgb2JqZWN0XG4gICAgID4gVXNhZ2VcbiAgICAgfCBwYXBlci5mb3JFYWNoKGZ1bmN0aW9uIChlbCkge1xuICAgICB8ICAgICBlbC5hdHRyKHsgc3Ryb2tlOiBcImJsdWVcIiB9KTtcbiAgICAgfCB9KTtcbiAgICBcXCovXG4gICAgcGFwZXJwcm90by5mb3JFYWNoID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0aGlzQXJnKSB7XG4gICAgICAgIHZhciBib3QgPSB0aGlzLmJvdHRvbTtcbiAgICAgICAgd2hpbGUgKGJvdCkge1xuICAgICAgICAgICAgaWYgKGNhbGxiYWNrLmNhbGwodGhpc0FyZywgYm90KSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJvdCA9IGJvdC5uZXh0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFBhcGVyLmdldEVsZW1lbnRzQnlQb2ludFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJucyBzZXQgb2YgZWxlbWVudHMgdGhhdCBoYXZlIGNvbW1vbiBwb2ludCBpbnNpZGVcbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0geCAobnVtYmVyKSB4IGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50XG4gICAgIC0geSAobnVtYmVyKSB5IGNvb3JkaW5hdGUgb2YgdGhlIHBvaW50XG4gICAgID0gKG9iamVjdCkgQFNldFxuICAgIFxcKi9cbiAgICBwYXBlcnByb3RvLmdldEVsZW1lbnRzQnlQb2ludCA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgIHZhciBzZXQgPSB0aGlzLnNldCgpO1xuICAgICAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICBpZiAoZWwuaXNQb2ludEluc2lkZSh4LCB5KSkge1xuICAgICAgICAgICAgICAgIHNldC5wdXNoKGVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzZXQ7XG4gICAgfTtcbiAgICBmdW5jdGlvbiB4X3koKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnggKyBTICsgdGhpcy55O1xuICAgIH1cbiAgICBmdW5jdGlvbiB4X3lfd19oKCkge1xuICAgICAgICByZXR1cm4gdGhpcy54ICsgUyArIHRoaXMueSArIFMgKyB0aGlzLndpZHRoICsgXCIgXFx4ZDcgXCIgKyB0aGlzLmhlaWdodDtcbiAgICB9XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuaXNQb2ludEluc2lkZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogRGV0ZXJtaW5lIGlmIGdpdmVuIHBvaW50IGlzIGluc2lkZSB0aGlzIGVsZW1lbnTigJlzIHNoYXBlXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIHggKG51bWJlcikgeCBjb29yZGluYXRlIG9mIHRoZSBwb2ludFxuICAgICAtIHkgKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSBwb2ludFxuICAgICA9IChib29sZWFuKSBgdHJ1ZWAgaWYgcG9pbnQgaW5zaWRlIHRoZSBzaGFwZVxuICAgIFxcKi9cbiAgICBlbHByb3RvLmlzUG9pbnRJbnNpZGUgPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICB2YXIgcnAgPSB0aGlzLnJlYWxQYXRoID0gZ2V0UGF0aFt0aGlzLnR5cGVdKHRoaXMpO1xuICAgICAgICBpZiAodGhpcy5hdHRyKCd0cmFuc2Zvcm0nKSAmJiB0aGlzLmF0dHIoJ3RyYW5zZm9ybScpLmxlbmd0aCkge1xuICAgICAgICAgICAgcnAgPSBSLnRyYW5zZm9ybVBhdGgocnAsIHRoaXMuYXR0cigndHJhbnNmb3JtJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSLmlzUG9pbnRJbnNpZGVQYXRoKHJwLCB4LCB5KTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LmdldEJCb3hcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJldHVybiBib3VuZGluZyBib3ggZm9yIGEgZ2l2ZW4gZWxlbWVudFxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSBpc1dpdGhvdXRUcmFuc2Zvcm0gKGJvb2xlYW4pIGZsYWcsIGB0cnVlYCBpZiB5b3Ugd2FudCB0byBoYXZlIGJvdW5kaW5nIGJveCBiZWZvcmUgdHJhbnNmb3JtYXRpb25zLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG4gICAgID0gKG9iamVjdCkgQm91bmRpbmcgYm94IG9iamVjdDpcbiAgICAgbyB7XG4gICAgIG8gICAgIHg6IChudW1iZXIpIHRvcCBsZWZ0IGNvcm5lciB4XG4gICAgIG8gICAgIHk6IChudW1iZXIpIHRvcCBsZWZ0IGNvcm5lciB5XG4gICAgIG8gICAgIHgyOiAobnVtYmVyKSBib3R0b20gcmlnaHQgY29ybmVyIHhcbiAgICAgbyAgICAgeTI6IChudW1iZXIpIGJvdHRvbSByaWdodCBjb3JuZXIgeVxuICAgICBvICAgICB3aWR0aDogKG51bWJlcikgd2lkdGhcbiAgICAgbyAgICAgaGVpZ2h0OiAobnVtYmVyKSBoZWlnaHRcbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIGVscHJvdG8uZ2V0QkJveCA9IGZ1bmN0aW9uIChpc1dpdGhvdXRUcmFuc2Zvcm0pIHtcbiAgICAgICAgaWYgKHRoaXMucmVtb3ZlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICB9XG4gICAgICAgIHZhciBfID0gdGhpcy5fO1xuICAgICAgICBpZiAoaXNXaXRob3V0VHJhbnNmb3JtKSB7XG4gICAgICAgICAgICBpZiAoXy5kaXJ0eSB8fCAhXy5iYm94d3QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlYWxQYXRoID0gZ2V0UGF0aFt0aGlzLnR5cGVdKHRoaXMpO1xuICAgICAgICAgICAgICAgIF8uYmJveHd0ID0gcGF0aERpbWVuc2lvbnModGhpcy5yZWFsUGF0aCk7XG4gICAgICAgICAgICAgICAgXy5iYm94d3QudG9TdHJpbmcgPSB4X3lfd19oO1xuICAgICAgICAgICAgICAgIF8uZGlydHkgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIF8uYmJveHd0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChfLmRpcnR5IHx8IF8uZGlydHlUIHx8ICFfLmJib3gpIHtcbiAgICAgICAgICAgIGlmIChfLmRpcnR5IHx8ICF0aGlzLnJlYWxQYXRoKSB7XG4gICAgICAgICAgICAgICAgXy5iYm94d3QgPSAwO1xuICAgICAgICAgICAgICAgIHRoaXMucmVhbFBhdGggPSBnZXRQYXRoW3RoaXMudHlwZV0odGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfLmJib3ggPSBwYXRoRGltZW5zaW9ucyhtYXBQYXRoKHRoaXMucmVhbFBhdGgsIHRoaXMubWF0cml4KSk7XG4gICAgICAgICAgICBfLmJib3gudG9TdHJpbmcgPSB4X3lfd19oO1xuICAgICAgICAgICAgXy5kaXJ0eSA9IF8uZGlydHlUID0gMDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gXy5iYm94O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuY2xvbmVcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICA9IChvYmplY3QpIGNsb25lIG9mIGEgZ2l2ZW4gZWxlbWVudFxuICAgICAqKlxuICAgIFxcKi9cbiAgICBlbHByb3RvLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5yZW1vdmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgb3V0ID0gdGhpcy5wYXBlclt0aGlzLnR5cGVdKCkuYXR0cih0aGlzLmF0dHIoKSk7XG4gICAgICAgIHRoaXMuX19zZXRfXyAmJiB0aGlzLl9fc2V0X18ucHVzaChvdXQpO1xuICAgICAgICByZXR1cm4gb3V0O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuZ2xvd1xuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJuIHNldCBvZiBlbGVtZW50cyB0aGF0IGNyZWF0ZSBnbG93LWxpa2UgZWZmZWN0IGFyb3VuZCBnaXZlbiBlbGVtZW50LiBTZWUgQFBhcGVyLnNldC5cbiAgICAgKlxuICAgICAqIE5vdGU6IEdsb3cgaXMgbm90IGNvbm5lY3RlZCB0byB0aGUgZWxlbWVudC4gSWYgeW91IGNoYW5nZSBlbGVtZW50IGF0dHJpYnV0ZXMgaXQgd29u4oCZdCBhZGp1c3QgaXRzZWxmLlxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSBnbG93IChvYmplY3QpICNvcHRpb25hbCBwYXJhbWV0ZXJzIG9iamVjdCB3aXRoIGFsbCBwcm9wZXJ0aWVzIG9wdGlvbmFsOlxuICAgICBvIHtcbiAgICAgbyAgICAgd2lkdGggKG51bWJlcikgc2l6ZSBvZiB0aGUgZ2xvdywgZGVmYXVsdCBpcyBgMTBgXG4gICAgIG8gICAgIGZpbGwgKGJvb2xlYW4pIHdpbGwgaXQgYmUgZmlsbGVkLCBkZWZhdWx0IGlzIGBmYWxzZWBcbiAgICAgbyAgICAgb3BhY2l0eSAobnVtYmVyKSBvcGFjaXR5LCBkZWZhdWx0IGlzIGAwLjVgXG4gICAgIG8gICAgIG9mZnNldHggKG51bWJlcikgaG9yaXpvbnRhbCBvZmZzZXQsIGRlZmF1bHQgaXMgYDBgXG4gICAgIG8gICAgIG9mZnNldHkgKG51bWJlcikgdmVydGljYWwgb2Zmc2V0LCBkZWZhdWx0IGlzIGAwYFxuICAgICBvICAgICBjb2xvciAoc3RyaW5nKSBnbG93IGNvbG91ciwgZGVmYXVsdCBpcyBgYmxhY2tgXG4gICAgIG8gfVxuICAgICA9IChvYmplY3QpIEBQYXBlci5zZXQgb2YgZWxlbWVudHMgdGhhdCByZXByZXNlbnRzIGdsb3dcbiAgICBcXCovXG4gICAgZWxwcm90by5nbG93ID0gZnVuY3Rpb24gKGdsb3cpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZSA9PSBcInRleHRcIikge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZ2xvdyA9IGdsb3cgfHwge307XG4gICAgICAgIHZhciBzID0ge1xuICAgICAgICAgICAgd2lkdGg6IChnbG93LndpZHRoIHx8IDEwKSArICgrdGhpcy5hdHRyKFwic3Ryb2tlLXdpZHRoXCIpIHx8IDEpLFxuICAgICAgICAgICAgZmlsbDogZ2xvdy5maWxsIHx8IGZhbHNlLFxuICAgICAgICAgICAgb3BhY2l0eTogZ2xvdy5vcGFjaXR5ID09IG51bGwgPyAuNSA6IGdsb3cub3BhY2l0eSxcbiAgICAgICAgICAgIG9mZnNldHg6IGdsb3cub2Zmc2V0eCB8fCAwLFxuICAgICAgICAgICAgb2Zmc2V0eTogZ2xvdy5vZmZzZXR5IHx8IDAsXG4gICAgICAgICAgICBjb2xvcjogZ2xvdy5jb2xvciB8fCBcIiMwMDBcIlxuICAgICAgICB9LFxuICAgICAgICAgICAgYyA9IHMud2lkdGggLyAyLFxuICAgICAgICAgICAgciA9IHRoaXMucGFwZXIsXG4gICAgICAgICAgICBvdXQgPSByLnNldCgpLFxuICAgICAgICAgICAgcGF0aCA9IHRoaXMucmVhbFBhdGggfHwgZ2V0UGF0aFt0aGlzLnR5cGVdKHRoaXMpO1xuICAgICAgICBwYXRoID0gdGhpcy5tYXRyaXggPyBtYXBQYXRoKHBhdGgsIHRoaXMubWF0cml4KSA6IHBhdGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYyArIDE7IGkrKykge1xuICAgICAgICAgICAgb3V0LnB1c2goci5wYXRoKHBhdGgpLmF0dHIoe1xuICAgICAgICAgICAgICAgIHN0cm9rZTogcy5jb2xvcixcbiAgICAgICAgICAgICAgICBmaWxsOiBzLmZpbGwgPyBzLmNvbG9yIDogXCJub25lXCIsXG4gICAgICAgICAgICAgICAgXCJzdHJva2UtbGluZWpvaW5cIjogXCJyb3VuZFwiLFxuICAgICAgICAgICAgICAgIFwic3Ryb2tlLWxpbmVjYXBcIjogXCJyb3VuZFwiLFxuICAgICAgICAgICAgICAgIFwic3Ryb2tlLXdpZHRoXCI6ICsocy53aWR0aCAvIGMgKiBpKS50b0ZpeGVkKDMpLFxuICAgICAgICAgICAgICAgIG9wYWNpdHk6ICsocy5vcGFjaXR5IC8gYykudG9GaXhlZCgzKVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXQuaW5zZXJ0QmVmb3JlKHRoaXMpLnRyYW5zbGF0ZShzLm9mZnNldHgsIHMub2Zmc2V0eSk7XG4gICAgfTtcbiAgICB2YXIgY3VydmVzbGVuZ3RocyA9IHt9LFxuICAgIGdldFBvaW50QXRTZWdtZW50TGVuZ3RoID0gZnVuY3Rpb24gKHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5LCBsZW5ndGgpIHtcbiAgICAgICAgaWYgKGxlbmd0aCA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gYmV6bGVuKHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBSLmZpbmREb3RzQXRTZWdtZW50KHAxeCwgcDF5LCBjMXgsIGMxeSwgYzJ4LCBjMnksIHAyeCwgcDJ5LCBnZXRUYXRMZW4ocDF4LCBwMXksIGMxeCwgYzF5LCBjMngsIGMyeSwgcDJ4LCBwMnksIGxlbmd0aCkpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBnZXRMZW5ndGhGYWN0b3J5ID0gZnVuY3Rpb24gKGlzdG90YWwsIHN1YnBhdGgpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChwYXRoLCBsZW5ndGgsIG9ubHlzdGFydCkge1xuICAgICAgICAgICAgcGF0aCA9IHBhdGgyY3VydmUocGF0aCk7XG4gICAgICAgICAgICB2YXIgeCwgeSwgcCwgbCwgc3AgPSBcIlwiLCBzdWJwYXRocyA9IHt9LCBwb2ludCxcbiAgICAgICAgICAgICAgICBsZW4gPSAwO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gcGF0aC5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcCA9IHBhdGhbaV07XG4gICAgICAgICAgICAgICAgaWYgKHBbMF0gPT0gXCJNXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgeCA9ICtwWzFdO1xuICAgICAgICAgICAgICAgICAgICB5ID0gK3BbMl07XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbCA9IGdldFBvaW50QXRTZWdtZW50TGVuZ3RoKHgsIHksIHBbMV0sIHBbMl0sIHBbM10sIHBbNF0sIHBbNV0sIHBbNl0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAobGVuICsgbCA+IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1YnBhdGggJiYgIXN1YnBhdGhzLnN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnQgPSBnZXRQb2ludEF0U2VnbWVudExlbmd0aCh4LCB5LCBwWzFdLCBwWzJdLCBwWzNdLCBwWzRdLCBwWzVdLCBwWzZdLCBsZW5ndGggLSBsZW4pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwICs9IFtcIkNcIiArIHBvaW50LnN0YXJ0LngsIHBvaW50LnN0YXJ0LnksIHBvaW50Lm0ueCwgcG9pbnQubS55LCBwb2ludC54LCBwb2ludC55XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob25seXN0YXJ0KSB7cmV0dXJuIHNwO31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJwYXRocy5zdGFydCA9IHNwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwID0gW1wiTVwiICsgcG9pbnQueCwgcG9pbnQueSArIFwiQ1wiICsgcG9pbnQubi54LCBwb2ludC5uLnksIHBvaW50LmVuZC54LCBwb2ludC5lbmQueSwgcFs1XSwgcFs2XV0uam9pbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbiArPSBsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSArcFs1XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gK3BbNl07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzdG90YWwgJiYgIXN1YnBhdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb2ludCA9IGdldFBvaW50QXRTZWdtZW50TGVuZ3RoKHgsIHksIHBbMV0sIHBbMl0sIHBbM10sIHBbNF0sIHBbNV0sIHBbNl0sIGxlbmd0aCAtIGxlbik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHt4OiBwb2ludC54LCB5OiBwb2ludC55LCBhbHBoYTogcG9pbnQuYWxwaGF9O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGxlbiArPSBsO1xuICAgICAgICAgICAgICAgICAgICB4ID0gK3BbNV07XG4gICAgICAgICAgICAgICAgICAgIHkgPSArcFs2XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc3AgKz0gcC5zaGlmdCgpICsgcDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1YnBhdGhzLmVuZCA9IHNwO1xuICAgICAgICAgICAgcG9pbnQgPSBpc3RvdGFsID8gbGVuIDogc3VicGF0aCA/IHN1YnBhdGhzIDogUi5maW5kRG90c0F0U2VnbWVudCh4LCB5LCBwWzBdLCBwWzFdLCBwWzJdLCBwWzNdLCBwWzRdLCBwWzVdLCAxKTtcbiAgICAgICAgICAgIHBvaW50LmFscGhhICYmIChwb2ludCA9IHt4OiBwb2ludC54LCB5OiBwb2ludC55LCBhbHBoYTogcG9pbnQuYWxwaGF9KTtcbiAgICAgICAgICAgIHJldHVybiBwb2ludDtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHZhciBnZXRUb3RhbExlbmd0aCA9IGdldExlbmd0aEZhY3RvcnkoMSksXG4gICAgICAgIGdldFBvaW50QXRMZW5ndGggPSBnZXRMZW5ndGhGYWN0b3J5KCksXG4gICAgICAgIGdldFN1YnBhdGhzQXRMZW5ndGggPSBnZXRMZW5ndGhGYWN0b3J5KDAsIDEpO1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLmdldFRvdGFsTGVuZ3RoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZXR1cm5zIGxlbmd0aCBvZiB0aGUgZ2l2ZW4gcGF0aCBpbiBwaXhlbHMuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIHBhdGggKHN0cmluZykgU1ZHIHBhdGggc3RyaW5nLlxuICAgICAqKlxuICAgICA9IChudW1iZXIpIGxlbmd0aC5cbiAgICBcXCovXG4gICAgUi5nZXRUb3RhbExlbmd0aCA9IGdldFRvdGFsTGVuZ3RoO1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLmdldFBvaW50QXRMZW5ndGhcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJldHVybiBjb29yZGluYXRlcyBvZiB0aGUgcG9pbnQgbG9jYXRlZCBhdCB0aGUgZ2l2ZW4gbGVuZ3RoIG9uIHRoZSBnaXZlbiBwYXRoLlxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSBwYXRoIChzdHJpbmcpIFNWRyBwYXRoIHN0cmluZ1xuICAgICAtIGxlbmd0aCAobnVtYmVyKVxuICAgICAqKlxuICAgICA9IChvYmplY3QpIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwb2ludDpcbiAgICAgbyB7XG4gICAgIG8gICAgIHg6IChudW1iZXIpIHggY29vcmRpbmF0ZVxuICAgICBvICAgICB5OiAobnVtYmVyKSB5IGNvb3JkaW5hdGVcbiAgICAgbyAgICAgYWxwaGE6IChudW1iZXIpIGFuZ2xlIG9mIGRlcml2YXRpdmVcbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIFIuZ2V0UG9pbnRBdExlbmd0aCA9IGdldFBvaW50QXRMZW5ndGg7XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZ2V0U3VicGF0aFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJuIHN1YnBhdGggb2YgYSBnaXZlbiBwYXRoIGZyb20gZ2l2ZW4gbGVuZ3RoIHRvIGdpdmVuIGxlbmd0aC5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gcGF0aCAoc3RyaW5nKSBTVkcgcGF0aCBzdHJpbmdcbiAgICAgLSBmcm9tIChudW1iZXIpIHBvc2l0aW9uIG9mIHRoZSBzdGFydCBvZiB0aGUgc2VnbWVudFxuICAgICAtIHRvIChudW1iZXIpIHBvc2l0aW9uIG9mIHRoZSBlbmQgb2YgdGhlIHNlZ21lbnRcbiAgICAgKipcbiAgICAgPSAoc3RyaW5nKSBwYXRoc3RyaW5nIGZvciB0aGUgc2VnbWVudFxuICAgIFxcKi9cbiAgICBSLmdldFN1YnBhdGggPSBmdW5jdGlvbiAocGF0aCwgZnJvbSwgdG8pIHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0VG90YWxMZW5ndGgocGF0aCkgLSB0byA8IDFlLTYpIHtcbiAgICAgICAgICAgIHJldHVybiBnZXRTdWJwYXRoc0F0TGVuZ3RoKHBhdGgsIGZyb20pLmVuZDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgYSA9IGdldFN1YnBhdGhzQXRMZW5ndGgocGF0aCwgdG8sIDEpO1xuICAgICAgICByZXR1cm4gZnJvbSA/IGdldFN1YnBhdGhzQXRMZW5ndGgoYSwgZnJvbSkuZW5kIDogYTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LmdldFRvdGFsTGVuZ3RoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZXR1cm5zIGxlbmd0aCBvZiB0aGUgcGF0aCBpbiBwaXhlbHMuIE9ubHkgd29ya3MgZm9yIGVsZW1lbnQgb2Yg4oCccGF0aOKAnSB0eXBlLlxuICAgICA9IChudW1iZXIpIGxlbmd0aC5cbiAgICBcXCovXG4gICAgZWxwcm90by5nZXRUb3RhbExlbmd0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBhdGggPSB0aGlzLmdldFBhdGgoKTtcbiAgICAgICAgaWYgKCFwYXRoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5ub2RlLmdldFRvdGFsTGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ub2RlLmdldFRvdGFsTGVuZ3RoKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZ2V0VG90YWxMZW5ndGgocGF0aCk7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5nZXRQb2ludEF0TGVuZ3RoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZXR1cm4gY29vcmRpbmF0ZXMgb2YgdGhlIHBvaW50IGxvY2F0ZWQgYXQgdGhlIGdpdmVuIGxlbmd0aCBvbiB0aGUgZ2l2ZW4gcGF0aC4gT25seSB3b3JrcyBmb3IgZWxlbWVudCBvZiDigJxwYXRo4oCdIHR5cGUuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGxlbmd0aCAobnVtYmVyKVxuICAgICAqKlxuICAgICA9IChvYmplY3QpIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwb2ludDpcbiAgICAgbyB7XG4gICAgIG8gICAgIHg6IChudW1iZXIpIHggY29vcmRpbmF0ZVxuICAgICBvICAgICB5OiAobnVtYmVyKSB5IGNvb3JkaW5hdGVcbiAgICAgbyAgICAgYWxwaGE6IChudW1iZXIpIGFuZ2xlIG9mIGRlcml2YXRpdmVcbiAgICAgbyB9XG4gICAgXFwqL1xuICAgIGVscHJvdG8uZ2V0UG9pbnRBdExlbmd0aCA9IGZ1bmN0aW9uIChsZW5ndGgpIHtcbiAgICAgICAgdmFyIHBhdGggPSB0aGlzLmdldFBhdGgoKTtcbiAgICAgICAgaWYgKCFwYXRoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZ2V0UG9pbnRBdExlbmd0aChwYXRoLCBsZW5ndGgpO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuZ2V0UGF0aFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJucyBwYXRoIG9mIHRoZSBlbGVtZW50LiBPbmx5IHdvcmtzIGZvciBlbGVtZW50cyBvZiDigJxwYXRo4oCdIHR5cGUgYW5kIHNpbXBsZSBlbGVtZW50cyBsaWtlIGNpcmNsZS5cbiAgICAgPSAob2JqZWN0KSBwYXRoXG4gICAgICoqXG4gICAgXFwqL1xuICAgIGVscHJvdG8uZ2V0UGF0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHBhdGgsXG4gICAgICAgICAgICBnZXRQYXRoID0gUi5fZ2V0UGF0aFt0aGlzLnR5cGVdO1xuXG4gICAgICAgIGlmICh0aGlzLnR5cGUgPT0gXCJ0ZXh0XCIgfHwgdGhpcy50eXBlID09IFwic2V0XCIpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChnZXRQYXRoKSB7XG4gICAgICAgICAgICBwYXRoID0gZ2V0UGF0aCh0aGlzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwYXRoO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuZ2V0U3VicGF0aFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmV0dXJuIHN1YnBhdGggb2YgYSBnaXZlbiBlbGVtZW50IGZyb20gZ2l2ZW4gbGVuZ3RoIHRvIGdpdmVuIGxlbmd0aC4gT25seSB3b3JrcyBmb3IgZWxlbWVudCBvZiDigJxwYXRo4oCdIHR5cGUuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGZyb20gKG51bWJlcikgcG9zaXRpb24gb2YgdGhlIHN0YXJ0IG9mIHRoZSBzZWdtZW50XG4gICAgIC0gdG8gKG51bWJlcikgcG9zaXRpb24gb2YgdGhlIGVuZCBvZiB0aGUgc2VnbWVudFxuICAgICAqKlxuICAgICA9IChzdHJpbmcpIHBhdGhzdHJpbmcgZm9yIHRoZSBzZWdtZW50XG4gICAgXFwqL1xuICAgIGVscHJvdG8uZ2V0U3VicGF0aCA9IGZ1bmN0aW9uIChmcm9tLCB0bykge1xuICAgICAgICB2YXIgcGF0aCA9IHRoaXMuZ2V0UGF0aCgpO1xuICAgICAgICBpZiAoIXBhdGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBSLmdldFN1YnBhdGgocGF0aCwgZnJvbSwgdG8pO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZWFzaW5nX2Zvcm11bGFzXG4gICAgIFsgcHJvcGVydHkgXVxuICAgICAqKlxuICAgICAqIE9iamVjdCB0aGF0IGNvbnRhaW5zIGVhc2luZyBmb3JtdWxhcyBmb3IgYW5pbWF0aW9uLiBZb3UgY291bGQgZXh0ZW5kIGl0IHdpdGggeW91ciBvd24uIEJ5IGRlZmF1bHQgaXQgaGFzIGZvbGxvd2luZyBsaXN0IG9mIGVhc2luZzpcbiAgICAgIyA8dWw+XG4gICAgICMgICAgIDxsaT7igJxsaW5lYXLigJ08L2xpPlxuICAgICAjICAgICA8bGk+4oCcJmx0O+KAnSBvciDigJxlYXNlSW7igJ0gb3Ig4oCcZWFzZS1pbuKAnTwvbGk+XG4gICAgICMgICAgIDxsaT7igJw+4oCdIG9yIOKAnGVhc2VPdXTigJ0gb3Ig4oCcZWFzZS1vdXTigJ08L2xpPlxuICAgICAjICAgICA8bGk+4oCcJmx0Oz7igJ0gb3Ig4oCcZWFzZUluT3V04oCdIG9yIOKAnGVhc2UtaW4tb3V04oCdPC9saT5cbiAgICAgIyAgICAgPGxpPuKAnGJhY2tJbuKAnSBvciDigJxiYWNrLWlu4oCdPC9saT5cbiAgICAgIyAgICAgPGxpPuKAnGJhY2tPdXTigJ0gb3Ig4oCcYmFjay1vdXTigJ08L2xpPlxuICAgICAjICAgICA8bGk+4oCcZWxhc3RpY+KAnTwvbGk+XG4gICAgICMgICAgIDxsaT7igJxib3VuY2XigJ08L2xpPlxuICAgICAjIDwvdWw+XG4gICAgICMgPHA+U2VlIGFsc28gPGEgaHJlZj1cImh0dHA6Ly9yYXBoYWVsanMuY29tL2Vhc2luZy5odG1sXCI+RWFzaW5nIGRlbW88L2E+LjwvcD5cbiAgICBcXCovXG4gICAgdmFyIGVmID0gUi5lYXNpbmdfZm9ybXVsYXMgPSB7XG4gICAgICAgIGxpbmVhcjogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgIHJldHVybiBuO1xuICAgICAgICB9LFxuICAgICAgICBcIjxcIjogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgIHJldHVybiBwb3cobiwgMS43KTtcbiAgICAgICAgfSxcbiAgICAgICAgXCI+XCI6IGZ1bmN0aW9uIChuKSB7XG4gICAgICAgICAgICByZXR1cm4gcG93KG4sIC40OCk7XG4gICAgICAgIH0sXG4gICAgICAgIFwiPD5cIjogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgIHZhciBxID0gLjQ4IC0gbiAvIDEuMDQsXG4gICAgICAgICAgICAgICAgUSA9IG1hdGguc3FydCguMTczNCArIHEgKiBxKSxcbiAgICAgICAgICAgICAgICB4ID0gUSAtIHEsXG4gICAgICAgICAgICAgICAgWCA9IHBvdyhhYnMoeCksIDEgLyAzKSAqICh4IDwgMCA/IC0xIDogMSksXG4gICAgICAgICAgICAgICAgeSA9IC1RIC0gcSxcbiAgICAgICAgICAgICAgICBZID0gcG93KGFicyh5KSwgMSAvIDMpICogKHkgPCAwID8gLTEgOiAxKSxcbiAgICAgICAgICAgICAgICB0ID0gWCArIFkgKyAuNTtcbiAgICAgICAgICAgIHJldHVybiAoMSAtIHQpICogMyAqIHQgKiB0ICsgdCAqIHQgKiB0O1xuICAgICAgICB9LFxuICAgICAgICBiYWNrSW46IGZ1bmN0aW9uIChuKSB7XG4gICAgICAgICAgICB2YXIgcyA9IDEuNzAxNTg7XG4gICAgICAgICAgICByZXR1cm4gbiAqIG4gKiAoKHMgKyAxKSAqIG4gLSBzKTtcbiAgICAgICAgfSxcbiAgICAgICAgYmFja091dDogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgIG4gPSBuIC0gMTtcbiAgICAgICAgICAgIHZhciBzID0gMS43MDE1ODtcbiAgICAgICAgICAgIHJldHVybiBuICogbiAqICgocyArIDEpICogbiArIHMpICsgMTtcbiAgICAgICAgfSxcbiAgICAgICAgZWxhc3RpYzogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgIGlmIChuID09ICEhbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHBvdygyLCAtMTAgKiBuKSAqIG1hdGguc2luKChuIC0gLjA3NSkgKiAoMiAqIFBJKSAvIC4zKSArIDE7XG4gICAgICAgIH0sXG4gICAgICAgIGJvdW5jZTogZnVuY3Rpb24gKG4pIHtcbiAgICAgICAgICAgIHZhciBzID0gNy41NjI1LFxuICAgICAgICAgICAgICAgIHAgPSAyLjc1LFxuICAgICAgICAgICAgICAgIGw7XG4gICAgICAgICAgICBpZiAobiA8ICgxIC8gcCkpIHtcbiAgICAgICAgICAgICAgICBsID0gcyAqIG4gKiBuO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAobiA8ICgyIC8gcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgbiAtPSAoMS41IC8gcCk7XG4gICAgICAgICAgICAgICAgICAgIGwgPSBzICogbiAqIG4gKyAuNzU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG4gPCAoMi41IC8gcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG4gLT0gKDIuMjUgLyBwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGwgPSBzICogbiAqIG4gKyAuOTM3NTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG4gLT0gKDIuNjI1IC8gcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBsID0gcyAqIG4gKiBuICsgLjk4NDM3NTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBsO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBlZi5lYXNlSW4gPSBlZltcImVhc2UtaW5cIl0gPSBlZltcIjxcIl07XG4gICAgZWYuZWFzZU91dCA9IGVmW1wiZWFzZS1vdXRcIl0gPSBlZltcIj5cIl07XG4gICAgZWYuZWFzZUluT3V0ID0gZWZbXCJlYXNlLWluLW91dFwiXSA9IGVmW1wiPD5cIl07XG4gICAgZWZbXCJiYWNrLWluXCJdID0gZWYuYmFja0luO1xuICAgIGVmW1wiYmFjay1vdXRcIl0gPSBlZi5iYWNrT3V0O1xuXG4gICAgdmFyIGFuaW1hdGlvbkVsZW1lbnRzID0gW10sXG4gICAgICAgIHJlcXVlc3RBbmltRnJhbWUgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lICAgICAgIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cud2Via2l0UmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubW96UmVxdWVzdEFuaW1hdGlvbkZyYW1lICAgIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cub1JlcXVlc3RBbmltYXRpb25GcmFtZSAgICAgIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cubXNSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgICAgIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGNhbGxiYWNrLCAxNik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICBhbmltYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgTm93ID0gK25ldyBEYXRlLFxuICAgICAgICAgICAgICAgIGwgPSAwO1xuICAgICAgICAgICAgZm9yICg7IGwgPCBhbmltYXRpb25FbGVtZW50cy5sZW5ndGg7IGwrKykge1xuICAgICAgICAgICAgICAgIHZhciBlID0gYW5pbWF0aW9uRWxlbWVudHNbbF07XG4gICAgICAgICAgICAgICAgaWYgKGUuZWwucmVtb3ZlZCB8fCBlLnBhdXNlZCkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIHRpbWUgPSBOb3cgLSBlLnN0YXJ0LFxuICAgICAgICAgICAgICAgICAgICBtcyA9IGUubXMsXG4gICAgICAgICAgICAgICAgICAgIGVhc2luZyA9IGUuZWFzaW5nLFxuICAgICAgICAgICAgICAgICAgICBmcm9tID0gZS5mcm9tLFxuICAgICAgICAgICAgICAgICAgICBkaWZmID0gZS5kaWZmLFxuICAgICAgICAgICAgICAgICAgICB0byA9IGUudG8sXG4gICAgICAgICAgICAgICAgICAgIHQgPSBlLnQsXG4gICAgICAgICAgICAgICAgICAgIHRoYXQgPSBlLmVsLFxuICAgICAgICAgICAgICAgICAgICBzZXQgPSB7fSxcbiAgICAgICAgICAgICAgICAgICAgbm93LFxuICAgICAgICAgICAgICAgICAgICBpbml0ID0ge30sXG4gICAgICAgICAgICAgICAgICAgIGtleTtcbiAgICAgICAgICAgICAgICBpZiAoZS5pbml0c3RhdHVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRpbWUgPSAoZS5pbml0c3RhdHVzICogZS5hbmltLnRvcCAtIGUucHJldikgLyAoZS5wZXJjZW50IC0gZS5wcmV2KSAqIG1zO1xuICAgICAgICAgICAgICAgICAgICBlLnN0YXR1cyA9IGUuaW5pdHN0YXR1cztcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGUuaW5pdHN0YXR1cztcbiAgICAgICAgICAgICAgICAgICAgZS5zdG9wICYmIGFuaW1hdGlvbkVsZW1lbnRzLnNwbGljZShsLS0sIDEpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGUuc3RhdHVzID0gKGUucHJldiArIChlLnBlcmNlbnQgLSBlLnByZXYpICogKHRpbWUgLyBtcykpIC8gZS5hbmltLnRvcDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRpbWUgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGltZSA8IG1zKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBwb3MgPSBlYXNpbmcodGltZSAvIG1zKTtcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgYXR0ciBpbiBmcm9tKSBpZiAoZnJvbVtoYXNdKGF0dHIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGF2YWlsYWJsZUFuaW1BdHRyc1thdHRyXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgbnU6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdyA9ICtmcm9tW2F0dHJdICsgcG9zICogbXMgKiBkaWZmW2F0dHJdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwiY29sb3VyXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdyA9IFwicmdiKFwiICsgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXB0bzI1NShyb3VuZChmcm9tW2F0dHJdLnIgKyBwb3MgKiBtcyAqIGRpZmZbYXR0cl0ucikpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXB0bzI1NShyb3VuZChmcm9tW2F0dHJdLmcgKyBwb3MgKiBtcyAqIGRpZmZbYXR0cl0uZykpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXB0bzI1NShyb3VuZChmcm9tW2F0dHJdLmIgKyBwb3MgKiBtcyAqIGRpZmZbYXR0cl0uYikpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0uam9pbihcIixcIikgKyBcIilcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcInBhdGhcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm93ID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGZyb21bYXR0cl0ubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm93W2ldID0gW2Zyb21bYXR0cl1baV1bMF1dO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDEsIGpqID0gZnJvbVthdHRyXVtpXS5sZW5ndGg7IGogPCBqajsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm93W2ldW2pdID0gK2Zyb21bYXR0cl1baV1bal0gKyBwb3MgKiBtcyAqIGRpZmZbYXR0cl1baV1bal07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3dbaV0gPSBub3dbaV0uam9pbihTKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3cgPSBub3cuam9pbihTKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcInRyYW5zZm9ybVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGlmZlthdHRyXS5yZWFsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3cgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGlpID0gZnJvbVthdHRyXS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm93W2ldID0gW2Zyb21bYXR0cl1baV1bMF1dO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDEsIGpqID0gZnJvbVthdHRyXVtpXS5sZW5ndGg7IGogPCBqajsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vd1tpXVtqXSA9IGZyb21bYXR0cl1baV1bal0gKyBwb3MgKiBtcyAqIGRpZmZbYXR0cl1baV1bal07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGdldCA9IGZ1bmN0aW9uIChpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICtmcm9tW2F0dHJdW2ldICsgcG9zICogbXMgKiBkaWZmW2F0dHJdW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vdyA9IFtbXCJyXCIsIGdldCgyKSwgMCwgMF0sIFtcInRcIiwgZ2V0KDMpLCBnZXQoNCldLCBbXCJzXCIsIGdldCgwKSwgZ2V0KDEpLCAwLCAwXV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3cgPSBbW1wibVwiLCBnZXQoMCksIGdldCgxKSwgZ2V0KDIpLCBnZXQoMyksIGdldCg0KSwgZ2V0KDUpXV07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcImNzdlwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ciA9PSBcImNsaXAtcmVjdFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3cgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPSA0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vd1tpXSA9ICtmcm9tW2F0dHJdW2ldICsgcG9zICogbXMgKiBkaWZmW2F0dHJdW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmcm9tMiA9IFtdW2NvbmNhdF0oZnJvbVthdHRyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID0gdGhhdC5wYXBlci5jdXN0b21BdHRyaWJ1dGVzW2F0dHJdLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm93W2ldID0gK2Zyb20yW2ldICsgcG9zICogbXMgKiBkaWZmW2F0dHJdW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0W2F0dHJdID0gbm93O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoYXQuYXR0cihzZXQpO1xuICAgICAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKGlkLCB0aGF0LCBhbmltKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmUoXCJyYXBoYWVsLmFuaW0uZnJhbWUuXCIgKyBpZCwgdGhhdCwgYW5pbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSkodGhhdC5pZCwgdGhhdCwgZS5hbmltKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAoZnVuY3Rpb24oZiwgZWwsIGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlKFwicmFwaGFlbC5hbmltLmZyYW1lLlwiICsgZWwuaWQsIGVsLCBhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmUoXCJyYXBoYWVsLmFuaW0uZmluaXNoLlwiICsgZWwuaWQsIGVsLCBhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSLmlzKGYsIFwiZnVuY3Rpb25cIikgJiYgZi5jYWxsKGVsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KShlLmNhbGxiYWNrLCB0aGF0LCBlLmFuaW0pO1xuICAgICAgICAgICAgICAgICAgICB0aGF0LmF0dHIodG8pO1xuICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25FbGVtZW50cy5zcGxpY2UobC0tLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGUucmVwZWF0ID4gMSAmJiAhZS5uZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiB0bykgaWYgKHRvW2hhc10oa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaXRba2V5XSA9IGUudG90YWxPcmlnaW5ba2V5XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGUuZWwuYXR0cihpbml0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bkFuaW1hdGlvbihlLmFuaW0sIGUuZWwsIGUuYW5pbS5wZXJjZW50c1swXSwgbnVsbCwgZS50b3RhbE9yaWdpbiwgZS5yZXBlYXQgLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZS5uZXh0ICYmICFlLnN0b3ApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bkFuaW1hdGlvbihlLmFuaW0sIGUuZWwsIGUubmV4dCwgbnVsbCwgZS50b3RhbE9yaWdpbiwgZS5yZXBlYXQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYW5pbWF0aW9uRWxlbWVudHMubGVuZ3RoICYmIHJlcXVlc3RBbmltRnJhbWUoYW5pbWF0aW9uKTtcbiAgICAgICAgfSxcbiAgICAgICAgdXB0bzI1NSA9IGZ1bmN0aW9uIChjb2xvcikge1xuICAgICAgICAgICAgcmV0dXJuIGNvbG9yID4gMjU1ID8gMjU1IDogY29sb3IgPCAwID8gMCA6IGNvbG9yO1xuICAgICAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LmFuaW1hdGVXaXRoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBY3RzIHNpbWlsYXIgdG8gQEVsZW1lbnQuYW5pbWF0ZSwgYnV0IGVuc3VyZSB0aGF0IGdpdmVuIGFuaW1hdGlvbiBydW5zIGluIHN5bmMgd2l0aCBhbm90aGVyIGdpdmVuIGVsZW1lbnQuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGVsIChvYmplY3QpIGVsZW1lbnQgdG8gc3luYyB3aXRoXG4gICAgIC0gYW5pbSAob2JqZWN0KSBhbmltYXRpb24gdG8gc3luYyB3aXRoXG4gICAgIC0gcGFyYW1zIChvYmplY3QpICNvcHRpb25hbCBmaW5hbCBhdHRyaWJ1dGVzIGZvciB0aGUgZWxlbWVudCwgc2VlIGFsc28gQEVsZW1lbnQuYXR0clxuICAgICAtIG1zIChudW1iZXIpICNvcHRpb25hbCBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGZvciBhbmltYXRpb24gdG8gcnVuXG4gICAgIC0gZWFzaW5nIChzdHJpbmcpICNvcHRpb25hbCBlYXNpbmcgdHlwZS4gQWNjZXB0IG9uIG9mIEBSYXBoYWVsLmVhc2luZ19mb3JtdWxhcyBvciBDU1MgZm9ybWF0OiBgY3ViaWMmI3gyMDEwO2JlemllcihYWCwmIzE2MDtYWCwmIzE2MDtYWCwmIzE2MDtYWClgXG4gICAgIC0gY2FsbGJhY2sgKGZ1bmN0aW9uKSAjb3B0aW9uYWwgY2FsbGJhY2sgZnVuY3Rpb24uIFdpbGwgYmUgY2FsbGVkIGF0IHRoZSBlbmQgb2YgYW5pbWF0aW9uLlxuICAgICAqIG9yXG4gICAgIC0gZWxlbWVudCAob2JqZWN0KSBlbGVtZW50IHRvIHN5bmMgd2l0aFxuICAgICAtIGFuaW0gKG9iamVjdCkgYW5pbWF0aW9uIHRvIHN5bmMgd2l0aFxuICAgICAtIGFuaW1hdGlvbiAob2JqZWN0KSAjb3B0aW9uYWwgYW5pbWF0aW9uIG9iamVjdCwgc2VlIEBSYXBoYWVsLmFuaW1hdGlvblxuICAgICAqKlxuICAgICA9IChvYmplY3QpIG9yaWdpbmFsIGVsZW1lbnRcbiAgICBcXCovXG4gICAgZWxwcm90by5hbmltYXRlV2l0aCA9IGZ1bmN0aW9uIChlbCwgYW5pbSwgcGFyYW1zLCBtcywgZWFzaW5nLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgZWxlbWVudCA9IHRoaXM7XG4gICAgICAgIGlmIChlbGVtZW50LnJlbW92ZWQpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrLmNhbGwoZWxlbWVudCk7XG4gICAgICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgYSA9IHBhcmFtcyBpbnN0YW5jZW9mIEFuaW1hdGlvbiA/IHBhcmFtcyA6IFIuYW5pbWF0aW9uKHBhcmFtcywgbXMsIGVhc2luZywgY2FsbGJhY2spLFxuICAgICAgICAgICAgeCwgeTtcbiAgICAgICAgcnVuQW5pbWF0aW9uKGEsIGVsZW1lbnQsIGEucGVyY2VudHNbMF0sIG51bGwsIGVsZW1lbnQuYXR0cigpKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gYW5pbWF0aW9uRWxlbWVudHMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgaWYgKGFuaW1hdGlvbkVsZW1lbnRzW2ldLmFuaW0gPT0gYW5pbSAmJiBhbmltYXRpb25FbGVtZW50c1tpXS5lbCA9PSBlbCkge1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbkVsZW1lbnRzW2lpIC0gMV0uc3RhcnQgPSBhbmltYXRpb25FbGVtZW50c1tpXS5zdGFydDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgLy9cbiAgICAgICAgLy9cbiAgICAgICAgLy8gdmFyIGEgPSBwYXJhbXMgPyBSLmFuaW1hdGlvbihwYXJhbXMsIG1zLCBlYXNpbmcsIGNhbGxiYWNrKSA6IGFuaW0sXG4gICAgICAgIC8vICAgICBzdGF0dXMgPSBlbGVtZW50LnN0YXR1cyhhbmltKTtcbiAgICAgICAgLy8gcmV0dXJuIHRoaXMuYW5pbWF0ZShhKS5zdGF0dXMoYSwgc3RhdHVzICogYW5pbS5tcyAvIGEubXMpO1xuICAgIH07XG4gICAgZnVuY3Rpb24gQ3ViaWNCZXppZXJBdFRpbWUodCwgcDF4LCBwMXksIHAyeCwgcDJ5LCBkdXJhdGlvbikge1xuICAgICAgICB2YXIgY3ggPSAzICogcDF4LFxuICAgICAgICAgICAgYnggPSAzICogKHAyeCAtIHAxeCkgLSBjeCxcbiAgICAgICAgICAgIGF4ID0gMSAtIGN4IC0gYngsXG4gICAgICAgICAgICBjeSA9IDMgKiBwMXksXG4gICAgICAgICAgICBieSA9IDMgKiAocDJ5IC0gcDF5KSAtIGN5LFxuICAgICAgICAgICAgYXkgPSAxIC0gY3kgLSBieTtcbiAgICAgICAgZnVuY3Rpb24gc2FtcGxlQ3VydmVYKHQpIHtcbiAgICAgICAgICAgIHJldHVybiAoKGF4ICogdCArIGJ4KSAqIHQgKyBjeCkgKiB0O1xuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIHNvbHZlKHgsIGVwc2lsb24pIHtcbiAgICAgICAgICAgIHZhciB0ID0gc29sdmVDdXJ2ZVgoeCwgZXBzaWxvbik7XG4gICAgICAgICAgICByZXR1cm4gKChheSAqIHQgKyBieSkgKiB0ICsgY3kpICogdDtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBzb2x2ZUN1cnZlWCh4LCBlcHNpbG9uKSB7XG4gICAgICAgICAgICB2YXIgdDAsIHQxLCB0MiwgeDIsIGQyLCBpO1xuICAgICAgICAgICAgZm9yKHQyID0geCwgaSA9IDA7IGkgPCA4OyBpKyspIHtcbiAgICAgICAgICAgICAgICB4MiA9IHNhbXBsZUN1cnZlWCh0MikgLSB4O1xuICAgICAgICAgICAgICAgIGlmIChhYnMoeDIpIDwgZXBzaWxvbikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdDI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGQyID0gKDMgKiBheCAqIHQyICsgMiAqIGJ4KSAqIHQyICsgY3g7XG4gICAgICAgICAgICAgICAgaWYgKGFicyhkMikgPCAxZS02KSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0MiA9IHQyIC0geDIgLyBkMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHQwID0gMDtcbiAgICAgICAgICAgIHQxID0gMTtcbiAgICAgICAgICAgIHQyID0geDtcbiAgICAgICAgICAgIGlmICh0MiA8IHQwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHQwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHQyID4gdDEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB3aGlsZSAodDAgPCB0MSkge1xuICAgICAgICAgICAgICAgIHgyID0gc2FtcGxlQ3VydmVYKHQyKTtcbiAgICAgICAgICAgICAgICBpZiAoYWJzKHgyIC0geCkgPCBlcHNpbG9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0MjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHggPiB4Mikge1xuICAgICAgICAgICAgICAgICAgICB0MCA9IHQyO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHQxID0gdDI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHQyID0gKHQxIC0gdDApIC8gMiArIHQwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHQyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzb2x2ZSh0LCAxIC8gKDIwMCAqIGR1cmF0aW9uKSk7XG4gICAgfVxuICAgIGVscHJvdG8ub25BbmltYXRpb24gPSBmdW5jdGlvbiAoZikge1xuICAgICAgICBmID8gZXZlLm9uKFwicmFwaGFlbC5hbmltLmZyYW1lLlwiICsgdGhpcy5pZCwgZikgOiBldmUudW5iaW5kKFwicmFwaGFlbC5hbmltLmZyYW1lLlwiICsgdGhpcy5pZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgZnVuY3Rpb24gQW5pbWF0aW9uKGFuaW0sIG1zKSB7XG4gICAgICAgIHZhciBwZXJjZW50cyA9IFtdLFxuICAgICAgICAgICAgbmV3QW5pbSA9IHt9O1xuICAgICAgICB0aGlzLm1zID0gbXM7XG4gICAgICAgIHRoaXMudGltZXMgPSAxO1xuICAgICAgICBpZiAoYW5pbSkge1xuICAgICAgICAgICAgZm9yICh2YXIgYXR0ciBpbiBhbmltKSBpZiAoYW5pbVtoYXNdKGF0dHIpKSB7XG4gICAgICAgICAgICAgICAgbmV3QW5pbVt0b0Zsb2F0KGF0dHIpXSA9IGFuaW1bYXR0cl07XG4gICAgICAgICAgICAgICAgcGVyY2VudHMucHVzaCh0b0Zsb2F0KGF0dHIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBlcmNlbnRzLnNvcnQoc29ydEJ5TnVtYmVyKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFuaW0gPSBuZXdBbmltO1xuICAgICAgICB0aGlzLnRvcCA9IHBlcmNlbnRzW3BlcmNlbnRzLmxlbmd0aCAtIDFdO1xuICAgICAgICB0aGlzLnBlcmNlbnRzID0gcGVyY2VudHM7XG4gICAgfVxuICAgIC8qXFxcbiAgICAgKiBBbmltYXRpb24uZGVsYXlcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIENyZWF0ZXMgYSBjb3B5IG9mIGV4aXN0aW5nIGFuaW1hdGlvbiBvYmplY3Qgd2l0aCBnaXZlbiBkZWxheS5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gZGVsYXkgKG51bWJlcikgbnVtYmVyIG9mIG1zIHRvIHBhc3MgYmV0d2VlbiBhbmltYXRpb24gc3RhcnQgYW5kIGFjdHVhbCBhbmltYXRpb25cbiAgICAgKipcbiAgICAgPSAob2JqZWN0KSBuZXcgYWx0ZXJlZCBBbmltYXRpb24gb2JqZWN0XG4gICAgIHwgdmFyIGFuaW0gPSBSYXBoYWVsLmFuaW1hdGlvbih7Y3g6IDEwLCBjeTogMjB9LCAyZTMpO1xuICAgICB8IGNpcmNsZTEuYW5pbWF0ZShhbmltKTsgLy8gcnVuIHRoZSBnaXZlbiBhbmltYXRpb24gaW1tZWRpYXRlbHlcbiAgICAgfCBjaXJjbGUyLmFuaW1hdGUoYW5pbS5kZWxheSg1MDApKTsgLy8gcnVuIHRoZSBnaXZlbiBhbmltYXRpb24gYWZ0ZXIgNTAwIG1zXG4gICAgXFwqL1xuICAgIEFuaW1hdGlvbi5wcm90b3R5cGUuZGVsYXkgPSBmdW5jdGlvbiAoZGVsYXkpIHtcbiAgICAgICAgdmFyIGEgPSBuZXcgQW5pbWF0aW9uKHRoaXMuYW5pbSwgdGhpcy5tcyk7XG4gICAgICAgIGEudGltZXMgPSB0aGlzLnRpbWVzO1xuICAgICAgICBhLmRlbCA9ICtkZWxheSB8fCAwO1xuICAgICAgICByZXR1cm4gYTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBBbmltYXRpb24ucmVwZWF0XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBDcmVhdGVzIGEgY29weSBvZiBleGlzdGluZyBhbmltYXRpb24gb2JqZWN0IHdpdGggZ2l2ZW4gcmVwZXRpdGlvbi5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gcmVwZWF0IChudW1iZXIpIG51bWJlciBpdGVyYXRpb25zIG9mIGFuaW1hdGlvbi4gRm9yIGluZmluaXRlIGFuaW1hdGlvbiBwYXNzIGBJbmZpbml0eWBcbiAgICAgKipcbiAgICAgPSAob2JqZWN0KSBuZXcgYWx0ZXJlZCBBbmltYXRpb24gb2JqZWN0XG4gICAgXFwqL1xuICAgIEFuaW1hdGlvbi5wcm90b3R5cGUucmVwZWF0ID0gZnVuY3Rpb24gKHRpbWVzKSB7XG4gICAgICAgIHZhciBhID0gbmV3IEFuaW1hdGlvbih0aGlzLmFuaW0sIHRoaXMubXMpO1xuICAgICAgICBhLmRlbCA9IHRoaXMuZGVsO1xuICAgICAgICBhLnRpbWVzID0gbWF0aC5mbG9vcihtbWF4KHRpbWVzLCAwKSkgfHwgMTtcbiAgICAgICAgcmV0dXJuIGE7XG4gICAgfTtcbiAgICBmdW5jdGlvbiBydW5BbmltYXRpb24oYW5pbSwgZWxlbWVudCwgcGVyY2VudCwgc3RhdHVzLCB0b3RhbE9yaWdpbiwgdGltZXMpIHtcbiAgICAgICAgcGVyY2VudCA9IHRvRmxvYXQocGVyY2VudCk7XG4gICAgICAgIHZhciBwYXJhbXMsXG4gICAgICAgICAgICBpc0luQW5pbSxcbiAgICAgICAgICAgIGlzSW5BbmltU2V0LFxuICAgICAgICAgICAgcGVyY2VudHMgPSBbXSxcbiAgICAgICAgICAgIG5leHQsXG4gICAgICAgICAgICBwcmV2LFxuICAgICAgICAgICAgdGltZXN0YW1wLFxuICAgICAgICAgICAgbXMgPSBhbmltLm1zLFxuICAgICAgICAgICAgZnJvbSA9IHt9LFxuICAgICAgICAgICAgdG8gPSB7fSxcbiAgICAgICAgICAgIGRpZmYgPSB7fTtcbiAgICAgICAgaWYgKHN0YXR1cykge1xuICAgICAgICAgICAgZm9yIChpID0gMCwgaWkgPSBhbmltYXRpb25FbGVtZW50cy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGUgPSBhbmltYXRpb25FbGVtZW50c1tpXTtcbiAgICAgICAgICAgICAgICBpZiAoZS5lbC5pZCA9PSBlbGVtZW50LmlkICYmIGUuYW5pbSA9PSBhbmltKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlLnBlcmNlbnQgIT0gcGVyY2VudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uRWxlbWVudHMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNJbkFuaW1TZXQgPSAxO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNJbkFuaW0gPSBlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYXR0cihlLnRvdGFsT3JpZ2luKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RhdHVzID0gK3RvOyAvLyBOYU5cbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBhbmltLnBlcmNlbnRzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChhbmltLnBlcmNlbnRzW2ldID09IHBlcmNlbnQgfHwgYW5pbS5wZXJjZW50c1tpXSA+IHN0YXR1cyAqIGFuaW0udG9wKSB7XG4gICAgICAgICAgICAgICAgcGVyY2VudCA9IGFuaW0ucGVyY2VudHNbaV07XG4gICAgICAgICAgICAgICAgcHJldiA9IGFuaW0ucGVyY2VudHNbaSAtIDFdIHx8IDA7XG4gICAgICAgICAgICAgICAgbXMgPSBtcyAvIGFuaW0udG9wICogKHBlcmNlbnQgLSBwcmV2KTtcbiAgICAgICAgICAgICAgICBuZXh0ID0gYW5pbS5wZXJjZW50c1tpICsgMV07XG4gICAgICAgICAgICAgICAgcGFyYW1zID0gYW5pbS5hbmltW3BlcmNlbnRdO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0dXMpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50LmF0dHIoYW5pbS5hbmltW2FuaW0ucGVyY2VudHNbaV1dKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIXBhcmFtcykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNJbkFuaW0pIHtcbiAgICAgICAgICAgIGZvciAodmFyIGF0dHIgaW4gcGFyYW1zKSBpZiAocGFyYW1zW2hhc10oYXR0cikpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXZhaWxhYmxlQW5pbUF0dHJzW2hhc10oYXR0cikgfHwgZWxlbWVudC5wYXBlci5jdXN0b21BdHRyaWJ1dGVzW2hhc10oYXR0cikpIHtcbiAgICAgICAgICAgICAgICAgICAgZnJvbVthdHRyXSA9IGVsZW1lbnQuYXR0cihhdHRyKTtcbiAgICAgICAgICAgICAgICAgICAgKGZyb21bYXR0cl0gPT0gbnVsbCkgJiYgKGZyb21bYXR0cl0gPSBhdmFpbGFibGVBdHRyc1thdHRyXSk7XG4gICAgICAgICAgICAgICAgICAgIHRvW2F0dHJdID0gcGFyYW1zW2F0dHJdO1xuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGF2YWlsYWJsZUFuaW1BdHRyc1thdHRyXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBudTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWZmW2F0dHJdID0gKHRvW2F0dHJdIC0gZnJvbVthdHRyXSkgLyBtcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJjb2xvdXJcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tW2F0dHJdID0gUi5nZXRSR0IoZnJvbVthdHRyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRvQ29sb3VyID0gUi5nZXRSR0IodG9bYXR0cl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZbYXR0cl0gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHI6ICh0b0NvbG91ci5yIC0gZnJvbVthdHRyXS5yKSAvIG1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnOiAodG9Db2xvdXIuZyAtIGZyb21bYXR0cl0uZykgLyBtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYjogKHRvQ29sb3VyLmIgLSBmcm9tW2F0dHJdLmIpIC8gbXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcInBhdGhcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGF0aGVzID0gcGF0aDJjdXJ2ZShmcm9tW2F0dHJdLCB0b1thdHRyXSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvUGF0aCA9IHBhdGhlc1sxXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tW2F0dHJdID0gcGF0aGVzWzBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZbYXR0cl0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBpaSA9IGZyb21bYXR0cl0ubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWZmW2F0dHJdW2ldID0gWzBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMSwgamogPSBmcm9tW2F0dHJdW2ldLmxlbmd0aDsgaiA8IGpqOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZbYXR0cl1baV1bal0gPSAodG9QYXRoW2ldW2pdIC0gZnJvbVthdHRyXVtpXVtqXSkgLyBtcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJ0cmFuc2Zvcm1cIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgXyA9IGVsZW1lbnQuXyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXEgPSBlcXVhbGlzZVRyYW5zZm9ybShfW2F0dHJdLCB0b1thdHRyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21bYXR0cl0gPSBlcS5mcm9tO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1thdHRyXSA9IGVxLnRvO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWZmW2F0dHJdID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZbYXR0cl0ucmVhbCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGlpID0gZnJvbVthdHRyXS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWZmW2F0dHJdW2ldID0gW2Zyb21bYXR0cl1baV1bMF1dO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChqID0gMSwgamogPSBmcm9tW2F0dHJdW2ldLmxlbmd0aDsgaiA8IGpqOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaWZmW2F0dHJdW2ldW2pdID0gKHRvW2F0dHJdW2ldW2pdIC0gZnJvbVthdHRyXVtpXVtqXSkgLyBtcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtID0gKGVsZW1lbnQubWF0cml4IHx8IG5ldyBNYXRyaXgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8yID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF86IHt0cmFuc2Zvcm06IF8udHJhbnNmb3JtfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRCQm94OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50LmdldEJCb3goMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbVthdHRyXSA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uYSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uYixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uZlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRyYWN0VHJhbnNmb3JtKHRvMiwgdG9bYXR0cl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1thdHRyXSA9IHRvMi5fLnRyYW5zZm9ybTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlmZlthdHRyXSA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0bzIubWF0cml4LmEgLSBtLmEpIC8gbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodG8yLm1hdHJpeC5iIC0gbS5iKSAvIG1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRvMi5tYXRyaXguYyAtIG0uYykgLyBtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0bzIubWF0cml4LmQgLSBtLmQpIC8gbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodG8yLm1hdHJpeC5lIC0gbS5lKSAvIG1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRvMi5tYXRyaXguZiAtIG0uZikgLyBtc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmcm9tW2F0dHJdID0gW18uc3gsIF8uc3ksIF8uZGVnLCBfLmR4LCBfLmR5XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmFyIHRvMiA9IHtfOnt9LCBnZXRCQm94OiBmdW5jdGlvbiAoKSB7IHJldHVybiBlbGVtZW50LmdldEJCb3goKTsgfX07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGV4dHJhY3RUcmFuc2Zvcm0odG8yLCB0b1thdHRyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRpZmZbYXR0cl0gPSBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAodG8yLl8uc3ggLSBfLnN4KSAvIG1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgKHRvMi5fLnN5IC0gXy5zeSkgLyBtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICh0bzIuXy5kZWcgLSBfLmRlZykgLyBtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICh0bzIuXy5keCAtIF8uZHgpIC8gbXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAodG8yLl8uZHkgLSBfLmR5KSAvIG1zXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcImNzdlwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBTdHIocGFyYW1zW2F0dHJdKVtzcGxpdF0oc2VwYXJhdG9yKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbTIgPSBTdHIoZnJvbVthdHRyXSlbc3BsaXRdKHNlcGFyYXRvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHIgPT0gXCJjbGlwLXJlY3RcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tW2F0dHJdID0gZnJvbTI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZbYXR0cl0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA9IGZyb20yLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlmZlthdHRyXVtpXSA9ICh2YWx1ZXNbaV0gLSBmcm9tW2F0dHJdW2ldKSAvIG1zO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvW2F0dHJdID0gdmFsdWVzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBbXVtjb25jYXRdKHBhcmFtc1thdHRyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbTIgPSBbXVtjb25jYXRdKGZyb21bYXR0cl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZbYXR0cl0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpID0gZWxlbWVudC5wYXBlci5jdXN0b21BdHRyaWJ1dGVzW2F0dHJdLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpZmZbYXR0cl1baV0gPSAoKHZhbHVlc1tpXSB8fCAwKSAtIChmcm9tMltpXSB8fCAwKSkgLyBtcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZWFzaW5nID0gcGFyYW1zLmVhc2luZyxcbiAgICAgICAgICAgICAgICBlYXN5ZWFzeSA9IFIuZWFzaW5nX2Zvcm11bGFzW2Vhc2luZ107XG4gICAgICAgICAgICBpZiAoIWVhc3llYXN5KSB7XG4gICAgICAgICAgICAgICAgZWFzeWVhc3kgPSBTdHIoZWFzaW5nKS5tYXRjaChiZXppZXJyZyk7XG4gICAgICAgICAgICAgICAgaWYgKGVhc3llYXN5ICYmIGVhc3llYXN5Lmxlbmd0aCA9PSA1KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJ2ZSA9IGVhc3llYXN5O1xuICAgICAgICAgICAgICAgICAgICBlYXN5ZWFzeSA9IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gQ3ViaWNCZXppZXJBdFRpbWUodCwgK2N1cnZlWzFdLCArY3VydmVbMl0sICtjdXJ2ZVszXSwgK2N1cnZlWzRdLCBtcyk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZWFzeWVhc3kgPSBwaXBlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRpbWVzdGFtcCA9IHBhcmFtcy5zdGFydCB8fCBhbmltLnN0YXJ0IHx8ICtuZXcgRGF0ZTtcbiAgICAgICAgICAgIGUgPSB7XG4gICAgICAgICAgICAgICAgYW5pbTogYW5pbSxcbiAgICAgICAgICAgICAgICBwZXJjZW50OiBwZXJjZW50LFxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogdGltZXN0YW1wLFxuICAgICAgICAgICAgICAgIHN0YXJ0OiB0aW1lc3RhbXAgKyAoYW5pbS5kZWwgfHwgMCksXG4gICAgICAgICAgICAgICAgc3RhdHVzOiAwLFxuICAgICAgICAgICAgICAgIGluaXRzdGF0dXM6IHN0YXR1cyB8fCAwLFxuICAgICAgICAgICAgICAgIHN0b3A6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1zOiBtcyxcbiAgICAgICAgICAgICAgICBlYXNpbmc6IGVhc3llYXN5LFxuICAgICAgICAgICAgICAgIGZyb206IGZyb20sXG4gICAgICAgICAgICAgICAgZGlmZjogZGlmZixcbiAgICAgICAgICAgICAgICB0bzogdG8sXG4gICAgICAgICAgICAgICAgZWw6IGVsZW1lbnQsXG4gICAgICAgICAgICAgICAgY2FsbGJhY2s6IHBhcmFtcy5jYWxsYmFjayxcbiAgICAgICAgICAgICAgICBwcmV2OiBwcmV2LFxuICAgICAgICAgICAgICAgIG5leHQ6IG5leHQsXG4gICAgICAgICAgICAgICAgcmVwZWF0OiB0aW1lcyB8fCBhbmltLnRpbWVzLFxuICAgICAgICAgICAgICAgIG9yaWdpbjogZWxlbWVudC5hdHRyKCksXG4gICAgICAgICAgICAgICAgdG90YWxPcmlnaW46IHRvdGFsT3JpZ2luXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgYW5pbWF0aW9uRWxlbWVudHMucHVzaChlKTtcbiAgICAgICAgICAgIGlmIChzdGF0dXMgJiYgIWlzSW5BbmltICYmICFpc0luQW5pbVNldCkge1xuICAgICAgICAgICAgICAgIGUuc3RvcCA9IHRydWU7XG4gICAgICAgICAgICAgICAgZS5zdGFydCA9IG5ldyBEYXRlIC0gbXMgKiBzdGF0dXM7XG4gICAgICAgICAgICAgICAgaWYgKGFuaW1hdGlvbkVsZW1lbnRzLmxlbmd0aCA9PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhbmltYXRpb24oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNJbkFuaW1TZXQpIHtcbiAgICAgICAgICAgICAgICBlLnN0YXJ0ID0gbmV3IERhdGUgLSBlLm1zICogc3RhdHVzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYW5pbWF0aW9uRWxlbWVudHMubGVuZ3RoID09IDEgJiYgcmVxdWVzdEFuaW1GcmFtZShhbmltYXRpb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaXNJbkFuaW0uaW5pdHN0YXR1cyA9IHN0YXR1cztcbiAgICAgICAgICAgIGlzSW5BbmltLnN0YXJ0ID0gbmV3IERhdGUgLSBpc0luQW5pbS5tcyAqIHN0YXR1cztcbiAgICAgICAgfVxuICAgICAgICBldmUoXCJyYXBoYWVsLmFuaW0uc3RhcnQuXCIgKyBlbGVtZW50LmlkLCBlbGVtZW50LCBhbmltKTtcbiAgICB9XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuYW5pbWF0aW9uXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBDcmVhdGVzIGFuIGFuaW1hdGlvbiBvYmplY3QgdGhhdCBjYW4gYmUgcGFzc2VkIHRvIHRoZSBARWxlbWVudC5hbmltYXRlIG9yIEBFbGVtZW50LmFuaW1hdGVXaXRoIG1ldGhvZHMuXG4gICAgICogU2VlIGFsc28gQEFuaW1hdGlvbi5kZWxheSBhbmQgQEFuaW1hdGlvbi5yZXBlYXQgbWV0aG9kcy5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gcGFyYW1zIChvYmplY3QpIGZpbmFsIGF0dHJpYnV0ZXMgZm9yIHRoZSBlbGVtZW50LCBzZWUgYWxzbyBARWxlbWVudC5hdHRyXG4gICAgIC0gbXMgKG51bWJlcikgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBmb3IgYW5pbWF0aW9uIHRvIHJ1blxuICAgICAtIGVhc2luZyAoc3RyaW5nKSAjb3B0aW9uYWwgZWFzaW5nIHR5cGUuIEFjY2VwdCBvbmUgb2YgQFJhcGhhZWwuZWFzaW5nX2Zvcm11bGFzIG9yIENTUyBmb3JtYXQ6IGBjdWJpYyYjeDIwMTA7YmV6aWVyKFhYLCYjMTYwO1hYLCYjMTYwO1hYLCYjMTYwO1hYKWBcbiAgICAgLSBjYWxsYmFjayAoZnVuY3Rpb24pICNvcHRpb25hbCBjYWxsYmFjayBmdW5jdGlvbi4gV2lsbCBiZSBjYWxsZWQgYXQgdGhlIGVuZCBvZiBhbmltYXRpb24uXG4gICAgICoqXG4gICAgID0gKG9iamVjdCkgQEFuaW1hdGlvblxuICAgIFxcKi9cbiAgICBSLmFuaW1hdGlvbiA9IGZ1bmN0aW9uIChwYXJhbXMsIG1zLCBlYXNpbmcsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmIChwYXJhbXMgaW5zdGFuY2VvZiBBbmltYXRpb24pIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJhbXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFIuaXMoZWFzaW5nLCBcImZ1bmN0aW9uXCIpIHx8ICFlYXNpbmcpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgZWFzaW5nIHx8IG51bGw7XG4gICAgICAgICAgICBlYXNpbmcgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHBhcmFtcyA9IE9iamVjdChwYXJhbXMpO1xuICAgICAgICBtcyA9ICttcyB8fCAwO1xuICAgICAgICB2YXIgcCA9IHt9LFxuICAgICAgICAgICAganNvbixcbiAgICAgICAgICAgIGF0dHI7XG4gICAgICAgIGZvciAoYXR0ciBpbiBwYXJhbXMpIGlmIChwYXJhbXNbaGFzXShhdHRyKSAmJiB0b0Zsb2F0KGF0dHIpICE9IGF0dHIgJiYgdG9GbG9hdChhdHRyKSArIFwiJVwiICE9IGF0dHIpIHtcbiAgICAgICAgICAgIGpzb24gPSB0cnVlO1xuICAgICAgICAgICAgcFthdHRyXSA9IHBhcmFtc1thdHRyXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWpzb24pIHtcbiAgICAgICAgICAgIC8vIGlmIHBlcmNlbnQtbGlrZSBzeW50YXggaXMgdXNlZCBhbmQgZW5kLW9mLWFsbCBhbmltYXRpb24gY2FsbGJhY2sgdXNlZFxuICAgICAgICAgICAgaWYoY2FsbGJhY2spe1xuICAgICAgICAgICAgICAgIC8vIGZpbmQgdGhlIGxhc3Qgb25lXG4gICAgICAgICAgICAgICAgdmFyIGxhc3RLZXkgPSAwO1xuICAgICAgICAgICAgICAgIGZvcih2YXIgaSBpbiBwYXJhbXMpe1xuICAgICAgICAgICAgICAgICAgICB2YXIgcGVyY2VudCA9IHRvSW50KGkpO1xuICAgICAgICAgICAgICAgICAgICBpZihwYXJhbXNbaGFzXShpKSAmJiBwZXJjZW50ID4gbGFzdEtleSl7XG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0S2V5ID0gcGVyY2VudDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsYXN0S2V5ICs9ICclJztcbiAgICAgICAgICAgICAgICAvLyBpZiBhbHJlYWR5IGRlZmluZWQgY2FsbGJhY2sgaW4gdGhlIGxhc3Qga2V5ZnJhbWUsIHNraXBcbiAgICAgICAgICAgICAgICAhcGFyYW1zW2xhc3RLZXldLmNhbGxiYWNrICYmIChwYXJhbXNbbGFzdEtleV0uY2FsbGJhY2sgPSBjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBBbmltYXRpb24ocGFyYW1zLCBtcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlYXNpbmcgJiYgKHAuZWFzaW5nID0gZWFzaW5nKTtcbiAgICAgICAgICAgIGNhbGxiYWNrICYmIChwLmNhbGxiYWNrID0gY2FsbGJhY2spO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBBbmltYXRpb24oezEwMDogcH0sIG1zKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuYW5pbWF0ZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQ3JlYXRlcyBhbmQgc3RhcnRzIGFuaW1hdGlvbiBmb3IgZ2l2ZW4gZWxlbWVudC5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gcGFyYW1zIChvYmplY3QpIGZpbmFsIGF0dHJpYnV0ZXMgZm9yIHRoZSBlbGVtZW50LCBzZWUgYWxzbyBARWxlbWVudC5hdHRyXG4gICAgIC0gbXMgKG51bWJlcikgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBmb3IgYW5pbWF0aW9uIHRvIHJ1blxuICAgICAtIGVhc2luZyAoc3RyaW5nKSAjb3B0aW9uYWwgZWFzaW5nIHR5cGUuIEFjY2VwdCBvbmUgb2YgQFJhcGhhZWwuZWFzaW5nX2Zvcm11bGFzIG9yIENTUyBmb3JtYXQ6IGBjdWJpYyYjeDIwMTA7YmV6aWVyKFhYLCYjMTYwO1hYLCYjMTYwO1hYLCYjMTYwO1hYKWBcbiAgICAgLSBjYWxsYmFjayAoZnVuY3Rpb24pICNvcHRpb25hbCBjYWxsYmFjayBmdW5jdGlvbi4gV2lsbCBiZSBjYWxsZWQgYXQgdGhlIGVuZCBvZiBhbmltYXRpb24uXG4gICAgICogb3JcbiAgICAgLSBhbmltYXRpb24gKG9iamVjdCkgYW5pbWF0aW9uIG9iamVjdCwgc2VlIEBSYXBoYWVsLmFuaW1hdGlvblxuICAgICAqKlxuICAgICA9IChvYmplY3QpIG9yaWdpbmFsIGVsZW1lbnRcbiAgICBcXCovXG4gICAgZWxwcm90by5hbmltYXRlID0gZnVuY3Rpb24gKHBhcmFtcywgbXMsIGVhc2luZywgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIGVsZW1lbnQgPSB0aGlzO1xuICAgICAgICBpZiAoZWxlbWVudC5yZW1vdmVkKSB7XG4gICAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjay5jYWxsKGVsZW1lbnQpO1xuICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGFuaW0gPSBwYXJhbXMgaW5zdGFuY2VvZiBBbmltYXRpb24gPyBwYXJhbXMgOiBSLmFuaW1hdGlvbihwYXJhbXMsIG1zLCBlYXNpbmcsIGNhbGxiYWNrKTtcbiAgICAgICAgcnVuQW5pbWF0aW9uKGFuaW0sIGVsZW1lbnQsIGFuaW0ucGVyY2VudHNbMF0sIG51bGwsIGVsZW1lbnQuYXR0cigpKTtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5zZXRUaW1lXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBTZXRzIHRoZSBzdGF0dXMgb2YgYW5pbWF0aW9uIG9mIHRoZSBlbGVtZW50IGluIG1pbGxpc2Vjb25kcy4gU2ltaWxhciB0byBARWxlbWVudC5zdGF0dXMgbWV0aG9kLlxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSBhbmltIChvYmplY3QpIGFuaW1hdGlvbiBvYmplY3RcbiAgICAgLSB2YWx1ZSAobnVtYmVyKSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgYW5pbWF0aW9uXG4gICAgICoqXG4gICAgID0gKG9iamVjdCkgb3JpZ2luYWwgZWxlbWVudCBpZiBgdmFsdWVgIGlzIHNwZWNpZmllZFxuICAgICAqIE5vdGUsIHRoYXQgZHVyaW5nIGFuaW1hdGlvbiBmb2xsb3dpbmcgZXZlbnRzIGFyZSB0cmlnZ2VyZWQ6XG4gICAgICpcbiAgICAgKiBPbiBlYWNoIGFuaW1hdGlvbiBmcmFtZSBldmVudCBgYW5pbS5mcmFtZS48aWQ+YCwgb24gc3RhcnQgYGFuaW0uc3RhcnQuPGlkPmAgYW5kIG9uIGVuZCBgYW5pbS5maW5pc2guPGlkPmAuXG4gICAgXFwqL1xuICAgIGVscHJvdG8uc2V0VGltZSA9IGZ1bmN0aW9uIChhbmltLCB2YWx1ZSkge1xuICAgICAgICBpZiAoYW5pbSAmJiB2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXR1cyhhbmltLCBtbWluKHZhbHVlLCBhbmltLm1zKSAvIGFuaW0ubXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuc3RhdHVzXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBHZXRzIG9yIHNldHMgdGhlIHN0YXR1cyBvZiBhbmltYXRpb24gb2YgdGhlIGVsZW1lbnQuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGFuaW0gKG9iamVjdCkgI29wdGlvbmFsIGFuaW1hdGlvbiBvYmplY3RcbiAgICAgLSB2YWx1ZSAobnVtYmVyKSAjb3B0aW9uYWwgMCDigJMgMS4gSWYgc3BlY2lmaWVkLCBtZXRob2Qgd29ya3MgbGlrZSBhIHNldHRlciBhbmQgc2V0cyB0aGUgc3RhdHVzIG9mIGEgZ2l2ZW4gYW5pbWF0aW9uIHRvIHRoZSB2YWx1ZS4gVGhpcyB3aWxsIGNhdXNlIGFuaW1hdGlvbiB0byBqdW1wIHRvIHRoZSBnaXZlbiBwb3NpdGlvbi5cbiAgICAgKipcbiAgICAgPSAobnVtYmVyKSBzdGF0dXNcbiAgICAgKiBvclxuICAgICA9IChhcnJheSkgc3RhdHVzIGlmIGBhbmltYCBpcyBub3Qgc3BlY2lmaWVkLiBBcnJheSBvZiBvYmplY3RzIGluIGZvcm1hdDpcbiAgICAgbyB7XG4gICAgIG8gICAgIGFuaW06IChvYmplY3QpIGFuaW1hdGlvbiBvYmplY3RcbiAgICAgbyAgICAgc3RhdHVzOiAobnVtYmVyKSBzdGF0dXNcbiAgICAgbyB9XG4gICAgICogb3JcbiAgICAgPSAob2JqZWN0KSBvcmlnaW5hbCBlbGVtZW50IGlmIGB2YWx1ZWAgaXMgc3BlY2lmaWVkXG4gICAgXFwqL1xuICAgIGVscHJvdG8uc3RhdHVzID0gZnVuY3Rpb24gKGFuaW0sIHZhbHVlKSB7XG4gICAgICAgIHZhciBvdXQgPSBbXSxcbiAgICAgICAgICAgIGkgPSAwLFxuICAgICAgICAgICAgbGVuLFxuICAgICAgICAgICAgZTtcbiAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJ1bkFuaW1hdGlvbihhbmltLCB0aGlzLCAtMSwgbW1pbih2YWx1ZSwgMSkpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZW4gPSBhbmltYXRpb25FbGVtZW50cy5sZW5ndGg7XG4gICAgICAgICAgICBmb3IgKDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgZSA9IGFuaW1hdGlvbkVsZW1lbnRzW2ldO1xuICAgICAgICAgICAgICAgIGlmIChlLmVsLmlkID09IHRoaXMuaWQgJiYgKCFhbmltIHx8IGUuYW5pbSA9PSBhbmltKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYW5pbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGUuc3RhdHVzO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG91dC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuaW06IGUuYW5pbSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1czogZS5zdGF0dXNcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGFuaW0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBvdXQ7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnBhdXNlXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBTdG9wcyBhbmltYXRpb24gb2YgdGhlIGVsZW1lbnQgd2l0aCBhYmlsaXR5IHRvIHJlc3VtZSBpdCBsYXRlciBvbi5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gYW5pbSAob2JqZWN0KSAjb3B0aW9uYWwgYW5pbWF0aW9uIG9iamVjdFxuICAgICAqKlxuICAgICA9IChvYmplY3QpIG9yaWdpbmFsIGVsZW1lbnRcbiAgICBcXCovXG4gICAgZWxwcm90by5wYXVzZSA9IGZ1bmN0aW9uIChhbmltKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYW5pbWF0aW9uRWxlbWVudHMubGVuZ3RoOyBpKyspIGlmIChhbmltYXRpb25FbGVtZW50c1tpXS5lbC5pZCA9PSB0aGlzLmlkICYmICghYW5pbSB8fCBhbmltYXRpb25FbGVtZW50c1tpXS5hbmltID09IGFuaW0pKSB7XG4gICAgICAgICAgICBpZiAoZXZlKFwicmFwaGFlbC5hbmltLnBhdXNlLlwiICsgdGhpcy5pZCwgdGhpcywgYW5pbWF0aW9uRWxlbWVudHNbaV0uYW5pbSkgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uRWxlbWVudHNbaV0ucGF1c2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnJlc3VtZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVzdW1lcyBhbmltYXRpb24gaWYgaXQgd2FzIHBhdXNlZCB3aXRoIEBFbGVtZW50LnBhdXNlIG1ldGhvZC5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gYW5pbSAob2JqZWN0KSAjb3B0aW9uYWwgYW5pbWF0aW9uIG9iamVjdFxuICAgICAqKlxuICAgICA9IChvYmplY3QpIG9yaWdpbmFsIGVsZW1lbnRcbiAgICBcXCovXG4gICAgZWxwcm90by5yZXN1bWUgPSBmdW5jdGlvbiAoYW5pbSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFuaW1hdGlvbkVsZW1lbnRzLmxlbmd0aDsgaSsrKSBpZiAoYW5pbWF0aW9uRWxlbWVudHNbaV0uZWwuaWQgPT0gdGhpcy5pZCAmJiAoIWFuaW0gfHwgYW5pbWF0aW9uRWxlbWVudHNbaV0uYW5pbSA9PSBhbmltKSkge1xuICAgICAgICAgICAgdmFyIGUgPSBhbmltYXRpb25FbGVtZW50c1tpXTtcbiAgICAgICAgICAgIGlmIChldmUoXCJyYXBoYWVsLmFuaW0ucmVzdW1lLlwiICsgdGhpcy5pZCwgdGhpcywgZS5hbmltKSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgZS5wYXVzZWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0dXMoZS5hbmltLCBlLnN0YXR1cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5zdG9wXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBTdG9wcyBhbmltYXRpb24gb2YgdGhlIGVsZW1lbnQuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGFuaW0gKG9iamVjdCkgI29wdGlvbmFsIGFuaW1hdGlvbiBvYmplY3RcbiAgICAgKipcbiAgICAgPSAob2JqZWN0KSBvcmlnaW5hbCBlbGVtZW50XG4gICAgXFwqL1xuICAgIGVscHJvdG8uc3RvcCA9IGZ1bmN0aW9uIChhbmltKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYW5pbWF0aW9uRWxlbWVudHMubGVuZ3RoOyBpKyspIGlmIChhbmltYXRpb25FbGVtZW50c1tpXS5lbC5pZCA9PSB0aGlzLmlkICYmICghYW5pbSB8fCBhbmltYXRpb25FbGVtZW50c1tpXS5hbmltID09IGFuaW0pKSB7XG4gICAgICAgICAgICBpZiAoZXZlKFwicmFwaGFlbC5hbmltLnN0b3AuXCIgKyB0aGlzLmlkLCB0aGlzLCBhbmltYXRpb25FbGVtZW50c1tpXS5hbmltKSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBhbmltYXRpb25FbGVtZW50cy5zcGxpY2UoaS0tLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIGZ1bmN0aW9uIHN0b3BBbmltYXRpb24ocGFwZXIpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhbmltYXRpb25FbGVtZW50cy5sZW5ndGg7IGkrKykgaWYgKGFuaW1hdGlvbkVsZW1lbnRzW2ldLmVsLnBhcGVyID09IHBhcGVyKSB7XG4gICAgICAgICAgICBhbmltYXRpb25FbGVtZW50cy5zcGxpY2UoaS0tLCAxKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBldmUub24oXCJyYXBoYWVsLnJlbW92ZVwiLCBzdG9wQW5pbWF0aW9uKTtcbiAgICBldmUub24oXCJyYXBoYWVsLmNsZWFyXCIsIHN0b3BBbmltYXRpb24pO1xuICAgIGVscHJvdG8udG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBcIlJhcGhhXFx4ZWJsXFx1MjAxOXMgb2JqZWN0XCI7XG4gICAgfTtcblxuICAgIC8vIFNldFxuICAgIHZhciBTZXQgPSBmdW5jdGlvbiAoaXRlbXMpIHtcbiAgICAgICAgdGhpcy5pdGVtcyA9IFtdO1xuICAgICAgICB0aGlzLmxlbmd0aCA9IDA7XG4gICAgICAgIHRoaXMudHlwZSA9IFwic2V0XCI7XG4gICAgICAgIGlmIChpdGVtcykge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gaXRlbXMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChpdGVtc1tpXSAmJiAoaXRlbXNbaV0uY29uc3RydWN0b3IgPT0gZWxwcm90by5jb25zdHJ1Y3RvciB8fCBpdGVtc1tpXS5jb25zdHJ1Y3RvciA9PSBTZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNbdGhpcy5pdGVtcy5sZW5ndGhdID0gdGhpcy5pdGVtc1t0aGlzLml0ZW1zLmxlbmd0aF0gPSBpdGVtc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sZW5ndGgrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIHNldHByb3RvID0gU2V0LnByb3RvdHlwZTtcbiAgICAvKlxcXG4gICAgICogU2V0LnB1c2hcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEFkZHMgZWFjaCBhcmd1bWVudCB0byB0aGUgY3VycmVudCBzZXQuXG4gICAgID0gKG9iamVjdCkgb3JpZ2luYWwgZWxlbWVudFxuICAgIFxcKi9cbiAgICBzZXRwcm90by5wdXNoID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgaXRlbSxcbiAgICAgICAgICAgIGxlbjtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgIGl0ZW0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgICAgICBpZiAoaXRlbSAmJiAoaXRlbS5jb25zdHJ1Y3RvciA9PSBlbHByb3RvLmNvbnN0cnVjdG9yIHx8IGl0ZW0uY29uc3RydWN0b3IgPT0gU2V0KSkge1xuICAgICAgICAgICAgICAgIGxlbiA9IHRoaXMuaXRlbXMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIHRoaXNbbGVuXSA9IHRoaXMuaXRlbXNbbGVuXSA9IGl0ZW07XG4gICAgICAgICAgICAgICAgdGhpcy5sZW5ndGgrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBTZXQucG9wXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZW1vdmVzIGxhc3QgZWxlbWVudCBhbmQgcmV0dXJucyBpdC5cbiAgICAgPSAob2JqZWN0KSBlbGVtZW50XG4gICAgXFwqL1xuICAgIHNldHByb3RvLnBvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5sZW5ndGggJiYgZGVsZXRlIHRoaXNbdGhpcy5sZW5ndGgtLV07XG4gICAgICAgIHJldHVybiB0aGlzLml0ZW1zLnBvcCgpO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFNldC5mb3JFYWNoXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBFeGVjdXRlcyBnaXZlbiBmdW5jdGlvbiBmb3IgZWFjaCBlbGVtZW50IGluIHRoZSBzZXQuXG4gICAgICpcbiAgICAgKiBJZiBmdW5jdGlvbiByZXR1cm5zIGBmYWxzZWAgaXQgd2lsbCBzdG9wIGxvb3AgcnVubmluZy5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gY2FsbGJhY2sgKGZ1bmN0aW9uKSBmdW5jdGlvbiB0byBydW5cbiAgICAgLSB0aGlzQXJnIChvYmplY3QpIGNvbnRleHQgb2JqZWN0IGZvciB0aGUgY2FsbGJhY2tcbiAgICAgPSAob2JqZWN0KSBTZXQgb2JqZWN0XG4gICAgXFwqL1xuICAgIHNldHByb3RvLmZvckVhY2ggPSBmdW5jdGlvbiAoY2FsbGJhY2ssIHRoaXNBcmcpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gdGhpcy5pdGVtcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB0aGlzLml0ZW1zW2ldLCBpKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIGZvciAodmFyIG1ldGhvZCBpbiBlbHByb3RvKSBpZiAoZWxwcm90b1toYXNdKG1ldGhvZCkpIHtcbiAgICAgICAgc2V0cHJvdG9bbWV0aG9kXSA9IChmdW5jdGlvbiAobWV0aG9kbmFtZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXJnID0gYXJndW1lbnRzO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsW21ldGhvZG5hbWVdW2FwcGx5XShlbCwgYXJnKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKG1ldGhvZCk7XG4gICAgfVxuICAgIHNldHByb3RvLmF0dHIgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKG5hbWUgJiYgUi5pcyhuYW1lLCBhcnJheSkgJiYgUi5pcyhuYW1lWzBdLCBcIm9iamVjdFwiKSkge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGpqID0gbmFtZS5sZW5ndGg7IGogPCBqajsgaisrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pdGVtc1tqXS5hdHRyKG5hbWVbal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gdGhpcy5pdGVtcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pdGVtc1tpXS5hdHRyKG5hbWUsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBTZXQuY2xlYXJcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20gdGhlIHNldFxuICAgIFxcKi9cbiAgICBzZXRwcm90by5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2hpbGUgKHRoaXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLnBvcCgpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogU2V0LnNwbGljZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVtb3ZlcyBnaXZlbiBlbGVtZW50IGZyb20gdGhlIHNldFxuICAgICAqKlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgKipcbiAgICAgLSBpbmRleCAobnVtYmVyKSBwb3NpdGlvbiBvZiB0aGUgZGVsZXRpb25cbiAgICAgLSBjb3VudCAobnVtYmVyKSBudW1iZXIgb2YgZWxlbWVudCB0byByZW1vdmVcbiAgICAgLSBpbnNlcnRpb27igKYgKG9iamVjdCkgI29wdGlvbmFsIGVsZW1lbnRzIHRvIGluc2VydFxuICAgICA9IChvYmplY3QpIHNldCBlbGVtZW50cyB0aGF0IHdlcmUgZGVsZXRlZFxuICAgIFxcKi9cbiAgICBzZXRwcm90by5zcGxpY2UgPSBmdW5jdGlvbiAoaW5kZXgsIGNvdW50LCBpbnNlcnRpb24pIHtcbiAgICAgICAgaW5kZXggPSBpbmRleCA8IDAgPyBtbWF4KHRoaXMubGVuZ3RoICsgaW5kZXgsIDApIDogaW5kZXg7XG4gICAgICAgIGNvdW50ID0gbW1heCgwLCBtbWluKHRoaXMubGVuZ3RoIC0gaW5kZXgsIGNvdW50KSk7XG4gICAgICAgIHZhciB0YWlsID0gW10sXG4gICAgICAgICAgICB0b2RlbCA9IFtdLFxuICAgICAgICAgICAgYXJncyA9IFtdLFxuICAgICAgICAgICAgaTtcbiAgICAgICAgZm9yIChpID0gMjsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJncy5wdXNoKGFyZ3VtZW50c1tpXSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgIHRvZGVsLnB1c2godGhpc1tpbmRleCArIGldKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKDsgaSA8IHRoaXMubGVuZ3RoIC0gaW5kZXg7IGkrKykge1xuICAgICAgICAgICAgdGFpbC5wdXNoKHRoaXNbaW5kZXggKyBpXSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGFyZ2xlbiA9IGFyZ3MubGVuZ3RoO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYXJnbGVuICsgdGFpbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdGhpcy5pdGVtc1tpbmRleCArIGldID0gdGhpc1tpbmRleCArIGldID0gaSA8IGFyZ2xlbiA/IGFyZ3NbaV0gOiB0YWlsW2kgLSBhcmdsZW5dO1xuICAgICAgICB9XG4gICAgICAgIGkgPSB0aGlzLml0ZW1zLmxlbmd0aCA9IHRoaXMubGVuZ3RoIC09IGNvdW50IC0gYXJnbGVuO1xuICAgICAgICB3aGlsZSAodGhpc1tpXSkge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXNbaSsrXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFNldCh0b2RlbCk7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogU2V0LmV4Y2x1ZGVcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZ2l2ZW4gZWxlbWVudCBmcm9tIHRoZSBzZXRcbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gZWxlbWVudCAob2JqZWN0KSBlbGVtZW50IHRvIHJlbW92ZVxuICAgICA9IChib29sZWFuKSBgdHJ1ZWAgaWYgb2JqZWN0IHdhcyBmb3VuZCAmIHJlbW92ZWQgZnJvbSB0aGUgc2V0XG4gICAgXFwqL1xuICAgIHNldHByb3RvLmV4Y2x1ZGUgPSBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gdGhpcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSBpZiAodGhpc1tpXSA9PSBlbCkge1xuICAgICAgICAgICAgdGhpcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgc2V0cHJvdG8uYW5pbWF0ZSA9IGZ1bmN0aW9uIChwYXJhbXMsIG1zLCBlYXNpbmcsIGNhbGxiYWNrKSB7XG4gICAgICAgIChSLmlzKGVhc2luZywgXCJmdW5jdGlvblwiKSB8fCAhZWFzaW5nKSAmJiAoY2FsbGJhY2sgPSBlYXNpbmcgfHwgbnVsbCk7XG4gICAgICAgIHZhciBsZW4gPSB0aGlzLml0ZW1zLmxlbmd0aCxcbiAgICAgICAgICAgIGkgPSBsZW4sXG4gICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgc2V0ID0gdGhpcyxcbiAgICAgICAgICAgIGNvbGxlY3RvcjtcbiAgICAgICAgaWYgKCFsZW4pIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIGNhbGxiYWNrICYmIChjb2xsZWN0b3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAhLS1sZW4gJiYgY2FsbGJhY2suY2FsbChzZXQpO1xuICAgICAgICB9KTtcbiAgICAgICAgZWFzaW5nID0gUi5pcyhlYXNpbmcsIHN0cmluZykgPyBlYXNpbmcgOiBjb2xsZWN0b3I7XG4gICAgICAgIHZhciBhbmltID0gUi5hbmltYXRpb24ocGFyYW1zLCBtcywgZWFzaW5nLCBjb2xsZWN0b3IpO1xuICAgICAgICBpdGVtID0gdGhpcy5pdGVtc1stLWldLmFuaW1hdGUoYW5pbSk7XG4gICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgIHRoaXMuaXRlbXNbaV0gJiYgIXRoaXMuaXRlbXNbaV0ucmVtb3ZlZCAmJiB0aGlzLml0ZW1zW2ldLmFuaW1hdGVXaXRoKGl0ZW0sIGFuaW0sIGFuaW0pO1xuICAgICAgICAgICAgKHRoaXMuaXRlbXNbaV0gJiYgIXRoaXMuaXRlbXNbaV0ucmVtb3ZlZCkgfHwgbGVuLS07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBzZXRwcm90by5pbnNlcnRBZnRlciA9IGZ1bmN0aW9uIChlbCkge1xuICAgICAgICB2YXIgaSA9IHRoaXMuaXRlbXMubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICB0aGlzLml0ZW1zW2ldLmluc2VydEFmdGVyKGVsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIHNldHByb3RvLmdldEJCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB4ID0gW10sXG4gICAgICAgICAgICB5ID0gW10sXG4gICAgICAgICAgICB4MiA9IFtdLFxuICAgICAgICAgICAgeTIgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IHRoaXMuaXRlbXMubGVuZ3RoOyBpLS07KSBpZiAoIXRoaXMuaXRlbXNbaV0ucmVtb3ZlZCkge1xuICAgICAgICAgICAgdmFyIGJveCA9IHRoaXMuaXRlbXNbaV0uZ2V0QkJveCgpO1xuICAgICAgICAgICAgeC5wdXNoKGJveC54KTtcbiAgICAgICAgICAgIHkucHVzaChib3gueSk7XG4gICAgICAgICAgICB4Mi5wdXNoKGJveC54ICsgYm94LndpZHRoKTtcbiAgICAgICAgICAgIHkyLnB1c2goYm94LnkgKyBib3guaGVpZ2h0KTtcbiAgICAgICAgfVxuICAgICAgICB4ID0gbW1pblthcHBseV0oMCwgeCk7XG4gICAgICAgIHkgPSBtbWluW2FwcGx5XSgwLCB5KTtcbiAgICAgICAgeDIgPSBtbWF4W2FwcGx5XSgwLCB4Mik7XG4gICAgICAgIHkyID0gbW1heFthcHBseV0oMCwgeTIpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgIHk6IHksXG4gICAgICAgICAgICB4MjogeDIsXG4gICAgICAgICAgICB5MjogeTIsXG4gICAgICAgICAgICB3aWR0aDogeDIgLSB4LFxuICAgICAgICAgICAgaGVpZ2h0OiB5MiAtIHlcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHNldHByb3RvLmNsb25lID0gZnVuY3Rpb24gKHMpIHtcbiAgICAgICAgcyA9IHRoaXMucGFwZXIuc2V0KCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRoaXMuaXRlbXMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgcy5wdXNoKHRoaXMuaXRlbXNbaV0uY2xvbmUoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHM7XG4gICAgfTtcbiAgICBzZXRwcm90by50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFwiUmFwaGFcXHhlYmxcXHUyMDE4cyBzZXRcIjtcbiAgICB9O1xuXG4gICAgc2V0cHJvdG8uZ2xvdyA9IGZ1bmN0aW9uKGdsb3dDb25maWcpIHtcbiAgICAgICAgdmFyIHJldCA9IHRoaXMucGFwZXIuc2V0KCk7XG4gICAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbihzaGFwZSwgaW5kZXgpe1xuICAgICAgICAgICAgdmFyIGcgPSBzaGFwZS5nbG93KGdsb3dDb25maWcpO1xuICAgICAgICAgICAgaWYoZyAhPSBudWxsKXtcbiAgICAgICAgICAgICAgICBnLmZvckVhY2goZnVuY3Rpb24oc2hhcGUyLCBpbmRleDIpe1xuICAgICAgICAgICAgICAgICAgICByZXQucHVzaChzaGFwZTIpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9O1xuXG5cbiAgICAvKlxcXG4gICAgICogU2V0LmlzUG9pbnRJbnNpZGVcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIERldGVybWluZSBpZiBnaXZlbiBwb2ludCBpcyBpbnNpZGUgdGhpcyBzZXTigJlzIGVsZW1lbnRzXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIHggKG51bWJlcikgeCBjb29yZGluYXRlIG9mIHRoZSBwb2ludFxuICAgICAtIHkgKG51bWJlcikgeSBjb29yZGluYXRlIG9mIHRoZSBwb2ludFxuICAgICA9IChib29sZWFuKSBgdHJ1ZWAgaWYgcG9pbnQgaXMgaW5zaWRlIGFueSBvZiB0aGUgc2V0J3MgZWxlbWVudHNcbiAgICAgXFwqL1xuICAgIHNldHByb3RvLmlzUG9pbnRJbnNpZGUgPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICB2YXIgaXNQb2ludEluc2lkZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsKSB7XG4gICAgICAgICAgICBpZiAoZWwuaXNQb2ludEluc2lkZSh4LCB5KSkge1xuICAgICAgICAgICAgICAgIGlzUG9pbnRJbnNpZGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gc3RvcCBsb29wXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gaXNQb2ludEluc2lkZTtcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwucmVnaXN0ZXJGb250XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBBZGRzIGdpdmVuIGZvbnQgdG8gdGhlIHJlZ2lzdGVyZWQgc2V0IG9mIGZvbnRzIGZvciBSYXBoYcOrbC4gU2hvdWxkIGJlIHVzZWQgYXMgYW4gaW50ZXJuYWwgY2FsbCBmcm9tIHdpdGhpbiBDdWbDs27igJlzIGZvbnQgZmlsZS5cbiAgICAgKiBSZXR1cm5zIG9yaWdpbmFsIHBhcmFtZXRlciwgc28gaXQgY291bGQgYmUgdXNlZCB3aXRoIGNoYWluaW5nLlxuICAgICAjIDxhIGhyZWY9XCJodHRwOi8vd2lraS5naXRodWIuY29tL3NvcmNjdS9jdWZvbi9hYm91dFwiPk1vcmUgYWJvdXQgQ3Vmw7NuIGFuZCBob3cgdG8gY29udmVydCB5b3VyIGZvbnQgZm9ybSBUVEYsIE9URiwgZXRjIHRvIEphdmFTY3JpcHQgZmlsZS48L2E+XG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIGZvbnQgKG9iamVjdCkgdGhlIGZvbnQgdG8gcmVnaXN0ZXJcbiAgICAgPSAob2JqZWN0KSB0aGUgZm9udCB5b3UgcGFzc2VkIGluXG4gICAgID4gVXNhZ2VcbiAgICAgfCBDdWZvbi5yZWdpc3RlckZvbnQoUmFwaGFlbC5yZWdpc3RlckZvbnQoe+KApn0pKTtcbiAgICBcXCovXG4gICAgUi5yZWdpc3RlckZvbnQgPSBmdW5jdGlvbiAoZm9udCkge1xuICAgICAgICBpZiAoIWZvbnQuZmFjZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZvbnQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mb250cyA9IHRoaXMuZm9udHMgfHwge307XG4gICAgICAgIHZhciBmb250Y29weSA9IHtcbiAgICAgICAgICAgICAgICB3OiBmb250LncsXG4gICAgICAgICAgICAgICAgZmFjZToge30sXG4gICAgICAgICAgICAgICAgZ2x5cGhzOiB7fVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGZhbWlseSA9IGZvbnQuZmFjZVtcImZvbnQtZmFtaWx5XCJdO1xuICAgICAgICBmb3IgKHZhciBwcm9wIGluIGZvbnQuZmFjZSkgaWYgKGZvbnQuZmFjZVtoYXNdKHByb3ApKSB7XG4gICAgICAgICAgICBmb250Y29weS5mYWNlW3Byb3BdID0gZm9udC5mYWNlW3Byb3BdO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmZvbnRzW2ZhbWlseV0pIHtcbiAgICAgICAgICAgIHRoaXMuZm9udHNbZmFtaWx5XS5wdXNoKGZvbnRjb3B5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZm9udHNbZmFtaWx5XSA9IFtmb250Y29weV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFmb250LnN2Zykge1xuICAgICAgICAgICAgZm9udGNvcHkuZmFjZVtcInVuaXRzLXBlci1lbVwiXSA9IHRvSW50KGZvbnQuZmFjZVtcInVuaXRzLXBlci1lbVwiXSwgMTApO1xuICAgICAgICAgICAgZm9yICh2YXIgZ2x5cGggaW4gZm9udC5nbHlwaHMpIGlmIChmb250LmdseXBoc1toYXNdKGdseXBoKSkge1xuICAgICAgICAgICAgICAgIHZhciBwYXRoID0gZm9udC5nbHlwaHNbZ2x5cGhdO1xuICAgICAgICAgICAgICAgIGZvbnRjb3B5LmdseXBoc1tnbHlwaF0gPSB7XG4gICAgICAgICAgICAgICAgICAgIHc6IHBhdGgudyxcbiAgICAgICAgICAgICAgICAgICAgazoge30sXG4gICAgICAgICAgICAgICAgICAgIGQ6IHBhdGguZCAmJiBcIk1cIiArIHBhdGguZC5yZXBsYWNlKC9bbWxjeHRydl0vZywgZnVuY3Rpb24gKGNvbW1hbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge2w6IFwiTFwiLCBjOiBcIkNcIiwgeDogXCJ6XCIsIHQ6IFwibVwiLCByOiBcImxcIiwgdjogXCJjXCJ9W2NvbW1hbmRdIHx8IFwiTVwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkgKyBcInpcIlxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKHBhdGguaykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBrIGluIHBhdGguaykgaWYgKHBhdGhbaGFzXShrKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9udGNvcHkuZ2x5cGhzW2dseXBoXS5rW2tdID0gcGF0aC5rW2tdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmb250O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFBhcGVyLmdldEZvbnRcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEZpbmRzIGZvbnQgb2JqZWN0IGluIHRoZSByZWdpc3RlcmVkIGZvbnRzIGJ5IGdpdmVuIHBhcmFtZXRlcnMuIFlvdSBjb3VsZCBzcGVjaWZ5IG9ubHkgb25lIHdvcmQgZnJvbSB0aGUgZm9udCBuYW1lLCBsaWtlIOKAnE15cmlhZOKAnSBmb3Ig4oCcTXlyaWFkIFByb+KAnS5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gZmFtaWx5IChzdHJpbmcpIGZvbnQgZmFtaWx5IG5hbWUgb3IgYW55IHdvcmQgZnJvbSBpdFxuICAgICAtIHdlaWdodCAoc3RyaW5nKSAjb3B0aW9uYWwgZm9udCB3ZWlnaHRcbiAgICAgLSBzdHlsZSAoc3RyaW5nKSAjb3B0aW9uYWwgZm9udCBzdHlsZVxuICAgICAtIHN0cmV0Y2ggKHN0cmluZykgI29wdGlvbmFsIGZvbnQgc3RyZXRjaFxuICAgICA9IChvYmplY3QpIHRoZSBmb250IG9iamVjdFxuICAgICA+IFVzYWdlXG4gICAgIHwgcGFwZXIucHJpbnQoMTAwLCAxMDAsIFwiVGVzdCBzdHJpbmdcIiwgcGFwZXIuZ2V0Rm9udChcIlRpbWVzXCIsIDgwMCksIDMwKTtcbiAgICBcXCovXG4gICAgcGFwZXJwcm90by5nZXRGb250ID0gZnVuY3Rpb24gKGZhbWlseSwgd2VpZ2h0LCBzdHlsZSwgc3RyZXRjaCkge1xuICAgICAgICBzdHJldGNoID0gc3RyZXRjaCB8fCBcIm5vcm1hbFwiO1xuICAgICAgICBzdHlsZSA9IHN0eWxlIHx8IFwibm9ybWFsXCI7XG4gICAgICAgIHdlaWdodCA9ICt3ZWlnaHQgfHwge25vcm1hbDogNDAwLCBib2xkOiA3MDAsIGxpZ2h0ZXI6IDMwMCwgYm9sZGVyOiA4MDB9W3dlaWdodF0gfHwgNDAwO1xuICAgICAgICBpZiAoIVIuZm9udHMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZm9udCA9IFIuZm9udHNbZmFtaWx5XTtcbiAgICAgICAgaWYgKCFmb250KSB7XG4gICAgICAgICAgICB2YXIgbmFtZSA9IG5ldyBSZWdFeHAoXCIoXnxcXFxccylcIiArIGZhbWlseS5yZXBsYWNlKC9bXlxcd1xcZFxccyshfi46Xy1dL2csIEUpICsgXCIoXFxcXHN8JClcIiwgXCJpXCIpO1xuICAgICAgICAgICAgZm9yICh2YXIgZm9udE5hbWUgaW4gUi5mb250cykgaWYgKFIuZm9udHNbaGFzXShmb250TmFtZSkpIHtcbiAgICAgICAgICAgICAgICBpZiAobmFtZS50ZXN0KGZvbnROYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICBmb250ID0gUi5mb250c1tmb250TmFtZV07XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgdGhlZm9udDtcbiAgICAgICAgaWYgKGZvbnQpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGZvbnQubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgIHRoZWZvbnQgPSBmb250W2ldO1xuICAgICAgICAgICAgICAgIGlmICh0aGVmb250LmZhY2VbXCJmb250LXdlaWdodFwiXSA9PSB3ZWlnaHQgJiYgKHRoZWZvbnQuZmFjZVtcImZvbnQtc3R5bGVcIl0gPT0gc3R5bGUgfHwgIXRoZWZvbnQuZmFjZVtcImZvbnQtc3R5bGVcIl0pICYmIHRoZWZvbnQuZmFjZVtcImZvbnQtc3RyZXRjaFwiXSA9PSBzdHJldGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhlZm9udDtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5wcmludFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQ3JlYXRlcyBwYXRoIHRoYXQgcmVwcmVzZW50IGdpdmVuIHRleHQgd3JpdHRlbiB1c2luZyBnaXZlbiBmb250IGF0IGdpdmVuIHBvc2l0aW9uIHdpdGggZ2l2ZW4gc2l6ZS5cbiAgICAgKiBSZXN1bHQgb2YgdGhlIG1ldGhvZCBpcyBwYXRoIGVsZW1lbnQgdGhhdCBjb250YWlucyB3aG9sZSB0ZXh0IGFzIGEgc2VwYXJhdGUgcGF0aC5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0geCAobnVtYmVyKSB4IHBvc2l0aW9uIG9mIHRoZSB0ZXh0XG4gICAgIC0geSAobnVtYmVyKSB5IHBvc2l0aW9uIG9mIHRoZSB0ZXh0XG4gICAgIC0gc3RyaW5nIChzdHJpbmcpIHRleHQgdG8gcHJpbnRcbiAgICAgLSBmb250IChvYmplY3QpIGZvbnQgb2JqZWN0LCBzZWUgQFBhcGVyLmdldEZvbnRcbiAgICAgLSBzaXplIChudW1iZXIpICNvcHRpb25hbCBzaXplIG9mIHRoZSBmb250LCBkZWZhdWx0IGlzIGAxNmBcbiAgICAgLSBvcmlnaW4gKHN0cmluZykgI29wdGlvbmFsIGNvdWxkIGJlIGBcImJhc2VsaW5lXCJgIG9yIGBcIm1pZGRsZVwiYCwgZGVmYXVsdCBpcyBgXCJtaWRkbGVcImBcbiAgICAgLSBsZXR0ZXJfc3BhY2luZyAobnVtYmVyKSAjb3B0aW9uYWwgbnVtYmVyIGluIHJhbmdlIGAtMS4uMWAsIGRlZmF1bHQgaXMgYDBgXG4gICAgIC0gbGluZV9zcGFjaW5nIChudW1iZXIpICNvcHRpb25hbCBudW1iZXIgaW4gcmFuZ2UgYDEuLjNgLCBkZWZhdWx0IGlzIGAxYFxuICAgICA9IChvYmplY3QpIHJlc3VsdGluZyBwYXRoIGVsZW1lbnQsIHdoaWNoIGNvbnNpc3Qgb2YgYWxsIGxldHRlcnNcbiAgICAgPiBVc2FnZVxuICAgICB8IHZhciB0eHQgPSByLnByaW50KDEwLCA1MCwgXCJwcmludFwiLCByLmdldEZvbnQoXCJNdXNlb1wiKSwgMzApLmF0dHIoe2ZpbGw6IFwiI2ZmZlwifSk7XG4gICAgXFwqL1xuICAgIHBhcGVycHJvdG8ucHJpbnQgPSBmdW5jdGlvbiAoeCwgeSwgc3RyaW5nLCBmb250LCBzaXplLCBvcmlnaW4sIGxldHRlcl9zcGFjaW5nLCBsaW5lX3NwYWNpbmcpIHtcbiAgICAgICAgb3JpZ2luID0gb3JpZ2luIHx8IFwibWlkZGxlXCI7IC8vIGJhc2VsaW5lfG1pZGRsZVxuICAgICAgICBsZXR0ZXJfc3BhY2luZyA9IG1tYXgobW1pbihsZXR0ZXJfc3BhY2luZyB8fCAwLCAxKSwgLTEpO1xuICAgICAgICBsaW5lX3NwYWNpbmcgPSBtbWF4KG1taW4obGluZV9zcGFjaW5nIHx8IDEsIDMpLCAxKTtcbiAgICAgICAgdmFyIGxldHRlcnMgPSBTdHIoc3RyaW5nKVtzcGxpdF0oRSksXG4gICAgICAgICAgICBzaGlmdCA9IDAsXG4gICAgICAgICAgICBub3RmaXJzdCA9IDAsXG4gICAgICAgICAgICBwYXRoID0gRSxcbiAgICAgICAgICAgIHNjYWxlO1xuICAgICAgICBSLmlzKGZvbnQsIFwic3RyaW5nXCIpICYmIChmb250ID0gdGhpcy5nZXRGb250KGZvbnQpKTtcbiAgICAgICAgaWYgKGZvbnQpIHtcbiAgICAgICAgICAgIHNjYWxlID0gKHNpemUgfHwgMTYpIC8gZm9udC5mYWNlW1widW5pdHMtcGVyLWVtXCJdO1xuICAgICAgICAgICAgdmFyIGJiID0gZm9udC5mYWNlLmJib3hbc3BsaXRdKHNlcGFyYXRvciksXG4gICAgICAgICAgICAgICAgdG9wID0gK2JiWzBdLFxuICAgICAgICAgICAgICAgIGxpbmVIZWlnaHQgPSBiYlszXSAtIGJiWzFdLFxuICAgICAgICAgICAgICAgIHNoaWZ0eSA9IDAsXG4gICAgICAgICAgICAgICAgaGVpZ2h0ID0gK2JiWzFdICsgKG9yaWdpbiA9PSBcImJhc2VsaW5lXCIgPyBsaW5lSGVpZ2h0ICsgKCtmb250LmZhY2UuZGVzY2VudCkgOiBsaW5lSGVpZ2h0IC8gMik7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBsZXR0ZXJzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAobGV0dGVyc1tpXSA9PSBcIlxcblwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHNoaWZ0ID0gMDtcbiAgICAgICAgICAgICAgICAgICAgY3VyciA9IDA7XG4gICAgICAgICAgICAgICAgICAgIG5vdGZpcnN0ID0gMDtcbiAgICAgICAgICAgICAgICAgICAgc2hpZnR5ICs9IGxpbmVIZWlnaHQgKiBsaW5lX3NwYWNpbmc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByZXYgPSBub3RmaXJzdCAmJiBmb250LmdseXBoc1tsZXR0ZXJzW2kgLSAxXV0gfHwge30sXG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyID0gZm9udC5nbHlwaHNbbGV0dGVyc1tpXV07XG4gICAgICAgICAgICAgICAgICAgIHNoaWZ0ICs9IG5vdGZpcnN0ID8gKHByZXYudyB8fCBmb250LncpICsgKHByZXYuayAmJiBwcmV2LmtbbGV0dGVyc1tpXV0gfHwgMCkgKyAoZm9udC53ICogbGV0dGVyX3NwYWNpbmcpIDogMDtcbiAgICAgICAgICAgICAgICAgICAgbm90Zmlyc3QgPSAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoY3VyciAmJiBjdXJyLmQpIHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aCArPSBSLnRyYW5zZm9ybVBhdGgoY3Vyci5kLCBbXCJ0XCIsIHNoaWZ0ICogc2NhbGUsIHNoaWZ0eSAqIHNjYWxlLCBcInNcIiwgc2NhbGUsIHNjYWxlLCB0b3AsIGhlaWdodCwgXCJ0XCIsICh4IC0gdG9wKSAvIHNjYWxlLCAoeSAtIGhlaWdodCkgLyBzY2FsZV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5wYXRoKHBhdGgpLmF0dHIoe1xuICAgICAgICAgICAgZmlsbDogXCIjMDAwXCIsXG4gICAgICAgICAgICBzdHJva2U6IFwibm9uZVwiXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKlxcXG4gICAgICogUGFwZXIuYWRkXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBJbXBvcnRzIGVsZW1lbnRzIGluIEpTT04gYXJyYXkgaW4gZm9ybWF0IGB7dHlwZTogdHlwZSwgPGF0dHJpYnV0ZXM+fWBcbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0ganNvbiAoYXJyYXkpXG4gICAgID0gKG9iamVjdCkgcmVzdWx0aW5nIHNldCBvZiBpbXBvcnRlZCBlbGVtZW50c1xuICAgICA+IFVzYWdlXG4gICAgIHwgcGFwZXIuYWRkKFtcbiAgICAgfCAgICAge1xuICAgICB8ICAgICAgICAgdHlwZTogXCJjaXJjbGVcIixcbiAgICAgfCAgICAgICAgIGN4OiAxMCxcbiAgICAgfCAgICAgICAgIGN5OiAxMCxcbiAgICAgfCAgICAgICAgIHI6IDVcbiAgICAgfCAgICAgfSxcbiAgICAgfCAgICAge1xuICAgICB8ICAgICAgICAgdHlwZTogXCJyZWN0XCIsXG4gICAgIHwgICAgICAgICB4OiAxMCxcbiAgICAgfCAgICAgICAgIHk6IDEwLFxuICAgICB8ICAgICAgICAgd2lkdGg6IDEwLFxuICAgICB8ICAgICAgICAgaGVpZ2h0OiAxMCxcbiAgICAgfCAgICAgICAgIGZpbGw6IFwiI2ZjMFwiXG4gICAgIHwgICAgIH1cbiAgICAgfCBdKTtcbiAgICBcXCovXG4gICAgcGFwZXJwcm90by5hZGQgPSBmdW5jdGlvbiAoanNvbikge1xuICAgICAgICBpZiAoUi5pcyhqc29uLCBcImFycmF5XCIpKSB7XG4gICAgICAgICAgICB2YXIgcmVzID0gdGhpcy5zZXQoKSxcbiAgICAgICAgICAgICAgICBpID0gMCxcbiAgICAgICAgICAgICAgICBpaSA9IGpzb24ubGVuZ3RoLFxuICAgICAgICAgICAgICAgIGo7XG4gICAgICAgICAgICBmb3IgKDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgICAgICBqID0ganNvbltpXSB8fCB7fTtcbiAgICAgICAgICAgICAgICBlbGVtZW50c1toYXNdKGoudHlwZSkgJiYgcmVzLnB1c2godGhpc1tqLnR5cGVdKCkuYXR0cihqKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9O1xuXG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZm9ybWF0XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBTaW1wbGUgZm9ybWF0IGZ1bmN0aW9uLiBSZXBsYWNlcyBjb25zdHJ1Y3Rpb24gb2YgdHlwZSDigJxgezxudW1iZXI+fWDigJ0gdG8gdGhlIGNvcnJlc3BvbmRpbmcgYXJndW1lbnQuXG4gICAgICoqXG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAqKlxuICAgICAtIHRva2VuIChzdHJpbmcpIHN0cmluZyB0byBmb3JtYXRcbiAgICAgLSDigKYgKHN0cmluZykgcmVzdCBvZiBhcmd1bWVudHMgd2lsbCBiZSB0cmVhdGVkIGFzIHBhcmFtZXRlcnMgZm9yIHJlcGxhY2VtZW50XG4gICAgID0gKHN0cmluZykgZm9ybWF0ZWQgc3RyaW5nXG4gICAgID4gVXNhZ2VcbiAgICAgfCB2YXIgeCA9IDEwLFxuICAgICB8ICAgICB5ID0gMjAsXG4gICAgIHwgICAgIHdpZHRoID0gNDAsXG4gICAgIHwgICAgIGhlaWdodCA9IDUwO1xuICAgICB8IC8vIHRoaXMgd2lsbCBkcmF3IGEgcmVjdGFuZ3VsYXIgc2hhcGUgZXF1aXZhbGVudCB0byBcIk0xMCwyMGg0MHY1MGgtNDB6XCJcbiAgICAgfCBwYXBlci5wYXRoKFJhcGhhZWwuZm9ybWF0KFwiTXswfSx7MX1oezJ9dnszfWh7NH16XCIsIHgsIHksIHdpZHRoLCBoZWlnaHQsIC13aWR0aCkpO1xuICAgIFxcKi9cbiAgICBSLmZvcm1hdCA9IGZ1bmN0aW9uICh0b2tlbiwgcGFyYW1zKSB7XG4gICAgICAgIHZhciBhcmdzID0gUi5pcyhwYXJhbXMsIGFycmF5KSA/IFswXVtjb25jYXRdKHBhcmFtcykgOiBhcmd1bWVudHM7XG4gICAgICAgIHRva2VuICYmIFIuaXModG9rZW4sIHN0cmluZykgJiYgYXJncy5sZW5ndGggLSAxICYmICh0b2tlbiA9IHRva2VuLnJlcGxhY2UoZm9ybWF0cmcsIGZ1bmN0aW9uIChzdHIsIGkpIHtcbiAgICAgICAgICAgIHJldHVybiBhcmdzWysraV0gPT0gbnVsbCA/IEUgOiBhcmdzW2ldO1xuICAgICAgICB9KSk7XG4gICAgICAgIHJldHVybiB0b2tlbiB8fCBFO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFJhcGhhZWwuZnVsbGZpbGxcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEEgbGl0dGxlIGJpdCBtb3JlIGFkdmFuY2VkIGZvcm1hdCBmdW5jdGlvbiB0aGFuIEBSYXBoYWVsLmZvcm1hdC4gUmVwbGFjZXMgY29uc3RydWN0aW9uIG9mIHR5cGUg4oCcYHs8bmFtZT59YOKAnSB0byB0aGUgY29ycmVzcG9uZGluZyBhcmd1bWVudC5cbiAgICAgKipcbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgICoqXG4gICAgIC0gdG9rZW4gKHN0cmluZykgc3RyaW5nIHRvIGZvcm1hdFxuICAgICAtIGpzb24gKG9iamVjdCkgb2JqZWN0IHdoaWNoIHByb3BlcnRpZXMgd2lsbCBiZSB1c2VkIGFzIGEgcmVwbGFjZW1lbnRcbiAgICAgPSAoc3RyaW5nKSBmb3JtYXRlZCBzdHJpbmdcbiAgICAgPiBVc2FnZVxuICAgICB8IC8vIHRoaXMgd2lsbCBkcmF3IGEgcmVjdGFuZ3VsYXIgc2hhcGUgZXF1aXZhbGVudCB0byBcIk0xMCwyMGg0MHY1MGgtNDB6XCJcbiAgICAgfCBwYXBlci5wYXRoKFJhcGhhZWwuZnVsbGZpbGwoXCJNe3h9LHt5fWh7ZGltLndpZHRofXZ7ZGltLmhlaWdodH1oe2RpbVsnbmVnYXRpdmUgd2lkdGgnXX16XCIsIHtcbiAgICAgfCAgICAgeDogMTAsXG4gICAgIHwgICAgIHk6IDIwLFxuICAgICB8ICAgICBkaW06IHtcbiAgICAgfCAgICAgICAgIHdpZHRoOiA0MCxcbiAgICAgfCAgICAgICAgIGhlaWdodDogNTAsXG4gICAgIHwgICAgICAgICBcIm5lZ2F0aXZlIHdpZHRoXCI6IC00MFxuICAgICB8ICAgICB9XG4gICAgIHwgfSkpO1xuICAgIFxcKi9cbiAgICBSLmZ1bGxmaWxsID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHRva2VuUmVnZXggPSAvXFx7KFteXFx9XSspXFx9L2csXG4gICAgICAgICAgICBvYmpOb3RhdGlvblJlZ2V4ID0gLyg/Oig/Ol58XFwuKSguKz8pKD89XFxbfFxcLnwkfFxcKCl8XFxbKCd8XCIpKC4rPylcXDJcXF0pKFxcKFxcKSk/L2csIC8vIG1hdGNoZXMgLnh4eHh4IG9yIFtcInh4eHh4XCJdIHRvIHJ1biBvdmVyIG9iamVjdCBwcm9wZXJ0aWVzXG4gICAgICAgICAgICByZXBsYWNlciA9IGZ1bmN0aW9uIChhbGwsIGtleSwgb2JqKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlcyA9IG9iajtcbiAgICAgICAgICAgICAgICBrZXkucmVwbGFjZShvYmpOb3RhdGlvblJlZ2V4LCBmdW5jdGlvbiAoYWxsLCBuYW1lLCBxdW90ZSwgcXVvdGVkTmFtZSwgaXNGdW5jKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lIHx8IHF1b3RlZE5hbWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYW1lIGluIHJlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcyA9IHJlc1tuYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiByZXMgPT0gXCJmdW5jdGlvblwiICYmIGlzRnVuYyAmJiAocmVzID0gcmVzKCkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmVzID0gKHJlcyA9PSBudWxsIHx8IHJlcyA9PSBvYmogPyBhbGwgOiByZXMpICsgXCJcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzdHIsIG9iaikge1xuICAgICAgICAgICAgcmV0dXJuIFN0cmluZyhzdHIpLnJlcGxhY2UodG9rZW5SZWdleCwgZnVuY3Rpb24gKGFsbCwga2V5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcGxhY2VyKGFsbCwga2V5LCBvYmopO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgfSkoKTtcbiAgICAvKlxcXG4gICAgICogUmFwaGFlbC5uaW5qYVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogSWYgeW91IHdhbnQgdG8gbGVhdmUgbm8gdHJhY2Ugb2YgUmFwaGHDq2wgKFdlbGwsIFJhcGhhw6tsIGNyZWF0ZXMgb25seSBvbmUgZ2xvYmFsIHZhcmlhYmxlIGBSYXBoYWVsYCwgYnV0IGFueXdheS4pIFlvdSBjYW4gdXNlIGBuaW5qYWAgbWV0aG9kLlxuICAgICAqIEJld2FyZSwgdGhhdCBpbiB0aGlzIGNhc2UgcGx1Z2lucyBjb3VsZCBzdG9wIHdvcmtpbmcsIGJlY2F1c2UgdGhleSBhcmUgZGVwZW5kaW5nIG9uIGdsb2JhbCB2YXJpYWJsZSBleGlzdGVuY2UuXG4gICAgICoqXG4gICAgID0gKG9iamVjdCkgUmFwaGFlbCBvYmplY3RcbiAgICAgPiBVc2FnZVxuICAgICB8IChmdW5jdGlvbiAobG9jYWxfcmFwaGFlbCkge1xuICAgICB8ICAgICB2YXIgcGFwZXIgPSBsb2NhbF9yYXBoYWVsKDEwLCAxMCwgMzIwLCAyMDApO1xuICAgICB8ICAgICDigKZcbiAgICAgfCB9KShSYXBoYWVsLm5pbmphKCkpO1xuICAgIFxcKi9cbiAgICBSLm5pbmphID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAob2xkUmFwaGFlbC53YXMpIHtcbiAgICAgICAgICAgIGcud2luLlJhcGhhZWwgPSBvbGRSYXBoYWVsLmlzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSUU4IHJhaXNlcyBhbiBlcnJvciB3aGVuIGRlbGV0aW5nIHdpbmRvdyBwcm9wZXJ0eVxuICAgICAgICAgICAgd2luZG93LlJhcGhhZWwgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB3aW5kb3cuUmFwaGFlbDtcbiAgICAgICAgICAgIH0gY2F0Y2goZSkge31cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUjtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBSYXBoYWVsLnN0XG4gICAgIFsgcHJvcGVydHkgKG9iamVjdCkgXVxuICAgICAqKlxuICAgICAqIFlvdSBjYW4gYWRkIHlvdXIgb3duIG1ldGhvZCB0byBlbGVtZW50cyBhbmQgc2V0cy4gSXQgaXMgd2lzZSB0byBhZGQgYSBzZXQgbWV0aG9kIGZvciBlYWNoIGVsZW1lbnQgbWV0aG9kXG4gICAgICogeW91IGFkZGVkLCBzbyB5b3Ugd2lsbCBiZSBhYmxlIHRvIGNhbGwgdGhlIHNhbWUgbWV0aG9kIG9uIHNldHMgdG9vLlxuICAgICAqKlxuICAgICAqIFNlZSBhbHNvIEBSYXBoYWVsLmVsLlxuICAgICA+IFVzYWdlXG4gICAgIHwgUmFwaGFlbC5lbC5yZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgIHwgICAgIHRoaXMuYXR0cih7ZmlsbDogXCIjZjAwXCJ9KTtcbiAgICAgfCB9O1xuICAgICB8IFJhcGhhZWwuc3QucmVkID0gZnVuY3Rpb24gKCkge1xuICAgICB8ICAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsKSB7XG4gICAgIHwgICAgICAgICBlbC5yZWQoKTtcbiAgICAgfCAgICAgfSk7XG4gICAgIHwgfTtcbiAgICAgfCAvLyB0aGVuIHVzZSBpdFxuICAgICB8IHBhcGVyLnNldChwYXBlci5jaXJjbGUoMTAwLCAxMDAsIDIwKSwgcGFwZXIuY2lyY2xlKDExMCwgMTAwLCAyMCkpLnJlZCgpO1xuICAgIFxcKi9cbiAgICBSLnN0ID0gc2V0cHJvdG87XG5cbiAgICBldmUub24oXCJyYXBoYWVsLkRPTWxvYWRcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICBsb2FkZWQgPSB0cnVlO1xuICAgIH0pO1xuXG4gICAgLy8gRmlyZWZveCA8My42IGZpeDogaHR0cDovL3dlYnJlZmxlY3Rpb24uYmxvZ3Nwb3QuY29tLzIwMDkvMTEvMTk1LWNoYXJzLXRvLWhlbHAtbGF6eS1sb2FkaW5nLmh0bWxcbiAgICAoZnVuY3Rpb24gKGRvYywgbG9hZGVkLCBmKSB7XG4gICAgICAgIGlmIChkb2MucmVhZHlTdGF0ZSA9PSBudWxsICYmIGRvYy5hZGRFdmVudExpc3RlbmVyKXtcbiAgICAgICAgICAgIGRvYy5hZGRFdmVudExpc3RlbmVyKGxvYWRlZCwgZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcihsb2FkZWQsIGYsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICBkb2MucmVhZHlTdGF0ZSA9IFwiY29tcGxldGVcIjtcbiAgICAgICAgICAgIH0sIGZhbHNlKTtcbiAgICAgICAgICAgIGRvYy5yZWFkeVN0YXRlID0gXCJsb2FkaW5nXCI7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gaXNMb2FkZWQoKSB7XG4gICAgICAgICAgICAoL2luLykudGVzdChkb2MucmVhZHlTdGF0ZSkgPyBzZXRUaW1lb3V0KGlzTG9hZGVkLCA5KSA6IFIuZXZlKFwicmFwaGFlbC5ET01sb2FkXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlzTG9hZGVkKCk7XG4gICAgfSkoZG9jdW1lbnQsIFwiRE9NQ29udGVudExvYWRlZFwiKTtcblxuICAgIHJldHVybiBSO1xufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./dev/raphael.core.js\n"); + +/***/ }), + +/***/ "./dev/raphael.svg.js": +/*!****************************!*\ + !*** ./dev/raphael.svg.js ***! + \****************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! ./raphael.core */ \"./dev/raphael.core.js\")], __WEBPACK_AMD_DEFINE_RESULT__ = (function(R) {\n if (R && !R.svg) {\n return;\n }\n\n var has = \"hasOwnProperty\",\n Str = String,\n toFloat = parseFloat,\n toInt = parseInt,\n math = Math,\n mmax = math.max,\n abs = math.abs,\n pow = math.pow,\n separator = /[, ]+/,\n eve = R.eve,\n E = \"\",\n S = \" \";\n var xlink = \"http://www.w3.org/1999/xlink\",\n markers = {\n block: \"M5,0 0,2.5 5,5z\",\n classic: \"M5,0 0,2.5 5,5 3.5,3 3.5,2z\",\n diamond: \"M2.5,0 5,2.5 2.5,5 0,2.5z\",\n open: \"M6,1 1,3.5 6,6\",\n oval: \"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z\"\n },\n markerCounter = {};\n R.toString = function () {\n return \"Your browser supports SVG.\\nYou are running Rapha\\xebl \" + this.version;\n };\n var $ = function (el, attr) {\n if (attr) {\n if (typeof el == \"string\") {\n el = $(el);\n }\n for (var key in attr) if (attr[has](key)) {\n if (key.substring(0, 6) == \"xlink:\") {\n el.setAttributeNS(xlink, key.substring(6), Str(attr[key]));\n } else {\n el.setAttribute(key, Str(attr[key]));\n }\n }\n } else {\n el = R._g.doc.createElementNS(\"http://www.w3.org/2000/svg\", el);\n el.style && (el.style.webkitTapHighlightColor = \"rgba(0,0,0,0)\");\n }\n return el;\n },\n addGradientFill = function (element, gradient) {\n var type = \"linear\",\n id = element.id + gradient,\n fx = .5, fy = .5,\n o = element.node,\n SVG = element.paper,\n s = o.style,\n el = R._g.doc.getElementById(id);\n if (!el) {\n gradient = Str(gradient).replace(R._radial_gradient, function (all, _fx, _fy) {\n type = \"radial\";\n if (_fx && _fy) {\n fx = toFloat(_fx);\n fy = toFloat(_fy);\n var dir = ((fy > .5) * 2 - 1);\n pow(fx - .5, 2) + pow(fy - .5, 2) > .25 &&\n (fy = math.sqrt(.25 - pow(fx - .5, 2)) * dir + .5) &&\n fy != .5 &&\n (fy = fy.toFixed(5) - 1e-5 * dir);\n }\n return E;\n });\n gradient = gradient.split(/\\s*\\-\\s*/);\n if (type == \"linear\") {\n var angle = gradient.shift();\n angle = -toFloat(angle);\n if (isNaN(angle)) {\n return null;\n }\n var vector = [0, 0, math.cos(R.rad(angle)), math.sin(R.rad(angle))],\n max = 1 / (mmax(abs(vector[2]), abs(vector[3])) || 1);\n vector[2] *= max;\n vector[3] *= max;\n if (vector[2] < 0) {\n vector[0] = -vector[2];\n vector[2] = 0;\n }\n if (vector[3] < 0) {\n vector[1] = -vector[3];\n vector[3] = 0;\n }\n }\n var dots = R._parseDots(gradient);\n if (!dots) {\n return null;\n }\n id = id.replace(/[\\(\\)\\s,\\xb0#]/g, \"_\");\n\n if (element.gradient && id != element.gradient.id) {\n SVG.defs.removeChild(element.gradient);\n delete element.gradient;\n }\n\n if (!element.gradient) {\n el = $(type + \"Gradient\", {id: id});\n element.gradient = el;\n $(el, type == \"radial\" ? {\n fx: fx,\n fy: fy\n } : {\n x1: vector[0],\n y1: vector[1],\n x2: vector[2],\n y2: vector[3],\n gradientTransform: element.matrix.invert()\n });\n SVG.defs.appendChild(el);\n for (var i = 0, ii = dots.length; i < ii; i++) {\n el.appendChild($(\"stop\", {\n offset: dots[i].offset ? dots[i].offset : i ? \"100%\" : \"0%\",\n \"stop-color\": dots[i].color || \"#fff\",\n \"stop-opacity\": isFinite(dots[i].opacity) ? dots[i].opacity : 1\n }));\n }\n }\n }\n $(o, {\n fill: fillurl(id),\n opacity: 1,\n \"fill-opacity\": 1\n });\n s.fill = E;\n s.opacity = 1;\n s.fillOpacity = 1;\n return 1;\n },\n isIE9or10 = function () {\n var mode = document.documentMode;\n return mode && (mode === 9 || mode === 10);\n },\n fillurl = function (id) {\n if (isIE9or10()) {\n return \"url('#\" + id + \"')\";\n }\n var location = document.location;\n var locationString = (\n location.protocol + '//' +\n location.host +\n location.pathname +\n location.search\n );\n return \"url('\" + locationString + \"#\" + id + \"')\";\n },\n updatePosition = function (o) {\n var bbox = o.getBBox(1);\n $(o.pattern, {patternTransform: o.matrix.invert() + \" translate(\" + bbox.x + \",\" + bbox.y + \")\"});\n },\n addArrow = function (o, value, isEnd) {\n if (o.type == \"path\") {\n var values = Str(value).toLowerCase().split(\"-\"),\n p = o.paper,\n se = isEnd ? \"end\" : \"start\",\n node = o.node,\n attrs = o.attrs,\n stroke = attrs[\"stroke-width\"],\n i = values.length,\n type = \"classic\",\n from,\n to,\n dx,\n refX,\n attr,\n w = 3,\n h = 3,\n t = 5;\n while (i--) {\n switch (values[i]) {\n case \"block\":\n case \"classic\":\n case \"oval\":\n case \"diamond\":\n case \"open\":\n case \"none\":\n type = values[i];\n break;\n case \"wide\": h = 5; break;\n case \"narrow\": h = 2; break;\n case \"long\": w = 5; break;\n case \"short\": w = 2; break;\n }\n }\n if (type == \"open\") {\n w += 2;\n h += 2;\n t += 2;\n dx = 1;\n refX = isEnd ? 4 : 1;\n attr = {\n fill: \"none\",\n stroke: attrs.stroke\n };\n } else {\n refX = dx = w / 2;\n attr = {\n fill: attrs.stroke,\n stroke: \"none\"\n };\n }\n if (o._.arrows) {\n if (isEnd) {\n o._.arrows.endPath && markerCounter[o._.arrows.endPath]--;\n o._.arrows.endMarker && markerCounter[o._.arrows.endMarker]--;\n } else {\n o._.arrows.startPath && markerCounter[o._.arrows.startPath]--;\n o._.arrows.startMarker && markerCounter[o._.arrows.startMarker]--;\n }\n } else {\n o._.arrows = {};\n }\n if (type != \"none\") {\n var pathId = \"raphael-marker-\" + type,\n markerId = \"raphael-marker-\" + se + type + w + h + \"-obj\" + o.id;\n if (!R._g.doc.getElementById(pathId)) {\n p.defs.appendChild($($(\"path\"), {\n \"stroke-linecap\": \"round\",\n d: markers[type],\n id: pathId\n }));\n markerCounter[pathId] = 1;\n } else {\n markerCounter[pathId]++;\n }\n var marker = R._g.doc.getElementById(markerId),\n use;\n if (!marker) {\n marker = $($(\"marker\"), {\n id: markerId,\n markerHeight: h,\n markerWidth: w,\n orient: \"auto\",\n refX: refX,\n refY: h / 2\n });\n use = $($(\"use\"), {\n \"xlink:href\": \"#\" + pathId,\n transform: (isEnd ? \"rotate(180 \" + w / 2 + \" \" + h / 2 + \") \" : E) + \"scale(\" + w / t + \",\" + h / t + \")\",\n \"stroke-width\": (1 / ((w / t + h / t) / 2)).toFixed(4)\n });\n marker.appendChild(use);\n p.defs.appendChild(marker);\n markerCounter[markerId] = 1;\n } else {\n markerCounter[markerId]++;\n use = marker.getElementsByTagName(\"use\")[0];\n }\n $(use, attr);\n var delta = dx * (type != \"diamond\" && type != \"oval\");\n if (isEnd) {\n from = o._.arrows.startdx * stroke || 0;\n to = R.getTotalLength(attrs.path) - delta * stroke;\n } else {\n from = delta * stroke;\n to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0);\n }\n attr = {};\n attr[\"marker-\" + se] = \"url(#\" + markerId + \")\";\n if (to || from) {\n attr.d = R.getSubpath(attrs.path, from, to);\n }\n $(node, attr);\n o._.arrows[se + \"Path\"] = pathId;\n o._.arrows[se + \"Marker\"] = markerId;\n o._.arrows[se + \"dx\"] = delta;\n o._.arrows[se + \"Type\"] = type;\n o._.arrows[se + \"String\"] = value;\n } else {\n if (isEnd) {\n from = o._.arrows.startdx * stroke || 0;\n to = R.getTotalLength(attrs.path) - from;\n } else {\n from = 0;\n to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0);\n }\n o._.arrows[se + \"Path\"] && $(node, {d: R.getSubpath(attrs.path, from, to)});\n delete o._.arrows[se + \"Path\"];\n delete o._.arrows[se + \"Marker\"];\n delete o._.arrows[se + \"dx\"];\n delete o._.arrows[se + \"Type\"];\n delete o._.arrows[se + \"String\"];\n }\n for (attr in markerCounter) if (markerCounter[has](attr) && !markerCounter[attr]) {\n var item = R._g.doc.getElementById(attr);\n item && item.parentNode.removeChild(item);\n }\n }\n },\n dasharray = {\n \"-\": [3, 1],\n \".\": [1, 1],\n \"-.\": [3, 1, 1, 1],\n \"-..\": [3, 1, 1, 1, 1, 1],\n \". \": [1, 3],\n \"- \": [4, 3],\n \"--\": [8, 3],\n \"- .\": [4, 3, 1, 3],\n \"--.\": [8, 3, 1, 3],\n \"--..\": [8, 3, 1, 3, 1, 3]\n },\n addDashes = function (o, value, params) {\n value = dasharray[Str(value).toLowerCase()];\n if (value) {\n var width = o.attrs[\"stroke-width\"] || \"1\",\n butt = {round: width, square: width, butt: 0}[o.attrs[\"stroke-linecap\"] || params[\"stroke-linecap\"]] || 0,\n dashes = [],\n i = value.length;\n while (i--) {\n dashes[i] = value[i] * width + ((i % 2) ? 1 : -1) * butt;\n }\n $(o.node, {\"stroke-dasharray\": dashes.join(\",\")});\n }\n else {\n $(o.node, {\"stroke-dasharray\": \"none\"});\n }\n },\n setFillAndStroke = function (o, params) {\n var node = o.node,\n attrs = o.attrs,\n vis = node.style.visibility;\n node.style.visibility = \"hidden\";\n for (var att in params) {\n if (params[has](att)) {\n if (!R._availableAttrs[has](att)) {\n continue;\n }\n var value = params[att];\n attrs[att] = value;\n switch (att) {\n case \"blur\":\n o.blur(value);\n break;\n case \"title\":\n var title = node.getElementsByTagName(\"title\");\n\n // Use the existing .\n if (title.length && (title = title[0])) {\n title.firstChild.nodeValue = value;\n } else {\n title = $(\"title\");\n var val = R._g.doc.createTextNode(value);\n title.appendChild(val);\n node.appendChild(title);\n }\n break;\n case \"href\":\n case \"target\":\n var pn = node.parentNode;\n if (pn.tagName.toLowerCase() != \"a\") {\n var hl = $(\"a\");\n pn.insertBefore(hl, node);\n hl.appendChild(node);\n pn = hl;\n }\n if (att == \"target\") {\n pn.setAttributeNS(xlink, \"show\", value == \"blank\" ? \"new\" : value);\n } else {\n pn.setAttributeNS(xlink, att, value);\n }\n break;\n case \"cursor\":\n node.style.cursor = value;\n break;\n case \"transform\":\n o.transform(value);\n break;\n case \"arrow-start\":\n addArrow(o, value);\n break;\n case \"arrow-end\":\n addArrow(o, value, 1);\n break;\n case \"clip-rect\":\n var rect = Str(value).split(separator);\n if (rect.length == 4) {\n o.clip && o.clip.parentNode.parentNode.removeChild(o.clip.parentNode);\n var el = $(\"clipPath\"),\n rc = $(\"rect\");\n el.id = R.createUUID();\n $(rc, {\n x: rect[0],\n y: rect[1],\n width: rect[2],\n height: rect[3]\n });\n el.appendChild(rc);\n o.paper.defs.appendChild(el);\n $(node, {\"clip-path\": \"url(#\" + el.id + \")\"});\n o.clip = rc;\n }\n if (!value) {\n var path = node.getAttribute(\"clip-path\");\n if (path) {\n var clip = R._g.doc.getElementById(path.replace(/(^url\\(#|\\)$)/g, E));\n clip && clip.parentNode.removeChild(clip);\n $(node, {\"clip-path\": E});\n delete o.clip;\n }\n }\n break;\n case \"path\":\n if (o.type == \"path\") {\n $(node, {d: value ? attrs.path = R._pathToAbsolute(value) : \"M0,0\"});\n o._.dirty = 1;\n if (o._.arrows) {\n \"startString\" in o._.arrows && addArrow(o, o._.arrows.startString);\n \"endString\" in o._.arrows && addArrow(o, o._.arrows.endString, 1);\n }\n }\n break;\n case \"width\":\n node.setAttribute(att, value);\n o._.dirty = 1;\n if (attrs.fx) {\n att = \"x\";\n value = attrs.x;\n } else {\n break;\n }\n case \"x\":\n if (attrs.fx) {\n value = -attrs.x - (attrs.width || 0);\n }\n case \"rx\":\n if (att == \"rx\" && o.type == \"rect\") {\n break;\n }\n case \"cx\":\n node.setAttribute(att, value);\n o.pattern && updatePosition(o);\n o._.dirty = 1;\n break;\n case \"height\":\n node.setAttribute(att, value);\n o._.dirty = 1;\n if (attrs.fy) {\n att = \"y\";\n value = attrs.y;\n } else {\n break;\n }\n case \"y\":\n if (attrs.fy) {\n value = -attrs.y - (attrs.height || 0);\n }\n case \"ry\":\n if (att == \"ry\" && o.type == \"rect\") {\n break;\n }\n case \"cy\":\n node.setAttribute(att, value);\n o.pattern && updatePosition(o);\n o._.dirty = 1;\n break;\n case \"r\":\n if (o.type == \"rect\") {\n $(node, {rx: value, ry: value});\n } else {\n node.setAttribute(att, value);\n }\n o._.dirty = 1;\n break;\n case \"src\":\n if (o.type == \"image\") {\n node.setAttributeNS(xlink, \"href\", value);\n }\n break;\n case \"stroke-width\":\n if (o._.sx != 1 || o._.sy != 1) {\n value /= mmax(abs(o._.sx), abs(o._.sy)) || 1;\n }\n node.setAttribute(att, value);\n if (attrs[\"stroke-dasharray\"]) {\n addDashes(o, attrs[\"stroke-dasharray\"], params);\n }\n if (o._.arrows) {\n \"startString\" in o._.arrows && addArrow(o, o._.arrows.startString);\n \"endString\" in o._.arrows && addArrow(o, o._.arrows.endString, 1);\n }\n break;\n case \"stroke-dasharray\":\n addDashes(o, value, params);\n break;\n case \"fill\":\n var isURL = Str(value).match(R._ISURL);\n if (isURL) {\n el = $(\"pattern\");\n var ig = $(\"image\");\n el.id = R.createUUID();\n $(el, {x: 0, y: 0, patternUnits: \"userSpaceOnUse\", height: 1, width: 1});\n $(ig, {x: 0, y: 0, \"xlink:href\": isURL[1]});\n el.appendChild(ig);\n\n (function (el) {\n R._preload(isURL[1], function () {\n var w = this.offsetWidth,\n h = this.offsetHeight;\n $(el, {width: w, height: h});\n $(ig, {width: w, height: h});\n });\n })(el);\n o.paper.defs.appendChild(el);\n $(node, {fill: \"url(#\" + el.id + \")\"});\n o.pattern = el;\n o.pattern && updatePosition(o);\n break;\n }\n var clr = R.getRGB(value);\n if (!clr.error) {\n delete params.gradient;\n delete attrs.gradient;\n !R.is(attrs.opacity, \"undefined\") &&\n R.is(params.opacity, \"undefined\") &&\n $(node, {opacity: attrs.opacity});\n !R.is(attrs[\"fill-opacity\"], \"undefined\") &&\n R.is(params[\"fill-opacity\"], \"undefined\") &&\n $(node, {\"fill-opacity\": attrs[\"fill-opacity\"]});\n } else if ((o.type == \"circle\" || o.type == \"ellipse\" || Str(value).charAt() != \"r\") && addGradientFill(o, value)) {\n if (\"opacity\" in attrs || \"fill-opacity\" in attrs) {\n var gradient = R._g.doc.getElementById(node.getAttribute(\"fill\").replace(/^url\\(#|\\)$/g, E));\n if (gradient) {\n var stops = gradient.getElementsByTagName(\"stop\");\n $(stops[stops.length - 1], {\"stop-opacity\": (\"opacity\" in attrs ? attrs.opacity : 1) * (\"fill-opacity\" in attrs ? attrs[\"fill-opacity\"] : 1)});\n }\n }\n attrs.gradient = value;\n attrs.fill = \"none\";\n break;\n }\n clr[has](\"opacity\") && $(node, {\"fill-opacity\": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity});\n case \"stroke\":\n clr = R.getRGB(value);\n node.setAttribute(att, clr.hex);\n att == \"stroke\" && clr[has](\"opacity\") && $(node, {\"stroke-opacity\": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity});\n if (att == \"stroke\" && o._.arrows) {\n \"startString\" in o._.arrows && addArrow(o, o._.arrows.startString);\n \"endString\" in o._.arrows && addArrow(o, o._.arrows.endString, 1);\n }\n break;\n case \"gradient\":\n (o.type == \"circle\" || o.type == \"ellipse\" || Str(value).charAt() != \"r\") && addGradientFill(o, value);\n break;\n case \"opacity\":\n if (attrs.gradient && !attrs[has](\"stroke-opacity\")) {\n $(node, {\"stroke-opacity\": value > 1 ? value / 100 : value});\n }\n // fall\n case \"fill-opacity\":\n if (attrs.gradient) {\n gradient = R._g.doc.getElementById(node.getAttribute(\"fill\").replace(/^url\\(#|\\)$/g, E));\n if (gradient) {\n stops = gradient.getElementsByTagName(\"stop\");\n $(stops[stops.length - 1], {\"stop-opacity\": value});\n }\n break;\n }\n default:\n att == \"font-size\" && (value = toInt(value, 10) + \"px\");\n var cssrule = att.replace(/(\\-.)/g, function (w) {\n return w.substring(1).toUpperCase();\n });\n node.style[cssrule] = value;\n o._.dirty = 1;\n node.setAttribute(att, value);\n break;\n }\n }\n }\n\n tuneText(o, params);\n node.style.visibility = vis;\n },\n leading = 1.2,\n tuneText = function (el, params) {\n if (el.type != \"text\" || !(params[has](\"text\") || params[has](\"font\") || params[has](\"font-size\") || params[has](\"x\") || params[has](\"y\"))) {\n return;\n }\n var a = el.attrs,\n node = el.node,\n fontSize = node.firstChild ? toInt(R._g.doc.defaultView.getComputedStyle(node.firstChild, E).getPropertyValue(\"font-size\"), 10) : 10;\n\n if (params[has](\"text\")) {\n a.text = params.text;\n while (node.firstChild) {\n node.removeChild(node.firstChild);\n }\n var texts = Str(params.text).split(\"\\n\"),\n tspans = [],\n tspan;\n for (var i = 0, ii = texts.length; i < ii; i++) {\n tspan = $(\"tspan\");\n i && $(tspan, {dy: fontSize * leading, x: a.x});\n tspan.appendChild(R._g.doc.createTextNode(texts[i]));\n node.appendChild(tspan);\n tspans[i] = tspan;\n }\n } else {\n tspans = node.getElementsByTagName(\"tspan\");\n for (i = 0, ii = tspans.length; i < ii; i++) if (i) {\n $(tspans[i], {dy: fontSize * leading, x: a.x});\n } else {\n $(tspans[0], {dy: 0});\n }\n }\n $(node, {x: a.x, y: a.y});\n el._.dirty = 1;\n var bb = el._getBBox(),\n dif = a.y - (bb.y + bb.height / 2);\n dif && R.is(dif, \"finite\") && $(tspans[0], {dy: dif});\n },\n getRealNode = function (node) {\n if (node.parentNode && node.parentNode.tagName.toLowerCase() === \"a\") {\n return node.parentNode;\n } else {\n return node;\n }\n },\n Element = function (node, svg) {\n var X = 0,\n Y = 0;\n /*\\\n * Element.node\n [ property (object) ]\n **\n * Gives you a reference to the DOM object, so you can assign event handlers or just mess around.\n **\n * Note: Don’t mess with it.\n > Usage\n | // draw a circle at coordinate 10,10 with radius of 10\n | var c = paper.circle(10, 10, 10);\n | c.node.onclick = function () {\n | c.attr(\"fill\", \"red\");\n | };\n \\*/\n this[0] = this.node = node;\n /*\\\n * Element.raphael\n [ property (object) ]\n **\n * Internal reference to @Raphael object. In case it is not available.\n > Usage\n | Raphael.el.red = function () {\n | var hsb = this.paper.raphael.rgb2hsb(this.attr(\"fill\"));\n | hsb.h = 1;\n | this.attr({fill: this.paper.raphael.hsb2rgb(hsb).hex});\n | }\n \\*/\n node.raphael = true;\n /*\\\n * Element.id\n [ property (number) ]\n **\n * Unique id of the element. Especially useful when you want to listen to events of the element,\n * because all events are fired in format `<module>.<action>.<id>`. Also useful for @Paper.getById method.\n \\*/\n this.id = guid();\n node.raphaelid = this.id;\n\n /**\n * Method that returns a 5 letter/digit id, enough for 36^5 = 60466176 elements\n * @returns {string} id\n */\n function guid() {\n return (\"0000\" + (Math.random()*Math.pow(36,5) << 0).toString(36)).slice(-5);\n }\n\n this.matrix = R.matrix();\n this.realPath = null;\n /*\\\n * Element.paper\n [ property (object) ]\n **\n * Internal reference to “paper” where object drawn. Mainly for use in plugins and element extensions.\n > Usage\n | Raphael.el.cross = function () {\n | this.attr({fill: \"red\"});\n | this.paper.path(\"M10,10L50,50M50,10L10,50\")\n | .attr({stroke: \"red\"});\n | }\n \\*/\n this.paper = svg;\n this.attrs = this.attrs || {};\n this._ = {\n transform: [],\n sx: 1,\n sy: 1,\n deg: 0,\n dx: 0,\n dy: 0,\n dirty: 1\n };\n !svg.bottom && (svg.bottom = this);\n /*\\\n * Element.prev\n [ property (object) ]\n **\n * Reference to the previous element in the hierarchy.\n \\*/\n this.prev = svg.top;\n svg.top && (svg.top.next = this);\n svg.top = this;\n /*\\\n * Element.next\n [ property (object) ]\n **\n * Reference to the next element in the hierarchy.\n \\*/\n this.next = null;\n },\n elproto = R.el;\n\n Element.prototype = elproto;\n elproto.constructor = Element;\n\n R._engine.path = function (pathString, SVG) {\n var el = $(\"path\");\n SVG.canvas && SVG.canvas.appendChild(el);\n var p = new Element(el, SVG);\n p.type = \"path\";\n setFillAndStroke(p, {\n fill: \"none\",\n stroke: \"#000\",\n path: pathString\n });\n return p;\n };\n /*\\\n * Element.rotate\n [ method ]\n **\n * Deprecated! Use @Element.transform instead.\n * Adds rotation by given angle around given point to the list of\n * transformations of the element.\n > Parameters\n - deg (number) angle in degrees\n - cx (number) #optional x coordinate of the centre of rotation\n - cy (number) #optional y coordinate of the centre of rotation\n * If cx & cy aren’t specified centre of the shape is used as a point of rotation.\n = (object) @Element\n \\*/\n elproto.rotate = function (deg, cx, cy) {\n if (this.removed) {\n return this;\n }\n deg = Str(deg).split(separator);\n if (deg.length - 1) {\n cx = toFloat(deg[1]);\n cy = toFloat(deg[2]);\n }\n deg = toFloat(deg[0]);\n (cy == null) && (cx = cy);\n if (cx == null || cy == null) {\n var bbox = this.getBBox(1);\n cx = bbox.x + bbox.width / 2;\n cy = bbox.y + bbox.height / 2;\n }\n this.transform(this._.transform.concat([[\"r\", deg, cx, cy]]));\n return this;\n };\n /*\\\n * Element.scale\n [ method ]\n **\n * Deprecated! Use @Element.transform instead.\n * Adds scale by given amount relative to given point to the list of\n * transformations of the element.\n > Parameters\n - sx (number) horisontal scale amount\n - sy (number) vertical scale amount\n - cx (number) #optional x coordinate of the centre of scale\n - cy (number) #optional y coordinate of the centre of scale\n * If cx & cy aren’t specified centre of the shape is used instead.\n = (object) @Element\n \\*/\n elproto.scale = function (sx, sy, cx, cy) {\n if (this.removed) {\n return this;\n }\n sx = Str(sx).split(separator);\n if (sx.length - 1) {\n sy = toFloat(sx[1]);\n cx = toFloat(sx[2]);\n cy = toFloat(sx[3]);\n }\n sx = toFloat(sx[0]);\n (sy == null) && (sy = sx);\n (cy == null) && (cx = cy);\n if (cx == null || cy == null) {\n var bbox = this.getBBox(1);\n }\n cx = cx == null ? bbox.x + bbox.width / 2 : cx;\n cy = cy == null ? bbox.y + bbox.height / 2 : cy;\n this.transform(this._.transform.concat([[\"s\", sx, sy, cx, cy]]));\n return this;\n };\n /*\\\n * Element.translate\n [ method ]\n **\n * Deprecated! Use @Element.transform instead.\n * Adds translation by given amount to the list of transformations of the element.\n > Parameters\n - dx (number) horisontal shift\n - dy (number) vertical shift\n = (object) @Element\n \\*/\n elproto.translate = function (dx, dy) {\n if (this.removed) {\n return this;\n }\n dx = Str(dx).split(separator);\n if (dx.length - 1) {\n dy = toFloat(dx[1]);\n }\n dx = toFloat(dx[0]) || 0;\n dy = +dy || 0;\n this.transform(this._.transform.concat([[\"t\", dx, dy]]));\n return this;\n };\n /*\\\n * Element.transform\n [ method ]\n **\n * Adds transformation to the element which is separate to other attributes,\n * i.e. translation doesn’t change `x` or `y` of the rectange. The format\n * of transformation string is similar to the path string syntax:\n | \"t100,100r30,100,100s2,2,100,100r45s1.5\"\n * Each letter is a command. There are four commands: `t` is for translate, `r` is for rotate, `s` is for\n * scale and `m` is for matrix.\n *\n * There are also alternative “absolute” translation, rotation and scale: `T`, `R` and `S`. They will not take previous transformation into account. For example, `...T100,0` will always move element 100 px horisontally, while `...t100,0` could move it vertically if there is `r90` before. Just compare results of `r90t100,0` and `r90T100,0`.\n *\n * So, the example line above could be read like “translate by 100, 100; rotate 30° around 100, 100; scale twice around 100, 100;\n * rotate 45° around centre; scale 1.5 times relative to centre”. As you can see rotate and scale commands have origin\n * coordinates as optional parameters, the default is the centre point of the element.\n * Matrix accepts six parameters.\n > Usage\n | var el = paper.rect(10, 20, 300, 200);\n | // translate 100, 100, rotate 45°, translate -100, 0\n | el.transform(\"t100,100r45t-100,0\");\n | // if you want you can append or prepend transformations\n | el.transform(\"...t50,50\");\n | el.transform(\"s2...\");\n | // or even wrap\n | el.transform(\"t50,50...t-50-50\");\n | // to reset transformation call method with empty string\n | el.transform(\"\");\n | // to get current value call it without parameters\n | console.log(el.transform());\n > Parameters\n - tstr (string) #optional transformation string\n * If tstr isn’t specified\n = (string) current transformation string\n * else\n = (object) @Element\n \\*/\n elproto.transform = function (tstr) {\n var _ = this._;\n if (tstr == null) {\n return _.transform;\n }\n R._extractTransform(this, tstr);\n\n this.clip && $(this.clip, {transform: this.matrix.invert()});\n this.pattern && updatePosition(this);\n this.node && $(this.node, {transform: this.matrix});\n\n if (_.sx != 1 || _.sy != 1) {\n var sw = this.attrs[has](\"stroke-width\") ? this.attrs[\"stroke-width\"] : 1;\n this.attr({\"stroke-width\": sw});\n }\n\n return this;\n };\n /*\\\n * Element.hide\n [ method ]\n **\n * Makes element invisible. See @Element.show.\n = (object) @Element\n \\*/\n elproto.hide = function () {\n if(!this.removed) this.node.style.display = \"none\";\n return this;\n };\n /*\\\n * Element.show\n [ method ]\n **\n * Makes element visible. See @Element.hide.\n = (object) @Element\n \\*/\n elproto.show = function () {\n if(!this.removed) this.node.style.display = \"\";\n return this;\n };\n /*\\\n * Element.remove\n [ method ]\n **\n * Removes element from the paper.\n \\*/\n elproto.remove = function () {\n var node = getRealNode(this.node);\n if (this.removed || !node.parentNode) {\n return;\n }\n var paper = this.paper;\n paper.__set__ && paper.__set__.exclude(this);\n eve.unbind(\"raphael.*.*.\" + this.id);\n if (this.gradient) {\n paper.defs.removeChild(this.gradient);\n }\n R._tear(this, paper);\n\n node.parentNode.removeChild(node);\n\n // Remove custom data for element\n this.removeData();\n\n for (var i in this) {\n this[i] = typeof this[i] == \"function\" ? R._removedFactory(i) : null;\n }\n this.removed = true;\n };\n elproto._getBBox = function () {\n if (this.node.style.display == \"none\") {\n this.show();\n var hide = true;\n }\n var canvasHidden = false,\n containerStyle;\n if (this.paper.canvas.parentElement) {\n containerStyle = this.paper.canvas.parentElement.style;\n } //IE10+ can't find parentElement\n else if (this.paper.canvas.parentNode) {\n containerStyle = this.paper.canvas.parentNode.style;\n }\n\n if(containerStyle && containerStyle.display == \"none\") {\n canvasHidden = true;\n containerStyle.display = \"\";\n }\n var bbox = {};\n try {\n bbox = this.node.getBBox();\n } catch(e) {\n // Firefox 3.0.x, 25.0.1 (probably more versions affected) play badly here - possible fix\n bbox = {\n x: this.node.clientLeft,\n y: this.node.clientTop,\n width: this.node.clientWidth,\n height: this.node.clientHeight\n }\n } finally {\n bbox = bbox || {};\n if(canvasHidden){\n containerStyle.display = \"none\";\n }\n }\n hide && this.hide();\n return bbox;\n };\n /*\\\n * Element.attr\n [ method ]\n **\n * Sets the attributes of the element.\n > Parameters\n - attrName (string) attribute’s name\n - value (string) value\n * or\n - params (object) object of name/value pairs\n * or\n - attrName (string) attribute’s name\n * or\n - attrNames (array) in this case method returns array of current values for given attribute names\n = (object) @Element if attrsName & value or params are passed in.\n = (...) value of the attribute if only attrsName is passed in.\n = (array) array of values of the attribute if attrsNames is passed in.\n = (object) object of attributes if nothing is passed in.\n > Possible parameters\n # <p>Please refer to the <a href=\"http://www.w3.org/TR/SVG/\" title=\"The W3C Recommendation for the SVG language describes these properties in detail.\">SVG specification</a> for an explanation of these parameters.</p>\n o arrow-end (string) arrowhead on the end of the path. The format for string is `<type>[-<width>[-<length>]]`. Possible types: `classic`, `block`, `open`, `oval`, `diamond`, `none`, width: `wide`, `narrow`, `medium`, length: `long`, `short`, `midium`.\n o clip-rect (string) comma or space separated values: x, y, width and height\n o cursor (string) CSS type of the cursor\n o cx (number) the x-axis coordinate of the center of the circle, or ellipse\n o cy (number) the y-axis coordinate of the center of the circle, or ellipse\n o fill (string) colour, gradient or image\n o fill-opacity (number)\n o font (string)\n o font-family (string)\n o font-size (number) font size in pixels\n o font-weight (string)\n o height (number)\n o href (string) URL, if specified element behaves as hyperlink\n o opacity (number)\n o path (string) SVG path string format\n o r (number) radius of the circle, ellipse or rounded corner on the rect\n o rx (number) horisontal radius of the ellipse\n o ry (number) vertical radius of the ellipse\n o src (string) image URL, only works for @Element.image element\n o stroke (string) stroke colour\n o stroke-dasharray (string) [“”, “none”, “`-`”, “`.`”, “`-.`”, “`-..`”, “`. `”, “`- `”, “`--`”, “`- .`”, “`--.`”, “`--..`”]\n o stroke-linecap (string) [“`butt`”, “`square`”, “`round`”]\n o stroke-linejoin (string) [“`bevel`”, “`round`”, “`miter`”]\n o stroke-miterlimit (number)\n o stroke-opacity (number)\n o stroke-width (number) stroke width in pixels, default is '1'\n o target (string) used with href\n o text (string) contents of the text element. Use `\\n` for multiline text\n o text-anchor (string) [“`start`”, “`middle`”, “`end`”], default is “`middle`”\n o title (string) will create tooltip with a given text\n o transform (string) see @Element.transform\n o width (number)\n o x (number)\n o y (number)\n > Gradients\n * Linear gradient format: “`‹angle›-‹colour›[-‹colour›[:‹offset›]]*-‹colour›`”, example: “`90-#fff-#000`” – 90°\n * gradient from white to black or “`0-#fff-#f00:20-#000`” – 0° gradient from white via red (at 20%) to black.\n *\n * radial gradient: “`r[(‹fx›, ‹fy›)]‹colour›[-‹colour›[:‹offset›]]*-‹colour›`”, example: “`r#fff-#000`” –\n * gradient from white to black or “`r(0.25, 0.75)#fff-#000`” – gradient from white to black with focus point\n * at 0.25, 0.75. Focus point coordinates are in 0..1 range. Radial gradients can only be applied to circles and ellipses.\n > Path String\n # <p>Please refer to <a href=\"http://www.w3.org/TR/SVG/paths.html#PathData\" title=\"Details of a path’s data attribute’s format are described in the SVG specification.\">SVG documentation regarding path string</a>. Raphaël fully supports it.</p>\n > Colour Parsing\n # <ul>\n # <li>Colour name (“<code>red</code>”, “<code>green</code>”, “<code>cornflowerblue</code>”, etc)</li>\n # <li>#••• — shortened HTML colour: (“<code>#000</code>”, “<code>#fc0</code>”, etc)</li>\n # <li>#•••••• — full length HTML colour: (“<code>#000000</code>”, “<code>#bd2300</code>”)</li>\n # <li>rgb(•••, •••, •••) — red, green and blue channels’ values: (“<code>rgb(200, 100, 0)</code>”)</li>\n # <li>rgb(•••%, •••%, •••%) — same as above, but in %: (“<code>rgb(100%, 175%, 0%)</code>”)</li>\n # <li>rgba(•••, •••, •••, •••) — red, green and blue channels’ values: (“<code>rgba(200, 100, 0, .5)</code>”)</li>\n # <li>rgba(•••%, •••%, •••%, •••%) — same as above, but in %: (“<code>rgba(100%, 175%, 0%, 50%)</code>”)</li>\n # <li>hsb(•••, •••, •••) — hue, saturation and brightness values: (“<code>hsb(0.5, 0.25, 1)</code>”)</li>\n # <li>hsb(•••%, •••%, •••%) — same as above, but in %</li>\n # <li>hsba(•••, •••, •••, •••) — same as above, but with opacity</li>\n # <li>hsl(•••, •••, •••) — almost the same as hsb, see <a href=\"http://en.wikipedia.org/wiki/HSL_and_HSV\" title=\"HSL and HSV - Wikipedia, the free encyclopedia\">Wikipedia page</a></li>\n # <li>hsl(•••%, •••%, •••%) — same as above, but in %</li>\n # <li>hsla(•••, •••, •••, •••) — same as above, but with opacity</li>\n # <li>Optionally for hsb and hsl you could specify hue as a degree: “<code>hsl(240deg, 1, .5)</code>” or, if you want to go fancy, “<code>hsl(240°, 1, .5)</code>”</li>\n # </ul>\n \\*/\n elproto.attr = function (name, value) {\n if (this.removed) {\n return this;\n }\n if (name == null) {\n var res = {};\n for (var a in this.attrs) if (this.attrs[has](a)) {\n res[a] = this.attrs[a];\n }\n res.gradient && res.fill == \"none\" && (res.fill = res.gradient) && delete res.gradient;\n res.transform = this._.transform;\n return res;\n }\n if (value == null && R.is(name, \"string\")) {\n if (name == \"fill\" && this.attrs.fill == \"none\" && this.attrs.gradient) {\n return this.attrs.gradient;\n }\n if (name == \"transform\") {\n return this._.transform;\n }\n var names = name.split(separator),\n out = {};\n for (var i = 0, ii = names.length; i < ii; i++) {\n name = names[i];\n if (name in this.attrs) {\n out[name] = this.attrs[name];\n } else if (R.is(this.paper.customAttributes[name], \"function\")) {\n out[name] = this.paper.customAttributes[name].def;\n } else {\n out[name] = R._availableAttrs[name];\n }\n }\n return ii - 1 ? out : out[names[0]];\n }\n if (value == null && R.is(name, \"array\")) {\n out = {};\n for (i = 0, ii = name.length; i < ii; i++) {\n out[name[i]] = this.attr(name[i]);\n }\n return out;\n }\n if (value != null) {\n var params = {};\n params[name] = value;\n } else if (name != null && R.is(name, \"object\")) {\n params = name;\n }\n for (var key in params) {\n eve(\"raphael.attr.\" + key + \".\" + this.id, this, params[key]);\n }\n for (key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], \"function\")) {\n var par = this.paper.customAttributes[key].apply(this, [].concat(params[key]));\n this.attrs[key] = params[key];\n for (var subkey in par) if (par[has](subkey)) {\n params[subkey] = par[subkey];\n }\n }\n setFillAndStroke(this, params);\n return this;\n };\n /*\\\n * Element.toFront\n [ method ]\n **\n * Moves the element so it is the closest to the viewer’s eyes, on top of other elements.\n = (object) @Element\n \\*/\n elproto.toFront = function () {\n if (this.removed) {\n return this;\n }\n var node = getRealNode(this.node);\n node.parentNode.appendChild(node);\n var svg = this.paper;\n svg.top != this && R._tofront(this, svg);\n return this;\n };\n /*\\\n * Element.toBack\n [ method ]\n **\n * Moves the element so it is the furthest from the viewer’s eyes, behind other elements.\n = (object) @Element\n \\*/\n elproto.toBack = function () {\n if (this.removed) {\n return this;\n }\n var node = getRealNode(this.node);\n var parentNode = node.parentNode;\n parentNode.insertBefore(node, parentNode.firstChild);\n R._toback(this, this.paper);\n var svg = this.paper;\n return this;\n };\n /*\\\n * Element.insertAfter\n [ method ]\n **\n * Inserts current object after the given one.\n = (object) @Element\n \\*/\n elproto.insertAfter = function (element) {\n if (this.removed || !element) {\n return this;\n }\n\n var node = getRealNode(this.node);\n var afterNode = getRealNode(element.node || element[element.length - 1].node);\n if (afterNode.nextSibling) {\n afterNode.parentNode.insertBefore(node, afterNode.nextSibling);\n } else {\n afterNode.parentNode.appendChild(node);\n }\n R._insertafter(this, element, this.paper);\n return this;\n };\n /*\\\n * Element.insertBefore\n [ method ]\n **\n * Inserts current object before the given one.\n = (object) @Element\n \\*/\n elproto.insertBefore = function (element) {\n if (this.removed || !element) {\n return this;\n }\n\n var node = getRealNode(this.node);\n var beforeNode = getRealNode(element.node || element[0].node);\n beforeNode.parentNode.insertBefore(node, beforeNode);\n R._insertbefore(this, element, this.paper);\n return this;\n };\n elproto.blur = function (size) {\n // Experimental. No Safari support. Use it on your own risk.\n var t = this;\n if (+size !== 0) {\n var fltr = $(\"filter\"),\n blur = $(\"feGaussianBlur\");\n t.attrs.blur = size;\n fltr.id = R.createUUID();\n $(blur, {stdDeviation: +size || 1.5});\n fltr.appendChild(blur);\n t.paper.defs.appendChild(fltr);\n t._blur = fltr;\n $(t.node, {filter: \"url(#\" + fltr.id + \")\"});\n } else {\n if (t._blur) {\n t._blur.parentNode.removeChild(t._blur);\n delete t._blur;\n delete t.attrs.blur;\n }\n t.node.removeAttribute(\"filter\");\n }\n return t;\n };\n R._engine.circle = function (svg, x, y, r) {\n var el = $(\"circle\");\n svg.canvas && svg.canvas.appendChild(el);\n var res = new Element(el, svg);\n res.attrs = {cx: x, cy: y, r: r, fill: \"none\", stroke: \"#000\"};\n res.type = \"circle\";\n $(el, res.attrs);\n return res;\n };\n R._engine.rect = function (svg, x, y, w, h, r) {\n var el = $(\"rect\");\n svg.canvas && svg.canvas.appendChild(el);\n var res = new Element(el, svg);\n res.attrs = {x: x, y: y, width: w, height: h, rx: r || 0, ry: r || 0, fill: \"none\", stroke: \"#000\"};\n res.type = \"rect\";\n $(el, res.attrs);\n return res;\n };\n R._engine.ellipse = function (svg, x, y, rx, ry) {\n var el = $(\"ellipse\");\n svg.canvas && svg.canvas.appendChild(el);\n var res = new Element(el, svg);\n res.attrs = {cx: x, cy: y, rx: rx, ry: ry, fill: \"none\", stroke: \"#000\"};\n res.type = \"ellipse\";\n $(el, res.attrs);\n return res;\n };\n R._engine.image = function (svg, src, x, y, w, h) {\n var el = $(\"image\");\n $(el, {x: x, y: y, width: w, height: h, preserveAspectRatio: \"none\"});\n el.setAttributeNS(xlink, \"href\", src);\n svg.canvas && svg.canvas.appendChild(el);\n var res = new Element(el, svg);\n res.attrs = {x: x, y: y, width: w, height: h, src: src};\n res.type = \"image\";\n return res;\n };\n R._engine.text = function (svg, x, y, text) {\n var el = $(\"text\");\n svg.canvas && svg.canvas.appendChild(el);\n var res = new Element(el, svg);\n res.attrs = {\n x: x,\n y: y,\n \"text-anchor\": \"middle\",\n text: text,\n \"font-family\": R._availableAttrs[\"font-family\"],\n \"font-size\": R._availableAttrs[\"font-size\"],\n stroke: \"none\",\n fill: \"#000\"\n };\n res.type = \"text\";\n setFillAndStroke(res, res.attrs);\n return res;\n };\n R._engine.setSize = function (width, height) {\n this.width = width || this.width;\n this.height = height || this.height;\n this.canvas.setAttribute(\"width\", this.width);\n this.canvas.setAttribute(\"height\", this.height);\n if (this._viewBox) {\n this.setViewBox.apply(this, this._viewBox);\n }\n return this;\n };\n R._engine.create = function () {\n var con = R._getContainer.apply(0, arguments),\n container = con && con.container,\n x = con.x,\n y = con.y,\n width = con.width,\n height = con.height;\n if (!container) {\n throw new Error(\"SVG container not found.\");\n }\n var cnvs = $(\"svg\"),\n css = \"overflow:hidden;\",\n isFloating;\n x = x || 0;\n y = y || 0;\n width = width || 512;\n height = height || 342;\n $(cnvs, {\n height: height,\n version: 1.1,\n width: width,\n xmlns: \"http://www.w3.org/2000/svg\",\n \"xmlns:xlink\": \"http://www.w3.org/1999/xlink\"\n });\n if (container == 1) {\n cnvs.style.cssText = css + \"position:absolute;left:\" + x + \"px;top:\" + y + \"px\";\n R._g.doc.body.appendChild(cnvs);\n isFloating = 1;\n } else {\n cnvs.style.cssText = css + \"position:relative\";\n if (container.firstChild) {\n container.insertBefore(cnvs, container.firstChild);\n } else {\n container.appendChild(cnvs);\n }\n }\n container = new R._Paper;\n container.width = width;\n container.height = height;\n container.canvas = cnvs;\n container.clear();\n container._left = container._top = 0;\n isFloating && (container.renderfix = function () {});\n container.renderfix();\n return container;\n };\n R._engine.setViewBox = function (x, y, w, h, fit) {\n eve(\"raphael.setViewBox\", this, this._viewBox, [x, y, w, h, fit]);\n var paperSize = this.getSize(),\n size = mmax(w / paperSize.width, h / paperSize.height),\n top = this.top,\n aspectRatio = fit ? \"xMidYMid meet\" : \"xMinYMin\",\n vb,\n sw;\n if (x == null) {\n if (this._vbSize) {\n size = 1;\n }\n delete this._vbSize;\n vb = \"0 0 \" + this.width + S + this.height;\n } else {\n this._vbSize = size;\n vb = x + S + y + S + w + S + h;\n }\n $(this.canvas, {\n viewBox: vb,\n preserveAspectRatio: aspectRatio\n });\n while (size && top) {\n sw = \"stroke-width\" in top.attrs ? top.attrs[\"stroke-width\"] : 1;\n top.attr({\"stroke-width\": sw});\n top._.dirty = 1;\n top._.dirtyT = 1;\n top = top.prev;\n }\n this._viewBox = [x, y, w, h, !!fit];\n return this;\n };\n /*\\\n * Paper.renderfix\n [ method ]\n **\n * Fixes the issue of Firefox and IE9 regarding subpixel rendering. If paper is dependent\n * on other elements after reflow it could shift half pixel which cause for lines to lost their crispness.\n * This method fixes the issue.\n **\n Special thanks to Mariusz Nowak (http://www.medikoo.com/) for this method.\n \\*/\n R.prototype.renderfix = function () {\n var cnvs = this.canvas,\n s = cnvs.style,\n pos;\n try {\n pos = cnvs.getScreenCTM() || cnvs.createSVGMatrix();\n } catch (e) {\n pos = cnvs.createSVGMatrix();\n }\n var left = -pos.e % 1,\n top = -pos.f % 1;\n if (left || top) {\n if (left) {\n this._left = (this._left + left) % 1;\n s.left = this._left + \"px\";\n }\n if (top) {\n this._top = (this._top + top) % 1;\n s.top = this._top + \"px\";\n }\n }\n };\n /*\\\n * Paper.clear\n [ method ]\n **\n * Clears the paper, i.e. removes all the elements.\n \\*/\n R.prototype.clear = function () {\n R.eve(\"raphael.clear\", this);\n var c = this.canvas;\n while (c.firstChild) {\n c.removeChild(c.firstChild);\n }\n this.bottom = this.top = null;\n (this.desc = $(\"desc\")).appendChild(R._g.doc.createTextNode(\"Created with Rapha\\xebl \" + R.version));\n c.appendChild(this.desc);\n c.appendChild(this.defs = $(\"defs\"));\n };\n /*\\\n * Paper.remove\n [ method ]\n **\n * Removes the paper from the DOM.\n \\*/\n R.prototype.remove = function () {\n eve(\"raphael.remove\", this);\n this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas);\n for (var i in this) {\n this[i] = typeof this[i] == \"function\" ? R._removedFactory(i) : null;\n }\n };\n var setproto = R.st;\n for (var method in elproto) if (elproto[has](method) && !setproto[has](method)) {\n setproto[method] = (function (methodname) {\n return function () {\n var arg = arguments;\n return this.forEach(function (el) {\n el[methodname].apply(el, arg);\n });\n };\n })(method);\n }\n}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9kZXYvcmFwaGFlbC5zdmcuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9SYXBoYWVsLy4vZGV2L3JhcGhhZWwuc3ZnLmpzP2Q4YzciXSwic291cmNlc0NvbnRlbnQiOlsiZGVmaW5lKFtcIi4vcmFwaGFlbC5jb3JlXCJdLCBmdW5jdGlvbihSKSB7XG4gICAgaWYgKFIgJiYgIVIuc3ZnKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgaGFzID0gXCJoYXNPd25Qcm9wZXJ0eVwiLFxuICAgICAgICBTdHIgPSBTdHJpbmcsXG4gICAgICAgIHRvRmxvYXQgPSBwYXJzZUZsb2F0LFxuICAgICAgICB0b0ludCA9IHBhcnNlSW50LFxuICAgICAgICBtYXRoID0gTWF0aCxcbiAgICAgICAgbW1heCA9IG1hdGgubWF4LFxuICAgICAgICBhYnMgPSBtYXRoLmFicyxcbiAgICAgICAgcG93ID0gbWF0aC5wb3csXG4gICAgICAgIHNlcGFyYXRvciA9IC9bLCBdKy8sXG4gICAgICAgIGV2ZSA9IFIuZXZlLFxuICAgICAgICBFID0gXCJcIixcbiAgICAgICAgUyA9IFwiIFwiO1xuICAgIHZhciB4bGluayA9IFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiLFxuICAgICAgICBtYXJrZXJzID0ge1xuICAgICAgICAgICAgYmxvY2s6IFwiTTUsMCAwLDIuNSA1LDV6XCIsXG4gICAgICAgICAgICBjbGFzc2ljOiBcIk01LDAgMCwyLjUgNSw1IDMuNSwzIDMuNSwyelwiLFxuICAgICAgICAgICAgZGlhbW9uZDogXCJNMi41LDAgNSwyLjUgMi41LDUgMCwyLjV6XCIsXG4gICAgICAgICAgICBvcGVuOiBcIk02LDEgMSwzLjUgNiw2XCIsXG4gICAgICAgICAgICBvdmFsOiBcIk0yLjUsMEEyLjUsMi41LDAsMCwxLDIuNSw1IDIuNSwyLjUsMCwwLDEsMi41LDB6XCJcbiAgICAgICAgfSxcbiAgICAgICAgbWFya2VyQ291bnRlciA9IHt9O1xuICAgIFIudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAgXCJZb3VyIGJyb3dzZXIgc3VwcG9ydHMgU1ZHLlxcbllvdSBhcmUgcnVubmluZyBSYXBoYVxceGVibCBcIiArIHRoaXMudmVyc2lvbjtcbiAgICB9O1xuICAgIHZhciAkID0gZnVuY3Rpb24gKGVsLCBhdHRyKSB7XG4gICAgICAgIGlmIChhdHRyKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGVsID09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICBlbCA9ICQoZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIGF0dHIpIGlmIChhdHRyW2hhc10oa2V5KSkge1xuICAgICAgICAgICAgICAgIGlmIChrZXkuc3Vic3RyaW5nKDAsIDYpID09IFwieGxpbms6XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgZWwuc2V0QXR0cmlidXRlTlMoeGxpbmssIGtleS5zdWJzdHJpbmcoNiksIFN0cihhdHRyW2tleV0pKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoa2V5LCBTdHIoYXR0cltrZXldKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZWwgPSBSLl9nLmRvYy5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLCBlbCk7XG4gICAgICAgICAgICBlbC5zdHlsZSAmJiAoZWwuc3R5bGUud2Via2l0VGFwSGlnaGxpZ2h0Q29sb3IgPSBcInJnYmEoMCwwLDAsMClcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGVsO1xuICAgIH0sXG4gICAgYWRkR3JhZGllbnRGaWxsID0gZnVuY3Rpb24gKGVsZW1lbnQsIGdyYWRpZW50KSB7XG4gICAgICAgIHZhciB0eXBlID0gXCJsaW5lYXJcIixcbiAgICAgICAgICAgIGlkID0gZWxlbWVudC5pZCArIGdyYWRpZW50LFxuICAgICAgICAgICAgZnggPSAuNSwgZnkgPSAuNSxcbiAgICAgICAgICAgIG8gPSBlbGVtZW50Lm5vZGUsXG4gICAgICAgICAgICBTVkcgPSBlbGVtZW50LnBhcGVyLFxuICAgICAgICAgICAgcyA9IG8uc3R5bGUsXG4gICAgICAgICAgICBlbCA9IFIuX2cuZG9jLmdldEVsZW1lbnRCeUlkKGlkKTtcbiAgICAgICAgaWYgKCFlbCkge1xuICAgICAgICAgICAgZ3JhZGllbnQgPSBTdHIoZ3JhZGllbnQpLnJlcGxhY2UoUi5fcmFkaWFsX2dyYWRpZW50LCBmdW5jdGlvbiAoYWxsLCBfZngsIF9meSkge1xuICAgICAgICAgICAgICAgIHR5cGUgPSBcInJhZGlhbFwiO1xuICAgICAgICAgICAgICAgIGlmIChfZnggJiYgX2Z5KSB7XG4gICAgICAgICAgICAgICAgICAgIGZ4ID0gdG9GbG9hdChfZngpO1xuICAgICAgICAgICAgICAgICAgICBmeSA9IHRvRmxvYXQoX2Z5KTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRpciA9ICgoZnkgPiAuNSkgKiAyIC0gMSk7XG4gICAgICAgICAgICAgICAgICAgIHBvdyhmeCAtIC41LCAyKSArIHBvdyhmeSAtIC41LCAyKSA+IC4yNSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKGZ5ID0gbWF0aC5zcXJ0KC4yNSAtIHBvdyhmeCAtIC41LCAyKSkgKiBkaXIgKyAuNSkgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIGZ5ICE9IC41ICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAoZnkgPSBmeS50b0ZpeGVkKDUpIC0gMWUtNSAqIGRpcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBFO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBncmFkaWVudCA9IGdyYWRpZW50LnNwbGl0KC9cXHMqXFwtXFxzKi8pO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJsaW5lYXJcIikge1xuICAgICAgICAgICAgICAgIHZhciBhbmdsZSA9IGdyYWRpZW50LnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgYW5nbGUgPSAtdG9GbG9hdChhbmdsZSk7XG4gICAgICAgICAgICAgICAgaWYgKGlzTmFOKGFuZ2xlKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIHZlY3RvciA9IFswLCAwLCBtYXRoLmNvcyhSLnJhZChhbmdsZSkpLCBtYXRoLnNpbihSLnJhZChhbmdsZSkpXSxcbiAgICAgICAgICAgICAgICAgICAgbWF4ID0gMSAvIChtbWF4KGFicyh2ZWN0b3JbMl0pLCBhYnModmVjdG9yWzNdKSkgfHwgMSk7XG4gICAgICAgICAgICAgICAgdmVjdG9yWzJdICo9IG1heDtcbiAgICAgICAgICAgICAgICB2ZWN0b3JbM10gKj0gbWF4O1xuICAgICAgICAgICAgICAgIGlmICh2ZWN0b3JbMl0gPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZlY3RvclswXSA9IC12ZWN0b3JbMl07XG4gICAgICAgICAgICAgICAgICAgIHZlY3RvclsyXSA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh2ZWN0b3JbM10gPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZlY3RvclsxXSA9IC12ZWN0b3JbM107XG4gICAgICAgICAgICAgICAgICAgIHZlY3RvclszXSA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGRvdHMgPSBSLl9wYXJzZURvdHMoZ3JhZGllbnQpO1xuICAgICAgICAgICAgaWYgKCFkb3RzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZCA9IGlkLnJlcGxhY2UoL1tcXChcXClcXHMsXFx4YjAjXS9nLCBcIl9cIik7XG5cbiAgICAgICAgICAgIGlmIChlbGVtZW50LmdyYWRpZW50ICYmIGlkICE9IGVsZW1lbnQuZ3JhZGllbnQuaWQpIHtcbiAgICAgICAgICAgICAgICBTVkcuZGVmcy5yZW1vdmVDaGlsZChlbGVtZW50LmdyYWRpZW50KTtcbiAgICAgICAgICAgICAgICBkZWxldGUgZWxlbWVudC5ncmFkaWVudDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFlbGVtZW50LmdyYWRpZW50KSB7XG4gICAgICAgICAgICAgICAgZWwgPSAkKHR5cGUgKyBcIkdyYWRpZW50XCIsIHtpZDogaWR9KTtcbiAgICAgICAgICAgICAgICBlbGVtZW50LmdyYWRpZW50ID0gZWw7XG4gICAgICAgICAgICAgICAgJChlbCwgdHlwZSA9PSBcInJhZGlhbFwiID8ge1xuICAgICAgICAgICAgICAgICAgICBmeDogZngsXG4gICAgICAgICAgICAgICAgICAgIGZ5OiBmeVxuICAgICAgICAgICAgICAgIH0gOiB7XG4gICAgICAgICAgICAgICAgICAgIHgxOiB2ZWN0b3JbMF0sXG4gICAgICAgICAgICAgICAgICAgIHkxOiB2ZWN0b3JbMV0sXG4gICAgICAgICAgICAgICAgICAgIHgyOiB2ZWN0b3JbMl0sXG4gICAgICAgICAgICAgICAgICAgIHkyOiB2ZWN0b3JbM10sXG4gICAgICAgICAgICAgICAgICAgIGdyYWRpZW50VHJhbnNmb3JtOiBlbGVtZW50Lm1hdHJpeC5pbnZlcnQoKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIFNWRy5kZWZzLmFwcGVuZENoaWxkKGVsKTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBkb3RzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgZWwuYXBwZW5kQ2hpbGQoJChcInN0b3BcIiwge1xuICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiBkb3RzW2ldLm9mZnNldCA/IGRvdHNbaV0ub2Zmc2V0IDogaSA/IFwiMTAwJVwiIDogXCIwJVwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJzdG9wLWNvbG9yXCI6IGRvdHNbaV0uY29sb3IgfHwgXCIjZmZmXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBcInN0b3Atb3BhY2l0eVwiOiBpc0Zpbml0ZShkb3RzW2ldLm9wYWNpdHkpID8gZG90c1tpXS5vcGFjaXR5IDogMVxuICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgICQobywge1xuICAgICAgICAgICAgZmlsbDogZmlsbHVybChpZCksXG4gICAgICAgICAgICBvcGFjaXR5OiAxLFxuICAgICAgICAgICAgXCJmaWxsLW9wYWNpdHlcIjogMVxuICAgICAgICB9KTtcbiAgICAgICAgcy5maWxsID0gRTtcbiAgICAgICAgcy5vcGFjaXR5ID0gMTtcbiAgICAgICAgcy5maWxsT3BhY2l0eSA9IDE7XG4gICAgICAgIHJldHVybiAxO1xuICAgIH0sXG4gICAgaXNJRTlvcjEwID0gZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIG1vZGUgPSBkb2N1bWVudC5kb2N1bWVudE1vZGU7XG4gICAgICByZXR1cm4gbW9kZSAmJiAobW9kZSA9PT0gOSB8fCBtb2RlID09PSAxMCk7XG4gICAgfSxcbiAgICBmaWxsdXJsID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBpZiAoaXNJRTlvcjEwKCkpIHtcbiAgICAgICAgICByZXR1cm4gXCJ1cmwoJyNcIiArIGlkICsgXCInKVwiO1xuICAgICAgfVxuICAgICAgdmFyIGxvY2F0aW9uID0gZG9jdW1lbnQubG9jYXRpb247XG4gICAgICB2YXIgbG9jYXRpb25TdHJpbmcgPSAoXG4gICAgICAgICAgbG9jYXRpb24ucHJvdG9jb2wgKyAnLy8nICtcbiAgICAgICAgICBsb2NhdGlvbi5ob3N0ICtcbiAgICAgICAgICBsb2NhdGlvbi5wYXRobmFtZSArXG4gICAgICAgICAgbG9jYXRpb24uc2VhcmNoXG4gICAgICApO1xuICAgICAgcmV0dXJuIFwidXJsKCdcIiArIGxvY2F0aW9uU3RyaW5nICsgXCIjXCIgKyBpZCArIFwiJylcIjtcbiAgICB9LFxuICAgIHVwZGF0ZVBvc2l0aW9uID0gZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgdmFyIGJib3ggPSBvLmdldEJCb3goMSk7XG4gICAgICAgICQoby5wYXR0ZXJuLCB7cGF0dGVyblRyYW5zZm9ybTogby5tYXRyaXguaW52ZXJ0KCkgKyBcIiB0cmFuc2xhdGUoXCIgKyBiYm94LnggKyBcIixcIiArIGJib3gueSArIFwiKVwifSk7XG4gICAgfSxcbiAgICBhZGRBcnJvdyA9IGZ1bmN0aW9uIChvLCB2YWx1ZSwgaXNFbmQpIHtcbiAgICAgICAgaWYgKG8udHlwZSA9PSBcInBhdGhcIikge1xuICAgICAgICAgICAgdmFyIHZhbHVlcyA9IFN0cih2YWx1ZSkudG9Mb3dlckNhc2UoKS5zcGxpdChcIi1cIiksXG4gICAgICAgICAgICAgICAgcCA9IG8ucGFwZXIsXG4gICAgICAgICAgICAgICAgc2UgPSBpc0VuZCA/IFwiZW5kXCIgOiBcInN0YXJ0XCIsXG4gICAgICAgICAgICAgICAgbm9kZSA9IG8ubm9kZSxcbiAgICAgICAgICAgICAgICBhdHRycyA9IG8uYXR0cnMsXG4gICAgICAgICAgICAgICAgc3Ryb2tlID0gYXR0cnNbXCJzdHJva2Utd2lkdGhcIl0sXG4gICAgICAgICAgICAgICAgaSA9IHZhbHVlcy5sZW5ndGgsXG4gICAgICAgICAgICAgICAgdHlwZSA9IFwiY2xhc3NpY1wiLFxuICAgICAgICAgICAgICAgIGZyb20sXG4gICAgICAgICAgICAgICAgdG8sXG4gICAgICAgICAgICAgICAgZHgsXG4gICAgICAgICAgICAgICAgcmVmWCxcbiAgICAgICAgICAgICAgICBhdHRyLFxuICAgICAgICAgICAgICAgIHcgPSAzLFxuICAgICAgICAgICAgICAgIGggPSAzLFxuICAgICAgICAgICAgICAgIHQgPSA1O1xuICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodmFsdWVzW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJibG9ja1wiOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiY2xhc3NpY1wiOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwib3ZhbFwiOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZGlhbW9uZFwiOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwib3BlblwiOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwibm9uZVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSA9IHZhbHVlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwid2lkZVwiOiBoID0gNTsgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJuYXJyb3dcIjogaCA9IDI7IGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwibG9uZ1wiOiB3ID0gNTsgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJzaG9ydFwiOiB3ID0gMjsgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJvcGVuXCIpIHtcbiAgICAgICAgICAgICAgICB3ICs9IDI7XG4gICAgICAgICAgICAgICAgaCArPSAyO1xuICAgICAgICAgICAgICAgIHQgKz0gMjtcbiAgICAgICAgICAgICAgICBkeCA9IDE7XG4gICAgICAgICAgICAgICAgcmVmWCA9IGlzRW5kID8gNCA6IDE7XG4gICAgICAgICAgICAgICAgYXR0ciA9IHtcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogXCJub25lXCIsXG4gICAgICAgICAgICAgICAgICAgIHN0cm9rZTogYXR0cnMuc3Ryb2tlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVmWCA9IGR4ID0gdyAvIDI7XG4gICAgICAgICAgICAgICAgYXR0ciA9IHtcbiAgICAgICAgICAgICAgICAgICAgZmlsbDogYXR0cnMuc3Ryb2tlLFxuICAgICAgICAgICAgICAgICAgICBzdHJva2U6IFwibm9uZVwiXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvLl8uYXJyb3dzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzRW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIG8uXy5hcnJvd3MuZW5kUGF0aCAmJiBtYXJrZXJDb3VudGVyW28uXy5hcnJvd3MuZW5kUGF0aF0tLTtcbiAgICAgICAgICAgICAgICAgICAgby5fLmFycm93cy5lbmRNYXJrZXIgJiYgbWFya2VyQ291bnRlcltvLl8uYXJyb3dzLmVuZE1hcmtlcl0tLTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBvLl8uYXJyb3dzLnN0YXJ0UGF0aCAmJiBtYXJrZXJDb3VudGVyW28uXy5hcnJvd3Muc3RhcnRQYXRoXS0tO1xuICAgICAgICAgICAgICAgICAgICBvLl8uYXJyb3dzLnN0YXJ0TWFya2VyICYmIG1hcmtlckNvdW50ZXJbby5fLmFycm93cy5zdGFydE1hcmtlcl0tLTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG8uXy5hcnJvd3MgPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlICE9IFwibm9uZVwiKSB7XG4gICAgICAgICAgICAgICAgdmFyIHBhdGhJZCA9IFwicmFwaGFlbC1tYXJrZXItXCIgKyB0eXBlLFxuICAgICAgICAgICAgICAgICAgICBtYXJrZXJJZCA9IFwicmFwaGFlbC1tYXJrZXItXCIgKyBzZSArIHR5cGUgKyB3ICsgaCArIFwiLW9ialwiICsgby5pZDtcbiAgICAgICAgICAgICAgICBpZiAoIVIuX2cuZG9jLmdldEVsZW1lbnRCeUlkKHBhdGhJZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcC5kZWZzLmFwcGVuZENoaWxkKCQoJChcInBhdGhcIiksIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwic3Ryb2tlLWxpbmVjYXBcIjogXCJyb3VuZFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgZDogbWFya2Vyc1t0eXBlXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBwYXRoSWRcbiAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICBtYXJrZXJDb3VudGVyW3BhdGhJZF0gPSAxO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG1hcmtlckNvdW50ZXJbcGF0aElkXSsrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgbWFya2VyID0gUi5fZy5kb2MuZ2V0RWxlbWVudEJ5SWQobWFya2VySWQpLFxuICAgICAgICAgICAgICAgICAgICB1c2U7XG4gICAgICAgICAgICAgICAgaWYgKCFtYXJrZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgbWFya2VyID0gJCgkKFwibWFya2VyXCIpLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZDogbWFya2VySWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXJrZXJIZWlnaHQ6IGgsXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXJrZXJXaWR0aDogdyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudDogXCJhdXRvXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICByZWZYOiByZWZYLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmWTogaCAvIDJcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHVzZSA9ICQoJChcInVzZVwiKSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgXCJ4bGluazpocmVmXCI6IFwiI1wiICsgcGF0aElkLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtOiAoaXNFbmQgPyBcInJvdGF0ZSgxODAgXCIgKyB3IC8gMiArIFwiIFwiICsgaCAvIDIgKyBcIikgXCIgOiBFKSArIFwic2NhbGUoXCIgKyB3IC8gdCArIFwiLFwiICsgaCAvIHQgKyBcIilcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIFwic3Ryb2tlLXdpZHRoXCI6ICgxIC8gKCh3IC8gdCArIGggLyB0KSAvIDIpKS50b0ZpeGVkKDQpXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBtYXJrZXIuYXBwZW5kQ2hpbGQodXNlKTtcbiAgICAgICAgICAgICAgICAgICAgcC5kZWZzLmFwcGVuZENoaWxkKG1hcmtlcik7XG4gICAgICAgICAgICAgICAgICAgIG1hcmtlckNvdW50ZXJbbWFya2VySWRdID0gMTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBtYXJrZXJDb3VudGVyW21hcmtlcklkXSsrO1xuICAgICAgICAgICAgICAgICAgICB1c2UgPSBtYXJrZXIuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJ1c2VcIilbMF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICQodXNlLCBhdHRyKTtcbiAgICAgICAgICAgICAgICB2YXIgZGVsdGEgPSBkeCAqICh0eXBlICE9IFwiZGlhbW9uZFwiICYmIHR5cGUgIT0gXCJvdmFsXCIpO1xuICAgICAgICAgICAgICAgIGlmIChpc0VuZCkge1xuICAgICAgICAgICAgICAgICAgICBmcm9tID0gby5fLmFycm93cy5zdGFydGR4ICogc3Ryb2tlIHx8IDA7XG4gICAgICAgICAgICAgICAgICAgIHRvID0gUi5nZXRUb3RhbExlbmd0aChhdHRycy5wYXRoKSAtIGRlbHRhICogc3Ryb2tlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZyb20gPSBkZWx0YSAqIHN0cm9rZTtcbiAgICAgICAgICAgICAgICAgICAgdG8gPSBSLmdldFRvdGFsTGVuZ3RoKGF0dHJzLnBhdGgpIC0gKG8uXy5hcnJvd3MuZW5kZHggKiBzdHJva2UgfHwgMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF0dHIgPSB7fTtcbiAgICAgICAgICAgICAgICBhdHRyW1wibWFya2VyLVwiICsgc2VdID0gXCJ1cmwoI1wiICsgbWFya2VySWQgKyBcIilcIjtcbiAgICAgICAgICAgICAgICBpZiAodG8gfHwgZnJvbSkge1xuICAgICAgICAgICAgICAgICAgICBhdHRyLmQgPSBSLmdldFN1YnBhdGgoYXR0cnMucGF0aCwgZnJvbSwgdG8pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAkKG5vZGUsIGF0dHIpO1xuICAgICAgICAgICAgICAgIG8uXy5hcnJvd3Nbc2UgKyBcIlBhdGhcIl0gPSBwYXRoSWQ7XG4gICAgICAgICAgICAgICAgby5fLmFycm93c1tzZSArIFwiTWFya2VyXCJdID0gbWFya2VySWQ7XG4gICAgICAgICAgICAgICAgby5fLmFycm93c1tzZSArIFwiZHhcIl0gPSBkZWx0YTtcbiAgICAgICAgICAgICAgICBvLl8uYXJyb3dzW3NlICsgXCJUeXBlXCJdID0gdHlwZTtcbiAgICAgICAgICAgICAgICBvLl8uYXJyb3dzW3NlICsgXCJTdHJpbmdcIl0gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzRW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIGZyb20gPSBvLl8uYXJyb3dzLnN0YXJ0ZHggKiBzdHJva2UgfHwgMDtcbiAgICAgICAgICAgICAgICAgICAgdG8gPSBSLmdldFRvdGFsTGVuZ3RoKGF0dHJzLnBhdGgpIC0gZnJvbTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmcm9tID0gMDtcbiAgICAgICAgICAgICAgICAgICAgdG8gPSBSLmdldFRvdGFsTGVuZ3RoKGF0dHJzLnBhdGgpIC0gKG8uXy5hcnJvd3MuZW5kZHggKiBzdHJva2UgfHwgMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG8uXy5hcnJvd3Nbc2UgKyBcIlBhdGhcIl0gJiYgJChub2RlLCB7ZDogUi5nZXRTdWJwYXRoKGF0dHJzLnBhdGgsIGZyb20sIHRvKX0pO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBvLl8uYXJyb3dzW3NlICsgXCJQYXRoXCJdO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBvLl8uYXJyb3dzW3NlICsgXCJNYXJrZXJcIl07XG4gICAgICAgICAgICAgICAgZGVsZXRlIG8uXy5hcnJvd3Nbc2UgKyBcImR4XCJdO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBvLl8uYXJyb3dzW3NlICsgXCJUeXBlXCJdO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBvLl8uYXJyb3dzW3NlICsgXCJTdHJpbmdcIl07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGF0dHIgaW4gbWFya2VyQ291bnRlcikgaWYgKG1hcmtlckNvdW50ZXJbaGFzXShhdHRyKSAmJiAhbWFya2VyQ291bnRlclthdHRyXSkge1xuICAgICAgICAgICAgICAgIHZhciBpdGVtID0gUi5fZy5kb2MuZ2V0RWxlbWVudEJ5SWQoYXR0cik7XG4gICAgICAgICAgICAgICAgaXRlbSAmJiBpdGVtLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoaXRlbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGRhc2hhcnJheSA9IHtcbiAgICAgICAgXCItXCI6IFszLCAxXSxcbiAgICAgICAgXCIuXCI6IFsxLCAxXSxcbiAgICAgICAgXCItLlwiOiBbMywgMSwgMSwgMV0sXG4gICAgICAgIFwiLS4uXCI6IFszLCAxLCAxLCAxLCAxLCAxXSxcbiAgICAgICAgXCIuIFwiOiBbMSwgM10sXG4gICAgICAgIFwiLSBcIjogWzQsIDNdLFxuICAgICAgICBcIi0tXCI6IFs4LCAzXSxcbiAgICAgICAgXCItIC5cIjogWzQsIDMsIDEsIDNdLFxuICAgICAgICBcIi0tLlwiOiBbOCwgMywgMSwgM10sXG4gICAgICAgIFwiLS0uLlwiOiBbOCwgMywgMSwgMywgMSwgM11cbiAgICB9LFxuICAgIGFkZERhc2hlcyA9IGZ1bmN0aW9uIChvLCB2YWx1ZSwgcGFyYW1zKSB7XG4gICAgICAgIHZhbHVlID0gZGFzaGFycmF5W1N0cih2YWx1ZSkudG9Mb3dlckNhc2UoKV07XG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgdmFyIHdpZHRoID0gby5hdHRyc1tcInN0cm9rZS13aWR0aFwiXSB8fCBcIjFcIixcbiAgICAgICAgICAgICAgICBidXR0ID0ge3JvdW5kOiB3aWR0aCwgc3F1YXJlOiB3aWR0aCwgYnV0dDogMH1bby5hdHRyc1tcInN0cm9rZS1saW5lY2FwXCJdIHx8IHBhcmFtc1tcInN0cm9rZS1saW5lY2FwXCJdXSB8fCAwLFxuICAgICAgICAgICAgICAgIGRhc2hlcyA9IFtdLFxuICAgICAgICAgICAgICAgIGkgPSB2YWx1ZS5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgZGFzaGVzW2ldID0gdmFsdWVbaV0gKiB3aWR0aCArICgoaSAlIDIpID8gMSA6IC0xKSAqIGJ1dHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAkKG8ubm9kZSwge1wic3Ryb2tlLWRhc2hhcnJheVwiOiBkYXNoZXMuam9pbihcIixcIil9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAkKG8ubm9kZSwge1wic3Ryb2tlLWRhc2hhcnJheVwiOiBcIm5vbmVcIn0pO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBzZXRGaWxsQW5kU3Ryb2tlID0gZnVuY3Rpb24gKG8sIHBhcmFtcykge1xuICAgICAgICB2YXIgbm9kZSA9IG8ubm9kZSxcbiAgICAgICAgICAgIGF0dHJzID0gby5hdHRycyxcbiAgICAgICAgICAgIHZpcyA9IG5vZGUuc3R5bGUudmlzaWJpbGl0eTtcbiAgICAgICAgbm9kZS5zdHlsZS52aXNpYmlsaXR5ID0gXCJoaWRkZW5cIjtcbiAgICAgICAgZm9yICh2YXIgYXR0IGluIHBhcmFtcykge1xuICAgICAgICAgICAgaWYgKHBhcmFtc1toYXNdKGF0dCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIVIuX2F2YWlsYWJsZUF0dHJzW2hhc10oYXR0KSkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gcGFyYW1zW2F0dF07XG4gICAgICAgICAgICAgICAgYXR0cnNbYXR0XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoYXR0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJibHVyXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBvLmJsdXIodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJ0aXRsZVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRpdGxlID0gbm9kZS5nZXRFbGVtZW50c0J5VGFnTmFtZShcInRpdGxlXCIpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBVc2UgdGhlIGV4aXN0aW5nIDx0aXRsZT4uXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGl0bGUubGVuZ3RoICYmICh0aXRsZSA9IHRpdGxlWzBdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZS5maXJzdENoaWxkLm5vZGVWYWx1ZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAkKFwidGl0bGVcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWwgPSBSLl9nLmRvYy5jcmVhdGVUZXh0Tm9kZSh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlLmFwcGVuZENoaWxkKHZhbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuYXBwZW5kQ2hpbGQodGl0bGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJocmVmXCI6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJ0YXJnZXRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwbiA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwbi50YWdOYW1lLnRvTG93ZXJDYXNlKCkgIT0gXCJhXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGwgPSAkKFwiYVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbi5pbnNlcnRCZWZvcmUoaGwsIG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhsLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBuID0gaGw7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ID09IFwidGFyZ2V0XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbi5zZXRBdHRyaWJ1dGVOUyh4bGluaywgXCJzaG93XCIsIHZhbHVlID09IFwiYmxhbmtcIiA/IFwibmV3XCIgOiB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBuLnNldEF0dHJpYnV0ZU5TKHhsaW5rLCBhdHQsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiY3Vyc29yXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLnN0eWxlLmN1cnNvciA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJ0cmFuc2Zvcm1cIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIG8udHJhbnNmb3JtKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiYXJyb3ctc3RhcnRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZEFycm93KG8sIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiYXJyb3ctZW5kXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRBcnJvdyhvLCB2YWx1ZSwgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImNsaXAtcmVjdFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlY3QgPSBTdHIodmFsdWUpLnNwbGl0KHNlcGFyYXRvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVjdC5sZW5ndGggPT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG8uY2xpcCAmJiBvLmNsaXAucGFyZW50Tm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG8uY2xpcC5wYXJlbnROb2RlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWwgPSAkKFwiY2xpcFBhdGhcIiksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJjID0gJChcInJlY3RcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwuaWQgPSBSLmNyZWF0ZVVVSUQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKHJjLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IHJlY3RbMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IHJlY3RbMV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiByZWN0WzJdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHJlY3RbM11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5hcHBlbmRDaGlsZChyYyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgby5wYXBlci5kZWZzLmFwcGVuZENoaWxkKGVsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKG5vZGUsIHtcImNsaXAtcGF0aFwiOiBcInVybCgjXCIgKyBlbC5pZCArIFwiKVwifSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgby5jbGlwID0gcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhdGggPSBub2RlLmdldEF0dHJpYnV0ZShcImNsaXAtcGF0aFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2xpcCA9IFIuX2cuZG9jLmdldEVsZW1lbnRCeUlkKHBhdGgucmVwbGFjZSgvKF51cmxcXCgjfFxcKSQpL2csIEUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpcCAmJiBjbGlwLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY2xpcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQobm9kZSwge1wiY2xpcC1wYXRoXCI6IEV9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIG8uY2xpcDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwicGF0aFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG8udHlwZSA9PSBcInBhdGhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQobm9kZSwge2Q6IHZhbHVlID8gYXR0cnMucGF0aCA9IFIuX3BhdGhUb0Fic29sdXRlKHZhbHVlKSA6IFwiTTAsMFwifSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgby5fLmRpcnR5ID0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoby5fLmFycm93cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcInN0YXJ0U3RyaW5nXCIgaW4gby5fLmFycm93cyAmJiBhZGRBcnJvdyhvLCBvLl8uYXJyb3dzLnN0YXJ0U3RyaW5nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJlbmRTdHJpbmdcIiBpbiBvLl8uYXJyb3dzICYmIGFkZEFycm93KG8sIG8uXy5hcnJvd3MuZW5kU3RyaW5nLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcIndpZHRoXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShhdHQsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG8uXy5kaXJ0eSA9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0cnMuZngpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHQgPSBcInhcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGF0dHJzLng7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwieFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJzLmZ4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSAtYXR0cnMueCAtIChhdHRycy53aWR0aCB8fCAwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInJ4XCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ID09IFwicnhcIiAmJiBvLnR5cGUgPT0gXCJyZWN0XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImN4XCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShhdHQsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG8ucGF0dGVybiAmJiB1cGRhdGVQb3NpdGlvbihvKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG8uXy5kaXJ0eSA9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImhlaWdodFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoYXR0LCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBvLl8uZGlydHkgPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJzLmZ5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ID0gXCJ5XCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBhdHRycy55O1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInlcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRycy5meSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gLWF0dHJzLnkgLSAoYXR0cnMuaGVpZ2h0IHx8IDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwicnlcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHQgPT0gXCJyeVwiICYmIG8udHlwZSA9PSBcInJlY3RcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiY3lcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKGF0dCwgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgby5wYXR0ZXJuICYmIHVwZGF0ZVBvc2l0aW9uKG8pO1xuICAgICAgICAgICAgICAgICAgICAgICAgby5fLmRpcnR5ID0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiclwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG8udHlwZSA9PSBcInJlY3RcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQobm9kZSwge3J4OiB2YWx1ZSwgcnk6IHZhbHVlfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlKGF0dCwgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgby5fLmRpcnR5ID0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwic3JjXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoby50eXBlID09IFwiaW1hZ2VcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuc2V0QXR0cmlidXRlTlMoeGxpbmssIFwiaHJlZlwiLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInN0cm9rZS13aWR0aFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG8uXy5zeCAhPSAxIHx8IG8uXy5zeSAhPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgLz0gbW1heChhYnMoby5fLnN4KSwgYWJzKG8uXy5zeSkpIHx8IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZShhdHQsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyc1tcInN0cm9rZS1kYXNoYXJyYXlcIl0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGREYXNoZXMobywgYXR0cnNbXCJzdHJva2UtZGFzaGFycmF5XCJdLCBwYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG8uXy5hcnJvd3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcInN0YXJ0U3RyaW5nXCIgaW4gby5fLmFycm93cyAmJiBhZGRBcnJvdyhvLCBvLl8uYXJyb3dzLnN0YXJ0U3RyaW5nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImVuZFN0cmluZ1wiIGluIG8uXy5hcnJvd3MgJiYgYWRkQXJyb3cobywgby5fLmFycm93cy5lbmRTdHJpbmcsIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJzdHJva2UtZGFzaGFycmF5XCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBhZGREYXNoZXMobywgdmFsdWUsIHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImZpbGxcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpc1VSTCA9IFN0cih2YWx1ZSkubWF0Y2goUi5fSVNVUkwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzVVJMKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSAkKFwicGF0dGVyblwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaWcgPSAkKFwiaW1hZ2VcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwuaWQgPSBSLmNyZWF0ZVVVSUQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKGVsLCB7eDogMCwgeTogMCwgcGF0dGVyblVuaXRzOiBcInVzZXJTcGFjZU9uVXNlXCIsIGhlaWdodDogMSwgd2lkdGg6IDF9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKGlnLCB7eDogMCwgeTogMCwgXCJ4bGluazpocmVmXCI6IGlzVVJMWzFdfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwuYXBwZW5kQ2hpbGQoaWcpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSLl9wcmVsb2FkKGlzVVJMWzFdLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdyA9IHRoaXMub2Zmc2V0V2lkdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaCA9IHRoaXMub2Zmc2V0SGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJChlbCwge3dpZHRoOiB3LCBoZWlnaHQ6IGh9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQoaWcsIHt3aWR0aDogdywgaGVpZ2h0OiBofSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKGVsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvLnBhcGVyLmRlZnMuYXBwZW5kQ2hpbGQoZWwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICQobm9kZSwge2ZpbGw6IFwidXJsKCNcIiArIGVsLmlkICsgXCIpXCJ9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvLnBhdHRlcm4gPSBlbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvLnBhdHRlcm4gJiYgdXBkYXRlUG9zaXRpb24obyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2xyID0gUi5nZXRSR0IodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjbHIuZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgcGFyYW1zLmdyYWRpZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBhdHRycy5ncmFkaWVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhUi5pcyhhdHRycy5vcGFjaXR5LCBcInVuZGVmaW5lZFwiKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSLmlzKHBhcmFtcy5vcGFjaXR5LCBcInVuZGVmaW5lZFwiKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKG5vZGUsIHtvcGFjaXR5OiBhdHRycy5vcGFjaXR5fSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIVIuaXMoYXR0cnNbXCJmaWxsLW9wYWNpdHlcIl0sIFwidW5kZWZpbmVkXCIpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFIuaXMocGFyYW1zW1wiZmlsbC1vcGFjaXR5XCJdLCBcInVuZGVmaW5lZFwiKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKG5vZGUsIHtcImZpbGwtb3BhY2l0eVwiOiBhdHRyc1tcImZpbGwtb3BhY2l0eVwiXX0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoby50eXBlID09IFwiY2lyY2xlXCIgfHwgby50eXBlID09IFwiZWxsaXBzZVwiIHx8IFN0cih2YWx1ZSkuY2hhckF0KCkgIT0gXCJyXCIpICYmIGFkZEdyYWRpZW50RmlsbChvLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoXCJvcGFjaXR5XCIgaW4gYXR0cnMgfHwgXCJmaWxsLW9wYWNpdHlcIiBpbiBhdHRycykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZ3JhZGllbnQgPSBSLl9nLmRvYy5nZXRFbGVtZW50QnlJZChub2RlLmdldEF0dHJpYnV0ZShcImZpbGxcIikucmVwbGFjZSgvXnVybFxcKCN8XFwpJC9nLCBFKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChncmFkaWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0b3BzID0gZ3JhZGllbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJzdG9wXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJChzdG9wc1tzdG9wcy5sZW5ndGggLSAxXSwge1wic3RvcC1vcGFjaXR5XCI6IChcIm9wYWNpdHlcIiBpbiBhdHRycyA/IGF0dHJzLm9wYWNpdHkgOiAxKSAqIChcImZpbGwtb3BhY2l0eVwiIGluIGF0dHJzID8gYXR0cnNbXCJmaWxsLW9wYWNpdHlcIl0gOiAxKX0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzLmdyYWRpZW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnMuZmlsbCA9IFwibm9uZVwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY2xyW2hhc10oXCJvcGFjaXR5XCIpICYmICQobm9kZSwge1wiZmlsbC1vcGFjaXR5XCI6IGNsci5vcGFjaXR5ID4gMSA/IGNsci5vcGFjaXR5IC8gMTAwIDogY2xyLm9wYWNpdHl9KTtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInN0cm9rZVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xyID0gUi5nZXRSR0IodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoYXR0LCBjbHIuaGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dCA9PSBcInN0cm9rZVwiICYmIGNscltoYXNdKFwib3BhY2l0eVwiKSAmJiAkKG5vZGUsIHtcInN0cm9rZS1vcGFjaXR5XCI6IGNsci5vcGFjaXR5ID4gMSA/IGNsci5vcGFjaXR5IC8gMTAwIDogY2xyLm9wYWNpdHl9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHQgPT0gXCJzdHJva2VcIiAmJiBvLl8uYXJyb3dzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJzdGFydFN0cmluZ1wiIGluIG8uXy5hcnJvd3MgJiYgYWRkQXJyb3cobywgby5fLmFycm93cy5zdGFydFN0cmluZyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJlbmRTdHJpbmdcIiBpbiBvLl8uYXJyb3dzICYmIGFkZEFycm93KG8sIG8uXy5hcnJvd3MuZW5kU3RyaW5nLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZ3JhZGllbnRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIChvLnR5cGUgPT0gXCJjaXJjbGVcIiB8fCBvLnR5cGUgPT0gXCJlbGxpcHNlXCIgfHwgU3RyKHZhbHVlKS5jaGFyQXQoKSAhPSBcInJcIikgJiYgYWRkR3JhZGllbnRGaWxsKG8sIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwib3BhY2l0eVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJzLmdyYWRpZW50ICYmICFhdHRyc1toYXNdKFwic3Ryb2tlLW9wYWNpdHlcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKG5vZGUsIHtcInN0cm9rZS1vcGFjaXR5XCI6IHZhbHVlID4gMSA/IHZhbHVlIC8gMTAwIDogdmFsdWV9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZhbGxcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcImZpbGwtb3BhY2l0eVwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGF0dHJzLmdyYWRpZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JhZGllbnQgPSBSLl9nLmRvYy5nZXRFbGVtZW50QnlJZChub2RlLmdldEF0dHJpYnV0ZShcImZpbGxcIikucmVwbGFjZSgvXnVybFxcKCN8XFwpJC9nLCBFKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdyYWRpZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3BzID0gZ3JhZGllbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJzdG9wXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKHN0b3BzW3N0b3BzLmxlbmd0aCAtIDFdLCB7XCJzdG9wLW9wYWNpdHlcIjogdmFsdWV9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICBhdHQgPT0gXCJmb250LXNpemVcIiAmJiAodmFsdWUgPSB0b0ludCh2YWx1ZSwgMTApICsgXCJweFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjc3NydWxlID0gYXR0LnJlcGxhY2UoLyhcXC0uKS9nLCBmdW5jdGlvbiAodykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB3LnN1YnN0cmluZygxKS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLnN0eWxlW2Nzc3J1bGVdID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBvLl8uZGlydHkgPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoYXR0LCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0dW5lVGV4dChvLCBwYXJhbXMpO1xuICAgICAgICBub2RlLnN0eWxlLnZpc2liaWxpdHkgPSB2aXM7XG4gICAgfSxcbiAgICBsZWFkaW5nID0gMS4yLFxuICAgIHR1bmVUZXh0ID0gZnVuY3Rpb24gKGVsLCBwYXJhbXMpIHtcbiAgICAgICAgaWYgKGVsLnR5cGUgIT0gXCJ0ZXh0XCIgfHwgIShwYXJhbXNbaGFzXShcInRleHRcIikgfHwgcGFyYW1zW2hhc10oXCJmb250XCIpIHx8IHBhcmFtc1toYXNdKFwiZm9udC1zaXplXCIpIHx8IHBhcmFtc1toYXNdKFwieFwiKSB8fCBwYXJhbXNbaGFzXShcInlcIikpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGEgPSBlbC5hdHRycyxcbiAgICAgICAgICAgIG5vZGUgPSBlbC5ub2RlLFxuICAgICAgICAgICAgZm9udFNpemUgPSBub2RlLmZpcnN0Q2hpbGQgPyB0b0ludChSLl9nLmRvYy5kZWZhdWx0Vmlldy5nZXRDb21wdXRlZFN0eWxlKG5vZGUuZmlyc3RDaGlsZCwgRSkuZ2V0UHJvcGVydHlWYWx1ZShcImZvbnQtc2l6ZVwiKSwgMTApIDogMTA7XG5cbiAgICAgICAgaWYgKHBhcmFtc1toYXNdKFwidGV4dFwiKSkge1xuICAgICAgICAgICAgYS50ZXh0ID0gcGFyYW1zLnRleHQ7XG4gICAgICAgICAgICB3aGlsZSAobm9kZS5maXJzdENoaWxkKSB7XG4gICAgICAgICAgICAgICAgbm9kZS5yZW1vdmVDaGlsZChub2RlLmZpcnN0Q2hpbGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHRleHRzID0gU3RyKHBhcmFtcy50ZXh0KS5zcGxpdChcIlxcblwiKSxcbiAgICAgICAgICAgICAgICB0c3BhbnMgPSBbXSxcbiAgICAgICAgICAgICAgICB0c3BhbjtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRleHRzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0c3BhbiA9ICQoXCJ0c3BhblwiKTtcbiAgICAgICAgICAgICAgICBpICYmICQodHNwYW4sIHtkeTogZm9udFNpemUgKiBsZWFkaW5nLCB4OiBhLnh9KTtcbiAgICAgICAgICAgICAgICB0c3Bhbi5hcHBlbmRDaGlsZChSLl9nLmRvYy5jcmVhdGVUZXh0Tm9kZSh0ZXh0c1tpXSkpO1xuICAgICAgICAgICAgICAgIG5vZGUuYXBwZW5kQ2hpbGQodHNwYW4pO1xuICAgICAgICAgICAgICAgIHRzcGFuc1tpXSA9IHRzcGFuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHNwYW5zID0gbm9kZS5nZXRFbGVtZW50c0J5VGFnTmFtZShcInRzcGFuXCIpO1xuICAgICAgICAgICAgZm9yIChpID0gMCwgaWkgPSB0c3BhbnMubGVuZ3RoOyBpIDwgaWk7IGkrKykgaWYgKGkpIHtcbiAgICAgICAgICAgICAgICAkKHRzcGFuc1tpXSwge2R5OiBmb250U2l6ZSAqIGxlYWRpbmcsIHg6IGEueH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAkKHRzcGFuc1swXSwge2R5OiAwfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgJChub2RlLCB7eDogYS54LCB5OiBhLnl9KTtcbiAgICAgICAgZWwuXy5kaXJ0eSA9IDE7XG4gICAgICAgIHZhciBiYiA9IGVsLl9nZXRCQm94KCksXG4gICAgICAgICAgICBkaWYgPSBhLnkgLSAoYmIueSArIGJiLmhlaWdodCAvIDIpO1xuICAgICAgICBkaWYgJiYgUi5pcyhkaWYsIFwiZmluaXRlXCIpICYmICQodHNwYW5zWzBdLCB7ZHk6IGRpZn0pO1xuICAgIH0sXG4gICAgZ2V0UmVhbE5vZGUgPSBmdW5jdGlvbiAobm9kZSkge1xuICAgICAgICBpZiAobm9kZS5wYXJlbnROb2RlICYmIG5vZGUucGFyZW50Tm9kZS50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiYVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5wYXJlbnROb2RlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIEVsZW1lbnQgPSBmdW5jdGlvbiAobm9kZSwgc3ZnKSB7XG4gICAgICAgIHZhciBYID0gMCxcbiAgICAgICAgICAgIFkgPSAwO1xuICAgICAgICAvKlxcXG4gICAgICAgICAqIEVsZW1lbnQubm9kZVxuICAgICAgICAgWyBwcm9wZXJ0eSAob2JqZWN0KSBdXG4gICAgICAgICAqKlxuICAgICAgICAgKiBHaXZlcyB5b3UgYSByZWZlcmVuY2UgdG8gdGhlIERPTSBvYmplY3QsIHNvIHlvdSBjYW4gYXNzaWduIGV2ZW50IGhhbmRsZXJzIG9yIGp1c3QgbWVzcyBhcm91bmQuXG4gICAgICAgICAqKlxuICAgICAgICAgKiBOb3RlOiBEb27igJl0IG1lc3Mgd2l0aCBpdC5cbiAgICAgICAgID4gVXNhZ2VcbiAgICAgICAgIHwgLy8gZHJhdyBhIGNpcmNsZSBhdCBjb29yZGluYXRlIDEwLDEwIHdpdGggcmFkaXVzIG9mIDEwXG4gICAgICAgICB8IHZhciBjID0gcGFwZXIuY2lyY2xlKDEwLCAxMCwgMTApO1xuICAgICAgICAgfCBjLm5vZGUub25jbGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgIHwgICAgIGMuYXR0cihcImZpbGxcIiwgXCJyZWRcIik7XG4gICAgICAgICB8IH07XG4gICAgICAgIFxcKi9cbiAgICAgICAgdGhpc1swXSA9IHRoaXMubm9kZSA9IG5vZGU7XG4gICAgICAgIC8qXFxcbiAgICAgICAgICogRWxlbWVudC5yYXBoYWVsXG4gICAgICAgICBbIHByb3BlcnR5IChvYmplY3QpIF1cbiAgICAgICAgICoqXG4gICAgICAgICAqIEludGVybmFsIHJlZmVyZW5jZSB0byBAUmFwaGFlbCBvYmplY3QuIEluIGNhc2UgaXQgaXMgbm90IGF2YWlsYWJsZS5cbiAgICAgICAgID4gVXNhZ2VcbiAgICAgICAgIHwgUmFwaGFlbC5lbC5yZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICB8ICAgICB2YXIgaHNiID0gdGhpcy5wYXBlci5yYXBoYWVsLnJnYjJoc2IodGhpcy5hdHRyKFwiZmlsbFwiKSk7XG4gICAgICAgICB8ICAgICBoc2IuaCA9IDE7XG4gICAgICAgICB8ICAgICB0aGlzLmF0dHIoe2ZpbGw6IHRoaXMucGFwZXIucmFwaGFlbC5oc2IycmdiKGhzYikuaGV4fSk7XG4gICAgICAgICB8IH1cbiAgICAgICAgXFwqL1xuICAgICAgICBub2RlLnJhcGhhZWwgPSB0cnVlO1xuICAgICAgICAvKlxcXG4gICAgICAgICAqIEVsZW1lbnQuaWRcbiAgICAgICAgIFsgcHJvcGVydHkgKG51bWJlcikgXVxuICAgICAgICAgKipcbiAgICAgICAgICogVW5pcXVlIGlkIG9mIHRoZSBlbGVtZW50LiBFc3BlY2lhbGx5IHVzZWZ1bCB3aGVuIHlvdSB3YW50IHRvIGxpc3RlbiB0byBldmVudHMgb2YgdGhlIGVsZW1lbnQsXG4gICAgICAgICAqIGJlY2F1c2UgYWxsIGV2ZW50cyBhcmUgZmlyZWQgaW4gZm9ybWF0IGA8bW9kdWxlPi48YWN0aW9uPi48aWQ+YC4gQWxzbyB1c2VmdWwgZm9yIEBQYXBlci5nZXRCeUlkIG1ldGhvZC5cbiAgICAgICAgXFwqL1xuICAgICAgICB0aGlzLmlkID0gZ3VpZCgpO1xuICAgICAgICBub2RlLnJhcGhhZWxpZCA9IHRoaXMuaWQ7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICogTWV0aG9kIHRoYXQgcmV0dXJucyBhIDUgbGV0dGVyL2RpZ2l0IGlkLCBlbm91Z2ggZm9yIDM2XjUgPSA2MDQ2NjE3NiBlbGVtZW50c1xuICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IGlkXG4gICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGd1aWQoKSB7XG4gICAgICAgICAgICByZXR1cm4gKFwiMDAwMFwiICsgKE1hdGgucmFuZG9tKCkqTWF0aC5wb3coMzYsNSkgPDwgMCkudG9TdHJpbmcoMzYpKS5zbGljZSgtNSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm1hdHJpeCA9IFIubWF0cml4KCk7XG4gICAgICAgIHRoaXMucmVhbFBhdGggPSBudWxsO1xuICAgICAgICAvKlxcXG4gICAgICAgICAqIEVsZW1lbnQucGFwZXJcbiAgICAgICAgIFsgcHJvcGVydHkgKG9iamVjdCkgXVxuICAgICAgICAgKipcbiAgICAgICAgICogSW50ZXJuYWwgcmVmZXJlbmNlIHRvIOKAnHBhcGVy4oCdIHdoZXJlIG9iamVjdCBkcmF3bi4gTWFpbmx5IGZvciB1c2UgaW4gcGx1Z2lucyBhbmQgZWxlbWVudCBleHRlbnNpb25zLlxuICAgICAgICAgPiBVc2FnZVxuICAgICAgICAgfCBSYXBoYWVsLmVsLmNyb3NzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgfCAgICAgdGhpcy5hdHRyKHtmaWxsOiBcInJlZFwifSk7XG4gICAgICAgICB8ICAgICB0aGlzLnBhcGVyLnBhdGgoXCJNMTAsMTBMNTAsNTBNNTAsMTBMMTAsNTBcIilcbiAgICAgICAgIHwgICAgICAgICAuYXR0cih7c3Ryb2tlOiBcInJlZFwifSk7XG4gICAgICAgICB8IH1cbiAgICAgICAgXFwqL1xuICAgICAgICB0aGlzLnBhcGVyID0gc3ZnO1xuICAgICAgICB0aGlzLmF0dHJzID0gdGhpcy5hdHRycyB8fCB7fTtcbiAgICAgICAgdGhpcy5fID0ge1xuICAgICAgICAgICAgdHJhbnNmb3JtOiBbXSxcbiAgICAgICAgICAgIHN4OiAxLFxuICAgICAgICAgICAgc3k6IDEsXG4gICAgICAgICAgICBkZWc6IDAsXG4gICAgICAgICAgICBkeDogMCxcbiAgICAgICAgICAgIGR5OiAwLFxuICAgICAgICAgICAgZGlydHk6IDFcbiAgICAgICAgfTtcbiAgICAgICAgIXN2Zy5ib3R0b20gJiYgKHN2Zy5ib3R0b20gPSB0aGlzKTtcbiAgICAgICAgLypcXFxuICAgICAgICAgKiBFbGVtZW50LnByZXZcbiAgICAgICAgIFsgcHJvcGVydHkgKG9iamVjdCkgXVxuICAgICAgICAgKipcbiAgICAgICAgICogUmVmZXJlbmNlIHRvIHRoZSBwcmV2aW91cyBlbGVtZW50IGluIHRoZSBoaWVyYXJjaHkuXG4gICAgICAgIFxcKi9cbiAgICAgICAgdGhpcy5wcmV2ID0gc3ZnLnRvcDtcbiAgICAgICAgc3ZnLnRvcCAmJiAoc3ZnLnRvcC5uZXh0ID0gdGhpcyk7XG4gICAgICAgIHN2Zy50b3AgPSB0aGlzO1xuICAgICAgICAvKlxcXG4gICAgICAgICAqIEVsZW1lbnQubmV4dFxuICAgICAgICAgWyBwcm9wZXJ0eSAob2JqZWN0KSBdXG4gICAgICAgICAqKlxuICAgICAgICAgKiBSZWZlcmVuY2UgdG8gdGhlIG5leHQgZWxlbWVudCBpbiB0aGUgaGllcmFyY2h5LlxuICAgICAgICBcXCovXG4gICAgICAgIHRoaXMubmV4dCA9IG51bGw7XG4gICAgfSxcbiAgICBlbHByb3RvID0gUi5lbDtcblxuICAgIEVsZW1lbnQucHJvdG90eXBlID0gZWxwcm90bztcbiAgICBlbHByb3RvLmNvbnN0cnVjdG9yID0gRWxlbWVudDtcblxuICAgIFIuX2VuZ2luZS5wYXRoID0gZnVuY3Rpb24gKHBhdGhTdHJpbmcsIFNWRykge1xuICAgICAgICB2YXIgZWwgPSAkKFwicGF0aFwiKTtcbiAgICAgICAgU1ZHLmNhbnZhcyAmJiBTVkcuY2FudmFzLmFwcGVuZENoaWxkKGVsKTtcbiAgICAgICAgdmFyIHAgPSBuZXcgRWxlbWVudChlbCwgU1ZHKTtcbiAgICAgICAgcC50eXBlID0gXCJwYXRoXCI7XG4gICAgICAgIHNldEZpbGxBbmRTdHJva2UocCwge1xuICAgICAgICAgICAgZmlsbDogXCJub25lXCIsXG4gICAgICAgICAgICBzdHJva2U6IFwiIzAwMFwiLFxuICAgICAgICAgICAgcGF0aDogcGF0aFN0cmluZ1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHA7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5yb3RhdGVcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIERlcHJlY2F0ZWQhIFVzZSBARWxlbWVudC50cmFuc2Zvcm0gaW5zdGVhZC5cbiAgICAgKiBBZGRzIHJvdGF0aW9uIGJ5IGdpdmVuIGFuZ2xlIGFyb3VuZCBnaXZlbiBwb2ludCB0byB0aGUgbGlzdCBvZlxuICAgICAqIHRyYW5zZm9ybWF0aW9ucyBvZiB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gZGVnIChudW1iZXIpIGFuZ2xlIGluIGRlZ3JlZXNcbiAgICAgLSBjeCAobnVtYmVyKSAjb3B0aW9uYWwgeCBjb29yZGluYXRlIG9mIHRoZSBjZW50cmUgb2Ygcm90YXRpb25cbiAgICAgLSBjeSAobnVtYmVyKSAjb3B0aW9uYWwgeSBjb29yZGluYXRlIG9mIHRoZSBjZW50cmUgb2Ygcm90YXRpb25cbiAgICAgKiBJZiBjeCAmIGN5IGFyZW7igJl0IHNwZWNpZmllZCBjZW50cmUgb2YgdGhlIHNoYXBlIGlzIHVzZWQgYXMgYSBwb2ludCBvZiByb3RhdGlvbi5cbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cbiAgICBlbHByb3RvLnJvdGF0ZSA9IGZ1bmN0aW9uIChkZWcsIGN4LCBjeSkge1xuICAgICAgICBpZiAodGhpcy5yZW1vdmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICBkZWcgPSBTdHIoZGVnKS5zcGxpdChzZXBhcmF0b3IpO1xuICAgICAgICBpZiAoZGVnLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIGN4ID0gdG9GbG9hdChkZWdbMV0pO1xuICAgICAgICAgICAgY3kgPSB0b0Zsb2F0KGRlZ1syXSk7XG4gICAgICAgIH1cbiAgICAgICAgZGVnID0gdG9GbG9hdChkZWdbMF0pO1xuICAgICAgICAoY3kgPT0gbnVsbCkgJiYgKGN4ID0gY3kpO1xuICAgICAgICBpZiAoY3ggPT0gbnVsbCB8fCBjeSA9PSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgYmJveCA9IHRoaXMuZ2V0QkJveCgxKTtcbiAgICAgICAgICAgIGN4ID0gYmJveC54ICsgYmJveC53aWR0aCAvIDI7XG4gICAgICAgICAgICBjeSA9IGJib3gueSArIGJib3guaGVpZ2h0IC8gMjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRyYW5zZm9ybSh0aGlzLl8udHJhbnNmb3JtLmNvbmNhdChbW1wiclwiLCBkZWcsIGN4LCBjeV1dKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuc2NhbGVcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIERlcHJlY2F0ZWQhIFVzZSBARWxlbWVudC50cmFuc2Zvcm0gaW5zdGVhZC5cbiAgICAgKiBBZGRzIHNjYWxlIGJ5IGdpdmVuIGFtb3VudCByZWxhdGl2ZSB0byBnaXZlbiBwb2ludCB0byB0aGUgbGlzdCBvZlxuICAgICAqIHRyYW5zZm9ybWF0aW9ucyBvZiB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gc3ggKG51bWJlcikgaG9yaXNvbnRhbCBzY2FsZSBhbW91bnRcbiAgICAgLSBzeSAobnVtYmVyKSB2ZXJ0aWNhbCBzY2FsZSBhbW91bnRcbiAgICAgLSBjeCAobnVtYmVyKSAjb3B0aW9uYWwgeCBjb29yZGluYXRlIG9mIHRoZSBjZW50cmUgb2Ygc2NhbGVcbiAgICAgLSBjeSAobnVtYmVyKSAjb3B0aW9uYWwgeSBjb29yZGluYXRlIG9mIHRoZSBjZW50cmUgb2Ygc2NhbGVcbiAgICAgKiBJZiBjeCAmIGN5IGFyZW7igJl0IHNwZWNpZmllZCBjZW50cmUgb2YgdGhlIHNoYXBlIGlzIHVzZWQgaW5zdGVhZC5cbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cbiAgICBlbHByb3RvLnNjYWxlID0gZnVuY3Rpb24gKHN4LCBzeSwgY3gsIGN5KSB7XG4gICAgICAgIGlmICh0aGlzLnJlbW92ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHN4ID0gU3RyKHN4KS5zcGxpdChzZXBhcmF0b3IpO1xuICAgICAgICBpZiAoc3gubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgc3kgPSB0b0Zsb2F0KHN4WzFdKTtcbiAgICAgICAgICAgIGN4ID0gdG9GbG9hdChzeFsyXSk7XG4gICAgICAgICAgICBjeSA9IHRvRmxvYXQoc3hbM10pO1xuICAgICAgICB9XG4gICAgICAgIHN4ID0gdG9GbG9hdChzeFswXSk7XG4gICAgICAgIChzeSA9PSBudWxsKSAmJiAoc3kgPSBzeCk7XG4gICAgICAgIChjeSA9PSBudWxsKSAmJiAoY3ggPSBjeSk7XG4gICAgICAgIGlmIChjeCA9PSBudWxsIHx8IGN5ID09IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBiYm94ID0gdGhpcy5nZXRCQm94KDEpO1xuICAgICAgICB9XG4gICAgICAgIGN4ID0gY3ggPT0gbnVsbCA/IGJib3gueCArIGJib3gud2lkdGggLyAyIDogY3g7XG4gICAgICAgIGN5ID0gY3kgPT0gbnVsbCA/IGJib3gueSArIGJib3guaGVpZ2h0IC8gMiA6IGN5O1xuICAgICAgICB0aGlzLnRyYW5zZm9ybSh0aGlzLl8udHJhbnNmb3JtLmNvbmNhdChbW1wic1wiLCBzeCwgc3ksIGN4LCBjeV1dKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQudHJhbnNsYXRlXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBEZXByZWNhdGVkISBVc2UgQEVsZW1lbnQudHJhbnNmb3JtIGluc3RlYWQuXG4gICAgICogQWRkcyB0cmFuc2xhdGlvbiBieSBnaXZlbiBhbW91bnQgdG8gdGhlIGxpc3Qgb2YgdHJhbnNmb3JtYXRpb25zIG9mIHRoZSBlbGVtZW50LlxuICAgICA+IFBhcmFtZXRlcnNcbiAgICAgLSBkeCAobnVtYmVyKSBob3Jpc29udGFsIHNoaWZ0XG4gICAgIC0gZHkgKG51bWJlcikgdmVydGljYWwgc2hpZnRcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cbiAgICBlbHByb3RvLnRyYW5zbGF0ZSA9IGZ1bmN0aW9uIChkeCwgZHkpIHtcbiAgICAgICAgaWYgKHRoaXMucmVtb3ZlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgZHggPSBTdHIoZHgpLnNwbGl0KHNlcGFyYXRvcik7XG4gICAgICAgIGlmIChkeC5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICBkeSA9IHRvRmxvYXQoZHhbMV0pO1xuICAgICAgICB9XG4gICAgICAgIGR4ID0gdG9GbG9hdChkeFswXSkgfHwgMDtcbiAgICAgICAgZHkgPSArZHkgfHwgMDtcbiAgICAgICAgdGhpcy50cmFuc2Zvcm0odGhpcy5fLnRyYW5zZm9ybS5jb25jYXQoW1tcInRcIiwgZHgsIGR5XV0pKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC50cmFuc2Zvcm1cbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEFkZHMgdHJhbnNmb3JtYXRpb24gdG8gdGhlIGVsZW1lbnQgd2hpY2ggaXMgc2VwYXJhdGUgdG8gb3RoZXIgYXR0cmlidXRlcyxcbiAgICAgKiBpLmUuIHRyYW5zbGF0aW9uIGRvZXNu4oCZdCBjaGFuZ2UgYHhgIG9yIGB5YCBvZiB0aGUgcmVjdGFuZ2UuIFRoZSBmb3JtYXRcbiAgICAgKiBvZiB0cmFuc2Zvcm1hdGlvbiBzdHJpbmcgaXMgc2ltaWxhciB0byB0aGUgcGF0aCBzdHJpbmcgc3ludGF4OlxuICAgICB8IFwidDEwMCwxMDByMzAsMTAwLDEwMHMyLDIsMTAwLDEwMHI0NXMxLjVcIlxuICAgICAqIEVhY2ggbGV0dGVyIGlzIGEgY29tbWFuZC4gVGhlcmUgYXJlIGZvdXIgY29tbWFuZHM6IGB0YCBpcyBmb3IgdHJhbnNsYXRlLCBgcmAgaXMgZm9yIHJvdGF0ZSwgYHNgIGlzIGZvclxuICAgICAqIHNjYWxlIGFuZCBgbWAgaXMgZm9yIG1hdHJpeC5cbiAgICAgKlxuICAgICAqIFRoZXJlIGFyZSBhbHNvIGFsdGVybmF0aXZlIOKAnGFic29sdXRl4oCdIHRyYW5zbGF0aW9uLCByb3RhdGlvbiBhbmQgc2NhbGU6IGBUYCwgYFJgIGFuZCBgU2AuIFRoZXkgd2lsbCBub3QgdGFrZSBwcmV2aW91cyB0cmFuc2Zvcm1hdGlvbiBpbnRvIGFjY291bnQuIEZvciBleGFtcGxlLCBgLi4uVDEwMCwwYCB3aWxsIGFsd2F5cyBtb3ZlIGVsZW1lbnQgMTAwIHB4IGhvcmlzb250YWxseSwgd2hpbGUgYC4uLnQxMDAsMGAgY291bGQgbW92ZSBpdCB2ZXJ0aWNhbGx5IGlmIHRoZXJlIGlzIGByOTBgIGJlZm9yZS4gSnVzdCBjb21wYXJlIHJlc3VsdHMgb2YgYHI5MHQxMDAsMGAgYW5kIGByOTBUMTAwLDBgLlxuICAgICAqXG4gICAgICogU28sIHRoZSBleGFtcGxlIGxpbmUgYWJvdmUgY291bGQgYmUgcmVhZCBsaWtlIOKAnHRyYW5zbGF0ZSBieSAxMDAsIDEwMDsgcm90YXRlIDMwwrAgYXJvdW5kIDEwMCwgMTAwOyBzY2FsZSB0d2ljZSBhcm91bmQgMTAwLCAxMDA7XG4gICAgICogcm90YXRlIDQ1wrAgYXJvdW5kIGNlbnRyZTsgc2NhbGUgMS41IHRpbWVzIHJlbGF0aXZlIHRvIGNlbnRyZeKAnS4gQXMgeW91IGNhbiBzZWUgcm90YXRlIGFuZCBzY2FsZSBjb21tYW5kcyBoYXZlIG9yaWdpblxuICAgICAqIGNvb3JkaW5hdGVzIGFzIG9wdGlvbmFsIHBhcmFtZXRlcnMsIHRoZSBkZWZhdWx0IGlzIHRoZSBjZW50cmUgcG9pbnQgb2YgdGhlIGVsZW1lbnQuXG4gICAgICogTWF0cml4IGFjY2VwdHMgc2l4IHBhcmFtZXRlcnMuXG4gICAgID4gVXNhZ2VcbiAgICAgfCB2YXIgZWwgPSBwYXBlci5yZWN0KDEwLCAyMCwgMzAwLCAyMDApO1xuICAgICB8IC8vIHRyYW5zbGF0ZSAxMDAsIDEwMCwgcm90YXRlIDQ1wrAsIHRyYW5zbGF0ZSAtMTAwLCAwXG4gICAgIHwgZWwudHJhbnNmb3JtKFwidDEwMCwxMDByNDV0LTEwMCwwXCIpO1xuICAgICB8IC8vIGlmIHlvdSB3YW50IHlvdSBjYW4gYXBwZW5kIG9yIHByZXBlbmQgdHJhbnNmb3JtYXRpb25zXG4gICAgIHwgZWwudHJhbnNmb3JtKFwiLi4udDUwLDUwXCIpO1xuICAgICB8IGVsLnRyYW5zZm9ybShcInMyLi4uXCIpO1xuICAgICB8IC8vIG9yIGV2ZW4gd3JhcFxuICAgICB8IGVsLnRyYW5zZm9ybShcInQ1MCw1MC4uLnQtNTAtNTBcIik7XG4gICAgIHwgLy8gdG8gcmVzZXQgdHJhbnNmb3JtYXRpb24gY2FsbCBtZXRob2Qgd2l0aCBlbXB0eSBzdHJpbmdcbiAgICAgfCBlbC50cmFuc2Zvcm0oXCJcIik7XG4gICAgIHwgLy8gdG8gZ2V0IGN1cnJlbnQgdmFsdWUgY2FsbCBpdCB3aXRob3V0IHBhcmFtZXRlcnNcbiAgICAgfCBjb25zb2xlLmxvZyhlbC50cmFuc2Zvcm0oKSk7XG4gICAgID4gUGFyYW1ldGVyc1xuICAgICAtIHRzdHIgKHN0cmluZykgI29wdGlvbmFsIHRyYW5zZm9ybWF0aW9uIHN0cmluZ1xuICAgICAqIElmIHRzdHIgaXNu4oCZdCBzcGVjaWZpZWRcbiAgICAgPSAoc3RyaW5nKSBjdXJyZW50IHRyYW5zZm9ybWF0aW9uIHN0cmluZ1xuICAgICAqIGVsc2VcbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cbiAgICBlbHByb3RvLnRyYW5zZm9ybSA9IGZ1bmN0aW9uICh0c3RyKSB7XG4gICAgICAgIHZhciBfID0gdGhpcy5fO1xuICAgICAgICBpZiAodHN0ciA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gXy50cmFuc2Zvcm07XG4gICAgICAgIH1cbiAgICAgICAgUi5fZXh0cmFjdFRyYW5zZm9ybSh0aGlzLCB0c3RyKTtcblxuICAgICAgICB0aGlzLmNsaXAgJiYgJCh0aGlzLmNsaXAsIHt0cmFuc2Zvcm06IHRoaXMubWF0cml4LmludmVydCgpfSk7XG4gICAgICAgIHRoaXMucGF0dGVybiAmJiB1cGRhdGVQb3NpdGlvbih0aGlzKTtcbiAgICAgICAgdGhpcy5ub2RlICYmICQodGhpcy5ub2RlLCB7dHJhbnNmb3JtOiB0aGlzLm1hdHJpeH0pO1xuXG4gICAgICAgIGlmIChfLnN4ICE9IDEgfHwgXy5zeSAhPSAxKSB7XG4gICAgICAgICAgICB2YXIgc3cgPSB0aGlzLmF0dHJzW2hhc10oXCJzdHJva2Utd2lkdGhcIikgPyB0aGlzLmF0dHJzW1wic3Ryb2tlLXdpZHRoXCJdIDogMTtcbiAgICAgICAgICAgIHRoaXMuYXR0cih7XCJzdHJva2Utd2lkdGhcIjogc3d9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuaGlkZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogTWFrZXMgZWxlbWVudCBpbnZpc2libGUuIFNlZSBARWxlbWVudC5zaG93LlxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIGVscHJvdG8uaGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYoIXRoaXMucmVtb3ZlZCkgdGhpcy5ub2RlLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5zaG93XG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBNYWtlcyBlbGVtZW50IHZpc2libGUuIFNlZSBARWxlbWVudC5oaWRlLlxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIGVscHJvdG8uc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYoIXRoaXMucmVtb3ZlZCkgdGhpcy5ub2RlLnN0eWxlLmRpc3BsYXkgPSBcIlwiO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnJlbW92ZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVtb3ZlcyBlbGVtZW50IGZyb20gdGhlIHBhcGVyLlxuICAgIFxcKi9cbiAgICBlbHByb3RvLnJlbW92ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGUgPSBnZXRSZWFsTm9kZSh0aGlzLm5vZGUpO1xuICAgICAgICBpZiAodGhpcy5yZW1vdmVkIHx8ICFub2RlLnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcGFwZXIgPSB0aGlzLnBhcGVyO1xuICAgICAgICBwYXBlci5fX3NldF9fICYmIHBhcGVyLl9fc2V0X18uZXhjbHVkZSh0aGlzKTtcbiAgICAgICAgZXZlLnVuYmluZChcInJhcGhhZWwuKi4qLlwiICsgdGhpcy5pZCk7XG4gICAgICAgIGlmICh0aGlzLmdyYWRpZW50KSB7XG4gICAgICAgICAgICBwYXBlci5kZWZzLnJlbW92ZUNoaWxkKHRoaXMuZ3JhZGllbnQpO1xuICAgICAgICB9XG4gICAgICAgIFIuX3RlYXIodGhpcywgcGFwZXIpO1xuXG4gICAgICAgIG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChub2RlKTtcblxuICAgICAgICAvLyBSZW1vdmUgY3VzdG9tIGRhdGEgZm9yIGVsZW1lbnRcbiAgICAgICAgdGhpcy5yZW1vdmVEYXRhKCk7XG5cbiAgICAgICAgZm9yICh2YXIgaSBpbiB0aGlzKSB7XG4gICAgICAgICAgICB0aGlzW2ldID0gdHlwZW9mIHRoaXNbaV0gPT0gXCJmdW5jdGlvblwiID8gUi5fcmVtb3ZlZEZhY3RvcnkoaSkgOiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlZCA9IHRydWU7XG4gICAgfTtcbiAgICBlbHByb3RvLl9nZXRCQm94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5ub2RlLnN0eWxlLmRpc3BsYXkgPT0gXCJub25lXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc2hvdygpO1xuICAgICAgICAgICAgdmFyIGhpZGUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjYW52YXNIaWRkZW4gPSBmYWxzZSxcbiAgICAgICAgICAgIGNvbnRhaW5lclN0eWxlO1xuICAgICAgICBpZiAodGhpcy5wYXBlci5jYW52YXMucGFyZW50RWxlbWVudCkge1xuICAgICAgICAgIGNvbnRhaW5lclN0eWxlID0gdGhpcy5wYXBlci5jYW52YXMucGFyZW50RWxlbWVudC5zdHlsZTtcbiAgICAgICAgfSAvL0lFMTArIGNhbid0IGZpbmQgcGFyZW50RWxlbWVudFxuICAgICAgICBlbHNlIGlmICh0aGlzLnBhcGVyLmNhbnZhcy5wYXJlbnROb2RlKSB7XG4gICAgICAgICAgY29udGFpbmVyU3R5bGUgPSB0aGlzLnBhcGVyLmNhbnZhcy5wYXJlbnROb2RlLnN0eWxlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYoY29udGFpbmVyU3R5bGUgJiYgY29udGFpbmVyU3R5bGUuZGlzcGxheSA9PSBcIm5vbmVcIikge1xuICAgICAgICAgIGNhbnZhc0hpZGRlbiA9IHRydWU7XG4gICAgICAgICAgY29udGFpbmVyU3R5bGUuZGlzcGxheSA9IFwiXCI7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGJib3ggPSB7fTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGJib3ggPSB0aGlzLm5vZGUuZ2V0QkJveCgpO1xuICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgIC8vIEZpcmVmb3ggMy4wLngsIDI1LjAuMSAocHJvYmFibHkgbW9yZSB2ZXJzaW9ucyBhZmZlY3RlZCkgcGxheSBiYWRseSBoZXJlIC0gcG9zc2libGUgZml4XG4gICAgICAgICAgICBiYm94ID0ge1xuICAgICAgICAgICAgICAgIHg6IHRoaXMubm9kZS5jbGllbnRMZWZ0LFxuICAgICAgICAgICAgICAgIHk6IHRoaXMubm9kZS5jbGllbnRUb3AsXG4gICAgICAgICAgICAgICAgd2lkdGg6IHRoaXMubm9kZS5jbGllbnRXaWR0aCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMubm9kZS5jbGllbnRIZWlnaHRcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGJib3ggPSBiYm94IHx8IHt9O1xuICAgICAgICAgICAgaWYoY2FudmFzSGlkZGVuKXtcbiAgICAgICAgICAgICAgY29udGFpbmVyU3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGhpZGUgJiYgdGhpcy5oaWRlKCk7XG4gICAgICAgIHJldHVybiBiYm94O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuYXR0clxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogU2V0cyB0aGUgYXR0cmlidXRlcyBvZiB0aGUgZWxlbWVudC5cbiAgICAgPiBQYXJhbWV0ZXJzXG4gICAgIC0gYXR0ck5hbWUgKHN0cmluZykgYXR0cmlidXRl4oCZcyBuYW1lXG4gICAgIC0gdmFsdWUgKHN0cmluZykgdmFsdWVcbiAgICAgKiBvclxuICAgICAtIHBhcmFtcyAob2JqZWN0KSBvYmplY3Qgb2YgbmFtZS92YWx1ZSBwYWlyc1xuICAgICAqIG9yXG4gICAgIC0gYXR0ck5hbWUgKHN0cmluZykgYXR0cmlidXRl4oCZcyBuYW1lXG4gICAgICogb3JcbiAgICAgLSBhdHRyTmFtZXMgKGFycmF5KSBpbiB0aGlzIGNhc2UgbWV0aG9kIHJldHVybnMgYXJyYXkgb2YgY3VycmVudCB2YWx1ZXMgZm9yIGdpdmVuIGF0dHJpYnV0ZSBuYW1lc1xuICAgICA9IChvYmplY3QpIEBFbGVtZW50IGlmIGF0dHJzTmFtZSAmIHZhbHVlIG9yIHBhcmFtcyBhcmUgcGFzc2VkIGluLlxuICAgICA9ICguLi4pIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgaWYgb25seSBhdHRyc05hbWUgaXMgcGFzc2VkIGluLlxuICAgICA9IChhcnJheSkgYXJyYXkgb2YgdmFsdWVzIG9mIHRoZSBhdHRyaWJ1dGUgaWYgYXR0cnNOYW1lcyBpcyBwYXNzZWQgaW4uXG4gICAgID0gKG9iamVjdCkgb2JqZWN0IG9mIGF0dHJpYnV0ZXMgaWYgbm90aGluZyBpcyBwYXNzZWQgaW4uXG4gICAgID4gUG9zc2libGUgcGFyYW1ldGVyc1xuICAgICAjIDxwPlBsZWFzZSByZWZlciB0byB0aGUgPGEgaHJlZj1cImh0dHA6Ly93d3cudzMub3JnL1RSL1NWRy9cIiB0aXRsZT1cIlRoZSBXM0MgUmVjb21tZW5kYXRpb24gZm9yIHRoZSBTVkcgbGFuZ3VhZ2UgZGVzY3JpYmVzIHRoZXNlIHByb3BlcnRpZXMgaW4gZGV0YWlsLlwiPlNWRyBzcGVjaWZpY2F0aW9uPC9hPiBmb3IgYW4gZXhwbGFuYXRpb24gb2YgdGhlc2UgcGFyYW1ldGVycy48L3A+XG4gICAgIG8gYXJyb3ctZW5kIChzdHJpbmcpIGFycm93aGVhZCBvbiB0aGUgZW5kIG9mIHRoZSBwYXRoLiBUaGUgZm9ybWF0IGZvciBzdHJpbmcgaXMgYDx0eXBlPlstPHdpZHRoPlstPGxlbmd0aD5dXWAuIFBvc3NpYmxlIHR5cGVzOiBgY2xhc3NpY2AsIGBibG9ja2AsIGBvcGVuYCwgYG92YWxgLCBgZGlhbW9uZGAsIGBub25lYCwgd2lkdGg6IGB3aWRlYCwgYG5hcnJvd2AsIGBtZWRpdW1gLCBsZW5ndGg6IGBsb25nYCwgYHNob3J0YCwgYG1pZGl1bWAuXG4gICAgIG8gY2xpcC1yZWN0IChzdHJpbmcpIGNvbW1hIG9yIHNwYWNlIHNlcGFyYXRlZCB2YWx1ZXM6IHgsIHksIHdpZHRoIGFuZCBoZWlnaHRcbiAgICAgbyBjdXJzb3IgKHN0cmluZykgQ1NTIHR5cGUgb2YgdGhlIGN1cnNvclxuICAgICBvIGN4IChudW1iZXIpIHRoZSB4LWF4aXMgY29vcmRpbmF0ZSBvZiB0aGUgY2VudGVyIG9mIHRoZSBjaXJjbGUsIG9yIGVsbGlwc2VcbiAgICAgbyBjeSAobnVtYmVyKSB0aGUgeS1heGlzIGNvb3JkaW5hdGUgb2YgdGhlIGNlbnRlciBvZiB0aGUgY2lyY2xlLCBvciBlbGxpcHNlXG4gICAgIG8gZmlsbCAoc3RyaW5nKSBjb2xvdXIsIGdyYWRpZW50IG9yIGltYWdlXG4gICAgIG8gZmlsbC1vcGFjaXR5IChudW1iZXIpXG4gICAgIG8gZm9udCAoc3RyaW5nKVxuICAgICBvIGZvbnQtZmFtaWx5IChzdHJpbmcpXG4gICAgIG8gZm9udC1zaXplIChudW1iZXIpIGZvbnQgc2l6ZSBpbiBwaXhlbHNcbiAgICAgbyBmb250LXdlaWdodCAoc3RyaW5nKVxuICAgICBvIGhlaWdodCAobnVtYmVyKVxuICAgICBvIGhyZWYgKHN0cmluZykgVVJMLCBpZiBzcGVjaWZpZWQgZWxlbWVudCBiZWhhdmVzIGFzIGh5cGVybGlua1xuICAgICBvIG9wYWNpdHkgKG51bWJlcilcbiAgICAgbyBwYXRoIChzdHJpbmcpIFNWRyBwYXRoIHN0cmluZyBmb3JtYXRcbiAgICAgbyByIChudW1iZXIpIHJhZGl1cyBvZiB0aGUgY2lyY2xlLCBlbGxpcHNlIG9yIHJvdW5kZWQgY29ybmVyIG9uIHRoZSByZWN0XG4gICAgIG8gcnggKG51bWJlcikgaG9yaXNvbnRhbCByYWRpdXMgb2YgdGhlIGVsbGlwc2VcbiAgICAgbyByeSAobnVtYmVyKSB2ZXJ0aWNhbCByYWRpdXMgb2YgdGhlIGVsbGlwc2VcbiAgICAgbyBzcmMgKHN0cmluZykgaW1hZ2UgVVJMLCBvbmx5IHdvcmtzIGZvciBARWxlbWVudC5pbWFnZSBlbGVtZW50XG4gICAgIG8gc3Ryb2tlIChzdHJpbmcpIHN0cm9rZSBjb2xvdXJcbiAgICAgbyBzdHJva2UtZGFzaGFycmF5IChzdHJpbmcpIFvigJzigJ0sIOKAnG5vbmXigJ0sIOKAnGAtYOKAnSwg4oCcYC5g4oCdLCDigJxgLS5g4oCdLCDigJxgLS4uYOKAnSwg4oCcYC4gYOKAnSwg4oCcYC0gYOKAnSwg4oCcYC0tYOKAnSwg4oCcYC0gLmDigJ0sIOKAnGAtLS5g4oCdLCDigJxgLS0uLmDigJ1dXG4gICAgIG8gc3Ryb2tlLWxpbmVjYXAgKHN0cmluZykgW+KAnGBidXR0YOKAnSwg4oCcYHNxdWFyZWDigJ0sIOKAnGByb3VuZGDigJ1dXG4gICAgIG8gc3Ryb2tlLWxpbmVqb2luIChzdHJpbmcpIFvigJxgYmV2ZWxg4oCdLCDigJxgcm91bmRg4oCdLCDigJxgbWl0ZXJg4oCdXVxuICAgICBvIHN0cm9rZS1taXRlcmxpbWl0IChudW1iZXIpXG4gICAgIG8gc3Ryb2tlLW9wYWNpdHkgKG51bWJlcilcbiAgICAgbyBzdHJva2Utd2lkdGggKG51bWJlcikgc3Ryb2tlIHdpZHRoIGluIHBpeGVscywgZGVmYXVsdCBpcyAnMSdcbiAgICAgbyB0YXJnZXQgKHN0cmluZykgdXNlZCB3aXRoIGhyZWZcbiAgICAgbyB0ZXh0IChzdHJpbmcpIGNvbnRlbnRzIG9mIHRoZSB0ZXh0IGVsZW1lbnQuIFVzZSBgXFxuYCBmb3IgbXVsdGlsaW5lIHRleHRcbiAgICAgbyB0ZXh0LWFuY2hvciAoc3RyaW5nKSBb4oCcYHN0YXJ0YOKAnSwg4oCcYG1pZGRsZWDigJ0sIOKAnGBlbmRg4oCdXSwgZGVmYXVsdCBpcyDigJxgbWlkZGxlYOKAnVxuICAgICBvIHRpdGxlIChzdHJpbmcpIHdpbGwgY3JlYXRlIHRvb2x0aXAgd2l0aCBhIGdpdmVuIHRleHRcbiAgICAgbyB0cmFuc2Zvcm0gKHN0cmluZykgc2VlIEBFbGVtZW50LnRyYW5zZm9ybVxuICAgICBvIHdpZHRoIChudW1iZXIpXG4gICAgIG8geCAobnVtYmVyKVxuICAgICBvIHkgKG51bWJlcilcbiAgICAgPiBHcmFkaWVudHNcbiAgICAgKiBMaW5lYXIgZ3JhZGllbnQgZm9ybWF0OiDigJxg4oC5YW5nbGXigLot4oC5Y29sb3Vy4oC6Wy3igLljb2xvdXLigLpbOuKAuW9mZnNldOKAul1dKi3igLljb2xvdXLigLpg4oCdLCBleGFtcGxlOiDigJxgOTAtI2ZmZi0jMDAwYOKAnSDigJMgOTDCsFxuICAgICAqIGdyYWRpZW50IGZyb20gd2hpdGUgdG8gYmxhY2sgb3Ig4oCcYDAtI2ZmZi0jZjAwOjIwLSMwMDBg4oCdIOKAkyAwwrAgZ3JhZGllbnQgZnJvbSB3aGl0ZSB2aWEgcmVkIChhdCAyMCUpIHRvIGJsYWNrLlxuICAgICAqXG4gICAgICogcmFkaWFsIGdyYWRpZW50OiDigJxgclso4oC5ZnjigLosIOKAuWZ54oC6KV3igLljb2xvdXLigLpbLeKAuWNvbG91cuKAuls64oC5b2Zmc2V04oC6XV0qLeKAuWNvbG91cuKAumDigJ0sIGV4YW1wbGU6IOKAnGByI2ZmZi0jMDAwYOKAnSDigJNcbiAgICAgKiBncmFkaWVudCBmcm9tIHdoaXRlIHRvIGJsYWNrIG9yIOKAnGByKDAuMjUsIDAuNzUpI2ZmZi0jMDAwYOKAnSDigJMgZ3JhZGllbnQgZnJvbSB3aGl0ZSB0byBibGFjayB3aXRoIGZvY3VzIHBvaW50XG4gICAgICogYXQgMC4yNSwgMC43NS4gRm9jdXMgcG9pbnQgY29vcmRpbmF0ZXMgYXJlIGluIDAuLjEgcmFuZ2UuIFJhZGlhbCBncmFkaWVudHMgY2FuIG9ubHkgYmUgYXBwbGllZCB0byBjaXJjbGVzIGFuZCBlbGxpcHNlcy5cbiAgICAgPiBQYXRoIFN0cmluZ1xuICAgICAjIDxwPlBsZWFzZSByZWZlciB0byA8YSBocmVmPVwiaHR0cDovL3d3dy53My5vcmcvVFIvU1ZHL3BhdGhzLmh0bWwjUGF0aERhdGFcIiB0aXRsZT1cIkRldGFpbHMgb2YgYSBwYXRo4oCZcyBkYXRhIGF0dHJpYnV0ZeKAmXMgZm9ybWF0IGFyZSBkZXNjcmliZWQgaW4gdGhlIFNWRyBzcGVjaWZpY2F0aW9uLlwiPlNWRyBkb2N1bWVudGF0aW9uIHJlZ2FyZGluZyBwYXRoIHN0cmluZzwvYT4uIFJhcGhhw6tsIGZ1bGx5IHN1cHBvcnRzIGl0LjwvcD5cbiAgICAgPiBDb2xvdXIgUGFyc2luZ1xuICAgICAjIDx1bD5cbiAgICAgIyAgICAgPGxpPkNvbG91ciBuYW1lICjigJw8Y29kZT5yZWQ8L2NvZGU+4oCdLCDigJw8Y29kZT5ncmVlbjwvY29kZT7igJ0sIOKAnDxjb2RlPmNvcm5mbG93ZXJibHVlPC9jb2RlPuKAnSwgZXRjKTwvbGk+XG4gICAgICMgICAgIDxsaT4j4oCi4oCi4oCiIOKAlCBzaG9ydGVuZWQgSFRNTCBjb2xvdXI6ICjigJw8Y29kZT4jMDAwPC9jb2RlPuKAnSwg4oCcPGNvZGU+I2ZjMDwvY29kZT7igJ0sIGV0Yyk8L2xpPlxuICAgICAjICAgICA8bGk+I+KAouKAouKAouKAouKAouKAoiDigJQgZnVsbCBsZW5ndGggSFRNTCBjb2xvdXI6ICjigJw8Y29kZT4jMDAwMDAwPC9jb2RlPuKAnSwg4oCcPGNvZGU+I2JkMjMwMDwvY29kZT7igJ0pPC9saT5cbiAgICAgIyAgICAgPGxpPnJnYijigKLigKLigKIsIOKAouKAouKAoiwg4oCi4oCi4oCiKSDigJQgcmVkLCBncmVlbiBhbmQgYmx1ZSBjaGFubmVsc+KAmSB2YWx1ZXM6ICjigJw8Y29kZT5yZ2IoMjAwLCZuYnNwOzEwMCwmbmJzcDswKTwvY29kZT7igJ0pPC9saT5cbiAgICAgIyAgICAgPGxpPnJnYijigKLigKLigKIlLCDigKLigKLigKIlLCDigKLigKLigKIlKSDigJQgc2FtZSBhcyBhYm92ZSwgYnV0IGluICU6ICjigJw8Y29kZT5yZ2IoMTAwJSwmbmJzcDsxNzUlLCZuYnNwOzAlKTwvY29kZT7igJ0pPC9saT5cbiAgICAgIyAgICAgPGxpPnJnYmEo4oCi4oCi4oCiLCDigKLigKLigKIsIOKAouKAouKAoiwg4oCi4oCi4oCiKSDigJQgcmVkLCBncmVlbiBhbmQgYmx1ZSBjaGFubmVsc+KAmSB2YWx1ZXM6ICjigJw8Y29kZT5yZ2JhKDIwMCwmbmJzcDsxMDAsJm5ic3A7MCwgLjUpPC9jb2RlPuKAnSk8L2xpPlxuICAgICAjICAgICA8bGk+cmdiYSjigKLigKLigKIlLCDigKLigKLigKIlLCDigKLigKLigKIlLCDigKLigKLigKIlKSDigJQgc2FtZSBhcyBhYm92ZSwgYnV0IGluICU6ICjigJw8Y29kZT5yZ2JhKDEwMCUsJm5ic3A7MTc1JSwmbmJzcDswJSwgNTAlKTwvY29kZT7igJ0pPC9saT5cbiAgICAgIyAgICAgPGxpPmhzYijigKLigKLigKIsIOKAouKAouKAoiwg4oCi4oCi4oCiKSDigJQgaHVlLCBzYXR1cmF0aW9uIGFuZCBicmlnaHRuZXNzIHZhbHVlczogKOKAnDxjb2RlPmhzYigwLjUsJm5ic3A7MC4yNSwmbmJzcDsxKTwvY29kZT7igJ0pPC9saT5cbiAgICAgIyAgICAgPGxpPmhzYijigKLigKLigKIlLCDigKLigKLigKIlLCDigKLigKLigKIlKSDigJQgc2FtZSBhcyBhYm92ZSwgYnV0IGluICU8L2xpPlxuICAgICAjICAgICA8bGk+aHNiYSjigKLigKLigKIsIOKAouKAouKAoiwg4oCi4oCi4oCiLCDigKLigKLigKIpIOKAlCBzYW1lIGFzIGFib3ZlLCBidXQgd2l0aCBvcGFjaXR5PC9saT5cbiAgICAgIyAgICAgPGxpPmhzbCjigKLigKLigKIsIOKAouKAouKAoiwg4oCi4oCi4oCiKSDigJQgYWxtb3N0IHRoZSBzYW1lIGFzIGhzYiwgc2VlIDxhIGhyZWY9XCJodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0hTTF9hbmRfSFNWXCIgdGl0bGU9XCJIU0wgYW5kIEhTViAtIFdpa2lwZWRpYSwgdGhlIGZyZWUgZW5jeWNsb3BlZGlhXCI+V2lraXBlZGlhIHBhZ2U8L2E+PC9saT5cbiAgICAgIyAgICAgPGxpPmhzbCjigKLigKLigKIlLCDigKLigKLigKIlLCDigKLigKLigKIlKSDigJQgc2FtZSBhcyBhYm92ZSwgYnV0IGluICU8L2xpPlxuICAgICAjICAgICA8bGk+aHNsYSjigKLigKLigKIsIOKAouKAouKAoiwg4oCi4oCi4oCiLCDigKLigKLigKIpIOKAlCBzYW1lIGFzIGFib3ZlLCBidXQgd2l0aCBvcGFjaXR5PC9saT5cbiAgICAgIyAgICAgPGxpPk9wdGlvbmFsbHkgZm9yIGhzYiBhbmQgaHNsIHlvdSBjb3VsZCBzcGVjaWZ5IGh1ZSBhcyBhIGRlZ3JlZTog4oCcPGNvZGU+aHNsKDI0MGRlZywmbmJzcDsxLCZuYnNwOy41KTwvY29kZT7igJ0gb3IsIGlmIHlvdSB3YW50IHRvIGdvIGZhbmN5LCDigJw8Y29kZT5oc2woMjQwwrAsJm5ic3A7MSwmbmJzcDsuNSk8L2NvZGU+4oCdPC9saT5cbiAgICAgIyA8L3VsPlxuICAgIFxcKi9cbiAgICBlbHByb3RvLmF0dHIgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKHRoaXMucmVtb3ZlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIHJlcyA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgYSBpbiB0aGlzLmF0dHJzKSBpZiAodGhpcy5hdHRyc1toYXNdKGEpKSB7XG4gICAgICAgICAgICAgICAgcmVzW2FdID0gdGhpcy5hdHRyc1thXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlcy5ncmFkaWVudCAmJiByZXMuZmlsbCA9PSBcIm5vbmVcIiAmJiAocmVzLmZpbGwgPSByZXMuZ3JhZGllbnQpICYmIGRlbGV0ZSByZXMuZ3JhZGllbnQ7XG4gICAgICAgICAgICByZXMudHJhbnNmb3JtID0gdGhpcy5fLnRyYW5zZm9ybTtcbiAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlID09IG51bGwgJiYgUi5pcyhuYW1lLCBcInN0cmluZ1wiKSkge1xuICAgICAgICAgICAgaWYgKG5hbWUgPT0gXCJmaWxsXCIgJiYgdGhpcy5hdHRycy5maWxsID09IFwibm9uZVwiICYmIHRoaXMuYXR0cnMuZ3JhZGllbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hdHRycy5ncmFkaWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChuYW1lID09IFwidHJhbnNmb3JtXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fLnRyYW5zZm9ybTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBuYW1lcyA9IG5hbWUuc3BsaXQoc2VwYXJhdG9yKSxcbiAgICAgICAgICAgICAgICBvdXQgPSB7fTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IG5hbWVzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgICAgICBuYW1lID0gbmFtZXNbaV07XG4gICAgICAgICAgICAgICAgaWYgKG5hbWUgaW4gdGhpcy5hdHRycykge1xuICAgICAgICAgICAgICAgICAgICBvdXRbbmFtZV0gPSB0aGlzLmF0dHJzW25hbWVdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoUi5pcyh0aGlzLnBhcGVyLmN1c3RvbUF0dHJpYnV0ZXNbbmFtZV0sIFwiZnVuY3Rpb25cIikpIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0W25hbWVdID0gdGhpcy5wYXBlci5jdXN0b21BdHRyaWJ1dGVzW25hbWVdLmRlZjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBvdXRbbmFtZV0gPSBSLl9hdmFpbGFibGVBdHRyc1tuYW1lXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaWkgLSAxID8gb3V0IDogb3V0W25hbWVzWzBdXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCAmJiBSLmlzKG5hbWUsIFwiYXJyYXlcIikpIHtcbiAgICAgICAgICAgIG91dCA9IHt9O1xuICAgICAgICAgICAgZm9yIChpID0gMCwgaWkgPSBuYW1lLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgICAgICBvdXRbbmFtZVtpXV0gPSB0aGlzLmF0dHIobmFtZVtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb3V0O1xuICAgICAgICB9XG4gICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICB2YXIgcGFyYW1zID0ge307XG4gICAgICAgICAgICBwYXJhbXNbbmFtZV0gPSB2YWx1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChuYW1lICE9IG51bGwgJiYgUi5pcyhuYW1lLCBcIm9iamVjdFwiKSkge1xuICAgICAgICAgICAgcGFyYW1zID0gbmFtZTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBrZXkgaW4gcGFyYW1zKSB7XG4gICAgICAgICAgICBldmUoXCJyYXBoYWVsLmF0dHIuXCIgKyBrZXkgKyBcIi5cIiArIHRoaXMuaWQsIHRoaXMsIHBhcmFtc1trZXldKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGtleSBpbiB0aGlzLnBhcGVyLmN1c3RvbUF0dHJpYnV0ZXMpIGlmICh0aGlzLnBhcGVyLmN1c3RvbUF0dHJpYnV0ZXNbaGFzXShrZXkpICYmIHBhcmFtc1toYXNdKGtleSkgJiYgUi5pcyh0aGlzLnBhcGVyLmN1c3RvbUF0dHJpYnV0ZXNba2V5XSwgXCJmdW5jdGlvblwiKSkge1xuICAgICAgICAgICAgdmFyIHBhciA9IHRoaXMucGFwZXIuY3VzdG9tQXR0cmlidXRlc1trZXldLmFwcGx5KHRoaXMsIFtdLmNvbmNhdChwYXJhbXNba2V5XSkpO1xuICAgICAgICAgICAgdGhpcy5hdHRyc1trZXldID0gcGFyYW1zW2tleV07XG4gICAgICAgICAgICBmb3IgKHZhciBzdWJrZXkgaW4gcGFyKSBpZiAocGFyW2hhc10oc3Via2V5KSkge1xuICAgICAgICAgICAgICAgIHBhcmFtc1tzdWJrZXldID0gcGFyW3N1YmtleV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2V0RmlsbEFuZFN0cm9rZSh0aGlzLCBwYXJhbXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBFbGVtZW50LnRvRnJvbnRcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIE1vdmVzIHRoZSBlbGVtZW50IHNvIGl0IGlzIHRoZSBjbG9zZXN0IHRvIHRoZSB2aWV3ZXLigJlzIGV5ZXMsIG9uIHRvcCBvZiBvdGhlciBlbGVtZW50cy5cbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cbiAgICBlbHByb3RvLnRvRnJvbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnJlbW92ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHZhciBub2RlID0gZ2V0UmVhbE5vZGUodGhpcy5ub2RlKTtcbiAgICAgICAgbm9kZS5wYXJlbnROb2RlLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgICAgICB2YXIgc3ZnID0gdGhpcy5wYXBlcjtcbiAgICAgICAgc3ZnLnRvcCAhPSB0aGlzICYmIFIuX3RvZnJvbnQodGhpcywgc3ZnKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC50b0JhY2tcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIE1vdmVzIHRoZSBlbGVtZW50IHNvIGl0IGlzIHRoZSBmdXJ0aGVzdCBmcm9tIHRoZSB2aWV3ZXLigJlzIGV5ZXMsIGJlaGluZCBvdGhlciBlbGVtZW50cy5cbiAgICAgPSAob2JqZWN0KSBARWxlbWVudFxuICAgIFxcKi9cbiAgICBlbHByb3RvLnRvQmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMucmVtb3ZlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG5vZGUgPSBnZXRSZWFsTm9kZSh0aGlzLm5vZGUpO1xuICAgICAgICB2YXIgcGFyZW50Tm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICAgICAgcGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobm9kZSwgcGFyZW50Tm9kZS5maXJzdENoaWxkKTtcbiAgICAgICAgUi5fdG9iYWNrKHRoaXMsIHRoaXMucGFwZXIpO1xuICAgICAgICB2YXIgc3ZnID0gdGhpcy5wYXBlcjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogRWxlbWVudC5pbnNlcnRBZnRlclxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogSW5zZXJ0cyBjdXJyZW50IG9iamVjdCBhZnRlciB0aGUgZ2l2ZW4gb25lLlxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIGVscHJvdG8uaW5zZXJ0QWZ0ZXIgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICBpZiAodGhpcy5yZW1vdmVkIHx8ICFlbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBub2RlID0gZ2V0UmVhbE5vZGUodGhpcy5ub2RlKTtcbiAgICAgICAgdmFyIGFmdGVyTm9kZSA9IGdldFJlYWxOb2RlKGVsZW1lbnQubm9kZSB8fCBlbGVtZW50W2VsZW1lbnQubGVuZ3RoIC0gMV0ubm9kZSk7XG4gICAgICAgIGlmIChhZnRlck5vZGUubmV4dFNpYmxpbmcpIHtcbiAgICAgICAgICAgIGFmdGVyTm9kZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShub2RlLCBhZnRlck5vZGUubmV4dFNpYmxpbmcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWZ0ZXJOb2RlLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQobm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgUi5faW5zZXJ0YWZ0ZXIodGhpcywgZWxlbWVudCwgdGhpcy5wYXBlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIEVsZW1lbnQuaW5zZXJ0QmVmb3JlXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBJbnNlcnRzIGN1cnJlbnQgb2JqZWN0IGJlZm9yZSB0aGUgZ2l2ZW4gb25lLlxuICAgICA9IChvYmplY3QpIEBFbGVtZW50XG4gICAgXFwqL1xuICAgIGVscHJvdG8uaW5zZXJ0QmVmb3JlID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgaWYgKHRoaXMucmVtb3ZlZCB8fCAhZWxlbWVudCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbm9kZSA9IGdldFJlYWxOb2RlKHRoaXMubm9kZSk7XG4gICAgICAgIHZhciBiZWZvcmVOb2RlID0gZ2V0UmVhbE5vZGUoZWxlbWVudC5ub2RlIHx8IGVsZW1lbnRbMF0ubm9kZSk7XG4gICAgICAgIGJlZm9yZU5vZGUucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobm9kZSwgYmVmb3JlTm9kZSk7XG4gICAgICAgIFIuX2luc2VydGJlZm9yZSh0aGlzLCBlbGVtZW50LCB0aGlzLnBhcGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBlbHByb3RvLmJsdXIgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICAgICAgICAvLyBFeHBlcmltZW50YWwuIE5vIFNhZmFyaSBzdXBwb3J0LiBVc2UgaXQgb24geW91ciBvd24gcmlzay5cbiAgICAgICAgdmFyIHQgPSB0aGlzO1xuICAgICAgICBpZiAoK3NpemUgIT09IDApIHtcbiAgICAgICAgICAgIHZhciBmbHRyID0gJChcImZpbHRlclwiKSxcbiAgICAgICAgICAgICAgICBibHVyID0gJChcImZlR2F1c3NpYW5CbHVyXCIpO1xuICAgICAgICAgICAgdC5hdHRycy5ibHVyID0gc2l6ZTtcbiAgICAgICAgICAgIGZsdHIuaWQgPSBSLmNyZWF0ZVVVSUQoKTtcbiAgICAgICAgICAgICQoYmx1ciwge3N0ZERldmlhdGlvbjogK3NpemUgfHwgMS41fSk7XG4gICAgICAgICAgICBmbHRyLmFwcGVuZENoaWxkKGJsdXIpO1xuICAgICAgICAgICAgdC5wYXBlci5kZWZzLmFwcGVuZENoaWxkKGZsdHIpO1xuICAgICAgICAgICAgdC5fYmx1ciA9IGZsdHI7XG4gICAgICAgICAgICAkKHQubm9kZSwge2ZpbHRlcjogXCJ1cmwoI1wiICsgZmx0ci5pZCArIFwiKVwifSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodC5fYmx1cikge1xuICAgICAgICAgICAgICAgIHQuX2JsdXIucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0Ll9ibHVyKTtcbiAgICAgICAgICAgICAgICBkZWxldGUgdC5fYmx1cjtcbiAgICAgICAgICAgICAgICBkZWxldGUgdC5hdHRycy5ibHVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdC5ub2RlLnJlbW92ZUF0dHJpYnV0ZShcImZpbHRlclwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIFIuX2VuZ2luZS5jaXJjbGUgPSBmdW5jdGlvbiAoc3ZnLCB4LCB5LCByKSB7XG4gICAgICAgIHZhciBlbCA9ICQoXCJjaXJjbGVcIik7XG4gICAgICAgIHN2Zy5jYW52YXMgJiYgc3ZnLmNhbnZhcy5hcHBlbmRDaGlsZChlbCk7XG4gICAgICAgIHZhciByZXMgPSBuZXcgRWxlbWVudChlbCwgc3ZnKTtcbiAgICAgICAgcmVzLmF0dHJzID0ge2N4OiB4LCBjeTogeSwgcjogciwgZmlsbDogXCJub25lXCIsIHN0cm9rZTogXCIjMDAwXCJ9O1xuICAgICAgICByZXMudHlwZSA9IFwiY2lyY2xlXCI7XG4gICAgICAgICQoZWwsIHJlcy5hdHRycyk7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfTtcbiAgICBSLl9lbmdpbmUucmVjdCA9IGZ1bmN0aW9uIChzdmcsIHgsIHksIHcsIGgsIHIpIHtcbiAgICAgICAgdmFyIGVsID0gJChcInJlY3RcIik7XG4gICAgICAgIHN2Zy5jYW52YXMgJiYgc3ZnLmNhbnZhcy5hcHBlbmRDaGlsZChlbCk7XG4gICAgICAgIHZhciByZXMgPSBuZXcgRWxlbWVudChlbCwgc3ZnKTtcbiAgICAgICAgcmVzLmF0dHJzID0ge3g6IHgsIHk6IHksIHdpZHRoOiB3LCBoZWlnaHQ6IGgsIHJ4OiByIHx8IDAsIHJ5OiByIHx8IDAsIGZpbGw6IFwibm9uZVwiLCBzdHJva2U6IFwiIzAwMFwifTtcbiAgICAgICAgcmVzLnR5cGUgPSBcInJlY3RcIjtcbiAgICAgICAgJChlbCwgcmVzLmF0dHJzKTtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9O1xuICAgIFIuX2VuZ2luZS5lbGxpcHNlID0gZnVuY3Rpb24gKHN2ZywgeCwgeSwgcngsIHJ5KSB7XG4gICAgICAgIHZhciBlbCA9ICQoXCJlbGxpcHNlXCIpO1xuICAgICAgICBzdmcuY2FudmFzICYmIHN2Zy5jYW52YXMuYXBwZW5kQ2hpbGQoZWwpO1xuICAgICAgICB2YXIgcmVzID0gbmV3IEVsZW1lbnQoZWwsIHN2Zyk7XG4gICAgICAgIHJlcy5hdHRycyA9IHtjeDogeCwgY3k6IHksIHJ4OiByeCwgcnk6IHJ5LCBmaWxsOiBcIm5vbmVcIiwgc3Ryb2tlOiBcIiMwMDBcIn07XG4gICAgICAgIHJlcy50eXBlID0gXCJlbGxpcHNlXCI7XG4gICAgICAgICQoZWwsIHJlcy5hdHRycyk7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfTtcbiAgICBSLl9lbmdpbmUuaW1hZ2UgPSBmdW5jdGlvbiAoc3ZnLCBzcmMsIHgsIHksIHcsIGgpIHtcbiAgICAgICAgdmFyIGVsID0gJChcImltYWdlXCIpO1xuICAgICAgICAkKGVsLCB7eDogeCwgeTogeSwgd2lkdGg6IHcsIGhlaWdodDogaCwgcHJlc2VydmVBc3BlY3RSYXRpbzogXCJub25lXCJ9KTtcbiAgICAgICAgZWwuc2V0QXR0cmlidXRlTlMoeGxpbmssIFwiaHJlZlwiLCBzcmMpO1xuICAgICAgICBzdmcuY2FudmFzICYmIHN2Zy5jYW52YXMuYXBwZW5kQ2hpbGQoZWwpO1xuICAgICAgICB2YXIgcmVzID0gbmV3IEVsZW1lbnQoZWwsIHN2Zyk7XG4gICAgICAgIHJlcy5hdHRycyA9IHt4OiB4LCB5OiB5LCB3aWR0aDogdywgaGVpZ2h0OiBoLCBzcmM6IHNyY307XG4gICAgICAgIHJlcy50eXBlID0gXCJpbWFnZVwiO1xuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH07XG4gICAgUi5fZW5naW5lLnRleHQgPSBmdW5jdGlvbiAoc3ZnLCB4LCB5LCB0ZXh0KSB7XG4gICAgICAgIHZhciBlbCA9ICQoXCJ0ZXh0XCIpO1xuICAgICAgICBzdmcuY2FudmFzICYmIHN2Zy5jYW52YXMuYXBwZW5kQ2hpbGQoZWwpO1xuICAgICAgICB2YXIgcmVzID0gbmV3IEVsZW1lbnQoZWwsIHN2Zyk7XG4gICAgICAgIHJlcy5hdHRycyA9IHtcbiAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICB5OiB5LFxuICAgICAgICAgICAgXCJ0ZXh0LWFuY2hvclwiOiBcIm1pZGRsZVwiLFxuICAgICAgICAgICAgdGV4dDogdGV4dCxcbiAgICAgICAgICAgIFwiZm9udC1mYW1pbHlcIjogUi5fYXZhaWxhYmxlQXR0cnNbXCJmb250LWZhbWlseVwiXSxcbiAgICAgICAgICAgIFwiZm9udC1zaXplXCI6IFIuX2F2YWlsYWJsZUF0dHJzW1wiZm9udC1zaXplXCJdLFxuICAgICAgICAgICAgc3Ryb2tlOiBcIm5vbmVcIixcbiAgICAgICAgICAgIGZpbGw6IFwiIzAwMFwiXG4gICAgICAgIH07XG4gICAgICAgIHJlcy50eXBlID0gXCJ0ZXh0XCI7XG4gICAgICAgIHNldEZpbGxBbmRTdHJva2UocmVzLCByZXMuYXR0cnMpO1xuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH07XG4gICAgUi5fZW5naW5lLnNldFNpemUgPSBmdW5jdGlvbiAod2lkdGgsIGhlaWdodCkge1xuICAgICAgICB0aGlzLndpZHRoID0gd2lkdGggfHwgdGhpcy53aWR0aDtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQgfHwgdGhpcy5oZWlnaHQ7XG4gICAgICAgIHRoaXMuY2FudmFzLnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIHRoaXMud2lkdGgpO1xuICAgICAgICB0aGlzLmNhbnZhcy5zZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIiwgdGhpcy5oZWlnaHQpO1xuICAgICAgICBpZiAodGhpcy5fdmlld0JveCkge1xuICAgICAgICAgICAgdGhpcy5zZXRWaWV3Qm94LmFwcGx5KHRoaXMsIHRoaXMuX3ZpZXdCb3gpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgUi5fZW5naW5lLmNyZWF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbiA9IFIuX2dldENvbnRhaW5lci5hcHBseSgwLCBhcmd1bWVudHMpLFxuICAgICAgICAgICAgY29udGFpbmVyID0gY29uICYmIGNvbi5jb250YWluZXIsXG4gICAgICAgICAgICB4ID0gY29uLngsXG4gICAgICAgICAgICB5ID0gY29uLnksXG4gICAgICAgICAgICB3aWR0aCA9IGNvbi53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodCA9IGNvbi5oZWlnaHQ7XG4gICAgICAgIGlmICghY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTVkcgY29udGFpbmVyIG5vdCBmb3VuZC5cIik7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNudnMgPSAkKFwic3ZnXCIpLFxuICAgICAgICAgICAgY3NzID0gXCJvdmVyZmxvdzpoaWRkZW47XCIsXG4gICAgICAgICAgICBpc0Zsb2F0aW5nO1xuICAgICAgICB4ID0geCB8fCAwO1xuICAgICAgICB5ID0geSB8fCAwO1xuICAgICAgICB3aWR0aCA9IHdpZHRoIHx8IDUxMjtcbiAgICAgICAgaGVpZ2h0ID0gaGVpZ2h0IHx8IDM0MjtcbiAgICAgICAgJChjbnZzLCB7XG4gICAgICAgICAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICAgICAgICAgIHZlcnNpb246IDEuMSxcbiAgICAgICAgICAgIHdpZHRoOiB3aWR0aCxcbiAgICAgICAgICAgIHhtbG5zOiBcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsXG4gICAgICAgICAgICBcInhtbG5zOnhsaW5rXCI6IFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoY29udGFpbmVyID09IDEpIHtcbiAgICAgICAgICAgIGNudnMuc3R5bGUuY3NzVGV4dCA9IGNzcyArIFwicG9zaXRpb246YWJzb2x1dGU7bGVmdDpcIiArIHggKyBcInB4O3RvcDpcIiArIHkgKyBcInB4XCI7XG4gICAgICAgICAgICBSLl9nLmRvYy5ib2R5LmFwcGVuZENoaWxkKGNudnMpO1xuICAgICAgICAgICAgaXNGbG9hdGluZyA9IDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjbnZzLnN0eWxlLmNzc1RleHQgPSBjc3MgKyBcInBvc2l0aW9uOnJlbGF0aXZlXCI7XG4gICAgICAgICAgICBpZiAoY29udGFpbmVyLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBjb250YWluZXIuaW5zZXJ0QmVmb3JlKGNudnMsIGNvbnRhaW5lci5maXJzdENoaWxkKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGNudnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnRhaW5lciA9IG5ldyBSLl9QYXBlcjtcbiAgICAgICAgY29udGFpbmVyLndpZHRoID0gd2lkdGg7XG4gICAgICAgIGNvbnRhaW5lci5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIGNvbnRhaW5lci5jYW52YXMgPSBjbnZzO1xuICAgICAgICBjb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgY29udGFpbmVyLl9sZWZ0ID0gY29udGFpbmVyLl90b3AgPSAwO1xuICAgICAgICBpc0Zsb2F0aW5nICYmIChjb250YWluZXIucmVuZGVyZml4ID0gZnVuY3Rpb24gKCkge30pO1xuICAgICAgICBjb250YWluZXIucmVuZGVyZml4KCk7XG4gICAgICAgIHJldHVybiBjb250YWluZXI7XG4gICAgfTtcbiAgICBSLl9lbmdpbmUuc2V0Vmlld0JveCA9IGZ1bmN0aW9uICh4LCB5LCB3LCBoLCBmaXQpIHtcbiAgICAgICAgZXZlKFwicmFwaGFlbC5zZXRWaWV3Qm94XCIsIHRoaXMsIHRoaXMuX3ZpZXdCb3gsIFt4LCB5LCB3LCBoLCBmaXRdKTtcbiAgICAgICAgdmFyIHBhcGVyU2l6ZSA9IHRoaXMuZ2V0U2l6ZSgpLFxuICAgICAgICAgICAgc2l6ZSA9IG1tYXgodyAvIHBhcGVyU2l6ZS53aWR0aCwgaCAvIHBhcGVyU2l6ZS5oZWlnaHQpLFxuICAgICAgICAgICAgdG9wID0gdGhpcy50b3AsXG4gICAgICAgICAgICBhc3BlY3RSYXRpbyA9IGZpdCA/IFwieE1pZFlNaWQgbWVldFwiIDogXCJ4TWluWU1pblwiLFxuICAgICAgICAgICAgdmIsXG4gICAgICAgICAgICBzdztcbiAgICAgICAgaWYgKHggPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3ZiU2l6ZSkge1xuICAgICAgICAgICAgICAgIHNpemUgPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX3ZiU2l6ZTtcbiAgICAgICAgICAgIHZiID0gXCIwIDAgXCIgKyB0aGlzLndpZHRoICsgUyArIHRoaXMuaGVpZ2h0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fdmJTaXplID0gc2l6ZTtcbiAgICAgICAgICAgIHZiID0geCArIFMgKyB5ICsgUyArIHcgKyBTICsgaDtcbiAgICAgICAgfVxuICAgICAgICAkKHRoaXMuY2FudmFzLCB7XG4gICAgICAgICAgICB2aWV3Qm94OiB2YixcbiAgICAgICAgICAgIHByZXNlcnZlQXNwZWN0UmF0aW86IGFzcGVjdFJhdGlvXG4gICAgICAgIH0pO1xuICAgICAgICB3aGlsZSAoc2l6ZSAmJiB0b3ApIHtcbiAgICAgICAgICAgIHN3ID0gXCJzdHJva2Utd2lkdGhcIiBpbiB0b3AuYXR0cnMgPyB0b3AuYXR0cnNbXCJzdHJva2Utd2lkdGhcIl0gOiAxO1xuICAgICAgICAgICAgdG9wLmF0dHIoe1wic3Ryb2tlLXdpZHRoXCI6IHN3fSk7XG4gICAgICAgICAgICB0b3AuXy5kaXJ0eSA9IDE7XG4gICAgICAgICAgICB0b3AuXy5kaXJ0eVQgPSAxO1xuICAgICAgICAgICAgdG9wID0gdG9wLnByZXY7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdmlld0JveCA9IFt4LCB5LCB3LCBoLCAhIWZpdF07XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFBhcGVyLnJlbmRlcmZpeFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogRml4ZXMgdGhlIGlzc3VlIG9mIEZpcmVmb3ggYW5kIElFOSByZWdhcmRpbmcgc3VicGl4ZWwgcmVuZGVyaW5nLiBJZiBwYXBlciBpcyBkZXBlbmRlbnRcbiAgICAgKiBvbiBvdGhlciBlbGVtZW50cyBhZnRlciByZWZsb3cgaXQgY291bGQgc2hpZnQgaGFsZiBwaXhlbCB3aGljaCBjYXVzZSBmb3IgbGluZXMgdG8gbG9zdCB0aGVpciBjcmlzcG5lc3MuXG4gICAgICogVGhpcyBtZXRob2QgZml4ZXMgdGhlIGlzc3VlLlxuICAgICAqKlxuICAgICAgIFNwZWNpYWwgdGhhbmtzIHRvIE1hcml1c3ogTm93YWsgKGh0dHA6Ly93d3cubWVkaWtvby5jb20vKSBmb3IgdGhpcyBtZXRob2QuXG4gICAgXFwqL1xuICAgIFIucHJvdG90eXBlLnJlbmRlcmZpeCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNudnMgPSB0aGlzLmNhbnZhcyxcbiAgICAgICAgICAgIHMgPSBjbnZzLnN0eWxlLFxuICAgICAgICAgICAgcG9zO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcG9zID0gY252cy5nZXRTY3JlZW5DVE0oKSB8fCBjbnZzLmNyZWF0ZVNWR01hdHJpeCgpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBwb3MgPSBjbnZzLmNyZWF0ZVNWR01hdHJpeCgpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBsZWZ0ID0gLXBvcy5lICUgMSxcbiAgICAgICAgICAgIHRvcCA9IC1wb3MuZiAlIDE7XG4gICAgICAgIGlmIChsZWZ0IHx8IHRvcCkge1xuICAgICAgICAgICAgaWYgKGxlZnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9sZWZ0ID0gKHRoaXMuX2xlZnQgKyBsZWZ0KSAlIDE7XG4gICAgICAgICAgICAgICAgcy5sZWZ0ID0gdGhpcy5fbGVmdCArIFwicHhcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0b3ApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90b3AgPSAodGhpcy5fdG9wICsgdG9wKSAlIDE7XG4gICAgICAgICAgICAgICAgcy50b3AgPSB0aGlzLl90b3AgKyBcInB4XCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBQYXBlci5jbGVhclxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQ2xlYXJzIHRoZSBwYXBlciwgaS5lLiByZW1vdmVzIGFsbCB0aGUgZWxlbWVudHMuXG4gICAgXFwqL1xuICAgIFIucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBSLmV2ZShcInJhcGhhZWwuY2xlYXJcIiwgdGhpcyk7XG4gICAgICAgIHZhciBjID0gdGhpcy5jYW52YXM7XG4gICAgICAgIHdoaWxlIChjLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgIGMucmVtb3ZlQ2hpbGQoYy5maXJzdENoaWxkKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmJvdHRvbSA9IHRoaXMudG9wID0gbnVsbDtcbiAgICAgICAgKHRoaXMuZGVzYyA9ICQoXCJkZXNjXCIpKS5hcHBlbmRDaGlsZChSLl9nLmRvYy5jcmVhdGVUZXh0Tm9kZShcIkNyZWF0ZWQgd2l0aCBSYXBoYVxceGVibCBcIiArIFIudmVyc2lvbikpO1xuICAgICAgICBjLmFwcGVuZENoaWxkKHRoaXMuZGVzYyk7XG4gICAgICAgIGMuYXBwZW5kQ2hpbGQodGhpcy5kZWZzID0gJChcImRlZnNcIikpO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIFBhcGVyLnJlbW92ZVxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogUmVtb3ZlcyB0aGUgcGFwZXIgZnJvbSB0aGUgRE9NLlxuICAgIFxcKi9cbiAgICBSLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGV2ZShcInJhcGhhZWwucmVtb3ZlXCIsIHRoaXMpO1xuICAgICAgICB0aGlzLmNhbnZhcy5wYXJlbnROb2RlICYmIHRoaXMuY2FudmFzLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5jYW52YXMpO1xuICAgICAgICBmb3IgKHZhciBpIGluIHRoaXMpIHtcbiAgICAgICAgICAgIHRoaXNbaV0gPSB0eXBlb2YgdGhpc1tpXSA9PSBcImZ1bmN0aW9uXCIgPyBSLl9yZW1vdmVkRmFjdG9yeShpKSA6IG51bGw7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHZhciBzZXRwcm90byA9IFIuc3Q7XG4gICAgZm9yICh2YXIgbWV0aG9kIGluIGVscHJvdG8pIGlmIChlbHByb3RvW2hhc10obWV0aG9kKSAmJiAhc2V0cHJvdG9baGFzXShtZXRob2QpKSB7XG4gICAgICAgIHNldHByb3RvW21ldGhvZF0gPSAoZnVuY3Rpb24gKG1ldGhvZG5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGFyZyA9IGFyZ3VtZW50cztcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgICAgICAgICBlbFttZXRob2RuYW1lXS5hcHBseShlbCwgYXJnKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKG1ldGhvZCk7XG4gICAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./dev/raphael.svg.js\n"); + +/***/ }), + +/***/ "./dev/raphael.vml.js": +/*!****************************!*\ + !*** ./dev/raphael.vml.js ***! + \****************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! ./raphael.core */ \"./dev/raphael.core.js\")], __WEBPACK_AMD_DEFINE_RESULT__ = (function(R) {\n if (R && !R.vml) {\n return;\n }\n\n var has = \"hasOwnProperty\",\n Str = String,\n toFloat = parseFloat,\n math = Math,\n round = math.round,\n mmax = math.max,\n mmin = math.min,\n abs = math.abs,\n fillString = \"fill\",\n separator = /[, ]+/,\n eve = R.eve,\n ms = \" progid:DXImageTransform.Microsoft\",\n S = \" \",\n E = \"\",\n map = {M: \"m\", L: \"l\", C: \"c\", Z: \"x\", m: \"t\", l: \"r\", c: \"v\", z: \"x\"},\n bites = /([clmz]),?([^clmz]*)/gi,\n blurregexp = / progid:\\S+Blur\\([^\\)]+\\)/g,\n val = /-?[^,\\s-]+/g,\n cssDot = \"position:absolute;left:0;top:0;width:1px;height:1px;behavior:url(#default#VML)\",\n zoom = 21600,\n pathTypes = {path: 1, rect: 1, image: 1},\n ovalTypes = {circle: 1, ellipse: 1},\n path2vml = function (path) {\n var total = /[ahqstv]/ig,\n command = R._pathToAbsolute;\n Str(path).match(total) && (command = R._path2curve);\n total = /[clmz]/g;\n if (command == R._pathToAbsolute && !Str(path).match(total)) {\n var res = Str(path).replace(bites, function (all, command, args) {\n var vals = [],\n isMove = command.toLowerCase() == \"m\",\n res = map[command];\n args.replace(val, function (value) {\n if (isMove && vals.length == 2) {\n res += vals + map[command == \"m\" ? \"l\" : \"L\"];\n vals = [];\n }\n vals.push(round(value * zoom));\n });\n return res + vals;\n });\n return res;\n }\n var pa = command(path), p, r;\n res = [];\n for (var i = 0, ii = pa.length; i < ii; i++) {\n p = pa[i];\n r = pa[i][0].toLowerCase();\n r == \"z\" && (r = \"x\");\n for (var j = 1, jj = p.length; j < jj; j++) {\n r += round(p[j] * zoom) + (j != jj - 1 ? \",\" : E);\n }\n res.push(r);\n }\n return res.join(S);\n },\n compensation = function (deg, dx, dy) {\n var m = R.matrix();\n m.rotate(-deg, .5, .5);\n return {\n dx: m.x(dx, dy),\n dy: m.y(dx, dy)\n };\n },\n setCoords = function (p, sx, sy, dx, dy, deg) {\n var _ = p._,\n m = p.matrix,\n fillpos = _.fillpos,\n o = p.node,\n s = o.style,\n y = 1,\n flip = \"\",\n dxdy,\n kx = zoom / sx,\n ky = zoom / sy;\n s.visibility = \"hidden\";\n if (!sx || !sy) {\n return;\n }\n o.coordsize = abs(kx) + S + abs(ky);\n s.rotation = deg * (sx * sy < 0 ? -1 : 1);\n if (deg) {\n var c = compensation(deg, dx, dy);\n dx = c.dx;\n dy = c.dy;\n }\n sx < 0 && (flip += \"x\");\n sy < 0 && (flip += \" y\") && (y = -1);\n s.flip = flip;\n o.coordorigin = (dx * -kx) + S + (dy * -ky);\n if (fillpos || _.fillsize) {\n var fill = o.getElementsByTagName(fillString);\n fill = fill && fill[0];\n o.removeChild(fill);\n if (fillpos) {\n c = compensation(deg, m.x(fillpos[0], fillpos[1]), m.y(fillpos[0], fillpos[1]));\n fill.position = c.dx * y + S + c.dy * y;\n }\n if (_.fillsize) {\n fill.size = _.fillsize[0] * abs(sx) + S + _.fillsize[1] * abs(sy);\n }\n o.appendChild(fill);\n }\n s.visibility = \"visible\";\n };\n R.toString = function () {\n return \"Your browser doesn\\u2019t support SVG. Falling down to VML.\\nYou are running Rapha\\xebl \" + this.version;\n };\n var addArrow = function (o, value, isEnd) {\n var values = Str(value).toLowerCase().split(\"-\"),\n se = isEnd ? \"end\" : \"start\",\n i = values.length,\n type = \"classic\",\n w = \"medium\",\n h = \"medium\";\n while (i--) {\n switch (values[i]) {\n case \"block\":\n case \"classic\":\n case \"oval\":\n case \"diamond\":\n case \"open\":\n case \"none\":\n type = values[i];\n break;\n case \"wide\":\n case \"narrow\": h = values[i]; break;\n case \"long\":\n case \"short\": w = values[i]; break;\n }\n }\n var stroke = o.node.getElementsByTagName(\"stroke\")[0];\n stroke[se + \"arrow\"] = type;\n stroke[se + \"arrowlength\"] = w;\n stroke[se + \"arrowwidth\"] = h;\n },\n setFillAndStroke = function (o, params) {\n // o.paper.canvas.style.display = \"none\";\n o.attrs = o.attrs || {};\n var node = o.node,\n a = o.attrs,\n s = node.style,\n xy,\n newpath = pathTypes[o.type] && (params.x != a.x || params.y != a.y || params.width != a.width || params.height != a.height || params.cx != a.cx || params.cy != a.cy || params.rx != a.rx || params.ry != a.ry || params.r != a.r),\n isOval = ovalTypes[o.type] && (a.cx != params.cx || a.cy != params.cy || a.r != params.r || a.rx != params.rx || a.ry != params.ry),\n res = o;\n\n\n for (var par in params) if (params[has](par)) {\n a[par] = params[par];\n }\n if (newpath) {\n a.path = R._getPath[o.type](o);\n o._.dirty = 1;\n }\n params.href && (node.href = params.href);\n params.title && (node.title = params.title);\n params.target && (node.target = params.target);\n params.cursor && (s.cursor = params.cursor);\n \"blur\" in params && o.blur(params.blur);\n if (params.path && o.type == \"path\" || newpath) {\n node.path = path2vml(~Str(a.path).toLowerCase().indexOf(\"r\") ? R._pathToAbsolute(a.path) : a.path);\n o._.dirty = 1;\n if (o.type == \"image\") {\n o._.fillpos = [a.x, a.y];\n o._.fillsize = [a.width, a.height];\n setCoords(o, 1, 1, 0, 0, 0);\n }\n }\n \"transform\" in params && o.transform(params.transform);\n if (isOval) {\n var cx = +a.cx,\n cy = +a.cy,\n rx = +a.rx || +a.r || 0,\n ry = +a.ry || +a.r || 0;\n node.path = R.format(\"ar{0},{1},{2},{3},{4},{1},{4},{1}x\", round((cx - rx) * zoom), round((cy - ry) * zoom), round((cx + rx) * zoom), round((cy + ry) * zoom), round(cx * zoom));\n o._.dirty = 1;\n }\n if (\"clip-rect\" in params) {\n var rect = Str(params[\"clip-rect\"]).split(separator);\n if (rect.length == 4) {\n rect[2] = +rect[2] + (+rect[0]);\n rect[3] = +rect[3] + (+rect[1]);\n var div = node.clipRect || R._g.doc.createElement(\"div\"),\n dstyle = div.style;\n dstyle.clip = R.format(\"rect({1}px {2}px {3}px {0}px)\", rect);\n if (!node.clipRect) {\n dstyle.position = \"absolute\";\n dstyle.top = 0;\n dstyle.left = 0;\n dstyle.width = o.paper.width + \"px\";\n dstyle.height = o.paper.height + \"px\";\n node.parentNode.insertBefore(div, node);\n div.appendChild(node);\n node.clipRect = div;\n }\n }\n if (!params[\"clip-rect\"]) {\n node.clipRect && (node.clipRect.style.clip = \"auto\");\n }\n }\n if (o.textpath) {\n var textpathStyle = o.textpath.style;\n params.font && (textpathStyle.font = params.font);\n params[\"font-family\"] && (textpathStyle.fontFamily = '\"' + params[\"font-family\"].split(\",\")[0].replace(/^['\"]+|['\"]+$/g, E) + '\"');\n params[\"font-size\"] && (textpathStyle.fontSize = params[\"font-size\"]);\n params[\"font-weight\"] && (textpathStyle.fontWeight = params[\"font-weight\"]);\n params[\"font-style\"] && (textpathStyle.fontStyle = params[\"font-style\"]);\n }\n if (\"arrow-start\" in params) {\n addArrow(res, params[\"arrow-start\"]);\n }\n if (\"arrow-end\" in params) {\n addArrow(res, params[\"arrow-end\"], 1);\n }\n if (params.opacity != null ||\n params.fill != null ||\n params.src != null ||\n params.stroke != null ||\n params[\"stroke-width\"] != null ||\n params[\"stroke-opacity\"] != null ||\n params[\"fill-opacity\"] != null ||\n params[\"stroke-dasharray\"] != null ||\n params[\"stroke-miterlimit\"] != null ||\n params[\"stroke-linejoin\"] != null ||\n params[\"stroke-linecap\"] != null) {\n var fill = node.getElementsByTagName(fillString),\n newfill = false;\n fill = fill && fill[0];\n !fill && (newfill = fill = createNode(fillString));\n if (o.type == \"image\" && params.src) {\n fill.src = params.src;\n }\n params.fill && (fill.on = true);\n if (fill.on == null || params.fill == \"none\" || params.fill === null) {\n fill.on = false;\n }\n if (fill.on && params.fill) {\n var isURL = Str(params.fill).match(R._ISURL);\n if (isURL) {\n fill.parentNode == node && node.removeChild(fill);\n fill.rotate = true;\n fill.src = isURL[1];\n fill.type = \"tile\";\n var bbox = o.getBBox(1);\n fill.position = bbox.x + S + bbox.y;\n o._.fillpos = [bbox.x, bbox.y];\n\n R._preload(isURL[1], function () {\n o._.fillsize = [this.offsetWidth, this.offsetHeight];\n });\n } else {\n fill.color = R.getRGB(params.fill).hex;\n fill.src = E;\n fill.type = \"solid\";\n if (R.getRGB(params.fill).error && (res.type in {circle: 1, ellipse: 1} || Str(params.fill).charAt() != \"r\") && addGradientFill(res, params.fill, fill)) {\n a.fill = \"none\";\n a.gradient = params.fill;\n fill.rotate = false;\n }\n }\n }\n if (\"fill-opacity\" in params || \"opacity\" in params) {\n var opacity = ((+a[\"fill-opacity\"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+R.getRGB(params.fill).o + 1 || 2) - 1);\n opacity = mmin(mmax(opacity, 0), 1);\n fill.opacity = opacity;\n if (fill.src) {\n fill.color = \"none\";\n }\n }\n node.appendChild(fill);\n var stroke = (node.getElementsByTagName(\"stroke\") && node.getElementsByTagName(\"stroke\")[0]),\n newstroke = false;\n !stroke && (newstroke = stroke = createNode(\"stroke\"));\n if ((params.stroke && params.stroke != \"none\") ||\n params[\"stroke-width\"] ||\n params[\"stroke-opacity\"] != null ||\n params[\"stroke-dasharray\"] ||\n params[\"stroke-miterlimit\"] ||\n params[\"stroke-linejoin\"] ||\n params[\"stroke-linecap\"]) {\n stroke.on = true;\n }\n (params.stroke == \"none\" || params.stroke === null || stroke.on == null || params.stroke == 0 || params[\"stroke-width\"] == 0) && (stroke.on = false);\n var strokeColor = R.getRGB(params.stroke);\n stroke.on && params.stroke && (stroke.color = strokeColor.hex);\n opacity = ((+a[\"stroke-opacity\"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+strokeColor.o + 1 || 2) - 1);\n var width = (toFloat(params[\"stroke-width\"]) || 1) * .75;\n opacity = mmin(mmax(opacity, 0), 1);\n params[\"stroke-width\"] == null && (width = a[\"stroke-width\"]);\n params[\"stroke-width\"] && (stroke.weight = width);\n width && width < 1 && (opacity *= width) && (stroke.weight = 1);\n stroke.opacity = opacity;\n\n params[\"stroke-linejoin\"] && (stroke.joinstyle = params[\"stroke-linejoin\"] || \"miter\");\n stroke.miterlimit = params[\"stroke-miterlimit\"] || 8;\n params[\"stroke-linecap\"] && (stroke.endcap = params[\"stroke-linecap\"] == \"butt\" ? \"flat\" : params[\"stroke-linecap\"] == \"square\" ? \"square\" : \"round\");\n if (\"stroke-dasharray\" in params) {\n var dasharray = {\n \"-\": \"shortdash\",\n \".\": \"shortdot\",\n \"-.\": \"shortdashdot\",\n \"-..\": \"shortdashdotdot\",\n \". \": \"dot\",\n \"- \": \"dash\",\n \"--\": \"longdash\",\n \"- .\": \"dashdot\",\n \"--.\": \"longdashdot\",\n \"--..\": \"longdashdotdot\"\n };\n stroke.dashstyle = dasharray[has](params[\"stroke-dasharray\"]) ? dasharray[params[\"stroke-dasharray\"]] : E;\n }\n newstroke && node.appendChild(stroke);\n }\n if (res.type == \"text\") {\n res.paper.canvas.style.display = E;\n var span = res.paper.span,\n m = 100,\n fontSize = a.font && a.font.match(/\\d+(?:\\.\\d*)?(?=px)/);\n s = span.style;\n a.font && (s.font = a.font);\n a[\"font-family\"] && (s.fontFamily = a[\"font-family\"]);\n a[\"font-weight\"] && (s.fontWeight = a[\"font-weight\"]);\n a[\"font-style\"] && (s.fontStyle = a[\"font-style\"]);\n fontSize = toFloat(a[\"font-size\"] || fontSize && fontSize[0]) || 10;\n s.fontSize = fontSize * m + \"px\";\n res.textpath.string && (span.innerHTML = Str(res.textpath.string).replace(/</g, \"<\").replace(/&/g, \"&\").replace(/\\n/g, \"<br>\"));\n var brect = span.getBoundingClientRect();\n res.W = a.w = (brect.right - brect.left) / m;\n res.H = a.h = (brect.bottom - brect.top) / m;\n // res.paper.canvas.style.display = \"none\";\n res.X = a.x;\n res.Y = a.y + res.H / 2;\n\n (\"x\" in params || \"y\" in params) && (res.path.v = R.format(\"m{0},{1}l{2},{1}\", round(a.x * zoom), round(a.y * zoom), round(a.x * zoom) + 1));\n var dirtyattrs = [\"x\", \"y\", \"text\", \"font\", \"font-family\", \"font-weight\", \"font-style\", \"font-size\"];\n for (var d = 0, dd = dirtyattrs.length; d < dd; d++) if (dirtyattrs[d] in params) {\n res._.dirty = 1;\n break;\n }\n\n // text-anchor emulation\n switch (a[\"text-anchor\"]) {\n case \"start\":\n res.textpath.style[\"v-text-align\"] = \"left\";\n res.bbx = res.W / 2;\n break;\n case \"end\":\n res.textpath.style[\"v-text-align\"] = \"right\";\n res.bbx = -res.W / 2;\n break;\n default:\n res.textpath.style[\"v-text-align\"] = \"center\";\n res.bbx = 0;\n break;\n }\n res.textpath.style[\"v-text-kern\"] = true;\n }\n // res.paper.canvas.style.display = E;\n },\n addGradientFill = function (o, gradient, fill) {\n o.attrs = o.attrs || {};\n var attrs = o.attrs,\n pow = Math.pow,\n opacity,\n oindex,\n type = \"linear\",\n fxfy = \".5 .5\";\n o.attrs.gradient = gradient;\n gradient = Str(gradient).replace(R._radial_gradient, function (all, fx, fy) {\n type = \"radial\";\n if (fx && fy) {\n fx = toFloat(fx);\n fy = toFloat(fy);\n pow(fx - .5, 2) + pow(fy - .5, 2) > .25 && (fy = math.sqrt(.25 - pow(fx - .5, 2)) * ((fy > .5) * 2 - 1) + .5);\n fxfy = fx + S + fy;\n }\n return E;\n });\n gradient = gradient.split(/\\s*\\-\\s*/);\n if (type == \"linear\") {\n var angle = gradient.shift();\n angle = -toFloat(angle);\n if (isNaN(angle)) {\n return null;\n }\n }\n var dots = R._parseDots(gradient);\n if (!dots) {\n return null;\n }\n o = o.shape || o.node;\n if (dots.length) {\n o.removeChild(fill);\n fill.on = true;\n fill.method = \"none\";\n fill.color = dots[0].color;\n fill.color2 = dots[dots.length - 1].color;\n var clrs = [];\n for (var i = 0, ii = dots.length; i < ii; i++) {\n dots[i].offset && clrs.push(dots[i].offset + S + dots[i].color);\n }\n fill.colors = clrs.length ? clrs.join() : \"0% \" + fill.color;\n if (type == \"radial\") {\n fill.type = \"gradientTitle\";\n fill.focus = \"100%\";\n fill.focussize = \"0 0\";\n fill.focusposition = fxfy;\n fill.angle = 0;\n } else {\n // fill.rotate= true;\n fill.type = \"gradient\";\n fill.angle = (270 - angle) % 360;\n }\n o.appendChild(fill);\n }\n return 1;\n },\n Element = function (node, vml) {\n this[0] = this.node = node;\n node.raphael = true;\n this.id = R._oid++;\n node.raphaelid = this.id;\n this.X = 0;\n this.Y = 0;\n this.attrs = {};\n this.paper = vml;\n this.matrix = R.matrix();\n this._ = {\n transform: [],\n sx: 1,\n sy: 1,\n dx: 0,\n dy: 0,\n deg: 0,\n dirty: 1,\n dirtyT: 1\n };\n !vml.bottom && (vml.bottom = this);\n this.prev = vml.top;\n vml.top && (vml.top.next = this);\n vml.top = this;\n this.next = null;\n };\n var elproto = R.el;\n\n Element.prototype = elproto;\n elproto.constructor = Element;\n elproto.transform = function (tstr) {\n if (tstr == null) {\n return this._.transform;\n }\n var vbs = this.paper._viewBoxShift,\n vbt = vbs ? \"s\" + [vbs.scale, vbs.scale] + \"-1-1t\" + [vbs.dx, vbs.dy] : E,\n oldt;\n if (vbs) {\n oldt = tstr = Str(tstr).replace(/\\.{3}|\\u2026/g, this._.transform || E);\n }\n R._extractTransform(this, vbt + tstr);\n var matrix = this.matrix.clone(),\n skew = this.skew,\n o = this.node,\n split,\n isGrad = ~Str(this.attrs.fill).indexOf(\"-\"),\n isPatt = !Str(this.attrs.fill).indexOf(\"url(\");\n matrix.translate(1, 1);\n if (isPatt || isGrad || this.type == \"image\") {\n skew.matrix = \"1 0 0 1\";\n skew.offset = \"0 0\";\n split = matrix.split();\n if ((isGrad && split.noRotation) || !split.isSimple) {\n o.style.filter = matrix.toFilter();\n var bb = this.getBBox(),\n bbt = this.getBBox(1),\n dx = bb.x - bbt.x,\n dy = bb.y - bbt.y;\n o.coordorigin = (dx * -zoom) + S + (dy * -zoom);\n setCoords(this, 1, 1, dx, dy, 0);\n } else {\n o.style.filter = E;\n setCoords(this, split.scalex, split.scaley, split.dx, split.dy, split.rotate);\n }\n } else {\n o.style.filter = E;\n skew.matrix = Str(matrix);\n skew.offset = matrix.offset();\n }\n if (oldt !== null) { // empty string value is true as well\n this._.transform = oldt;\n R._extractTransform(this, oldt);\n }\n return this;\n };\n elproto.rotate = function (deg, cx, cy) {\n if (this.removed) {\n return this;\n }\n if (deg == null) {\n return;\n }\n deg = Str(deg).split(separator);\n if (deg.length - 1) {\n cx = toFloat(deg[1]);\n cy = toFloat(deg[2]);\n }\n deg = toFloat(deg[0]);\n (cy == null) && (cx = cy);\n if (cx == null || cy == null) {\n var bbox = this.getBBox(1);\n cx = bbox.x + bbox.width / 2;\n cy = bbox.y + bbox.height / 2;\n }\n this._.dirtyT = 1;\n this.transform(this._.transform.concat([[\"r\", deg, cx, cy]]));\n return this;\n };\n elproto.translate = function (dx, dy) {\n if (this.removed) {\n return this;\n }\n dx = Str(dx).split(separator);\n if (dx.length - 1) {\n dy = toFloat(dx[1]);\n }\n dx = toFloat(dx[0]) || 0;\n dy = +dy || 0;\n if (this._.bbox) {\n this._.bbox.x += dx;\n this._.bbox.y += dy;\n }\n this.transform(this._.transform.concat([[\"t\", dx, dy]]));\n return this;\n };\n elproto.scale = function (sx, sy, cx, cy) {\n if (this.removed) {\n return this;\n }\n sx = Str(sx).split(separator);\n if (sx.length - 1) {\n sy = toFloat(sx[1]);\n cx = toFloat(sx[2]);\n cy = toFloat(sx[3]);\n isNaN(cx) && (cx = null);\n isNaN(cy) && (cy = null);\n }\n sx = toFloat(sx[0]);\n (sy == null) && (sy = sx);\n (cy == null) && (cx = cy);\n if (cx == null || cy == null) {\n var bbox = this.getBBox(1);\n }\n cx = cx == null ? bbox.x + bbox.width / 2 : cx;\n cy = cy == null ? bbox.y + bbox.height / 2 : cy;\n\n this.transform(this._.transform.concat([[\"s\", sx, sy, cx, cy]]));\n this._.dirtyT = 1;\n return this;\n };\n elproto.hide = function () {\n !this.removed && (this.node.style.display = \"none\");\n return this;\n };\n elproto.show = function () {\n !this.removed && (this.node.style.display = E);\n return this;\n };\n // Needed to fix the vml setViewBox issues\n elproto.auxGetBBox = R.el.getBBox;\n elproto.getBBox = function(){\n var b = this.auxGetBBox();\n if (this.paper && this.paper._viewBoxShift)\n {\n var c = {};\n var z = 1/this.paper._viewBoxShift.scale;\n c.x = b.x - this.paper._viewBoxShift.dx;\n c.x *= z;\n c.y = b.y - this.paper._viewBoxShift.dy;\n c.y *= z;\n c.width = b.width * z;\n c.height = b.height * z;\n c.x2 = c.x + c.width;\n c.y2 = c.y + c.height;\n return c;\n }\n return b;\n };\n elproto._getBBox = function () {\n if (this.removed) {\n return {};\n }\n return {\n x: this.X + (this.bbx || 0) - this.W / 2,\n y: this.Y - this.H,\n width: this.W,\n height: this.H\n };\n };\n elproto.remove = function () {\n if (this.removed || !this.node.parentNode) {\n return;\n }\n this.paper.__set__ && this.paper.__set__.exclude(this);\n R.eve.unbind(\"raphael.*.*.\" + this.id);\n R._tear(this, this.paper);\n this.node.parentNode.removeChild(this.node);\n this.shape && this.shape.parentNode.removeChild(this.shape);\n for (var i in this) {\n this[i] = typeof this[i] == \"function\" ? R._removedFactory(i) : null;\n }\n this.removed = true;\n };\n elproto.attr = function (name, value) {\n if (this.removed) {\n return this;\n }\n if (name == null) {\n var res = {};\n for (var a in this.attrs) if (this.attrs[has](a)) {\n res[a] = this.attrs[a];\n }\n res.gradient && res.fill == \"none\" && (res.fill = res.gradient) && delete res.gradient;\n res.transform = this._.transform;\n return res;\n }\n if (value == null && R.is(name, \"string\")) {\n if (name == fillString && this.attrs.fill == \"none\" && this.attrs.gradient) {\n return this.attrs.gradient;\n }\n var names = name.split(separator),\n out = {};\n for (var i = 0, ii = names.length; i < ii; i++) {\n name = names[i];\n if (name in this.attrs) {\n out[name] = this.attrs[name];\n } else if (R.is(this.paper.customAttributes[name], \"function\")) {\n out[name] = this.paper.customAttributes[name].def;\n } else {\n out[name] = R._availableAttrs[name];\n }\n }\n return ii - 1 ? out : out[names[0]];\n }\n if (this.attrs && value == null && R.is(name, \"array\")) {\n out = {};\n for (i = 0, ii = name.length; i < ii; i++) {\n out[name[i]] = this.attr(name[i]);\n }\n return out;\n }\n var params;\n if (value != null) {\n params = {};\n params[name] = value;\n }\n value == null && R.is(name, \"object\") && (params = name);\n for (var key in params) {\n eve(\"raphael.attr.\" + key + \".\" + this.id, this, params[key]);\n }\n if (params) {\n for (key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], \"function\")) {\n var par = this.paper.customAttributes[key].apply(this, [].concat(params[key]));\n this.attrs[key] = params[key];\n for (var subkey in par) if (par[has](subkey)) {\n params[subkey] = par[subkey];\n }\n }\n // this.paper.canvas.style.display = \"none\";\n if (params.text && this.type == \"text\") {\n this.textpath.string = params.text;\n }\n setFillAndStroke(this, params);\n // this.paper.canvas.style.display = E;\n }\n return this;\n };\n elproto.toFront = function () {\n !this.removed && this.node.parentNode.appendChild(this.node);\n this.paper && this.paper.top != this && R._tofront(this, this.paper);\n return this;\n };\n elproto.toBack = function () {\n if (this.removed) {\n return this;\n }\n if (this.node.parentNode.firstChild != this.node) {\n this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild);\n R._toback(this, this.paper);\n }\n return this;\n };\n elproto.insertAfter = function (element) {\n if (this.removed) {\n return this;\n }\n if (element.constructor == R.st.constructor) {\n element = element[element.length - 1];\n }\n if (element.node.nextSibling) {\n element.node.parentNode.insertBefore(this.node, element.node.nextSibling);\n } else {\n element.node.parentNode.appendChild(this.node);\n }\n R._insertafter(this, element, this.paper);\n return this;\n };\n elproto.insertBefore = function (element) {\n if (this.removed) {\n return this;\n }\n if (element.constructor == R.st.constructor) {\n element = element[0];\n }\n element.node.parentNode.insertBefore(this.node, element.node);\n R._insertbefore(this, element, this.paper);\n return this;\n };\n elproto.blur = function (size) {\n var s = this.node.runtimeStyle,\n f = s.filter;\n f = f.replace(blurregexp, E);\n if (+size !== 0) {\n this.attrs.blur = size;\n s.filter = f + S + ms + \".Blur(pixelradius=\" + (+size || 1.5) + \")\";\n s.margin = R.format(\"-{0}px 0 0 -{0}px\", round(+size || 1.5));\n } else {\n s.filter = f;\n s.margin = 0;\n delete this.attrs.blur;\n }\n return this;\n };\n\n R._engine.path = function (pathString, vml) {\n var el = createNode(\"shape\");\n el.style.cssText = cssDot;\n el.coordsize = zoom + S + zoom;\n el.coordorigin = vml.coordorigin;\n var p = new Element(el, vml),\n attr = {fill: \"none\", stroke: \"#000\"};\n pathString && (attr.path = pathString);\n p.type = \"path\";\n p.path = [];\n p.Path = E;\n setFillAndStroke(p, attr);\n vml.canvas && vml.canvas.appendChild(el);\n var skew = createNode(\"skew\");\n skew.on = true;\n el.appendChild(skew);\n p.skew = skew;\n p.transform(E);\n return p;\n };\n R._engine.rect = function (vml, x, y, w, h, r) {\n var path = R._rectPath(x, y, w, h, r),\n res = vml.path(path),\n a = res.attrs;\n res.X = a.x = x;\n res.Y = a.y = y;\n res.W = a.width = w;\n res.H = a.height = h;\n a.r = r;\n a.path = path;\n res.type = \"rect\";\n return res;\n };\n R._engine.ellipse = function (vml, x, y, rx, ry) {\n var res = vml.path(),\n a = res.attrs;\n res.X = x - rx;\n res.Y = y - ry;\n res.W = rx * 2;\n res.H = ry * 2;\n res.type = \"ellipse\";\n setFillAndStroke(res, {\n cx: x,\n cy: y,\n rx: rx,\n ry: ry\n });\n return res;\n };\n R._engine.circle = function (vml, x, y, r) {\n var res = vml.path(),\n a = res.attrs;\n res.X = x - r;\n res.Y = y - r;\n res.W = res.H = r * 2;\n res.type = \"circle\";\n setFillAndStroke(res, {\n cx: x,\n cy: y,\n r: r\n });\n return res;\n };\n R._engine.image = function (vml, src, x, y, w, h) {\n var path = R._rectPath(x, y, w, h),\n res = vml.path(path).attr({stroke: \"none\"}),\n a = res.attrs,\n node = res.node,\n fill = node.getElementsByTagName(fillString)[0];\n a.src = src;\n res.X = a.x = x;\n res.Y = a.y = y;\n res.W = a.width = w;\n res.H = a.height = h;\n a.path = path;\n res.type = \"image\";\n fill.parentNode == node && node.removeChild(fill);\n fill.rotate = true;\n fill.src = src;\n fill.type = \"tile\";\n res._.fillpos = [x, y];\n res._.fillsize = [w, h];\n node.appendChild(fill);\n setCoords(res, 1, 1, 0, 0, 0);\n return res;\n };\n R._engine.text = function (vml, x, y, text) {\n var el = createNode(\"shape\"),\n path = createNode(\"path\"),\n o = createNode(\"textpath\");\n x = x || 0;\n y = y || 0;\n text = text || \"\";\n path.v = R.format(\"m{0},{1}l{2},{1}\", round(x * zoom), round(y * zoom), round(x * zoom) + 1);\n path.textpathok = true;\n o.string = Str(text);\n o.on = true;\n el.style.cssText = cssDot;\n el.coordsize = zoom + S + zoom;\n el.coordorigin = \"0 0\";\n var p = new Element(el, vml),\n attr = {\n fill: \"#000\",\n stroke: \"none\",\n font: R._availableAttrs.font,\n text: text\n };\n p.shape = el;\n p.path = path;\n p.textpath = o;\n p.type = \"text\";\n p.attrs.text = Str(text);\n p.attrs.x = x;\n p.attrs.y = y;\n p.attrs.w = 1;\n p.attrs.h = 1;\n setFillAndStroke(p, attr);\n el.appendChild(o);\n el.appendChild(path);\n vml.canvas.appendChild(el);\n var skew = createNode(\"skew\");\n skew.on = true;\n el.appendChild(skew);\n p.skew = skew;\n p.transform(E);\n return p;\n };\n R._engine.setSize = function (width, height) {\n var cs = this.canvas.style;\n this.width = width;\n this.height = height;\n width == +width && (width += \"px\");\n height == +height && (height += \"px\");\n cs.width = width;\n cs.height = height;\n cs.clip = \"rect(0 \" + width + \" \" + height + \" 0)\";\n if (this._viewBox) {\n R._engine.setViewBox.apply(this, this._viewBox);\n }\n return this;\n };\n R._engine.setViewBox = function (x, y, w, h, fit) {\n R.eve(\"raphael.setViewBox\", this, this._viewBox, [x, y, w, h, fit]);\n var paperSize = this.getSize(),\n width = paperSize.width,\n height = paperSize.height,\n H, W;\n if (fit) {\n H = height / h;\n W = width / w;\n if (w * H < width) {\n x -= (width - w * H) / 2 / H;\n }\n if (h * W < height) {\n y -= (height - h * W) / 2 / W;\n }\n }\n this._viewBox = [x, y, w, h, !!fit];\n this._viewBoxShift = {\n dx: -x,\n dy: -y,\n scale: paperSize\n };\n this.forEach(function (el) {\n el.transform(\"...\");\n });\n return this;\n };\n var createNode;\n R._engine.initWin = function (win) {\n var doc = win.document;\n if (doc.styleSheets.length < 31) {\n doc.createStyleSheet().addRule(\".rvml\", \"behavior:url(#default#VML)\");\n } else {\n // no more room, add to the existing one\n // http://msdn.microsoft.com/en-us/library/ms531194%28VS.85%29.aspx\n doc.styleSheets[0].addRule(\".rvml\", \"behavior:url(#default#VML)\");\n }\n try {\n !doc.namespaces.rvml && doc.namespaces.add(\"rvml\", \"urn:schemas-microsoft-com:vml\");\n createNode = function (tagName) {\n return doc.createElement('<rvml:' + tagName + ' class=\"rvml\">');\n };\n } catch (e) {\n createNode = function (tagName) {\n return doc.createElement('<' + tagName + ' xmlns=\"urn:schemas-microsoft.com:vml\" class=\"rvml\">');\n };\n }\n };\n R._engine.initWin(R._g.win);\n R._engine.create = function () {\n var con = R._getContainer.apply(0, arguments),\n container = con.container,\n height = con.height,\n s,\n width = con.width,\n x = con.x,\n y = con.y;\n if (!container) {\n throw new Error(\"VML container not found.\");\n }\n var res = new R._Paper,\n c = res.canvas = R._g.doc.createElement(\"div\"),\n cs = c.style;\n x = x || 0;\n y = y || 0;\n width = width || 512;\n height = height || 342;\n res.width = width;\n res.height = height;\n width == +width && (width += \"px\");\n height == +height && (height += \"px\");\n res.coordsize = zoom * 1e3 + S + zoom * 1e3;\n res.coordorigin = \"0 0\";\n res.span = R._g.doc.createElement(\"span\");\n res.span.style.cssText = \"position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;\";\n c.appendChild(res.span);\n cs.cssText = R.format(\"top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden\", width, height);\n if (container == 1) {\n R._g.doc.body.appendChild(c);\n cs.left = x + \"px\";\n cs.top = y + \"px\";\n cs.position = \"absolute\";\n } else {\n if (container.firstChild) {\n container.insertBefore(c, container.firstChild);\n } else {\n container.appendChild(c);\n }\n }\n res.renderfix = function () {};\n return res;\n };\n R.prototype.clear = function () {\n R.eve(\"raphael.clear\", this);\n this.canvas.innerHTML = E;\n this.span = R._g.doc.createElement(\"span\");\n this.span.style.cssText = \"position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;\";\n this.canvas.appendChild(this.span);\n this.bottom = this.top = null;\n };\n R.prototype.remove = function () {\n R.eve(\"raphael.remove\", this);\n this.canvas.parentNode.removeChild(this.canvas);\n for (var i in this) {\n this[i] = typeof this[i] == \"function\" ? R._removedFactory(i) : null;\n }\n return true;\n };\n\n var setproto = R.st;\n for (var method in elproto) if (elproto[has](method) && !setproto[has](method)) {\n setproto[method] = (function (methodname) {\n return function () {\n var arg = arguments;\n return this.forEach(function (el) {\n el[methodname].apply(el, arg);\n });\n };\n })(method);\n }\n}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9kZXYvcmFwaGFlbC52bWwuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9SYXBoYWVsLy4vZGV2L3JhcGhhZWwudm1sLmpzP2JhZjAiXSwic291cmNlc0NvbnRlbnQiOlsiZGVmaW5lKFtcIi4vcmFwaGFlbC5jb3JlXCJdLCBmdW5jdGlvbihSKSB7XG4gICAgaWYgKFIgJiYgIVIudm1sKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgaGFzID0gXCJoYXNPd25Qcm9wZXJ0eVwiLFxuICAgICAgICBTdHIgPSBTdHJpbmcsXG4gICAgICAgIHRvRmxvYXQgPSBwYXJzZUZsb2F0LFxuICAgICAgICBtYXRoID0gTWF0aCxcbiAgICAgICAgcm91bmQgPSBtYXRoLnJvdW5kLFxuICAgICAgICBtbWF4ID0gbWF0aC5tYXgsXG4gICAgICAgIG1taW4gPSBtYXRoLm1pbixcbiAgICAgICAgYWJzID0gbWF0aC5hYnMsXG4gICAgICAgIGZpbGxTdHJpbmcgPSBcImZpbGxcIixcbiAgICAgICAgc2VwYXJhdG9yID0gL1ssIF0rLyxcbiAgICAgICAgZXZlID0gUi5ldmUsXG4gICAgICAgIG1zID0gXCIgcHJvZ2lkOkRYSW1hZ2VUcmFuc2Zvcm0uTWljcm9zb2Z0XCIsXG4gICAgICAgIFMgPSBcIiBcIixcbiAgICAgICAgRSA9IFwiXCIsXG4gICAgICAgIG1hcCA9IHtNOiBcIm1cIiwgTDogXCJsXCIsIEM6IFwiY1wiLCBaOiBcInhcIiwgbTogXCJ0XCIsIGw6IFwiclwiLCBjOiBcInZcIiwgejogXCJ4XCJ9LFxuICAgICAgICBiaXRlcyA9IC8oW2NsbXpdKSw/KFteY2xtel0qKS9naSxcbiAgICAgICAgYmx1cnJlZ2V4cCA9IC8gcHJvZ2lkOlxcUytCbHVyXFwoW15cXCldK1xcKS9nLFxuICAgICAgICB2YWwgPSAvLT9bXixcXHMtXSsvZyxcbiAgICAgICAgY3NzRG90ID0gXCJwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0OjA7dG9wOjA7d2lkdGg6MXB4O2hlaWdodDoxcHg7YmVoYXZpb3I6dXJsKCNkZWZhdWx0I1ZNTClcIixcbiAgICAgICAgem9vbSA9IDIxNjAwLFxuICAgICAgICBwYXRoVHlwZXMgPSB7cGF0aDogMSwgcmVjdDogMSwgaW1hZ2U6IDF9LFxuICAgICAgICBvdmFsVHlwZXMgPSB7Y2lyY2xlOiAxLCBlbGxpcHNlOiAxfSxcbiAgICAgICAgcGF0aDJ2bWwgPSBmdW5jdGlvbiAocGF0aCkge1xuICAgICAgICAgICAgdmFyIHRvdGFsID0gIC9bYWhxc3R2XS9pZyxcbiAgICAgICAgICAgICAgICBjb21tYW5kID0gUi5fcGF0aFRvQWJzb2x1dGU7XG4gICAgICAgICAgICBTdHIocGF0aCkubWF0Y2godG90YWwpICYmIChjb21tYW5kID0gUi5fcGF0aDJjdXJ2ZSk7XG4gICAgICAgICAgICB0b3RhbCA9IC9bY2xtel0vZztcbiAgICAgICAgICAgIGlmIChjb21tYW5kID09IFIuX3BhdGhUb0Fic29sdXRlICYmICFTdHIocGF0aCkubWF0Y2godG90YWwpKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlcyA9IFN0cihwYXRoKS5yZXBsYWNlKGJpdGVzLCBmdW5jdGlvbiAoYWxsLCBjb21tYW5kLCBhcmdzKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB2YWxzID0gW10sXG4gICAgICAgICAgICAgICAgICAgICAgICBpc01vdmUgPSBjb21tYW5kLnRvTG93ZXJDYXNlKCkgPT0gXCJtXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXMgPSBtYXBbY29tbWFuZF07XG4gICAgICAgICAgICAgICAgICAgIGFyZ3MucmVwbGFjZSh2YWwsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzTW92ZSAmJiB2YWxzLmxlbmd0aCA9PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzICs9IHZhbHMgKyBtYXBbY29tbWFuZCA9PSBcIm1cIiA/IFwibFwiIDogXCJMXCJdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHMucHVzaChyb3VuZCh2YWx1ZSAqIHpvb20pKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXMgKyB2YWxzO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgcGEgPSBjb21tYW5kKHBhdGgpLCBwLCByO1xuICAgICAgICAgICAgcmVzID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBwYS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgcCA9IHBhW2ldO1xuICAgICAgICAgICAgICAgIHIgPSBwYVtpXVswXS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgICAgIHIgPT0gXCJ6XCIgJiYgKHIgPSBcInhcIik7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDEsIGpqID0gcC5sZW5ndGg7IGogPCBqajsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIHIgKz0gcm91bmQocFtqXSAqIHpvb20pICsgKGogIT0gamogLSAxID8gXCIsXCIgOiBFKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzLnB1c2gocik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzLmpvaW4oUyk7XG4gICAgICAgIH0sXG4gICAgICAgIGNvbXBlbnNhdGlvbiA9IGZ1bmN0aW9uIChkZWcsIGR4LCBkeSkge1xuICAgICAgICAgICAgdmFyIG0gPSBSLm1hdHJpeCgpO1xuICAgICAgICAgICAgbS5yb3RhdGUoLWRlZywgLjUsIC41KTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZHg6IG0ueChkeCwgZHkpLFxuICAgICAgICAgICAgICAgIGR5OiBtLnkoZHgsIGR5KVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0Q29vcmRzID0gZnVuY3Rpb24gKHAsIHN4LCBzeSwgZHgsIGR5LCBkZWcpIHtcbiAgICAgICAgICAgIHZhciBfID0gcC5fLFxuICAgICAgICAgICAgICAgIG0gPSBwLm1hdHJpeCxcbiAgICAgICAgICAgICAgICBmaWxscG9zID0gXy5maWxscG9zLFxuICAgICAgICAgICAgICAgIG8gPSBwLm5vZGUsXG4gICAgICAgICAgICAgICAgcyA9IG8uc3R5bGUsXG4gICAgICAgICAgICAgICAgeSA9IDEsXG4gICAgICAgICAgICAgICAgZmxpcCA9IFwiXCIsXG4gICAgICAgICAgICAgICAgZHhkeSxcbiAgICAgICAgICAgICAgICBreCA9IHpvb20gLyBzeCxcbiAgICAgICAgICAgICAgICBreSA9IHpvb20gLyBzeTtcbiAgICAgICAgICAgIHMudmlzaWJpbGl0eSA9IFwiaGlkZGVuXCI7XG4gICAgICAgICAgICBpZiAoIXN4IHx8ICFzeSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG8uY29vcmRzaXplID0gYWJzKGt4KSArIFMgKyBhYnMoa3kpO1xuICAgICAgICAgICAgcy5yb3RhdGlvbiA9IGRlZyAqIChzeCAqIHN5IDwgMCA/IC0xIDogMSk7XG4gICAgICAgICAgICBpZiAoZGVnKSB7XG4gICAgICAgICAgICAgICAgdmFyIGMgPSBjb21wZW5zYXRpb24oZGVnLCBkeCwgZHkpO1xuICAgICAgICAgICAgICAgIGR4ID0gYy5keDtcbiAgICAgICAgICAgICAgICBkeSA9IGMuZHk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzeCA8IDAgJiYgKGZsaXAgKz0gXCJ4XCIpO1xuICAgICAgICAgICAgc3kgPCAwICYmIChmbGlwICs9IFwiIHlcIikgJiYgKHkgPSAtMSk7XG4gICAgICAgICAgICBzLmZsaXAgPSBmbGlwO1xuICAgICAgICAgICAgby5jb29yZG9yaWdpbiA9IChkeCAqIC1reCkgKyBTICsgKGR5ICogLWt5KTtcbiAgICAgICAgICAgIGlmIChmaWxscG9zIHx8IF8uZmlsbHNpemUpIHtcbiAgICAgICAgICAgICAgICB2YXIgZmlsbCA9IG8uZ2V0RWxlbWVudHNCeVRhZ05hbWUoZmlsbFN0cmluZyk7XG4gICAgICAgICAgICAgICAgZmlsbCA9IGZpbGwgJiYgZmlsbFswXTtcbiAgICAgICAgICAgICAgICBvLnJlbW92ZUNoaWxkKGZpbGwpO1xuICAgICAgICAgICAgICAgIGlmIChmaWxscG9zKSB7XG4gICAgICAgICAgICAgICAgICAgIGMgPSBjb21wZW5zYXRpb24oZGVnLCBtLngoZmlsbHBvc1swXSwgZmlsbHBvc1sxXSksIG0ueShmaWxscG9zWzBdLCBmaWxscG9zWzFdKSk7XG4gICAgICAgICAgICAgICAgICAgIGZpbGwucG9zaXRpb24gPSBjLmR4ICogeSArIFMgKyBjLmR5ICogeTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKF8uZmlsbHNpemUpIHtcbiAgICAgICAgICAgICAgICAgICAgZmlsbC5zaXplID0gXy5maWxsc2l6ZVswXSAqIGFicyhzeCkgKyBTICsgXy5maWxsc2l6ZVsxXSAqIGFicyhzeSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG8uYXBwZW5kQ2hpbGQoZmlsbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzLnZpc2liaWxpdHkgPSBcInZpc2libGVcIjtcbiAgICAgICAgfTtcbiAgICBSLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gIFwiWW91ciBicm93c2VyIGRvZXNuXFx1MjAxOXQgc3VwcG9ydCBTVkcuIEZhbGxpbmcgZG93biB0byBWTUwuXFxuWW91IGFyZSBydW5uaW5nIFJhcGhhXFx4ZWJsIFwiICsgdGhpcy52ZXJzaW9uO1xuICAgIH07XG4gICAgdmFyIGFkZEFycm93ID0gZnVuY3Rpb24gKG8sIHZhbHVlLCBpc0VuZCkge1xuICAgICAgICB2YXIgdmFsdWVzID0gU3RyKHZhbHVlKS50b0xvd2VyQ2FzZSgpLnNwbGl0KFwiLVwiKSxcbiAgICAgICAgICAgIHNlID0gaXNFbmQgPyBcImVuZFwiIDogXCJzdGFydFwiLFxuICAgICAgICAgICAgaSA9IHZhbHVlcy5sZW5ndGgsXG4gICAgICAgICAgICB0eXBlID0gXCJjbGFzc2ljXCIsXG4gICAgICAgICAgICB3ID0gXCJtZWRpdW1cIixcbiAgICAgICAgICAgIGggPSBcIm1lZGl1bVwiO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHZhbHVlc1tpXSkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJibG9ja1wiOlxuICAgICAgICAgICAgICAgIGNhc2UgXCJjbGFzc2ljXCI6XG4gICAgICAgICAgICAgICAgY2FzZSBcIm92YWxcIjpcbiAgICAgICAgICAgICAgICBjYXNlIFwiZGlhbW9uZFwiOlxuICAgICAgICAgICAgICAgIGNhc2UgXCJvcGVuXCI6XG4gICAgICAgICAgICAgICAgY2FzZSBcIm5vbmVcIjpcbiAgICAgICAgICAgICAgICAgICAgdHlwZSA9IHZhbHVlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcIndpZGVcIjpcbiAgICAgICAgICAgICAgICBjYXNlIFwibmFycm93XCI6IGggPSB2YWx1ZXNbaV07IGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJsb25nXCI6XG4gICAgICAgICAgICAgICAgY2FzZSBcInNob3J0XCI6IHcgPSB2YWx1ZXNbaV07IGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBzdHJva2UgPSBvLm5vZGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJzdHJva2VcIilbMF07XG4gICAgICAgIHN0cm9rZVtzZSArIFwiYXJyb3dcIl0gPSB0eXBlO1xuICAgICAgICBzdHJva2Vbc2UgKyBcImFycm93bGVuZ3RoXCJdID0gdztcbiAgICAgICAgc3Ryb2tlW3NlICsgXCJhcnJvd3dpZHRoXCJdID0gaDtcbiAgICB9LFxuICAgIHNldEZpbGxBbmRTdHJva2UgPSBmdW5jdGlvbiAobywgcGFyYW1zKSB7XG4gICAgICAgIC8vIG8ucGFwZXIuY2FudmFzLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICAgICAgby5hdHRycyA9IG8uYXR0cnMgfHwge307XG4gICAgICAgIHZhciBub2RlID0gby5ub2RlLFxuICAgICAgICAgICAgYSA9IG8uYXR0cnMsXG4gICAgICAgICAgICBzID0gbm9kZS5zdHlsZSxcbiAgICAgICAgICAgIHh5LFxuICAgICAgICAgICAgbmV3cGF0aCA9IHBhdGhUeXBlc1tvLnR5cGVdICYmIChwYXJhbXMueCAhPSBhLnggfHwgcGFyYW1zLnkgIT0gYS55IHx8IHBhcmFtcy53aWR0aCAhPSBhLndpZHRoIHx8IHBhcmFtcy5oZWlnaHQgIT0gYS5oZWlnaHQgfHwgcGFyYW1zLmN4ICE9IGEuY3ggfHwgcGFyYW1zLmN5ICE9IGEuY3kgfHwgcGFyYW1zLnJ4ICE9IGEucnggfHwgcGFyYW1zLnJ5ICE9IGEucnkgfHwgcGFyYW1zLnIgIT0gYS5yKSxcbiAgICAgICAgICAgIGlzT3ZhbCA9IG92YWxUeXBlc1tvLnR5cGVdICYmIChhLmN4ICE9IHBhcmFtcy5jeCB8fCBhLmN5ICE9IHBhcmFtcy5jeSB8fCBhLnIgIT0gcGFyYW1zLnIgfHwgYS5yeCAhPSBwYXJhbXMucnggfHwgYS5yeSAhPSBwYXJhbXMucnkpLFxuICAgICAgICAgICAgcmVzID0gbztcblxuXG4gICAgICAgIGZvciAodmFyIHBhciBpbiBwYXJhbXMpIGlmIChwYXJhbXNbaGFzXShwYXIpKSB7XG4gICAgICAgICAgICBhW3Bhcl0gPSBwYXJhbXNbcGFyXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmV3cGF0aCkge1xuICAgICAgICAgICAgYS5wYXRoID0gUi5fZ2V0UGF0aFtvLnR5cGVdKG8pO1xuICAgICAgICAgICAgby5fLmRpcnR5ID0gMTtcbiAgICAgICAgfVxuICAgICAgICBwYXJhbXMuaHJlZiAmJiAobm9kZS5ocmVmID0gcGFyYW1zLmhyZWYpO1xuICAgICAgICBwYXJhbXMudGl0bGUgJiYgKG5vZGUudGl0bGUgPSBwYXJhbXMudGl0bGUpO1xuICAgICAgICBwYXJhbXMudGFyZ2V0ICYmIChub2RlLnRhcmdldCA9IHBhcmFtcy50YXJnZXQpO1xuICAgICAgICBwYXJhbXMuY3Vyc29yICYmIChzLmN1cnNvciA9IHBhcmFtcy5jdXJzb3IpO1xuICAgICAgICBcImJsdXJcIiBpbiBwYXJhbXMgJiYgby5ibHVyKHBhcmFtcy5ibHVyKTtcbiAgICAgICAgaWYgKHBhcmFtcy5wYXRoICYmIG8udHlwZSA9PSBcInBhdGhcIiB8fCBuZXdwYXRoKSB7XG4gICAgICAgICAgICBub2RlLnBhdGggPSBwYXRoMnZtbCh+U3RyKGEucGF0aCkudG9Mb3dlckNhc2UoKS5pbmRleE9mKFwiclwiKSA/IFIuX3BhdGhUb0Fic29sdXRlKGEucGF0aCkgOiBhLnBhdGgpO1xuICAgICAgICAgICAgby5fLmRpcnR5ID0gMTtcbiAgICAgICAgICAgIGlmIChvLnR5cGUgPT0gXCJpbWFnZVwiKSB7XG4gICAgICAgICAgICAgICAgby5fLmZpbGxwb3MgPSBbYS54LCBhLnldO1xuICAgICAgICAgICAgICAgIG8uXy5maWxsc2l6ZSA9IFthLndpZHRoLCBhLmhlaWdodF07XG4gICAgICAgICAgICAgICAgc2V0Q29vcmRzKG8sIDEsIDEsIDAsIDAsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIFwidHJhbnNmb3JtXCIgaW4gcGFyYW1zICYmIG8udHJhbnNmb3JtKHBhcmFtcy50cmFuc2Zvcm0pO1xuICAgICAgICBpZiAoaXNPdmFsKSB7XG4gICAgICAgICAgICB2YXIgY3ggPSArYS5jeCxcbiAgICAgICAgICAgICAgICBjeSA9ICthLmN5LFxuICAgICAgICAgICAgICAgIHJ4ID0gK2EucnggfHwgK2EuciB8fCAwLFxuICAgICAgICAgICAgICAgIHJ5ID0gK2EucnkgfHwgK2EuciB8fCAwO1xuICAgICAgICAgICAgbm9kZS5wYXRoID0gUi5mb3JtYXQoXCJhcnswfSx7MX0sezJ9LHszfSx7NH0sezF9LHs0fSx7MX14XCIsIHJvdW5kKChjeCAtIHJ4KSAqIHpvb20pLCByb3VuZCgoY3kgLSByeSkgKiB6b29tKSwgcm91bmQoKGN4ICsgcngpICogem9vbSksIHJvdW5kKChjeSArIHJ5KSAqIHpvb20pLCByb3VuZChjeCAqIHpvb20pKTtcbiAgICAgICAgICAgIG8uXy5kaXJ0eSA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFwiY2xpcC1yZWN0XCIgaW4gcGFyYW1zKSB7XG4gICAgICAgICAgICB2YXIgcmVjdCA9IFN0cihwYXJhbXNbXCJjbGlwLXJlY3RcIl0pLnNwbGl0KHNlcGFyYXRvcik7XG4gICAgICAgICAgICBpZiAocmVjdC5sZW5ndGggPT0gNCkge1xuICAgICAgICAgICAgICAgIHJlY3RbMl0gPSArcmVjdFsyXSArICgrcmVjdFswXSk7XG4gICAgICAgICAgICAgICAgcmVjdFszXSA9ICtyZWN0WzNdICsgKCtyZWN0WzFdKTtcbiAgICAgICAgICAgICAgICB2YXIgZGl2ID0gbm9kZS5jbGlwUmVjdCB8fCBSLl9nLmRvYy5jcmVhdGVFbGVtZW50KFwiZGl2XCIpLFxuICAgICAgICAgICAgICAgICAgICBkc3R5bGUgPSBkaXYuc3R5bGU7XG4gICAgICAgICAgICAgICAgZHN0eWxlLmNsaXAgPSBSLmZvcm1hdChcInJlY3QoezF9cHggezJ9cHggezN9cHggezB9cHgpXCIsIHJlY3QpO1xuICAgICAgICAgICAgICAgIGlmICghbm9kZS5jbGlwUmVjdCkge1xuICAgICAgICAgICAgICAgICAgICBkc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG4gICAgICAgICAgICAgICAgICAgIGRzdHlsZS50b3AgPSAwO1xuICAgICAgICAgICAgICAgICAgICBkc3R5bGUubGVmdCA9IDA7XG4gICAgICAgICAgICAgICAgICAgIGRzdHlsZS53aWR0aCA9IG8ucGFwZXIud2lkdGggKyBcInB4XCI7XG4gICAgICAgICAgICAgICAgICAgIGRzdHlsZS5oZWlnaHQgPSBvLnBhcGVyLmhlaWdodCArIFwicHhcIjtcbiAgICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShkaXYsIG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICBkaXYuYXBwZW5kQ2hpbGQobm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUuY2xpcFJlY3QgPSBkaXY7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFwYXJhbXNbXCJjbGlwLXJlY3RcIl0pIHtcbiAgICAgICAgICAgICAgICBub2RlLmNsaXBSZWN0ICYmIChub2RlLmNsaXBSZWN0LnN0eWxlLmNsaXAgPSBcImF1dG9cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG8udGV4dHBhdGgpIHtcbiAgICAgICAgICAgIHZhciB0ZXh0cGF0aFN0eWxlID0gby50ZXh0cGF0aC5zdHlsZTtcbiAgICAgICAgICAgIHBhcmFtcy5mb250ICYmICh0ZXh0cGF0aFN0eWxlLmZvbnQgPSBwYXJhbXMuZm9udCk7XG4gICAgICAgICAgICBwYXJhbXNbXCJmb250LWZhbWlseVwiXSAmJiAodGV4dHBhdGhTdHlsZS5mb250RmFtaWx5ID0gJ1wiJyArIHBhcmFtc1tcImZvbnQtZmFtaWx5XCJdLnNwbGl0KFwiLFwiKVswXS5yZXBsYWNlKC9eWydcIl0rfFsnXCJdKyQvZywgRSkgKyAnXCInKTtcbiAgICAgICAgICAgIHBhcmFtc1tcImZvbnQtc2l6ZVwiXSAmJiAodGV4dHBhdGhTdHlsZS5mb250U2l6ZSA9IHBhcmFtc1tcImZvbnQtc2l6ZVwiXSk7XG4gICAgICAgICAgICBwYXJhbXNbXCJmb250LXdlaWdodFwiXSAmJiAodGV4dHBhdGhTdHlsZS5mb250V2VpZ2h0ID0gcGFyYW1zW1wiZm9udC13ZWlnaHRcIl0pO1xuICAgICAgICAgICAgcGFyYW1zW1wiZm9udC1zdHlsZVwiXSAmJiAodGV4dHBhdGhTdHlsZS5mb250U3R5bGUgPSBwYXJhbXNbXCJmb250LXN0eWxlXCJdKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXCJhcnJvdy1zdGFydFwiIGluIHBhcmFtcykge1xuICAgICAgICAgICAgYWRkQXJyb3cocmVzLCBwYXJhbXNbXCJhcnJvdy1zdGFydFwiXSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFwiYXJyb3ctZW5kXCIgaW4gcGFyYW1zKSB7XG4gICAgICAgICAgICBhZGRBcnJvdyhyZXMsIHBhcmFtc1tcImFycm93LWVuZFwiXSwgMSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcmFtcy5vcGFjaXR5ICE9IG51bGwgfHxcbiAgICAgICAgICAgIHBhcmFtcy5maWxsICE9IG51bGwgfHxcbiAgICAgICAgICAgIHBhcmFtcy5zcmMgIT0gbnVsbCB8fFxuICAgICAgICAgICAgcGFyYW1zLnN0cm9rZSAhPSBudWxsIHx8XG4gICAgICAgICAgICBwYXJhbXNbXCJzdHJva2Utd2lkdGhcIl0gIT0gbnVsbCB8fFxuICAgICAgICAgICAgcGFyYW1zW1wic3Ryb2tlLW9wYWNpdHlcIl0gIT0gbnVsbCB8fFxuICAgICAgICAgICAgcGFyYW1zW1wiZmlsbC1vcGFjaXR5XCJdICE9IG51bGwgfHxcbiAgICAgICAgICAgIHBhcmFtc1tcInN0cm9rZS1kYXNoYXJyYXlcIl0gIT0gbnVsbCB8fFxuICAgICAgICAgICAgcGFyYW1zW1wic3Ryb2tlLW1pdGVybGltaXRcIl0gIT0gbnVsbCB8fFxuICAgICAgICAgICAgcGFyYW1zW1wic3Ryb2tlLWxpbmVqb2luXCJdICE9IG51bGwgfHxcbiAgICAgICAgICAgIHBhcmFtc1tcInN0cm9rZS1saW5lY2FwXCJdICE9IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBmaWxsID0gbm9kZS5nZXRFbGVtZW50c0J5VGFnTmFtZShmaWxsU3RyaW5nKSxcbiAgICAgICAgICAgICAgICBuZXdmaWxsID0gZmFsc2U7XG4gICAgICAgICAgICBmaWxsID0gZmlsbCAmJiBmaWxsWzBdO1xuICAgICAgICAgICAgIWZpbGwgJiYgKG5ld2ZpbGwgPSBmaWxsID0gY3JlYXRlTm9kZShmaWxsU3RyaW5nKSk7XG4gICAgICAgICAgICBpZiAoby50eXBlID09IFwiaW1hZ2VcIiAmJiBwYXJhbXMuc3JjKSB7XG4gICAgICAgICAgICAgICAgZmlsbC5zcmMgPSBwYXJhbXMuc3JjO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcGFyYW1zLmZpbGwgJiYgKGZpbGwub24gPSB0cnVlKTtcbiAgICAgICAgICAgIGlmIChmaWxsLm9uID09IG51bGwgfHwgcGFyYW1zLmZpbGwgPT0gXCJub25lXCIgfHwgcGFyYW1zLmZpbGwgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBmaWxsLm9uID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZmlsbC5vbiAmJiBwYXJhbXMuZmlsbCkge1xuICAgICAgICAgICAgICAgIHZhciBpc1VSTCA9IFN0cihwYXJhbXMuZmlsbCkubWF0Y2goUi5fSVNVUkwpO1xuICAgICAgICAgICAgICAgIGlmIChpc1VSTCkge1xuICAgICAgICAgICAgICAgICAgICBmaWxsLnBhcmVudE5vZGUgPT0gbm9kZSAmJiBub2RlLnJlbW92ZUNoaWxkKGZpbGwpO1xuICAgICAgICAgICAgICAgICAgICBmaWxsLnJvdGF0ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGZpbGwuc3JjID0gaXNVUkxbMV07XG4gICAgICAgICAgICAgICAgICAgIGZpbGwudHlwZSA9IFwidGlsZVwiO1xuICAgICAgICAgICAgICAgICAgICB2YXIgYmJveCA9IG8uZ2V0QkJveCgxKTtcbiAgICAgICAgICAgICAgICAgICAgZmlsbC5wb3NpdGlvbiA9IGJib3gueCArIFMgKyBiYm94Lnk7XG4gICAgICAgICAgICAgICAgICAgIG8uXy5maWxscG9zID0gW2Jib3gueCwgYmJveC55XTtcblxuICAgICAgICAgICAgICAgICAgICBSLl9wcmVsb2FkKGlzVVJMWzFdLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvLl8uZmlsbHNpemUgPSBbdGhpcy5vZmZzZXRXaWR0aCwgdGhpcy5vZmZzZXRIZWlnaHRdO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmaWxsLmNvbG9yID0gUi5nZXRSR0IocGFyYW1zLmZpbGwpLmhleDtcbiAgICAgICAgICAgICAgICAgICAgZmlsbC5zcmMgPSBFO1xuICAgICAgICAgICAgICAgICAgICBmaWxsLnR5cGUgPSBcInNvbGlkXCI7XG4gICAgICAgICAgICAgICAgICAgIGlmIChSLmdldFJHQihwYXJhbXMuZmlsbCkuZXJyb3IgJiYgKHJlcy50eXBlIGluIHtjaXJjbGU6IDEsIGVsbGlwc2U6IDF9IHx8IFN0cihwYXJhbXMuZmlsbCkuY2hhckF0KCkgIT0gXCJyXCIpICYmIGFkZEdyYWRpZW50RmlsbChyZXMsIHBhcmFtcy5maWxsLCBmaWxsKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYS5maWxsID0gXCJub25lXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICBhLmdyYWRpZW50ID0gcGFyYW1zLmZpbGw7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaWxsLnJvdGF0ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKFwiZmlsbC1vcGFjaXR5XCIgaW4gcGFyYW1zIHx8IFwib3BhY2l0eVwiIGluIHBhcmFtcykge1xuICAgICAgICAgICAgICAgIHZhciBvcGFjaXR5ID0gKCgrYVtcImZpbGwtb3BhY2l0eVwiXSArIDEgfHwgMikgLSAxKSAqICgoK2Eub3BhY2l0eSArIDEgfHwgMikgLSAxKSAqICgoK1IuZ2V0UkdCKHBhcmFtcy5maWxsKS5vICsgMSB8fCAyKSAtIDEpO1xuICAgICAgICAgICAgICAgIG9wYWNpdHkgPSBtbWluKG1tYXgob3BhY2l0eSwgMCksIDEpO1xuICAgICAgICAgICAgICAgIGZpbGwub3BhY2l0eSA9IG9wYWNpdHk7XG4gICAgICAgICAgICAgICAgaWYgKGZpbGwuc3JjKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpbGwuY29sb3IgPSBcIm5vbmVcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBub2RlLmFwcGVuZENoaWxkKGZpbGwpO1xuICAgICAgICAgICAgdmFyIHN0cm9rZSA9IChub2RlLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwic3Ryb2tlXCIpICYmIG5vZGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJzdHJva2VcIilbMF0pLFxuICAgICAgICAgICAgbmV3c3Ryb2tlID0gZmFsc2U7XG4gICAgICAgICAgICAhc3Ryb2tlICYmIChuZXdzdHJva2UgPSBzdHJva2UgPSBjcmVhdGVOb2RlKFwic3Ryb2tlXCIpKTtcbiAgICAgICAgICAgIGlmICgocGFyYW1zLnN0cm9rZSAmJiBwYXJhbXMuc3Ryb2tlICE9IFwibm9uZVwiKSB8fFxuICAgICAgICAgICAgICAgIHBhcmFtc1tcInN0cm9rZS13aWR0aFwiXSB8fFxuICAgICAgICAgICAgICAgIHBhcmFtc1tcInN0cm9rZS1vcGFjaXR5XCJdICE9IG51bGwgfHxcbiAgICAgICAgICAgICAgICBwYXJhbXNbXCJzdHJva2UtZGFzaGFycmF5XCJdIHx8XG4gICAgICAgICAgICAgICAgcGFyYW1zW1wic3Ryb2tlLW1pdGVybGltaXRcIl0gfHxcbiAgICAgICAgICAgICAgICBwYXJhbXNbXCJzdHJva2UtbGluZWpvaW5cIl0gfHxcbiAgICAgICAgICAgICAgICBwYXJhbXNbXCJzdHJva2UtbGluZWNhcFwiXSkge1xuICAgICAgICAgICAgICAgIHN0cm9rZS5vbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAocGFyYW1zLnN0cm9rZSA9PSBcIm5vbmVcIiB8fCBwYXJhbXMuc3Ryb2tlID09PSBudWxsIHx8IHN0cm9rZS5vbiA9PSBudWxsIHx8IHBhcmFtcy5zdHJva2UgPT0gMCB8fCBwYXJhbXNbXCJzdHJva2Utd2lkdGhcIl0gPT0gMCkgJiYgKHN0cm9rZS5vbiA9IGZhbHNlKTtcbiAgICAgICAgICAgIHZhciBzdHJva2VDb2xvciA9IFIuZ2V0UkdCKHBhcmFtcy5zdHJva2UpO1xuICAgICAgICAgICAgc3Ryb2tlLm9uICYmIHBhcmFtcy5zdHJva2UgJiYgKHN0cm9rZS5jb2xvciA9IHN0cm9rZUNvbG9yLmhleCk7XG4gICAgICAgICAgICBvcGFjaXR5ID0gKCgrYVtcInN0cm9rZS1vcGFjaXR5XCJdICsgMSB8fCAyKSAtIDEpICogKCgrYS5vcGFjaXR5ICsgMSB8fCAyKSAtIDEpICogKCgrc3Ryb2tlQ29sb3IubyArIDEgfHwgMikgLSAxKTtcbiAgICAgICAgICAgIHZhciB3aWR0aCA9ICh0b0Zsb2F0KHBhcmFtc1tcInN0cm9rZS13aWR0aFwiXSkgfHwgMSkgKiAuNzU7XG4gICAgICAgICAgICBvcGFjaXR5ID0gbW1pbihtbWF4KG9wYWNpdHksIDApLCAxKTtcbiAgICAgICAgICAgIHBhcmFtc1tcInN0cm9rZS13aWR0aFwiXSA9PSBudWxsICYmICh3aWR0aCA9IGFbXCJzdHJva2Utd2lkdGhcIl0pO1xuICAgICAgICAgICAgcGFyYW1zW1wic3Ryb2tlLXdpZHRoXCJdICYmIChzdHJva2Uud2VpZ2h0ID0gd2lkdGgpO1xuICAgICAgICAgICAgd2lkdGggJiYgd2lkdGggPCAxICYmIChvcGFjaXR5ICo9IHdpZHRoKSAmJiAoc3Ryb2tlLndlaWdodCA9IDEpO1xuICAgICAgICAgICAgc3Ryb2tlLm9wYWNpdHkgPSBvcGFjaXR5O1xuXG4gICAgICAgICAgICBwYXJhbXNbXCJzdHJva2UtbGluZWpvaW5cIl0gJiYgKHN0cm9rZS5qb2luc3R5bGUgPSBwYXJhbXNbXCJzdHJva2UtbGluZWpvaW5cIl0gfHwgXCJtaXRlclwiKTtcbiAgICAgICAgICAgIHN0cm9rZS5taXRlcmxpbWl0ID0gcGFyYW1zW1wic3Ryb2tlLW1pdGVybGltaXRcIl0gfHwgODtcbiAgICAgICAgICAgIHBhcmFtc1tcInN0cm9rZS1saW5lY2FwXCJdICYmIChzdHJva2UuZW5kY2FwID0gcGFyYW1zW1wic3Ryb2tlLWxpbmVjYXBcIl0gPT0gXCJidXR0XCIgPyBcImZsYXRcIiA6IHBhcmFtc1tcInN0cm9rZS1saW5lY2FwXCJdID09IFwic3F1YXJlXCIgPyBcInNxdWFyZVwiIDogXCJyb3VuZFwiKTtcbiAgICAgICAgICAgIGlmIChcInN0cm9rZS1kYXNoYXJyYXlcIiBpbiBwYXJhbXMpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGFzaGFycmF5ID0ge1xuICAgICAgICAgICAgICAgICAgICBcIi1cIjogXCJzaG9ydGRhc2hcIixcbiAgICAgICAgICAgICAgICAgICAgXCIuXCI6IFwic2hvcnRkb3RcIixcbiAgICAgICAgICAgICAgICAgICAgXCItLlwiOiBcInNob3J0ZGFzaGRvdFwiLFxuICAgICAgICAgICAgICAgICAgICBcIi0uLlwiOiBcInNob3J0ZGFzaGRvdGRvdFwiLFxuICAgICAgICAgICAgICAgICAgICBcIi4gXCI6IFwiZG90XCIsXG4gICAgICAgICAgICAgICAgICAgIFwiLSBcIjogXCJkYXNoXCIsXG4gICAgICAgICAgICAgICAgICAgIFwiLS1cIjogXCJsb25nZGFzaFwiLFxuICAgICAgICAgICAgICAgICAgICBcIi0gLlwiOiBcImRhc2hkb3RcIixcbiAgICAgICAgICAgICAgICAgICAgXCItLS5cIjogXCJsb25nZGFzaGRvdFwiLFxuICAgICAgICAgICAgICAgICAgICBcIi0tLi5cIjogXCJsb25nZGFzaGRvdGRvdFwiXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBzdHJva2UuZGFzaHN0eWxlID0gZGFzaGFycmF5W2hhc10ocGFyYW1zW1wic3Ryb2tlLWRhc2hhcnJheVwiXSkgPyBkYXNoYXJyYXlbcGFyYW1zW1wic3Ryb2tlLWRhc2hhcnJheVwiXV0gOiBFO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbmV3c3Ryb2tlICYmIG5vZGUuYXBwZW5kQ2hpbGQoc3Ryb2tlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzLnR5cGUgPT0gXCJ0ZXh0XCIpIHtcbiAgICAgICAgICAgIHJlcy5wYXBlci5jYW52YXMuc3R5bGUuZGlzcGxheSA9IEU7XG4gICAgICAgICAgICB2YXIgc3BhbiA9IHJlcy5wYXBlci5zcGFuLFxuICAgICAgICAgICAgICAgIG0gPSAxMDAsXG4gICAgICAgICAgICAgICAgZm9udFNpemUgPSBhLmZvbnQgJiYgYS5mb250Lm1hdGNoKC9cXGQrKD86XFwuXFxkKik/KD89cHgpLyk7XG4gICAgICAgICAgICBzID0gc3Bhbi5zdHlsZTtcbiAgICAgICAgICAgIGEuZm9udCAmJiAocy5mb250ID0gYS5mb250KTtcbiAgICAgICAgICAgIGFbXCJmb250LWZhbWlseVwiXSAmJiAocy5mb250RmFtaWx5ID0gYVtcImZvbnQtZmFtaWx5XCJdKTtcbiAgICAgICAgICAgIGFbXCJmb250LXdlaWdodFwiXSAmJiAocy5mb250V2VpZ2h0ID0gYVtcImZvbnQtd2VpZ2h0XCJdKTtcbiAgICAgICAgICAgIGFbXCJmb250LXN0eWxlXCJdICYmIChzLmZvbnRTdHlsZSA9IGFbXCJmb250LXN0eWxlXCJdKTtcbiAgICAgICAgICAgIGZvbnRTaXplID0gdG9GbG9hdChhW1wiZm9udC1zaXplXCJdIHx8IGZvbnRTaXplICYmIGZvbnRTaXplWzBdKSB8fCAxMDtcbiAgICAgICAgICAgIHMuZm9udFNpemUgPSBmb250U2l6ZSAqIG0gKyBcInB4XCI7XG4gICAgICAgICAgICByZXMudGV4dHBhdGguc3RyaW5nICYmIChzcGFuLmlubmVySFRNTCA9IFN0cihyZXMudGV4dHBhdGguc3RyaW5nKS5yZXBsYWNlKC88L2csIFwiJiM2MDtcIikucmVwbGFjZSgvJi9nLCBcIiYjMzg7XCIpLnJlcGxhY2UoL1xcbi9nLCBcIjxicj5cIikpO1xuICAgICAgICAgICAgdmFyIGJyZWN0ID0gc3Bhbi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgICAgIHJlcy5XID0gYS53ID0gKGJyZWN0LnJpZ2h0IC0gYnJlY3QubGVmdCkgLyBtO1xuICAgICAgICAgICAgcmVzLkggPSBhLmggPSAoYnJlY3QuYm90dG9tIC0gYnJlY3QudG9wKSAvIG07XG4gICAgICAgICAgICAvLyByZXMucGFwZXIuY2FudmFzLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICAgICAgICAgIHJlcy5YID0gYS54O1xuICAgICAgICAgICAgcmVzLlkgPSBhLnkgKyByZXMuSCAvIDI7XG5cbiAgICAgICAgICAgIChcInhcIiBpbiBwYXJhbXMgfHwgXCJ5XCIgaW4gcGFyYW1zKSAmJiAocmVzLnBhdGgudiA9IFIuZm9ybWF0KFwibXswfSx7MX1sezJ9LHsxfVwiLCByb3VuZChhLnggKiB6b29tKSwgcm91bmQoYS55ICogem9vbSksIHJvdW5kKGEueCAqIHpvb20pICsgMSkpO1xuICAgICAgICAgICAgdmFyIGRpcnR5YXR0cnMgPSBbXCJ4XCIsIFwieVwiLCBcInRleHRcIiwgXCJmb250XCIsIFwiZm9udC1mYW1pbHlcIiwgXCJmb250LXdlaWdodFwiLCBcImZvbnQtc3R5bGVcIiwgXCJmb250LXNpemVcIl07XG4gICAgICAgICAgICBmb3IgKHZhciBkID0gMCwgZGQgPSBkaXJ0eWF0dHJzLmxlbmd0aDsgZCA8IGRkOyBkKyspIGlmIChkaXJ0eWF0dHJzW2RdIGluIHBhcmFtcykge1xuICAgICAgICAgICAgICAgIHJlcy5fLmRpcnR5ID0gMTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdGV4dC1hbmNob3IgZW11bGF0aW9uXG4gICAgICAgICAgICBzd2l0Y2ggKGFbXCJ0ZXh0LWFuY2hvclwiXSkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzdGFydFwiOlxuICAgICAgICAgICAgICAgICAgICByZXMudGV4dHBhdGguc3R5bGVbXCJ2LXRleHQtYWxpZ25cIl0gPSBcImxlZnRcIjtcbiAgICAgICAgICAgICAgICAgICAgcmVzLmJieCA9IHJlcy5XIC8gMjtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgICAgIHJlcy50ZXh0cGF0aC5zdHlsZVtcInYtdGV4dC1hbGlnblwiXSA9IFwicmlnaHRcIjtcbiAgICAgICAgICAgICAgICAgICAgcmVzLmJieCA9IC1yZXMuVyAvIDI7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmVzLnRleHRwYXRoLnN0eWxlW1widi10ZXh0LWFsaWduXCJdID0gXCJjZW50ZXJcIjtcbiAgICAgICAgICAgICAgICAgICAgcmVzLmJieCA9IDA7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXMudGV4dHBhdGguc3R5bGVbXCJ2LXRleHQta2VyblwiXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVzLnBhcGVyLmNhbnZhcy5zdHlsZS5kaXNwbGF5ID0gRTtcbiAgICB9LFxuICAgIGFkZEdyYWRpZW50RmlsbCA9IGZ1bmN0aW9uIChvLCBncmFkaWVudCwgZmlsbCkge1xuICAgICAgICBvLmF0dHJzID0gby5hdHRycyB8fCB7fTtcbiAgICAgICAgdmFyIGF0dHJzID0gby5hdHRycyxcbiAgICAgICAgICAgIHBvdyA9IE1hdGgucG93LFxuICAgICAgICAgICAgb3BhY2l0eSxcbiAgICAgICAgICAgIG9pbmRleCxcbiAgICAgICAgICAgIHR5cGUgPSBcImxpbmVhclwiLFxuICAgICAgICAgICAgZnhmeSA9IFwiLjUgLjVcIjtcbiAgICAgICAgby5hdHRycy5ncmFkaWVudCA9IGdyYWRpZW50O1xuICAgICAgICBncmFkaWVudCA9IFN0cihncmFkaWVudCkucmVwbGFjZShSLl9yYWRpYWxfZ3JhZGllbnQsIGZ1bmN0aW9uIChhbGwsIGZ4LCBmeSkge1xuICAgICAgICAgICAgdHlwZSA9IFwicmFkaWFsXCI7XG4gICAgICAgICAgICBpZiAoZnggJiYgZnkpIHtcbiAgICAgICAgICAgICAgICBmeCA9IHRvRmxvYXQoZngpO1xuICAgICAgICAgICAgICAgIGZ5ID0gdG9GbG9hdChmeSk7XG4gICAgICAgICAgICAgICAgcG93KGZ4IC0gLjUsIDIpICsgcG93KGZ5IC0gLjUsIDIpID4gLjI1ICYmIChmeSA9IG1hdGguc3FydCguMjUgLSBwb3coZnggLSAuNSwgMikpICogKChmeSA+IC41KSAqIDIgLSAxKSArIC41KTtcbiAgICAgICAgICAgICAgICBmeGZ5ID0gZnggKyBTICsgZnk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gRTtcbiAgICAgICAgfSk7XG4gICAgICAgIGdyYWRpZW50ID0gZ3JhZGllbnQuc3BsaXQoL1xccypcXC1cXHMqLyk7XG4gICAgICAgIGlmICh0eXBlID09IFwibGluZWFyXCIpIHtcbiAgICAgICAgICAgIHZhciBhbmdsZSA9IGdyYWRpZW50LnNoaWZ0KCk7XG4gICAgICAgICAgICBhbmdsZSA9IC10b0Zsb2F0KGFuZ2xlKTtcbiAgICAgICAgICAgIGlmIChpc05hTihhbmdsZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgZG90cyA9IFIuX3BhcnNlRG90cyhncmFkaWVudCk7XG4gICAgICAgIGlmICghZG90cykge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgbyA9IG8uc2hhcGUgfHwgby5ub2RlO1xuICAgICAgICBpZiAoZG90cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIG8ucmVtb3ZlQ2hpbGQoZmlsbCk7XG4gICAgICAgICAgICBmaWxsLm9uID0gdHJ1ZTtcbiAgICAgICAgICAgIGZpbGwubWV0aG9kID0gXCJub25lXCI7XG4gICAgICAgICAgICBmaWxsLmNvbG9yID0gZG90c1swXS5jb2xvcjtcbiAgICAgICAgICAgIGZpbGwuY29sb3IyID0gZG90c1tkb3RzLmxlbmd0aCAtIDFdLmNvbG9yO1xuICAgICAgICAgICAgdmFyIGNscnMgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGRvdHMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgIGRvdHNbaV0ub2Zmc2V0ICYmIGNscnMucHVzaChkb3RzW2ldLm9mZnNldCArIFMgKyBkb3RzW2ldLmNvbG9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbGwuY29sb3JzID0gY2xycy5sZW5ndGggPyBjbHJzLmpvaW4oKSA6IFwiMCUgXCIgKyBmaWxsLmNvbG9yO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT0gXCJyYWRpYWxcIikge1xuICAgICAgICAgICAgICAgIGZpbGwudHlwZSA9IFwiZ3JhZGllbnRUaXRsZVwiO1xuICAgICAgICAgICAgICAgIGZpbGwuZm9jdXMgPSBcIjEwMCVcIjtcbiAgICAgICAgICAgICAgICBmaWxsLmZvY3Vzc2l6ZSA9IFwiMCAwXCI7XG4gICAgICAgICAgICAgICAgZmlsbC5mb2N1c3Bvc2l0aW9uID0gZnhmeTtcbiAgICAgICAgICAgICAgICBmaWxsLmFuZ2xlID0gMDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gZmlsbC5yb3RhdGU9IHRydWU7XG4gICAgICAgICAgICAgICAgZmlsbC50eXBlID0gXCJncmFkaWVudFwiO1xuICAgICAgICAgICAgICAgIGZpbGwuYW5nbGUgPSAoMjcwIC0gYW5nbGUpICUgMzYwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgby5hcHBlbmRDaGlsZChmaWxsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gMTtcbiAgICB9LFxuICAgIEVsZW1lbnQgPSBmdW5jdGlvbiAobm9kZSwgdm1sKSB7XG4gICAgICAgIHRoaXNbMF0gPSB0aGlzLm5vZGUgPSBub2RlO1xuICAgICAgICBub2RlLnJhcGhhZWwgPSB0cnVlO1xuICAgICAgICB0aGlzLmlkID0gUi5fb2lkKys7XG4gICAgICAgIG5vZGUucmFwaGFlbGlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy5YID0gMDtcbiAgICAgICAgdGhpcy5ZID0gMDtcbiAgICAgICAgdGhpcy5hdHRycyA9IHt9O1xuICAgICAgICB0aGlzLnBhcGVyID0gdm1sO1xuICAgICAgICB0aGlzLm1hdHJpeCA9IFIubWF0cml4KCk7XG4gICAgICAgIHRoaXMuXyA9IHtcbiAgICAgICAgICAgIHRyYW5zZm9ybTogW10sXG4gICAgICAgICAgICBzeDogMSxcbiAgICAgICAgICAgIHN5OiAxLFxuICAgICAgICAgICAgZHg6IDAsXG4gICAgICAgICAgICBkeTogMCxcbiAgICAgICAgICAgIGRlZzogMCxcbiAgICAgICAgICAgIGRpcnR5OiAxLFxuICAgICAgICAgICAgZGlydHlUOiAxXG4gICAgICAgIH07XG4gICAgICAgICF2bWwuYm90dG9tICYmICh2bWwuYm90dG9tID0gdGhpcyk7XG4gICAgICAgIHRoaXMucHJldiA9IHZtbC50b3A7XG4gICAgICAgIHZtbC50b3AgJiYgKHZtbC50b3AubmV4dCA9IHRoaXMpO1xuICAgICAgICB2bWwudG9wID0gdGhpcztcbiAgICAgICAgdGhpcy5uZXh0ID0gbnVsbDtcbiAgICB9O1xuICAgIHZhciBlbHByb3RvID0gUi5lbDtcblxuICAgIEVsZW1lbnQucHJvdG90eXBlID0gZWxwcm90bztcbiAgICBlbHByb3RvLmNvbnN0cnVjdG9yID0gRWxlbWVudDtcbiAgICBlbHByb3RvLnRyYW5zZm9ybSA9IGZ1bmN0aW9uICh0c3RyKSB7XG4gICAgICAgIGlmICh0c3RyID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl8udHJhbnNmb3JtO1xuICAgICAgICB9XG4gICAgICAgIHZhciB2YnMgPSB0aGlzLnBhcGVyLl92aWV3Qm94U2hpZnQsXG4gICAgICAgICAgICB2YnQgPSB2YnMgPyBcInNcIiArIFt2YnMuc2NhbGUsIHZicy5zY2FsZV0gKyBcIi0xLTF0XCIgKyBbdmJzLmR4LCB2YnMuZHldIDogRSxcbiAgICAgICAgICAgIG9sZHQ7XG4gICAgICAgIGlmICh2YnMpIHtcbiAgICAgICAgICAgIG9sZHQgPSB0c3RyID0gU3RyKHRzdHIpLnJlcGxhY2UoL1xcLnszfXxcXHUyMDI2L2csIHRoaXMuXy50cmFuc2Zvcm0gfHwgRSk7XG4gICAgICAgIH1cbiAgICAgICAgUi5fZXh0cmFjdFRyYW5zZm9ybSh0aGlzLCB2YnQgKyB0c3RyKTtcbiAgICAgICAgdmFyIG1hdHJpeCA9IHRoaXMubWF0cml4LmNsb25lKCksXG4gICAgICAgICAgICBza2V3ID0gdGhpcy5za2V3LFxuICAgICAgICAgICAgbyA9IHRoaXMubm9kZSxcbiAgICAgICAgICAgIHNwbGl0LFxuICAgICAgICAgICAgaXNHcmFkID0gflN0cih0aGlzLmF0dHJzLmZpbGwpLmluZGV4T2YoXCItXCIpLFxuICAgICAgICAgICAgaXNQYXR0ID0gIVN0cih0aGlzLmF0dHJzLmZpbGwpLmluZGV4T2YoXCJ1cmwoXCIpO1xuICAgICAgICBtYXRyaXgudHJhbnNsYXRlKDEsIDEpO1xuICAgICAgICBpZiAoaXNQYXR0IHx8IGlzR3JhZCB8fCB0aGlzLnR5cGUgPT0gXCJpbWFnZVwiKSB7XG4gICAgICAgICAgICBza2V3Lm1hdHJpeCA9IFwiMSAwIDAgMVwiO1xuICAgICAgICAgICAgc2tldy5vZmZzZXQgPSBcIjAgMFwiO1xuICAgICAgICAgICAgc3BsaXQgPSBtYXRyaXguc3BsaXQoKTtcbiAgICAgICAgICAgIGlmICgoaXNHcmFkICYmIHNwbGl0Lm5vUm90YXRpb24pIHx8ICFzcGxpdC5pc1NpbXBsZSkge1xuICAgICAgICAgICAgICAgIG8uc3R5bGUuZmlsdGVyID0gbWF0cml4LnRvRmlsdGVyKCk7XG4gICAgICAgICAgICAgICAgdmFyIGJiID0gdGhpcy5nZXRCQm94KCksXG4gICAgICAgICAgICAgICAgICAgIGJidCA9IHRoaXMuZ2V0QkJveCgxKSxcbiAgICAgICAgICAgICAgICAgICAgZHggPSBiYi54IC0gYmJ0LngsXG4gICAgICAgICAgICAgICAgICAgIGR5ID0gYmIueSAtIGJidC55O1xuICAgICAgICAgICAgICAgIG8uY29vcmRvcmlnaW4gPSAoZHggKiAtem9vbSkgKyBTICsgKGR5ICogLXpvb20pO1xuICAgICAgICAgICAgICAgIHNldENvb3Jkcyh0aGlzLCAxLCAxLCBkeCwgZHksIDApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBvLnN0eWxlLmZpbHRlciA9IEU7XG4gICAgICAgICAgICAgICAgc2V0Q29vcmRzKHRoaXMsIHNwbGl0LnNjYWxleCwgc3BsaXQuc2NhbGV5LCBzcGxpdC5keCwgc3BsaXQuZHksIHNwbGl0LnJvdGF0ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBvLnN0eWxlLmZpbHRlciA9IEU7XG4gICAgICAgICAgICBza2V3Lm1hdHJpeCA9IFN0cihtYXRyaXgpO1xuICAgICAgICAgICAgc2tldy5vZmZzZXQgPSBtYXRyaXgub2Zmc2V0KCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9sZHQgIT09IG51bGwpIHsgLy8gZW1wdHkgc3RyaW5nIHZhbHVlIGlzIHRydWUgYXMgd2VsbFxuICAgICAgICAgICAgdGhpcy5fLnRyYW5zZm9ybSA9IG9sZHQ7XG4gICAgICAgICAgICBSLl9leHRyYWN0VHJhbnNmb3JtKHRoaXMsIG9sZHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgZWxwcm90by5yb3RhdGUgPSBmdW5jdGlvbiAoZGVnLCBjeCwgY3kpIHtcbiAgICAgICAgaWYgKHRoaXMucmVtb3ZlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlZyA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgZGVnID0gU3RyKGRlZykuc3BsaXQoc2VwYXJhdG9yKTtcbiAgICAgICAgaWYgKGRlZy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICBjeCA9IHRvRmxvYXQoZGVnWzFdKTtcbiAgICAgICAgICAgIGN5ID0gdG9GbG9hdChkZWdbMl0pO1xuICAgICAgICB9XG4gICAgICAgIGRlZyA9IHRvRmxvYXQoZGVnWzBdKTtcbiAgICAgICAgKGN5ID09IG51bGwpICYmIChjeCA9IGN5KTtcbiAgICAgICAgaWYgKGN4ID09IG51bGwgfHwgY3kgPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGJib3ggPSB0aGlzLmdldEJCb3goMSk7XG4gICAgICAgICAgICBjeCA9IGJib3gueCArIGJib3gud2lkdGggLyAyO1xuICAgICAgICAgICAgY3kgPSBiYm94LnkgKyBiYm94LmhlaWdodCAvIDI7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fLmRpcnR5VCA9IDE7XG4gICAgICAgIHRoaXMudHJhbnNmb3JtKHRoaXMuXy50cmFuc2Zvcm0uY29uY2F0KFtbXCJyXCIsIGRlZywgY3gsIGN5XV0pKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBlbHByb3RvLnRyYW5zbGF0ZSA9IGZ1bmN0aW9uIChkeCwgZHkpIHtcbiAgICAgICAgaWYgKHRoaXMucmVtb3ZlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgZHggPSBTdHIoZHgpLnNwbGl0KHNlcGFyYXRvcik7XG4gICAgICAgIGlmIChkeC5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICBkeSA9IHRvRmxvYXQoZHhbMV0pO1xuICAgICAgICB9XG4gICAgICAgIGR4ID0gdG9GbG9hdChkeFswXSkgfHwgMDtcbiAgICAgICAgZHkgPSArZHkgfHwgMDtcbiAgICAgICAgaWYgKHRoaXMuXy5iYm94KSB7XG4gICAgICAgICAgICB0aGlzLl8uYmJveC54ICs9IGR4O1xuICAgICAgICAgICAgdGhpcy5fLmJib3gueSArPSBkeTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRyYW5zZm9ybSh0aGlzLl8udHJhbnNmb3JtLmNvbmNhdChbW1widFwiLCBkeCwgZHldXSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIGVscHJvdG8uc2NhbGUgPSBmdW5jdGlvbiAoc3gsIHN5LCBjeCwgY3kpIHtcbiAgICAgICAgaWYgKHRoaXMucmVtb3ZlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgc3ggPSBTdHIoc3gpLnNwbGl0KHNlcGFyYXRvcik7XG4gICAgICAgIGlmIChzeC5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICBzeSA9IHRvRmxvYXQoc3hbMV0pO1xuICAgICAgICAgICAgY3ggPSB0b0Zsb2F0KHN4WzJdKTtcbiAgICAgICAgICAgIGN5ID0gdG9GbG9hdChzeFszXSk7XG4gICAgICAgICAgICBpc05hTihjeCkgJiYgKGN4ID0gbnVsbCk7XG4gICAgICAgICAgICBpc05hTihjeSkgJiYgKGN5ID0gbnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgc3ggPSB0b0Zsb2F0KHN4WzBdKTtcbiAgICAgICAgKHN5ID09IG51bGwpICYmIChzeSA9IHN4KTtcbiAgICAgICAgKGN5ID09IG51bGwpICYmIChjeCA9IGN5KTtcbiAgICAgICAgaWYgKGN4ID09IG51bGwgfHwgY3kgPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGJib3ggPSB0aGlzLmdldEJCb3goMSk7XG4gICAgICAgIH1cbiAgICAgICAgY3ggPSBjeCA9PSBudWxsID8gYmJveC54ICsgYmJveC53aWR0aCAvIDIgOiBjeDtcbiAgICAgICAgY3kgPSBjeSA9PSBudWxsID8gYmJveC55ICsgYmJveC5oZWlnaHQgLyAyIDogY3k7XG5cbiAgICAgICAgdGhpcy50cmFuc2Zvcm0odGhpcy5fLnRyYW5zZm9ybS5jb25jYXQoW1tcInNcIiwgc3gsIHN5LCBjeCwgY3ldXSkpO1xuICAgICAgICB0aGlzLl8uZGlydHlUID0gMTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBlbHByb3RvLmhpZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICF0aGlzLnJlbW92ZWQgJiYgKHRoaXMubm9kZS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIGVscHJvdG8uc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgIXRoaXMucmVtb3ZlZCAmJiAodGhpcy5ub2RlLnN0eWxlLmRpc3BsYXkgPSBFKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICAvLyBOZWVkZWQgdG8gZml4IHRoZSB2bWwgc2V0Vmlld0JveCBpc3N1ZXNcbiAgICBlbHByb3RvLmF1eEdldEJCb3ggPSBSLmVsLmdldEJCb3g7XG4gICAgZWxwcm90by5nZXRCQm94ID0gZnVuY3Rpb24oKXtcbiAgICAgIHZhciBiID0gdGhpcy5hdXhHZXRCQm94KCk7XG4gICAgICBpZiAodGhpcy5wYXBlciAmJiB0aGlzLnBhcGVyLl92aWV3Qm94U2hpZnQpXG4gICAgICB7XG4gICAgICAgIHZhciBjID0ge307XG4gICAgICAgIHZhciB6ID0gMS90aGlzLnBhcGVyLl92aWV3Qm94U2hpZnQuc2NhbGU7XG4gICAgICAgIGMueCA9IGIueCAtIHRoaXMucGFwZXIuX3ZpZXdCb3hTaGlmdC5keDtcbiAgICAgICAgYy54ICo9IHo7XG4gICAgICAgIGMueSA9IGIueSAtIHRoaXMucGFwZXIuX3ZpZXdCb3hTaGlmdC5keTtcbiAgICAgICAgYy55ICo9IHo7XG4gICAgICAgIGMud2lkdGggID0gYi53aWR0aCAgKiB6O1xuICAgICAgICBjLmhlaWdodCA9IGIuaGVpZ2h0ICogejtcbiAgICAgICAgYy54MiA9IGMueCArIGMud2lkdGg7XG4gICAgICAgIGMueTIgPSBjLnkgKyBjLmhlaWdodDtcbiAgICAgICAgcmV0dXJuIGM7XG4gICAgICB9XG4gICAgICByZXR1cm4gYjtcbiAgICB9O1xuICAgIGVscHJvdG8uX2dldEJCb3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnJlbW92ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeDogdGhpcy5YICsgKHRoaXMuYmJ4IHx8IDApIC0gdGhpcy5XIC8gMixcbiAgICAgICAgICAgIHk6IHRoaXMuWSAtIHRoaXMuSCxcbiAgICAgICAgICAgIHdpZHRoOiB0aGlzLlcsXG4gICAgICAgICAgICBoZWlnaHQ6IHRoaXMuSFxuICAgICAgICB9O1xuICAgIH07XG4gICAgZWxwcm90by5yZW1vdmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnJlbW92ZWQgfHwgIXRoaXMubm9kZS5wYXJlbnROb2RlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wYXBlci5fX3NldF9fICYmIHRoaXMucGFwZXIuX19zZXRfXy5leGNsdWRlKHRoaXMpO1xuICAgICAgICBSLmV2ZS51bmJpbmQoXCJyYXBoYWVsLiouKi5cIiArIHRoaXMuaWQpO1xuICAgICAgICBSLl90ZWFyKHRoaXMsIHRoaXMucGFwZXIpO1xuICAgICAgICB0aGlzLm5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLm5vZGUpO1xuICAgICAgICB0aGlzLnNoYXBlICYmIHRoaXMuc2hhcGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnNoYXBlKTtcbiAgICAgICAgZm9yICh2YXIgaSBpbiB0aGlzKSB7XG4gICAgICAgICAgICB0aGlzW2ldID0gdHlwZW9mIHRoaXNbaV0gPT0gXCJmdW5jdGlvblwiID8gUi5fcmVtb3ZlZEZhY3RvcnkoaSkgOiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlZCA9IHRydWU7XG4gICAgfTtcbiAgICBlbHByb3RvLmF0dHIgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKHRoaXMucmVtb3ZlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5hbWUgPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIHJlcyA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgYSBpbiB0aGlzLmF0dHJzKSBpZiAodGhpcy5hdHRyc1toYXNdKGEpKSB7XG4gICAgICAgICAgICAgICAgcmVzW2FdID0gdGhpcy5hdHRyc1thXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlcy5ncmFkaWVudCAmJiByZXMuZmlsbCA9PSBcIm5vbmVcIiAmJiAocmVzLmZpbGwgPSByZXMuZ3JhZGllbnQpICYmIGRlbGV0ZSByZXMuZ3JhZGllbnQ7XG4gICAgICAgICAgICByZXMudHJhbnNmb3JtID0gdGhpcy5fLnRyYW5zZm9ybTtcbiAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlID09IG51bGwgJiYgUi5pcyhuYW1lLCBcInN0cmluZ1wiKSkge1xuICAgICAgICAgICAgaWYgKG5hbWUgPT0gZmlsbFN0cmluZyAmJiB0aGlzLmF0dHJzLmZpbGwgPT0gXCJub25lXCIgJiYgdGhpcy5hdHRycy5ncmFkaWVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmF0dHJzLmdyYWRpZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIG5hbWVzID0gbmFtZS5zcGxpdChzZXBhcmF0b3IpLFxuICAgICAgICAgICAgICAgIG91dCA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gbmFtZXMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lc1tpXTtcbiAgICAgICAgICAgICAgICBpZiAobmFtZSBpbiB0aGlzLmF0dHJzKSB7XG4gICAgICAgICAgICAgICAgICAgIG91dFtuYW1lXSA9IHRoaXMuYXR0cnNbbmFtZV07XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChSLmlzKHRoaXMucGFwZXIuY3VzdG9tQXR0cmlidXRlc1tuYW1lXSwgXCJmdW5jdGlvblwiKSkge1xuICAgICAgICAgICAgICAgICAgICBvdXRbbmFtZV0gPSB0aGlzLnBhcGVyLmN1c3RvbUF0dHJpYnV0ZXNbbmFtZV0uZGVmO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG91dFtuYW1lXSA9IFIuX2F2YWlsYWJsZUF0dHJzW25hbWVdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBpaSAtIDEgPyBvdXQgOiBvdXRbbmFtZXNbMF1dO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmF0dHJzICYmIHZhbHVlID09IG51bGwgJiYgUi5pcyhuYW1lLCBcImFycmF5XCIpKSB7XG4gICAgICAgICAgICBvdXQgPSB7fTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGlpID0gbmFtZS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgb3V0W25hbWVbaV1dID0gdGhpcy5hdHRyKG5hbWVbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG91dDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcGFyYW1zO1xuICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgICAgICAgcGFyYW1zID0ge307XG4gICAgICAgICAgICBwYXJhbXNbbmFtZV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICB2YWx1ZSA9PSBudWxsICYmIFIuaXMobmFtZSwgXCJvYmplY3RcIikgJiYgKHBhcmFtcyA9IG5hbWUpO1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gcGFyYW1zKSB7XG4gICAgICAgICAgICBldmUoXCJyYXBoYWVsLmF0dHIuXCIgKyBrZXkgKyBcIi5cIiArIHRoaXMuaWQsIHRoaXMsIHBhcmFtc1trZXldKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFyYW1zKSB7XG4gICAgICAgICAgICBmb3IgKGtleSBpbiB0aGlzLnBhcGVyLmN1c3RvbUF0dHJpYnV0ZXMpIGlmICh0aGlzLnBhcGVyLmN1c3RvbUF0dHJpYnV0ZXNbaGFzXShrZXkpICYmIHBhcmFtc1toYXNdKGtleSkgJiYgUi5pcyh0aGlzLnBhcGVyLmN1c3RvbUF0dHJpYnV0ZXNba2V5XSwgXCJmdW5jdGlvblwiKSkge1xuICAgICAgICAgICAgICAgIHZhciBwYXIgPSB0aGlzLnBhcGVyLmN1c3RvbUF0dHJpYnV0ZXNba2V5XS5hcHBseSh0aGlzLCBbXS5jb25jYXQocGFyYW1zW2tleV0pKTtcbiAgICAgICAgICAgICAgICB0aGlzLmF0dHJzW2tleV0gPSBwYXJhbXNba2V5XTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBzdWJrZXkgaW4gcGFyKSBpZiAocGFyW2hhc10oc3Via2V5KSkge1xuICAgICAgICAgICAgICAgICAgICBwYXJhbXNbc3Via2V5XSA9IHBhcltzdWJrZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHRoaXMucGFwZXIuY2FudmFzLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICAgICAgICAgIGlmIChwYXJhbXMudGV4dCAmJiB0aGlzLnR5cGUgPT0gXCJ0ZXh0XCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRleHRwYXRoLnN0cmluZyA9IHBhcmFtcy50ZXh0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2V0RmlsbEFuZFN0cm9rZSh0aGlzLCBwYXJhbXMpO1xuICAgICAgICAgICAgLy8gdGhpcy5wYXBlci5jYW52YXMuc3R5bGUuZGlzcGxheSA9IEU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBlbHByb3RvLnRvRnJvbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICF0aGlzLnJlbW92ZWQgJiYgdGhpcy5ub2RlLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQodGhpcy5ub2RlKTtcbiAgICAgICAgdGhpcy5wYXBlciAmJiB0aGlzLnBhcGVyLnRvcCAhPSB0aGlzICYmIFIuX3RvZnJvbnQodGhpcywgdGhpcy5wYXBlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgZWxwcm90by50b0JhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnJlbW92ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm5vZGUucGFyZW50Tm9kZS5maXJzdENoaWxkICE9IHRoaXMubm9kZSkge1xuICAgICAgICAgICAgdGhpcy5ub2RlLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHRoaXMubm9kZSwgdGhpcy5ub2RlLnBhcmVudE5vZGUuZmlyc3RDaGlsZCk7XG4gICAgICAgICAgICBSLl90b2JhY2sodGhpcywgdGhpcy5wYXBlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBlbHByb3RvLmluc2VydEFmdGVyID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgICAgaWYgKHRoaXMucmVtb3ZlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVsZW1lbnQuY29uc3RydWN0b3IgPT0gUi5zdC5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnRbZWxlbWVudC5sZW5ndGggLSAxXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZWxlbWVudC5ub2RlLm5leHRTaWJsaW5nKSB7XG4gICAgICAgICAgICBlbGVtZW50Lm5vZGUucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUodGhpcy5ub2RlLCBlbGVtZW50Lm5vZGUubmV4dFNpYmxpbmcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZWxlbWVudC5ub2RlLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQodGhpcy5ub2RlKTtcbiAgICAgICAgfVxuICAgICAgICBSLl9pbnNlcnRhZnRlcih0aGlzLCBlbGVtZW50LCB0aGlzLnBhcGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBlbHByb3RvLmluc2VydEJlZm9yZSA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgICAgIGlmICh0aGlzLnJlbW92ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlbGVtZW50LmNvbnN0cnVjdG9yID09IFIuc3QuY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50WzBdO1xuICAgICAgICB9XG4gICAgICAgIGVsZW1lbnQubm9kZS5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLm5vZGUsIGVsZW1lbnQubm9kZSk7XG4gICAgICAgIFIuX2luc2VydGJlZm9yZSh0aGlzLCBlbGVtZW50LCB0aGlzLnBhcGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICBlbHByb3RvLmJsdXIgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICAgICAgICB2YXIgcyA9IHRoaXMubm9kZS5ydW50aW1lU3R5bGUsXG4gICAgICAgICAgICBmID0gcy5maWx0ZXI7XG4gICAgICAgIGYgPSBmLnJlcGxhY2UoYmx1cnJlZ2V4cCwgRSk7XG4gICAgICAgIGlmICgrc2l6ZSAhPT0gMCkge1xuICAgICAgICAgICAgdGhpcy5hdHRycy5ibHVyID0gc2l6ZTtcbiAgICAgICAgICAgIHMuZmlsdGVyID0gZiArIFMgKyBtcyArIFwiLkJsdXIocGl4ZWxyYWRpdXM9XCIgKyAoK3NpemUgfHwgMS41KSArIFwiKVwiO1xuICAgICAgICAgICAgcy5tYXJnaW4gPSBSLmZvcm1hdChcIi17MH1weCAwIDAgLXswfXB4XCIsIHJvdW5kKCtzaXplIHx8IDEuNSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcy5maWx0ZXIgPSBmO1xuICAgICAgICAgICAgcy5tYXJnaW4gPSAwO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuYXR0cnMuYmx1cjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgUi5fZW5naW5lLnBhdGggPSBmdW5jdGlvbiAocGF0aFN0cmluZywgdm1sKSB7XG4gICAgICAgIHZhciBlbCA9IGNyZWF0ZU5vZGUoXCJzaGFwZVwiKTtcbiAgICAgICAgZWwuc3R5bGUuY3NzVGV4dCA9IGNzc0RvdDtcbiAgICAgICAgZWwuY29vcmRzaXplID0gem9vbSArIFMgKyB6b29tO1xuICAgICAgICBlbC5jb29yZG9yaWdpbiA9IHZtbC5jb29yZG9yaWdpbjtcbiAgICAgICAgdmFyIHAgPSBuZXcgRWxlbWVudChlbCwgdm1sKSxcbiAgICAgICAgICAgIGF0dHIgPSB7ZmlsbDogXCJub25lXCIsIHN0cm9rZTogXCIjMDAwXCJ9O1xuICAgICAgICBwYXRoU3RyaW5nICYmIChhdHRyLnBhdGggPSBwYXRoU3RyaW5nKTtcbiAgICAgICAgcC50eXBlID0gXCJwYXRoXCI7XG4gICAgICAgIHAucGF0aCA9IFtdO1xuICAgICAgICBwLlBhdGggPSBFO1xuICAgICAgICBzZXRGaWxsQW5kU3Ryb2tlKHAsIGF0dHIpO1xuICAgICAgICB2bWwuY2FudmFzICYmIHZtbC5jYW52YXMuYXBwZW5kQ2hpbGQoZWwpO1xuICAgICAgICB2YXIgc2tldyA9IGNyZWF0ZU5vZGUoXCJza2V3XCIpO1xuICAgICAgICBza2V3Lm9uID0gdHJ1ZTtcbiAgICAgICAgZWwuYXBwZW5kQ2hpbGQoc2tldyk7XG4gICAgICAgIHAuc2tldyA9IHNrZXc7XG4gICAgICAgIHAudHJhbnNmb3JtKEUpO1xuICAgICAgICByZXR1cm4gcDtcbiAgICB9O1xuICAgIFIuX2VuZ2luZS5yZWN0ID0gZnVuY3Rpb24gKHZtbCwgeCwgeSwgdywgaCwgcikge1xuICAgICAgICB2YXIgcGF0aCA9IFIuX3JlY3RQYXRoKHgsIHksIHcsIGgsIHIpLFxuICAgICAgICAgICAgcmVzID0gdm1sLnBhdGgocGF0aCksXG4gICAgICAgICAgICBhID0gcmVzLmF0dHJzO1xuICAgICAgICByZXMuWCA9IGEueCA9IHg7XG4gICAgICAgIHJlcy5ZID0gYS55ID0geTtcbiAgICAgICAgcmVzLlcgPSBhLndpZHRoID0gdztcbiAgICAgICAgcmVzLkggPSBhLmhlaWdodCA9IGg7XG4gICAgICAgIGEuciA9IHI7XG4gICAgICAgIGEucGF0aCA9IHBhdGg7XG4gICAgICAgIHJlcy50eXBlID0gXCJyZWN0XCI7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfTtcbiAgICBSLl9lbmdpbmUuZWxsaXBzZSA9IGZ1bmN0aW9uICh2bWwsIHgsIHksIHJ4LCByeSkge1xuICAgICAgICB2YXIgcmVzID0gdm1sLnBhdGgoKSxcbiAgICAgICAgICAgIGEgPSByZXMuYXR0cnM7XG4gICAgICAgIHJlcy5YID0geCAtIHJ4O1xuICAgICAgICByZXMuWSA9IHkgLSByeTtcbiAgICAgICAgcmVzLlcgPSByeCAqIDI7XG4gICAgICAgIHJlcy5IID0gcnkgKiAyO1xuICAgICAgICByZXMudHlwZSA9IFwiZWxsaXBzZVwiO1xuICAgICAgICBzZXRGaWxsQW5kU3Ryb2tlKHJlcywge1xuICAgICAgICAgICAgY3g6IHgsXG4gICAgICAgICAgICBjeTogeSxcbiAgICAgICAgICAgIHJ4OiByeCxcbiAgICAgICAgICAgIHJ5OiByeVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9O1xuICAgIFIuX2VuZ2luZS5jaXJjbGUgPSBmdW5jdGlvbiAodm1sLCB4LCB5LCByKSB7XG4gICAgICAgIHZhciByZXMgPSB2bWwucGF0aCgpLFxuICAgICAgICAgICAgYSA9IHJlcy5hdHRycztcbiAgICAgICAgcmVzLlggPSB4IC0gcjtcbiAgICAgICAgcmVzLlkgPSB5IC0gcjtcbiAgICAgICAgcmVzLlcgPSByZXMuSCA9IHIgKiAyO1xuICAgICAgICByZXMudHlwZSA9IFwiY2lyY2xlXCI7XG4gICAgICAgIHNldEZpbGxBbmRTdHJva2UocmVzLCB7XG4gICAgICAgICAgICBjeDogeCxcbiAgICAgICAgICAgIGN5OiB5LFxuICAgICAgICAgICAgcjogclxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9O1xuICAgIFIuX2VuZ2luZS5pbWFnZSA9IGZ1bmN0aW9uICh2bWwsIHNyYywgeCwgeSwgdywgaCkge1xuICAgICAgICB2YXIgcGF0aCA9IFIuX3JlY3RQYXRoKHgsIHksIHcsIGgpLFxuICAgICAgICAgICAgcmVzID0gdm1sLnBhdGgocGF0aCkuYXR0cih7c3Ryb2tlOiBcIm5vbmVcIn0pLFxuICAgICAgICAgICAgYSA9IHJlcy5hdHRycyxcbiAgICAgICAgICAgIG5vZGUgPSByZXMubm9kZSxcbiAgICAgICAgICAgIGZpbGwgPSBub2RlLmdldEVsZW1lbnRzQnlUYWdOYW1lKGZpbGxTdHJpbmcpWzBdO1xuICAgICAgICBhLnNyYyA9IHNyYztcbiAgICAgICAgcmVzLlggPSBhLnggPSB4O1xuICAgICAgICByZXMuWSA9IGEueSA9IHk7XG4gICAgICAgIHJlcy5XID0gYS53aWR0aCA9IHc7XG4gICAgICAgIHJlcy5IID0gYS5oZWlnaHQgPSBoO1xuICAgICAgICBhLnBhdGggPSBwYXRoO1xuICAgICAgICByZXMudHlwZSA9IFwiaW1hZ2VcIjtcbiAgICAgICAgZmlsbC5wYXJlbnROb2RlID09IG5vZGUgJiYgbm9kZS5yZW1vdmVDaGlsZChmaWxsKTtcbiAgICAgICAgZmlsbC5yb3RhdGUgPSB0cnVlO1xuICAgICAgICBmaWxsLnNyYyA9IHNyYztcbiAgICAgICAgZmlsbC50eXBlID0gXCJ0aWxlXCI7XG4gICAgICAgIHJlcy5fLmZpbGxwb3MgPSBbeCwgeV07XG4gICAgICAgIHJlcy5fLmZpbGxzaXplID0gW3csIGhdO1xuICAgICAgICBub2RlLmFwcGVuZENoaWxkKGZpbGwpO1xuICAgICAgICBzZXRDb29yZHMocmVzLCAxLCAxLCAwLCAwLCAwKTtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9O1xuICAgIFIuX2VuZ2luZS50ZXh0ID0gZnVuY3Rpb24gKHZtbCwgeCwgeSwgdGV4dCkge1xuICAgICAgICB2YXIgZWwgPSBjcmVhdGVOb2RlKFwic2hhcGVcIiksXG4gICAgICAgICAgICBwYXRoID0gY3JlYXRlTm9kZShcInBhdGhcIiksXG4gICAgICAgICAgICBvID0gY3JlYXRlTm9kZShcInRleHRwYXRoXCIpO1xuICAgICAgICB4ID0geCB8fCAwO1xuICAgICAgICB5ID0geSB8fCAwO1xuICAgICAgICB0ZXh0ID0gdGV4dCB8fCBcIlwiO1xuICAgICAgICBwYXRoLnYgPSBSLmZvcm1hdChcIm17MH0sezF9bHsyfSx7MX1cIiwgcm91bmQoeCAqIHpvb20pLCByb3VuZCh5ICogem9vbSksIHJvdW5kKHggKiB6b29tKSArIDEpO1xuICAgICAgICBwYXRoLnRleHRwYXRob2sgPSB0cnVlO1xuICAgICAgICBvLnN0cmluZyA9IFN0cih0ZXh0KTtcbiAgICAgICAgby5vbiA9IHRydWU7XG4gICAgICAgIGVsLnN0eWxlLmNzc1RleHQgPSBjc3NEb3Q7XG4gICAgICAgIGVsLmNvb3Jkc2l6ZSA9IHpvb20gKyBTICsgem9vbTtcbiAgICAgICAgZWwuY29vcmRvcmlnaW4gPSBcIjAgMFwiO1xuICAgICAgICB2YXIgcCA9IG5ldyBFbGVtZW50KGVsLCB2bWwpLFxuICAgICAgICAgICAgYXR0ciA9IHtcbiAgICAgICAgICAgICAgICBmaWxsOiBcIiMwMDBcIixcbiAgICAgICAgICAgICAgICBzdHJva2U6IFwibm9uZVwiLFxuICAgICAgICAgICAgICAgIGZvbnQ6IFIuX2F2YWlsYWJsZUF0dHJzLmZvbnQsXG4gICAgICAgICAgICAgICAgdGV4dDogdGV4dFxuICAgICAgICAgICAgfTtcbiAgICAgICAgcC5zaGFwZSA9IGVsO1xuICAgICAgICBwLnBhdGggPSBwYXRoO1xuICAgICAgICBwLnRleHRwYXRoID0gbztcbiAgICAgICAgcC50eXBlID0gXCJ0ZXh0XCI7XG4gICAgICAgIHAuYXR0cnMudGV4dCA9IFN0cih0ZXh0KTtcbiAgICAgICAgcC5hdHRycy54ID0geDtcbiAgICAgICAgcC5hdHRycy55ID0geTtcbiAgICAgICAgcC5hdHRycy53ID0gMTtcbiAgICAgICAgcC5hdHRycy5oID0gMTtcbiAgICAgICAgc2V0RmlsbEFuZFN0cm9rZShwLCBhdHRyKTtcbiAgICAgICAgZWwuYXBwZW5kQ2hpbGQobyk7XG4gICAgICAgIGVsLmFwcGVuZENoaWxkKHBhdGgpO1xuICAgICAgICB2bWwuY2FudmFzLmFwcGVuZENoaWxkKGVsKTtcbiAgICAgICAgdmFyIHNrZXcgPSBjcmVhdGVOb2RlKFwic2tld1wiKTtcbiAgICAgICAgc2tldy5vbiA9IHRydWU7XG4gICAgICAgIGVsLmFwcGVuZENoaWxkKHNrZXcpO1xuICAgICAgICBwLnNrZXcgPSBza2V3O1xuICAgICAgICBwLnRyYW5zZm9ybShFKTtcbiAgICAgICAgcmV0dXJuIHA7XG4gICAgfTtcbiAgICBSLl9lbmdpbmUuc2V0U2l6ZSA9IGZ1bmN0aW9uICh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgICAgIHZhciBjcyA9IHRoaXMuY2FudmFzLnN0eWxlO1xuICAgICAgICB0aGlzLndpZHRoID0gd2lkdGg7XG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgICB3aWR0aCA9PSArd2lkdGggJiYgKHdpZHRoICs9IFwicHhcIik7XG4gICAgICAgIGhlaWdodCA9PSAraGVpZ2h0ICYmIChoZWlnaHQgKz0gXCJweFwiKTtcbiAgICAgICAgY3Mud2lkdGggPSB3aWR0aDtcbiAgICAgICAgY3MuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgICAgICBjcy5jbGlwID0gXCJyZWN0KDAgXCIgKyB3aWR0aCArIFwiIFwiICsgaGVpZ2h0ICsgXCIgMClcIjtcbiAgICAgICAgaWYgKHRoaXMuX3ZpZXdCb3gpIHtcbiAgICAgICAgICAgIFIuX2VuZ2luZS5zZXRWaWV3Qm94LmFwcGx5KHRoaXMsIHRoaXMuX3ZpZXdCb3gpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gICAgUi5fZW5naW5lLnNldFZpZXdCb3ggPSBmdW5jdGlvbiAoeCwgeSwgdywgaCwgZml0KSB7XG4gICAgICAgIFIuZXZlKFwicmFwaGFlbC5zZXRWaWV3Qm94XCIsIHRoaXMsIHRoaXMuX3ZpZXdCb3gsIFt4LCB5LCB3LCBoLCBmaXRdKTtcbiAgICAgICAgdmFyIHBhcGVyU2l6ZSA9IHRoaXMuZ2V0U2l6ZSgpLFxuICAgICAgICAgICAgd2lkdGggPSBwYXBlclNpemUud2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQgPSBwYXBlclNpemUuaGVpZ2h0LFxuICAgICAgICAgICAgSCwgVztcbiAgICAgICAgaWYgKGZpdCkge1xuICAgICAgICAgICAgSCA9IGhlaWdodCAvIGg7XG4gICAgICAgICAgICBXID0gd2lkdGggLyB3O1xuICAgICAgICAgICAgaWYgKHcgKiBIIDwgd2lkdGgpIHtcbiAgICAgICAgICAgICAgICB4IC09ICh3aWR0aCAtIHcgKiBIKSAvIDIgLyBIO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGggKiBXIDwgaGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgeSAtPSAoaGVpZ2h0IC0gaCAqIFcpIC8gMiAvIFc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdmlld0JveCA9IFt4LCB5LCB3LCBoLCAhIWZpdF07XG4gICAgICAgIHRoaXMuX3ZpZXdCb3hTaGlmdCA9IHtcbiAgICAgICAgICAgIGR4OiAteCxcbiAgICAgICAgICAgIGR5OiAteSxcbiAgICAgICAgICAgIHNjYWxlOiBwYXBlclNpemVcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgZWwudHJhbnNmb3JtKFwiLi4uXCIpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcbiAgICB2YXIgY3JlYXRlTm9kZTtcbiAgICBSLl9lbmdpbmUuaW5pdFdpbiA9IGZ1bmN0aW9uICh3aW4pIHtcbiAgICAgICAgICAgIHZhciBkb2MgPSB3aW4uZG9jdW1lbnQ7XG4gICAgICAgICAgICBpZiAoZG9jLnN0eWxlU2hlZXRzLmxlbmd0aCA8IDMxKSB7XG4gICAgICAgICAgICAgICAgZG9jLmNyZWF0ZVN0eWxlU2hlZXQoKS5hZGRSdWxlKFwiLnJ2bWxcIiwgXCJiZWhhdmlvcjp1cmwoI2RlZmF1bHQjVk1MKVwiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gbm8gbW9yZSByb29tLCBhZGQgdG8gdGhlIGV4aXN0aW5nIG9uZVxuICAgICAgICAgICAgICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzMTE5NCUyOFZTLjg1JTI5LmFzcHhcbiAgICAgICAgICAgICAgICBkb2Muc3R5bGVTaGVldHNbMF0uYWRkUnVsZShcIi5ydm1sXCIsIFwiYmVoYXZpb3I6dXJsKCNkZWZhdWx0I1ZNTClcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICFkb2MubmFtZXNwYWNlcy5ydm1sICYmIGRvYy5uYW1lc3BhY2VzLmFkZChcInJ2bWxcIiwgXCJ1cm46c2NoZW1hcy1taWNyb3NvZnQtY29tOnZtbFwiKTtcbiAgICAgICAgICAgICAgICBjcmVhdGVOb2RlID0gZnVuY3Rpb24gKHRhZ05hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvYy5jcmVhdGVFbGVtZW50KCc8cnZtbDonICsgdGFnTmFtZSArICcgY2xhc3M9XCJydm1sXCI+Jyk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjcmVhdGVOb2RlID0gZnVuY3Rpb24gKHRhZ05hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvYy5jcmVhdGVFbGVtZW50KCc8JyArIHRhZ05hbWUgKyAnIHhtbG5zPVwidXJuOnNjaGVtYXMtbWljcm9zb2Z0LmNvbTp2bWxcIiBjbGFzcz1cInJ2bWxcIj4nKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIFIuX2VuZ2luZS5pbml0V2luKFIuX2cud2luKTtcbiAgICBSLl9lbmdpbmUuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29uID0gUi5fZ2V0Q29udGFpbmVyLmFwcGx5KDAsIGFyZ3VtZW50cyksXG4gICAgICAgICAgICBjb250YWluZXIgPSBjb24uY29udGFpbmVyLFxuICAgICAgICAgICAgaGVpZ2h0ID0gY29uLmhlaWdodCxcbiAgICAgICAgICAgIHMsXG4gICAgICAgICAgICB3aWR0aCA9IGNvbi53aWR0aCxcbiAgICAgICAgICAgIHggPSBjb24ueCxcbiAgICAgICAgICAgIHkgPSBjb24ueTtcbiAgICAgICAgaWYgKCFjb250YWluZXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlZNTCBjb250YWluZXIgbm90IGZvdW5kLlwiKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcmVzID0gbmV3IFIuX1BhcGVyLFxuICAgICAgICAgICAgYyA9IHJlcy5jYW52YXMgPSBSLl9nLmRvYy5jcmVhdGVFbGVtZW50KFwiZGl2XCIpLFxuICAgICAgICAgICAgY3MgPSBjLnN0eWxlO1xuICAgICAgICB4ID0geCB8fCAwO1xuICAgICAgICB5ID0geSB8fCAwO1xuICAgICAgICB3aWR0aCA9IHdpZHRoIHx8IDUxMjtcbiAgICAgICAgaGVpZ2h0ID0gaGVpZ2h0IHx8IDM0MjtcbiAgICAgICAgcmVzLndpZHRoID0gd2lkdGg7XG4gICAgICAgIHJlcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIHdpZHRoID09ICt3aWR0aCAmJiAod2lkdGggKz0gXCJweFwiKTtcbiAgICAgICAgaGVpZ2h0ID09ICtoZWlnaHQgJiYgKGhlaWdodCArPSBcInB4XCIpO1xuICAgICAgICByZXMuY29vcmRzaXplID0gem9vbSAqIDFlMyArIFMgKyB6b29tICogMWUzO1xuICAgICAgICByZXMuY29vcmRvcmlnaW4gPSBcIjAgMFwiO1xuICAgICAgICByZXMuc3BhbiA9IFIuX2cuZG9jLmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO1xuICAgICAgICByZXMuc3Bhbi5zdHlsZS5jc3NUZXh0ID0gXCJwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0Oi05OTk5ZW07dG9wOi05OTk5ZW07cGFkZGluZzowO21hcmdpbjowO2xpbmUtaGVpZ2h0OjE7XCI7XG4gICAgICAgIGMuYXBwZW5kQ2hpbGQocmVzLnNwYW4pO1xuICAgICAgICBjcy5jc3NUZXh0ID0gUi5mb3JtYXQoXCJ0b3A6MDtsZWZ0OjA7d2lkdGg6ezB9O2hlaWdodDp7MX07ZGlzcGxheTppbmxpbmUtYmxvY2s7cG9zaXRpb246cmVsYXRpdmU7Y2xpcDpyZWN0KDAgezB9IHsxfSAwKTtvdmVyZmxvdzpoaWRkZW5cIiwgd2lkdGgsIGhlaWdodCk7XG4gICAgICAgIGlmIChjb250YWluZXIgPT0gMSkge1xuICAgICAgICAgICAgUi5fZy5kb2MuYm9keS5hcHBlbmRDaGlsZChjKTtcbiAgICAgICAgICAgIGNzLmxlZnQgPSB4ICsgXCJweFwiO1xuICAgICAgICAgICAgY3MudG9wID0geSArIFwicHhcIjtcbiAgICAgICAgICAgIGNzLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNvbnRhaW5lci5maXJzdENoaWxkKSB7XG4gICAgICAgICAgICAgICAgY29udGFpbmVyLmluc2VydEJlZm9yZShjLCBjb250YWluZXIuZmlyc3RDaGlsZCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChjKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXMucmVuZGVyZml4ID0gZnVuY3Rpb24gKCkge307XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfTtcbiAgICBSLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgUi5ldmUoXCJyYXBoYWVsLmNsZWFyXCIsIHRoaXMpO1xuICAgICAgICB0aGlzLmNhbnZhcy5pbm5lckhUTUwgPSBFO1xuICAgICAgICB0aGlzLnNwYW4gPSBSLl9nLmRvYy5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcbiAgICAgICAgdGhpcy5zcGFuLnN0eWxlLmNzc1RleHQgPSBcInBvc2l0aW9uOmFic29sdXRlO2xlZnQ6LTk5OTllbTt0b3A6LTk5OTllbTtwYWRkaW5nOjA7bWFyZ2luOjA7bGluZS1oZWlnaHQ6MTtkaXNwbGF5OmlubGluZTtcIjtcbiAgICAgICAgdGhpcy5jYW52YXMuYXBwZW5kQ2hpbGQodGhpcy5zcGFuKTtcbiAgICAgICAgdGhpcy5ib3R0b20gPSB0aGlzLnRvcCA9IG51bGw7XG4gICAgfTtcbiAgICBSLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIFIuZXZlKFwicmFwaGFlbC5yZW1vdmVcIiwgdGhpcyk7XG4gICAgICAgIHRoaXMuY2FudmFzLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5jYW52YXMpO1xuICAgICAgICBmb3IgKHZhciBpIGluIHRoaXMpIHtcbiAgICAgICAgICAgIHRoaXNbaV0gPSB0eXBlb2YgdGhpc1tpXSA9PSBcImZ1bmN0aW9uXCIgPyBSLl9yZW1vdmVkRmFjdG9yeShpKSA6IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIHZhciBzZXRwcm90byA9IFIuc3Q7XG4gICAgZm9yICh2YXIgbWV0aG9kIGluIGVscHJvdG8pIGlmIChlbHByb3RvW2hhc10obWV0aG9kKSAmJiAhc2V0cHJvdG9baGFzXShtZXRob2QpKSB7XG4gICAgICAgIHNldHByb3RvW21ldGhvZF0gPSAoZnVuY3Rpb24gKG1ldGhvZG5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGFyZyA9IGFyZ3VtZW50cztcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbCkge1xuICAgICAgICAgICAgICAgICAgICBlbFttZXRob2RuYW1lXS5hcHBseShlbCwgYXJnKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKG1ldGhvZCk7XG4gICAgfVxufSk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./dev/raphael.vml.js\n"); + +/***/ }), + +/***/ "./node_modules/eve-raphael/eve.js": +/*!*****************************************!*\ + !*** ./node_modules/eve-raphael/eve.js ***! + \*****************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.\n// \n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n// \n// http://www.apache.org/licenses/LICENSE-2.0\n// \n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ┌────────────────────────────────────────────────────────────┐ \\\\\n// │ Eve 0.5.0 - JavaScript Events Library │ \\\\\n// ├────────────────────────────────────────────────────────────┤ \\\\\n// │ Author Dmitry Baranovskiy (http://dmitry.baranovskiy.com/) │ \\\\\n// └────────────────────────────────────────────────────────────┘ \\\\\n\n(function (glob) {\n var version = \"0.5.0\",\n has = \"hasOwnProperty\",\n separator = /[\\.\\/]/,\n comaseparator = /\\s*,\\s*/,\n wildcard = \"*\",\n fun = function () {},\n numsort = function (a, b) {\n return a - b;\n },\n current_event,\n stop,\n events = {n: {}},\n firstDefined = function () {\n for (var i = 0, ii = this.length; i < ii; i++) {\n if (typeof this[i] != \"undefined\") {\n return this[i];\n }\n }\n },\n lastDefined = function () {\n var i = this.length;\n while (--i) {\n if (typeof this[i] != \"undefined\") {\n return this[i];\n }\n }\n },\n objtos = Object.prototype.toString,\n Str = String,\n isArray = Array.isArray || function (ar) {\n return ar instanceof Array || objtos.call(ar) == \"[object Array]\";\n };\n /*\\\n * eve\n [ method ]\n\n * Fires event with given `name`, given scope and other parameters.\n\n > Arguments\n\n - name (string) name of the *event*, dot (`.`) or slash (`/`) separated\n - scope (object) context for the event handlers\n - varargs (...) the rest of arguments will be sent to event handlers\n\n = (object) array of returned values from the listeners. Array has two methods `.firstDefined()` and `.lastDefined()` to get first or last not `undefined` value.\n \\*/\n var eve = function (name, scope) {\n var e = events,\n oldstop = stop,\n args = Array.prototype.slice.call(arguments, 2),\n listeners = eve.listeners(name),\n z = 0,\n f = false,\n l,\n indexed = [],\n queue = {},\n out = [],\n ce = current_event,\n errors = [];\n out.firstDefined = firstDefined;\n out.lastDefined = lastDefined;\n current_event = name;\n stop = 0;\n for (var i = 0, ii = listeners.length; i < ii; i++) if (\"zIndex\" in listeners[i]) {\n indexed.push(listeners[i].zIndex);\n if (listeners[i].zIndex < 0) {\n queue[listeners[i].zIndex] = listeners[i];\n }\n }\n indexed.sort(numsort);\n while (indexed[z] < 0) {\n l = queue[indexed[z++]];\n out.push(l.apply(scope, args));\n if (stop) {\n stop = oldstop;\n return out;\n }\n }\n for (i = 0; i < ii; i++) {\n l = listeners[i];\n if (\"zIndex\" in l) {\n if (l.zIndex == indexed[z]) {\n out.push(l.apply(scope, args));\n if (stop) {\n break;\n }\n do {\n z++;\n l = queue[indexed[z]];\n l && out.push(l.apply(scope, args));\n if (stop) {\n break;\n }\n } while (l)\n } else {\n queue[l.zIndex] = l;\n }\n } else {\n out.push(l.apply(scope, args));\n if (stop) {\n break;\n }\n }\n }\n stop = oldstop;\n current_event = ce;\n return out;\n };\n // Undocumented. Debug only.\n eve._events = events;\n /*\\\n * eve.listeners\n [ method ]\n\n * Internal method which gives you array of all event handlers that will be triggered by the given `name`.\n\n > Arguments\n\n - name (string) name of the event, dot (`.`) or slash (`/`) separated\n\n = (array) array of event handlers\n \\*/\n eve.listeners = function (name) {\n var names = isArray(name) ? name : name.split(separator),\n e = events,\n item,\n items,\n k,\n i,\n ii,\n j,\n jj,\n nes,\n es = [e],\n out = [];\n for (i = 0, ii = names.length; i < ii; i++) {\n nes = [];\n for (j = 0, jj = es.length; j < jj; j++) {\n e = es[j].n;\n items = [e[names[i]], e[wildcard]];\n k = 2;\n while (k--) {\n item = items[k];\n if (item) {\n nes.push(item);\n out = out.concat(item.f || []);\n }\n }\n }\n es = nes;\n }\n return out;\n };\n /*\\\n * eve.separator\n [ method ]\n\n * If for some reasons you don’t like default separators (`.` or `/`) you can specify yours\n * here. Be aware that if you pass a string longer than one character it will be treated as\n * a list of characters.\n\n - separator (string) new separator. Empty string resets to default: `.` or `/`.\n \\*/\n eve.separator = function (sep) {\n if (sep) {\n sep = Str(sep).replace(/(?=[\\.\\^\\]\\[\\-])/g, \"\\\\\");\n sep = \"[\" + sep + \"]\";\n separator = new RegExp(sep);\n } else {\n separator = /[\\.\\/]/;\n }\n };\n /*\\\n * eve.on\n [ method ]\n **\n * Binds given event handler with a given name. You can use wildcards “`*`” for the names:\n | eve.on(\"*.under.*\", f);\n | eve(\"mouse.under.floor\"); // triggers f\n * Use @eve to trigger the listener.\n **\n - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards\n - f (function) event handler function\n **\n - name (array) if you don’t want to use separators, you can use array of strings\n - f (function) event handler function\n **\n = (function) returned function accepts a single numeric parameter that represents z-index of the handler. It is an optional feature and only used when you need to ensure that some subset of handlers will be invoked in a given order, despite of the order of assignment. \n > Example:\n | eve.on(\"mouse\", eatIt)(2);\n | eve.on(\"mouse\", scream);\n | eve.on(\"mouse\", catchIt)(1);\n * This will ensure that `catchIt` function will be called before `eatIt`.\n *\n * If you want to put your handler before non-indexed handlers, specify a negative value.\n * Note: I assume most of the time you don’t need to worry about z-index, but it’s nice to have this feature “just in case”.\n \\*/\n eve.on = function (name, f) {\n if (typeof f != \"function\") {\n return function () {};\n }\n var names = isArray(name) ? (isArray(name[0]) ? name : [name]) : Str(name).split(comaseparator);\n for (var i = 0, ii = names.length; i < ii; i++) {\n (function (name) {\n var names = isArray(name) ? name : Str(name).split(separator),\n e = events,\n exist;\n for (var i = 0, ii = names.length; i < ii; i++) {\n e = e.n;\n e = e.hasOwnProperty(names[i]) && e[names[i]] || (e[names[i]] = {n: {}});\n }\n e.f = e.f || [];\n for (i = 0, ii = e.f.length; i < ii; i++) if (e.f[i] == f) {\n exist = true;\n break;\n }\n !exist && e.f.push(f);\n }(names[i]));\n }\n return function (zIndex) {\n if (+zIndex == +zIndex) {\n f.zIndex = +zIndex;\n }\n };\n };\n /*\\\n * eve.f\n [ method ]\n **\n * Returns function that will fire given event with optional arguments.\n * Arguments that will be passed to the result function will be also\n * concated to the list of final arguments.\n | el.onclick = eve.f(\"click\", 1, 2);\n | eve.on(\"click\", function (a, b, c) {\n | console.log(a, b, c); // 1, 2, [event object]\n | });\n > Arguments\n - event (string) event name\n - varargs (…) and any other arguments\n = (function) possible event handler function\n \\*/\n eve.f = function (event) {\n var attrs = [].slice.call(arguments, 1);\n return function () {\n eve.apply(null, [event, null].concat(attrs).concat([].slice.call(arguments, 0)));\n };\n };\n /*\\\n * eve.stop\n [ method ]\n **\n * Is used inside an event handler to stop the event, preventing any subsequent listeners from firing.\n \\*/\n eve.stop = function () {\n stop = 1;\n };\n /*\\\n * eve.nt\n [ method ]\n **\n * Could be used inside event handler to figure out actual name of the event.\n **\n > Arguments\n **\n - subname (string) #optional subname of the event\n **\n = (string) name of the event, if `subname` is not specified\n * or\n = (boolean) `true`, if current event’s name contains `subname`\n \\*/\n eve.nt = function (subname) {\n var cur = isArray(current_event) ? current_event.join(\".\") : current_event;\n if (subname) {\n return new RegExp(\"(?:\\\\.|\\\\/|^)\" + subname + \"(?:\\\\.|\\\\/|$)\").test(cur);\n }\n return cur;\n };\n /*\\\n * eve.nts\n [ method ]\n **\n * Could be used inside event handler to figure out actual name of the event.\n **\n **\n = (array) names of the event\n \\*/\n eve.nts = function () {\n return isArray(current_event) ? current_event : current_event.split(separator);\n };\n /*\\\n * eve.off\n [ method ]\n **\n * Removes given function from the list of event listeners assigned to given name.\n * If no arguments specified all the events will be cleared.\n **\n > Arguments\n **\n - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards\n - f (function) event handler function\n \\*/\n /*\\\n * eve.unbind\n [ method ]\n **\n * See @eve.off\n \\*/\n eve.off = eve.unbind = function (name, f) {\n if (!name) {\n eve._events = events = {n: {}};\n return;\n }\n var names = isArray(name) ? (isArray(name[0]) ? name : [name]) : Str(name).split(comaseparator);\n if (names.length > 1) {\n for (var i = 0, ii = names.length; i < ii; i++) {\n eve.off(names[i], f);\n }\n return;\n }\n names = isArray(name) ? name : Str(name).split(separator);\n var e,\n key,\n splice,\n i, ii, j, jj,\n cur = [events];\n for (i = 0, ii = names.length; i < ii; i++) {\n for (j = 0; j < cur.length; j += splice.length - 2) {\n splice = [j, 1];\n e = cur[j].n;\n if (names[i] != wildcard) {\n if (e[names[i]]) {\n splice.push(e[names[i]]);\n }\n } else {\n for (key in e) if (e[has](key)) {\n splice.push(e[key]);\n }\n }\n cur.splice.apply(cur, splice);\n }\n }\n for (i = 0, ii = cur.length; i < ii; i++) {\n e = cur[i];\n while (e.n) {\n if (f) {\n if (e.f) {\n for (j = 0, jj = e.f.length; j < jj; j++) if (e.f[j] == f) {\n e.f.splice(j, 1);\n break;\n }\n !e.f.length && delete e.f;\n }\n for (key in e.n) if (e.n[has](key) && e.n[key].f) {\n var funcs = e.n[key].f;\n for (j = 0, jj = funcs.length; j < jj; j++) if (funcs[j] == f) {\n funcs.splice(j, 1);\n break;\n }\n !funcs.length && delete e.n[key].f;\n }\n } else {\n delete e.f;\n for (key in e.n) if (e.n[has](key) && e.n[key].f) {\n delete e.n[key].f;\n }\n }\n e = e.n;\n }\n }\n };\n /*\\\n * eve.once\n [ method ]\n **\n * Binds given event handler with a given name to only run once then unbind itself.\n | eve.once(\"login\", f);\n | eve(\"login\"); // triggers f\n | eve(\"login\"); // no listeners\n * Use @eve to trigger the listener.\n **\n > Arguments\n **\n - name (string) name of the event, dot (`.`) or slash (`/`) separated, with optional wildcards\n - f (function) event handler function\n **\n = (function) same return function as @eve.on\n \\*/\n eve.once = function (name, f) {\n var f2 = function () {\n eve.off(name, f2);\n return f.apply(this, arguments);\n };\n return eve.on(name, f2);\n };\n /*\\\n * eve.version\n [ property (string) ]\n **\n * Current version of the library.\n \\*/\n eve.version = version;\n eve.toString = function () {\n return \"You are running Eve \" + version;\n };\n (typeof module != \"undefined\" && module.exports) ? (module.exports = eve) : ( true ? (!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() { return eve; }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))) : (undefined));\n})(this);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvZXZlLXJhcGhhZWwvZXZlLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vUmFwaGFlbC8uL25vZGVfbW9kdWxlcy9ldmUtcmFwaGFlbC9ldmUuanM/ZDJiNCJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgKGMpIDIwMTMgQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4vLyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4vLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbi8vIFxuLy8gaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4vLyBcbi8vIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbi8vIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbi8vIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuLy8gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuLy8gbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4vLyDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJAgXFxcXFxuLy8g4pSCIEV2ZSAwLjUuMCAtIEphdmFTY3JpcHQgRXZlbnRzIExpYnJhcnkgICAgICAgICAgICAgICAgICAgICAg4pSCIFxcXFxcbi8vIOKUnOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUpCBcXFxcXG4vLyDilIIgQXV0aG9yIERtaXRyeSBCYXJhbm92c2tpeSAoaHR0cDovL2RtaXRyeS5iYXJhbm92c2tpeS5jb20vKSDilIIgXFxcXFxuLy8g4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYIFxcXFxcblxuKGZ1bmN0aW9uIChnbG9iKSB7XG4gICAgdmFyIHZlcnNpb24gPSBcIjAuNS4wXCIsXG4gICAgICAgIGhhcyA9IFwiaGFzT3duUHJvcGVydHlcIixcbiAgICAgICAgc2VwYXJhdG9yID0gL1tcXC5cXC9dLyxcbiAgICAgICAgY29tYXNlcGFyYXRvciA9IC9cXHMqLFxccyovLFxuICAgICAgICB3aWxkY2FyZCA9IFwiKlwiLFxuICAgICAgICBmdW4gPSBmdW5jdGlvbiAoKSB7fSxcbiAgICAgICAgbnVtc29ydCA9IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgICAgICByZXR1cm4gYSAtIGI7XG4gICAgICAgIH0sXG4gICAgICAgIGN1cnJlbnRfZXZlbnQsXG4gICAgICAgIHN0b3AsXG4gICAgICAgIGV2ZW50cyA9IHtuOiB7fX0sXG4gICAgICAgIGZpcnN0RGVmaW5lZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRoaXMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpc1tpXSAhPSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgbGFzdERlZmluZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgaSA9IHRoaXMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKC0taSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpc1tpXSAhPSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzW2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgb2JqdG9zID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyxcbiAgICAgICAgU3RyID0gU3RyaW5nLFxuICAgICAgICBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXIpIHtcbiAgICAgICAgICAgIHJldHVybiBhciBpbnN0YW5jZW9mIEFycmF5IHx8IG9ianRvcy5jYWxsKGFyKSA9PSBcIltvYmplY3QgQXJyYXldXCI7XG4gICAgICAgIH07XG4gICAgLypcXFxuICAgICAqIGV2ZVxuICAgICBbIG1ldGhvZCBdXG5cbiAgICAgKiBGaXJlcyBldmVudCB3aXRoIGdpdmVuIGBuYW1lYCwgZ2l2ZW4gc2NvcGUgYW5kIG90aGVyIHBhcmFtZXRlcnMuXG5cbiAgICAgPiBBcmd1bWVudHNcblxuICAgICAtIG5hbWUgKHN0cmluZykgbmFtZSBvZiB0aGUgKmV2ZW50KiwgZG90IChgLmApIG9yIHNsYXNoIChgL2ApIHNlcGFyYXRlZFxuICAgICAtIHNjb3BlIChvYmplY3QpIGNvbnRleHQgZm9yIHRoZSBldmVudCBoYW5kbGVyc1xuICAgICAtIHZhcmFyZ3MgKC4uLikgdGhlIHJlc3Qgb2YgYXJndW1lbnRzIHdpbGwgYmUgc2VudCB0byBldmVudCBoYW5kbGVyc1xuXG4gICAgID0gKG9iamVjdCkgYXJyYXkgb2YgcmV0dXJuZWQgdmFsdWVzIGZyb20gdGhlIGxpc3RlbmVycy4gQXJyYXkgaGFzIHR3byBtZXRob2RzIGAuZmlyc3REZWZpbmVkKClgIGFuZCBgLmxhc3REZWZpbmVkKClgIHRvIGdldCBmaXJzdCBvciBsYXN0IG5vdCBgdW5kZWZpbmVkYCB2YWx1ZS5cbiAgICBcXCovXG4gICAgICAgIHZhciBldmUgPSBmdW5jdGlvbiAobmFtZSwgc2NvcGUpIHtcbiAgICAgICAgICAgIHZhciBlID0gZXZlbnRzLFxuICAgICAgICAgICAgICAgIG9sZHN0b3AgPSBzdG9wLFxuICAgICAgICAgICAgICAgIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpLFxuICAgICAgICAgICAgICAgIGxpc3RlbmVycyA9IGV2ZS5saXN0ZW5lcnMobmFtZSksXG4gICAgICAgICAgICAgICAgeiA9IDAsXG4gICAgICAgICAgICAgICAgZiA9IGZhbHNlLFxuICAgICAgICAgICAgICAgIGwsXG4gICAgICAgICAgICAgICAgaW5kZXhlZCA9IFtdLFxuICAgICAgICAgICAgICAgIHF1ZXVlID0ge30sXG4gICAgICAgICAgICAgICAgb3V0ID0gW10sXG4gICAgICAgICAgICAgICAgY2UgPSBjdXJyZW50X2V2ZW50LFxuICAgICAgICAgICAgICAgIGVycm9ycyA9IFtdO1xuICAgICAgICAgICAgb3V0LmZpcnN0RGVmaW5lZCA9IGZpcnN0RGVmaW5lZDtcbiAgICAgICAgICAgIG91dC5sYXN0RGVmaW5lZCA9IGxhc3REZWZpbmVkO1xuICAgICAgICAgICAgY3VycmVudF9ldmVudCA9IG5hbWU7XG4gICAgICAgICAgICBzdG9wID0gMDtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBpaTsgaSsrKSBpZiAoXCJ6SW5kZXhcIiBpbiBsaXN0ZW5lcnNbaV0pIHtcbiAgICAgICAgICAgICAgICBpbmRleGVkLnB1c2gobGlzdGVuZXJzW2ldLnpJbmRleCk7XG4gICAgICAgICAgICAgICAgaWYgKGxpc3RlbmVyc1tpXS56SW5kZXggPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHF1ZXVlW2xpc3RlbmVyc1tpXS56SW5kZXhdID0gbGlzdGVuZXJzW2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGluZGV4ZWQuc29ydChudW1zb3J0KTtcbiAgICAgICAgICAgIHdoaWxlIChpbmRleGVkW3pdIDwgMCkge1xuICAgICAgICAgICAgICAgIGwgPSBxdWV1ZVtpbmRleGVkW3orK11dO1xuICAgICAgICAgICAgICAgIG91dC5wdXNoKGwuYXBwbHkoc2NvcGUsIGFyZ3MpKTtcbiAgICAgICAgICAgICAgICBpZiAoc3RvcCkge1xuICAgICAgICAgICAgICAgICAgICBzdG9wID0gb2xkc3RvcDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG91dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgIGwgPSBsaXN0ZW5lcnNbaV07XG4gICAgICAgICAgICAgICAgaWYgKFwiekluZGV4XCIgaW4gbCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAobC56SW5kZXggPT0gaW5kZXhlZFt6XSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3V0LnB1c2gobC5hcHBseShzY29wZSwgYXJncykpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0b3ApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB6Kys7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbCA9IHF1ZXVlW2luZGV4ZWRbel1dO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGwgJiYgb3V0LnB1c2gobC5hcHBseShzY29wZSwgYXJncykpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdG9wKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gd2hpbGUgKGwpXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBxdWV1ZVtsLnpJbmRleF0gPSBsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0LnB1c2gobC5hcHBseShzY29wZSwgYXJncykpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RvcCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdG9wID0gb2xkc3RvcDtcbiAgICAgICAgICAgIGN1cnJlbnRfZXZlbnQgPSBjZTtcbiAgICAgICAgICAgIHJldHVybiBvdXQ7XG4gICAgICAgIH07XG4gICAgICAgIC8vIFVuZG9jdW1lbnRlZC4gRGVidWcgb25seS5cbiAgICAgICAgZXZlLl9ldmVudHMgPSBldmVudHM7XG4gICAgLypcXFxuICAgICAqIGV2ZS5saXN0ZW5lcnNcbiAgICAgWyBtZXRob2QgXVxuXG4gICAgICogSW50ZXJuYWwgbWV0aG9kIHdoaWNoIGdpdmVzIHlvdSBhcnJheSBvZiBhbGwgZXZlbnQgaGFuZGxlcnMgdGhhdCB3aWxsIGJlIHRyaWdnZXJlZCBieSB0aGUgZ2l2ZW4gYG5hbWVgLlxuXG4gICAgID4gQXJndW1lbnRzXG5cbiAgICAgLSBuYW1lIChzdHJpbmcpIG5hbWUgb2YgdGhlIGV2ZW50LCBkb3QgKGAuYCkgb3Igc2xhc2ggKGAvYCkgc2VwYXJhdGVkXG5cbiAgICAgPSAoYXJyYXkpIGFycmF5IG9mIGV2ZW50IGhhbmRsZXJzXG4gICAgXFwqL1xuICAgIGV2ZS5saXN0ZW5lcnMgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICB2YXIgbmFtZXMgPSBpc0FycmF5KG5hbWUpID8gbmFtZSA6IG5hbWUuc3BsaXQoc2VwYXJhdG9yKSxcbiAgICAgICAgICAgIGUgPSBldmVudHMsXG4gICAgICAgICAgICBpdGVtLFxuICAgICAgICAgICAgaXRlbXMsXG4gICAgICAgICAgICBrLFxuICAgICAgICAgICAgaSxcbiAgICAgICAgICAgIGlpLFxuICAgICAgICAgICAgaixcbiAgICAgICAgICAgIGpqLFxuICAgICAgICAgICAgbmVzLFxuICAgICAgICAgICAgZXMgPSBbZV0sXG4gICAgICAgICAgICBvdXQgPSBbXTtcbiAgICAgICAgZm9yIChpID0gMCwgaWkgPSBuYW1lcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICBuZXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAoaiA9IDAsIGpqID0gZXMubGVuZ3RoOyBqIDwgamo7IGorKykge1xuICAgICAgICAgICAgICAgIGUgPSBlc1tqXS5uO1xuICAgICAgICAgICAgICAgIGl0ZW1zID0gW2VbbmFtZXNbaV1dLCBlW3dpbGRjYXJkXV07XG4gICAgICAgICAgICAgICAgayA9IDI7XG4gICAgICAgICAgICAgICAgd2hpbGUgKGstLSkge1xuICAgICAgICAgICAgICAgICAgICBpdGVtID0gaXRlbXNba107XG4gICAgICAgICAgICAgICAgICAgIGlmIChpdGVtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXMucHVzaChpdGVtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dCA9IG91dC5jb25jYXQoaXRlbS5mIHx8IFtdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVzID0gbmVzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogZXZlLnNlcGFyYXRvclxuICAgICBbIG1ldGhvZCBdXG5cbiAgICAgKiBJZiBmb3Igc29tZSByZWFzb25zIHlvdSBkb27igJl0IGxpa2UgZGVmYXVsdCBzZXBhcmF0b3JzIChgLmAgb3IgYC9gKSB5b3UgY2FuIHNwZWNpZnkgeW91cnNcbiAgICAgKiBoZXJlLiBCZSBhd2FyZSB0aGF0IGlmIHlvdSBwYXNzIGEgc3RyaW5nIGxvbmdlciB0aGFuIG9uZSBjaGFyYWN0ZXIgaXQgd2lsbCBiZSB0cmVhdGVkIGFzXG4gICAgICogYSBsaXN0IG9mIGNoYXJhY3RlcnMuXG5cbiAgICAgLSBzZXBhcmF0b3IgKHN0cmluZykgbmV3IHNlcGFyYXRvci4gRW1wdHkgc3RyaW5nIHJlc2V0cyB0byBkZWZhdWx0OiBgLmAgb3IgYC9gLlxuICAgIFxcKi9cbiAgICBldmUuc2VwYXJhdG9yID0gZnVuY3Rpb24gKHNlcCkge1xuICAgICAgICBpZiAoc2VwKSB7XG4gICAgICAgICAgICBzZXAgPSBTdHIoc2VwKS5yZXBsYWNlKC8oPz1bXFwuXFxeXFxdXFxbXFwtXSkvZywgXCJcXFxcXCIpO1xuICAgICAgICAgICAgc2VwID0gXCJbXCIgKyBzZXAgKyBcIl1cIjtcbiAgICAgICAgICAgIHNlcGFyYXRvciA9IG5ldyBSZWdFeHAoc2VwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlcGFyYXRvciA9IC9bXFwuXFwvXS87XG4gICAgICAgIH1cbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBldmUub25cbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEJpbmRzIGdpdmVuIGV2ZW50IGhhbmRsZXIgd2l0aCBhIGdpdmVuIG5hbWUuIFlvdSBjYW4gdXNlIHdpbGRjYXJkcyDigJxgKmDigJ0gZm9yIHRoZSBuYW1lczpcbiAgICAgfCBldmUub24oXCIqLnVuZGVyLipcIiwgZik7XG4gICAgIHwgZXZlKFwibW91c2UudW5kZXIuZmxvb3JcIik7IC8vIHRyaWdnZXJzIGZcbiAgICAgKiBVc2UgQGV2ZSB0byB0cmlnZ2VyIHRoZSBsaXN0ZW5lci5cbiAgICAgKipcbiAgICAgLSBuYW1lIChzdHJpbmcpIG5hbWUgb2YgdGhlIGV2ZW50LCBkb3QgKGAuYCkgb3Igc2xhc2ggKGAvYCkgc2VwYXJhdGVkLCB3aXRoIG9wdGlvbmFsIHdpbGRjYXJkc1xuICAgICAtIGYgKGZ1bmN0aW9uKSBldmVudCBoYW5kbGVyIGZ1bmN0aW9uXG4gICAgICoqXG4gICAgIC0gbmFtZSAoYXJyYXkpIGlmIHlvdSBkb27igJl0IHdhbnQgdG8gdXNlIHNlcGFyYXRvcnMsIHlvdSBjYW4gdXNlIGFycmF5IG9mIHN0cmluZ3NcbiAgICAgLSBmIChmdW5jdGlvbikgZXZlbnQgaGFuZGxlciBmdW5jdGlvblxuICAgICAqKlxuICAgICA9IChmdW5jdGlvbikgcmV0dXJuZWQgZnVuY3Rpb24gYWNjZXB0cyBhIHNpbmdsZSBudW1lcmljIHBhcmFtZXRlciB0aGF0IHJlcHJlc2VudHMgei1pbmRleCBvZiB0aGUgaGFuZGxlci4gSXQgaXMgYW4gb3B0aW9uYWwgZmVhdHVyZSBhbmQgb25seSB1c2VkIHdoZW4geW91IG5lZWQgdG8gZW5zdXJlIHRoYXQgc29tZSBzdWJzZXQgb2YgaGFuZGxlcnMgd2lsbCBiZSBpbnZva2VkIGluIGEgZ2l2ZW4gb3JkZXIsIGRlc3BpdGUgb2YgdGhlIG9yZGVyIG9mIGFzc2lnbm1lbnQuIFxuICAgICA+IEV4YW1wbGU6XG4gICAgIHwgZXZlLm9uKFwibW91c2VcIiwgZWF0SXQpKDIpO1xuICAgICB8IGV2ZS5vbihcIm1vdXNlXCIsIHNjcmVhbSk7XG4gICAgIHwgZXZlLm9uKFwibW91c2VcIiwgY2F0Y2hJdCkoMSk7XG4gICAgICogVGhpcyB3aWxsIGVuc3VyZSB0aGF0IGBjYXRjaEl0YCBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCBiZWZvcmUgYGVhdEl0YC5cbiAgICAgKlxuICAgICAqIElmIHlvdSB3YW50IHRvIHB1dCB5b3VyIGhhbmRsZXIgYmVmb3JlIG5vbi1pbmRleGVkIGhhbmRsZXJzLCBzcGVjaWZ5IGEgbmVnYXRpdmUgdmFsdWUuXG4gICAgICogTm90ZTogSSBhc3N1bWUgbW9zdCBvZiB0aGUgdGltZSB5b3UgZG9u4oCZdCBuZWVkIHRvIHdvcnJ5IGFib3V0IHotaW5kZXgsIGJ1dCBpdOKAmXMgbmljZSB0byBoYXZlIHRoaXMgZmVhdHVyZSDigJxqdXN0IGluIGNhc2XigJ0uXG4gICAgXFwqL1xuICAgIGV2ZS5vbiA9IGZ1bmN0aW9uIChuYW1lLCBmKSB7XG4gICAgICAgIGlmICh0eXBlb2YgZiAhPSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmFtZXMgPSBpc0FycmF5KG5hbWUpID8gKGlzQXJyYXkobmFtZVswXSkgPyBuYW1lIDogW25hbWVdKSA6IFN0cihuYW1lKS5zcGxpdChjb21hc2VwYXJhdG9yKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gbmFtZXMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICAgICAgdmFyIG5hbWVzID0gaXNBcnJheShuYW1lKSA/IG5hbWUgOiBTdHIobmFtZSkuc3BsaXQoc2VwYXJhdG9yKSxcbiAgICAgICAgICAgICAgICAgICAgZSA9IGV2ZW50cyxcbiAgICAgICAgICAgICAgICAgICAgZXhpc3Q7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gbmFtZXMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBlID0gZS5uO1xuICAgICAgICAgICAgICAgICAgICBlID0gZS5oYXNPd25Qcm9wZXJ0eShuYW1lc1tpXSkgJiYgZVtuYW1lc1tpXV0gfHwgKGVbbmFtZXNbaV1dID0ge246IHt9fSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGUuZiA9IGUuZiB8fCBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBpaSA9IGUuZi5sZW5ndGg7IGkgPCBpaTsgaSsrKSBpZiAoZS5mW2ldID09IGYpIHtcbiAgICAgICAgICAgICAgICAgICAgZXhpc3QgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgIWV4aXN0ICYmIGUuZi5wdXNoKGYpO1xuICAgICAgICAgICAgfShuYW1lc1tpXSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoekluZGV4KSB7XG4gICAgICAgICAgICBpZiAoK3pJbmRleCA9PSArekluZGV4KSB7XG4gICAgICAgICAgICAgICAgZi56SW5kZXggPSArekluZGV4O1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIGV2ZS5mXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBSZXR1cm5zIGZ1bmN0aW9uIHRoYXQgd2lsbCBmaXJlIGdpdmVuIGV2ZW50IHdpdGggb3B0aW9uYWwgYXJndW1lbnRzLlxuICAgICAqIEFyZ3VtZW50cyB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSByZXN1bHQgZnVuY3Rpb24gd2lsbCBiZSBhbHNvXG4gICAgICogY29uY2F0ZWQgdG8gdGhlIGxpc3Qgb2YgZmluYWwgYXJndW1lbnRzLlxuICAgICB8IGVsLm9uY2xpY2sgPSBldmUuZihcImNsaWNrXCIsIDEsIDIpO1xuICAgICB8IGV2ZS5vbihcImNsaWNrXCIsIGZ1bmN0aW9uIChhLCBiLCBjKSB7XG4gICAgIHwgICAgIGNvbnNvbGUubG9nKGEsIGIsIGMpOyAvLyAxLCAyLCBbZXZlbnQgb2JqZWN0XVxuICAgICB8IH0pO1xuICAgICA+IEFyZ3VtZW50c1xuICAgICAtIGV2ZW50IChzdHJpbmcpIGV2ZW50IG5hbWVcbiAgICAgLSB2YXJhcmdzICjigKYpIGFuZCBhbnkgb3RoZXIgYXJndW1lbnRzXG4gICAgID0gKGZ1bmN0aW9uKSBwb3NzaWJsZSBldmVudCBoYW5kbGVyIGZ1bmN0aW9uXG4gICAgXFwqL1xuICAgIGV2ZS5mID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIHZhciBhdHRycyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV2ZS5hcHBseShudWxsLCBbZXZlbnQsIG51bGxdLmNvbmNhdChhdHRycykuY29uY2F0KFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSkpO1xuICAgICAgICB9O1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIGV2ZS5zdG9wXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBJcyB1c2VkIGluc2lkZSBhbiBldmVudCBoYW5kbGVyIHRvIHN0b3AgdGhlIGV2ZW50LCBwcmV2ZW50aW5nIGFueSBzdWJzZXF1ZW50IGxpc3RlbmVycyBmcm9tIGZpcmluZy5cbiAgICBcXCovXG4gICAgZXZlLnN0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHN0b3AgPSAxO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIGV2ZS5udFxuICAgICBbIG1ldGhvZCBdXG4gICAgICoqXG4gICAgICogQ291bGQgYmUgdXNlZCBpbnNpZGUgZXZlbnQgaGFuZGxlciB0byBmaWd1cmUgb3V0IGFjdHVhbCBuYW1lIG9mIHRoZSBldmVudC5cbiAgICAgKipcbiAgICAgPiBBcmd1bWVudHNcbiAgICAgKipcbiAgICAgLSBzdWJuYW1lIChzdHJpbmcpICNvcHRpb25hbCBzdWJuYW1lIG9mIHRoZSBldmVudFxuICAgICAqKlxuICAgICA9IChzdHJpbmcpIG5hbWUgb2YgdGhlIGV2ZW50LCBpZiBgc3VibmFtZWAgaXMgbm90IHNwZWNpZmllZFxuICAgICAqIG9yXG4gICAgID0gKGJvb2xlYW4pIGB0cnVlYCwgaWYgY3VycmVudCBldmVudOKAmXMgbmFtZSBjb250YWlucyBgc3VibmFtZWBcbiAgICBcXCovXG4gICAgZXZlLm50ID0gZnVuY3Rpb24gKHN1Ym5hbWUpIHtcbiAgICAgICAgdmFyIGN1ciA9IGlzQXJyYXkoY3VycmVudF9ldmVudCkgPyBjdXJyZW50X2V2ZW50LmpvaW4oXCIuXCIpIDogY3VycmVudF9ldmVudDtcbiAgICAgICAgaWYgKHN1Ym5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVnRXhwKFwiKD86XFxcXC58XFxcXC98XilcIiArIHN1Ym5hbWUgKyBcIig/OlxcXFwufFxcXFwvfCQpXCIpLnRlc3QoY3VyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY3VyO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIGV2ZS5udHNcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIENvdWxkIGJlIHVzZWQgaW5zaWRlIGV2ZW50IGhhbmRsZXIgdG8gZmlndXJlIG91dCBhY3R1YWwgbmFtZSBvZiB0aGUgZXZlbnQuXG4gICAgICoqXG4gICAgICoqXG4gICAgID0gKGFycmF5KSBuYW1lcyBvZiB0aGUgZXZlbnRcbiAgICBcXCovXG4gICAgZXZlLm50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGlzQXJyYXkoY3VycmVudF9ldmVudCkgPyBjdXJyZW50X2V2ZW50IDogY3VycmVudF9ldmVudC5zcGxpdChzZXBhcmF0b3IpO1xuICAgIH07XG4gICAgLypcXFxuICAgICAqIGV2ZS5vZmZcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIFJlbW92ZXMgZ2l2ZW4gZnVuY3Rpb24gZnJvbSB0aGUgbGlzdCBvZiBldmVudCBsaXN0ZW5lcnMgYXNzaWduZWQgdG8gZ2l2ZW4gbmFtZS5cbiAgICAgKiBJZiBubyBhcmd1bWVudHMgc3BlY2lmaWVkIGFsbCB0aGUgZXZlbnRzIHdpbGwgYmUgY2xlYXJlZC5cbiAgICAgKipcbiAgICAgPiBBcmd1bWVudHNcbiAgICAgKipcbiAgICAgLSBuYW1lIChzdHJpbmcpIG5hbWUgb2YgdGhlIGV2ZW50LCBkb3QgKGAuYCkgb3Igc2xhc2ggKGAvYCkgc2VwYXJhdGVkLCB3aXRoIG9wdGlvbmFsIHdpbGRjYXJkc1xuICAgICAtIGYgKGZ1bmN0aW9uKSBldmVudCBoYW5kbGVyIGZ1bmN0aW9uXG4gICAgXFwqL1xuICAgIC8qXFxcbiAgICAgKiBldmUudW5iaW5kXG4gICAgIFsgbWV0aG9kIF1cbiAgICAgKipcbiAgICAgKiBTZWUgQGV2ZS5vZmZcbiAgICBcXCovXG4gICAgZXZlLm9mZiA9IGV2ZS51bmJpbmQgPSBmdW5jdGlvbiAobmFtZSwgZikge1xuICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIGV2ZS5fZXZlbnRzID0gZXZlbnRzID0ge246IHt9fTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmFtZXMgPSBpc0FycmF5KG5hbWUpID8gKGlzQXJyYXkobmFtZVswXSkgPyBuYW1lIDogW25hbWVdKSA6IFN0cihuYW1lKS5zcGxpdChjb21hc2VwYXJhdG9yKTtcbiAgICAgICAgaWYgKG5hbWVzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IG5hbWVzLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgICAgICAgICAgICBldmUub2ZmKG5hbWVzW2ldLCBmKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBuYW1lcyA9IGlzQXJyYXkobmFtZSkgPyBuYW1lIDogU3RyKG5hbWUpLnNwbGl0KHNlcGFyYXRvcik7XG4gICAgICAgIHZhciBlLFxuICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgc3BsaWNlLFxuICAgICAgICAgICAgaSwgaWksIGosIGpqLFxuICAgICAgICAgICAgY3VyID0gW2V2ZW50c107XG4gICAgICAgIGZvciAoaSA9IDAsIGlpID0gbmFtZXMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGN1ci5sZW5ndGg7IGogKz0gc3BsaWNlLmxlbmd0aCAtIDIpIHtcbiAgICAgICAgICAgICAgICBzcGxpY2UgPSBbaiwgMV07XG4gICAgICAgICAgICAgICAgZSA9IGN1cltqXS5uO1xuICAgICAgICAgICAgICAgIGlmIChuYW1lc1tpXSAhPSB3aWxkY2FyZCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZVtuYW1lc1tpXV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNwbGljZS5wdXNoKGVbbmFtZXNbaV1dKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoa2V5IGluIGUpIGlmIChlW2hhc10oa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3BsaWNlLnB1c2goZVtrZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjdXIuc3BsaWNlLmFwcGx5KGN1ciwgc3BsaWNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKGkgPSAwLCBpaSA9IGN1ci5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICAgICAgICBlID0gY3VyW2ldO1xuICAgICAgICAgICAgd2hpbGUgKGUubikge1xuICAgICAgICAgICAgICAgIGlmIChmKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlLmYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDAsIGpqID0gZS5mLmxlbmd0aDsgaiA8IGpqOyBqKyspIGlmIChlLmZbal0gPT0gZikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUuZi5zcGxpY2UoaiwgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAhZS5mLmxlbmd0aCAmJiBkZWxldGUgZS5mO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZvciAoa2V5IGluIGUubikgaWYgKGUubltoYXNdKGtleSkgJiYgZS5uW2tleV0uZikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZ1bmNzID0gZS5uW2tleV0uZjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDAsIGpqID0gZnVuY3MubGVuZ3RoOyBqIDwgamo7IGorKykgaWYgKGZ1bmNzW2pdID09IGYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jcy5zcGxpY2UoaiwgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAhZnVuY3MubGVuZ3RoICYmIGRlbGV0ZSBlLm5ba2V5XS5mO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGUuZjtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gZS5uKSBpZiAoZS5uW2hhc10oa2V5KSAmJiBlLm5ba2V5XS5mKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgZS5uW2tleV0uZjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlID0gZS5uO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICAvKlxcXG4gICAgICogZXZlLm9uY2VcbiAgICAgWyBtZXRob2QgXVxuICAgICAqKlxuICAgICAqIEJpbmRzIGdpdmVuIGV2ZW50IGhhbmRsZXIgd2l0aCBhIGdpdmVuIG5hbWUgdG8gb25seSBydW4gb25jZSB0aGVuIHVuYmluZCBpdHNlbGYuXG4gICAgIHwgZXZlLm9uY2UoXCJsb2dpblwiLCBmKTtcbiAgICAgfCBldmUoXCJsb2dpblwiKTsgLy8gdHJpZ2dlcnMgZlxuICAgICB8IGV2ZShcImxvZ2luXCIpOyAvLyBubyBsaXN0ZW5lcnNcbiAgICAgKiBVc2UgQGV2ZSB0byB0cmlnZ2VyIHRoZSBsaXN0ZW5lci5cbiAgICAgKipcbiAgICAgPiBBcmd1bWVudHNcbiAgICAgKipcbiAgICAgLSBuYW1lIChzdHJpbmcpIG5hbWUgb2YgdGhlIGV2ZW50LCBkb3QgKGAuYCkgb3Igc2xhc2ggKGAvYCkgc2VwYXJhdGVkLCB3aXRoIG9wdGlvbmFsIHdpbGRjYXJkc1xuICAgICAtIGYgKGZ1bmN0aW9uKSBldmVudCBoYW5kbGVyIGZ1bmN0aW9uXG4gICAgICoqXG4gICAgID0gKGZ1bmN0aW9uKSBzYW1lIHJldHVybiBmdW5jdGlvbiBhcyBAZXZlLm9uXG4gICAgXFwqL1xuICAgIGV2ZS5vbmNlID0gZnVuY3Rpb24gKG5hbWUsIGYpIHtcbiAgICAgICAgdmFyIGYyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXZlLm9mZihuYW1lLCBmMik7XG4gICAgICAgICAgICByZXR1cm4gZi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gZXZlLm9uKG5hbWUsIGYyKTtcbiAgICB9O1xuICAgIC8qXFxcbiAgICAgKiBldmUudmVyc2lvblxuICAgICBbIHByb3BlcnR5IChzdHJpbmcpIF1cbiAgICAgKipcbiAgICAgKiBDdXJyZW50IHZlcnNpb24gb2YgdGhlIGxpYnJhcnkuXG4gICAgXFwqL1xuICAgIGV2ZS52ZXJzaW9uID0gdmVyc2lvbjtcbiAgICBldmUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBcIllvdSBhcmUgcnVubmluZyBFdmUgXCIgKyB2ZXJzaW9uO1xuICAgIH07XG4gICAgKHR5cGVvZiBtb2R1bGUgIT0gXCJ1bmRlZmluZWRcIiAmJiBtb2R1bGUuZXhwb3J0cykgPyAobW9kdWxlLmV4cG9ydHMgPSBldmUpIDogKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kID8gKGRlZmluZShcImV2ZVwiLCBbXSwgZnVuY3Rpb24oKSB7IHJldHVybiBldmU7IH0pKSA6IChnbG9iLmV2ZSA9IGV2ZSkpO1xufSkodGhpcyk7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/eve-raphael/eve.js\n"); + +/***/ }) + +/******/ }); +}); \ No newline at end of file diff --git a/src/muya/lib/assets/libs/sequence-diagram.js b/src/muya/lib/assets/libs/sequence-diagram.js new file mode 100755 index 00000000..79fc2368 --- /dev/null +++ b/src/muya/lib/assets/libs/sequence-diagram.js @@ -0,0 +1,2698 @@ +/** js sequence diagrams 2.0.1 + * https://bramp.github.io/js-sequence-diagrams/ + * (c) 2012-2017 Andrew Brampton (bramp.net) + * @license Simplified BSD license. + */ +import _ from 'underscore' +import './raphael' +import './webFontLoader' + +function Diagram() { + this.title = undefined; + this.actors = []; + this.signals = []; +} +/* + * Return an existing actor with this alias, or creates a new one with alias and name. + */ +Diagram.prototype.getActor = function(alias, name) { + alias = alias.trim(); + + var i; + var actors = this.actors; + for (i in actors) { + if (actors[i].alias == alias) { + return actors[i]; + } + } + i = actors.push(new Diagram.Actor(alias, (name || alias), actors.length)); + return actors[ i - 1 ]; +}; + +/* + * Parses the input as either a alias, or a "name as alias", and returns the corresponding actor. + */ +Diagram.prototype.getActorWithAlias = function(input) { + input = input.trim(); + + // We are lazy and do some of the parsing in javascript :(. TODO move into the .jison file. + var s = /([\s\S]+) as (\S+)$/im.exec(input); + var alias; + var name; + if (s) { + name = s[1].trim(); + alias = s[2].trim(); + } else { + name = alias = input; + } + return this.getActor(alias, name); +}; + +Diagram.prototype.setTitle = function(title) { + this.title = title; +}; + +Diagram.prototype.addSignal = function(signal) { + this.signals.push(signal); +}; + +Diagram.Actor = function(alias, name, index) { + this.alias = alias; + this.name = name; + this.index = index; +}; + +Diagram.Signal = function(actorA, signaltype, actorB, message) { + this.type = 'Signal'; + this.actorA = actorA; + this.actorB = actorB; + this.linetype = signaltype & 3; + this.arrowtype = (signaltype >> 2) & 3; + this.message = message; +}; + +Diagram.Signal.prototype.isSelf = function() { + return this.actorA.index == this.actorB.index; +}; + +Diagram.Note = function(actor, placement, message) { + this.type = 'Note'; + this.actor = actor; + this.placement = placement; + this.message = message; + + if (this.hasManyActors() && actor[0] == actor[1]) { + throw new Error('Note should be over two different actors'); + } +}; + +Diagram.Note.prototype.hasManyActors = function() { + return _.isArray(this.actor); +}; + +Diagram.unescape = function(s) { + // Turn "\\n" into "\n" + return s.trim().replace(/^"(.*)"$/m, '$1').replace(/\\n/gm, '\n'); +}; + +Diagram.LINETYPE = { + SOLID: 0, + DOTTED: 1 +}; + +Diagram.ARROWTYPE = { + FILLED: 0, + OPEN: 1 +}; + +Diagram.PLACEMENT = { + LEFTOF: 0, + RIGHTOF: 1, + OVER: 2 +}; + +// Some older browsers don't have getPrototypeOf, thus we polyfill it +// https://github.com/bramp/js-sequence-diagrams/issues/57 +// https://github.com/zaach/jison/issues/194 +// Taken from http://ejohn.org/blog/objectgetprototypeof/ +if (typeof Object.getPrototypeOf !== 'function') { + /* jshint -W103 */ + if (typeof 'test'.__proto__ === 'object') { + Object.getPrototypeOf = function(object) { + return object.__proto__; + }; + } else { + Object.getPrototypeOf = function(object) { + // May break if the constructor has been tampered with + return object.constructor.prototype; + }; + } + /* jshint +W103 */ +} + +/** The following is included by preprocessor */ +/* parser generated by jison 0.4.15 */ +/* + Returns a Parser object of the following structure: + + Parser: { + yy: {} + } + + Parser.prototype: { + yy: {}, + trace: function(), + symbols_: {associative list: name ==> number}, + terminals_: {associative list: number ==> name}, + productions_: [...], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), + table: [...], + defaultActions: {...}, + parseError: function(str, hash), + parse: function(input), + + lexer: { + EOF: 1, + parseError: function(str, hash), + setInput: function(input), + input: function(), + unput: function(str), + more: function(), + less: function(n), + pastInput: function(), + upcomingInput: function(), + showPosition: function(), + test_match: function(regex_match_array, rule_index), + next: function(), + lex: function(), + begin: function(condition), + popState: function(), + _currentRules: function(), + topState: function(), + pushState: function(condition), + + options: { + ranges: boolean (optional: true ==> token location info will include a .range[] member) + flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) + backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) + }, + + performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), + rules: [...], + conditions: {associative list: name ==> set}, + } + } + + + token location info (@$, _$, etc.): { + first_line: n, + last_line: n, + first_column: n, + last_column: n, + range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) + } + + + the parseError function receives a 'hash' object with these members for lexer and parser errors: { + text: (matched text) + token: (the produced terminal token, if any) + line: (yylineno) + } + while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { + loc: (yylloc) + expected: (string describing the set of expected tokens) + recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) + } +*/ +var parser = function() { + function Parser() { + this.yy = {}; + } + var o = function(k, v, o, l) { + for (o = o || {}, l = k.length; l--; o[k[l]] = v) ; + return o; + }, $V0 = [ 5, 8, 9, 13, 15, 24 ], $V1 = [ 1, 13 ], $V2 = [ 1, 17 ], $V3 = [ 24, 29, 30 ], parser = { + trace: function() {}, + yy: {}, + symbols_: { + error: 2, + start: 3, + document: 4, + EOF: 5, + line: 6, + statement: 7, + NL: 8, + participant: 9, + actor_alias: 10, + signal: 11, + note_statement: 12, + title: 13, + message: 14, + note: 15, + placement: 16, + actor: 17, + over: 18, + actor_pair: 19, + ",": 20, + left_of: 21, + right_of: 22, + signaltype: 23, + ACTOR: 24, + linetype: 25, + arrowtype: 26, + LINE: 27, + DOTLINE: 28, + ARROW: 29, + OPENARROW: 30, + MESSAGE: 31, + $accept: 0, + $end: 1 + }, + terminals_: { + 2: "error", + 5: "EOF", + 8: "NL", + 9: "participant", + 13: "title", + 15: "note", + 18: "over", + 20: ",", + 21: "left_of", + 22: "right_of", + 24: "ACTOR", + 27: "LINE", + 28: "DOTLINE", + 29: "ARROW", + 30: "OPENARROW", + 31: "MESSAGE" + }, + productions_: [ 0, [ 3, 2 ], [ 4, 0 ], [ 4, 2 ], [ 6, 1 ], [ 6, 1 ], [ 7, 2 ], [ 7, 1 ], [ 7, 1 ], [ 7, 2 ], [ 12, 4 ], [ 12, 4 ], [ 19, 1 ], [ 19, 3 ], [ 16, 1 ], [ 16, 1 ], [ 11, 4 ], [ 17, 1 ], [ 10, 1 ], [ 23, 2 ], [ 23, 1 ], [ 25, 1 ], [ 25, 1 ], [ 26, 1 ], [ 26, 1 ], [ 14, 1 ] ], + performAction: function(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + /* this == yyval */ + var $0 = $$.length - 1; + switch (yystate) { + case 1: + return yy.parser.yy; + + case 4: + break; + + case 6: + $$[$0]; + break; + + case 7: + case 8: + yy.parser.yy.addSignal($$[$0]); + break; + + case 9: + yy.parser.yy.setTitle($$[$0]); + break; + + case 10: + this.$ = new Diagram.Note($$[$0 - 1], $$[$0 - 2], $$[$0]); + break; + + case 11: + this.$ = new Diagram.Note($$[$0 - 1], Diagram.PLACEMENT.OVER, $$[$0]); + break; + + case 12: + case 20: + this.$ = $$[$0]; + break; + + case 13: + this.$ = [ $$[$0 - 2], $$[$0] ]; + break; + + case 14: + this.$ = Diagram.PLACEMENT.LEFTOF; + break; + + case 15: + this.$ = Diagram.PLACEMENT.RIGHTOF; + break; + + case 16: + this.$ = new Diagram.Signal($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + + case 17: + this.$ = yy.parser.yy.getActor(Diagram.unescape($$[$0])); + break; + + case 18: + this.$ = yy.parser.yy.getActorWithAlias(Diagram.unescape($$[$0])); + break; + + case 19: + this.$ = $$[$0 - 1] | $$[$0] << 2; + break; + + case 21: + this.$ = Diagram.LINETYPE.SOLID; + break; + + case 22: + this.$ = Diagram.LINETYPE.DOTTED; + break; + + case 23: + this.$ = Diagram.ARROWTYPE.FILLED; + break; + + case 24: + this.$ = Diagram.ARROWTYPE.OPEN; + break; + + case 25: + this.$ = Diagram.unescape($$[$0].substring(1)); + } + }, + table: [ o($V0, [ 2, 2 ], { + 3: 1, + 4: 2 + }), { + 1: [ 3 ] + }, { + 5: [ 1, 3 ], + 6: 4, + 7: 5, + 8: [ 1, 6 ], + 9: [ 1, 7 ], + 11: 8, + 12: 9, + 13: [ 1, 10 ], + 15: [ 1, 12 ], + 17: 11, + 24: $V1 + }, { + 1: [ 2, 1 ] + }, o($V0, [ 2, 3 ]), o($V0, [ 2, 4 ]), o($V0, [ 2, 5 ]), { + 10: 14, + 24: [ 1, 15 ] + }, o($V0, [ 2, 7 ]), o($V0, [ 2, 8 ]), { + 14: 16, + 31: $V2 + }, { + 23: 18, + 25: 19, + 27: [ 1, 20 ], + 28: [ 1, 21 ] + }, { + 16: 22, + 18: [ 1, 23 ], + 21: [ 1, 24 ], + 22: [ 1, 25 ] + }, o([ 20, 27, 28, 31 ], [ 2, 17 ]), o($V0, [ 2, 6 ]), o($V0, [ 2, 18 ]), o($V0, [ 2, 9 ]), o($V0, [ 2, 25 ]), { + 17: 26, + 24: $V1 + }, { + 24: [ 2, 20 ], + 26: 27, + 29: [ 1, 28 ], + 30: [ 1, 29 ] + }, o($V3, [ 2, 21 ]), o($V3, [ 2, 22 ]), { + 17: 30, + 24: $V1 + }, { + 17: 32, + 19: 31, + 24: $V1 + }, { + 24: [ 2, 14 ] + }, { + 24: [ 2, 15 ] + }, { + 14: 33, + 31: $V2 + }, { + 24: [ 2, 19 ] + }, { + 24: [ 2, 23 ] + }, { + 24: [ 2, 24 ] + }, { + 14: 34, + 31: $V2 + }, { + 14: 35, + 31: $V2 + }, { + 20: [ 1, 36 ], + 31: [ 2, 12 ] + }, o($V0, [ 2, 16 ]), o($V0, [ 2, 10 ]), o($V0, [ 2, 11 ]), { + 17: 37, + 24: $V1 + }, { + 31: [ 2, 13 ] + } ], + defaultActions: { + 3: [ 2, 1 ], + 24: [ 2, 14 ], + 25: [ 2, 15 ], + 27: [ 2, 19 ], + 28: [ 2, 23 ], + 29: [ 2, 24 ], + 37: [ 2, 13 ] + }, + parseError: function(str, hash) { + if (!hash.recoverable) throw new Error(str); + this.trace(str); + }, + parse: function(input) { + function lex() { + var token; + return token = lexer.lex() || EOF, "number" != typeof token && (token = self.symbols_[token] || token), + token; + } + var self = this, stack = [ 0 ], vstack = [ null ], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1, args = lstack.slice.call(arguments, 1), lexer = Object.create(this.lexer), sharedState = { + yy: {} + }; + for (var k in this.yy) Object.prototype.hasOwnProperty.call(this.yy, k) && (sharedState.yy[k] = this.yy[k]); + lexer.setInput(input, sharedState.yy), sharedState.yy.lexer = lexer, sharedState.yy.parser = this, + "undefined" == typeof lexer.yylloc && (lexer.yylloc = {}); + var yyloc = lexer.yylloc; + lstack.push(yyloc); + var ranges = lexer.options && lexer.options.ranges; + "function" == typeof sharedState.yy.parseError ? this.parseError = sharedState.yy.parseError : this.parseError = Object.getPrototypeOf(this).parseError; + for (var symbol, preErrorSymbol, state, action, r, p, len, newState, expected, yyval = {}; ;) { + if (state = stack[stack.length - 1], this.defaultActions[state] ? action = this.defaultActions[state] : (null !== symbol && "undefined" != typeof symbol || (symbol = lex()), + action = table[state] && table[state][symbol]), "undefined" == typeof action || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) this.terminals_[p] && p > TERROR && expected.push("'" + this.terminals_[p] + "'"); + errStr = lexer.showPosition ? "Parse error on line " + (yylineno + 1) + ":\n" + lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'" : "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"), + this.parseError(errStr, { + text: lexer.match, + token: this.terminals_[symbol] || symbol, + line: lexer.yylineno, + loc: yyloc, + expected: expected + }); + } + 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: + stack.push(symbol), vstack.push(lexer.yytext), lstack.push(lexer.yylloc), stack.push(action[1]), + symbol = null, preErrorSymbol ? (symbol = preErrorSymbol, preErrorSymbol = null) : (yyleng = lexer.yyleng, + yytext = lexer.yytext, yylineno = lexer.yylineno, yyloc = lexer.yylloc, recovering > 0 && recovering--); + break; + + case 2: + if (len = this.productions_[action[1]][1], yyval.$ = vstack[vstack.length - len], + 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 + }, ranges && (yyval._$.range = [ lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1] ]), + r = this.performAction.apply(yyval, [ yytext, yyleng, yylineno, sharedState.yy, action[1], vstack, lstack ].concat(args)), + "undefined" != typeof r) return r; + 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]), + vstack.push(yyval.$), lstack.push(yyval._$), newState = table[stack[stack.length - 2]][stack[stack.length - 1]], + stack.push(newState); + break; + + case 3: + return !0; + } + } + return !0; + } + }, lexer = function() { + var lexer = { + EOF: 1, + parseError: function(str, hash) { + if (!this.yy.parser) throw new Error(str); + this.yy.parser.parseError(str, hash); + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + return this.yy = yy || this.yy || {}, this._input = input, this._more = this._backtrack = this.done = !1, + 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 + }, this.options.ranges && (this.yylloc.range = [ 0, 0 ]), this.offset = 0, this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch, this.yyleng++, this.offset++, this.match += ch, this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + return lines ? (this.yylineno++, this.yylloc.last_line++) : this.yylloc.last_column++, + this.options.ranges && this.yylloc.range[1]++, this._input = this._input.slice(1), + ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length, lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input, this.yytext = this.yytext.substr(0, this.yytext.length - len), + //this.yyleng -= len; + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1), this.matched = this.matched.substr(0, this.matched.length - 1), + lines.length - 1 && (this.yylineno -= lines.length - 1); + var r = this.yylloc.range; + return this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }, this.options.ranges && (this.yylloc.range = [ r[0], r[0] + this.yyleng - len ]), + this.yyleng = this.yytext.length, this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + return this._more = !0, this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + return this.options.backtrack_lexer ? (this._backtrack = !0, this) : this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + return next.length < 20 && (next += this._input.substr(0, 20 - next.length)), (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(), c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer && (// save context + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }, this.options.ranges && (backup.yylloc.range = this.yylloc.range.slice(0))), lines = match[0].match(/(?:\r\n?|\n).*/g), + 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 - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }, this.yytext += match[0], this.match += match[0], this.matches = match, this.yyleng = this.yytext.length, + this.options.ranges && (this.yylloc.range = [ this.offset, this.offset += this.yyleng ]), + this._more = !1, this._backtrack = !1, this._input = this._input.slice(match[0].length), + this.matched += match[0], token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]), + this.done && this._input && (this.done = !1), token) return token; + if (this._backtrack) { + // recover context + for (var k in backup) this[k] = backup[k]; + return !1; + } + return !1; + }, + // return next match in input + next: function() { + if (this.done) return this.EOF; + this._input || (this.done = !0); + var token, match, tempMatch, index; + this._more || (this.yytext = "", this.match = ""); + for (var rules = this._currentRules(), i = 0; i < rules.length; i++) if (tempMatch = this._input.match(this.rules[rules[i]]), + tempMatch && (!match || tempMatch[0].length > match[0].length)) { + if (match = tempMatch, index = i, this.options.backtrack_lexer) { + if (token = this.test_match(tempMatch, rules[i]), token !== !1) return token; + if (this._backtrack) { + match = !1; + continue; + } + // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) + return !1; + } + if (!this.options.flex) break; + } + return match ? (token = this.test_match(match, rules[index]), token !== !1 && token) : "" === this._input ? this.EOF : this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + }, + // return next match that has a token + lex: function() { + var r = this.next(); + return r ? r : this.lex(); + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function() { + var n = this.conditionStack.length - 1; + return n > 0 ? this.conditionStack.pop() : this.conditionStack[0]; + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function() { + return this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1] ? this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules : this.conditions.INITIAL.rules; + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function(n) { + return n = this.conditionStack.length - 1 - Math.abs(n || 0), n >= 0 ? this.conditionStack[n] : "INITIAL"; + }, + // alias for begin(condition) + pushState: function(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function() { + return this.conditionStack.length; + }, + options: { + "case-insensitive": !0 + }, + performAction: function(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 8; + + case 1: + /* skip whitespace */ + break; + + case 2: + /* skip comments */ + break; + + case 3: + return 9; + + case 4: + return 21; + + case 5: + return 22; + + case 6: + return 18; + + case 7: + return 15; + + case 8: + return 13; + + case 9: + return 20; + + case 10: + return 24; + + case 11: + return 24; + + case 12: + return 28; + + case 13: + return 27; + + case 14: + return 30; + + case 15: + return 29; + + case 16: + return 31; + + case 17: + return 5; + + case 18: + return "INVALID"; + } + }, + rules: [ /^(?:[\r\n]+)/i, /^(?:\s+)/i, /^(?:#[^\r\n]*)/i, /^(?:participant\b)/i, /^(?:left of\b)/i, /^(?:right of\b)/i, /^(?:over\b)/i, /^(?:note\b)/i, /^(?:title\b)/i, /^(?:,)/i, /^(?:[^\->:,\r\n"]+)/i, /^(?:"[^"]+")/i, /^(?:--)/i, /^(?:-)/i, /^(?:>>)/i, /^(?:>)/i, /^(?:[^\r\n]+)/i, /^(?:$)/i, /^(?:.)/i ], + conditions: { + INITIAL: { + rules: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 ], + inclusive: !0 + } + } + }; + return lexer; + }(); + return parser.lexer = lexer, Parser.prototype = parser, parser.Parser = Parser, + new Parser(); +}(); + +"undefined" != typeof require && "undefined" != typeof exports && (exports.parser = parser, +exports.Parser = parser.Parser, exports.parse = function() { + return parser.parse.apply(parser, arguments); +}, exports.main = function(args) { + args[1] || (console.log("Usage: " + args[0] + " FILE"), process.exit(1)); + var source = require("fs").readFileSync(require("path").normalize(args[1]), "utf8"); + return exports.parser.parse(source); +}, "undefined" != typeof module && require.main === module && exports.main(process.argv.slice(1))); +/** + * jison doesn't have a good exception, so we make one. + * This is brittle as it depends on jison internals + */ +function ParseError(message, hash) { + _.extend(this, hash); + + this.name = 'ParseError'; + this.message = (message || ''); +} +ParseError.prototype = new Error(); +Diagram.ParseError = ParseError; + +Diagram.parse = function(input) { + // TODO jison v0.4.17 changed their API slightly, so parser is no longer defined: + + // Create the object to track state and deal with errors + parser.yy = new Diagram(); + parser.yy.parseError = function(message, hash) { + throw new ParseError(message, hash); + }; + + // Parse + var diagram = parser.parse(input); + + // Then clean up the parseError key that a user won't care about + delete diagram.parseError; + return diagram; +}; + + +/** js sequence diagrams + * https://bramp.github.io/js-sequence-diagrams/ + * (c) 2012-2017 Andrew Brampton (bramp.net) + * Simplified BSD license. + */ +/*global Diagram, _ */ + +// Following the CSS convention +// Margin is the gap outside the box +// Padding is the gap inside the box +// Each object has x/y/width/height properties +// The x/y should be top left corner +// width/height is with both margin and padding + +// TODO +// Image width is wrong, when there is a note in the right hand col +// Title box could look better +// Note box could look better + +var DIAGRAM_MARGIN = 10; + +var ACTOR_MARGIN = 10; // Margin around a actor +var ACTOR_PADDING = 10; // Padding inside a actor + +var SIGNAL_MARGIN = 5; // Margin around a signal +var SIGNAL_PADDING = 5; // Padding inside a signal + +var NOTE_MARGIN = 10; // Margin around a note +var NOTE_PADDING = 5; // Padding inside a note +var NOTE_OVERLAP = 15; // Overlap when using a "note over A,B" + +var TITLE_MARGIN = 0; +var TITLE_PADDING = 5; + +var SELF_SIGNAL_WIDTH = 20; // How far out a self signal goes + +var PLACEMENT = Diagram.PLACEMENT; +var LINETYPE = Diagram.LINETYPE; +var ARROWTYPE = Diagram.ARROWTYPE; + +var ALIGN_LEFT = 0; +var ALIGN_CENTER = 1; + +function AssertException(message) { this.message = message; } +AssertException.prototype.toString = function() { + return 'AssertException: ' + this.message; +}; + +function assert(exp, message) { + if (!exp) { + throw new AssertException(message); + } +} + +if (!String.prototype.trim) { + String.prototype.trim = function() { + return this.replace(/^\s+|\s+$/g, ''); + }; +} + +Diagram.themes = {}; +function registerTheme(name, theme) { + Diagram.themes[name] = theme; +} + +/****************** + * Drawing extras + ******************/ + +function getCenterX(box) { + return box.x + box.width / 2; +} + +function getCenterY(box) { + return box.y + box.height / 2; +} + +/****************** + * SVG Path extras + ******************/ + +function clamp(x, min, max) { + if (x < min) { + return min; + } + if (x > max) { + return max; + } + return x; +} + +function wobble(x1, y1, x2, y2) { + assert(_.every([x1,x2,y1,y2], _.isFinite), 'x1,x2,y1,y2 must be numeric'); + + // Wobble no more than 1/25 of the line length + var factor = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) / 25; + + // Distance along line where the control points are + // Clamp between 20% and 80% so any arrow heads aren't angled too much + var r1 = clamp(Math.random(), 0.2, 0.8); + var r2 = clamp(Math.random(), 0.2, 0.8); + + var xfactor = Math.random() > 0.5 ? factor : -factor; + var yfactor = Math.random() > 0.5 ? factor : -factor; + + var p1 = { + x: (x2 - x1) * r1 + x1 + xfactor, + y: (y2 - y1) * r1 + y1 + yfactor + }; + + var p2 = { + x: (x2 - x1) * r2 + x1 - xfactor, + y: (y2 - y1) * r2 + y1 - yfactor + }; + + return 'C' + p1.x.toFixed(1) + ',' + p1.y.toFixed(1) + // start control point + ' ' + p2.x.toFixed(1) + ',' + p2.y.toFixed(1) + // end control point + ' ' + x2.toFixed(1) + ',' + y2.toFixed(1); // end point +} + +/** + * Draws a wobbly (hand drawn) rect + */ +function handRect(x, y, w, h) { + assert(_.every([x, y, w, h], _.isFinite), 'x, y, w, h must be numeric'); + return 'M' + x + ',' + y + + wobble(x, y, x + w, y) + + wobble(x + w, y, x + w, y + h) + + wobble(x + w, y + h, x, y + h) + + wobble(x, y + h, x, y); +} + +/** + * Draws a wobbly (hand drawn) line + */ +function handLine(x1, y1, x2, y2) { + assert(_.every([x1,x2,y1,y2], _.isFinite), 'x1,x2,y1,y2 must be numeric'); + return 'M' + x1.toFixed(1) + ',' + y1.toFixed(1) + wobble(x1, y1, x2, y2); +} + +/****************** + * BaseTheme + ******************/ + +var BaseTheme = function(diagram, options) { + this.init(diagram, options); +}; + +_.extend(BaseTheme.prototype, { + + // Init called while creating the Theme + init: function(diagram, options) { + this.diagram = diagram; + + this.actorsHeight_ = 0; + this.signalsHeight_ = 0; + this.title_ = undefined; // hack - This should be somewhere better + }, + + setupPaper: function(container) {}, + + draw: function(container) { + this.setupPaper(container); + + this.layout(); + + var titleHeight = this.title_ ? this.title_.height : 0; + var y = DIAGRAM_MARGIN + titleHeight; + + this.drawTitle(); + this.drawActors(y); + this.drawSignals(y + this.actorsHeight_); + }, + + layout: function() { + // Local copies + var diagram = this.diagram; + var font = this.font_; + var actors = diagram.actors; + var signals = diagram.signals; + + diagram.width = 0; // min width + diagram.height = 0; // min height + + // Setup some layout stuff + if (diagram.title) { + var title = this.title_ = {}; + var bb = this.textBBox(diagram.title, font); + title.textBB = bb; + title.message = diagram.title; + + title.width = bb.width + (TITLE_PADDING + TITLE_MARGIN) * 2; + title.height = bb.height + (TITLE_PADDING + TITLE_MARGIN) * 2; + title.x = DIAGRAM_MARGIN; + title.y = DIAGRAM_MARGIN; + + diagram.width += title.width; + diagram.height += title.height; + } + + _.each(actors, _.bind(function(a) { + var bb = this.textBBox(a.name, font); + a.textBB = bb; + + a.x = 0; a.y = 0; + a.width = bb.width + (ACTOR_PADDING + ACTOR_MARGIN) * 2; + a.height = bb.height + (ACTOR_PADDING + ACTOR_MARGIN) * 2; + + a.distances = []; + a.paddingRight = 0; + this.actorsHeight_ = Math.max(a.height, this.actorsHeight_); + }, this)); + + function actorEnsureDistance(a, b, d) { + assert(a < b, 'a must be less than or equal to b'); + + if (a < 0) { + // Ensure b has left margin + b = actors[b]; + b.x = Math.max(d - b.width / 2, b.x); + } else if (b >= actors.length) { + // Ensure a has right margin + a = actors[a]; + a.paddingRight = Math.max(d, a.paddingRight); + } else { + a = actors[a]; + a.distances[b] = Math.max(d, a.distances[b] ? a.distances[b] : 0); + } + } + + _.each(signals, _.bind(function(s) { + // Indexes of the left and right actors involved + var a; + var b; + + var bb = this.textBBox(s.message, font); + + s.textBB = bb; + s.width = bb.width; + s.height = bb.height; + + var extraWidth = 0; + + if (s.type == 'Signal') { + + s.width += (SIGNAL_MARGIN + SIGNAL_PADDING) * 2; + s.height += (SIGNAL_MARGIN + SIGNAL_PADDING) * 2; + + if (s.isSelf()) { + // TODO Self signals need a min height + a = s.actorA.index; + b = a + 1; + s.width += SELF_SIGNAL_WIDTH; + } else { + a = Math.min(s.actorA.index, s.actorB.index); + b = Math.max(s.actorA.index, s.actorB.index); + } + + } else if (s.type == 'Note') { + s.width += (NOTE_MARGIN + NOTE_PADDING) * 2; + s.height += (NOTE_MARGIN + NOTE_PADDING) * 2; + + // HACK lets include the actor's padding + extraWidth = 2 * ACTOR_MARGIN; + + if (s.placement == PLACEMENT.LEFTOF) { + b = s.actor.index; + a = b - 1; + } else if (s.placement == PLACEMENT.RIGHTOF) { + a = s.actor.index; + b = a + 1; + } else if (s.placement == PLACEMENT.OVER && s.hasManyActors()) { + // Over multiple actors + a = Math.min(s.actor[0].index, s.actor[1].index); + b = Math.max(s.actor[0].index, s.actor[1].index); + + // We don't need our padding, and we want to overlap + extraWidth = -(NOTE_PADDING * 2 + NOTE_OVERLAP * 2); + + } else if (s.placement == PLACEMENT.OVER) { + // Over single actor + a = s.actor.index; + actorEnsureDistance(a - 1, a, s.width / 2); + actorEnsureDistance(a, a + 1, s.width / 2); + this.signalsHeight_ += s.height; + + return; // Bail out early + } + } else { + throw new Error('Unhandled signal type:' + s.type); + } + + actorEnsureDistance(a, b, s.width + extraWidth); + this.signalsHeight_ += s.height; + }, this)); + + // Re-jig the positions + var actorsX = 0; + _.each(actors, function(a) { + a.x = Math.max(actorsX, a.x); + + // TODO This only works if we loop in sequence, 0, 1, 2, etc + _.each(a.distances, function(distance, b) { + // lodash (and possibly others) do not like sparse arrays + // so sometimes they return undefined + if (typeof distance == 'undefined') { + return; + } + + b = actors[b]; + distance = Math.max(distance, a.width / 2, b.width / 2); + b.x = Math.max(b.x, a.x + a.width / 2 + distance - b.width / 2); + }); + + actorsX = a.x + a.width + a.paddingRight; + }); + + diagram.width = Math.max(actorsX, diagram.width); + + // TODO Refactor a little + diagram.width += 2 * DIAGRAM_MARGIN; + diagram.height += 2 * DIAGRAM_MARGIN + 2 * this.actorsHeight_ + this.signalsHeight_; + + return this; + }, + + // TODO Instead of one textBBox function, create a function for each element type, e.g + // layout_title, layout_actor, etc that returns it's bounding box + textBBox: function(text, font) {}, + + drawTitle: function() { + var title = this.title_; + if (title) { + this.drawTextBox(title, title.message, TITLE_MARGIN, TITLE_PADDING, this.font_, ALIGN_LEFT); + } + }, + + drawActors: function(offsetY) { + var y = offsetY; + _.each(this.diagram.actors, _.bind(function(a) { + // Top box + this.drawActor(a, y, this.actorsHeight_); + + // Bottom box + this.drawActor(a, y + this.actorsHeight_ + this.signalsHeight_, this.actorsHeight_); + + // Veritical line + var aX = getCenterX(a); + this.drawLine( + aX, y + this.actorsHeight_ - ACTOR_MARGIN, + aX, y + this.actorsHeight_ + ACTOR_MARGIN + this.signalsHeight_); + }, this)); + }, + + drawActor: function(actor, offsetY, height) { + actor.y = offsetY; + actor.height = height; + this.drawTextBox(actor, actor.name, ACTOR_MARGIN, ACTOR_PADDING, this.font_, ALIGN_CENTER); + }, + + drawSignals: function(offsetY) { + var y = offsetY; + _.each(this.diagram.signals, _.bind(function(s) { + // TODO Add debug mode, that draws padding/margin box + if (s.type == 'Signal') { + if (s.isSelf()) { + this.drawSelfSignal(s, y); + } else { + this.drawSignal(s, y); + } + + } else if (s.type == 'Note') { + this.drawNote(s, y); + } + + y += s.height; + }, this)); + }, + + drawSelfSignal: function(signal, offsetY) { + assert(signal.isSelf(), 'signal must be a self signal'); + + var textBB = signal.textBB; + var aX = getCenterX(signal.actorA); + + var x = aX + SELF_SIGNAL_WIDTH + SIGNAL_PADDING; + var y = offsetY + SIGNAL_PADDING + signal.height / 2 + textBB.y; + + this.drawText(x, y, signal.message, this.font_, ALIGN_LEFT); + + var y1 = offsetY + SIGNAL_MARGIN + SIGNAL_PADDING; + var y2 = y1 + signal.height - 2 * SIGNAL_MARGIN - SIGNAL_PADDING; + + // Draw three lines, the last one with a arrow + this.drawLine(aX, y1, aX + SELF_SIGNAL_WIDTH, y1, signal.linetype); + this.drawLine(aX + SELF_SIGNAL_WIDTH, y1, aX + SELF_SIGNAL_WIDTH, y2, signal.linetype); + this.drawLine(aX + SELF_SIGNAL_WIDTH, y2, aX, y2, signal.linetype, signal.arrowtype); + }, + + drawSignal: function(signal, offsetY) { + var aX = getCenterX(signal.actorA); + var bX = getCenterX(signal.actorB); + + // Mid point between actors + var x = (bX - aX) / 2 + aX; + var y = offsetY + SIGNAL_MARGIN + 2 * SIGNAL_PADDING; + + // Draw the text in the middle of the signal + this.drawText(x, y, signal.message, this.font_, ALIGN_CENTER); + + // Draw the line along the bottom of the signal + y = offsetY + signal.height - SIGNAL_MARGIN - SIGNAL_PADDING; + this.drawLine(aX, y, bX, y, signal.linetype, signal.arrowtype); + }, + + drawNote: function(note, offsetY) { + note.y = offsetY; + var actorA = note.hasManyActors() ? note.actor[0] : note.actor; + var aX = getCenterX(actorA); + switch (note.placement) { + case PLACEMENT.RIGHTOF: + note.x = aX + ACTOR_MARGIN; + break; + case PLACEMENT.LEFTOF: + note.x = aX - ACTOR_MARGIN - note.width; + break; + case PLACEMENT.OVER: + if (note.hasManyActors()) { + var bX = getCenterX(note.actor[1]); + var overlap = NOTE_OVERLAP + NOTE_PADDING; + note.x = Math.min(aX, bX) - overlap; + note.width = (Math.max(aX, bX) + overlap) - note.x; + } else { + note.x = aX - note.width / 2; + } + break; + default: + throw new Error('Unhandled note placement: ' + note.placement); + } + return this.drawTextBox(note, note.message, NOTE_MARGIN, NOTE_PADDING, this.font_, ALIGN_LEFT); + }, + + /** + * Draw text surrounded by a box + */ + drawTextBox: function(box, text, margin, padding, font, align) { + var x = box.x + margin; + var y = box.y + margin; + var w = box.width - 2 * margin; + var h = box.height - 2 * margin; + + // Draw inner box + this.drawRect(x, y, w, h); + + // Draw text (in the center) + if (align == ALIGN_CENTER) { + x = getCenterX(box); + y = getCenterY(box); + } else { + x += padding; + y += padding; + } + + return this.drawText(x, y, text, font, align); + } +}); + +/** js sequence diagrams + * https://bramp.github.io/js-sequence-diagrams/ + * (c) 2012-2017 Andrew Brampton (bramp.net) + * Simplified BSD license. + */ +/*global Diagram, Snap, WebFont _ */ +// TODO Move defintion of font onto the <svg>, so it can easily be override at each level +if (typeof Snap != 'undefined') { + + var xmlns = 'http://www.w3.org/2000/svg'; + + var LINE = { + 'stroke': '#000000', + 'stroke-width': 2, // BUG TODO This gets set as a style, not as a attribute. Look at eve.on("snap.util.attr"... + 'fill': 'none' + }; + + var RECT = { + 'stroke': '#000000', + 'stroke-width': 2, + 'fill': '#fff' + }; + + var LOADED_FONTS = {}; + + /****************** + * SnapTheme + ******************/ + + var SnapTheme = function(diagram, options, resume) { + _.defaults(options, { + 'css-class': 'simple', + 'font-size': 16, + 'font-family': 'Andale Mono, monospace' + }); + + this.init(diagram, options, resume); + }; + + _.extend(SnapTheme.prototype, BaseTheme.prototype, { + + init: function(diagram, options, resume) { + BaseTheme.prototype.init.call(this, diagram); + + this.paper_ = undefined; + this.cssClass_ = options['css-class'] || undefined; + this.font_ = { + 'font-size': options['font-size'], + 'font-family': options['font-family'] + }; + + var a = this.arrowTypes_ = {}; + a[ARROWTYPE.FILLED] = 'Block'; + a[ARROWTYPE.OPEN] = 'Open'; + + var l = this.lineTypes_ = {}; + l[LINETYPE.SOLID] = ''; + l[LINETYPE.DOTTED] = '6,2'; + + var that = this; + this.waitForFont(function() { + resume(that); + }); + }, + + // Wait for loading of the font + waitForFont: function(callback) { + var fontFamily = this.font_['font-family']; + + if (typeof WebFont == 'undefined') { + throw new Error('WebFont is required (https://github.com/typekit/webfontloader).'); + } + + if (LOADED_FONTS[fontFamily]) { + // If already loaded, just return instantly. + callback(); + return; + } + + WebFont.load({ + custom: { + families: [fontFamily] // TODO replace this with something that reads the css + }, + classes: false, // No need to place classes on the DOM, just use JS Events + active: function() { + LOADED_FONTS[fontFamily] = true; + callback(); + }, + inactive: function() { + // If we fail to fetch the font, still continue. + LOADED_FONTS[fontFamily] = true; + callback(); + } + }); + }, + + addDescription: function(svg, description) { + var desc = document.createElementNS(xmlns, 'desc'); + desc.appendChild(document.createTextNode(description)); + svg.appendChild(desc); + }, + + setupPaper: function(container) { + // Container must be a SVG element. We assume it's a div, so lets create a SVG and insert + var svg = document.createElementNS(xmlns, 'svg'); + container.appendChild(svg); + + this.addDescription(svg, this.diagram.title || ''); + + this.paper_ = Snap(svg); + this.paper_.addClass('sequence'); + + if (this.cssClass_) { + this.paper_.addClass(this.cssClass_); + } + + this.beginGroup(); + + // TODO Perhaps only include the markers if we actually use them. + var a = this.arrowMarkers_ = {}; + var arrow = this.paper_.path('M 0 0 L 5 2.5 L 0 5 z'); + a[ARROWTYPE.FILLED] = arrow.marker(0, 0, 5, 5, 5, 2.5) + .attr({id: 'markerArrowBlock'}); + + arrow = this.paper_.path('M 9.6,8 1.92,16 0,13.7 5.76,8 0,2.286 1.92,0 9.6,8 z'); + a[ARROWTYPE.OPEN] = arrow.marker(0, 0, 9.6, 16, 9.6, 8) + .attr({markerWidth: '4', id: 'markerArrowOpen'}); + }, + + layout: function() { + BaseTheme.prototype.layout.call(this); + this.paper_.attr({ + width: this.diagram.width + 'px', + height: this.diagram.height + 'px' + }); + }, + + textBBox: function(text, font) { + // TODO getBBox will return the bounds with any whitespace/kerning. This makes some of our aligments screwed up + var t = this.createText(text, font); + var bb = t.getBBox(); + t.remove(); + return bb; + }, + + // For each drawn element, push onto the stack, so it can be wrapped in a single outer element + pushToStack: function(element) { + this._stack.push(element); + return element; + }, + + // Begin a group of elements + beginGroup: function() { + this._stack = []; + }, + + // Finishes the group, and returns the <group> element + finishGroup: function() { + var g = this.paper_.group.apply(this.paper_, this._stack); + this.beginGroup(); // Reset the group + return g; + }, + + createText: function(text, font) { + text = text.split('\n').map(function(x) { + return x.trim(); + }); + var t = this.paper_.text(0, 0, text); + t.attr(font || {}); + if (text.length > 1) { + // Every row after the first, set tspan to be 1.2em below the previous line + t.selectAll('tspan:nth-child(n+2)').attr({ + dy: '1.2em', + x: 0 + }); + } + + return t; + }, + + drawLine: function(x1, y1, x2, y2, linetype, arrowhead) { + var line = this.paper_.line(x1, y1, x2, y2).attr(LINE); + if (linetype !== undefined) { + line.attr('strokeDasharray', this.lineTypes_[linetype]); + } + if (arrowhead !== undefined) { + line.attr('markerEnd', this.arrowMarkers_[arrowhead]); + } + return this.pushToStack(line); + }, + + drawRect: function(x, y, w, h) { + var rect = this.paper_.rect(x, y, w, h).attr(RECT); + return this.pushToStack(rect); + }, + + /** + * Draws text with a optional white background + * x,y (int) x,y top left point of the text, or the center of the text (depending on align param) + * text (string) text to print + * font (Object) + * align (string) ALIGN_LEFT or ALIGN_CENTER + */ + drawText: function(x, y, text, font, align) { + var t = this.createText(text, font); + var bb = t.getBBox(); + + if (align == ALIGN_CENTER) { + x = x - bb.width / 2; + y = y - bb.height / 2; + } + + // Now move the text into place + // `y - bb.y` because text(..) is positioned from the baseline, so this moves it down. + t.attr({x: x - bb.x, y: y - bb.y}); + t.selectAll('tspan').attr({x: x}); + + this.pushToStack(t); + return t; + }, + + drawTitle: function() { + this.beginGroup(); + BaseTheme.prototype.drawTitle.call(this); + return this.finishGroup().addClass('title'); + }, + + drawActor: function(actor, offsetY, height) { + this.beginGroup(); + BaseTheme.prototype.drawActor.call(this, actor, offsetY, height); + return this.finishGroup().addClass('actor'); + }, + + drawSignal: function(signal, offsetY) { + this.beginGroup(); + BaseTheme.prototype.drawSignal.call(this, signal, offsetY); + return this.finishGroup().addClass('signal'); + }, + + drawSelfSignal: function(signal, offsetY) { + this.beginGroup(); + BaseTheme.prototype.drawSelfSignal.call(this, signal, offsetY); + return this.finishGroup().addClass('signal'); + }, + + drawNote: function(note, offsetY) { + this.beginGroup(); + BaseTheme.prototype.drawNote.call(this, note, offsetY); + return this.finishGroup().addClass('note'); + }, + }); + + /****************** + * SnapHandTheme + ******************/ + + var SnapHandTheme = function(diagram, options, resume) { + _.defaults(options, { + 'css-class': 'hand', + 'font-size': 16, + 'font-family': 'danielbd' + }); + + this.init(diagram, options, resume); + }; + + // Take the standard SnapTheme and make all the lines wobbly + _.extend(SnapHandTheme.prototype, SnapTheme.prototype, { + drawLine: function(x1, y1, x2, y2, linetype, arrowhead) { + var line = this.paper_.path(handLine(x1, y1, x2, y2)).attr(LINE); + if (linetype !== undefined) { + line.attr('strokeDasharray', this.lineTypes_[linetype]); + } + if (arrowhead !== undefined) { + line.attr('markerEnd', this.arrowMarkers_[arrowhead]); + } + return this.pushToStack(line); + }, + + drawRect: function(x, y, w, h) { + var rect = this.paper_.path(handRect(x, y, w, h)).attr(RECT); + return this.pushToStack(rect); + } + }); + + registerTheme('snapSimple', SnapTheme); + registerTheme('snapHand', SnapHandTheme); +} + +/** js sequence diagrams + * https://bramp.github.io/js-sequence-diagrams/ + * (c) 2012-2017 Andrew Brampton (bramp.net) + * Simplified BSD license. + */ +/*global Diagram, Raphael, _ */ + +if (typeof Raphael != 'undefined') { + + var LINE = { + 'stroke': '#000000', + 'stroke-width': 2, + 'fill': 'none' + }; + + var RECT = { + 'stroke': '#000000', + 'stroke-width': 2, + 'fill': '#fff' + }; + + /****************** + * Raphaël extras + ******************/ + Raphael.fn.line = function(x1, y1, x2, y2) { + assert(_.every([x1,x2,y1,y2], _.isFinite), 'x1,x2,y1,y2 must be numeric'); + return this.path('M{0},{1} L{2},{3}', x1, y1, x2, y2); + }; + + /****************** + * RaphaelTheme + ******************/ + + var RaphaelTheme = function(diagram, options, resume) { + this.init(diagram, _.defaults(options, { + 'font-size': 16, + 'font-family': 'Andale Mono, monospace' + }), resume); + }; + + _.extend(RaphaelTheme.prototype, BaseTheme.prototype, { + + init: function(diagram, options, resume) { + BaseTheme.prototype.init.call(this, diagram); + + this.paper_ = undefined; + this.font_ = { + 'font-size': options['font-size'], + 'font-family': options['font-family'] + }; + + var a = this.arrowTypes_ = {}; + a[ARROWTYPE.FILLED] = 'block'; + a[ARROWTYPE.OPEN] = 'open'; + + var l = this.lineTypes_ = {}; + l[LINETYPE.SOLID] = ''; + l[LINETYPE.DOTTED] = '-'; + + resume(this); + }, + + setupPaper: function(container) { + this.paper_ = new Raphael(container, 320, 200); + this.paper_.setStart(); + }, + + draw: function(container) { + BaseTheme.prototype.draw.call(this, container); + this.paper_.setFinish(); + }, + + layout: function() { + BaseTheme.prototype.layout.call(this); + this.paper_.setSize( + this.diagram.width, + this.diagram.height + ); + }, + + /** + * Strip whitespace from each newline + */ + cleanText: function(text) { + return text.split('\n').map(function(x) { + return x.trim(); + }).join('\n'); + }, + + /** + * Returns the text's bounding box + */ + textBBox: function(text, font) { + text = this.cleanText(text); + font = font || {}; + var p; + if (font.obj_) { + p = this.paper_.print(0, 0, text, font.obj_, font['font-size']); + } else { + p = this.paper_.text(0, 0, text); + p.attr(font); + } + + var bb = p.getBBox(); + p.remove(); + + return bb; + }, + + drawLine: function(x1, y1, x2, y2, linetype, arrowhead) { + var line = this.paper_.line(x1, y1, x2, y2).attr(LINE); + if (arrowhead !== undefined) { + line.attr('arrow-end', this.arrowTypes_[arrowhead] + '-wide-long'); + } + if (arrowhead !== undefined) { + line.attr('stroke-dasharray', this.lineTypes_[linetype]); + } + return line; + }, + + drawRect: function(x, y, w, h) { + return this.paper_.rect(x, y, w, h).attr(RECT); + }, + + /** + * Draws text with a optional white background + * x,y (int) x,y top left point of the text, or the center of the text (depending on align param) + * text (string) text to print + * font (Object) + * align (string) ALIGN_LEFT or ALIGN_CENTER + */ + drawText: function(x, y, text, font, align) { + text = this.cleanText(text); + font = font || {}; + align = align || ALIGN_LEFT; + + var paper = this.paper_; + var bb = this.textBBox(text, font); + + if (align == ALIGN_CENTER) { + x = x - bb.width / 2; + y = y - bb.height / 2; + } + + var t; + if (font.obj_) { + // When using a font, we have to use .print(..) + t = paper.print(x - bb.x, y - bb.y, text, font.obj_, font['font-size']); + } else { + t = paper.text(x - bb.x - bb.width / 2, y - bb.y, text); + t.attr(font); + t.attr({'text-anchor': 'start'}); + } + + return t; + } + }); + + /****************** + * RaphaelHandTheme + ******************/ + + var RaphaelHandTheme = function(diagram, options, resume) { + this.init(diagram, _.defaults(options, { + 'font-size': 16, + 'font-family': 'daniel' + }), resume); + }; + + // Take the standard RaphaelTheme and make all the lines wobbly + _.extend(RaphaelHandTheme.prototype, RaphaelTheme.prototype, { + setupPaper: function(container) { + RaphaelTheme.prototype.setupPaper.call(this, container); + this.font_.obj_ = this.paper_.getFont('daniel'); + }, + + drawLine: function(x1, y1, x2, y2, linetype, arrowhead) { + var line = this.paper_.path(handLine(x1, y1, x2, y2)).attr(LINE); + if (arrowhead !== undefined) { + line.attr('arrow-end', this.arrowTypes_[arrowhead] + '-wide-long'); + } + if (arrowhead !== undefined) { + line.attr('stroke-dasharray', this.lineTypes_[linetype]); + } + return line; + }, + + drawRect: function(x, y, w, h) { + return this.paper_.path(handRect(x, y, w, h)).attr(RECT); + } + }); + + registerTheme('raphaelSimple', RaphaelTheme); + registerTheme('raphaelHand', RaphaelHandTheme); +} +/*! + * The following copyright notice may not be removed under any circumstances. + * + * Copyright: + * Copyright (c) 2011 by Daniel Midgley. All rights reserved. + * + * Trademark: + * Please refer to the Copyright section for the font trademark attribution + * notices. + * + * Full name: + * Daniel-Bold + * + * Description: + * Daniel Bold is a font by Daniel Midgley. + * + * Designer: + * Daniel Midgley + * + * Vendor URL: + * http://goodreasonblog.blogspot.com/p/fontery.html + * + * License information: + * http://creativecommons.org/licenses/by-nd/3.0/ + */ +if (typeof Raphael != 'undefined') { +Raphael.registerFont({ + "w": 209, + "face": { + "font-family": "Daniel", + "font-weight": 700, + "font-stretch": "normal", + "units-per-em": "360", + "panose-1": "2 11 8 0 0 0 0 0 0 0", + "ascent": "288", + "descent": "-72", + "x-height": "7", + "bbox": "-92.0373 -310.134 519 184.967", + "underline-thickness": "3.51562", + "underline-position": "-25.1367", + "unicode-range": "U+0009-U+F002" + }, + "glyphs": { + " ": { + "w": 179 + }, + "\t": { + "w": 179 + }, + "\r": { + "w": 179 + }, + "!": { + "d": "66,-306v9,3,18,11,19,24v-18,73,-20,111,-37,194v0,10,2,34,-12,34v-12,0,-18,-9,-18,-28v0,-85,23,-136,38,-214v1,-7,4,-10,10,-10xm25,-30v15,-1,28,34,5,35v-11,-1,-38,-36,-5,-35", + "w": 115 + }, + "\"": { + "d": "91,-214v-32,3,-25,-40,-20,-68v3,-16,7,-25,12,-27v35,13,14,56,8,95xm8,-231v4,-31,1,-40,18,-75v37,7,11,51,11,79v-3,3,-4,8,-5,13v-17,4,-16,-10,-24,-17", + "w": 117 + }, + "#": { + "d": "271,-64v-30,26,-96,-7,-102,51v-6,2,-13,2,-24,-2v-2,-11,10,-21,2,-28v-14,5,-48,0,-48,22v0,23,-11,14,-29,10v-7,-6,6,-19,-1,-24r-32,4v-19,-8,-15,-24,5,-28r33,-6v4,0,24,-23,11,-27v-26,0,-63,14,-74,-10v3,-1,9,-17,16,-10v15,-8,81,4,89,-30v8,-14,16,-34,24,-38v23,9,24,38,5,49v37,24,55,-38,72,-43v19,10,20,23,-1,45v2,8,23,1,29,4v3,3,6,6,10,11v-14,13,-20,12,-45,12v-17,0,-16,17,-19,29v18,-7,49,3,67,-2v4,0,8,4,12,11xm161,-104v-30,-1,-44,10,-44,37v14,1,24,0,40,-5v0,-1,3,-10,8,-26v0,-4,-1,-6,-4,-6", + "w": 285 + }, + "$": { + "d": "164,-257v29,4,1,42,-3,50v5,5,38,13,41,24v8,4,6,15,-2,21v-18,3,-36,-17,-49,-17v-17,1,-31,40,-28,48v5,4,8,8,9,10v13,1,35,37,28,44v-10,21,-36,20,-65,28v-10,10,-12,40,-17,51v-9,-3,-28,1,-18,-17v0,-13,5,-24,-1,-35v-18,1,-59,-10,-42,-29v21,0,56,16,55,-16v5,-4,9,-18,9,-26v-14,-15,-55,-41,-53,-65v2,-33,56,-19,98,-26v10,-14,31,-43,38,-45xm93,-152v11,-10,15,-15,14,-29v-17,-3,-37,1,-43,6v10,12,20,19,29,23xm111,-103v-8,1,-11,12,-10,22v10,0,28,2,27,-8v0,-4,-13,-15,-17,-14", + "w": 225 + }, + "%": { + "d": "181,-96v24,-7,67,-13,104,1v14,18,21,19,22,44v-13,43,-99,61,-146,36v-9,-9,-22,-11,-32,-29v0,-27,24,-53,52,-52xm139,-185v-9,68,-138,73,-131,-5v0,-3,3,-9,9,-17v13,1,27,1,17,-16v5,-39,63,0,93,-6v36,1,80,-9,102,11v15,32,12,32,-8,56v-16,21,-103,78,-152,125r-14,28v-23,11,-25,-7,-29,-20v34,-71,133,-98,171,-162v-13,-12,-52,-5,-61,1v0,1,1,3,3,5xm38,-190v0,34,55,29,70,8v0,-14,-20,-11,-32,-14v-14,-3,-24,-9,-40,-10v1,0,5,11,2,16xm172,-53v12,27,90,18,102,-5v-18,-7,-32,-10,-40,-10v-29,3,-57,-4,-62,15", + "w": 308 + }, + "&": { + "d": "145,-82v17,-8,47,-15,71,-26v13,2,25,12,9,23v-23,7,-40,16,-53,27r0,6v13,8,30,21,36,38v0,8,-4,12,-11,12v-19,0,-43,-39,-59,-44v-30,12,-65,29,-97,32v-32,3,-45,-41,-23,-63v21,-20,52,-26,70,-48v-4,-31,-12,-47,9,-73v13,-16,20,-29,23,-39v15,-15,32,-22,51,-22v30,9,62,64,32,96v-2,3,-47,42,-69,48v-15,8,-11,9,0,22v6,7,10,11,11,11xm114,-138v25,-13,62,-38,74,-62v0,-9,-10,-31,-20,-29v-28,7,-60,42,-60,75v0,10,2,15,6,16xm99,-91v-18,10,-54,18,-59,45v26,5,61,-12,77,-22v-1,-5,-13,-23,-18,-23", + "w": 253 + }, + "'": { + "d": "36,-182v-36,7,-34,-61,-17,-80v15,1,21,19,21,20r-1,-1v0,0,-1,12,-5,35v1,5,3,17,2,26", + "w": 63 + }, + "(": { + "d": "130,-306v13,2,23,43,-1,43v-49,43,-77,77,-90,148v5,49,27,67,64,101v4,14,5,6,2,19r-15,0v-35,-17,-79,-58,-79,-120v0,-58,66,-176,119,-191", + "w": 120 + }, + ")": { + "d": "108,-138v-2,73,-48,120,-98,153v-17,-5,-16,-20,-6,-31v52,-64,73,-62,74,-135v1,-42,-40,-98,-58,-128v0,-5,-1,-12,-2,-22v18,-18,25,0,42,27v25,39,50,66,48,136", + "w": 120 + }, + "*": { + "d": "121,-271v15,-5,36,-8,40,9v-5,10,-31,19,-47,31v0,11,34,43,14,53v-18,8,-24,-24,-34,-20v-4,10,-4,19,-12,41v-25,7,-15,-30,-17,-47v-13,-1,-17,9,-46,30r-10,0v-20,-32,37,-43,54,-64v-10,-11,-36,-33,-16,-51v3,0,14,8,33,24v8,-10,26,-39,32,-42v14,7,15,23,9,36", + "w": 177 + }, + "+": { + "d": "163,-64v-7,22,-65,2,-77,21v-2,10,-6,21,-11,35v-20,4,-21,-12,-19,-29v3,-23,-44,6,-39,-27v-8,-22,36,-8,49,-18v8,-13,6,-36,24,-40v19,-4,14,32,11,39v18,3,19,2,54,8v2,1,5,5,8,11", + "w": 170 + }, + ",": { + "d": "25,63v-26,21,-48,-2,-22,-24v14,-12,35,-40,35,-69v3,-2,3,-11,12,-9v35,17,5,88,-25,102", + "w": 97 + }, + "-": { + "d": "57,-94v19,4,55,-5,54,17v-15,23,-54,20,-91,15v-4,2,-13,-10,-11,-16v-1,-22,28,-15,48,-16", + "w": 124 + }, + ".": { + "d": "40,-48v21,20,21,44,-4,44v-33,0,-26,-24,-10,-44r14,0", + "w": 67 + }, + "\/": { + "d": "21,20v-22,-45,21,-95,41,-126v38,-57,115,-158,193,-201v2,0,4,3,7,11v11,29,-15,34,-25,55v-81,56,-189,208,-197,261r-19,0", + "w": 275 + }, + "0": { + "d": "78,-237v70,-47,269,-41,270,59v0,34,-11,53,-29,76v-13,35,-30,32,-85,64v-6,2,-10,6,-7,8v-73,14,-98,38,-173,1v-7,-13,-52,-48,-46,-88v9,-57,27,-75,70,-120xm123,-38v100,0,202,-46,195,-153v-32,-55,-144,-73,-211,-35v-16,34,-68,54,-53,108v6,25,1,22,-3,39v6,24,41,41,72,41", + "w": 353 + }, + "1": { + "d": "39,-208v0,-14,6,-59,29,-39v3,4,6,13,10,24r-22,128r8,87v-4,6,-9,3,-16,2v-44,-38,-9,-137,-9,-202", + "w": 93 + }, + "2": { + "d": "88,-35v47,-10,119,-24,168,-9v0,12,-23,13,-35,16v1,1,3,1,5,1v-74,8,-118,23,-194,23v-14,0,-20,-13,-21,-28v55,-40,83,-61,123,-104v26,-13,65,-67,71,-102v-1,-9,-11,-16,-22,-16v-20,-1,-120,29,-156,49v-10,-2,-30,-20,-10,-28v50,-21,111,-51,178,-48v25,10,44,22,36,39v12,30,-19,64,-34,83v-39,48,-37,39,-115,109v0,5,-3,8,-8,11v4,3,8,4,14,4", + "w": 265 + }, + "3": { + "d": "188,-282v34,-10,74,25,47,51v-19,32,-55,50,-92,70v28,14,116,25,108,70v8,14,-49,40,-63,48v-29,9,-130,22,-168,42v-6,-5,-19,-7,-12,-22v56,-36,175,-21,210,-76v-9,-20,-88,-42,-97,-33v-20,-1,-41,2,-56,-7r5,-21v56,-25,103,-36,137,-78v1,-1,2,-5,4,-11v-15,-14,-56,7,-79,0v-10,9,-73,22,-92,31v-11,-4,-28,-23,-13,-30v50,-22,96,-26,154,-37v0,-1,8,3,7,3", + "w": 260 + }, + "4": { + "d": "79,-249v-7,17,-29,75,-33,96v0,6,3,8,8,8v43,-2,111,6,141,-6v17,-47,20,-100,63,-148v9,4,16,7,21,10v-17,31,-44,95,-51,141v7,4,24,-4,23,10v-1,16,-29,12,-31,23v-10,22,-9,69,-7,103v-3,2,-7,5,-10,9v-47,-11,-23,-74,-16,-114v0,-4,-2,-6,-7,-6v-65,2,-89,13,-162,4v-22,-22,-2,-53,5,-76v16,-15,17,-57,35,-70v6,-1,21,11,21,16", + "w": 267 + }, + "5": { + "d": "185,-272v30,7,45,-8,53,18v1,16,-17,18,-34,14v0,0,-95,-11,-129,1v-6,9,-24,33,-29,54v76,10,171,5,214,47v11,11,22,30,5,52v-14,12,-30,14,-34,27v-26,11,-141,63,-157,60v-16,-2,-25,-19,-4,-27v48,-18,128,-39,170,-86v4,-14,-65,-41,-85,-41r-92,0v-10,-4,-66,-1,-57,-23v0,-23,23,-51,35,-83v11,-28,133,-10,144,-13", + "w": 284 + }, + "6": { + "d": "70,-64v9,-51,63,-74,123,-71v43,2,109,3,111,41r-25,47v0,1,1,2,2,3v-5,0,-39,10,-41,20v-15,3,-22,4,-22,11v-39,1,-77,20,-119,13v-42,-7,-35,-9,-77,-46v-56,-118,94,-201,176,-229v7,0,21,8,20,15v-2,17,-23,15,-43,24v-69,31,-119,72,-134,145v-5,25,36,68,78,64v59,-6,128,-18,153,-61v-7,-14,-13,-9,-32,-21v-67,-15,-118,-5,-150,43r0,12v-13,4,-17,-3,-20,-10", + "w": 310 + }, + "7": { + "d": "37,-228v33,-14,173,-17,181,-19v28,-1,24,31,9,45v-17,15,-45,49,-59,69v-17,26,-55,67,-61,113v-10,13,-9,14,-14,20v-33,-13,-20,-25,-11,-53v16,-48,73,-115,109,-156v2,-7,5,-14,-10,-12v-26,4,-54,6,-76,13v-23,-5,-83,31,-94,-9v2,-8,18,-19,26,-11", + "w": 245 + }, + "8": { + "d": "57,-236v40,-50,166,-51,213,-10v22,28,10,63,-22,78r-35,17v8,5,54,24,53,44v-5,14,-4,33,-18,42v-13,13,-35,18,-44,34v-60,27,-190,49,-194,-42v7,-41,17,-54,59,-70r0,-4v-32,-9,-73,-62,-26,-85v4,0,8,-2,14,-4xm142,-160v24,-2,160,-31,99,-72v-28,-18,-108,-33,-146,-5v-16,12,-28,30,-33,59v24,12,37,20,80,18xm41,-62v30,65,189,6,199,-37v3,-14,-60,-30,-74,-30v-70,0,-118,10,-125,67", + "w": 290 + }, + "9": { + "d": "11,-192v15,-49,119,-61,161,-23v16,15,27,55,11,79v-20,62,-51,79,-96,118v-10,4,-45,27,-50,6v9,-15,66,-52,98,-99v-7,-7,-8,-3,-25,0v-49,-11,-96,-25,-99,-81xm145,-131v7,-5,13,-34,13,-41v-2,-51,-104,-38,-114,-6v-2,10,37,35,46,35v23,1,43,-1,55,12", + "w": 198 + }, + ":": { + "d": "39,-125v15,-8,40,-1,40,15v0,15,-6,22,-19,22v-13,0,-29,-21,-21,-37xm66,-17v-8,27,-51,19,-46,-8v-1,-6,8,-22,14,-20v29,0,30,6,32,28", + "w": 95 + }, + ";": { + "d": "56,-93v2,-30,37,-22,40,2v0,2,-1,7,-3,15v-13,8,-15,6,-27,4xm64,-44v11,-11,30,-4,32,14v-21,39,-63,71,-92,85v-5,0,-11,-2,-18,-8v11,-23,36,-36,50,-61v11,-7,19,-20,28,-30", + "w": 107 + }, + "<": { + "d": "166,-202v12,0,29,15,24,29v0,4,-119,64,-120,73v15,21,89,64,91,86v2,29,-18,12,-30,15v-27,-29,-59,-54,-95,-75v-18,-10,-25,-13,-24,-41", + "w": 176 + }, + "=": { + "d": "125,-121v18,7,55,-9,69,14v0,17,-45,26,-135,26v-18,0,-27,-7,-27,-21v-1,-37,60,-5,93,-19xm138,-71v20,0,48,-1,50,16v-13,24,-86,32,-131,29v-29,-2,-43,-10,-43,-24v-7,-23,36,-14,39,-17v27,6,57,-4,85,-4", + "w": 196 + }, + ">": { + "d": "4,-14v20,-48,77,-59,118,-94v-16,-19,-58,-52,-81,-75v-11,-7,-15,-38,-1,-40v33,16,83,71,121,105v26,23,-6,35,-41,53v-29,16,-56,28,-73,54v-21,15,-16,20,-34,15v-3,0,-9,-16,-9,-18", + "w": 174 + }, + "?": { + "d": "105,-291v57,-13,107,-4,107,39v0,67,-136,85,-155,137v-1,6,10,23,-4,23v-23,1,-33,-35,-23,-57v31,-41,124,-60,149,-103v-8,-21,-72,-5,-88,-1v-23,6,-59,39,-71,8v0,0,-1,0,1,-17v10,-4,45,-20,84,-29xm80,-25v-6,4,-8,39,-24,22v-24,3,-22,-21,-13,-35v17,-7,29,5,37,13", + "w": 216 + }, + "@": { + "d": "218,-207v23,8,42,14,47,37v44,68,-27,137,-87,85r1,0v0,2,-59,19,-61,17v-35,0,-42,-47,-17,-68r0,-4v-19,-1,-45,37,-49,40v-37,76,58,72,121,62v11,-2,34,-13,36,3v-14,31,-69,31,-114,33v-51,2,-99,-41,-80,-92v2,-30,22,-40,42,-63v35,-20,91,-53,161,-50xm217,-101v23,0,35,-19,35,-41v0,-43,-75,-41,-102,-19v36,3,55,16,62,41v-6,5,-6,19,5,19xm127,-110v8,5,51,-15,28,-16v-4,0,-25,4,-28,16", + "w": 291 + }, + "A": { + "d": "97,-81v-23,-10,-39,38,-52,60v-8,6,-8,6,-22,18v-22,-7,-23,-37,-4,-49v7,-8,11,-15,15,-23r-1,1v-14,-26,23,-29,31,-40v1,-1,15,-29,26,-36v17,-31,39,-58,54,-92v16,-20,20,-51,41,-66v29,5,34,62,45,92v9,64,21,103,49,155v-3,25,-44,11,-54,0v-34,-12,-97,-29,-128,-20xm107,-118v20,6,80,10,111,17v6,-7,-4,-15,-7,-24v-11,-28,-9,-92,-30,-117v-9,9,-19,44,-34,55v-9,23,-27,40,-40,69", + "w": 294 + }, + "B": { + "d": "256,-179v41,10,115,34,91,91v-6,3,-14,12,-19,20v-37,19,-50,34,-63,25v-9,10,-12,11,-34,13r3,-3v-4,-4,-12,-4,-18,0v0,0,2,2,5,4v-21,14,-26,6,-44,15v-4,0,-7,-2,-8,-5v-6,11,-20,-5,-18,11v-36,4,-91,35,-114,4v-7,-62,-10,-138,4,-199v-1,-19,-37,2,-37,-27v0,-8,2,-13,6,-15v68,-31,231,-92,311,-39v8,12,12,20,12,25v-8,42,-32,49,-77,80xm79,-160v72,-17,135,-39,184,-70v20,-13,31,-23,31,-27v1,-6,-30,-13,-38,-12v-54,0,-116,13,-186,41v11,21,1,48,9,68xm262,-43v0,-4,3,-6,-4,-5v0,1,1,2,4,5xm211,-140v-34,7,-94,24,-139,15v-6,20,-4,56,-4,82v0,29,43,1,56,2v48,-11,108,-25,154,-48v20,-10,32,-17,32,-25v0,-18,-33,-26,-99,-26xm195,-20v6,1,6,-2,5,-7v-3,2,-7,2,-5,7", + "w": 364 + }, + "C": { + "d": "51,-114v-12,75,96,76,166,71r145,-10v9,2,9,5,9,18v-37,18,-85,28,-109,22v-18,10,-47,10,-71,10v-29,0,-68,1,-105,-11v-6,-1,-10,-3,-10,-8v-33,-13,-48,-33,-66,-59v-19,-114,146,-150,224,-177v35,0,88,-31,99,7v-1,29,-49,14,-76,28v-55,8,-115,35,-175,71v-13,8,-23,21,-31,38", + "w": 376 + }, + "D": { + "d": "312,-78v-2,1,-3,7,-10,5v6,-3,10,-4,10,-5xm4,-252v2,-27,83,-38,106,-39v130,-7,267,1,291,109v0,0,-2,8,-3,25v-5,9,-4,28,-23,34v-4,4,-2,5,-7,0v-3,3,-15,7,-5,10v0,0,-10,14,-13,2v-11,1,-8,5,-20,14v1,2,7,3,9,1v-4,13,-22,13,-11,4v0,-3,1,-6,-3,-5v-40,29,-103,38,-141,65v10,6,22,-7,34,-3v-41,20,-127,44,-171,46v-21,1,-47,-33,-11,-39v15,-2,43,-6,56,-11v-16,-101,-5,-130,9,-207v2,0,4,-1,6,-3v-16,-17,-91,38,-103,-3xm297,-69v-7,3,-17,8,-25,7v1,1,3,2,5,2v-4,2,-11,5,-23,9v4,-11,30,-21,43,-18xm240,-51v10,0,12,2,0,6r0,-6xm220,-36v-1,-3,4,-6,6,-3v0,1,-2,1,-6,3xm125,-48v16,6,137,-46,155,-53v29,-18,101,-44,82,-93v-21,-53,-84,-61,-168,-67v-20,7,-50,3,-77,8v33,54,-12,132,8,205xm159,-22v-4,-1,-15,-5,-15,2v7,-1,12,-2,15,-2", + "w": 381 + }, + "E": { + "d": "45,-219v-19,-36,34,-41,63,-36v44,-10,133,-8,194,-15v3,2,38,11,52,15v-73,19,-171,21,-246,38v-9,11,-16,32,-20,61v35,11,133,-6,183,3v1,6,2,7,3,14v-46,24,-118,16,-193,27v-15,13,-22,52,-22,66v60,1,121,-20,188,-20v22,10,53,-7,74,5v16,29,-23,26,-43,32v-73,4,-139,13,-216,27r-52,-10v-4,-22,23,-69,26,-98v-3,0,-10,-15,-12,-24v20,-12,34,-23,35,-67v2,-1,5,-5,5,-7v0,-4,-14,-11,-19,-11", + "w": 353 + }, + "F": { + "d": "270,-258v13,2,59,6,48,34v-78,-3,-143,1,-212,22v-10,16,-21,43,-24,69r145,-9v8,3,29,-3,16,21v-14,-1,-59,13,-60,7v-12,13,-67,18,-108,21v-2,1,-4,3,-7,6v-2,23,-8,43,-7,69v1,28,-30,11,-40,5r10,-80r-26,-14v5,-10,10,-33,28,-25v21,-3,15,-46,26,-59v-1,-3,-32,-13,-28,-24v2,-22,45,-16,59,-30v47,4,99,-14,151,-9v5,-3,25,-3,29,-4", + "w": 236 + }, + "G": { + "d": "311,-168v53,0,94,57,74,110v-31,37,-71,34,-136,52v-13,-7,-41,10,-57,7v-73,-1,-122,-17,-162,-59v-49,-51,-24,-80,5,-130v35,-61,138,-93,214,-106v16,4,42,-1,40,21v-5,40,-39,2,-73,21v-76,19,-162,65,-177,142v28,103,237,76,312,29v2,-3,3,-7,3,-13v-10,-35,-37,-43,-87,-45v-16,-13,-53,-9,-78,1v-4,-3,-5,-7,-5,-11v17,-29,73,-17,108,-24v12,4,18,5,19,5", + "w": 391 + }, + "H": { + "d": "300,-268v18,12,19,32,4,51v-35,44,-34,140,-46,217v-1,5,-5,13,-11,12v-6,1,-19,-14,-18,-27r7,-106v-28,7,-76,22,-116,14v-18,2,-36,6,-55,3v-43,-8,-14,53,-33,75v-29,1,-26,-67,-21,-97v5,-31,28,-73,43,-98v2,2,7,3,14,3v13,33,-11,48,-13,78v61,4,118,2,176,2v8,0,13,-6,15,-20v4,-47,21,-87,54,-107", + "w": 288 + }, + "I": { + "d": "63,-266v34,10,-4,105,-8,128r-24,126v-2,2,-3,1,-9,6v-12,-10,-12,-15,-12,-47v0,-93,9,-156,28,-188v10,-17,19,-25,25,-25", + "w": 79 + }, + "J": { + "d": "235,-291v26,11,31,104,31,142v0,37,-2,95,-32,126v-33,34,-121,26,-167,1v-18,-11,-54,-29,-59,-59v0,-3,5,-15,16,-14v31,36,90,57,162,51v63,-30,56,-148,32,-226v-1,-16,11,-13,17,-21", + "w": 282 + }, + "K": { + "d": "212,-219v17,-5,80,-60,80,-19v0,9,-2,14,-5,16r-132,78v-34,23,-54,32,-21,50v39,21,74,23,124,41v5,2,7,5,7,9v-4,24,-55,15,-79,8v-67,-19,-98,-36,-116,-83v9,-24,38,-35,66,-61v7,-4,49,-30,76,-39xm47,-194v11,-20,11,-45,31,-55v2,2,4,3,6,0v29,39,-21,96,-18,128v-17,24,-15,62,-29,113v-4,3,-10,7,-19,11v-12,-13,-10,-28,-8,-53v3,-31,17,-79,37,-144", + "w": 270 + }, + "L": { + "d": "84,-43v58,0,179,-27,242,-4v3,17,-29,24,-40,26v-85,-4,-202,46,-268,3v-24,-16,-2,-33,-4,-57v26,-76,38,-108,86,-191v14,-7,26,-50,45,-32v6,22,5,31,-12,46v-20,39,-50,82,-67,142v-7,6,-19,46,-19,54v0,9,12,13,37,13", + "w": 331 + }, + "M": { + "d": "174,-236v-1,52,-11,92,-7,143v10,5,15,-12,22,-18v42,-55,90,-130,136,-174r15,-18v42,2,32,53,11,80v-12,58,-54,143,-34,210v0,3,-3,12,-9,10v-31,-5,-32,-57,-27,-92v4,-27,12,-58,25,-93v-5,-10,5,-19,6,-30v-46,44,-66,110,-129,172v-11,10,-18,15,-22,15v-34,6,-28,-103,-28,-152v-28,22,-65,119,-96,170v-9,15,-34,3,-31,-19v30,-64,91,-177,139,-229v12,-1,29,13,29,25", + "w": 343 + }, + "N": { + "d": "248,-20v-3,17,-37,18,-43,3v-24,-35,-53,-145,-80,-203v-32,40,-55,120,-92,174v-13,3,-26,-13,-27,-22r87,-171v4,-13,20,-57,42,-32v42,48,46,139,82,198v29,-45,46,-88,65,-153v12,-19,23,-42,38,-60v27,-1,14,18,4,44v-6,46,-32,68,-37,121v-15,29,-33,69,-39,101", + "w": 307 + }, + "O": { + "d": "240,-268v85,1,163,29,150,125v13,7,-12,18,-5,26v-23,63,-133,112,-228,124v-80,-16,-171,-56,-148,-153v11,-47,20,-43,53,-83v17,-9,39,-22,73,-29v45,-10,81,-10,105,-10xm363,-156v16,-51,-62,-85,-111,-79v-25,-11,-50,8,-81,0v-15,10,-70,16,-85,31v6,20,-27,24,-39,45v-42,75,40,128,115,128v56,0,209,-71,201,-125", + "w": 383 + }, + "P": { + "d": "70,-225v-7,-12,-36,16,-49,19v-4,0,-9,-5,-14,-17v21,-47,114,-55,172,-59v41,-3,132,33,99,87v-21,34,-72,59,-144,80v-2,16,-79,3,-74,46v3,25,-5,47,-10,68v-22,-1,-23,-29,-22,-56v2,-25,-20,-32,-8,-50v21,-5,10,-35,25,-57v6,-28,14,-48,25,-61xm71,-229v47,14,-2,50,-1,99v41,-3,113,-37,173,-76v5,-9,8,-14,8,-15v-28,-47,-125,-29,-180,-8", + "w": 252 + }, + "Q": { + "d": "374,-217v20,59,-11,127,-48,156r30,38v-1,6,-8,16,-14,9v-3,0,-19,-9,-47,-26v-72,35,-173,75,-236,12v-70,-40,-67,-213,26,-217r8,5v24,-20,72,-48,112,-38v21,-4,22,-1,50,-2v66,-2,94,20,119,63xm296,-88v13,5,61,-49,63,-84v4,-62,-54,-78,-119,-76v-14,-6,-49,5,-71,3v-42,16,-89,41,-93,94v-9,11,1,25,-7,38v-12,-19,-7,-67,-1,-88v-56,30,-37,137,19,155v27,17,92,19,119,0v12,-2,29,-9,52,-20v2,-2,3,-3,3,-6v-11,-12,-46,-27,-54,-56v0,-13,3,-19,9,-19v18,1,60,52,80,59", + "w": 379 + }, + "R": { + "d": "100,-275v96,-23,196,-10,208,78v-3,18,-17,52,-49,62v-14,20,-54,23,-79,40v-2,0,-14,2,-36,6v-40,8,-30,14,-3,33v37,27,52,30,118,55v16,6,31,23,12,27v-58,-2,-104,-29,-143,-61v-14,-3,-16,-15,-39,-27v-23,-19,-28,-12,-15,-38v63,-19,111,-15,163,-53v27,-20,43,-36,43,-49v0,-64,-120,-62,-173,-38v-9,4,-38,9,-40,18v-10,32,-16,70,-13,116v-10,21,-8,47,-6,75v2,31,-9,29,-27,22v-9,-55,5,-140,15,-190v-8,-6,-24,10,-24,-11v0,-34,16,-34,42,-55v2,-1,17,-4,46,-10", + "w": 297 + }, + "S": { + "d": "13,-3v-7,-3,-22,-18,-5,-22v68,-15,119,-32,154,-45v51,-19,39,-34,3,-53v-46,-25,-82,-30,-121,-64v-33,-29,-50,-35,-25,-58v37,-20,119,-29,181,-29v29,0,44,6,44,18v-9,26,-62,6,-104,14v-17,2,-72,6,-92,16v37,53,132,58,180,111v8,9,11,20,11,30v-4,17,-23,35,-42,34v-21,16,-17,1,-49,17v-14,7,-41,9,-56,20v-25,-3,-49,10,-79,11", + "w": 234 + }, + "T": { + "d": "141,-3v-36,-6,1,-49,-3,-79v10,-19,6,-35,15,-64r26,-85v-51,-9,-100,10,-141,14v-16,2,-30,-26,-11,-32v26,-8,143,-8,179,-19r12,6v67,-2,142,-1,200,-1v8,0,14,3,19,10v-18,16,-74,3,-103,14v-48,-4,-60,4,-113,7v-42,22,-36,130,-58,187v1,12,-9,44,-22,42", + "w": 277 + }, + "U": { + "d": "365,-262v13,56,-22,104,-36,141v-19,22,-30,38,-57,56v-4,18,-60,35,-78,50v-53,28,-142,0,-161,-34v-31,-56,-37,-108,-11,-164v17,-33,29,-50,48,-29v-2,2,-3,7,-4,13v-44,36,-38,149,7,174v30,26,55,19,102,4v56,-17,66,-34,120,-76v12,-24,56,-68,46,-122r0,-16v0,1,-1,3,-1,6v4,-13,11,-10,25,-3", + "w": 368 + }, + "V": { + "d": "246,-258v21,-22,31,-26,44,-8v1,1,-12,22,-28,35v-15,25,-41,38,-56,69v-13,15,-20,31,-28,57v-15,13,-11,29,-27,72v3,21,-5,24,-27,27v-33,-45,-54,-118,-84,-167v-5,-26,-18,-50,-25,-76v-3,-12,24,-8,29,-5v8,13,18,52,26,70r52,115v9,-2,4,-9,10,-21r25,-47v25,-44,46,-76,89,-121", + "w": 234 + }, + "W": { + "d": "31,-213v16,46,17,106,41,151v31,-35,49,-89,76,-127v30,-15,39,27,52,56v10,22,21,48,35,67v2,0,4,-1,5,-3v16,-28,50,-76,79,-121v14,-21,40,-63,64,-83r5,8v-30,58,-76,110,-97,173v-18,28,-25,37,-33,63v-11,1,-16,25,-30,15v-21,-31,-44,-89,-62,-131v0,-2,-1,-3,-5,-5v-17,11,-16,36,-31,50v-20,33,-20,84,-68,94v-24,-19,-23,-81,-39,-111v-1,-15,-29,-94,-10,-108v9,2,12,5,18,12", + "w": 331 + }, + "X": { + "d": "143,-183v43,-25,69,-36,126,-62v22,-10,86,-10,56,21v-51,3,-158,61,-154,64v10,15,41,30,50,52v27,17,46,60,70,82v9,14,-6,30,-24,20v-35,-43,-75,-100,-116,-132v-48,13,-100,47,-118,94v-1,49,-26,34,-27,4v-1,-26,13,-27,17,-48v22,-27,68,-55,90,-77v-9,-12,-60,-39,-79,-57v-6,-10,-6,-25,12,-25", + "w": 312 + }, + "Y": { + "d": "216,-240v19,-14,42,10,22,26v-54,66,-121,109,-156,197v-8,21,-11,15,-30,4v3,-37,27,-61,33,-76v12,-12,15,-19,32,-42v-8,-6,-40,5,-45,5v-48,-6,-69,-65,-56,-113v14,0,13,-1,24,7v2,33,12,75,42,73v36,-2,102,-57,134,-81", + "w": 189 + }, + "Z": { + "d": "60,-255v66,12,200,-34,240,21v-13,42,-63,62,-98,89v-19,15,-47,33,-82,55v-25,16,-47,32,-66,47v58,24,129,-6,208,-6v23,0,36,12,13,19v-33,2,-53,5,-86,10v-32,18,-88,15,-135,15v-9,-1,-55,-1,-48,-29v1,-24,30,-24,40,-41v64,-50,151,-86,208,-147v-38,-17,-155,12,-198,-4v0,0,-11,-33,4,-29", + "w": 310 + }, + "[": { + "d": "72,-258r-15,250v30,4,55,-3,80,-6v7,-1,8,17,9,23v-28,15,-73,23,-121,21v-7,0,-10,-6,-10,-17v0,-60,25,-193,22,-288v0,-16,13,-20,33,-19v9,-3,34,-12,51,-12v16,0,15,16,19,29v-16,7,-48,10,-68,19", + "w": 151 + }, + "\\": { + "d": "236,38v20,-18,-8,-74,-13,-90v-44,-78,-112,-190,-200,-253v-2,0,-5,4,-7,12v-11,31,13,36,24,58v74,61,174,219,180,273r16,0", + "w": 257 + }, + "]": { + "d": "133,-258v-23,-13,-84,6,-85,-32v0,-10,5,-15,14,-15v0,0,30,2,90,7v10,1,15,13,15,36v2,7,-8,59,-13,112r-11,125v-9,48,9,90,-59,71v-20,-4,-39,-1,-59,-4v-5,-10,-25,-12,-14,-30v8,-3,61,-13,78,-8v14,1,8,-7,10,-17v15,-69,21,-166,34,-245", + "w": 171 + }, + "^": { + "d": "68,-306v20,15,47,36,58,60v-1,4,0,7,-9,7v-26,0,-47,-38,-49,-32v-15,9,-41,50,-54,30v-2,-31,17,-23,33,-51v8,-9,15,-14,21,-14", + "w": 135 + }, + "_": { + "d": "11,15v-8,33,18,45,50,34r205,2r197,-5v11,-5,14,-9,7,-28v-95,-21,-258,-10,-376,-10v-25,0,-72,-3,-83,7", + "w": 485 + }, + "`": { + "d": "75,-264v16,8,56,14,39,43v-30,-8,-65,-23,-105,-44v-1,-3,-3,-28,5,-25v16,5,44,17,61,26", + "w": 129 + }, + "a": { + "d": "124,-56v10,4,59,41,65,50v1,7,-6,17,-12,17r-60,-30v-22,2,-42,21,-65,19v-33,4,-68,-67,-15,-81v41,-27,96,-39,110,9v0,6,-4,12,-11,16v-33,-25,-67,-5,-88,12v10,16,61,-18,76,-12", + "w": 196 + }, + "b": { + "d": "80,-140v69,1,123,0,134,52v5,26,-71,71,-97,70v-11,11,-88,22,-94,22v-11,-3,-26,-18,-6,-24v19,-5,-2,-19,-1,-35v1,-18,11,-36,-5,-47v-6,-17,-6,-21,14,-32v6,-45,18,-89,28,-124v2,-7,8,-12,17,-15v5,3,10,11,16,28v-12,27,-13,63,-23,96v0,6,6,9,17,9xm87,-107v-40,-9,-31,31,-39,54v8,15,0,25,12,22v30,-8,60,-18,88,-32v39,-18,49,-33,-1,-42v-20,-4,-45,-7,-60,-2", + "w": 217 + }, + "c": { + "d": "128,-123v29,-7,37,29,12,33v-27,-4,-40,6,-79,25v-8,4,-13,11,-16,22v30,32,91,3,134,11v5,13,-8,26,-22,19v-51,25,-139,28,-150,-30v6,-50,69,-82,121,-80", + "w": 194 + }, + "d": { + "d": "224,-201v0,-35,-17,-111,24,-94v7,86,-2,119,0,197v-4,2,-8,21,-18,16v-62,-7,-154,-8,-185,29v6,17,28,26,51,26v16,0,100,-15,132,-18v7,5,-6,20,-10,22v-24,8,-122,42,-163,25v-32,-5,-62,-53,-36,-80v35,-37,118,-46,198,-43v1,-22,7,-49,7,-80", + "w": 265 + }, + "e": { + "d": "4,-57v0,-58,51,-71,110,-74v33,-1,45,16,59,35v1,14,2,39,-7,42v-24,-2,-73,13,-99,11v-2,2,-2,3,-2,3v0,3,12,8,37,15v21,0,69,9,31,22v-9,14,-34,6,-56,6v-27,-5,-73,-28,-73,-60xm123,-102v-22,2,-68,5,-65,26v24,-2,66,5,79,-6v-5,-13,-1,-13,-14,-20", + "w": 182 + }, + "f": { + "d": "6,-59v6,-29,53,-4,53,-43v0,-64,29,-118,84,-150v45,-25,167,-24,155,51v-1,2,-7,6,0,6r-10,2v-45,-58,-165,-39,-186,39v-7,26,-11,42,-9,62v44,8,95,-21,135,-7v-12,25,-39,21,-76,30v-19,5,-18,7,-54,19v-2,8,15,32,17,35v-6,25,-26,26,-40,-5r-15,-24v-41,10,-44,12,-54,-15", + "w": 234 + }, + "g": { + "d": "132,-97v30,27,21,75,30,117v-12,31,-11,66,-36,103v-32,46,-105,83,-167,39v-31,-21,-49,-29,-51,-75v-2,-37,77,-50,121,-57v37,-6,68,-10,95,-11v7,-6,3,-32,4,-46v0,0,-1,1,-1,2v0,-18,-5,-31,-14,-45v-44,5,-79,20,-94,-18v3,-54,73,-54,125,-50v12,7,12,13,4,25v-30,-11,-76,8,-90,20v23,3,50,-16,74,-4xm-34,121v60,53,168,1,159,-86v-47,-7,-93,24,-142,30v-12,7,-45,19,-42,29v0,10,8,19,25,27", + "w": 188 + }, + "h": { + "d": "100,-310v11,-2,10,19,11,20v-11,52,-40,133,-53,189v-6,30,-9,37,-9,47v27,0,113,-34,143,-34v42,0,31,47,39,79v0,4,-5,17,-16,16v4,2,11,3,4,6v-24,-1,-28,-34,-25,-64v-1,-1,-2,-3,-5,-5v-51,0,-110,38,-162,51v-9,1,-15,-15,-16,-23v17,-89,39,-141,71,-264v0,-9,6,-19,18,-18", + "w": 251 + }, + "i": { + "d": "62,-209v7,18,9,23,-5,38v-23,-6,-21,-18,-11,-36v2,0,8,-1,16,-2xm34,-7v-18,-21,-8,-73,-1,-106v7,-10,20,-8,23,6v-1,36,7,72,-2,104v-8,2,-8,0,-20,-4", + "w": 80 + }, + "j": { + "d": "88,-191v5,28,-18,40,-28,21v0,-20,12,-29,28,-21xm82,-99v28,-1,16,35,16,61v0,60,-19,150,-35,202v-12,8,-19,31,-35,16v-32,-7,-43,-19,-56,-44r2,-17v11,4,49,45,61,18v10,-55,27,-107,30,-171v0,-16,0,-59,17,-65", + "w": 120 + }, + "k": { + "d": "59,-66v33,26,114,37,155,62v8,-4,22,-2,19,-17v0,-4,-12,-11,-30,-24v-36,-25,-54,-22,-99,-33v14,-21,119,-13,103,-63r-16,-7r-123,47r25,-93v-3,-15,16,-49,18,-81v1,-15,-21,-14,-25,-3v-31,82,-49,168,-75,257v2,2,22,30,27,10v2,-5,4,-9,9,-11v4,-16,4,-15,12,-44", + "w": 236 + }, + "l": { + "d": "66,-300v21,-6,37,23,30,55v-10,51,-28,135,-28,208v0,11,6,36,-13,37v-29,-5,-30,-48,-25,-83r28,-177v-6,-17,1,-29,8,-40", + "w": 102 + }, + "m": { + "d": "348,-59v-2,21,0,57,3,73v-17,3,-30,-1,-32,-16v-8,-7,-5,-44,-13,-70v-35,3,-82,49,-111,70v-12,8,-40,4,-39,-15r2,-56v-1,-13,4,-28,-8,-29v-35,8,-79,72,-115,87v-6,2,-20,-18,-21,-22v1,-20,14,-105,39,-64r8,15v17,-14,72,-56,93,-54v27,3,49,40,43,80v24,-2,66,-55,124,-53v11,14,28,23,27,54", + "w": 368 + }, + "n": { + "d": "121,-136v37,6,62,54,62,111v0,32,-16,25,-31,17v-18,-30,-5,-45,-22,-85v-37,-13,-71,55,-92,65v-20,-3,-39,-39,-21,-62v2,-12,3,-15,11,-30v12,-8,20,11,29,12", + "w": 194 + }, + "o": { + "d": "108,-139v52,-24,104,18,104,63v0,59,-66,67,-114,83v-52,-2,-115,-50,-80,-105v23,-18,52,-35,90,-41xm45,-60v16,54,125,16,131,-23v-12,-59,-129,-8,-131,23", + "w": 217 + }, + "p": { + "d": "82,14v-10,12,-8,117,-24,142v-15,2,-19,0,-29,-13v0,-76,9,-113,22,-192v14,-27,35,-6,37,13v0,8,-3,21,-7,38v2,2,3,2,4,2v26,-9,116,-33,126,-72v-7,-17,-24,-33,-49,-31v-40,3,-116,13,-116,47v-5,7,-2,17,-16,20v-17,-12,-18,-20,-12,-38v8,-25,74,-61,110,-59v55,-15,113,15,118,70v-15,52,-84,79,-146,83v-5,0,-11,-4,-18,-10", + "w": 251 + }, + "q": { + "d": "144,-147v27,-8,89,-3,97,31v-9,29,-42,-4,-73,1v-32,6,-118,20,-111,49v0,7,13,13,21,13v21,0,78,-24,104,-34v2,0,9,8,22,21v1,1,1,2,1,5v-27,90,-22,70,-43,203v11,15,-15,54,-33,33v-6,-8,-10,-20,-3,-28v1,-72,5,-114,15,-172v-35,3,-35,10,-59,8v-41,-4,-98,-41,-56,-85v33,-34,59,-27,118,-45", + "w": 248 + }, + "r": { + "d": "242,-117v2,22,5,10,-14,23v-73,-7,-166,-23,-174,56v-8,6,-3,20,-8,36v-29,10,-40,-9,-33,-46v6,-31,7,-69,32,-55v58,-37,66,-42,175,-19v3,5,15,4,22,5", + "w": 229 + }, + "s": { + "d": "154,-151v19,1,27,24,13,32v-4,1,-22,4,-53,7v-16,8,-22,-2,-39,9v23,21,89,16,96,62v-13,24,-85,35,-124,42v-9,-3,-18,-3,-27,0v-6,-4,-21,-16,-8,-25v30,-6,83,-13,102,-24v-17,-16,-80,-33,-97,-48v-3,-2,-4,-7,-4,-15v-6,-6,3,-13,15,-18v22,-9,94,-23,126,-22", + "w": 188 + }, + "t": { + "d": "85,-150v10,-41,35,-126,65,-134v4,1,24,19,11,36v-17,22,-29,57,-36,104v26,8,50,-7,73,5v14,0,22,3,22,9v-1,19,-44,18,-57,23v-10,1,-46,0,-54,10v-10,24,-4,67,-20,98v-21,-3,-26,1,-26,-20v0,-9,2,-36,8,-81v-15,-13,-81,9,-77,-27v4,-38,71,6,91,-23", + "w": 194 + }, + "u": { + "d": "207,-136v-1,-2,11,-14,14,-13v6,0,10,7,10,22v-3,40,-23,56,-40,82v-13,19,-62,43,-93,43v-67,-2,-111,-75,-71,-133v26,-3,21,29,19,49v-1,27,26,44,57,42v41,-2,93,-55,104,-92", + "w": 242 + }, + "v": { + "d": "24,-127r52,71v42,-16,70,-54,124,-65v5,4,8,7,8,11v-8,19,-4,8,-33,32v0,1,-1,3,-1,5v-61,45,-93,68,-97,68v-40,-15,-50,-72,-68,-100v6,-14,10,-22,15,-22", + "w": 214 + }, + "w": { + "d": "15,-139v38,-2,27,57,45,86v30,2,67,-66,101,-78v26,6,36,69,60,78v47,-35,51,-54,119,-104v3,0,7,-2,15,-4v19,23,-9,28,-21,49v-33,28,-68,90,-107,109v-10,6,-52,-47,-72,-71v-20,17,-85,74,-97,73v-38,7,-41,-98,-52,-122v0,-1,3,-7,9,-16", + "w": 325 + }, + "x": { + "d": "95,-124v22,-13,78,-32,99,-31v16,0,23,6,23,18v0,22,-17,11,-49,21v-3,0,-45,20,-42,24v0,1,2,4,8,10v20,24,49,41,44,80v-35,3,-27,-9,-60,-44v-40,-43,-37,-26,-79,9v-1,1,-2,3,-3,8v-12,8,-28,10,-27,-11v-6,-8,45,-65,48,-65v-17,-21,-61,-52,-24,-68v9,0,48,37,62,49", + "w": 223 + }, + "y": { + "d": "44,-65v22,33,70,4,99,-8v5,-4,28,-15,41,-31r17,0v25,47,-26,70,-40,114v-5,4,-9,8,-10,21v-16,12,-11,33,-27,51v-5,18,-12,43,-23,71v-1,-1,-2,34,-18,29v-12,1,-22,-12,-22,-23v20,-70,24,-65,68,-177v-47,16,-111,8,-116,-39v-11,-13,-7,-62,8,-62v18,0,22,26,23,54", + "w": 216 + }, + "z": { + "d": "189,-43v9,-1,46,-6,41,12v0,7,-5,13,-15,14v-45,6,-148,24,-181,13v0,-3,-5,-8,-14,-15v5,-44,66,-46,90,-85v-15,-18,-84,21,-84,-14v0,-10,5,-17,14,-18v33,-3,79,-13,109,-3v4,-2,14,11,12,15v0,23,-26,51,-78,84v28,10,73,-3,106,-3", + "w": 244 + }, + "{": { + "d": "94,-303v27,-9,90,-14,79,26v-20,17,-55,-5,-87,13v-4,1,-6,4,-6,8v33,42,31,44,7,85v-6,10,-13,16,-13,13v5,6,17,17,15,31r-33,78v7,35,28,49,57,63r49,0v7,42,-51,41,-86,20v-43,-13,-51,-51,-56,-89v-2,-25,25,-54,27,-71v-3,-4,-46,-5,-41,-21v2,-10,-3,-29,11,-25v2,0,51,-17,52,-38v4,-3,-25,-23,-25,-49v0,-41,8,-30,50,-44", + "w": 179 + }, + "|": { + "d": "30,-308v26,5,14,50,15,80v5,78,-8,153,-3,225v-2,15,-1,31,-11,36v-8,-3,-25,-22,-25,-32r9,-183v0,-40,0,-78,1,-112v0,-4,9,-15,14,-14", + "w": 63 + }, + "}": { + "d": "47,-298v34,-17,118,-18,112,36v6,25,-76,98,-69,103v4,16,39,7,44,28v7,34,-34,17,-37,39v8,29,49,83,23,123v-15,23,-43,26,-73,46v-34,8,-43,11,-49,-17v1,-15,30,-15,33,-20v24,-12,70,-27,55,-61v-14,-33,-37,-68,-19,-103v-46,-50,46,-100,60,-141v-10,-16,-68,6,-77,-12", + "w": 143 + }, + "~": { + "d": "7,-254v2,-6,59,-50,67,-46v11,-1,35,19,46,26v5,0,27,-10,66,-31v21,8,-1,25,-7,38v-27,21,-48,31,-65,31v-24,-11,-37,-39,-65,-9v-7,7,-26,36,-42,11v3,-5,-3,-17,0,-20", + "w": 199 + }, + "\u00a0": { + "w": 179 + }, + "\u00a1": { + "d": "86,-197v8,16,-7,41,-24,25v-11,-11,-4,-16,-3,-29v13,0,15,-2,27,4xm46,-107v4,-8,11,-16,23,-7v19,26,-5,57,-6,87v-7,0,-5,18,-9,28v0,14,-17,52,-11,70v-2,7,-15,28,-25,12v-4,-6,-15,-7,-6,-16v2,-39,14,-96,34,-174", + "w": 95 + }, + "\u00a2": { + "d": "105,-188v13,-12,14,-18,26,-15v7,23,7,15,-3,49v6,0,18,14,17,20v-3,5,-12,19,-26,13v-14,1,-14,5,-16,21v10,10,46,-13,38,18v-9,17,-23,16,-54,20v-17,16,-4,55,-29,60v-37,-10,19,-64,-24,-71v-20,-10,-37,-47,-6,-62v23,-20,73,-4,77,-53xm65,-101v4,-9,7,-8,3,-13v-14,4,-22,10,-3,13", + "w": 154 + }, + "\u00a3": { + "d": "153,-170v3,22,62,0,49,39v-18,6,-31,12,-58,9v-12,-1,-17,30,-23,39v19,26,50,56,91,35v9,-2,27,-13,27,4v0,27,-27,39,-58,42v-32,-5,-59,-19,-78,-39v-6,1,-35,44,-57,39v-25,0,-37,-15,-37,-46v0,-41,43,-53,73,-50v4,1,12,-18,12,-21v-7,-15,-49,0,-44,-30v-2,-31,31,-16,60,-19v16,-30,25,-119,93,-113v16,2,75,16,50,44v-4,5,-7,7,-12,8v-18,-12,-32,-18,-41,-18v-35,-1,-38,52,-47,77xm43,-45v4,5,12,-2,11,-9v-1,2,-12,1,-11,9", + "w": 242 + }, + "\u00a4": { + "d": "308,-133r-200,16v-2,1,-6,4,-10,10v70,-2,144,-14,211,-8v3,0,8,4,13,8v-1,4,-3,9,-9,17v-57,11,-164,6,-219,25v26,32,112,25,173,25v9,0,35,2,35,19v0,9,-4,13,-12,14v-115,12,-146,23,-211,-19v-12,-4,-22,-9,-25,-27v-6,-29,-61,3,-43,-49v17,-1,36,7,42,-12v-32,7,-36,-39,-11,-40v29,14,63,-25,73,-30v52,-25,72,-44,142,-44v23,0,21,41,-1,39v-35,-3,-61,9,-102,31v2,2,5,4,8,4v18,-6,101,-9,115,-9v7,0,55,13,31,30", + "w": 312 + }, + "\u20ac": { + "d": "308,-133r-200,16v-2,1,-6,4,-10,10v70,-2,144,-14,211,-8v3,0,8,4,13,8v-1,4,-3,9,-9,17v-57,11,-164,6,-219,25v26,32,112,25,173,25v9,0,35,2,35,19v0,9,-4,13,-12,14v-115,12,-146,23,-211,-19v-12,-4,-22,-9,-25,-27v-6,-29,-61,3,-43,-49v17,-1,36,7,42,-12v-32,7,-36,-39,-11,-40v29,14,63,-25,73,-30v52,-25,72,-44,142,-44v23,0,21,41,-1,39v-35,-3,-61,9,-102,31v2,2,5,4,8,4v18,-6,101,-9,115,-9v7,0,55,13,31,30", + "w": 312 + }, + "\u00a5": { + "d": "31,-248v30,-3,64,64,74,59v37,-22,77,-65,107,-82v20,-11,34,18,21,32v-28,19,-52,38,-70,57v-18,8,-40,21,-35,60v2,19,39,7,64,7v25,0,16,21,2,27v-36,16,-46,8,-68,18v6,11,101,-20,66,24v-21,11,-42,12,-75,20v-2,1,-5,6,-10,18v-8,3,-11,10,-24,8v-7,-17,-2,-18,-9,-26v-13,5,-39,3,-53,-2v-10,-17,-7,-27,0,-34v23,-1,45,1,64,-5v-11,-7,-28,-4,-64,-6v-13,-8,-15,-24,-6,-35v33,-2,102,9,76,-37v-14,-14,-33,-38,-60,-66v-10,-10,-8,-28,0,-37", + "w": 219 + }, + "\u00a7": { + "d": "141,-115v12,10,29,36,28,56v-4,68,-129,69,-152,16v-1,-12,-10,-22,8,-23v17,3,47,21,67,23v16,1,40,-8,38,-21v-8,-49,-119,-30,-117,-85v1,-28,15,-45,-3,-64v-1,-53,55,-61,103,-62v15,-5,6,-5,20,-2v16,17,23,27,23,30v-1,26,-29,7,-45,7v-21,0,-51,2,-62,17v19,14,87,8,97,43v18,14,16,57,-5,65xm64,-147r57,17v10,-28,-22,-43,-47,-44v-25,-1,-35,19,-10,27", + "w": 174 + }, + "\u00a8": { + "d": "124,-259v0,9,-4,13,-12,13v-18,0,-22,-21,-17,-35v19,-1,30,1,29,22xm23,-285v7,2,30,9,29,18v1,10,-9,19,-18,19v-19,0,-28,-26,-11,-37", + "w": 136 + }, + "\u00a9": { + "d": "102,-29v-74,5,-124,-84,-70,-140v22,-22,53,-35,97,-38v46,-4,88,49,74,100v0,44,-51,75,-101,78xm96,-66v42,-3,75,-23,75,-69v0,-23,-4,-38,-44,-38v-16,0,-33,6,-49,20v36,-4,55,-12,62,20v-5,16,-49,1,-50,21v10,15,53,-14,54,11v0,18,-14,27,-42,27v-22,1,-46,-11,-46,-31v0,-25,7,-39,20,-44v-1,-1,-2,-2,-3,-2v-51,22,-32,89,23,85", + "w": 217 + }, + "\u00aa": { + "d": "6,-265v1,-31,58,-53,80,-22v-11,14,25,28,25,36v-2,8,-15,12,-27,10v-22,-29,-68,19,-78,-24xm52,-281v-8,1,-24,10,-9,13v11,1,24,-10,9,-13", + "w": 117 + }, + "\u00ab": { + "d": "191,-64v16,6,87,37,53,63v-39,-9,-71,-28,-107,-40v-14,-13,-13,-34,10,-47v27,-15,48,-55,84,-62v9,-2,21,10,21,18r-13,21v-16,5,-44,22,-51,41v0,4,1,6,3,6xm71,-65v17,6,87,35,55,62v-39,-8,-66,-27,-108,-40v-14,-13,-13,-36,10,-46v23,-18,50,-56,84,-63v9,-2,21,10,21,18r-13,22v-20,6,-32,17,-51,37v0,3,-1,11,2,10", + "w": 265 + }, + "\u00ac": { + "d": "141,-99v47,7,103,-3,149,6v14,24,18,15,10,39v-10,34,-7,31,-26,76v-4,6,-15,8,-16,21v-4,2,-4,1,-13,5v-22,-33,-4,-33,16,-104v-5,-9,-28,-4,-38,-6r-183,4v-14,0,-41,-29,-17,-36v31,-9,82,5,118,-5", + "w": 315 + }, + "\u00ae": { + "d": "75,-194v78,-29,116,9,130,84v-2,42,-22,47,-57,67v-74,20,-161,-19,-129,-110v6,-18,29,-34,57,-40xm46,-86v51,36,84,21,129,-15v7,-15,0,-39,-10,-49v-13,-37,-49,-26,-86,-18v-28,7,-49,46,-33,82xm72,-123v-5,-43,68,-57,75,-14v-17,26,-18,17,3,32v2,25,-25,18,-45,7r-4,-4v-1,8,-3,20,-12,24v-10,-3,-21,-34,-17,-45xm112,-135v-10,-1,-20,13,-9,14v6,-6,9,-11,9,-14", + "w": 217 + }, + "\u00af": { + "d": "63,-295v28,-7,73,10,105,7v11,1,6,8,5,19v-37,21,-72,11,-136,11v-23,0,-31,-14,-27,-36v12,-15,40,0,53,-1", + "w": 183 + }, + "\u00b0": { + "d": "106,-268v0,36,-35,38,-51,46v-48,5,-60,-58,-25,-78v33,-11,76,-9,76,32xm38,-257v16,7,39,2,38,-17v-13,-9,-28,-1,-32,11v-5,3,-7,0,-6,6", + "w": 114 + }, + "\u00b1": { + "d": "93,-163v-7,46,76,-4,46,47v-14,6,-27,13,-38,8v-24,2,-14,28,-28,44r-14,0v-7,-12,-5,-15,-7,-33v-12,-7,-41,-1,-37,-24v2,-11,23,-17,36,-14r28,-38v4,0,9,4,14,10xm113,-27v-12,18,-58,27,-85,24v-16,2,-22,-23,-13,-36v28,-7,85,-11,98,12", + "w": 151 + }, + "\u00b4": { + "d": "52,-284v29,-11,50,-34,62,-14v3,12,-86,54,-94,56v-14,0,-16,-12,-12,-23v11,-5,25,-11,44,-19", + "w": 120 + }, + "\u00b6": { + "d": "121,-237v21,-9,44,-13,63,-1v-1,7,5,6,7,11r-4,190v-2,33,4,39,-15,40v-16,1,-10,-20,-10,-33r4,-161v0,-17,-1,-34,-16,-25v2,10,1,23,1,35v-9,46,-6,75,-15,156v-3,4,-7,5,-12,5v-17,-10,-3,-89,-10,-115v-43,14,-98,10,-101,-29v-4,-53,59,-63,104,-75v3,1,4,2,4,2xm95,-204v2,9,-30,50,1,50v35,0,23,-13,29,-43v0,-1,-2,-7,-4,-15v-12,-1,-14,2,-26,8", + "w": 206 + }, + "\u00b8": { + "d": "74,16v32,2,49,14,55,36v-3,7,-14,31,-29,33v-28,4,-57,11,-88,14v-19,-6,-13,-31,8,-33v20,-1,59,-5,73,-14v-17,-14,-68,8,-53,-37v9,-10,2,-28,24,-30v8,8,13,17,10,31", + "w": 129 + }, + "\u00ba": { + "d": "13,-273v1,-31,56,-41,83,-18v36,8,14,48,-9,52v-35,6,-64,-5,-74,-34xm81,-269v-7,-7,-20,-11,-29,-6v5,13,13,11,29,6", + "w": 128 + }, + "\u00bb": { + "d": "120,-129v9,-33,48,-10,64,5v9,20,86,52,50,86v-36,11,-66,31,-107,40v-6,-7,-9,-13,-9,-17v-2,-13,50,-46,63,-46v11,-18,-33,-42,-48,-47xm1,-128v10,-33,46,-8,64,6v8,19,86,50,51,85v-40,13,-69,30,-108,40v-6,-7,-8,-12,-8,-16v-2,-14,50,-46,63,-47v7,-13,-9,-20,-19,-30v-10,-9,-20,-15,-30,-17", + "w": 252 + }, + "\u00bf": { + "d": "181,-247v3,1,31,2,29,15v-4,22,-37,27,-41,4v1,-5,7,-20,12,-19xm161,-34v-45,-1,-105,19,-124,51v0,11,18,17,54,17v39,0,82,-13,112,4v-10,35,-58,31,-100,31v-47,0,-80,-10,-99,-31v-10,-56,22,-73,64,-90v8,-3,32,-9,74,-18v21,-15,7,-62,22,-92v-1,-5,-1,-11,4,-12v16,0,24,7,24,22v-8,30,-8,73,-17,111v-3,5,-7,7,-14,7", + "w": 213 + }, + "\u00c0": { + "d": "161,-217v20,53,23,124,54,170v-2,20,-34,9,-42,0v-27,-12,-78,-18,-101,-18v-26,6,-29,51,-54,63v-18,-4,-19,-30,-3,-38v5,-9,15,-16,8,-29v1,-12,23,-9,26,-19v6,-10,11,-20,20,-27r70,-121v12,-4,16,4,22,19xm82,-91v17,3,62,7,86,13v-13,-33,-13,-80,-29,-109v-15,30,-38,63,-57,96xm150,-268v14,10,54,14,37,41v-28,-7,-62,-22,-100,-42v-2,-3,-2,-26,5,-23v16,4,42,17,58,24" + }, + "\u00c1": { + "d": "161,-217v20,53,23,124,54,170v-2,20,-34,9,-42,0v-27,-12,-78,-18,-101,-18v-26,6,-29,51,-54,63v-18,-4,-19,-30,-3,-38v5,-9,15,-16,8,-29v1,-12,23,-9,26,-19v6,-10,11,-20,20,-27r70,-121v12,-4,16,4,22,19xm82,-91v17,3,62,7,86,13v-13,-33,-13,-80,-29,-109v-15,30,-38,63,-57,96xm84,-250v31,-5,83,-53,100,-31v0,5,-11,15,-35,28v-16,5,-51,28,-53,25v-14,1,-16,-11,-12,-22" + }, + "\u00c2": { + "d": "161,-217v20,53,23,124,54,170v-2,20,-34,9,-42,0v-27,-12,-78,-18,-101,-18v-26,6,-29,51,-54,63v-18,-4,-19,-30,-3,-38v5,-9,15,-16,8,-29v1,-12,23,-9,26,-19v6,-10,11,-20,20,-27r70,-121v12,-4,16,4,22,19xm82,-91v17,3,62,7,86,13v-13,-33,-13,-80,-29,-109v-15,30,-38,63,-57,96xm202,-219v-27,-6,-40,-26,-61,-37v-21,7,-39,46,-65,23v-2,-4,-3,-10,-4,-14v19,-4,43,-32,61,-43v27,6,40,22,62,37v12,8,18,17,18,25v0,6,-3,9,-11,9" + }, + "\u00c3": { + "d": "161,-217v20,53,23,124,54,170v-2,20,-34,9,-42,0v-27,-12,-78,-18,-101,-18v-26,6,-29,51,-54,63v-18,-4,-19,-30,-3,-38v5,-9,15,-16,8,-29v1,-12,23,-9,26,-19v6,-10,11,-20,20,-27r70,-121v12,-4,16,4,22,19xm82,-91v17,3,62,7,86,13v-13,-33,-13,-80,-29,-109v-15,30,-38,63,-57,96xm100,-285v26,-19,54,19,69,22v4,0,15,-5,34,-13v23,-9,22,-17,31,-12v3,11,-9,9,-7,21v-26,20,-46,30,-59,30v-3,3,-50,-26,-49,-29v-12,1,-31,35,-51,32v-3,-8,-5,-14,-5,-18v10,-9,16,-17,37,-33" + }, + "\u00c4": { + "d": "161,-217v20,53,23,124,54,170v-2,20,-34,9,-42,0v-27,-12,-78,-18,-101,-18v-26,6,-29,51,-54,63v-18,-4,-19,-30,-3,-38v5,-9,15,-16,8,-29v1,-12,23,-9,26,-19v6,-10,11,-20,20,-27r70,-121v12,-4,16,4,22,19xm82,-91v17,3,62,7,86,13v-13,-33,-13,-80,-29,-109v-15,30,-38,63,-57,96xm187,-259v0,8,-4,13,-12,13v-18,0,-21,-20,-16,-34v18,-1,28,2,28,21xm90,-284v7,3,28,11,28,18v0,9,-9,18,-18,17v-17,0,-25,-24,-10,-35" + }, + "\u00c5": { + "d": "161,-217v20,53,23,124,54,170v-2,20,-34,9,-42,0v-27,-12,-78,-18,-101,-18v-26,6,-29,51,-54,63v-18,-4,-19,-30,-3,-38v5,-9,15,-16,8,-29v1,-12,23,-9,26,-19v6,-10,11,-20,20,-27r70,-121v12,-4,16,4,22,19xm82,-91v17,3,62,7,86,13v-13,-33,-13,-80,-29,-109v-15,30,-38,63,-57,96xm112,-239v-31,-17,-9,-61,29,-56v12,2,22,3,33,12v24,39,-30,62,-62,44xm119,-262v2,14,41,8,41,-4v0,-4,-8,-6,-24,-9v-10,-2,-17,10,-17,13" + }, + "\u00c6": { + "d": "335,-259v0,30,-102,12,-122,34v10,21,2,79,16,100v24,-6,59,-13,86,-16v23,-2,32,21,13,26r-103,29v-3,22,-4,38,8,43v28,-5,60,-6,86,-14v5,-1,14,7,14,11v6,16,-90,40,-107,40v-29,0,-39,-19,-32,-46v-2,-4,0,-26,-9,-28v-29,2,-58,6,-88,6v-31,0,-40,74,-82,73v-18,-23,4,-37,12,-50v40,-65,112,-126,165,-207v20,-17,69,-11,112,-13v21,0,31,4,31,12xm123,-111v28,1,44,-2,67,-10v-4,-22,5,-49,-7,-65v-3,6,-65,61,-60,75", + "w": 348 + }, + "\u00c7": { + "d": "48,-108v-12,70,90,71,159,67r138,-9v9,-1,7,9,7,17v-37,16,-80,27,-103,21v-14,9,-40,3,-67,9v-30,0,-64,1,-100,-10v-6,-1,-10,-4,-10,-8v-32,-12,-46,-31,-63,-56v-16,-61,47,-103,83,-121v82,-42,118,-45,200,-60v21,-4,36,34,11,37v-90,11,-148,31,-225,77v-12,8,-23,20,-30,36xm172,18v29,4,47,14,53,35v-2,7,-14,31,-27,31v-28,7,-55,9,-84,14v-18,-5,-13,-32,7,-32v21,0,55,-5,69,-13v-16,-14,-63,10,-50,-35v9,-10,1,-27,23,-29v7,8,11,16,9,29", + "w": 331 + }, + "\u00c8": { + "d": "49,-160v1,-4,-10,-9,-15,-8v-15,-35,32,-30,57,-31r142,-8v2,1,30,7,40,10v-52,16,-133,17,-190,30v-7,9,-12,24,-15,47v26,10,102,-6,141,3v1,3,1,6,2,10v-36,18,-92,12,-149,21v-11,9,-16,41,-16,51v55,-1,111,-21,168,-13v15,-8,48,1,31,18v-53,16,-130,13,-198,29r-39,-8v-4,-19,17,-53,20,-76v-1,0,-7,-11,-9,-18v18,-7,22,-28,30,-57xm184,-236v6,9,5,13,0,23v-28,-7,-62,-21,-100,-41v-3,-2,-3,-27,5,-23v34,11,60,25,95,41", + "w": 252 + }, + "\u00c9": { + "d": "49,-160v1,-4,-10,-9,-15,-8v-15,-35,32,-30,57,-31r142,-8v2,1,30,7,40,10v-52,16,-133,17,-190,30v-7,9,-12,24,-15,47v26,10,102,-6,141,3v1,3,1,6,2,10v-36,18,-92,12,-149,21v-11,9,-16,41,-16,51v55,-1,111,-21,168,-13v15,-8,48,1,31,18v-53,16,-130,13,-198,29r-39,-8v-4,-19,17,-53,20,-76v-1,0,-7,-11,-9,-18v18,-7,22,-28,30,-57xm133,-248v27,-11,48,-32,59,-14v3,11,-79,52,-88,53v-14,1,-16,-11,-12,-21v10,-4,23,-11,41,-18", + "w": 252 + }, + "\u00ca": { + "d": "49,-160v1,-4,-10,-9,-15,-8v-15,-35,32,-30,57,-31r142,-8v2,1,30,7,40,10v-52,16,-133,17,-190,30v-7,9,-12,24,-15,47v26,10,102,-6,141,3v1,3,1,6,2,10v-36,18,-92,12,-149,21v-11,9,-16,41,-16,51v55,-1,111,-21,168,-13v15,-8,48,1,31,18v-53,16,-130,13,-198,29r-39,-8v-4,-19,17,-53,20,-76v-1,0,-7,-11,-9,-18v18,-7,22,-28,30,-57xm199,-211v-27,-6,-39,-26,-60,-37v-21,7,-40,47,-65,22v-2,-7,-2,-7,-4,-13v18,-5,44,-31,61,-43v27,6,41,22,62,37v12,9,18,17,18,25v0,6,-4,9,-12,9", + "w": 252 + }, + "\u00cb": { + "d": "49,-160v1,-4,-10,-9,-15,-8v-15,-35,32,-30,57,-31r142,-8v2,1,30,7,40,10v-52,16,-133,17,-190,30v-7,9,-12,24,-15,47v26,10,102,-6,141,3v1,3,1,6,2,10v-36,18,-92,12,-149,21v-11,9,-17,41,-17,51v55,0,112,-21,169,-13v15,-8,48,1,31,18v-53,16,-130,13,-198,29r-39,-8v-3,-21,17,-53,20,-76v-1,0,-7,-11,-9,-18v18,-7,22,-28,30,-57xm191,-236v0,8,-4,13,-12,13v-17,0,-19,-19,-16,-34v18,-1,29,1,28,21xm95,-261v7,3,29,9,28,18v0,7,-9,17,-18,17v-18,0,-26,-25,-10,-35", + "w": 252 + }, + "\u00cc": { + "d": "33,-5v-9,-6,-9,-12,-9,-36v0,-71,8,-119,22,-144v8,-13,14,-20,19,-20v27,20,-11,87,-10,120r-15,76v-1,1,-4,2,-7,4xm72,-247v7,6,55,15,36,40v-28,-7,-61,-21,-99,-41v-3,-2,-3,-27,5,-23v18,3,41,17,58,24", + "w": 111 + }, + "\u00cd": { + "d": "26,-5v-9,-6,-9,-12,-9,-36v0,-71,7,-119,21,-144v8,-13,14,-20,19,-20v28,19,-7,89,-10,120v-2,21,-8,47,-14,76v-2,1,-2,0,-7,4xm6,-233v31,-6,83,-53,101,-31v2,11,-80,53,-89,53v-14,1,-14,-11,-12,-22", + "w": 104 + }, + "\u00ce": { + "d": "53,-9v-15,7,-16,-3,-16,-32v0,-71,7,-119,21,-144v8,-13,14,-20,19,-20v28,19,-7,89,-10,120v-2,21,-8,47,-14,76xm137,-209v-27,-6,-40,-26,-61,-37v-8,0,-9,4,-13,10v-11,13,-50,37,-56,0v18,-5,43,-32,61,-43v28,5,40,21,62,36v12,9,18,17,18,25v0,6,-4,9,-11,9", + "w": 144 + }, + "\u00cf": { + "d": "33,-5v-9,-6,-9,-12,-9,-36v0,-71,8,-119,22,-144v8,-13,14,-20,19,-20v27,20,-11,87,-10,120r-15,76v-1,1,-4,2,-7,4xm111,-222v0,8,-4,12,-12,12v-18,0,-19,-19,-16,-33v18,-1,29,1,28,21xm15,-247v8,2,29,9,28,17v0,21,-37,24,-36,1v0,-7,2,-13,8,-18", + "w": 110 + }, + "\u00d1": { + "d": "224,-182v1,-17,15,-24,22,-38v20,0,13,10,3,33v-3,36,-25,52,-28,94v-10,24,-30,55,-29,82r-19,7v-32,-8,-36,-70,-58,-111v-2,-23,-7,-27,-19,-54v-28,36,-41,93,-71,133v-9,5,-20,-9,-20,-17r73,-149v9,-24,31,-5,36,7v19,41,31,98,53,139v22,-35,34,-69,50,-118v2,-3,3,-3,7,-8xm203,-257v22,-8,41,-24,65,-26v3,11,-8,9,-7,21v-26,20,-46,31,-59,31v-2,3,-49,-27,-49,-29v-11,0,-32,31,-46,32v-11,-2,-12,-21,-4,-23v4,-6,28,-30,48,-34v17,-4,43,28,52,28", + "w": 219 + }, + "\u00d2": { + "d": "62,-184v78,-31,249,-50,238,74v-6,65,-102,105,-179,115v-77,-7,-152,-71,-101,-149v2,-5,24,-33,42,-40xm279,-120v14,-38,-47,-64,-85,-61v-20,-9,-41,7,-62,0v-11,7,-54,12,-66,24v0,20,-51,35,-38,66v-1,43,50,67,96,67v44,0,162,-55,155,-96xm161,-262v14,10,52,13,37,41v-28,-7,-62,-21,-100,-41v-3,-3,-3,-26,5,-24v16,5,42,17,58,24", + "w": 273 + }, + "\u00d3": { + "d": "62,-184v78,-31,249,-50,238,74v-6,65,-102,105,-179,115v-77,-7,-152,-71,-101,-149v2,-5,24,-33,42,-40xm279,-120v14,-38,-47,-64,-85,-61v-20,-9,-41,7,-62,0v-11,7,-54,12,-66,24v0,20,-51,35,-38,66v-1,43,50,67,96,67v44,0,162,-55,155,-96xm142,-250v27,-11,47,-32,59,-14v2,11,-80,53,-89,53v-13,1,-15,-11,-12,-21v10,-5,24,-11,42,-18", + "w": 273 + }, + "\u00d4": { + "d": "62,-184v78,-31,249,-50,238,74v-6,65,-102,105,-179,115v-77,-7,-152,-71,-101,-149v2,-5,24,-33,42,-40xm279,-120v14,-38,-47,-64,-85,-61v-20,-9,-41,7,-62,0v-11,7,-54,12,-66,24v0,20,-51,35,-38,66v-1,43,50,67,96,67v44,0,162,-55,155,-96xm157,-282v17,18,52,34,54,63v-24,12,-52,-36,-53,-29r-42,34v-23,-4,-6,-31,5,-34v1,1,27,-37,36,-34", + "w": 273 + }, + "\u00d5": { + "d": "62,-184v78,-31,249,-50,238,74v-6,65,-102,105,-179,115v-77,-7,-152,-71,-101,-149v2,-5,24,-33,42,-40xm279,-120v14,-38,-47,-64,-85,-61v-20,-9,-41,7,-62,0v-11,7,-54,12,-66,24v0,20,-51,35,-38,66v-1,43,50,67,96,67v44,0,162,-55,155,-96xm116,-270v26,-19,54,19,69,22v4,0,15,-5,34,-13v23,-10,22,-16,31,-12v3,11,-8,9,-7,21v-45,28,-47,42,-88,16v-29,-19,-12,-20,-43,2v-8,5,-12,18,-23,15v-13,-3,-12,-20,-4,-23v4,-6,14,-15,31,-28", + "w": 273 + }, + "\u00d6": { + "d": "62,-184v78,-31,249,-50,238,74v-6,65,-102,105,-179,115v-77,-7,-152,-71,-101,-149v2,-5,24,-33,42,-40xm279,-120v14,-38,-47,-64,-85,-61v-20,-9,-41,7,-62,0v-11,7,-54,12,-66,24v0,20,-51,35,-38,66v-1,43,50,67,96,67v44,0,162,-55,155,-96xm197,-229v0,8,-4,13,-12,13v-17,0,-19,-19,-16,-34v18,-1,29,1,28,21xm101,-254v7,3,28,9,27,18v1,8,-8,17,-17,17v-18,0,-26,-24,-10,-35", + "w": 273 + }, + "\u00d8": { + "d": "76,-211v41,-13,100,-22,140,-3v26,-19,40,-29,44,-29v10,0,15,7,15,20v0,15,-23,23,-30,35v23,39,29,114,-21,139v-36,19,-102,35,-147,18v-14,-5,-29,29,-46,35v-25,-13,-19,-24,3,-56v-9,-17,-28,-27,-28,-60v0,-38,23,-72,70,-99xm107,-66v55,15,125,-12,123,-70v0,-16,-5,-25,-13,-29r-110,95r0,4xm39,-108v-1,3,17,31,22,27v8,-6,109,-90,123,-106v-15,-11,-43,1,-63,2v-33,10,-80,35,-82,77", + "w": 270 + }, + "\u00d9": { + "d": "281,-202v6,67,-30,121,-71,152v-3,14,-47,26,-60,39v-41,20,-110,1,-125,-26v-24,-44,-28,-84,-8,-127v12,-26,23,-38,37,-22v-2,2,-3,5,-3,10v-34,26,-30,116,5,134v22,32,86,-1,109,-8v38,-28,104,-64,97,-149v2,-10,7,-8,19,-3xm151,-243v14,10,54,14,37,41v-28,-7,-61,-22,-99,-42v-3,-2,-4,-25,4,-23v16,5,42,17,58,24", + "w": 262 + }, + "\u00da": { + "d": "281,-202v6,67,-30,121,-71,152v-3,14,-47,26,-60,39v-41,20,-110,1,-125,-26v-24,-44,-28,-84,-8,-127v12,-26,23,-38,37,-22v-2,2,-3,5,-3,10v-34,26,-30,116,5,134v22,32,86,-1,109,-8v38,-28,104,-64,97,-149v2,-10,7,-8,19,-3xm194,-265v3,-1,11,4,11,6v3,12,-81,52,-89,54v-14,0,-13,-9,-12,-22", + "w": 262 + }, + "\u00db": { + "d": "281,-202v6,67,-30,121,-71,152v-3,14,-47,26,-60,39v-41,20,-110,1,-125,-26v-24,-44,-28,-84,-8,-127v12,-26,23,-38,37,-22v-2,2,-3,5,-3,10v-34,26,-30,116,5,134v22,32,86,-1,109,-8v38,-28,104,-64,97,-149v2,-10,7,-8,19,-3xm150,-266v24,11,58,27,73,46v0,5,-3,6,-10,6v-28,2,-61,-30,-63,-25v-10,0,-57,40,-69,23v3,-10,-8,-15,8,-19v17,-1,34,-29,61,-31", + "w": 262 + }, + "\u00dc": { + "d": "281,-202v6,67,-30,121,-71,152v-3,14,-47,26,-60,39v-41,20,-110,1,-125,-26v-24,-44,-28,-84,-8,-127v12,-26,23,-38,37,-22v-2,2,-3,5,-3,10v-34,26,-29,116,5,134v22,32,86,-1,109,-8v38,-28,104,-64,97,-149v2,-10,7,-8,19,-3xm197,-227v0,8,-4,13,-12,13v-18,0,-21,-20,-16,-34v18,-1,28,2,28,21xm101,-252v7,3,27,10,27,18v0,8,-9,18,-18,17v-18,-1,-24,-25,-9,-35", + "w": 262 + }, + "\u00df": { + "d": "33,10v-29,4,-28,-32,-16,-70v18,-58,17,-137,56,-176v12,-24,46,-58,82,-43v20,8,47,24,47,54v0,30,-62,59,-67,90v33,23,56,33,63,63v-18,21,-22,36,-48,54v-24,17,-27,41,-53,16v-2,-19,7,-35,24,-42v15,-13,26,-22,34,-40v-13,-17,-78,-29,-56,-70v-3,-27,64,-54,66,-86v-8,-25,-41,-4,-52,8v-29,30,-47,83,-51,141v-17,25,-8,71,-29,101" + }, + "\u00e0": { + "d": "118,-53v10,4,55,41,62,47v0,7,-5,16,-12,16r-57,-28v-20,3,-40,19,-61,18v-10,2,-43,-17,-42,-36v0,-14,7,-40,27,-41v39,-26,92,-36,104,9v0,6,-2,11,-9,15v-32,-24,-64,-6,-84,11v8,15,58,-17,72,-11xm99,-137v7,6,56,14,37,40v-28,-7,-62,-21,-100,-41v-2,-3,-2,-26,5,-23v16,4,42,17,58,24", + "w": 173 + }, + "\u00e1": { + "d": "118,-53v10,4,55,41,62,47v0,7,-5,16,-12,16r-57,-28v-20,3,-40,19,-61,18v-10,2,-43,-17,-42,-36v0,-14,7,-40,27,-41v39,-26,92,-36,104,9v0,6,-2,11,-9,15v-32,-24,-64,-6,-84,11v8,15,58,-17,72,-11xm32,-117v24,-3,85,-55,101,-32v3,11,-80,53,-89,53v-13,2,-14,-10,-12,-21", + "w": 173 + }, + "\u00e2": { + "d": "118,-53v10,4,55,41,62,47v0,7,-5,16,-12,16r-57,-28v-20,3,-40,19,-61,18v-10,2,-43,-17,-42,-36v0,-14,7,-40,27,-41v39,-26,92,-36,104,9v0,6,-2,11,-9,15v-32,-24,-64,-6,-84,11v8,15,58,-17,72,-11xm147,-97v-27,-6,-39,-26,-60,-37v-21,7,-38,46,-65,23v-2,-5,-3,-10,-4,-14v18,-4,43,-31,61,-42v28,5,40,21,62,36v12,8,18,17,18,25v0,6,-4,9,-12,9", + "w": 173 + }, + "\u00e3": { + "d": "118,-53v10,4,55,41,62,47v0,7,-5,16,-12,16r-57,-28v-20,3,-40,19,-61,18v-10,2,-43,-17,-42,-36v0,-14,7,-40,27,-41v39,-26,92,-36,104,9v0,6,-2,11,-9,15v-32,-24,-64,-6,-84,11v8,15,58,-17,72,-11xm114,-136v22,-8,41,-24,64,-26v3,11,-7,10,-7,21v-26,20,-45,30,-58,30v-3,3,-49,-26,-49,-28v-10,-1,-32,35,-51,31v-12,-32,8,-29,32,-51v24,-21,54,20,69,23", + "w": 173 + }, + "\u00e4": { + "d": "118,-53v10,4,55,41,62,47v0,7,-5,16,-12,16r-57,-28v-20,3,-40,19,-61,18v-32,5,-66,-64,-15,-77v39,-26,92,-36,104,9v0,6,-3,11,-9,15v-32,-24,-64,-6,-84,11v8,15,58,-17,72,-11xm142,-119v0,8,-4,13,-12,13v-18,0,-21,-20,-16,-34v18,-1,28,2,28,21xm46,-144v7,3,28,9,27,18v1,8,-9,18,-18,17v-18,-1,-25,-25,-9,-35", + "w": 173 + }, + "\u00e5": { + "d": "118,-53v10,4,55,41,62,47v0,7,-5,16,-12,16r-57,-28v-20,3,-40,19,-61,18v-10,2,-43,-17,-42,-36v0,-14,7,-40,27,-41v39,-26,92,-36,104,9v0,6,-2,11,-9,15v-32,-24,-64,-6,-84,11v8,15,58,-17,72,-11xm54,-101v-37,-20,-9,-71,34,-65v13,1,25,3,38,13v27,45,-34,73,-72,52xm61,-128v4,20,48,7,49,-5v0,-5,-9,-7,-28,-10v-12,-2,-21,11,-21,15", + "w": 173 + }, + "\u00e6": { + "d": "145,-44r33,7v2,42,-59,29,-85,16v-6,7,-35,24,-48,15v-19,2,-35,-21,-33,-37v2,-24,5,-19,28,-36v-6,-8,-45,3,-33,-21v21,-22,58,-12,85,-1v6,-5,35,-28,45,-15v20,-4,36,17,36,35v0,23,-4,21,-28,37xm111,-72v12,3,49,-16,19,-17v-5,0,-20,12,-19,17xm74,-50v-14,-4,-48,16,-19,17v4,1,19,-14,19,-17", + "w": 184 + }, + "\u00e7": { + "d": "108,-118v30,-6,56,21,25,33v-24,-6,-39,5,-75,23v-7,4,-12,12,-15,22v31,28,86,3,128,9v3,28,-29,16,-44,28v-53,15,-106,10,-120,-37v0,-48,62,-70,101,-78xm92,18v23,4,45,12,48,32v-2,6,-12,28,-25,28v-24,6,-50,10,-77,13v-16,-4,-11,-28,7,-29v17,-1,51,-4,63,-12v-14,-15,-57,10,-46,-32v9,-8,0,-25,21,-26v6,6,12,14,9,26", + "w": 171 + }, + "\u00e8": { + "d": "108,-124v42,-3,70,39,50,73v-22,-1,-70,12,-94,10v-1,1,-2,3,-2,3v0,3,12,7,35,14v18,0,64,7,30,21v-10,14,-31,6,-53,6v-26,-7,-70,-26,-70,-58v0,-54,48,-65,104,-69xm130,-78v-2,-35,-66,-13,-77,3v16,6,62,6,77,-3xm95,-166v7,6,54,14,37,40v-28,-7,-62,-21,-100,-41v-3,-3,-3,-26,5,-24v16,5,42,18,58,25", + "w": 161 + }, + "\u00e9": { + "d": "108,-124v42,-3,70,39,50,73v-22,-1,-70,12,-94,10v-1,1,-2,3,-2,3v0,3,12,7,35,14v18,0,64,7,30,21v-10,14,-31,6,-53,6v-26,-7,-70,-26,-70,-58v0,-54,48,-65,104,-69xm130,-78v-2,-35,-66,-13,-77,3v16,6,62,6,77,-3xm76,-169v26,-11,48,-32,59,-14v3,10,-80,53,-89,53v-14,1,-14,-10,-12,-21v15,-7,16,-7,42,-18", + "w": 161 + }, + "\u00ea": { + "d": "108,-124v42,-3,70,39,50,73v-22,-1,-70,12,-94,10v-1,1,-2,3,-2,3v0,3,12,7,35,14v18,0,64,7,30,21v-10,14,-31,6,-53,6v-26,-7,-70,-26,-70,-58v0,-54,48,-65,104,-69xm130,-78v-2,-35,-66,-13,-77,3v16,6,62,6,77,-3xm145,-129v-27,-6,-39,-26,-60,-37v-8,0,-10,4,-14,10v-11,15,-51,34,-56,0v17,-4,44,-32,61,-43v28,5,41,21,63,36v12,8,17,17,17,25v0,6,-3,9,-11,9", + "w": 161 + }, + "\u00eb": { + "d": "108,-124v42,-3,70,39,50,73v-22,-1,-70,12,-94,10r-3,3v0,3,12,7,36,14v18,0,64,7,30,21v-10,14,-31,6,-53,6v-26,-7,-67,-27,-71,-58v7,-52,48,-65,105,-69xm130,-78v-2,-35,-66,-13,-77,3v16,6,62,6,77,-3xm140,-144v0,8,-4,12,-12,12v-18,0,-19,-19,-16,-33v18,-1,29,1,28,21xm44,-169v7,3,28,9,28,17v0,9,-9,18,-18,18v-18,0,-25,-24,-10,-35", + "w": 161 + }, + "\u00ec": { + "d": "57,-98v22,5,13,50,11,95v-7,1,-11,2,-20,-4v1,-7,-12,-18,-10,-24v4,-22,-2,-64,19,-67xm70,-139v14,10,54,14,37,41v-28,-7,-61,-22,-99,-42v-3,-2,-3,-25,5,-23v15,5,41,17,57,24", + "w": 109 + }, + "\u00ed": { + "d": "59,-98v20,4,15,53,10,95v-6,1,-11,2,-19,-4v1,-7,-12,-18,-10,-24v4,-22,-4,-65,19,-67xm50,-139v27,-11,49,-32,59,-14v3,11,-80,53,-89,53v-14,1,-14,-12,-11,-22v15,-7,14,-6,41,-17", + "w": 105 + }, + "\u00ee": { + "d": "72,-98v20,5,12,51,10,95v-6,2,-13,1,-20,-4v1,-8,-12,-18,-10,-24v4,-22,-3,-65,20,-67xm134,-94v-26,-7,-39,-25,-60,-37v-7,0,-9,4,-13,10v-14,15,-51,34,-56,-1v18,-4,45,-33,61,-43v27,6,40,22,62,37v12,8,18,17,18,25v0,6,-4,9,-12,9", + "w": 143 + }, + "\u00ef": { + "d": "55,-97v19,5,15,53,10,95v-17,5,-26,-14,-30,-28v6,-20,-3,-65,20,-67xm110,-118v0,8,-4,13,-12,13v-17,0,-19,-19,-16,-34v18,-1,29,1,28,21xm14,-143v6,3,28,8,28,17v0,9,-9,18,-18,18v-18,0,-25,-24,-10,-35", + "w": 107 + }, + "\u00f1": { + "d": "115,-129v34,6,59,50,59,105v0,31,-15,24,-30,17v-15,-29,-5,-42,-20,-81v-35,-13,-68,52,-88,61v-20,-4,-38,-36,-19,-59v0,-12,3,-14,10,-28v11,-8,18,11,27,12xm117,-166v22,-7,41,-23,64,-26v3,11,-7,10,-7,21v-26,20,-45,30,-58,30v-3,3,-49,-26,-49,-28v-10,-1,-32,35,-51,31v-5,-12,-8,-16,0,-23v4,-6,28,-29,48,-33v17,-3,43,28,53,28", + "w": 171 + }, + "\u00f2": { + "d": "102,-132v50,-20,99,16,99,60v0,54,-60,64,-108,79v-50,-2,-110,-48,-76,-100v22,-17,49,-33,85,-39xm136,-104v-34,0,-91,27,-94,47v16,51,125,16,125,-22v0,-17,-10,-25,-31,-25xm115,-181v14,10,51,13,37,40v-28,-7,-62,-21,-100,-41v-3,-2,-3,-26,5,-23v16,5,42,17,58,24", + "w": 191 + }, + "\u00f3": { + "d": "102,-132v50,-20,99,16,99,60v0,54,-60,64,-108,79v-50,-2,-110,-48,-76,-100v22,-17,49,-33,85,-39xm136,-104v-34,0,-91,27,-94,47v16,51,125,16,125,-22v0,-17,-10,-25,-31,-25xm49,-154v24,-3,85,-55,101,-32v3,11,-80,53,-89,53v-14,0,-13,-8,-12,-21", + "w": 191 + }, + "\u00f4": { + "d": "102,-132v50,-20,99,16,99,60v0,54,-60,64,-108,79v-50,-2,-110,-48,-76,-100v22,-17,49,-33,85,-39xm136,-104v-34,0,-91,27,-94,47v16,51,125,16,125,-22v0,-17,-10,-25,-31,-25xm110,-177v-22,6,-38,45,-65,22v-2,-4,-3,-9,-4,-13v18,-4,43,-32,61,-43v27,6,40,21,62,36v12,9,18,17,18,25v1,11,-15,10,-23,7", + "w": 191 + }, + "\u00f5": { + "d": "102,-132v50,-20,99,16,99,60v0,54,-60,64,-108,79v-50,-2,-110,-48,-76,-100v22,-17,49,-33,85,-39xm136,-104v-34,0,-91,27,-94,47v16,51,125,16,125,-22v0,-17,-10,-25,-31,-25xm58,-199v26,-21,54,18,69,22v4,0,15,-5,34,-13v22,-9,21,-16,31,-13v3,11,-9,9,-7,22v-26,20,-46,30,-59,30v-2,4,-49,-28,-49,-29v-11,0,-32,31,-46,32v-12,-3,-13,-21,-4,-23v4,-6,14,-15,31,-28", + "w": 191 + }, + "\u00f6": { + "d": "102,-132v50,-20,99,16,99,60v0,54,-60,64,-108,79v-50,-2,-110,-48,-76,-100v22,-17,49,-33,85,-39xm136,-104v-34,0,-91,27,-94,47v16,51,125,16,125,-22v0,-17,-10,-25,-31,-25xm161,-160v0,8,-4,13,-12,13v-17,0,-19,-19,-16,-34v18,-1,29,1,28,21xm65,-185v7,3,28,9,28,18v0,7,-9,18,-18,17v-18,1,-25,-24,-10,-35", + "w": 191 + }, + "\u00f7": { + "d": "167,-158v-4,3,-7,9,-10,20v-23,4,-34,-8,-29,-31v14,-6,18,1,39,11xm78,-72v-53,11,-53,12,-69,-15v-1,-12,11,-17,22,-14v71,-13,151,-18,230,-24v11,1,21,16,23,28v-28,20,-90,11,-126,16v-36,5,-62,5,-80,9xm123,-40v19,-17,41,-1,41,17v0,13,-6,19,-17,19v-15,0,-29,-14,-24,-36", + "w": 293 + }, + "\u00f8": { + "d": "76,-136v17,7,33,-8,51,0v9,-6,21,-13,36,-21v23,22,-13,31,3,50v11,13,4,21,14,35v-4,5,-1,14,-4,23v-14,23,-45,41,-84,39v-12,2,-29,28,-41,38v-2,-11,-34,-10,-15,-30v3,-7,5,-11,5,-11v-15,-24,-60,-54,-22,-89v23,-21,25,-32,57,-34xm102,-54v18,1,50,-19,30,-32v-12,7,-22,18,-30,32xm85,-92v-14,3,-26,8,-38,17v2,20,17,13,26,0v6,-8,12,-13,12,-17", + "w": 188 + }, + "\u00f9": { + "d": "196,-129v-1,-4,12,-13,15,-13v6,0,8,7,8,21v0,24,-7,25,-13,45v-7,7,-14,21,-24,29v-9,24,-61,45,-89,45v-63,0,-105,-72,-67,-126v24,-3,19,27,18,46v-1,26,23,42,54,40v38,-3,88,-51,98,-87xm126,-166v7,6,56,14,37,40v-28,-7,-62,-22,-100,-42v-2,-3,-2,-26,5,-23v16,4,42,18,58,25", + "w": 213 + }, + "\u00fa": { + "d": "196,-129v-1,-4,12,-13,15,-13v6,0,8,7,8,21v0,24,-7,25,-13,45v-7,7,-14,21,-24,29v-9,24,-61,45,-89,45v-63,0,-105,-72,-67,-126v24,-3,19,27,18,46v-1,26,23,42,54,40v38,-3,88,-51,98,-87xm106,-174v26,-11,48,-32,59,-14v3,11,-81,53,-89,54v-13,1,-15,-12,-11,-22v15,-7,14,-7,41,-18", + "w": 213 + }, + "\u00fb": { + "d": "196,-129v-1,-4,12,-13,15,-13v6,0,8,7,8,21v0,24,-7,25,-13,45v-7,7,-14,21,-24,29v-9,24,-61,45,-89,45v-63,0,-105,-72,-67,-126v24,-3,19,27,18,46v-1,26,23,42,54,40v38,-3,88,-51,98,-87xm172,-143v-27,-6,-39,-26,-60,-37v-8,0,-10,4,-14,10v-11,15,-49,35,-56,0v17,-4,44,-32,61,-43v27,6,41,21,63,36v12,9,17,17,17,25v0,6,-3,9,-11,9", + "w": 213 + }, + "\u00fc": { + "d": "196,-129v-1,-4,12,-13,15,-13v6,0,8,7,8,21v0,24,-7,25,-13,45v-7,7,-14,21,-24,29v-9,24,-61,45,-89,45v-63,0,-105,-72,-67,-126v24,-3,19,27,18,46v-1,26,23,42,54,40v38,-3,88,-51,98,-87xm168,-161v0,8,-3,13,-11,13v-17,0,-20,-19,-17,-34v18,-1,29,1,28,21xm72,-186v7,3,29,9,28,18v0,7,-9,18,-18,17v-18,1,-25,-24,-10,-35", + "w": 213 + }, + "\u00ff": { + "d": "118,85v-11,11,-11,38,-22,61v-2,-1,-2,31,-17,27v-11,0,-21,-10,-21,-22v20,-66,23,-61,64,-168v-22,1,-38,16,-58,4v-22,4,-51,-16,-51,-42v-11,-13,-7,-59,7,-58v16,1,21,24,22,51v21,33,66,5,94,-7v4,-3,26,-14,38,-29r17,0v23,44,-23,59,-34,102v-6,9,-13,9,-13,26v-15,6,-12,33,-27,48v0,2,1,4,1,7xm158,-136v0,8,-4,13,-12,13v-18,0,-21,-20,-16,-34v18,-1,29,1,28,21xm62,-161v7,3,28,9,27,18v1,8,-8,17,-17,17v-18,0,-26,-24,-10,-35", + "w": 190 + }, + "\u0131": { + "d": "43,-103v21,4,16,56,11,100v-7,2,-11,1,-20,-5v0,-7,-13,-18,-11,-25v4,-23,-3,-68,20,-70", + "w": 80 + }, + "\u0152": { + "d": "247,-243v71,4,161,-7,245,-8v17,0,27,6,27,17v-8,27,-70,14,-104,23v-3,1,-52,0,-65,7r0,4v16,16,17,29,17,65v32,10,74,-14,99,16v-14,25,-76,17,-127,24v-17,18,-55,32,-75,51v85,0,128,-3,204,-11v15,-2,21,11,20,29v-78,24,-177,12,-270,24v-24,3,-24,-29,-48,-15v-46,7,-70,4,-105,-4v-19,-18,-42,-22,-52,-55v-10,-34,0,-47,12,-78v-18,-59,48,-78,105,-84v17,-18,103,-13,117,-5xm125,-45v76,-9,186,-43,209,-105v-26,-67,-137,-83,-217,-54v3,34,-45,25,-60,58v-41,48,5,108,68,101", + "w": 492 + }, + "\u0153": { + "d": "185,-54v25,28,107,-17,104,33v-12,12,-60,14,-87,14v0,0,1,1,2,1v-11,1,-39,-9,-50,-17v-28,17,-75,32,-114,7v-22,-14,-34,-11,-34,-41v0,-36,33,-49,48,-75v29,-16,72,-3,95,11v12,-9,48,-27,59,-26v30,0,64,15,65,40v0,7,-6,20,-20,37v-29,1,-44,11,-68,16xm226,-106v-21,-7,-41,-2,-48,13v14,1,42,-7,48,-13xm132,-87v-21,-35,-94,11,-92,24v-2,14,43,21,61,21v25,0,36,-20,31,-45", + "w": 295 + }, + "\u0178": { + "d": "176,-189v35,20,-25,54,-39,72v-26,34,-57,57,-74,104v-10,15,-4,14,-23,3r0,-10v19,-44,27,-46,50,-81v-9,-5,-24,4,-34,4v-38,0,-54,-50,-44,-87v21,-5,18,19,22,35v4,18,15,27,29,27v41,0,60,-39,113,-67xm153,-222v0,8,-3,12,-11,12v-18,0,-21,-19,-16,-33v18,-1,28,2,27,21xm57,-247v8,2,29,9,28,17v0,21,-37,24,-36,1v0,-7,2,-13,8,-18", + "w": 135 + }, + "\u0192": { + "d": "115,-262v-23,6,-39,63,-38,96v1,3,57,2,54,16v1,22,-45,15,-51,30v3,34,12,68,10,103v14,17,-18,53,-28,63v-48,8,-89,5,-95,-37v20,-5,77,21,83,-18v17,-29,-4,-61,0,-98v0,-5,-3,-10,-7,-17v-33,4,-43,-17,-25,-37v10,-4,27,5,27,-10v0,-43,15,-77,32,-109v12,-7,16,-22,38,-20v11,1,51,35,25,55v-9,1,-16,-17,-25,-17", + "w": 145 + }, + "\u02c6": { + "d": "144,-220v-29,0,-41,-27,-63,-39v-8,0,-11,5,-15,11v-17,12,-32,31,-54,13v-2,-5,-3,-9,-4,-14v20,-5,45,-33,64,-45v28,6,43,23,65,38v12,9,19,19,19,27v0,6,-4,9,-12,9", + "w": 165 + }, + "\u02c7": { + "d": "39,-286v33,46,63,-4,96,-16v6,0,9,6,9,19v0,24,-49,46,-77,46v-32,0,-52,-28,-59,-48v0,-25,23,-17,31,-1", + "w": 153 + }, + "\u02d8": { + "d": "65,-269v20,-11,45,-31,74,-36v20,30,-42,40,-59,66v-5,6,-11,8,-18,8v-8,-3,-45,-32,-51,-54v5,-24,14,-13,34,1", + "w": 158 + }, + "\u02d9": { + "d": "23,-302v15,-13,32,1,32,18v1,22,-36,29,-39,4v0,0,3,-7,7,-22", + "w": 70 + }, + "\u02da": { + "d": "23,-225v-43,-24,-11,-85,41,-78v16,2,31,4,46,17v32,54,-41,86,-87,61xm33,-257v2,20,57,11,57,-6v0,-6,-11,-9,-33,-12v-14,-2,-24,13,-24,18", + "w": 123 + }, + "\u02db": { + "d": "82,-5v-8,12,-16,55,-21,75v0,4,2,7,7,7v6,0,22,-7,50,-20v8,0,12,7,12,20v-2,22,-6,14,-27,30v-15,12,-26,16,-30,16v-47,-8,-59,-14,-56,-75v8,-27,12,-54,25,-77v19,-21,35,15,40,24", + "w": 138 + }, + "\u02dc": { + "d": "47,-300v26,-21,57,19,72,23v4,0,16,-5,36,-14v24,-10,22,-16,32,-13v3,12,-7,11,-7,23v-27,21,-48,32,-62,32v-3,2,-52,-27,-51,-31v-12,-2,-34,40,-54,33v-4,-13,-8,-18,1,-24v5,-7,16,-15,33,-29", + "w": 186 + }, + "\u02dd": { + "d": "91,-249v15,-11,38,-53,57,-29v0,9,0,14,-3,23v-2,3,-20,22,-54,55v-5,5,-10,8,-16,8v-17,2,-6,-22,-7,-31v-1,0,-2,0,-4,1v-17,21,-29,31,-50,27v-5,-18,-3,-15,3,-27v23,-27,40,-46,48,-59v7,-12,31,3,29,9v-1,14,-3,24,-13,31v4,4,9,-1,10,-8", + "w": 151 + }, + "\u2013": { + "d": "6,-66v-8,-72,79,-21,146,-39v37,-10,79,7,111,0v9,8,14,13,14,17v2,26,-72,13,-99,21v-83,4,-124,21,-172,1", + "w": 282 + }, + "\u2014": { + "d": "175,-106v86,-9,201,1,286,-1v11,6,13,11,6,30v-118,15,-246,10,-377,10v-25,0,-73,3,-82,-8r-2,-26v11,-13,32,-9,52,-7v38,3,84,-5,117,2", + "w": 485 + }, + "\u2018": { + "d": "73,-262v-10,7,-41,39,-38,69v-15,13,-27,-16,-28,-28v-2,-20,51,-83,66,-83v20,0,25,41,0,42", + "w": 95 + }, + "\u2019": { + "d": "74,-300v13,31,-1,99,-44,101v-13,0,-19,-5,-19,-15v6,-10,31,-34,35,-59v2,-11,1,-32,11,-32v6,0,11,2,17,5", + "w": 90 + }, + "\u201a": { + "d": "25,63v-26,21,-48,-2,-22,-24v14,-12,35,-40,35,-69v3,-2,3,-11,12,-9v35,17,5,88,-25,102", + "w": 97 + }, + "\u201c": { + "d": "66,-261v-21,5,-37,51,-22,77v0,4,-2,6,-7,6v-31,-9,-38,-62,-12,-94v12,-15,21,-28,31,-34v16,-1,19,24,22,34v10,-11,22,-32,43,-23v-2,8,4,16,5,19v-6,11,-51,53,-29,74v-12,21,-30,5,-33,-17v-6,-13,9,-28,2,-42", + "w": 118 + }, + "\u201d": { + "d": "120,-294v12,3,30,26,19,34v2,15,-40,70,-55,66v-40,-10,10,-51,14,-64v3,-3,8,-31,22,-36xm70,-306v14,3,26,34,16,49v-19,30,-31,45,-58,59v-12,-11,-33,-17,-7,-36v13,-19,36,-27,36,-59v0,-5,9,-13,13,-13", + "w": 148 + }, + "\u201e": { + "d": "25,63v-26,21,-48,-2,-22,-24v11,-9,36,-41,35,-69v3,-2,4,-12,12,-9v36,14,5,89,-25,102xm84,64v-24,20,-45,-1,-21,-24v21,-20,32,-35,35,-69v3,-2,3,-11,12,-9v36,17,9,86,-26,102", + "w": 135 + }, + "\u2020": { + "d": "22,-286v15,6,5,-20,19,-19v9,-3,15,21,17,22v6,1,12,3,20,6v3,10,5,16,-9,16v-34,-10,-6,51,-34,52v-20,-7,11,-47,-15,-49v-14,3,-25,-5,-17,-24v7,-2,14,-4,19,-4", + "w": 77 + }, + "\u2021": { + "d": "102,-284v16,2,42,-2,33,18v-7,15,-42,1,-38,30v3,3,31,1,30,11v4,15,-29,19,-36,24v-2,18,-4,24,-16,29r-25,-26v-25,7,-53,3,-42,-25v4,-10,70,0,51,-22v-17,4,-41,12,-39,-15v-5,-16,39,-18,44,-20v4,-2,7,-10,10,-24v19,-3,23,6,28,20", + "w": 145 + }, + "\u2022": { + "d": "130,-114v0,47,-124,54,-120,-8r6,-31v44,-28,64,-34,104,0v8,6,10,20,10,39", + "w": 139 + }, + "\u2026": { + "d": "244,-24v-1,21,-38,32,-41,3v-2,-19,23,-22,34,-17v0,7,0,15,7,14xm113,-24v0,-22,28,-21,38,-8v5,34,-39,40,-38,8xm35,-2v-10,-2,-36,-17,-18,-29v-1,-15,17,-17,31,-6v7,17,6,33,-13,35", + "w": 258 + }, + "\u2030": { + "d": "398,-131v58,-1,87,13,72,65v-1,30,-66,63,-99,65v-56,3,-99,-58,-62,-102v2,2,5,2,8,2v20,-16,51,-17,81,-30xm202,-279v33,0,94,-24,95,18v-7,31,-33,27,-54,55v-36,32,-71,74,-112,99v-18,18,-40,34,-51,58v-19,14,-25,37,-56,40v-17,2,-25,-29,-10,-40v15,-11,40,-37,52,-52r87,-72v-51,13,-100,6,-116,-27v1,-5,-6,-30,-9,-36v-3,-5,22,-41,27,-39v29,2,16,34,5,49v0,15,14,23,42,23v42,0,59,-31,28,-38v-17,-4,-53,3,-50,-23v0,-7,1,-12,4,-16v16,-9,36,4,49,5v0,0,23,-4,69,-4xm222,-118v33,-2,55,18,50,57v-29,36,-48,45,-96,50v-27,-5,-56,-17,-58,-51v13,-37,64,-43,104,-56xm335,-61v13,44,101,7,108,-31v-11,-3,-20,-4,-30,-4v-18,-1,-82,18,-78,35xm225,-244v-18,0,-29,-1,-46,3v7,15,6,28,0,43v15,-14,34,-30,46,-46xm164,-53v26,5,59,-10,76,-26v-17,-16,-49,2,-67,14v1,8,-8,6,-9,12", + "w": 485 + }, + "\u2039": { + "d": "64,-107v9,17,86,17,87,43v0,11,-4,16,-13,16v-36,-11,-70,-22,-109,-31v-19,-4,-18,-14,-9,-36v59,-56,93,-84,101,-84v17,0,19,20,13,29", + "w": 159 + }, + "\u203a": { + "d": "41,-181v26,27,112,44,70,91r-82,60v-20,3,-25,-23,-13,-32r70,-51r-66,-46v-5,-6,-4,-28,5,-29v4,2,9,4,16,7", + "w": 137 + }, + "\u2044": { + "d": "193,-305v7,6,17,31,3,41v-10,7,-12,13,-21,25v-79,56,-190,209,-197,260r-18,0v-23,-19,9,-70,15,-85v52,-83,121,-179,218,-241", + "w": 120 + }, + "\u2122": { + "d": "213,-307v28,9,11,49,7,75v-1,4,-4,6,-11,6v-7,1,-11,-14,-11,-34v-14,-6,-34,34,-46,28v-2,0,-10,-9,-24,-27v-10,7,-3,36,-27,31v-15,-24,-3,-27,1,-48v-6,-7,-27,-1,-31,3v-3,14,-7,30,-11,51v-5,10,-29,9,-24,-12v-5,-8,1,-18,3,-35v-13,6,-33,2,-29,-18v20,-17,64,-17,100,-19v28,-1,29,30,45,39v11,-6,35,-32,58,-40", + "w": 239 + }, + "\u2206": { + "d": "18,-1v-24,-30,8,-48,25,-71v14,-19,34,-28,40,-56v20,-35,29,-14,57,4v9,39,43,62,57,102v0,16,-34,17,-50,14v-28,2,-72,4,-129,7xm139,-47r-22,-52v-12,-5,-12,15,-24,27v-7,6,-14,16,-23,28v23,1,36,-1,69,-3", + "w": 199 + }, + "\u2219": { + "d": "57,-77v6,18,-7,21,-19,23v-34,6,-25,-40,-9,-43v18,-3,29,8,28,20", + "w": 67 + }, + "\u221a": { + "d": "364,-218v43,-21,80,-51,104,-32v-3,19,-24,21,-44,40v-41,15,-78,53,-136,78r-137,98v-20,16,-79,66,-91,68v-3,1,-25,-11,-24,-13v-4,-28,-43,-61,-30,-85v26,-15,42,19,58,32r295,-188v0,1,2,2,5,2", + "w": 474 + }, + "\u221e": { + "d": "322,-72v-4,22,-54,41,-76,41v-43,0,-83,-17,-114,-35v-46,19,-125,53,-128,-18v-1,-14,10,-22,13,-35v29,-10,62,-31,97,-4v37,28,47,5,75,-8v40,-19,73,-10,114,1v13,1,18,55,19,58xm228,-69v15,0,62,-12,61,-25v-19,-23,-89,-10,-105,11v0,2,1,4,2,4v28,6,42,10,42,10xm75,-102v-13,2,-41,4,-44,19v0,4,3,7,10,7v21,0,40,-6,54,-17v-9,-6,-16,-9,-20,-9", + "w": 330 + }, + "\u222b": { + "d": "62,-151v-7,-70,20,-130,63,-150v28,1,39,10,70,23v20,8,6,33,-6,35v-29,-13,-45,-20,-49,-20v-20,-4,-45,51,-43,70v8,60,5,129,5,189v0,62,-27,93,-79,93v-37,-1,-71,-14,-63,-57v21,0,79,34,91,-2v16,-3,14,-64,21,-85v-2,-31,-1,-74,-10,-96", + "w": 156 + }, + "\u2248": { + "d": "133,-112v21,15,48,-30,78,-17v3,3,5,7,5,9v-8,30,-47,45,-76,45v-19,0,-64,-48,-90,-21r-29,20v-6,-1,-17,-16,-15,-32v24,-17,70,-42,107,-21v4,4,10,9,20,17xm138,-57v28,2,48,-25,76,-26v13,30,-21,42,-40,53v-41,24,-77,-15,-114,-23v-15,14,-46,32,-49,-1v-3,-9,27,-28,54,-30", + "w": 223 + }, + "\u2260": { + "d": "48,-130v29,11,49,-57,60,-50v25,6,7,27,-1,46v22,5,29,7,21,22v-18,2,-48,-1,-50,15v9,8,53,-7,54,10v-4,22,-46,20,-72,24v-7,13,-18,32,-34,57v-8,6,-15,-3,-13,-14v-1,-9,15,-39,14,-45v-30,5,-24,-17,-13,-25v12,-1,36,4,29,-13v-14,0,-47,6,-36,-12v0,-18,27,-13,41,-15", + "w": 140 + }, + "\u2264": { + "d": "73,-109v10,15,87,16,87,42v0,11,-5,16,-13,16v-36,-11,-69,-24,-109,-31v-18,-8,-18,-13,-9,-36v59,-56,93,-83,101,-83v16,0,18,17,14,28v-27,24,-42,35,-71,64xm10,-29v35,-12,117,-26,148,-3v1,2,-5,19,-8,18r-124,15v-16,2,-26,-18,-16,-30", + "w": 168 + }, + "\u2265": { + "d": "115,-174v20,7,53,36,20,57v-19,11,-91,68,-82,59v-18,3,-25,-22,-13,-31v15,-10,14,-10,70,-51r-50,-37v-5,-4,-5,-27,4,-28v16,7,40,17,51,31xm14,-32v33,-10,86,-14,127,-10v12,12,5,23,-11,27v-49,9,-82,13,-99,13v-22,0,-24,-16,-17,-30", + "w": 163 + }, + "\u25ca": { + "d": "76,-158v48,-8,64,11,100,36v28,19,-5,39,-22,54v-15,13,-40,32,-48,49v-17,5,-12,0,-27,-16v-6,-6,-86,-31,-68,-53r2,-9v27,-23,48,-44,63,-61xm93,-65v12,-2,35,-31,41,-38v-5,-10,-16,-14,-34,-24v-12,12,-36,29,-40,44v19,11,30,18,33,18", + "w": 199 + } + } +}); +} +/** js sequence diagrams + * https://bramp.github.io/js-sequence-diagrams/ + * (c) 2012-2017 Andrew Brampton (bramp.net) + * Simplified BSD license. + */ +/*global Diagram, _ */ + +if (typeof Raphael == 'undefined' && typeof Snap == 'undefined') { + throw new Error('Raphael or Snap.svg is required to be included.'); +} + +if (_.isEmpty(Diagram.themes)) { + // If you are using stock js-sequence-diagrams you should never see this. This only + // happens if you have removed the built in themes. + throw new Error('No themes were registered. Please call registerTheme(...).'); +} + +// Set the default hand/simple based on which theme is available. +Diagram.themes.hand = Diagram.themes.snapHand || Diagram.themes.raphaelHand; +Diagram.themes.simple = Diagram.themes.snapSimple || Diagram.themes.raphaelSimple; + +/* Draws the diagram. Creates a SVG inside the container +* container (HTMLElement|string) DOM element or its ID to draw on +* options (Object) +*/ +Diagram.prototype.drawSVG = function(container, options) { + var defaultOptions = { + theme: 'hand' + }; + + options = _.defaults(options || {}, defaultOptions); + + if (!(options.theme in Diagram.themes)) { + throw new Error('Unsupported theme: ' + options.theme); + } + + // TODO Write tests for this check + var div = _.isString(container) ? document.getElementById(container) : container; + if (div === null || !div.tagName) { + throw new Error('Invalid container: ' + container); + } + + var Theme = Diagram.themes[options.theme]; + new Theme(this, options, function(drawing) { + drawing.draw(div); + }); +}; // end of drawSVG + +export default Diagram diff --git a/src/muya/lib/assets/libs/webFontLoader.js b/src/muya/lib/assets/libs/webFontLoader.js new file mode 100644 index 00000000..d1e856a2 --- /dev/null +++ b/src/muya/lib/assets/libs/webFontLoader.js @@ -0,0 +1,17 @@ +/* Web Font Loader v1.6.28 - (c) Adobe Systems, Google. License: Apache 2.0 */(function(){function aa(a,b,c){return a.call.apply(a.bind,arguments)}function ba(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}}function p(a,b,c){p=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?aa:ba;return p.apply(null,arguments)}var q=Date.now||function(){return+new Date};function ca(a,b){this.a=a;this.o=b||a;this.c=this.o.document}var da=!!window.FontFace;function t(a,b,c,d){b=a.c.createElement(b);if(c)for(var e in c)c.hasOwnProperty(e)&&("style"==e?b.style.cssText=c[e]:b.setAttribute(e,c[e]));d&&b.appendChild(a.c.createTextNode(d));return b}function u(a,b,c){a=a.c.getElementsByTagName(b)[0];a||(a=document.documentElement);a.insertBefore(c,a.lastChild)}function v(a){a.parentNode&&a.parentNode.removeChild(a)} +function w(a,b,c){b=b||[];c=c||[];for(var d=a.className.split(/\s+/),e=0;e<b.length;e+=1){for(var f=!1,g=0;g<d.length;g+=1)if(b[e]===d[g]){f=!0;break}f||d.push(b[e])}b=[];for(e=0;e<d.length;e+=1){f=!1;for(g=0;g<c.length;g+=1)if(d[e]===c[g]){f=!0;break}f||b.push(d[e])}a.className=b.join(" ").replace(/\s+/g," ").replace(/^\s+|\s+$/,"")}function y(a,b){for(var c=a.className.split(/\s+/),d=0,e=c.length;d<e;d++)if(c[d]==b)return!0;return!1} +function ea(a){return a.o.location.hostname||a.a.location.hostname}function z(a,b,c){function d(){m&&e&&f&&(m(g),m=null)}b=t(a,"link",{rel:"stylesheet",href:b,media:"all"});var e=!1,f=!0,g=null,m=c||null;da?(b.onload=function(){e=!0;d()},b.onerror=function(){e=!0;g=Error("Stylesheet failed to load");d()}):setTimeout(function(){e=!0;d()},0);u(a,"head",b)} +function A(a,b,c,d){var e=a.c.getElementsByTagName("head")[0];if(e){var f=t(a,"script",{src:b}),g=!1;f.onload=f.onreadystatechange=function(){g||this.readyState&&"loaded"!=this.readyState&&"complete"!=this.readyState||(g=!0,c&&c(null),f.onload=f.onreadystatechange=null,"HEAD"==f.parentNode.tagName&&e.removeChild(f))};e.appendChild(f);setTimeout(function(){g||(g=!0,c&&c(Error("Script load timeout")))},d||5E3);return f}return null};function B(){this.a=0;this.c=null}function C(a){a.a++;return function(){a.a--;D(a)}}function E(a,b){a.c=b;D(a)}function D(a){0==a.a&&a.c&&(a.c(),a.c=null)};function F(a){this.a=a||"-"}F.prototype.c=function(a){for(var b=[],c=0;c<arguments.length;c++)b.push(arguments[c].replace(/[\W_]+/g,"").toLowerCase());return b.join(this.a)};function G(a,b){this.c=a;this.f=4;this.a="n";var c=(b||"n4").match(/^([nio])([1-9])$/i);c&&(this.a=c[1],this.f=parseInt(c[2],10))}function fa(a){return H(a)+" "+(a.f+"00")+" 300px "+I(a.c)}function I(a){var b=[];a=a.split(/,\s*/);for(var c=0;c<a.length;c++){var d=a[c].replace(/['"]/g,"");-1!=d.indexOf(" ")||/^\d/.test(d)?b.push("'"+d+"'"):b.push(d)}return b.join(",")}function J(a){return a.a+a.f}function H(a){var b="normal";"o"===a.a?b="oblique":"i"===a.a&&(b="italic");return b} +function ga(a){var b=4,c="n",d=null;a&&((d=a.match(/(normal|oblique|italic)/i))&&d[1]&&(c=d[1].substr(0,1).toLowerCase()),(d=a.match(/([1-9]00|normal|bold)/i))&&d[1]&&(/bold/i.test(d[1])?b=7:/[1-9]00/.test(d[1])&&(b=parseInt(d[1].substr(0,1),10))));return c+b};function ha(a,b){this.c=a;this.f=a.o.document.documentElement;this.h=b;this.a=new F("-");this.j=!1!==b.events;this.g=!1!==b.classes}function ia(a){a.g&&w(a.f,[a.a.c("wf","loading")]);K(a,"loading")}function L(a){if(a.g){var b=y(a.f,a.a.c("wf","active")),c=[],d=[a.a.c("wf","loading")];b||c.push(a.a.c("wf","inactive"));w(a.f,c,d)}K(a,"inactive")}function K(a,b,c){if(a.j&&a.h[b])if(c)a.h[b](c.c,J(c));else a.h[b]()};function ja(){this.c={}}function ka(a,b,c){var d=[],e;for(e in b)if(b.hasOwnProperty(e)){var f=a.c[e];f&&d.push(f(b[e],c))}return d};function M(a,b){this.c=a;this.f=b;this.a=t(this.c,"span",{"aria-hidden":"true"},this.f)}function N(a){u(a.c,"body",a.a)}function O(a){return"display:block;position:absolute;top:-9999px;left:-9999px;font-size:300px;width:auto;height:auto;line-height:normal;margin:0;padding:0;font-variant:normal;white-space:nowrap;font-family:"+I(a.c)+";"+("font-style:"+H(a)+";font-weight:"+(a.f+"00")+";")};function P(a,b,c,d,e,f){this.g=a;this.j=b;this.a=d;this.c=c;this.f=e||3E3;this.h=f||void 0}P.prototype.start=function(){var a=this.c.o.document,b=this,c=q(),d=new Promise(function(d,e){function f(){q()-c>=b.f?e():a.fonts.load(fa(b.a),b.h).then(function(a){1<=a.length?d():setTimeout(f,25)},function(){e()})}f()}),e=null,f=new Promise(function(a,d){e=setTimeout(d,b.f)});Promise.race([f,d]).then(function(){e&&(clearTimeout(e),e=null);b.g(b.a)},function(){b.j(b.a)})};function Q(a,b,c,d,e,f,g){this.v=a;this.B=b;this.c=c;this.a=d;this.s=g||"BESbswy";this.f={};this.w=e||3E3;this.u=f||null;this.m=this.j=this.h=this.g=null;this.g=new M(this.c,this.s);this.h=new M(this.c,this.s);this.j=new M(this.c,this.s);this.m=new M(this.c,this.s);a=new G(this.a.c+",serif",J(this.a));a=O(a);this.g.a.style.cssText=a;a=new G(this.a.c+",sans-serif",J(this.a));a=O(a);this.h.a.style.cssText=a;a=new G("serif",J(this.a));a=O(a);this.j.a.style.cssText=a;a=new G("sans-serif",J(this.a));a= +O(a);this.m.a.style.cssText=a;N(this.g);N(this.h);N(this.j);N(this.m)}var R={D:"serif",C:"sans-serif"},S=null;function T(){if(null===S){var a=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent);S=!!a&&(536>parseInt(a[1],10)||536===parseInt(a[1],10)&&11>=parseInt(a[2],10))}return S}Q.prototype.start=function(){this.f.serif=this.j.a.offsetWidth;this.f["sans-serif"]=this.m.a.offsetWidth;this.A=q();U(this)}; +function la(a,b,c){for(var d in R)if(R.hasOwnProperty(d)&&b===a.f[R[d]]&&c===a.f[R[d]])return!0;return!1}function U(a){var b=a.g.a.offsetWidth,c=a.h.a.offsetWidth,d;(d=b===a.f.serif&&c===a.f["sans-serif"])||(d=T()&&la(a,b,c));d?q()-a.A>=a.w?T()&&la(a,b,c)&&(null===a.u||a.u.hasOwnProperty(a.a.c))?V(a,a.v):V(a,a.B):ma(a):V(a,a.v)}function ma(a){setTimeout(p(function(){U(this)},a),50)}function V(a,b){setTimeout(p(function(){v(this.g.a);v(this.h.a);v(this.j.a);v(this.m.a);b(this.a)},a),0)};function W(a,b,c){this.c=a;this.a=b;this.f=0;this.m=this.j=!1;this.s=c}var X=null;W.prototype.g=function(a){var b=this.a;b.g&&w(b.f,[b.a.c("wf",a.c,J(a).toString(),"active")],[b.a.c("wf",a.c,J(a).toString(),"loading"),b.a.c("wf",a.c,J(a).toString(),"inactive")]);K(b,"fontactive",a);this.m=!0;na(this)}; +W.prototype.h=function(a){var b=this.a;if(b.g){var c=y(b.f,b.a.c("wf",a.c,J(a).toString(),"active")),d=[],e=[b.a.c("wf",a.c,J(a).toString(),"loading")];c||d.push(b.a.c("wf",a.c,J(a).toString(),"inactive"));w(b.f,d,e)}K(b,"fontinactive",a);na(this)};function na(a){0==--a.f&&a.j&&(a.m?(a=a.a,a.g&&w(a.f,[a.a.c("wf","active")],[a.a.c("wf","loading"),a.a.c("wf","inactive")]),K(a,"active")):L(a.a))};function oa(a){this.j=a;this.a=new ja;this.h=0;this.f=this.g=!0}oa.prototype.load=function(a){this.c=new ca(this.j,a.context||this.j);this.g=!1!==a.events;this.f=!1!==a.classes;pa(this,new ha(this.c,a),a)}; +function qa(a,b,c,d,e){var f=0==--a.h;(a.f||a.g)&&setTimeout(function(){var a=e||null,m=d||null||{};if(0===c.length&&f)L(b.a);else{b.f+=c.length;f&&(b.j=f);var h,l=[];for(h=0;h<c.length;h++){var k=c[h],n=m[k.c],r=b.a,x=k;r.g&&w(r.f,[r.a.c("wf",x.c,J(x).toString(),"loading")]);K(r,"fontloading",x);r=null;if(null===X)if(window.FontFace){var x=/Gecko.*Firefox\/(\d+)/.exec(window.navigator.userAgent),xa=/OS X.*Version\/10\..*Safari/.exec(window.navigator.userAgent)&&/Apple/.exec(window.navigator.vendor); +X=x?42<parseInt(x[1],10):xa?!1:!0}else X=!1;X?r=new P(p(b.g,b),p(b.h,b),b.c,k,b.s,n):r=new Q(p(b.g,b),p(b.h,b),b.c,k,b.s,a,n);l.push(r)}for(h=0;h<l.length;h++)l[h].start()}},0)}function pa(a,b,c){var d=[],e=c.timeout;ia(b);var d=ka(a.a,c,a.c),f=new W(a.c,b,e);a.h=d.length;b=0;for(c=d.length;b<c;b++)d[b].load(function(b,d,c){qa(a,f,b,d,c)})};function ra(a,b){this.c=a;this.a=b} +ra.prototype.load=function(a){function b(){if(f["__mti_fntLst"+d]){var c=f["__mti_fntLst"+d](),e=[],h;if(c)for(var l=0;l<c.length;l++){var k=c[l].fontfamily;void 0!=c[l].fontStyle&&void 0!=c[l].fontWeight?(h=c[l].fontStyle+c[l].fontWeight,e.push(new G(k,h))):e.push(new G(k))}a(e)}else setTimeout(function(){b()},50)}var c=this,d=c.a.projectId,e=c.a.version;if(d){var f=c.c.o;A(this.c,(c.a.api||"https://fast.fonts.net/jsapi")+"/"+d+".js"+(e?"?v="+e:""),function(e){e?a([]):(f["__MonotypeConfiguration__"+ +d]=function(){return c.a},b())}).id="__MonotypeAPIScript__"+d}else a([])};function sa(a,b){this.c=a;this.a=b}sa.prototype.load=function(a){var b,c,d=this.a.urls||[],e=this.a.families||[],f=this.a.testStrings||{},g=new B;b=0;for(c=d.length;b<c;b++)z(this.c,d[b],C(g));var m=[];b=0;for(c=e.length;b<c;b++)if(d=e[b].split(":"),d[1])for(var h=d[1].split(","),l=0;l<h.length;l+=1)m.push(new G(d[0],h[l]));else m.push(new G(d[0]));E(g,function(){a(m,f)})};function ta(a,b){a?this.c=a:this.c=ua;this.a=[];this.f=[];this.g=b||""}var ua="https://fonts.googleapis.com/css";function va(a,b){for(var c=b.length,d=0;d<c;d++){var e=b[d].split(":");3==e.length&&a.f.push(e.pop());var f="";2==e.length&&""!=e[1]&&(f=":");a.a.push(e.join(f))}} +function wa(a){if(0==a.a.length)throw Error("No fonts to load!");if(-1!=a.c.indexOf("kit="))return a.c;for(var b=a.a.length,c=[],d=0;d<b;d++)c.push(a.a[d].replace(/ /g,"+"));b=a.c+"?family="+c.join("%7C");0<a.f.length&&(b+="&subset="+a.f.join(","));0<a.g.length&&(b+="&text="+encodeURIComponent(a.g));return b};function ya(a){this.f=a;this.a=[];this.c={}} +var za={latin:"BESbswy","latin-ext":"\u00e7\u00f6\u00fc\u011f\u015f",cyrillic:"\u0439\u044f\u0416",greek:"\u03b1\u03b2\u03a3",khmer:"\u1780\u1781\u1782",Hanuman:"\u1780\u1781\u1782"},Aa={thin:"1",extralight:"2","extra-light":"2",ultralight:"2","ultra-light":"2",light:"3",regular:"4",book:"4",medium:"5","semi-bold":"6",semibold:"6","demi-bold":"6",demibold:"6",bold:"7","extra-bold":"8",extrabold:"8","ultra-bold":"8",ultrabold:"8",black:"9",heavy:"9",l:"3",r:"4",b:"7"},Ba={i:"i",italic:"i",n:"n",normal:"n"}, +Ca=/^(thin|(?:(?:extra|ultra)-?)?light|regular|book|medium|(?:(?:semi|demi|extra|ultra)-?)?bold|black|heavy|l|r|b|[1-9]00)?(n|i|normal|italic)?$/; +function Da(a){for(var b=a.f.length,c=0;c<b;c++){var d=a.f[c].split(":"),e=d[0].replace(/\+/g," "),f=["n4"];if(2<=d.length){var g;var m=d[1];g=[];if(m)for(var m=m.split(","),h=m.length,l=0;l<h;l++){var k;k=m[l];if(k.match(/^[\w-]+$/)){var n=Ca.exec(k.toLowerCase());if(null==n)k="";else{k=n[2];k=null==k||""==k?"n":Ba[k];n=n[1];if(null==n||""==n)n="4";else var r=Aa[n],n=r?r:isNaN(n)?"4":n.substr(0,1);k=[k,n].join("")}}else k="";k&&g.push(k)}0<g.length&&(f=g);3==d.length&&(d=d[2],g=[],d=d?d.split(","): +g,0<d.length&&(d=za[d[0]])&&(a.c[e]=d))}a.c[e]||(d=za[e])&&(a.c[e]=d);for(d=0;d<f.length;d+=1)a.a.push(new G(e,f[d]))}};function Ea(a,b){this.c=a;this.a=b}var Fa={Arimo:!0,Cousine:!0,Tinos:!0};Ea.prototype.load=function(a){var b=new B,c=this.c,d=new ta(this.a.api,this.a.text),e=this.a.families;va(d,e);var f=new ya(e);Da(f);z(c,wa(d),C(b));E(b,function(){a(f.a,f.c,Fa)})};function Ga(a,b){this.c=a;this.a=b}Ga.prototype.load=function(a){var b=this.a.id,c=this.c.o;b?A(this.c,(this.a.api||"https://use.typekit.net")+"/"+b+".js",function(b){if(b)a([]);else if(c.Typekit&&c.Typekit.config&&c.Typekit.config.fn){b=c.Typekit.config.fn;for(var e=[],f=0;f<b.length;f+=2)for(var g=b[f],m=b[f+1],h=0;h<m.length;h++)e.push(new G(g,m[h]));try{c.Typekit.load({events:!1,classes:!1,async:!0})}catch(l){}a(e)}},2E3):a([])};function Ha(a,b){this.c=a;this.f=b;this.a=[]}Ha.prototype.load=function(a){var b=this.f.id,c=this.c.o,d=this;b?(c.__webfontfontdeckmodule__||(c.__webfontfontdeckmodule__={}),c.__webfontfontdeckmodule__[b]=function(b,c){for(var g=0,m=c.fonts.length;g<m;++g){var h=c.fonts[g];d.a.push(new G(h.name,ga("font-weight:"+h.weight+";font-style:"+h.style)))}a(d.a)},A(this.c,(this.f.api||"https://f.fontdeck.com/s/css/js/")+ea(this.c)+"/"+b+".js",function(b){b&&a([])})):a([])};var Y=new oa(window);Y.a.c.custom=function(a,b){return new sa(b,a)};Y.a.c.fontdeck=function(a,b){return new Ha(b,a)};Y.a.c.monotype=function(a,b){return new ra(b,a)};Y.a.c.typekit=function(a,b){return new Ga(b,a)};Y.a.c.google=function(a,b){return new Ea(b,a)};var Z={load:p(Y.load,Y)};"function"===typeof define&&define.amd?define(function(){return Z}):"undefined"!==typeof module&&module.exports?module.exports=Z:(window.WebFont=Z,window.WebFontConfig&&Y.load(window.WebFontConfig));}()); diff --git a/src/muya/lib/assets/styles/danielbd.woff b/src/muya/lib/assets/styles/danielbd.woff new file mode 100755 index 00000000..aa01f17b Binary files /dev/null and b/src/muya/lib/assets/styles/danielbd.woff differ diff --git a/src/muya/lib/assets/styles/danielbd.woff2 b/src/muya/lib/assets/styles/danielbd.woff2 new file mode 100755 index 00000000..15ceb491 Binary files /dev/null and b/src/muya/lib/assets/styles/danielbd.woff2 differ diff --git a/src/muya/lib/assets/styles/index.css b/src/muya/lib/assets/styles/index.css index 29c04da1..78fe2bf6 100644 --- a/src/muya/lib/assets/styles/index.css +++ b/src/muya/lib/assets/styles/index.css @@ -113,7 +113,7 @@ p.ag-paragraph.ag-active > span.ag-line:first-of-type:empty::after { color: transparent; } -figure pre.ag-multiple-math, +figure.ag-container-block pre, div.ag-function-html pre.ag-html-block { width: 0; height: 0; @@ -127,7 +127,7 @@ div.ag-function-html pre.ag-html-block { } div.ag-function-html.ag-active pre.ag-html-block, -figure.ag-active pre.ag-multiple-math { +figure.ag-active.ag-container-block pre { position: static; width: 100%; height: auto; @@ -491,15 +491,43 @@ pre.ag-active.ag-multiple-math::after { content: '$$'; } +pre.ag-active[data-role="mermaid"]::before { + content: '``` mermaid'; +} + +pre.ag-active[data-role="flowchart"]::before { + content: '``` flowchart'; +} + +pre.ag-active[data-role="sequence"]::before { + content: '``` sequence'; +} + +pre.ag-active[data-role="vega-lite"]::before { + content: '``` vega-lite'; +} + pre.ag-active.ag-fence-code::before, pre.ag-active.ag-indent-code::after, pre.ag-active.ag-fence-code::after, -pre.ag-active.ag-indent-code::before { +pre.ag-active.ag-indent-code::before, +pre.ag-active[data-role="mermaid"]::after, +pre.ag-active[data-role="flowchart"]::after, +pre.ag-active[data-role="sequence"]::after, +pre.ag-active[data-role="vega-lite"]::after { content: '```'; } pre.ag-active.ag-front-matter::before, pre.ag-active.ag-front-matter::after, +pre.ag-active[data-role="mermaid"]::before, +pre.ag-active[data-role="mermaid"]::after, +pre.ag-active[data-role="flowchart"]::before, +pre.ag-active[data-role="flowchart"]::after, +pre.ag-active[data-role="sequence"]::before, +pre.ag-active[data-role="sequence"]::after, +pre.ag-active[data-role="vega-lite"]::before, +pre.ag-active[data-role="vega-lite"]::after, pre.ag-active.ag-fence-code::before, pre.ag-active.ag-fence-code::after, pre.ag-active.ag-indent-code::before, @@ -514,6 +542,10 @@ pre.ag-active.ag-multiple-math::after { } pre.ag-active.ag-front-matter::before, +pre.ag-active[data-role="mermaid"]::before, +pre.ag-active[data-role="flowchart"]::before, +pre.ag-active[data-role="sequence"]::before, +pre.ag-active[data-role="vega-lite"]::before, pre.ag-active.ag-multiple-math::before, pre.ag-active.ag-indent-code::before, pre.ag-active.ag-fence-code::before { @@ -521,6 +553,10 @@ pre.ag-active.ag-fence-code::before { } pre.ag-active.ag-front-matter::after, +pre.ag-active[data-role="mermaid"]::after, +pre.ag-active[data-role="flowchart"]::after, +pre.ag-active[data-role="sequence"]::after, +pre.ag-active[data-role="vega-lite"]::after, pre.ag-active.ag-multiple-math::after, pre.ag-active.ag-fence-code::after, pre.ag-active.ag-indent-code::after { @@ -532,16 +568,17 @@ span.ag-multiple-math-line { font-family: monospace; } -figure div.ag-math-preview { +figure.ag-container-block div.ag-container-preview { width: 100%; text-align: center; } -figure.ag-active div.ag-math-preview { +figure.ag-active.ag-container-block > div.ag-container-preview { position: absolute; - top: calc(100% + 8px); + top: calc(100% + 20px); left: 50%; - width: auto; + width: 100%; + box-sizing: border-box; z-index: 10000; transform: translateX(-50%); padding: .5rem; diff --git a/src/muya/lib/assets/styles/sequence-diagram.css b/src/muya/lib/assets/styles/sequence-diagram.css new file mode 100755 index 00000000..244b80da --- /dev/null +++ b/src/muya/lib/assets/styles/sequence-diagram.css @@ -0,0 +1,12 @@ +/** js sequence diagrams + * https://bramp.github.io/js-sequence-diagrams/ + * (c) 2012-2017 Andrew Brampton (bramp.net) + * Simplified BSD license. + */ +@font-face { + font-family: 'danielbd'; + src: url('danielbd.woff2') format('woff2'), + url('danielbd.woff') format('woff'); + font-weight: normal; + font-style: normal; +} diff --git a/src/muya/lib/config/index.js b/src/muya/lib/config/index.js index 3d3d40f0..e8b98da0 100644 --- a/src/muya/lib/config/index.js +++ b/src/muya/lib/config/index.js @@ -112,8 +112,12 @@ export const CLASS_OR_ID = genUpper2LowerKeyHash([ 'AG_MATH_ERROR', 'AG_EMPTY', 'AG_MATH_MARKER', - 'AG_MATH_PREVIEW', - 'AG_MULTIPLE_MATH_BLOCK', + 'AG_CONTAINER_PREVIEW', + 'AG_FLOWCHART', + 'AG_SEQUENCE', + 'AG_MERMAID', + 'AG_VEGA_LITE', + 'AG_CONTAINER_BLOCK', 'AG_MULTIPLE_MATH', 'AG_LOOSE_LIST_ITEM', 'AG_TIGHT_LIST_ITEM', @@ -211,4 +215,22 @@ export const EXPORT_DOMPURIFY_CONFIG = { } } +export const MUYA_DEFAULT_OPTION = { + focusMode: false, + theme: 'light', + markdown: '', + preferLooseListItem: true, + autoPairBracket: true, + autoPairMarkdownSyntax: true, + autoPairQuote: true, + bulletListMarker: '-', + tabSize: 4, + sequenceTheme: 'hand', // hand or simple + mermaidTheme: 'forest' // dark or forest +} + +// export const DIAGRAM_TEMPLATE = { +// 'mermaid': `graph LR;\nYou-->|Mark Text|Me;` +// } + export const isInElectron = window && window.process && window.process.type === 'renderer' diff --git a/src/muya/lib/contentState/backspaceCtrl.js b/src/muya/lib/contentState/backspaceCtrl.js index 971563d5..a38f26bf 100644 --- a/src/muya/lib/contentState/backspaceCtrl.js +++ b/src/muya/lib/contentState/backspaceCtrl.js @@ -179,6 +179,10 @@ const backspaceCtrl = ContentState => { referenceBlock = preBlock break case 'multiplemath': + case 'flowchart': + case 'mermaid': + case 'sequence': + case 'vega-lite': referenceBlock = this.getParent(preBlock) break case 'html': diff --git a/src/muya/lib/contentState/containerCtrl.js b/src/muya/lib/contentState/containerCtrl.js new file mode 100644 index 00000000..e48f3faa --- /dev/null +++ b/src/muya/lib/contentState/containerCtrl.js @@ -0,0 +1,85 @@ +const LINE_BREAKS_REG = /\n/ +const FUNCTION_TYPE_LANG = { + 'multiplemath': 'latex', + 'flowchart': 'yaml', + 'mermaid': 'yaml', + 'sequence': 'yaml', + 'vega-lite': 'yaml' +} + +const containerCtrl = ContentState => { + ContentState.prototype.createContainerBlock = function (functionType, value = '') { + const figureBlock = this.createBlock('figure') + figureBlock.functionType = functionType + const { preBlock, preview } = this.createPreAndPreview(functionType, value) + this.appendChild(figureBlock, preBlock) + this.appendChild(figureBlock, preview) + this.codeBlocks.set(preBlock.key, value) + return figureBlock + } + + ContentState.prototype.createPreAndPreview = function (functionType, value = '') { + const preBlock = this.createBlock('pre') + const codeBlock = this.createBlock('code') + preBlock.functionType = functionType + preBlock.lang = codeBlock.lang = FUNCTION_TYPE_LANG[functionType] + this.appendChild(preBlock, codeBlock) + + if (typeof value === 'string' && value) { + value.replace(/^\s+/, '').split(LINE_BREAKS_REG).forEach(line => { + const codeLine = this.createBlock('span', line) + codeLine.functionType = 'codeLine' + codeLine.lang = FUNCTION_TYPE_LANG[functionType] + this.appendChild(codeBlock, codeLine) + }) + } else { + const emptyLine = this.createBlock('span') + emptyLine.functionType = 'codeLine' + emptyLine.lang = FUNCTION_TYPE_LANG[functionType] + this.appendChild(codeBlock, emptyLine) + } + + const preview = this.createBlock('div', '', false) + this.codeBlocks.set(preBlock.key, '') + preview.functionType = functionType + + return { preBlock, preview } + } + + ContentState.prototype.initContainerBlock = function (functionType, block) { // p block + block.type = 'figure' + block.functionType = functionType + block.children = [] + + const { preBlock, preview } = this.createPreAndPreview(functionType) + + this.appendChild(block, preBlock) + this.appendChild(block, preview) + return preBlock.children[0].children[0] + } + + ContentState.prototype.handleContainerBlockClick = function (figure) { + const { id } = figure + const mathBlock = this.getBlock(id) + const preBlock = mathBlock.children[0] + const firstLine = preBlock.children[0].children[0] + + const { key } = firstLine + const offset = 0 + this.cursor = { + start: { key, offset }, + end: { key, offset } + } + this.partialRender() + } + + ContentState.prototype.updateMathBlock = function (block) { + const { type } = block + if (type !== 'p') return false + const { text } = block.children[0] + const functionType = 'multiplemath' + return text.trim() === '$$' ? this.initContainerBlock(functionType, block) : false + } +} + +export default containerCtrl diff --git a/src/muya/lib/contentState/copyCutCtrl.js b/src/muya/lib/contentState/copyCutCtrl.js index 58b07233..3f119693 100644 --- a/src/muya/lib/contentState/copyCutCtrl.js +++ b/src/muya/lib/contentState/copyCutCtrl.js @@ -86,14 +86,29 @@ const copyCutCtrl = ContentState => { hb.replaceWith(pre) }) - const mathBlock = wrapper.querySelectorAll(`figure.ag-multiple-math-block`) + const mathBlock = wrapper.querySelectorAll(`figure.ag-container-block`) ;[...mathBlock].forEach(mb => { + const preElement = mb.querySelector('pre[data-role]') + const functionType = preElement.getAttribute('data-role') const selectedCodeLines = mb.querySelectorAll('span.ag-code-line') const value = [...selectedCodeLines].map(codeLine => codeLine.textContent).join('\n') - const pre = document.createElement('pre') - pre.classList.add('multiple-math') - pre.textContent = value - mb.replaceWith(pre) + let pre + switch (functionType) { + case 'multiplemath': + pre = document.createElement('pre') + pre.classList.add('multiple-math') + pre.textContent = value + mb.replaceWith(pre) + break + case 'mermaid': + case 'flowchart': + case 'sequence': + case 'vega-lite': + pre = document.createElement('pre') + pre.innerHTML = `<code class="language-${functionType}">${value}</code>` + mb.replaceWith(pre) + break + } }) const htmlData = wrapper.innerHTML diff --git a/src/muya/lib/contentState/index.js b/src/muya/lib/contentState/index.js index 077f5466..bce84007 100644 --- a/src/muya/lib/contentState/index.js +++ b/src/muya/lib/contentState/index.js @@ -17,7 +17,7 @@ import paragraphCtrl from './paragraphCtrl' import tabCtrl from './tabCtrl' import formatCtrl from './formatCtrl' import searchCtrl from './searchCtrl' -import mathCtrl from './mathCtrl' +import containerCtrl from './containerCtrl' import imagePathCtrl from './imagePathCtrl' import htmlBlockCtrl from './htmlBlock' import clickCtrl from './clickCtrl' @@ -39,7 +39,7 @@ const prototypes = [ paragraphCtrl, formatCtrl, searchCtrl, - mathCtrl, + containerCtrl, imagePathCtrl, htmlBlockCtrl, clickCtrl, diff --git a/src/muya/lib/contentState/mathCtrl.js b/src/muya/lib/contentState/mathCtrl.js deleted file mode 100644 index 30b0c6c9..00000000 --- a/src/muya/lib/contentState/mathCtrl.js +++ /dev/null @@ -1,81 +0,0 @@ -// import { CLASS_OR_ID } from '../config' -const LINE_BREAKS_REG = /\n/ - -const mathCtrl = ContentState => { - ContentState.prototype.createMathBlock = function (value = '') { - const FUNCTION_TYPE = 'multiplemath' - const mathBlock = this.createBlock('figure') - mathBlock.functionType = FUNCTION_TYPE - const { preBlock, mathPreview } = this.createMathAndPreview(value) - this.appendChild(mathBlock, preBlock) - this.appendChild(mathBlock, mathPreview) - this.codeBlocks.set(preBlock.key, value) - return mathBlock - } - - ContentState.prototype.createMathAndPreview = function (value = '') { - const FUNCTION_TYPE = 'multiplemath' - const preBlock = this.createBlock('pre') - const codeBlock = this.createBlock('code') - preBlock.functionType = FUNCTION_TYPE - preBlock.lang = codeBlock.lang = 'latex' - this.appendChild(preBlock, codeBlock) - - if (typeof value === 'string' && value) { - value.replace(/^\s+/, '').split(LINE_BREAKS_REG).forEach(line => { - const codeLine = this.createBlock('span', line) - codeLine.functionType = 'codeLine' - codeLine.lang = 'latex' - this.appendChild(codeBlock, codeLine) - }) - } else { - const emptyLine = this.createBlock('span') - emptyLine.functionType = 'codeLine' - emptyLine.lang = 'latex' - this.appendChild(codeBlock, emptyLine) - } - - const mathPreview = this.createBlock('div', '', false) - this.codeBlocks.set(preBlock.key, '') - mathPreview.functionType = FUNCTION_TYPE - - return { preBlock, mathPreview } - } - - ContentState.prototype.initMathBlock = function (block) { // p block - const FUNCTION_TYPE = 'multiplemath' - block.type = 'figure' - block.functionType = FUNCTION_TYPE - block.children = [] - - const { preBlock, mathPreview } = this.createMathAndPreview() - - this.appendChild(block, preBlock) - this.appendChild(block, mathPreview) - return preBlock.children[0].children[0] - } - - ContentState.prototype.handleMathBlockClick = function (mathFigure) { - const { id } = mathFigure - const mathBlock = this.getBlock(id) - const preBlock = mathBlock.children[0] - const firstLine = preBlock.children[0].children[0] - - const { key } = firstLine - const offset = 0 - this.cursor = { - start: { key, offset }, - end: { key, offset } - } - this.partialRender() - } - - ContentState.prototype.updateMathBlock = function (block) { - const { type } = block - if (type !== 'p') return false - const { text } = block.children[0] - return text.trim() === '$$' ? this.initMathBlock(block) : false - } -} - -export default mathCtrl diff --git a/src/muya/lib/contentState/paragraphCtrl.js b/src/muya/lib/contentState/paragraphCtrl.js index 3028b2ac..4ad2998a 100644 --- a/src/muya/lib/contentState/paragraphCtrl.js +++ b/src/muya/lib/contentState/paragraphCtrl.js @@ -319,19 +319,19 @@ const paragraphCtrl = ContentState => { } } - ContentState.prototype.insertMathBlock = function () { + ContentState.prototype.insertContainerBlock = function (functionType, value = '') { const { start, end } = selection.getCursorRange() if (start.key !== end.key) return let block = this.getBlock(start.key) if (block.type === 'span') { block = this.getParent(block) } - const mathBlock = this.createMathBlock() + const mathBlock = this.createContainerBlock(functionType, value) this.insertAfter(mathBlock, block) if (block.type === 'p' && block.children.length === 1 && !block.children[0].text) { this.removeBlock(block) } - const cursorBlock = mathBlock.children[0].children[0] + const cursorBlock = mathBlock.children[0].children[0].children[0] const { key } = cursorBlock const offset = 0 this.cursor = { @@ -391,7 +391,7 @@ const paragraphCtrl = ContentState => { break } case 'mathblock': { - this.insertMathBlock() + this.insertContainerBlock('multiplemath') break } case 'table': { @@ -402,6 +402,12 @@ const paragraphCtrl = ContentState => { this.insertHtmlBlock(block) break } + case 'flowchart': + case 'sequence': + case 'mermaid': + case 'vega-lite': + this.insertContainerBlock(paraType) + break case 'heading 1': case 'heading 2': case 'heading 3': diff --git a/src/muya/lib/contentState/pasteCtrl.js b/src/muya/lib/contentState/pasteCtrl.js index fe3ea861..ca582733 100644 --- a/src/muya/lib/contentState/pasteCtrl.js +++ b/src/muya/lib/contentState/pasteCtrl.js @@ -127,7 +127,7 @@ const pasteCtrl = ContentState => { end: { key, offset } } } - + this.updateCodeBlocks(startBlock) return this.partialRender() } diff --git a/src/muya/lib/eventHandler/clickEvent.js b/src/muya/lib/eventHandler/clickEvent.js index c4151810..6de67784 100644 --- a/src/muya/lib/eventHandler/clickEvent.js +++ b/src/muya/lib/eventHandler/clickEvent.js @@ -41,12 +41,12 @@ class ClickEvent { event.stopPropagation() contentState.handleHtmlBlockClick(htmlPreview) } - // handler math block preview click - const mathFigure = target.closest('.ag-multiple-math-block') - if (mathFigure && !mathFigure.classList.contains(CLASS_OR_ID['AG_ACTIVE'])) { + // handler container block preview click + const container = target.closest('.ag-container-block') + if (container && !container.classList.contains(CLASS_OR_ID['AG_ACTIVE'])) { event.preventDefault() event.stopPropagation() - contentState.handleMathBlockClick(mathFigure) + contentState.handleContainerBlockClick(container) } // handler to-do checkbox click if (target.tagName === 'INPUT' && target.classList.contains(CLASS_OR_ID['AG_TASK_LIST_ITEM_CHECKBOX'])) { diff --git a/src/muya/lib/index.js b/src/muya/lib/index.js index ae0a7c5b..7a99c61c 100644 --- a/src/muya/lib/index.js +++ b/src/muya/lib/index.js @@ -3,7 +3,7 @@ import EventCenter from './eventHandler/event' import Clipboard from './eventHandler/clipboard' import Keyboard from './eventHandler/keyboard' import ClickEvent from './eventHandler/clickEvent' -import { CLASS_OR_ID } from './config' +import { CLASS_OR_ID, MUYA_DEFAULT_OPTION } from './config' import { wordCount } from './utils' import ExportMarkdown from './utils/exportMarkdown' import ExportHtml from './utils/exportHtml' @@ -18,11 +18,8 @@ import './assets/styles/index.css' class Muya { constructor (container, options) { - const { - focusMode = false, theme = 'light', markdown = '', preferLooseListItem = true, - autoPairBracket = true, autoPairMarkdownSyntax = true, autoPairQuote = true, - bulletListMarker = '-', tabSize = 4 - } = options + this.options = Object.assign({}, MUYA_DEFAULT_OPTION, options) + const { focusMode, theme, markdown } = this.options this.focusMode = focusMode this.theme = theme this.markdown = markdown @@ -35,7 +32,7 @@ class Muya { this.emojiPicker = new EmojiPicker(this) this.imagePathPicker = new ImagePathPicker(this) this.formatPicker = new FormatPicker(this) - this.contentState = new ContentState(this, { preferLooseListItem, autoPairBracket, autoPairMarkdownSyntax, autoPairQuote, bulletListMarker, tabSize }) + this.contentState = new ContentState(this, this.options) this.clipboard = new Clipboard(this) this.clickEvent = new ClickEvent(this) this.keyboard = new Keyboard(this) diff --git a/src/muya/lib/parser/render/index.js b/src/muya/lib/parser/render/index.js index b12b0417..45221fdb 100644 --- a/src/muya/lib/parser/render/index.js +++ b/src/muya/lib/parser/render/index.js @@ -1,8 +1,11 @@ +import mermaid from 'mermaid' +import flowchart from 'flowchart.js' +import Diagram from './sequence' +import vegaEmbed from 'vega-embed' import { CLASS_OR_ID } from '../../config' import { conflict, mixins } from '../../utils' import { patch, toVNode, toHTML, h } from './snabbdom' import { beginRules } from '../rules' - import renderInlines from './renderInlines' import renderBlock from './renderBlock' @@ -12,6 +15,8 @@ class StateRender { this.eventCenter = muya.eventCenter this.loadImageMap = new Map() this.loadMathMap = new Map() + this.mermaidCache = new Set() + this.diagramCache = new Map() this.tokenCache = new Map() this.labels = new Map() this.container = null @@ -84,6 +89,48 @@ class StateRender { return selector } + renderMermaid () { + if (this.mermaidCache.size) { + mermaid.init(undefined, document.querySelectorAll([...this.mermaidCache].join(', '))) + this.mermaidCache.clear() + } + } + + async renderDiagram () { + const cache = this.diagramCache + const RENDER_MAP = { + 'flowchart': flowchart, + 'sequence': Diagram, + 'vega-lite': vegaEmbed + } + if (cache.size) { + for (const [key, value] of cache.entries()) { + const target = document.querySelector(key) + const { code, functionType } = value + const render = RENDER_MAP[functionType] + const options = {} + if (functionType === 'sequence') { + Object.assign(options, { theme: this.muya.options.sequenceTheme }) + } else if (functionType === 'vega-lite') { + Object.assign(options, { actions: false, tooltip: false, renderer: 'svg' }) + } + try { + if (functionType === 'flowchart' || functionType === 'sequence') { + const diagram = render.parse(code) + target.innerHTML = '' + diagram.drawSVG(target, options) + } else if (functionType === 'vega-lite') { + await vegaEmbed(key, JSON.parse(code), options) + } + } catch (err) { + target.innerHTML = `< Invalid ${functionType === 'flowchart' ? 'Flow Chart' : 'Sequence'} Codes >` + target.classList.add(CLASS_OR_ID['AG_MATH_ERROR']) + } + } + this.diagramCache.clear() + } + } + render (blocks, cursor, activeBlocks, matches) { const selector = `div#${CLASS_OR_ID['AG_EDITOR_ID']}` @@ -96,6 +143,8 @@ class StateRender { const oldVdom = toVNode(rootDom) patch(oldVdom, newVdom) + this.renderMermaid() + this.renderDiagram() } // Only render the blocks which you updated @@ -133,6 +182,8 @@ class StateRender { patch(oldCursorVnode, newCursorVnode) } } + this.renderMermaid() + this.renderDiagram() } } diff --git a/src/muya/lib/parser/render/renderBlock/renderContainerBlock.js b/src/muya/lib/parser/render/renderBlock/renderContainerBlock.js index 6db7e350..e3c5916d 100644 --- a/src/muya/lib/parser/render/renderBlock/renderContainerBlock.js +++ b/src/muya/lib/parser/render/renderBlock/renderContainerBlock.js @@ -6,7 +6,11 @@ const PRE_BLOCK_HASH = { 'indentcode': `.${CLASS_OR_ID['AG_INDENT_CODE']}`, 'html': `.${CLASS_OR_ID['AG_HTML_BLOCK']}`, 'frontmatter': `.${CLASS_OR_ID['AG_FRONT_MATTER']}`, - 'multiplemath': `.${CLASS_OR_ID['AG_MULTIPLE_MATH']}` + 'multiplemath': `.${CLASS_OR_ID['AG_MULTIPLE_MATH']}`, + 'flowchart': `.${CLASS_OR_ID['AG_FLOWCHART']}`, + 'sequence': `.${CLASS_OR_ID['AG_SEQUENCE']}`, + 'mermaid': `.${CLASS_OR_ID['AG_MERMAID']}`, + 'vega-lite': `.${CLASS_OR_ID['AG_VEGA_LITE']}` } export default function renderContainerBlock (block, cursor, activeBlocks, matches, useCache = false) { @@ -29,11 +33,14 @@ export default function renderContainerBlock (block, cursor, activeBlocks, match } // handle `figure` block if (block.type === 'figure') { - if (block.functionType === 'html') { // HTML Block + if (block.functionType) { Object.assign(data.dataset, { role: block.functionType.toUpperCase() }) } - if (block.functionType === 'multiplemath') { - selector += `.${CLASS_OR_ID['AG_MULTIPLE_MATH_BLOCK']}` + + if ( + /multiplemath|flowchart|mermaid|sequence|vega-lite/.test(block.functionType) + ) { + selector += `.${CLASS_OR_ID['AG_CONTAINER_BLOCK']}` } } // hanle list block diff --git a/src/muya/lib/parser/render/renderBlock/renderLeafBlock.js b/src/muya/lib/parser/render/renderBlock/renderLeafBlock.js index 7ae691d3..ecebb44f 100644 --- a/src/muya/lib/parser/render/renderBlock/renderLeafBlock.js +++ b/src/muya/lib/parser/render/renderBlock/renderLeafBlock.js @@ -1,4 +1,5 @@ import katex from 'katex' +import mermaid from 'mermaid' import prism, { loadedCache } from '../../../prism/' import { CLASS_OR_ID, DEVICE_MEMORY, isInElectron, PREVIEW_DOMPURIFY_CONFIG } from '../../../config' import { tokenizer } from '../../parse' @@ -90,36 +91,75 @@ export default function renderLeafBlock (block, cursor, activeBlocks, matches, u style: `text-align:${align}` }) } else if (type === 'div') { - if (functionType === 'preview') { - selector += `.${CLASS_OR_ID['AG_HTML_PREVIEW']}` - const htmlContent = sanitize(this.muya.contentState.codeBlocks.get(block.preSibling), PREVIEW_DOMPURIFY_CONFIG) - // handle empty html bock - if (/<([a-z][a-z\d]*).*>\s*<\/\1>/.test(htmlContent)) { - children = htmlToVNode('<div class="ag-empty"><Empty HTML Block></div>') - } else { - children = htmlToVNode(htmlContent) - } - } else if (functionType === 'multiplemath') { - const math = this.muya.contentState.codeBlocks.get(block.preSibling) - const key = `${math}_display_math` - selector += `.${CLASS_OR_ID['AG_MATH_PREVIEW']}` - if (math === '') { - children = '< Empty Mathematical Formula >' - selector += `.${CLASS_OR_ID['AG_EMPTY']}` - } else if (loadMathMap.has(key)) { - children = loadMathMap.get(key) - } else { - try { - const html = katex.renderToString(math, { - displayMode: true - }) - - children = htmlToVNode(html) - loadMathMap.set(key, children) - } catch (err) { - children = '< Invalid Mathematical Formula >' - selector += `.${CLASS_OR_ID['AG_MATH_ERROR']}` + const code = this.muya.contentState.codeBlocks.get(block.preSibling) + switch (functionType) { + case 'preview': { + selector += `.${CLASS_OR_ID['AG_HTML_PREVIEW']}` + const htmlContent = sanitize(code, PREVIEW_DOMPURIFY_CONFIG) + // handle empty html bock + if (/<([a-z][a-z\d]*).*>\s*<\/\1>/.test(htmlContent)) { + children = htmlToVNode('<div class="ag-empty"><Empty HTML Block></div>') + } else { + children = htmlToVNode(htmlContent) } + break + } + case 'multiplemath': { + const key = `${code}_display_math` + selector += `.${CLASS_OR_ID['AG_CONTAINER_PREVIEW']}` + if (code === '') { + children = '< Empty Mathematical Formula >' + selector += `.${CLASS_OR_ID['AG_EMPTY']}` + } else if (loadMathMap.has(key)) { + children = loadMathMap.get(key) + } else { + try { + const html = katex.renderToString(code, { + displayMode: true + }) + + children = htmlToVNode(html) + loadMathMap.set(key, children) + } catch (err) { + children = '< Invalid Mathematical Formula >' + selector += `.${CLASS_OR_ID['AG_MATH_ERROR']}` + } + } + break + } + case 'mermaid': { + selector += `.${CLASS_OR_ID['AG_CONTAINER_PREVIEW']}` + if (code === '') { + children = '< Empty Mermaid Block >' + selector += `.${CLASS_OR_ID['AG_EMPTY']}` + } else { + try { + mermaid.parse(code) + children = code + this.mermaidCache.add(`#${block.key}`) + } catch (err) { + children = '< Invalid Mermaid Codes >' + selector += `.${CLASS_OR_ID['AG_MATH_ERROR']}` + } + } + break + } + case 'flowchart': + case 'sequence': + case 'vega-lite': { + const code = this.muya.contentState.codeBlocks.get(block.preSibling) + selector += `.${CLASS_OR_ID['AG_CONTAINER_PREVIEW']}` + if (code === '') { + children = '< Empty Diagram Block >' + selector += `.${CLASS_OR_ID['AG_EMPTY']}` + } else { + children = '' + this.diagramCache.set(`#${block.key}`, { + code, + functionType + }) + } + break } } } else if (type === 'svg' && icon) { diff --git a/src/muya/lib/parser/render/sequence.js b/src/muya/lib/parser/render/sequence.js new file mode 100644 index 00000000..97fd6649 --- /dev/null +++ b/src/muya/lib/parser/render/sequence.js @@ -0,0 +1,5 @@ + +import Diagram from '../../assets/libs/sequence-diagram' +import '../../assets/styles/sequence-diagram.css' + +export default Diagram diff --git a/src/muya/lib/selection/index.js b/src/muya/lib/selection/index.js index 266498f0..9f40297d 100644 --- a/src/muya/lib/selection/index.js +++ b/src/muya/lib/selection/index.js @@ -843,7 +843,9 @@ class Selection { range.collapse(true) let rects = range.getClientRects() if (rects.length === 0) { - rects = range.startContainer ? range.startContainer.getClientRects() : [] + rects = range.startContainer && range.startContainer.nodeType === Node.ELEMENT_NODE + ? range.startContainer.getClientRects() + : [] } if (rects.length) { const { left, top, x: rectX, y: rectY } = rects[0] diff --git a/src/muya/lib/ui/quickInsert/config.js b/src/muya/lib/ui/quickInsert/config.js index 7826818e..ba863c8a 100644 --- a/src/muya/lib/ui/quickInsert/config.js +++ b/src/muya/lib/ui/quickInsert/config.js @@ -15,8 +15,37 @@ import quoteIcon from '../../assets/icons/quote.svg' import todoListIcon from '../../assets/icons/todolist.svg' import mathblockIcon from '../../assets/icons/math.svg' import orderListIcon from '../../assets/icons/order_list.svg' +import flowchartIcon from '../../assets/icons/flowchart.svg' +import sequenceIcon from '../../assets/icons/sequence.svg' +import mermaidIcon from '../../assets/icons/mermaid.svg' +import vegaIcon from '../../assets/icons/chart.svg' export const quicInsertObj = { + 'diagram': [{ + title: 'Vega Chart', + subTitle: 'Render flow chart by vega-lite.js.', + label: 'vega-lite', + icon: vegaIcon, + color: 'rgb(224, 54, 54)' + }, { + title: 'Flow Chart', + subTitle: 'Render flow chart by flowchart.js.', + label: 'flowchart', + icon: flowchartIcon, + color: 'rgb(224, 54, 54)' + }, { + title: 'Sequence Diagram', + subTitle: 'Render sequence diagram by js-sequence.', + label: 'sequence', + icon: sequenceIcon, + color: 'rgb(224, 54, 54)' + }, { + title: 'Mermaid', + subTitle: 'Render Diagram by mermaid.', + label: 'mermaid', + icon: mermaidIcon, + color: 'rgb(224, 54, 54)' + }], 'basic block': [{ title: 'Text', subTitle: 'Just start write plain text.', diff --git a/src/muya/lib/utils/exportMarkdown.js b/src/muya/lib/utils/exportMarkdown.js index cc78b2fe..f28641fd 100644 --- a/src/muya/lib/utils/exportMarkdown.js +++ b/src/muya/lib/utils/exportMarkdown.js @@ -52,13 +52,23 @@ class ExportMarkdown { case 'figure': this.insertLineBreak(result, indent, true) - if (block.functionType === 'table') { - const table = block.children[1] - result.push(this.normalizeTable(table, indent)) - } else if (block.functionType === 'html') { - result.push(this.normalizeHTML(block, indent)) - } else if (block.functionType === 'multiplemath') { - result.push(this.normalizeMultipleMath(block, indent)) + switch (block.functionType) { + case 'table': + const table = block.children[1] + result.push(this.normalizeTable(table, indent)) + break + case 'html': + result.push(this.normalizeHTML(block, indent)) + break + case 'multiplemath': + result.push(this.normalizeMultipleMath(block, indent)) + break + case 'mermaid': + case 'flowchart': + case 'sequence': + case 'vega-lite': + result.push(this.normalizeContainer(block, indent)) + break } break @@ -173,6 +183,18 @@ class ExportMarkdown { return result.join('') } + // `mermaid` `flowchart` `sequence` `vega-lite` + normalizeContainer (block, indent) { + const result = [] + const diagramType = block.children[0].functionType + result.push('```' + diagramType + '\n') + for (const line of block.children[0].children[0].children) { + result.push(`${line.text}\n`) + } + result.push('```\n') + return result.join('') + } + normalizeCodeBlock (block, indent) { const result = [] const textList = block.children[1].children.map(codeLine => codeLine.text) diff --git a/src/muya/lib/utils/importMarkdown.js b/src/muya/lib/utils/importMarkdown.js index 4fc21050..80b1a232 100644 --- a/src/muya/lib/utils/importMarkdown.js +++ b/src/muya/lib/utils/importMarkdown.js @@ -73,7 +73,7 @@ const importRegister = ContentState => { } case 'multiplemath': { value = token.text - block = this.createMathBlock(value) + block = this.createContainerBlock(token.type, value) this.appendChild(parentList[0], block) break } @@ -83,25 +83,30 @@ const importRegister = ContentState => { if (value.endsWith('\n')) { value = value.replace(/\n+$/, '') } - block = this.createBlock('pre') - const codeBlock = this.createBlock('code') - value.split(LINE_BREAKS_REG).forEach(line => { - const codeLine = this.createBlock('span', line) - codeLine.lang = lang - codeLine.functionType = 'codeLine' - this.appendChild(codeBlock, codeLine) - }) - const inputBlock = this.createBlock('span', lang) - if (lang) { - loadLanguage(lang) + if (/mermaid|flowchart|vega-lite|sequence/.test(lang)) { + block = this.createContainerBlock(lang, value) + this.appendChild(parentList[0], block) + } else { + block = this.createBlock('pre') + const codeBlock = this.createBlock('code') + value.split(LINE_BREAKS_REG).forEach(line => { + const codeLine = this.createBlock('span', line) + codeLine.lang = lang + codeLine.functionType = 'codeLine' + this.appendChild(codeBlock, codeLine) + }) + const inputBlock = this.createBlock('span', lang) + if (lang) { + loadLanguage(lang) + } + inputBlock.functionType = 'languageInput' + this.codeBlocks.set(block.key, value) + block.functionType = codeBlockStyle === 'fenced' ? 'fencecode' : 'indentcode' + block.lang = codeBlock.lang = lang + this.appendChild(block, inputBlock) + this.appendChild(block, codeBlock) + this.appendChild(parentList[0], block) } - inputBlock.functionType = 'languageInput' - this.codeBlocks.set(block.key, value) - block.functionType = codeBlockStyle === 'fenced' ? 'fencecode' : 'indentcode' - block.lang = codeBlock.lang = lang - this.appendChild(block, inputBlock) - this.appendChild(block, codeBlock) - this.appendChild(parentList[0], block) break } case 'table': { diff --git a/src/muya/themes/dark.css b/src/muya/themes/dark.css index 73eefd9b..81d2b9e3 100755 --- a/src/muya/themes/dark.css +++ b/src/muya/themes/dark.css @@ -321,15 +321,14 @@ table tr:nth-child(2n) { table tr th { font-weight: bold; - border-top: 2px solid #606266; - border-bottom: 2px solid #606266; + border: 2px solid #606266; text-align: left; margin: 0; padding: 6px 13px; } table tr td { - border-bottom: 1px solid #606266; + border: 1px solid #606266; text-align: left; margin: 0; padding: 6px 13px;