diff --git a/.nyc_output/126e95e1-65f4-48bc-83ee-8648e86bd69e.json b/.nyc_output/126e95e1-65f4-48bc-83ee-8648e86bd69e.json new file mode 100644 index 0000000000000000000000000000000000000000..9e26dfeeb6e641a33dae4961196235bdb965b21b --- /dev/null +++ b/.nyc_output/126e95e1-65f4-48bc-83ee-8648e86bd69e.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/index.html b/index.html index abf2e772c44d380abbd4f691e7f3de3b055aa47c..a1005ed5b08df15b777afb69116eaa15589c087a 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> - <title>jabar-viz-masy</title> + <title>APBD Elektronik Provinsi Jawa Barat</title> </head> <body> <div id="app"></div> diff --git a/package-lock.json b/package-lock.json index 2863298d96330fcfbd0567776c7d11fd33faa75f..da35d07e4b05a2bef59b5901a8f9fd84961ac744 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,22 @@ "node-fetch": "^2.3.0" } }, + "@vue/test-utils": { + "version": "1.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-1.0.0-beta.29.tgz", + "integrity": "sha512-yX4sxEIHh4M9yAbLA/ikpEnGKMNBCnoX98xE1RwxfhQVcn0MaXNSj1Qmac+ZydTj6VBSEVukchBogXBTwc+9iA==", + "dev": true, + "requires": { + "dom-event-types": "^1.0.0", + "lodash": "^4.17.4" + } + }, + "abab": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz", + "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -53,6 +69,30 @@ } } }, + "acorn-globals": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.0.tgz", + "integrity": "sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw==", + "dev": true, + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, "ajv": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", @@ -94,6 +134,12 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, "ansi-html": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", @@ -178,6 +224,12 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", @@ -1416,6 +1468,18 @@ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", "dev": true }, + "browser-process-hrtime": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "dev": true + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", @@ -1936,8 +2000,7 @@ "commander": { "version": "2.17.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==" }, "commondir": { "version": "1.0.1", @@ -2494,6 +2557,21 @@ } } }, + "cssom": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz", + "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==", + "dev": true + }, + "cssstyle": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.2.tgz", + "integrity": "sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, "cuint": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", @@ -2524,6 +2602,270 @@ "es5-ext": "^0.10.9" } }, + "d3": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/d3/-/d3-5.9.2.tgz", + "integrity": "sha512-ydrPot6Lm3nTWH+gJ/Cxf3FcwuvesYQ5uk+j/kXEH/xbuYWYWTMAHTJQkyeuG8Y5WM5RSEYB41EctUrXQQytRQ==", + "requires": { + "d3-array": "1", + "d3-axis": "1", + "d3-brush": "1", + "d3-chord": "1", + "d3-collection": "1", + "d3-color": "1", + "d3-contour": "1", + "d3-dispatch": "1", + "d3-drag": "1", + "d3-dsv": "1", + "d3-ease": "1", + "d3-fetch": "1", + "d3-force": "1", + "d3-format": "1", + "d3-geo": "1", + "d3-hierarchy": "1", + "d3-interpolate": "1", + "d3-path": "1", + "d3-polygon": "1", + "d3-quadtree": "1", + "d3-random": "1", + "d3-scale": "2", + "d3-scale-chromatic": "1", + "d3-selection": "1", + "d3-shape": "1", + "d3-time": "1", + "d3-time-format": "2", + "d3-timer": "1", + "d3-transition": "1", + "d3-voronoi": "1", + "d3-zoom": "1" + } + }, + "d3-array": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" + }, + "d3-axis": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz", + "integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ==" + }, + "d3-brush": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.6.tgz", + "integrity": "sha512-lGSiF5SoSqO5/mYGD5FAeGKKS62JdA1EV7HPrU2b5rTX4qEJJtpjaGLJngjnkewQy7UnGstnFd3168wpf5z76w==", + "requires": { + "d3-dispatch": "1", + "d3-drag": "1", + "d3-interpolate": "1", + "d3-selection": "1", + "d3-transition": "1" + } + }, + "d3-chord": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.6.tgz", + "integrity": "sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA==", + "requires": { + "d3-array": "1", + "d3-path": "1" + } + }, + "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-color": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.2.3.tgz", + "integrity": "sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw==" + }, + "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.5", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.5.tgz", + "integrity": "sha512-vwKx+lAqB1UuCeklr6Jh1bvC4SZgbSqbkGBLClItFBIYH4vqDJCA7qfoy14lXmJdnBOdxndAMxjCbImJYW7e6g==" + }, + "d3-drag": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.3.tgz", + "integrity": "sha512-8S3HWCAg+ilzjJsNtWW1Mutl74Nmzhb9yU6igspilaJzeZVFktmY6oO9xOh5TDk+BM2KrNFjttZNoJJmDnkjkg==", + "requires": { + "d3-dispatch": "1", + "d3-selection": "1" + } + }, + "d3-dsv": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.1.1.tgz", + "integrity": "sha512-1EH1oRGSkeDUlDRbhsFytAXU6cAmXFzc52YUe6MRlPClmWb85MP1J5x+YJRzya4ynZWnbELdSAvATFW/MbxaXw==", + "requires": { + "commander": "2", + "iconv-lite": "0.4", + "rw": "1" + } + }, + "d3-ease": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.5.tgz", + "integrity": "sha512-Ct1O//ly5y5lFM9YTdu+ygq7LleSgSE4oj7vUt9tPLHUi8VCV7QoizGpdWRWAwCO9LdYzIrQDg97+hGVdsSGPQ==" + }, + "d3-fetch": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.1.2.tgz", + "integrity": "sha512-S2loaQCV/ZeyTyIF2oP8D1K9Z4QizUzW7cWeAOAS4U88qOt3Ucf6GsmgthuYSdyB2HyEm4CeGvkQxWsmInsIVA==", + "requires": { + "d3-dsv": "1" + } + }, + "d3-force": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.2.1.tgz", + "integrity": "sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg==", + "requires": { + "d3-collection": "1", + "d3-dispatch": "1", + "d3-quadtree": "1", + "d3-timer": "1" + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.11.3.tgz", + "integrity": "sha512-n30yN9qSKREvV2fxcrhmHUdXP9TNH7ZZj3C/qnaoU0cVf/Ea85+yT7HY7i8ySPwkwjCNYtmKqQFTvLFngfkItQ==", + "requires": { + "d3-array": "1" + } + }, + "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==" + }, + "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-path": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.7.tgz", + "integrity": "sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA==" + }, + "d3-polygon": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.5.tgz", + "integrity": "sha512-RHhh1ZUJZfhgoqzWWuRhzQJvO7LavchhitSTHGu9oj6uuLFzYZVeBzaWTQ2qSO6bz2w55RMoOCf0MsLCDB6e0w==" + }, + "d3-quadtree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.6.tgz", + "integrity": "sha512-NUgeo9G+ENQCQ1LsRr2qJg3MQ4DJvxcDNCiohdJGHt5gRhBW6orIB5m5FJ9kK3HNL8g9F4ERVoBzcEwQBfXWVA==" + }, + "d3-random": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.2.tgz", + "integrity": "sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ==" + }, + "d3-scale": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.2.2.tgz", + "integrity": "sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==", + "requires": { + "d3-array": "^1.2.0", + "d3-collection": "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.4.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.0.tgz", + "integrity": "sha512-EYVwBxQGEjLCKF2pJ4+yrErskDnz5v403qvAid96cNdCMr8rmCYfY5RGzWz24mdIbxmDf6/4EAH+K9xperD5jg==" + }, + "d3-shape": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.5.tgz", + "integrity": "sha512-VKazVR3phgD+MUCldapHD7P9kcrvPcexeX/PkMJmkUov4JM8IxsSg1DvbYoYich9AtdTsa5nNk2++ImPiDiSxg==", + "requires": { + "d3-path": "1" + } + }, + "d3-time": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.11.tgz", + "integrity": "sha512-Z3wpvhPLW4vEScGeIMUckDW7+3hWKOQfAWg/U7PlWBnQmeKQ00gCUsTtWSYulrKNA7ta8hJ+xXc6MHrMuITwEw==" + }, + "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" + } + }, + "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==" + }, + "d3-transition": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.2.0.tgz", + "integrity": "sha512-VJ7cmX/FPIPJYuaL2r1o1EMHLttvoIuZhhuAlRoOxDzogV8iQS6jYulDm3xEU3TqL80IZIhI551/ebmCMrkvhw==", + "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.4", + "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.4.tgz", + "integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg==" + }, + "d3-zoom": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.7.3.tgz", + "integrity": "sha512-xEBSwFx5Z9T3/VrwDkMt+mr0HCzv7XjpGURJ8lWmIC8wxe32L39eWHIasEe/e7Ox8MPU4p1hvH8PKN2olLzIBg==", + "requires": { + "d3-dispatch": "1", + "d3-drag": "1", + "d3-interpolate": "1", + "d3-selection": "1", + "d3-transition": "1" + } + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -2533,6 +2875,17 @@ "assert-plus": "^1.0.0" } }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, "date-now": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", @@ -2572,6 +2925,12 @@ "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", "dev": true }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -2705,6 +3064,12 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", "dev": true }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, "detect-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", @@ -2720,6 +3085,12 @@ "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", "dev": true }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, "diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -2774,6 +3145,12 @@ "utila": "~0.4" } }, + "dom-event-types": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dom-event-types/-/dom-event-types-1.0.0.tgz", + "integrity": "sha512-2G2Vwi2zXTHBGqXHsJ4+ak/iP0N8Ar+G8a7LiD2oup5o4sQWytwqqrZu/O6hIMV0KMID2PL69OhpshLO0n7UJQ==", + "dev": true + }, "dom-serializer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", @@ -2796,6 +3173,15 @@ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", "dev": true }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, "domhandler": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", @@ -3049,6 +3435,27 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "escodegen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz", + "integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==", + "dev": true, + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + } + } + }, "escope": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", @@ -3227,6 +3634,15 @@ } } }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, "express": { "version": "4.16.4", "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", @@ -3393,6 +3809,12 @@ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, "fastparse": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", @@ -3524,6 +3946,46 @@ "locate-path": "^2.0.0" } }, + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", + "dev": true + } + } + }, "flatten": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", @@ -3705,7 +4167,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -3726,12 +4189,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3746,17 +4211,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3873,7 +4341,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3885,6 +4354,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3899,6 +4369,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3906,12 +4377,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3930,6 +4403,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -4010,7 +4484,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -4022,6 +4497,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -4107,7 +4583,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -4143,6 +4620,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4162,6 +4640,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4205,12 +4684,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -4383,6 +4864,30 @@ } } }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, "globals": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", @@ -4420,6 +4925,12 @@ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, "growly": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", @@ -4604,6 +5115,15 @@ "os-tmpdir": "^1.0.1" } }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, "hosted-git-info": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", @@ -4628,9 +5148,18 @@ "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", "dev": true }, - "html-entities": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", "dev": true }, @@ -4888,7 +5417,6 @@ "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -5003,6 +5531,12 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, "internal-ip": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz", @@ -5347,6 +5881,73 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, + "jsdom": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-14.0.0.tgz", + "integrity": "sha512-/VkyPmdtbwqpJSkwDx3YyJ3U1oawYNB/h5z8vTUZGAzjtu2OHTeFRfnJqyMHsJ5Cyes23trOmvUpM1GfHH1leA==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^6.0.4", + "acorn-globals": "^4.3.0", + "array-equal": "^1.0.0", + "cssom": "^0.3.4", + "cssstyle": "^1.1.1", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.0", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.0.9", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "saxes": "^3.1.5", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.5.0", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^6.1.2", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "jsdom-global": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsdom-global/-/jsdom-global-3.0.2.tgz", + "integrity": "sha1-a9KZwTsMRiay2iwDk81DhdYGrLk=", + "dev": true + }, "jsesc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", @@ -5447,6 +6048,16 @@ "invert-kv": "^1.0.0" } }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", @@ -5556,6 +6167,12 @@ "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", "dev": true }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, "lodash.tail": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz", @@ -5633,6 +6250,15 @@ "pify": "^3.0.0" } }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -5987,76 +6613,765 @@ "minimist": "0.0.8" } }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "dev": true, - "requires": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" + "mocha": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.0.2.tgz", + "integrity": "sha512-RtTJsmmToGyeTznSOMoM6TPEk1A84FQaHIciKrRqARZx+B5ccJ5tXlmJzEKGBxZdqk9UjpRsesZTUkZmR5YnuQ==", + "dev": true, + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "findup-sync": "2.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.12.0", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "ms": "2.1.1", + "node-environment-flags": "1.0.4", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "12.0.5", + "yargs-parser": "11.1.1", + "yargs-unparser": "1.5.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "camelcase": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz", + "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==", + "dev": true + }, + "cliui": { + "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", + "wrap-ansi": "^2.0.0" + } + }, + "cross-spawn": { + "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", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "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" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "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 + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "lcid": { + "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" + } + }, + "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" + } + }, + "mem": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.2.0.tgz", + "integrity": "sha512-5fJxa68urlY0Ir8ijatKa3eRz5lwXnRCTvo9+TbTGAuTFJOwpGcY0X05moBd0nW45965Njt4CDI2GFQoG8DvqA==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "mimic-fn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.0.0.tgz", + "integrity": "sha512-jbex9Yd/3lmICXwYT6gA/j2mNQGU48wCh/VzRd+/Y/PjYQtlg1gLMdZqvu9s/xH7qKvngxRObl56XZR609IMbA==", + "dev": true + }, + "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 + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "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" + } + }, + "p-try": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.1.0.tgz", + "integrity": "sha512-H2RyIJ7+A3rjkwKC2l5GGtU4H1vkxKCAGsWasNVd0Set+6i4znxbWy6/j16YDPJDWxhsgZiKAstMEP8wCdSpjA==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "strip-ansi": { + "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" + } + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } } }, - "multicast-dns-service-types": { + "mocha-webpack": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", - "dev": true - }, - "nan": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.1.tgz", - "integrity": "sha512-I6YB/YEuDeUZMmhscXKxGgZlFnhsn5y0hgOZBadkzfTRrZBtJDZeg6eQf7PYMIEclwmorTKK8GztsyOUSVBREA==", - "dev": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "resolved": "https://registry.npmjs.org/mocha-webpack/-/mocha-webpack-1.1.0.tgz", + "integrity": "sha512-brmE0tR6G5JbEzZXspJmF/uZm2J/YM/69M3VS6ND76i6wXbebFpE+bQDaehilK8CZanNSsTCcqTTLh1PZuRKJw==", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "babel-runtime": "^6.18.0", + "chalk": "^2.3.0", + "chokidar": "^1.6.1", + "glob-parent": "^3.1.0", + "globby": "^6.1.0", + "interpret": "^1.0.1", + "is-glob": "^4.0.0", + "loader-utils": "^1.1.0", + "lodash": "^4.3.0", + "memory-fs": "^0.4.1", + "nodent-runtime": "^3.0.3", + "normalize-path": "^2.0.1", + "progress": "^2.0.0", + "source-map-support": "^0.5.0", + "strip-ansi": "^4.0.0", + "toposort": "^1.0.0", + "yargs": "^4.8.0" }, "dependencies": { - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true - } - } - }, - "negotiator": { + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "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" + } + } + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-fullwidth-code-point": { + "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" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + }, + "dependencies": { + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "^1.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "source-map-support": { + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.11.tgz", + "integrity": "sha512-//sajEx/fGL3iw6fltKMdPvy8kL3kJ2O3iuYlRoT3k9Kb4BjOoZ+BZzaNHeuaruSt+Kf3Zk9tnfAQg9/AJqUVQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "string-width": { + "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", + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "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" + } + } + } + }, + "strip-ansi": { + "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" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yargs": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "dev": true, + "requires": { + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" + } + }, + "yargs-parser": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" + } + } + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "requires": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, + "nan": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.1.tgz", + "integrity": "sha512-I6YB/YEuDeUZMmhscXKxGgZlFnhsn5y0hgOZBadkzfTRrZBtJDZeg6eQf7PYMIEclwmorTKK8GztsyOUSVBREA==", + "dev": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", @@ -6074,13 +7389,28 @@ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, "no-case": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", "dev": true, "requires": { - "lower-case": "^1.1.1" + "lower-case": "^1.1.1" + } + }, + "node-environment-flags": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.4.tgz", + "integrity": "sha512-M9rwCnWVLW7PX+NUWe3ejEdiLYinRpsEre9hMkU/6NS4h+EEulYaDH1gCEZ2gyXsmw+RXYDaV2JkkTNcsPDJ0Q==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3" } }, "node-fetch": { @@ -6238,6 +7568,12 @@ } } }, + "nodent-runtime": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/nodent-runtime/-/nodent-runtime-3.2.1.tgz", + "integrity": "sha512-7Ws63oC+215smeKJQCxzrK21VFVlCFBkwl0MOObt0HOpVQXs3u483sAmtkF33nNqZ5rSOQjB76fgyPBmAUrtCA==", + "dev": true + }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -6325,6 +7661,15 @@ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, + "nwsapi": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.2.tgz", + "integrity": "sha512-TQOQNxqEdxVjwgwNZyvKDF0vALmzQKZJEZwE3fZWDb7Ns5Hw6l9PxJTGKOHZGsmf7R6grsOe8lWxI43Clz79zg==", + "dev": true, + "requires": { + "jsdom": "^14.0.0" + } + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -6374,6 +7719,28 @@ "isobject": "^3.0.0" } }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", @@ -6457,6 +7824,28 @@ "last-call-webpack-plugin": "^2.1.2" } }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + }, + "dependencies": { + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, "ora": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ora/-/ora-1.4.0.tgz", @@ -6517,12 +7906,24 @@ "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 + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, + "p-is-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", + "dev": true + }, "p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", @@ -6632,6 +8033,18 @@ "json-parse-better-errors": "^1.0.1" } }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, "parseurl": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", @@ -6750,6 +8163,12 @@ "find-up": "^2.1.0" } }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, "popper.js": { "version": "1.14.7", "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.7.tgz", @@ -8852,6 +10271,12 @@ } } }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", @@ -8898,6 +10323,12 @@ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -9361,6 +10792,26 @@ "uuid": "^3.3.2" } }, + "request-promise-core": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", + "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + }, + "request-promise-native": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", + "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", + "dev": true, + "requires": { + "request-promise-core": "1.1.2", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -9403,6 +10854,16 @@ "resolve-from": "^3.0.0" } }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", @@ -9468,6 +10929,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=" + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -9486,8 +10952,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sass-graph": { "version": "2.2.4", @@ -9699,6 +11164,15 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, + "saxes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.9.tgz", + "integrity": "sha512-FZeKhJglhJHk7eWG5YM0z46VHmI3KJpMBAQm3xa9meDvd+wevB5GuBB0wc0exPInZiBBHqi00DbS8AcvCGCFMw==", + "dev": true, + "requires": { + "xmlchars": "^1.3.1" + } + }, "schema-utils": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", @@ -10270,6 +11744,12 @@ "readable-stream": "^2.0.1" } }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, "stream-browserify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", @@ -10381,6 +11861,12 @@ "get-stdin": "^4.0.1" } }, + "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 + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -10404,6 +11890,12 @@ "whet.extend": "~0.9.9" } }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "dev": true + }, "tapable": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.9.tgz", @@ -10452,6 +11944,11 @@ "setimmediate": "^1.0.4" } }, + "tiny-cookie": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tiny-cookie/-/tiny-cookie-1.0.1.tgz", + "integrity": "sha1-dTeGB5xkKjw9CyrMrWAPjeEZrCo=" + }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -10519,6 +12016,15 @@ } } }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", @@ -10567,6 +12073,15 @@ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, "type-is": { "version": "1.6.16", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", @@ -10946,6 +12461,14 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.10.tgz", "integrity": "sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==" }, + "vue-cookie": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/vue-cookie/-/vue-cookie-1.1.4.tgz", + "integrity": "sha1-uLRtESvan5Oi9HAXwu1SgtIGT9o=", + "requires": { + "tiny-cookie": "^1.0" + } + }, "vue-functional-data-merge": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/vue-functional-data-merge/-/vue-functional-data-merge-2.0.7.tgz", @@ -11064,6 +12587,26 @@ "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.1.0.tgz", "integrity": "sha512-mdHeHT/7u4BncpUZMlxNaIdcN/HIt1GsGG5LKByArvYG/v6DvHcOxvDCts+7SRdCoIRGllK8IMZvQtQXLppDYg==" }, + "w3c-hr-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", + "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "dev": true, + "requires": { + "browser-process-hrtime": "^0.1.2" + } + }, + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "dev": true, + "requires": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, "watchpack": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", @@ -11084,6 +12627,12 @@ "minimalistic-assert": "^1.0.0" } }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, "webpack": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.12.0.tgz", @@ -11467,6 +13016,12 @@ "lodash": "^4.17.5" } }, + "webpack-node-externals": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz", + "integrity": "sha512-ajerHZ+BJKeCLviLUUmnyd5B4RavLF76uv3cs6KNuO8W+HuQaEs0y0L7o40NQxdPy5w0pcv8Ew7yPUAQG0UdCg==", + "dev": true + }, "webpack-sources": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", @@ -11493,6 +13048,43 @@ "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", "dev": true }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + }, + "dependencies": { + "iconv-lite": { + "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" + } + } + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", + "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, "whet.extend": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", @@ -11592,6 +13184,18 @@ "safe-buffer": "~5.1.0" } }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xmlchars": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-1.3.1.tgz", + "integrity": "sha512-tGkGJkN8XqCod7OT+EvGYK5Z4SfDQGD30zAa58OcnAa0RRWgzUEK72tkXhsX1FZd+rgnhRxFtmO+ihkp8LHSkw==", + "dev": true + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", @@ -11703,6 +13307,214 @@ "dev": true } } + }, + "yargs-unparser": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz", + "integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.11", + "yargs": "^12.0.5" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "camelcase": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz", + "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==", + "dev": true + }, + "cliui": { + "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", + "wrap-ansi": "^2.0.0" + } + }, + "cross-spawn": { + "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", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "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" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "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 + }, + "lcid": { + "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" + } + }, + "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" + } + }, + "mem": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.2.0.tgz", + "integrity": "sha512-5fJxa68urlY0Ir8ijatKa3eRz5lwXnRCTvo9+TbTGAuTFJOwpGcY0X05moBd0nW45965Njt4CDI2GFQoG8DvqA==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "mimic-fn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.0.0.tgz", + "integrity": "sha512-jbex9Yd/3lmICXwYT6gA/j2mNQGU48wCh/VzRd+/Y/PjYQtlg1gLMdZqvu9s/xH7qKvngxRObl56XZR609IMbA==", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "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" + } + }, + "p-try": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.1.0.tgz", + "integrity": "sha512-H2RyIJ7+A3rjkwKC2l5GGtU4H1vkxKCAGsWasNVd0Set+6i4znxbWy6/j16YDPJDWxhsgZiKAstMEP8wCdSpjA==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "strip-ansi": { + "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" + } + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } } } } diff --git a/package.json b/package.json index a121b3603e6a1552008f99e75d03b7943358991b..154057e9ccc9cacc91627a8bbf671b6fb7867fc7 100644 --- a/package.json +++ b/package.json @@ -12,11 +12,15 @@ "dependencies": { "bootstrap": "^4.3.1", "bootstrap-vue": "^2.0.0-rc.15", + "d3": "^5.9.2", + "d3-scale-chromatic": "^1.3.3", "vue": "^2.6.10", + "vue-cookie": "^1.1.4", "vue-router": "^3.0.1", "vuex": "^3.1.0" }, "devDependencies": { + "@vue/test-utils": "^1.0.0-beta.29", "autoprefixer": "^7.1.2", "babel-core": "^6.22.1", "babel-helper-vue-jsx-merge-props": "^2.0.3", @@ -33,6 +37,10 @@ "file-loader": "^1.1.4", "friendly-errors-webpack-plugin": "^1.6.1", "html-webpack-plugin": "^2.30.1", + "jsdom": "^14.0.0", + "jsdom-global": "^3.0.2", + "mocha": "^6.0.2", + "mocha-webpack": "^1.1.0", "node-notifier": "^5.1.2", "node-sass": "^4.11.0", "optimize-css-assets-webpack-plugin": "^3.2.0", @@ -53,7 +61,8 @@ "webpack": "^3.6.0", "webpack-bundle-analyzer": "^2.9.0", "webpack-dev-server": "^2.9.1", - "webpack-merge": "^4.1.0" + "webpack-merge": "^4.1.0", + "webpack-node-externals": "^1.7.2" }, "engines": { "node": ">= 6.0.0", diff --git a/src/App.vue b/src/App.vue index 6ffe61311b819f8453f8cc169efd9371afbf6fb4..4156da51e1c194b89f9858a559c42c71ebb911ba 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,27 +1,67 @@ <template> <div id="app"> - <app-navbar v-if="this.$route.name != 'LandingPage'"/> - <router-view/> + <app-navbar id="navbar" v-if="this.$route.name != 'LandingPage'"/> + <transition name="fade" mode="out-in"> + <router-view v-if="this.$route.name == 'LandingPage'"/> + <router-view v-else class="content"/> + </transition> </div> </template> <script> -import navbar from '@/components/Navbar' +import navbar from '@/components/partials/Navbar' export default { name: 'App', components: { 'app-navbar': navbar, }, + mounted() { + if(this.$cookie.get('token')) { + let fetchData = { + method: 'POST', + headers: { + "Authorization": this.$cookie.get('token'), + } + } + + fetch(`${this.$store.state.baseUrl}/api/get-user`, fetchData) + .then(response => response.json()) + .then(response => { + if(response.status === 200) { + let data = { + 'token': this.$cookie.get('token'), + 'id': response.data._id, + 'name': response.data.name, + 'role': response.data.role, + 'pageList': response.page_list + } + console.log(response) + this.$store.commit('setUser', data) + } + }) + } + } } </script> -<style> +<style lang="scss"> +@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700,700i'); #app { - font-family: 'Avenir', Helvetica, Arial, sans-serif; + font-family: 'Open Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + overflow: hidden; + + #navbar { + position: fixed; + z-index: 999; + } +} + +.content { + margin-top : 60px; } </style> diff --git a/src/assets/css/style.scss b/src/assets/css/style.scss index 449fa34f2ceeb6e61fda1ba0be80dad320799a09..f5af2f1ad78811a9cabfd6c3b59bdd2a61d89d69 100644 --- a/src/assets/css/style.scss +++ b/src/assets/css/style.scss @@ -2,3 +2,18 @@ $primary: #17a2b8; @import 'node_modules/bootstrap/scss/bootstrap'; @import 'node_modules/bootstrap-vue/src/index.scss'; + +.fade-enter-active, .fade-leave-active { + transition: all .3s ease; +} +.fade-enter, .fade-leave-to { + opacity: 0; +} +.fade-enter { + opacity: 0; + transform: translateY(10px); +} +.fade-leave-to { + opacity: 0; + transform: translateY(-10px); +} \ No newline at end of file diff --git a/src/assets/etc/visualisasi.csv b/src/assets/etc/visualisasi.csv new file mode 100644 index 0000000000000000000000000000000000000000..9b5a05c37e17d30b1528db493ee02fc736c47358 --- /dev/null +++ b/src/assets/etc/visualisasi.csv @@ -0,0 +1,5 @@ +id,title,category,amount +0,Pendapatan,Pendapatan,4000000000000 +1,Biaya Langsung,Biaya Langsung,3000000000000 +2,Biaya Tidak Langsung,Biaya Tidak Langsung,2000000000000 +3,Pembiayaan,Pembiayaan,1000000000000 \ No newline at end of file diff --git a/src/components/Navbar.vue b/src/components/Navbar.vue deleted file mode 100644 index 961d3d25ebc55bb9a4bbf8406b8a5bb7a1b0fb6f..0000000000000000000000000000000000000000 --- a/src/components/Navbar.vue +++ /dev/null @@ -1,94 +0,0 @@ -<template> - <div id="navbar"> - <b-navbar toggleable="lg" type="dark" variant="info"> - <b-navbar-brand> - <router-link to="/"> - APBD JABAR - </router-link> - </b-navbar-brand> - - <b-navbar-toggle target="nav_collapse" /> - - <b-collapse is-nav id="nav_collapse"> - <!-- Right aligned nav items --> - <b-navbar-nav> - <b-nav-item-dropdown v-bind:text=pilihan left> - <b-dropdown-item v-on:click="gotoPage('semua-anggaran')"> - Semua Anggaran - </b-dropdown-item> - <b-dropdown-item v-on:click="gotoPage('pendapatan')"> - Anggaran Pendapatan - </b-dropdown-item> - <b-dropdown-item v-on:click="gotoPage('biaya-langsung')"> - Anggaran Biaya Langsung - </b-dropdown-item> - <b-dropdown-item v-on:click="gotoPage('biaya-tidak-langsung')"> - Anggaran Biaya Tidak Langsung - </b-dropdown-item> - <b-dropdown-item v-on:click="gotoPage('pembiayaan')"> - Anggaran Pembiayaan - </b-dropdown-item> - </b-nav-item-dropdown> - </b-navbar-nav> - - <b-navbar-nav class="ml-auto"> - <b-nav-item> - <router-link to="/login" style="color:white;"> - Masuk - </router-link> - </b-nav-item> - </b-navbar-nav> - - - </b-collapse> - </b-navbar> - </div> -</template> - -<script> - -export default { - name: 'Navbar', - data () { - return { - pilihan : this.$store.state.pilihan, - } - }, - computed : { - state_watcher () { - return this.$store.state.pilihan - } - }, - methods : { - gotoPage : function(page) { - this.$router.push(page) - } - }, - created : function() { - this.pilihan = this.$store.state.pilihan - }, - watch : { - state_watcher(newPilihan, oldPilihan) { - // console.log("lama : " + oldPilihan + ", baru :" +newPilihan) - this.pilihan = newPilihan - } - } -} -</script> - -<!-- Add "scoped" attribute to limit CSS to this component only --> -<style scoped> -b-nav-item { - color: white; -} -li a { - text-decoration: none; - color : black; -} - -a { - text-decoration: none; - color : white; -} - -</style> diff --git a/src/components/pages/BiayaLangsungPage.vue b/src/components/pages/BiayaLangsungPage.vue index 5b5a8c2967ae17a9347406e39ad5bed3a6d421d5..2e65195f150309c49f0158850cefde5b0d388cba 100644 --- a/src/components/pages/BiayaLangsungPage.vue +++ b/src/components/pages/BiayaLangsungPage.vue @@ -1,25 +1,185 @@ <template> - <div> - Biaya Langsung - </div> + <b-container> + <b-breadcrumb class="bg-light" :items="items"></b-breadcrumb> + <h2>ANGGARAN BELANJA LANGSUNG APBD JABAR</h2> + <b-row class="justify-content-md-center"> + <b-col id="visualization" class="bg-light" cols="12"> + <div id="toggle" v-if="currentData.level == 1"> + <b-button class="option-toggle float-right" @click="toggleHandler()"> + <span v-if="toggleData">Tampilan per Dinas</span> + <span v-else>Tampilan per urusan</span> + </b-button> + </div> + <visualization + v-bind:src="data" + @click-handler="visualizationHandler" + ref="viz" + /> + </b-col> + </b-row> + <b-row class="justify-content-md-center"> + <b-col cols="12" lg="6"> + <detail-card :detailAnggaran='items' /> + </b-col> + <b-col id="anggaran-detail-card" cols="12" lg="6"> + <simple-card-container-scroll + @click-handler="visualizationHandler" + :dataBubble='data' + /> + </b-col> + </b-row> + <b-col id="comments-container" cols="12" lg="8"> + <comments + commentable + v-bind:id="this.$route.params.id" + /> + </b-col> + </b-container> </template> <script> +import SimpleCardContainerScroll from '@/components/partials/SimpleCardContainerScroll' +import Comments from '@/components/partials/Comments' +import Visualization from '@/components/partials/Visualization' +import DetailCard from '@/components/partials/DetailCard' + export default { name: 'BiayaLangsung', components: { - + 'simple-card-container-scroll' : SimpleCardContainerScroll, + 'comments' : Comments, + 'visualization' : Visualization, + 'detail-card' : DetailCard }, data() { return { - + data: [], + currentData: {level: 0}, + items: [], + toggleData: false } }, methods: { - + visualizationHandler(idobj) { + let id = idobj.$oid + this.toggleData = false + this.$router.push({ name: 'BiayaLangsungId', params: { id: id } }) + }, + getLowestLevel(data) { + return data[data.length-1].level + }, + searchData(data, currentData) { + for (let i = 0; i < data.length; i++) { + if (data[i].level == currentData.level && data[i].text == currentData.name) { + return i + } + } + return -1 + }, + clearArray(arr) { + arr.splice(0, arr.length) + }, + breadcrumbHandler() { + // Clear or slice breadcrumb item list depending on the condition + if (this.items.length != 0) { + if (this.getLowestLevel(this.items) > this.currentData.level) { + // If the user visits earlier page, trim the breadcrumb items + let i = this.searchData(this.items, this.currentData) + if (i != -1) + this.items = this.items.slice(0, i) + else + this.clearArray(this.items) + } else if (this.currentData.level - this.getLowestLevel(this.items) >= 2) + // If the user jumps two level after the lowest level + // immediately clear all breadcrumb items + this.clearArray(this.items) + } + + // Automatically append 'Semua Anggaran' when on the topmost level + if (this.currentData.level == 1 && this.items.length == 0) { + this.items.push({ + text: 'Semua Anggaran', + level: 0, + to: { name: 'SemuaAnggaran' } + }) + } + + // Push current item to breadcrumb item list + this.items.push({ + text: this.currentData.name, + level: this.currentData.level, + value: this.currentData.value, + id: this.currentData._id.$oid, + active: true + }) + + // Logic to add routing link to each non-active breadcrumb items + if (this.items.length >= 2 && this.items[this.items.length-2].text != "Semua Anggaran") { + var item = this.items[this.items.length-2] + item.active = false + item.to = { name: 'BiayaLangsungId', params: { id: item.id } } + } + }, + getData(id, updateBreadcrumbHandler) { + let fetchData = { + method: 'POST', + body: JSON.stringify({ page_id: id }), + headers: { "Content-Type": "application/json" } + } + + let url = '' + if (this.toggleData) + url = `${this.$store.state.baseUrl}/api/page/get-grandchildren` + else + url = `${this.$store.state.baseUrl}/api/page/get` + + fetch(url, fetchData) + .then(response => response.json()) + .then(response => { + if(response.status === 200) { + this.data = response.subdata.sort(function(a, b) { + return b.value - a.value; + }) + this.currentData = response.data + console.log(this.data) + if (updateBreadcrumbHandler) this.breadcrumbHandler() + } + }) + }, + getDataFromTop() { + let fetchData = { + method: 'POST', + body: JSON.stringify({ year: 2019 }), + headers: { "Content-Type": "application/json" } + } + + fetch(`${this.$store.state.baseUrl}/api/page/get-top`, fetchData) + .then(response => response.json()) + .then(response => { + if(response.status === 200) { + this.data = response.subdata + this.currentData = response.data + this.breadcrumbHandler() + } + }) + }, + toggleHandler() { + this.toggleData = !this.toggleData + this.getData(this.currentData._id.$oid, false) + this.$refs.viz.clear() + } }, created : function() { this.$store.commit('changed','Anggaran Biaya Langsung') + if (!this.$route.params.id) this.getDataFromTop() + else this.getData(this.$route.params.id, true) + }, + watch: { + $route(to, from) { + if (!this.$route.params.id) this.getDataFromTop() + else this.getData(this.$route.params.id, true) + this.$refs.viz.clear() + }, } } </script> @@ -28,4 +188,43 @@ export default { <style lang="scss" scoped> @import 'src/assets/css/style.scss'; +h2 { + color: $primary; + text-shadow: 0 5px 10px rgba(50, 50, 50, 0.25); + margin: 10px 10px; +} + +.container { + overflow: hidden; + + #comments-container { + margin: 10px auto; + max-width: 800px; + } +} + +#visualization { + height: 50vh; + + #toggle { + position: absolute; + top: 1rem; + right: 1rem; + z-index: 3; + } +} + +.breadcrumb { + height: auto; + margin: 10px 0; + font-size: 0.9rem; + color: white; + background: $primary; +} + +.breadcrumb-item + .breadcrumb-item:before { + color: #aaa; + content: ">>"; +} + </style> \ No newline at end of file diff --git a/src/components/pages/LandingPage.vue b/src/components/pages/LandingPage.vue index a9a8303402f092e78a2ecd6ef0bfa3eabad1618f..30035b204620fc458bd9ab5a66884c724ddb2ff3 100644 --- a/src/components/pages/LandingPage.vue +++ b/src/components/pages/LandingPage.vue @@ -8,7 +8,7 @@ Selamat Datang di APBD Elektronik Pemerintah Jawa Barat </h2> <div> - <b-dropdown id="ddown1" text="Pilih Tahun..." class="m-md-2"> + <b-dropdown id="ddown1" variant="primary" text="Pilih Tahun..." class="m-md-2"> <b-dropdown-item v-on:click="gotoYear('2016')">2016</b-dropdown-item> <b-dropdown-item v-on:click="gotoYear('2017')">2017</b-dropdown-item> <b-dropdown-item v-on:click="gotoYear('2018')">2018</b-dropdown-item> @@ -53,7 +53,7 @@ export default { display: flex; text-align: center; - background: linear-gradient(0deg, rgba(93,188,210,1) 0%, rgba(93,188,210,0.75) 50%, rgba(93,188,210,0) 100%), + background: linear-gradient(0deg, rgba($primary,1) 0%, rgba($primary,0.75) 50%, rgba($primary,0) 100%), url('https://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Gedung-Sate-Trees.jpg/1024px-Gedung-Sate-Trees.jpg'); background-size: cover; background-position: center; diff --git a/src/components/pages/LoginPage.vue b/src/components/pages/LoginPage.vue index 15941fd521dccd1088fe1ee72ae2435283373a22..4988bb6ae585d73a5af2c9717e82558b9c79e175 100644 --- a/src/components/pages/LoginPage.vue +++ b/src/components/pages/LoginPage.vue @@ -4,7 +4,16 @@ <b-card no-body> <b-tabs card> <b-tab title="Masuk" active> - <b-form @submit="submitLogin"> + <b-alert + :show="dismissCountDown" + dismissible + variant="warning" + @dismissed="dismissCountDown=0" + @dismiss-count-down="countdownCallback" + > + {{ errorMessage }} + </b-alert> + <b-form @submit.prevent="submitLogin"> <b-form-group label="Nama Pengguna:"> <b-form-input type="text" @@ -21,11 +30,20 @@ placeholder="Masukkan kata sandi" /> </b-form-group> - <b-button type="submit" variant="primary">Masuk</b-button> + <b-button @click="submitLogin" type="submit" variant="primary">Masuk</b-button> </b-form> </b-tab> <b-tab title="Daftar"> - <b-form @submit="submitRegister"> + <b-alert + :show="dismissCountDown" + dismissible + variant="warning" + @dismissed="dismissCountDown=0" + @dismiss-count-down="countdownCallback" + > + {{ errorMessage }} + </b-alert> + <b-form> <b-form-group label="NIK/NIP:"> <b-form-input type="text" @@ -66,7 +84,7 @@ placeholder="Masukkan ulang kata sandi" /> </b-form-group> - <b-button type="submit" variant="primary">Daftar</b-button> + <b-button @click="submitRegister" variant="primary">Daftar</b-button> </b-form> </b-tab> </b-tabs> @@ -93,22 +111,135 @@ export default { username: '', password: '', confirmPassword: '' - } + }, + errorMessage: '', + dismissSecs: 5, + dismissCountDown: 0 } }, created : function() { - this.$store.commit('changed','Jenis Keuangan') + this.$store.commit('changed','Jenis Anggaran') }, methods: { - submitLogin: function(event) { - // TODO: Create function to log in the user - this.$store.commit('setUser', 'ABCD', 1, this.login.username) - this.$router.push('/') + submitLogin() { + if (this.login.username.length == 0 || this.login.password.length == 0) { + this.setErrorMessage("Kata pengguna/sandi wajib diisi") + return + } + + let fetchData = { + method: 'POST', + body: JSON.stringify( + { + username: this.login.username, + password: this.login.password, + } + ), + headers: { + "Content-Type": "application/json", + } + } + + fetch(`${this.$store.state.baseUrl}/api/login`, fetchData) + .then(response => response.json()) + .then(response => { + if(response.status === 200) { + this.$cookie.set('token', response.data.token) + let data = { + 'token': response.data.token, + 'id': response.data.user._id, + 'name': response.data.user.name, + 'role': response.data.user.role, + 'pageList': response.data.page_list + } + this.$store.commit('setUser', data) + this.$router.push({name: 'LandingPage'}) + } else if(response.status === 404) { + this.setErrorMessage('Kata pengguna/sandi salah.') + } else { + this.setErrorMessage('Tidak dapat masuk. Silakan coba lagi.') + } + }) + .catch(error => { + this.setErrorMessage('Tidak dapat terhubung dengan server. Mohon periksa koneksi internet dan cobalah beberapa saat lagi.') + }) + }, + submitRegister() { + if (this.register.username.length === 0) { + this.setErrorMessage("Kata pengguna wajib diisi") + return + } + if (this.register.nik.length === 0) { + this.setErrorMessage("NIK wajib diisi") + return + } + if (this.register.name.length === 0) { + this.setErrorMessage("Nama lengkap wajib diisi") + return + } + if (this.register.password.length === 0) { + this.setErrorMessage("Kata sandi wajib diisi") + return + } + if (this.register.password !== this.register.confirmPassword) { + this.setErrorMessage("Kata sandi tidak cocok") + return + } + if (this.register.password !== this.register.confirmPassword) { + this.setErrorMessage("Kata sandi tidak cocok") + return + } + + let role = 0 + if (this.register.nik.length === 18) + role = 1 + + let fetchData = { + method: 'POST', + body: JSON.stringify( + { + username: this.register.username, + password: this.register.password, + user_id: this.register.nik, + name: this.register.name, + role: role + } + ), + headers: { + "Content-Type": "application/json", + } + }; + + fetch(`${this.$store.state.baseUrl}/api/register`, fetchData) + .then(response => response.json()) + .then(response => { + if(response.status === 200) { + this.$cookie.set('token', response.data.token) + let data = { + 'token': response.data.token, + 'id': this.register.nik, + 'name': this.register.name, + 'role': role, + 'pageList': [] + } + this.$store.commit('setUser', data) + this.$router.push({name: 'LandingPage'}) + } else if (response.status === 500) { + this.setErrorMessage('Akun dengan NIK ini sudah dibuat.') + } else { + this.setErrorMessage('Terjadi kesalahan. Kesalahan: ' + response.message) + } + }) + .catch(error => { + this.setErrorMessage('Tidak dapat terhubung dengan server. Mohon periksa koneksi internet dan cobalah beberapa saat lagi.') + }) + }, + countdownCallback(dismissCountDown) { + this.dismissCountDown = dismissCountDown }, - submitRegister: function(event) { - // TODO: Create function to register new user - this.$store.commit('setUser', 'ABCD', 1, this.register.username) - this.$router.push('/') + setErrorMessage(message) { + this.errorMessage = message + this.dismissCountDown = this.dismissSecs } } } diff --git a/src/components/pages/PanelAdministrator.vue b/src/components/pages/PanelAdministrator.vue new file mode 100644 index 0000000000000000000000000000000000000000..e8703e0272a8ede9a5239b75c74531c838daa05d --- /dev/null +++ b/src/components/pages/PanelAdministrator.vue @@ -0,0 +1,318 @@ +<template> + <div id="placeholder"> + <div id="container"> + <b-card no-body> + <b-tabs card> + <b-tab title="Komentar" active> + <b-card no-body> + <b-tabs v-model="tabIndex" pills vertical card> + <b-tab title="Entri Komentar" disabled/> + <b-tab + v-for="(item, index) in pageList" + :key=item._id.$oid + v-bind:title="item.name"> + <b-tabs v-model="tabIndexInner" content-class="mt-3"> + <b-tab title="Belum dibalas" active> + <comments :id="item._id.$oid" :ref="index+'-0'" replyable unreplied/> + </b-tab> + <b-tab title="Semua"> + <comments :id="item._id.$oid" :ref="index+'-1'" replyable/> + </b-tab> + </b-tabs> + </b-tab> + </b-tabs> + </b-card> + </b-tab> + <b-tab v-if="this.$store.state.user.role == 2" title="Pengaturan Admin"> + <table-budget :dataTable='dataTable' :key='dataTable.current_item.admin_name' v-on:changeActivity="updateActivity($event)" v-on:backState="backState()"/> + </b-tab> + </b-tabs> + </b-card> + </div> + </div> +</template> + +<script> +import Comments from '@/components/partials/Comments' +import TableBudget from '@/components/partials/TableBudget' + + +export default { + name: 'PanelAdministrator', + components: { + 'comments' : Comments, + 'table-budget' : TableBudget + }, + computed: { + pageList() { + return this.$store.state.user.pageList + } + }, + data() { + return { + currentRow: null, + clearedRowPointer: null, + modalVisibility: false, + totalRows: 1, + currentPage: 1, + perPage: 15, + filter: null, + selected: 'urusan', + tabIndex: 1, + tabIndexInner: 0, + fields: ['urusan', 'admin', 'aksi'], + urusan : [ + { judul: "Pendapatan", url: "" }, + { judul: "Pembiayaan", url: "" }, + { judul: "Biaya Langsung", url: "" }, + { judul: "Biaya Tidak Langsung", url: "" }, + ], + items : [ + { urusan: 'Biaya Langsung', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'Biaya Tak Langsung', admin: 'David Timothy Panjaitan'}, + { urusan: 'Pembiayaan', admin: '-'}, + { urusan: 'Pendapatan', admin: '-'}, + { urusan: 'A', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'B', admin: 'David Timothy Panjaitan'}, + { urusan: 'C', admin: '-'}, + { urusan: 'D', admin: '-'}, + { urusan: 'E', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'F', admin: 'David Timothy Panjaitan'}, + { urusan: 'G', admin: '-'}, + { urusan: 'H', admin: '-'}, + { urusan: 'I', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'J', admin: 'David Timothy Panjaitan'}, + { urusan: 'K', admin: '-'}, + { urusan: 'L', admin: '-'}, + { urusan: 'M', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'N', admin: 'David Timothy Panjaitan'}, + { urusan: 'O', admin: '-'}, + { urusan: 'P', admin: '-'}, + { urusan: 'Q', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'R', admin: 'David Timothy Panjaitan'}, + { urusan: 'S', admin: '-'}, + { urusan: 'T', admin: '-'}, + { urusan: 'U', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'V', admin: 'David Timothy Panjaitan'}, + { urusan: 'W', admin: '-'}, + { urusan: 'X', admin: '-'}, + { urusan: 'Y', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'Z', admin: 'David Timothy Panjaitan'}, + ], + options: [ + ], + dataTable : { + perPage: 10, + currentPage: 1, + fields : { + activity_name : { + label : 'Activity Name', + sortable : true, + }, + admin_name : { + label : 'Admin Name', + sortable : true, + }, + actions : { + label : 'Actions' + } + }, + current_item: { + id : 99, activity_name:'current activity', admin_name : 'aaa' + }, + items: [ + // { id: 1, activity_name: 'A', admin_name: 'Flintstone' }, + // { id: 2, activity_name: 'B', admin_name: 'Flintstone' }, + // { id: 3, activity_name: 'C', admin_name: 'Rubbleaskldjf klsajdfklsajdkalskjdfklsjdfalkdflksdj fljslkfjskldfj lksajlkfjsdl ksalksjdfklasjdlkjfs lkdjfklsajfklasklfmasdlkfsj oidfamslkdfmi saldkfmsialfi madlifsm' }, + // { id: 4, activity_name: 'D', admin_name: 'Rubble' }, + // { id: 5, activity_name: 'E', admin_name: 'Flintstone' }, + // { id: 6, activity_name: 'F', admin_name: 'Rubble' }, + // { id: 7, activity_name: 'G', admin_name: 'Gazzoo' }, + // { id: 8, activity_name: 'H', admin_name: 'Slate' }, + // { id: 9, activity_name: 'I', admin_name: 'Slaghoople' }, + // { id: 10, first_name: 'Ricky', last_name: 'Kennedy' } + ], + options: [ + // { value: '0', text: 'Rifo Ahmad Genadi' }, + // { value: '1', text: 'David Timothy Panjaitan' }, + // { value: '2', text: 'William Rukmansa' }, + // { value: '3', text: 'Ricky Kennedy' } + ], + isNotTop : false, + }, + dataStack : [ + + ] + } + }, + created : function() { + if (this.$store.state.user.role <= 0) { + this.$router.push({name: 'LandingPage'}); + return + } + this.totalRows = this.items.length + this.$store.commit('changed','Jenis Anggaran') + if (this.$store.state.user.role === 2 ) { + this.fillAdmin() + this.fillDataTable('top') + } + }, + watch : { + tabIndex() { + this['$refs'][(this.tabIndex-1) + '-' + this.tabIndexInner][0]['refreshContent']() + }, + tabIndexInner() { + this['$refs'][(this.tabIndex-1) + '-' + this.tabIndexInner][0]['refreshContent']() + } + }, + methods: { + assignAdmin : function(row) { + row.item.admin = this.options[this.selected].text + this.switchToggleDetails(null) + }, + clearButtonHandler : function(row) { + this.modalVisibility = true + this.clearedRowPointer = row + }, + clearAdminHandler : function() { + this.clearedRowPointer.item.admin = "-" + this.switchToggleDetails(null) + }, + switchToggleDetails : function(newRow) { + if (this.currentRow) { + this.currentRow.toggleDetails() + } + if (newRow) { + newRow.toggleDetails() + } + this.currentRow = newRow + this.selected = null + }, + filterTrigger(item) { + this.totalRows = item.length + this.currentPage = 1 + }, + + updateCurrentActivity: function(id, activity_name, admin_name) { + this.dataTable.current_item.id = id; + this.dataTable.current_item.activity_name = activity_name; + this.dataTable.current_item.admin_name = admin_name; + }, + + updateActivity: function(event) { + this.fillDataTable(event.$oid) + }, + fillAdmin : function() { + let fetchData = { + method: 'POST', + body: JSON.stringify({}), + headers: { "Content-Type": "application/json" } + } + + fetch(`${this.$store.state.baseUrl}/api/admin/get-all`, fetchData) + .then(response => response.json()) + .then(response => { + if(response.status === 200) { + for (var it in response.data) { + let temp = {value : 99 , text:'test'} + // console.log(response.data[it]) + temp.value = response.data[it]._id + temp.text = response.data[it].name + this.dataTable.options.push(temp) + } + } + }) + }, + fillDataTable : function(idPage) { + if (idPage === 'top') { + let fetchData = { + method: 'POST', + body: JSON.stringify({ year: 2019, return_admin : true }), + headers: { "Content-Type": "application/json" } + } + + fetch(`${this.$store.state.baseUrl}/api/page/get-top`, fetchData) + .then(response => response.json()) + .then(response => { + if(response.status === 200) { + this.dataTable.items = [] + for ( let i =0 ; i < response.subdata.length; i++) { + let admin = '--' + if (response.admin_subdata[i] !== null) { + admin = response.admin_subdata[i].name + } + this.dataTable.items.push({id:response.subdata[i]._id, activity_name:response.subdata[i].name, admin_name : admin}) + } + this.dataTable.current_item.id = response.data._id.$oid + if( response.admin !== null ) + this.dataTable.current_item.admin_name = response.admin.name + else + this.dataTable.current_item.admin_name = '--' + this.dataTable.current_item.activity_name = response.data.name + + this.dataStack.push(idPage); + } + }) + this.dataTable.isNotTop = false + } else { + let fetchData = { + method: 'POST', + body: JSON.stringify({ page_id: idPage , return_admin : true }), + headers: { "Content-Type": "application/json" } + } + + fetch(`${this.$store.state.baseUrl}/api/page/get`, fetchData) + .then(response => response.json()) + .then(response => { + if(response.status === 200) { + this.dataTable.items = [] + for ( let i =0 ; i < response.subdata.length; i++) { + let admin = '--' + if (response.admin_subdata[i] !== null) { + admin = response.admin_subdata[i].name + } + this.dataTable.items.push({id:response.subdata[i]._id, activity_name:response.subdata[i].name, admin_name : admin}) + } + this.dataTable.current_item.id = response.data._id.$oid + if( response.admin !== null ) + this.dataTable.current_item.admin_name = response.admin.name + else + this.dataTable.current_item.admin_name = '--' + this.dataTable.current_item.activity_name = response.data.name + this.dataStack.push(idPage); + + } + + }) + this.dataTable.isNotTop = true + } + + }, + backState : function() { + this.dataStack.pop() + let current= this.dataStack.pop() + this.fillDataTable(current) + } + + } +} +</script> + + +<style lang="scss" scoped> +@import 'src/assets/css/style.scss'; + +#placeholder { + padding: 30px 20px; + + #container { + height: auto; + width: 100%; + min-width: 250px; + max-width: 1000px; + margin: auto; + border-radius: 5px; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.25); + } +} +</style> \ No newline at end of file diff --git a/src/components/pages/PanelBackup.vue b/src/components/pages/PanelBackup.vue new file mode 100644 index 0000000000000000000000000000000000000000..19984f0bb6c5d1122509b923a4ec87dd13f8f43a --- /dev/null +++ b/src/components/pages/PanelBackup.vue @@ -0,0 +1,277 @@ +<template> + <div id="placeholder"> + <div id="container"> + <b-card no-body> + <b-tabs card> + <b-tab title="Komentar" active> + <b-card no-body> + <b-tabs pills vertical card> + <b-tab title="Entri Komentar" disabled/> + <b-tab + v-for="item in urusan" + :key=item.judul + v-bind:title="item.judul"> + <b-tabs content-class="mt-3"> + <b-tab title="Belum dibalas" active> + <comments replyable/> + </b-tab> + <b-tab title="Semua"> + <comments replyable/> + </b-tab> + </b-tabs> + </b-tab> + </b-tabs> + </b-card> + </b-tab> + <b-tab v-if="this.$store.state.user.role == 2" title="Pengaturan Admin"> + <!-- Table Pagination + Filter --> + <b-pagination + v-model="currentPage" + :total-rows="totalRows" + :per-page="perPage" + align="center" + /> + <b-form-input + v-model="filter" + placeholder="Ketik untuk menyaring urusan/admin..." + /> + <div class="mb-3"> + <small class="text-muted font-italic"> + Menampilkan {{ totalRows }} baris urusan + </small> + </div> + <b-table + show-empty + striped + hover + stacked="sm" + :items="items" + :fields="fields" + :current-page="currentPage" + :per-page="perPage" + :filter="filter" + @filtered="filterTrigger" + > + <template slot="aksi" slot-scope="row"> + <div v-if="row.item.admin === '-'"> + <div class="px-1 col-md-6 col-12"> + <b-button + @click="switchToggleDetails(row)" + variant="success" + size="sm" + class="w-100" + > + Pasang + </b-button> + </div> + </div> + <b-row class="mx-0" v-else> + <div class="px-1 col-md-6 col-12"> + <b-button + @click="switchToggleDetails(row)" + variant="primary" + size="sm" + class="w-100" + > + Ubah + </b-button> + </div> + <div class="px-1 col-md-6 col-12"> + <b-button + @click="clearButtonHandler(row)" + variant="danger" + size="sm" + class="w-100" + > + Kosongkan + </b-button> + </div> + </b-row> + </template> + <template slot="row-details" slot-scope="row"> + <b-card + bg-variant="light" + > + <small><b>Mohon pilih Admin dari daftar di bawah ini:</b></small> + <b-form-select + v-model="selected" + :options="options" + size="sm" + /> + <b-button + @click="assignAdmin(row)" + variant="primary" + size="sm" + class="float-right mt-2 ml-2" + > + Pilih Admin + </b-button> + <b-button + @click="switchToggleDetails(null)" + size="sm" + class="float-right mt-2" + > + Batalkan + </b-button> + </b-card> + </template> + <template slot="empty"> + <div align="center">Tidak ada data untuk ditampilkan</div> + </template> + <template slot="emptyfiltered"> + <div align="center">Data tidak ditemukan</div> + </template> + </b-table> + <b-pagination + v-model="currentPage" + :total-rows="totalRows" + :per-page="perPage" + align="center" + /> + + <!-- Modal Component --> + <b-modal + id="confirmation-modal" + centered + title="Konfirmasi" + v-model="modalVisibility" + ok-title="Kosongkan" + cancel-title="Batal" + ok-variant="danger" + @ok="clearAdminHandler" + > + <p align="center" class="my-4"> + Apakah Anda yakin ingin mengosongkan Admin?<br> + <b>Tindakan ini tidak dapat diurungkan.</b> + </p> + </b-modal> + </b-tab> + </b-tabs> + </b-card> + </div> + </div> +</template> + +<script> +import Comments from '@/components/partials/Comments' + +export default { + name: 'PanelAdministrator', + components: { + 'comments' : Comments, + }, + data() { + return { + currentRow: null, + clearedRowPointer: null, + modalVisibility: false, + totalRows: 1, + currentPage: 1, + perPage: 15, + filter: null, + selected: 'urusan', + fields: ['urusan', 'admin', 'aksi'], + urusan : [ + { judul: "Pendapatan", url: "" }, + { judul: "Pembiayaan", url: "" }, + { judul: "Biaya Langsung", url: "" }, + { judul: "Biaya Tidak Langsung", url: "" }, + ], + items : [ + { urusan: 'Biaya Langsung', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'Biaya Tak Langsung', admin: 'David Timothy Panjaitan'}, + { urusan: 'Pembiayaan', admin: '-'}, + { urusan: 'Pendapatan', admin: '-'}, + { urusan: 'A', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'B', admin: 'David Timothy Panjaitan'}, + { urusan: 'C', admin: '-'}, + { urusan: 'D', admin: '-'}, + { urusan: 'E', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'F', admin: 'David Timothy Panjaitan'}, + { urusan: 'G', admin: '-'}, + { urusan: 'H', admin: '-'}, + { urusan: 'I', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'J', admin: 'David Timothy Panjaitan'}, + { urusan: 'K', admin: '-'}, + { urusan: 'L', admin: '-'}, + { urusan: 'M', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'N', admin: 'David Timothy Panjaitan'}, + { urusan: 'O', admin: '-'}, + { urusan: 'P', admin: '-'}, + { urusan: 'Q', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'R', admin: 'David Timothy Panjaitan'}, + { urusan: 'S', admin: '-'}, + { urusan: 'T', admin: '-'}, + { urusan: 'U', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'V', admin: 'David Timothy Panjaitan'}, + { urusan: 'W', admin: '-'}, + { urusan: 'X', admin: '-'}, + { urusan: 'Y', admin: 'Rifo Ahmad Genadi'}, + { urusan: 'Z', admin: 'David Timothy Panjaitan'}, + ], + options: [ + { value: '0', text: 'Rifo Ahmad Genadi' }, + { value: '1', text: 'David Timothy Panjaitan' }, + { value: '2', text: 'William Rukmansa' }, + { value: '3', text: 'Ricky Kennedy' } + ], + } + }, + created : function() { + if (this.$store.state.user.role <= 0) { + this.$router.push({name: 'LandingPage'}); + return + } + + this.totalRows = this.items.length + this.$store.commit('changed','Jenis Anggaran') + }, + methods: { + assignAdmin : function(row) { + row.item.admin = this.options[this.selected].text + this.switchToggleDetails(null) + }, + clearButtonHandler : function(row) { + this.modalVisibility = true + this.clearedRowPointer = row + }, + clearAdminHandler : function() { + this.clearedRowPointer.item.admin = "-" + this.switchToggleDetails(null) + }, + switchToggleDetails : function(newRow) { + if (this.currentRow) { + this.currentRow.toggleDetails() + } + if (newRow) { + newRow.toggleDetails() + } + this.currentRow = newRow + this.selected = null + }, + filterTrigger(item) { + this.totalRows = item.length + this.currentPage = 1 + } + } +} +</script> + + +<style lang="scss" scoped> +@import 'src/assets/css/style.scss'; + +#placeholder { + padding: 30px 20px; + + #container { + height: auto; + width: 100%; + min-width: 250px; + max-width: 1000px; + margin: auto; + border-radius: 5px; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.25); + } +} +</style> \ No newline at end of file diff --git a/src/components/pages/PendapatanPage.vue b/src/components/pages/PendapatanPage.vue index d10e93592525e1d1d8a24de584d3c04eca31711b..d14ce62e954f8f0c316e18135e2a1e0d95ec552f 100644 --- a/src/components/pages/PendapatanPage.vue +++ b/src/components/pages/PendapatanPage.vue @@ -1,23 +1,72 @@ <template> - <div> - Pendapatan + <div class="content"> + <table-budget :data ='data'/> </div> </template> <script> +import TableBudget from '@/components/partials/TableBudget' + export default { name: 'Pendapatan', components: { - + 'table-budget' : TableBudget }, data() { return { - + data :{ + perPage: 5, + currentPage: 1, + fields : { + activity_name : { + label : 'Activity Name', + sortable : true, + }, + admin_name : { + label : 'Admin Name', + sortable : true, + }, + actions : { + label : 'Actions' + } + }, + current_item: { + id : 99, activity_name:'current activity', admin_name : '--' + }, + items: [ + { id: 1, activity_name: 'Aaaaaaaaaaaa', admin_name: 'Flintstone' }, + { id: 2, activity_name: 'B', admin_name: 'Flintstone' }, + { id: 3, activity_name: 'C', admin_name: 'Rubbleaskldjf klsajdfklsajdkalskjdfklsjdfalkdflksdj fljslkfjskldfj lksajlkfjsdl ksalksjdfklasjdlkjfs lkdjfklsajfklasklfmasdlkfsj oidfamslkdfmi saldkfmsialfi madlifsm' }, + { id: 4, activity_name: 'D', admin_name: 'Rubble' }, + { id: 5, activity_name: 'E', admin_name: 'Flintstone' }, + { id: 6, activity_name: 'F', admin_name: 'Rubble' }, + { id: 7, activity_name: 'G', admin_name: 'Gazzoo' }, + { id: 8, activity_name: 'H', admin_name: 'Slate' }, + { id: 9, activity_name: 'I', admin_name: 'Slaghoople' }, + // { id: 10, first_name: 'Ricky', last_name: 'Kennedy' } + ], + } + } + }, + computed: { + rows() { + return this.items.length } }, methods: { + changeSeen : function() { + this.seen = !this.seen; + if(this.rows % 5 !== 0) { + var remainder = this.rows % 5; + var number_of_blank = 5 - remainder; + for(var i=0; i < number_of_blank; i++) { + this.items.push({id : '--' , first_name : '--', last_name: '--' } ); + } + } + } }, + //ini jangan dihapus created : function() { this.$store.commit('changed','Anggaran Pendapatan') } diff --git a/src/components/pages/SemuaAnggaran.vue b/src/components/pages/SemuaAnggaran.vue index 2cae2a81a87eb321f127cf9b69741a2c21a75428..111d00c59fa278f091c08a4d8bb740a02f94ae5c 100644 --- a/src/components/pages/SemuaAnggaran.vue +++ b/src/components/pages/SemuaAnggaran.vue @@ -1,25 +1,72 @@ <template> - <div> - Semua Anggaran - </div> + <b-container> + <h2> SEMUA ANGGARAN APBD JABAR</h2> + <b-row class="justify-content-md-center"> + <b-col id="visualization" class="bg-light" cols="12" lg="8"> + <visualization + v-bind:src="data" + @click-handler="handler" + /> + </b-col> + <b-col cols="12" lg="4"> + <simple-card-container + :dataBubble="data" + @click-handler="handler" + /> + </b-col> + </b-row> + <div id="comments-container"> + <comments + commentable + v-bind:id="this.id" + /> + </div> + </b-container> </template> <script> +import SimpleCardContainer from '@/components/partials/SimpleCardContainer' +import Comments from '@/components/partials/Comments' +import Visualization from '@/components/partials/Visualization' + export default { name: 'SemuaAnggaran', components: { - + 'simple-card-container' : SimpleCardContainer, + 'comments' : Comments, + 'visualization' : Visualization, }, data() { return { - + data : [], + id : "" } }, methods: { - + handler(idobj) { + let id = idobj.$oid + this.$router.push({ name: 'BiayaLangsungId', params: { id: id } }) + }, + getDataFromTop() { + let fetchData = { + method: 'POST', + body: JSON.stringify({ year: 2019 }), + headers: { "Content-Type": "application/json" } + } + + fetch(`${this.$store.state.baseUrl}/api/page/get-top`, fetchData) + .then(response => response.json()) + .then(response => { + if(response.status === 200) { + this.id = response.data._id.$oid + this.data = response.subdata + } + }) + }, }, created : function() { this.$store.commit('changed','Semua Anggaran') + this.getDataFromTop() } } </script> @@ -28,4 +75,23 @@ export default { <style lang="scss" scoped> @import 'src/assets/css/style.scss'; +h2 { + color: $primary; + text-shadow: 0 5px 10px rgba(50, 50, 50, 0.25); + margin: 10px 10px; +} + +.container { + overflow-x: hidden; + + #comments-container { + margin: 10px auto; + max-width: 800px; + } +} + +#visualization { + min-height: 50vh; +} + </style> \ No newline at end of file diff --git a/src/components/pages/SettingsPage.vue b/src/components/pages/SettingsPage.vue new file mode 100644 index 0000000000000000000000000000000000000000..4f67f2573ebe247c075032e65a2a1ada05feebfa --- /dev/null +++ b/src/components/pages/SettingsPage.vue @@ -0,0 +1,148 @@ +<template> + <div id="placeholder"> + <div id="container"> + <b-card no-body> + <b-tabs card> + <b-tab title="Ubah Kata Sandi" active> + <b-alert + :show="dismissCountDown" + dismissible + :variant="alertVariant" + @dismissed="dismissCountDown=0" + @dismiss-count-down="countdownCallback" + > + {{ message }} + </b-alert> + <b-form @submit.prevent="submitChangePassword"> + <b-form-group label="Kata sandi lama:"> + <b-form-input + type="password" + v-model="changePass.oldPassword" + required + placeholder="Masukkan kata sandi lama" /> + </b-form-group> + + <b-form-group label="Kata sandi baru:"> + <b-form-input + type="password" + v-model="changePass.newPassword" + required + placeholder="Masukkan kata sandi baru" /> + </b-form-group> + + <b-form-group label="Konfirmasi kata sandi baru:"> + <b-form-input + type="password" + v-model="changePass.confirmPassword" + required + placeholder="Masukkan kata sandi baru" /> + </b-form-group> + <b-button @click="submitChangePassword" type="submit" variant="primary">Ubah Kata Sandi</b-button> + </b-form> + </b-tab> + </b-tabs> + </b-card> + </div> + </div> +</template> + +<script> +export default { + name: 'UserSettings', + components: { + + }, + data() { + return { + changePass: { + oldPassword: '', + newPassword: '', + confirmPassword: '' + }, + message: '', + dismissSecs: 15, + dismissCountDown: 0, + alertVariant: 'danger' + } + }, + created : function() { + this.$store.commit('changed','Jenis Anggaran') + }, + methods: { + submitChangePassword() { + if (this.changePass.oldPassword.length === 0) { + this.setMessage("Kata sandi lama wajib diisi", 'warning') + return + } + if (this.changePass.newPassword.length === 0) { + this.setMessage("Kata sandi baru wajib diisi", 'warning') + return + } + if (this.changePass.newPassword !== this.changePass.confirmPassword) { + this.setMessage("Kata sandi baru tidak cocok", 'warning') + return + } + + let fetchData = { + method: 'POST', + body: JSON.stringify( + { + current_password: this.changePass.oldPassword, + new_password: this.changePass.newPassword + } + ), + headers: { + "Content-Type": "application/json", + "Authorization": this.$store.state.user.token + } + }; + + fetch(`${this.$store.state.baseUrl}/api/change-password`, fetchData) + .then(response => response.json()) + .then(response => { + if(response.status === 200) { + this.setMessage('Kata sandi berhasil diubah!', 'success') + } else if (response.status === 401) { + this.setMessage('Kata sandi lama Anda salah. Silakan masukkan kembali kata sandi lama yang benar.', 'danger') + } else { + this.setMessage('Terjadi kesalahan. Kesalahan: ' + response.message, 'danger') + } + }) + .catch(error => { + this.setMessage('Tidak dapat terhubung dengan server. Mohon periksa koneksi internet dan cobalah beberapa saat lagi.', 'danger') + }) + }, + countdownCallback(dismissCountDown) { + this.dismissCountDown = dismissCountDown + }, + setMessage(message, variant) { + this.message = message + this.alertVariant = variant + this.dismissCountDown = this.dismissSecs + } + } +} +</script> + + +<style lang="scss" scoped> +@import 'src/assets/css/style.scss'; + +#placeholder { + display: flex; + padding: 30px 20px; + + #container { + height: auto; + width: 100%; + min-width: 250px; + max-width: 500px; + margin: auto; + border-radius: 5px; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.25); + } +} + + + +</style> \ No newline at end of file diff --git a/src/components/partials/Comments.vue b/src/components/partials/Comments.vue new file mode 100644 index 0000000000000000000000000000000000000000..e1175d5e8aee716f26998e2da1d426f417c179d3 --- /dev/null +++ b/src/components/partials/Comments.vue @@ -0,0 +1,241 @@ +<template> + <div id="comments-placeholder"> + <h4 class="font-weight-bold">Komentar ({{rows}})</h4> + <div id="comments-container"> + <h3 + class="center text-muted" + > + {{noticeText}} + </h3> + <b-card + bg-variant="light" + class="item" + v-for="comment in lists" + :key="comment._id.$oid" + > + <div><small class="font-weight-bold">{{comment.commenter_name}}</small></div> + {{comment.comment_text}} + <div><small class="text-muted font-italic">{{convertTimestamp(comment.date.$date)}}</small></div> + <b-card + v-if="comment.hasOwnProperty('reply')" + bg-variant="dark" + text-variant="white" + class="item-reply float-right" + > + <div><small class="font-weight-bold">Administrator</small></div> + {{comment.reply.reply_text}} + <div><small class="text-muted font-italic">{{comment.reply.timestamp}}</small></div> + </b-card> + <div v-else> + <b-card + v-if="replyable" + bg-variant="dark" + text-variant="white" + class="reply-box float-right" + > + <b-form-textarea + id="textarea" + class="reply-textarea" + v-model="replyText[comment._id.$oid]" + placeholder="Masukkan balasan..." + no-resize + /> + <b-button variant="primary" class="float-right mt-2" @click="replyComment(comment._id.$oid)">Kirim</b-button> + </b-card> + </div> + </b-card> + </div> + <div id="comment-box"> + <b-pagination + v-model="currentPage" + :total-rows="rows" + :per-page="perPage" + align="center" + /> + <div v-if="commentable"> + <div v-if="this.$store.state.user.token != ''" id="comment-section"> + <b-form-textarea + id="textarea" + v-model="text" + placeholder="Masukkan komentar..." + no-resize + /> + <b-button variant="primary" class="float-right mt-2" @click="addComment">Kirim</b-button> + </div> + <div v-else> + Anda harus <router-link :to="{ name:'LoginPage' }">masuk</router-link> terlebih dahulu sebelum memberikan komentar. + </div> + <div> + <small class="text-muted font-italic"> + Dengan mengirim komentar, Anda tunduk terhadap UU ITE yang berlaku. + </small> + </div> + </div> + </div> + </div> +</template> + +<script> +export default { + name: 'Comments', + props: { + commentable : Boolean, + replyable : Boolean, + unreplied : Boolean, + id: String + }, + components: { + + }, + data() { + return { + noticeText: "", + perPage: 5, + currentPage: 1, + text: "", + replyText: [], + data: [], + } + }, + computed: { + rows() { + return this.data.length + }, + lists() { + // Return just page of items needed + return this.data.slice( + (this.currentPage - 1) * this.perPage, + this.currentPage * this.perPage + ) + }, + }, + methods: { + addComment() { + let fetchData = { + method: 'POST', + body: JSON.stringify({ page_id: this.id, text: this.text }), + headers: { "Content-Type": "application/json", "Authorization": this.$store.state.user.token } + } + + fetch(`${this.$store.state.baseUrl}/api/comment/add`, fetchData) + .then(response => response.json()) + .then(response => { + if(response.status === 200) { + this.refreshContent() + } + }) + }, + replyComment(id) { + let fetchData = { + method: 'POST', + body: JSON.stringify({ comment_id: id, text: this.replyText[id] }), + headers: { "Content-Type": "application/json", "Authorization": this.$store.state.user.token } + } + + fetch(`${this.$store.state.baseUrl}/api/comment/add-reply`, fetchData) + .then(response => response.json()) + .then(response => { + if(response.status === 200) { + this.refreshContent() + } + }) + }, + refreshContent() { + if(this.id != '') { + this.data = [] + this.noticeText = "Memuat komentar" + let fetchData = { + method: 'POST', + body: JSON.stringify({ page_id: this.id }), + headers: { "Content-Type": "application/json" } + } + + let url = "" + if (this.unreplied) + url = `${this.$store.state.baseUrl}/api/comment/get-unreplied` + else + url = `${this.$store.state.baseUrl}/api/comment/get` + + fetch(url, fetchData) + .then(response => response.json()) + .then(response => { + if(response.status === 200) { + this.data = response.data + if (this.rows == 0) this.noticeText = "Tidak ada komentar" + else this.noticeText = "" + } + }) + } + }, + convertTimestamp(unix) { + let months = ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'] + let date = new Date(unix) + let year = date.getFullYear() + let month = months[date.getMonth()] + let day = date.getDate() + let hours = date.getHours() + let minutes = "0" + date.getMinutes() + let seconds = "0" + date.getSeconds() + return day + ' ' + month + ' ' + year + ', ' + hours +':'+ minutes.substr(-2) + ':' + seconds.substr(-2) + ' WIB' + } + }, + created() { + this.refreshContent() + }, + watch: { + id(val) { + this.refreshContent() + } + } +} +</script> + + +<style lang="scss" scoped> +@import 'src/assets/css/style.scss'; + +#comments-placeholder { + width: 100%; + height: 100%; + + #comments-container { + height: 60%; + padding: 10px; + overflow: auto; + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + border-radius: 5px; + + .item { + width: 100%; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.25); + margin-bottom: 5px; + } + + .item-reply, .reply-box { + width: 100%; + margin-top: 5px; + } + + .item-reply>.card-body { + padding: 5px 15px !important; + } + + .reply-box>.card-body { + padding: 5px !important; + } + + .reply-textarea { + background-color: #212529; + border: 1px solid #212529; + color: white; + } + } + + #comment-box { + height: 30%; + margin: 5% 0; + } +} + +</style> diff --git a/src/components/partials/DetailCard.vue b/src/components/partials/DetailCard.vue new file mode 100644 index 0000000000000000000000000000000000000000..29ee08840390d56c213d7dd8fad0d74674e9dfa7 --- /dev/null +++ b/src/components/partials/DetailCard.vue @@ -0,0 +1,94 @@ +<template> + <div id="placeholder"> + <h4 class="font-weight-bold title"> + Hierarki + </h4> + <b-card + header-text-variant="light" + header-tag="header" + header-bg-variant="info" + bg-variant="light" + > + <div slot="header" class="text-center px-2 py-1 mb-0"> + <h4>{{ head.text }}</h4> + <h5><b> + {{ "Rp "+ head.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.') + ',00.-' }} + </b></h5> + </div> + <div class="content-anggaran" v-for="data in tail" :key=data.text> + <p class="text-center separator">â–¼</p> + {{ data.text }} + <div class="text-right"><b> + {{ "Rp "+ data.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.') + ',00.-' }} + </b></div> + <hr/> + </div> + </b-card> + </div> +</template> + +<script> + +export default { + name: 'DetailCard', + props : ['detailAnggaran'], + data() { + return { + head : { + text: 'Memuat', + value: 0 + }, + tail : [] + } + }, + watch: { + detailAnggaran(val) { + // Exclude top level when the top level is 'Semua Anggaran' + if (val.length > 0 && val[0].text == 'Semua Anggaran') val = val.slice(1, val.length) + + this.head = val[0] + this.tail = val.slice(1, val.length) + } + } +} +</script> + +<!-- Add "scoped" attribute to limit CSS to this component only --> +<style lang="scss" scoped> +@import 'src/assets/css/style.scss'; + +#placeholder { + padding: 10px; +} + +.card-body { + font-size: 1rem; + padding: 0 1rem; +} + +.title { + color: $primary; + text-shadow: 0 5px 10px rgba(50, 50, 50, 0.25); +} + +.card { + width : 100%; + margin-top : 10px; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.25); +} + +.card-header { + font-size: 1.25rem; + padding: 0.2rem; +} + +.separator { + color: #00000020; + margin-top: -0.45rem; + margin-bottom: 0; +} + +hr { + margin-bottom: 0; +} +</style> \ No newline at end of file diff --git a/src/components/partials/Navbar.vue b/src/components/partials/Navbar.vue new file mode 100644 index 0000000000000000000000000000000000000000..f6782aa113f7b76c3f520c10f13e881d6695718b --- /dev/null +++ b/src/components/partials/Navbar.vue @@ -0,0 +1,115 @@ +<template> + <b-navbar id="navbar" toggleable="sm" type="dark" variant="info" fixed="top"> + <b-container> + <b-navbar-brand> + <router-link to="/"> + APBD JABAR + </router-link> + </b-navbar-brand> + + <b-navbar-toggle target="nav_collapse" /> + + <b-collapse is-nav id="nav_collapse"> + <!-- Right aligned nav items --> + <b-navbar-nav> + <b-nav-item-dropdown v-bind:text=state left> + <b-dropdown-item v-on:click="gotoPage('SemuaAnggaran')"> + Semua Anggaran + </b-dropdown-item> + <b-dropdown-item v-on:click="gotoPage('PendapatanPage')"> + Anggaran Pendapatan + </b-dropdown-item> + <b-dropdown-item v-on:click="gotoPage('BiayaLangsung')"> + Anggaran Biaya Langsung + </b-dropdown-item> + <b-dropdown-item v-on:click="gotoPage('BiayaTidakLangsung')"> + Anggaran Biaya Tidak Langsung + </b-dropdown-item> + <b-dropdown-item v-on:click="gotoPage('Pembiayaan')"> + Anggaran Pembiayaan + </b-dropdown-item> + </b-nav-item-dropdown> + </b-navbar-nav> + + <b-navbar-nav class="ml-auto"> + <div v-if="this.$store.state.user.token == ''"> + <b-nav-item v-on:click="gotoPage('LoginPage')" > + <span style="color:white;">Masuk</span> + </b-nav-item> + </div> + <div v-else> + <b-nav-item-dropdown v-bind:text=name right> + <b-dropdown-item + v-if="this.$store.state.user.role > 0" + v-on:click="gotoPage('PanelAdministrator')" + > + Panel Admin + </b-dropdown-item> + <b-dropdown-item v-on:click="gotoPage('UserSettings')"> + Pengaturan + </b-dropdown-item> + <b-dropdown-item v-on:click="logOut()"> + Keluar + </b-dropdown-item> + </b-nav-item-dropdown> + </div> + </b-navbar-nav> + </b-collapse> + </b-container> + </b-navbar> +</template> + +<script> + +export default { + name: 'Navbar', + data () { + return { + + } + }, + computed : { + state() { + return this.$store.state.pilihan + }, + name() { + return this.$store.state.user.name + } + }, + methods : { + gotoPage(page) { + this.$router.push({name: page}) + }, + logOut() { + this.$cookie.set('token', ""); + this.$store.commit('clearUser') + this.$router.push({name: 'LandingPage'}); + } + }, +} +</script> + +<!-- Add "scoped" attribute to limit CSS to this component only --> +<style scoped> +b-nav-item { + color: white; +} + +#navbar { + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); +} + +li a { + text-decoration: none; + color : black; +} + +a { + text-decoration: none; + color : white ; +} + +.navbar-link span { + color : rgba(255,255,255,1) !important; +} +</style> diff --git a/src/components/partials/SimpleCard.vue b/src/components/partials/SimpleCard.vue new file mode 100644 index 0000000000000000000000000000000000000000..6de2f3fccca0d2fff97ad21b543514905e3f1219 --- /dev/null +++ b/src/components/partials/SimpleCard.vue @@ -0,0 +1,67 @@ +<template> + <b-col class="px-2" md="6" lg="12" cols="12"> + <b-card + header-text-variant="light" + header-tag="header" + header-bg-variant="info" + bg-variant="light" + @click="passIndex()" + > + <div slot="header" class="text-left px-2 py-1 mb-0"> + {{ jenisAnggaran }} + </div> + <div class="content-anggaran text-right"> + <b>{{ total }}</b> + </div> + <div class="index"> + <b>{{ index + 1 }}</b> + </div> + </b-card> + </b-col> +</template> + +<script> + +export default { + name: 'SimpleCard', + props : ['jenisAnggaran','totalAnggaran','index'], + data() { + return { + total : "Rp "+this.totalAnggaran + } + }, + methods : { + passIndex() { + this.$emit('click-handler', this.index) + } + } +} +</script> + +<!-- Add "scoped" attribute to limit CSS to this component only --> +<style scoped> + +.card-body { + font-size: 1.25rem; +} + +.card { + width : 100%; + margin-top : 10px; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.25); + overflow: hidden; + cursor: pointer; +} + +.index { + position: absolute; + font-size: 8rem; + font-style: bold; + color: #00000011; + bottom: -80px; + -webkit-user-select: none; /* Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+/Edge */ + user-select: none; /* Standard */ +} +</style> diff --git a/src/components/partials/SimpleCardContainer.vue b/src/components/partials/SimpleCardContainer.vue new file mode 100644 index 0000000000000000000000000000000000000000..615029e79cb3068533bbf23e7cfc3f71f5a44315 --- /dev/null +++ b/src/components/partials/SimpleCardContainer.vue @@ -0,0 +1,42 @@ +<template> + <b-row id="content-detail"> + <simple-card v-for="(data, index) in dataBubble" @click-handler="passData" :key="data.name" :jenisAnggaran="data.name" :index="index" :totalAnggaran="data.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.') + + ',00.-'"/> + </b-row> +</template> + +<script> +import SimpleCard from './SimpleCard' + +export default { + name: 'SimpleCardContainer', + props: ['dataBubble'], + data() { + return { + } + }, + components: { + 'simple-card':SimpleCard, + }, + methods : { + passData(index) { + if (this.dataBubble[index].subdata.length != 0) { + window.scrollTo(0, 0); + this.$emit('click-handler', this.dataBubble[index]._id) + } + } + }, +} +</script> + +<!-- Add "scoped" attribute to limit CSS to this component only --> +<style lang="scss" scoped> +@import 'src/assets/css/style.scss'; + +b-col { + margin: 0; +} + + + +</style> diff --git a/src/components/partials/SimpleCardContainerScroll.vue b/src/components/partials/SimpleCardContainerScroll.vue new file mode 100644 index 0000000000000000000000000000000000000000..e78e681283e88211c7e6e62df019789bef04a3ea --- /dev/null +++ b/src/components/partials/SimpleCardContainerScroll.vue @@ -0,0 +1,77 @@ +<template> + <div id="placeholder"> + <h4 class="font-weight-bold title"> + {{"Detail (" + rows + ")" }} + </h4> + <b-row id="content-detail"> + <simple-card class="simple-card" @click-handler="passData" v-for="(data, index) in dataBubble" :key="data._id.$oid" :index="index" :jenisAnggaran="data.name" :totalAnggaran="data.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.') + + ',00.-'"" /> + </b-row> + </div> +</template> + +<script> +import SimpleCard from './SimpleCard' + +export default { + name: 'SimpleCardContainer', + props: ['dataBubble'], + data() { + return { + } + }, + computed : { + rows() { + return this.dataBubble.length; + } + }, + components: { + 'simple-card':SimpleCard, + }, + methods : { + passData(index) { + if (this.dataBubble[index].subdata.length != 0) { + window.scrollTo(0, 0); + this.$emit('click-handler', this.dataBubble[index]._id) + } + } + }, +} +</script> + +<!-- Add "scoped" attribute to limit CSS to this component only --> +<style lang="scss" scoped> +@import 'src/assets/css/style.scss'; + +b-col { + margin: 0; +} + +.title { + color: $primary; + text-shadow: 0 5px 10px rgba(50, 50, 50, 0.25); +} + +#placeholder { + width: 100%; + padding: 10px; + + #content-detail { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + border-radius: 5px; + padding-top: 20px; + max-height: 500px; + padding: 0 10px 10px; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + } + + .simple-card { + + } +} + + + +</style> diff --git a/src/components/partials/TableBudget.vue b/src/components/partials/TableBudget.vue new file mode 100644 index 0000000000000000000000000000000000000000..94704fad5404a38c4757b2eef5f6d58535a8f5fe --- /dev/null +++ b/src/components/partials/TableBudget.vue @@ -0,0 +1,265 @@ +<template> + <b-container class="content justify-content-center"> + <b-col> + <b-row align-h='left'> + <h3> + {{ "Activity : " + currentItemActivity }} + <br><br> + {{"Admin : " + currentItemAdmin}} + </h3> + </b-row> + <b-row v-if="showCard"> + <b-card > + <small><b>Mohon pilih Admin dari daftar di bawah ini:</b></small> + <b-form-select + v-model="selected" + :options="dataTable.options" + size="sm" + /> + <b-button + @click="updateAdmin()" + variant="primary" + size="sm" + class="float-right mt-2 ml-2" + > + Pilih Admin + </b-button> + <b-button + v-on:click="changeShowCardState()" + size="sm" + class="float-right mt-2" + > + Batalkan + </b-button> + </b-card> + </b-row> + <b-row class="my-2" align-h="space-between"> + <b-col class="pl-0"> + <b-button v-on:click="backState()" v-if="dataTable.isNotTop" variant="outline-secondary" size="sm"> kembali </b-button> + </b-col> + <b-col + v-if="dataTable.current_item.admin_name === '--'" + cols="auto" + > + <b-button + v-on:click="changeShowCardState()" + variant="success" + size="sm" + > + Pasang Admin + </b-button> + </b-col> + <b-col + v-else + cols="auto" + > + + + <b-button + v-on:click="changeShowCardState()" + variant="primary" + size="sm" + > + Ubah Admin + </b-button> + <b-button + v-on:click="showModal()" + variant="danger" + size="sm" + > + Hapus Admin + </b-button> + </b-col> + + </b-row> + + <b-row align-h='center' class=" justify-content-center overflow-auto"> + <b-table + hover + responsive + id="my-table" + :items="dataTable.items" + :per-page="dataTable.perPage" + :current-page="dataTable.currentPage" + :fields="dataTable.fields" + small + striped + :busy="isBusy" + stacked="md" + fixed + > + <div slot="table-busy" class="text-center text-danger my-2"> + <b-spinner class="align-middle"></b-spinner> + <strong>Loading...</strong> + </div> + <template slot="actions" slot-scope="row" > + <b-button + size="sm" + v-on:click="seeDetail(row)" + > + Lihat + </b-button> + </template> + </b-table> + + <b-pagination + v-model="dataTable.currentPage" + :total-rows="rows" + :per-page="dataTable.perPage" + aria-controls="my-table" + ></b-pagination> + </b-row> + </b-col> + <!-- Modal Component --> + <b-modal + id="confirmation-modal" + centered + title="Konfirmasi" + v-model="modalVisibility" + ok-title="Hapus" + cancel-title="Batal" + ok-variant="danger" + @ok="removeAdmin()" + > + <p align="center" class="my-4"> + Apakah Anda yakin ingin untuk menghapus Admin?<br> + <b>Tindakan ini tidak dapat diurungkan.</b> + </p> + </b-modal> + </b-container> +</template> + +<script> +export default { + name: 'TableBudget', + components: { + + }, + props: ['dataTable'], + data() { + return { + isBusy : false, + showCard : false, + selected : 0, + modalVisibility : false + } + }, + watch : { + currentItemAdmin() { + console.log(currentItemActivity) + } + }, + computed: { + rows() { + return this.dataTable.items.length + }, + currentItemAdmin() { + return this.dataTable.current_item.admin_name + }, + currentItemActivity() { + return this.dataTable.current_item.activity_name + }, + }, + methods: { + getData : function() { + return this.dataTable; + }, + // tambahkan property table + // :tbody-tr-class="rowClass" + + rowClass( items, type ) { + if(!items) return + if(items.admin_name === '--') + return 'table-danger' + else + return 'table-success' + }, + + changeShowCardState : function() { + this.showCard = !this.showCard; + }, + + removeAdmin : function() { + this.dataTable.current_item.admin_name = '--'; + }, + + updateAdmin : function() { + if(this.selected === 0) { + alert('pilihan tidak valid') + } else { + let fetchData = { + method: 'POST', + body: JSON.stringify({page_id : this.dataTable.current_item.id, admin_id: this.selected}), + headers: { "Content-Type": "application/json" } + } + + fetch(`${this.$store.state.baseUrl}/api/admin/add-page`, fetchData) + .then(response => response.json()) + .then(response => { + if(response.status === 200) { + for(let i in this.dataTable.options){ + if(this.dataTable.options[i].value === this.selected){ + this.dataTable.current_item.admin_name = this.dataTable.options[i].text; + break; + } + } + } + }) + + // fetchData = { + // method: 'POST', + // body: JSON.stringify({page_id : this.dataTable.current_item.id}), + // headers: { "Content-Type": "application/json" } + // } + + // fetch(`${this.$store.state.baseUrl}/api/admin/get-admin`, fetchData) + // .then(response => response.json()) + // .then(response => { + // if(response.status === 200) { + // console.log(response) + // this.dataTable.current_item.admin_name = response.data.name; + // } + // }) + } + }, + seeDetail : function(row) { + // this.isBusy = true + console.log('row : ') + console.log(row.item.id) + this.$emit('changeActivity',row.item.id); + }, + showModal : function() { + this.modalVisibility = true; + }, + backState : function() { + // this.isBusy = true + this.$emit('backState'); + }, + }, + created : function() { + + } +} +</script> + + +<style lang="scss" scoped> +@import 'src/assets/css/style.scss'; +* { + margin: 0%; + padding: 0%; +} + +.b-table tbody tr td { + cursor: pointer; +} + +.col-auto { + padding : 0px 5px; +} + +.card { + width: 100%; +} + +</style> \ No newline at end of file diff --git a/src/components/partials/Visualization.vue b/src/components/partials/Visualization.vue new file mode 100644 index 0000000000000000000000000000000000000000..6e43297ed0a1b42b1c289fc81f2b1ad3186376f8 --- /dev/null +++ b/src/components/partials/Visualization.vue @@ -0,0 +1,406 @@ +<template> + <div id="placeholder"> + <div id="chart-container" ref="container"> + <div id="options-container"> + <h3 + v-if="!hide" + class="text-center text-muted" + > + Memuat data + </h3> + <div id="options" v-else> + <div v-if="optionHidden"> + <b-button class="option-toggle" @click="optionHidden = !optionHidden"> + â–¼ + </b-button> + </div> + <div v-else> + <div> + <b-button class="option-toggle" @click="optionHidden = !optionHidden"> + â–² + </b-button> + </div> + <div id="option-choice"> + <b class="mr-3">Tata letak</b> + <b-form-group class="mb-0 mr-5"> + <b-form-radio-group v-model="selected" name="position-options"> + <b-form-radio value="normal">Normal</b-form-radio> + <b-form-radio value="sorted">Merata</b-form-radio> + <b-form-radio value="sorted-proportional">Proporsional</b-form-radio> + <b-form-radio value="separated">Pisah</b-form-radio> + <b-form-input v-if="selected == 'separated'" v-model="separator" type="range" :min="0" :max="src.length-1"></b-form-input> + </b-form-radio-group> + </b-form-group> + <b class="mr-3">Warna</b> + <b-form-group class="mb-0"> + <b-form-radio-group v-model="selectedColor" name="color-options"> + <b-form-radio value="random">Random</b-form-radio> + <b-form-radio value="valueDependent">Sesuai nilai</b-form-radio> + </b-form-radio-group> + </b-form-group> + </div> + </div> + </div> + </div> + <svg id="chart"/> + <div id="separator" v-if="selected=='separated'&&hide"> + <div id="text"> + <b>{{anggaran}}</b> + </div> + <div id="line"/> + </div> + </div> + </div> +</template> + +<script> +import * as d3 from 'd3' + +export default { + name: 'Visualization', + components: { + + }, + props: ['src'], + data() { + return { + hide: false, + svg: null, + tooltip: null, + simulation: null, + selected: 'normal', + selectedColor: 'random', + radiusCircles: null, + maxRadius: 60, + minRadius: 3, + separator: 0, + width: 600, + height: 400, + columnForColor: "name", + columnForWidth: "value", + columnId: "_id", + columnPercentage: "percentage", + columnSubdata: "subdata", + ticked: null, + optionHidden: true, + } + }, + computed: { + anggaran() { + if (this.src[this.separator]) + return 'Rp'+this.src[this.separator].value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.') + + ',00.-' + return '' + } + }, + mounted() { + window.addEventListener("resize", this.sizeHandler) + this.width = this.$refs.container.clientWidth + this.height = this.$refs.container.clientHeight + }, + destroyed() { + window.removeEventListener("resize", this.sizeHandler) + }, + watch: { + src(val) { + if (this.simulation) this.simulation.stop() + this.separator = parseInt(this.src.length/2); + this.createChart() + }, + width(val) { + this.clear() + if (this.simulation) this.simulation.stop() + this.createChart() + }, + height(val) { + this.clear() + if (this.simulation) this.simulation.stop() + this.createChart() + }, + selectedColor(val) { + this.clear() + if (this.simulation) this.simulation.stop() + this.createChart() + }, + selected(val) { + if (this.simulation) this.simulation.stop() + this.setSimulation() + }, + separator(val) { + if (this.simulation) this.simulation.stop() + this.setSimulation() + } + }, + methods: { + clear() { + if (this.svg) this.svg.selectAll("*").remove() + if (this.tooltip) this.tooltip.remove() + this.hide = false + }, + createChart() { + d3.select("#chart-container").datum(this.src).call(this.bubbleChart()); + this.hide = true + }, + sizeHandler() { + this.height = this.$refs.container.clientHeight + this.width = this.$refs.container.clientWidth + }, + setSimulation() { + this.simulation = d3.forceSimulation(this.src) + .force('charge', d3.forceManyBody().strength((d) => { + if (this.selected == 'normal') + return -20 + else + return -10 + })) + .force('collision', d3.forceCollide().radius((d) => { + return this.radiusCircles(d[this.columnForWidth]) + 1 + })) + .force('x', d3.forceX((d) => { + if (this.selected == 'sorted') + return this.width*((this.src.length-d.index-1)/this.src.length - 0.5)*0.75 + else if (this.selected == 'sorted-proportional') + return this.width*(this.radiusCircles(d[this.columnForWidth])/this.maxRadius - 0.5)*0.75 + else if (this.selected == 'normal') + return 0 + else if (this.selected == 'separated') + return d.index > this.separator ? -this.width/4 : this.width/4 + })) + .force('y', d3.forceY()) + .on('tick', this.ticked) + }, + bubbleChart() { + var width = this.width, + height = this.height, + maxRadius = 60, + minRadius = 3, + columnForColor = "name", + columnForWidth = "value", + columnId = "_id", + columnPercentage = "percentage", + columnSubdata = "subdata" + + var self = this + + function chart(selection) { + // create chart + var data = selection.datum() + var div = selection + self.svg = div.select("svg") + self.svg.attr("width", self.width).attr("height", self.height) + + //put the data (hidden) to be visible when mouseover + self.tooltip = selection + .append("div") + .style("position", "fixed") + .style("z-index", "99") + .style("visibility", "hidden") + .style("color", "white") + .style("padding", "8px") + .style("background-color", "#222222cc") + .style("border-radius", "6px") + .style("text-align", "center") + .style("width", "auto") + .style("max-width", "400px") + .style("box-shadow", "0 5px 10px rgba(0, 0, 0, 0.25)") + .text("") + + function validate(x, a, b) { + if (x < a) { + x = a + } + if (x > b) x = b + return x + } + + // ticked handler function + self.ticked = function(e) { + + node.attr("cx", function(d) { + let radius = self.radiusCircles(d[self.columnForWidth]) + return validate(d.x, -self.width/2+radius, self.width/2-radius) + }) + .attr("cy", function(d) { + let radius = self.radiusCircles(d[self.columnForWidth]) + return validate(d.y, -self.height/2+radius, self.height/2-radius) + }); + } + + //create circles width by data + self.radiusCircles = d3.scaleSqrt().domain([d3.min(data, function(d) { + return +d[self.columnForWidth] + }), d3.max(data, function(d) { + return +d[self.columnForWidth] + })]).range([self.minRadius,self.maxRadius]) + + //create circle colors by data + var colorCircles = d3.scaleOrdinal(d3.schemeCategory10) + + // make force simulation function + self.setSimulation() + + //create the circles + var node = self.svg.selectAll("circle") + .data(data) + .enter() + .append("circle") + .attr('r', function(d) { + return self.radiusCircles(d[self.columnForWidth]) + }) + .style("fill", function(d) { + if (self.selectedColor == 'valueDependent') + return d3.interpolateViridis(self.radiusCircles(d[self.columnForWidth])/self.maxRadius) + else if (self.selectedColor == 'random') + return colorCircles(d[self.columnForColor]) + }) + .style("cursor", "pointer") + .attr('transform', 'translate(' + [width / 2, height / 2] + ')') + + // set data visible in mouseover + .on("mouseover", function(d) { + self.tooltip.html( + "<h5 style='margin-bottom: 0;'>" + + d[self.columnForColor] + + "</h5><b>" + + // "<h6 style='margin-bottom: 0;'>" + + // d[columnPercentage].toFixed(2) + + // "%</h6><b>" + + "Rp " + + d[self.columnForWidth].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".") + + ",00.-</b>" + ); + return self.tooltip.style("visibility", "visible") + }) + .on("mouseup", function(d) { + if (d[self.columnSubdata].length != 0) { + self.clear() + self.$emit('click-handler', d[self.columnId]) + } + }) + .on("mousemove", function(d) { + let yPos = d3.event.pageY - window.scrollY + 2 + let xPos = (d3.event.pageX) + if (xPos < window.innerWidth/2) + return self.tooltip.style("top", yPos + "px").style("left", (xPos+10) + "px").style("right", null) + else + return self.tooltip.style("top", yPos + "px").style("left", null).style("right", (window.innerWidth-xPos-15) + "px") + }) + .on("mouseout", function() { + return self.tooltip.style("visibility", "hidden") + }); + } + + chart.width = function(val){ + if (!arguments) { + return self.width + } else { + self.width = val + } + return chart + } + + chart.height = function(val) { + if (!arguments) { + return self.height + } else { + self.height = val + } + return chart + } + + chart.columnForColor = function(value) { + if (!arguments.columnForColor) { + return self.columnForColor + } + self.columnForColor = value + return chart + }; + + chart.columnForWidth = function(value) { + if (!arguments.columnForWidth) { + return self.columnForWidth + } + self.columnForWidth = value + return chart + }; + + chart.columnId = function(value) { + if (!arguments.columnId) { + return self.columnId + } + self.columnId = value + return chart + }; + + return chart + } + } +} +</script> + + +<style lang="scss" scoped> +@import 'src/assets/css/style.scss'; + +#placeholder { + width: 100%; + height: 100%; + + #chart-container { + display: flex; + flex-wrap: wrap; + width: 100%; + height: 100%; + + #chart { + margin: auto; + z-index: 1; + } + } + + #options-container { + position: absolute; + padding: 1rem; + z-index: 2; + + #options { + .option-toggle { + color: white; + margin-bottom: 5px; + } + + #option-choice { + background-color: #ffffffcc; + padding: 1rem; + } + } + } + + #separator { + font-size: 1.5rem; + display: flex; + justify-content: center; + position: absolute; + width: 100%; + height: 100%; + + #text { + position: absolute; + color: #00000066; + z-index: 0; + text-align: center; + bottom: 0; + } + + #line { + background-color: #00000066; + position: absolute; + height: 90%; + width: 1px; + } + } + + +} + +</style> diff --git a/src/components/store/Store.js b/src/components/store/Store.js index ecda9dfd10f464694de99487c7f66d72f4e0a3f5..510788d9be0108ec187f9003542928647eb95f5f 100644 --- a/src/components/store/Store.js +++ b/src/components/store/Store.js @@ -7,12 +7,15 @@ export const store = new Vuex.Store({ state : { pilihan : 'Jenis Keuangan', count : 0, - year : '', + year : 2019, user : { - token : '', - id : -1, - name : '' - } + token: '', + id: -1, + name: '', + role: -1, + pageList: [] + }, + baseUrl: 'http://localhost:5000' }, computed: { pilihan() { @@ -26,10 +29,19 @@ export const store = new Vuex.Store({ setYear(state, data) { state.year = data }, - setUser(state, token, id, name) { - state.user.token = token - state.user.id = id - state.user.name = name + setUser(state, data) { + state.user.token = data.token + state.user.id = data.id + state.user.name = data.name + state.user.role = data.role + state.user.pageList = data.pageList + }, + clearUser(state) { + state.user.token = '', + state.user.id = -1, + state.user.name = '', + state.user.role = -1, + state.user.pageList = [] } }, getters : { diff --git a/src/main.js b/src/main.js index 9d4ab8846d9f4d49fae15007603ed7f9b7ec9d6f..44488f4ae3b2fc2fa48abc7526cd69167af0f869 100644 --- a/src/main.js +++ b/src/main.js @@ -5,6 +5,7 @@ import Vuex from 'vuex' import App from './App' import router from './router' import BootstrapVue from 'bootstrap-vue' +import VueCookie from 'vue-cookie' import {store} from './components/store/store' import 'bootstrap/dist/css/bootstrap.css' @@ -13,6 +14,8 @@ import 'bootstrap-vue/dist/bootstrap-vue.css' Vue.config.productionTip = false Vue.use(BootstrapVue) Vue.use(Vuex) +Vue.use(VueCookie) + /* eslint-disable no-new */ new Vue({ el: '#app', diff --git a/src/router/index.js b/src/router/index.js index 944e9235c1f8e1b7e85635a83609feb29264dfad..fa7d7fa16d106bfe81577a6be161ff45f59a2f61 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -7,6 +7,9 @@ import Pembiayaan from '@/components/pages/PembiayaanPage' import BiayaTidakLangsung from '@/components/pages/BiayaTidakLangsungPage' import BiayaLangsung from '@/components/pages/BiayaLangsungPage' import SemuaAnggaran from '@/components/pages/SemuaAnggaran' +import SimpleCardContainer from '@/components/partials/SimpleCardContainer' +import PanelAdministrator from '@/components/pages/PanelAdministrator' +import UserSettings from '@/components/pages/SettingsPage' Vue.use(Router) export default new Router({ @@ -36,6 +39,11 @@ export default new Router({ name: 'BiayaLangsung', component: BiayaLangsung }, + { + path: '/biaya-langsung/:id', + name: 'BiayaLangsungId', + component: BiayaLangsung + }, { path: '/pembiayaan', name: 'Pembiayaan', @@ -46,6 +54,21 @@ export default new Router({ name: 'SemuaAnggaran', component: SemuaAnggaran }, + { + path: '/tes', + name: 'SimpleCardContainer', + component: SimpleCardContainer + }, + { + path: '/panel-administrator', + name: 'PanelAdministrator', + component: PanelAdministrator + }, + { + path: '/pengaturan', + name: 'UserSettings', + component: UserSettings + }, ], mode: 'history', }) diff --git a/src/test/setup.js b/src/test/setup.js new file mode 100644 index 0000000000000000000000000000000000000000..d1a058b72dbfe007349608f8f2c0bb5230e2981b --- /dev/null +++ b/src/test/setup.js @@ -0,0 +1,11 @@ +// from @vue/cli-plugin-unit-mocha/setup.js +require('jsdom-global')(undefined, { pretendToBeVisual: true, url: 'http://localhost:8080' }) + +// https://github.com/vuejs/vue-test-utils/issues/936 +// better fix for "TypeError: Super expression must either be null or +// a function" than pinning an old version of prettier. +window.Date = Date + + +require('jsdom-global')() +global.expect = require('expect') \ No newline at end of file diff --git a/src/test/testHelloWorld.spec.js b/src/test/testHelloWorld.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..38c41e509cc724293d8e5a356d7a90c3ab0492d1 --- /dev/null +++ b/src/test/testHelloWorld.spec.js @@ -0,0 +1,12 @@ +import {shallow} from '@vue/test-utils' +import HelloWorld from '../src/components/HelloWorld.vue' +describe('HelloWorld.vue',function(){ + + it('Checking <h2> tag text',function(){ + + const wrapper = shallow(HelloWorld) + const h2= wrapper.find('h2') + expect(h2.text()).toBe('Essential Links') + + }) +}) \ No newline at end of file diff --git a/test/setup.js b/test/setup.js new file mode 100644 index 0000000000000000000000000000000000000000..e2fbfe114714a288f6bb442f8c63faa5707da3ba --- /dev/null +++ b/test/setup.js @@ -0,0 +1,3 @@ +require('jsdom-global')() + +global.expect = require('expect') \ No newline at end of file diff --git a/test/testHelloWorld.spec.js b/test/testHelloWorld.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..38c41e509cc724293d8e5a356d7a90c3ab0492d1 --- /dev/null +++ b/test/testHelloWorld.spec.js @@ -0,0 +1,12 @@ +import {shallow} from '@vue/test-utils' +import HelloWorld from '../src/components/HelloWorld.vue' +describe('HelloWorld.vue',function(){ + + it('Checking <h2> tag text',function(){ + + const wrapper = shallow(HelloWorld) + const h2= wrapper.find('h2') + expect(h2.text()).toBe('Essential Links') + + }) +}) \ No newline at end of file